# 支付管理 (17_Payment)
最后更新: 2024-09-20
# 📚 概述
DarkM 框架的支付模块提供了统一的支付接口,支持多种支付渠道(支付宝、微信支付、杉德支付等),实现一次开发,自由切换支付渠道。
源代码位置: DarkM/src/Framework/Payment
# 🏗️ 模块架构
# 项目结构
Payment/
├── Payment.Abstractions/ # 抽象层(接口、配置、异常)
│ ├── IPaymentServiceCollection.cs # 支付服务集合接口
│ ├── Alipay/ # 支付宝抽象
│ │ ├── AlipayOptions.cs # 支付宝配置
│ │ ├── AlipayCertUtil.cs # 证书工具
│ │ └── AlipayException.cs # 支付宝异常
│ └── Wechat/ # 微信支付抽象
│ ├── WeChatPayOptions.cs # 微信支付配置
│ ├── WeChatPayUtility.cs # 微信支付工具
│ ├── WeChatPayException.cs # 微信支付异常
│ └── WeChatPayConsts.cs # 微信支付常量
│
├── Payment.Integration/ # 集成层(DI 注册)
│ └── ServiceCollectionExtensions.cs # DI 扩展
│
├── Payment.Alipay/ # 支付宝实现
│ ├── AlipayClient.cs # 支付宝客户端
│ ├── AlipayNotifyClient.cs # 支付宝通知客户端
│ ├── IAlipayClient.cs # 支付宝客户端接口
│ ├── IAlipayNotifyClient.cs # 支付宝通知接口
│ ├── Request/ # 请求类
│ └── Notify/ # 通知类
│
├── Payment.WeChatPay/ # 微信支付实现
│ ├── V2/ # V2 版本
│ │ ├── WeChatPayClient.cs # 微信支付客户端
│ │ ├── WeChatPayNotifyClient.cs # 微信支付通知客户端
│ │ └── IWeChatPayClient.cs # 接口
│ └── V3/ # V3 版本
│
└── Payment.Sandpay/ # 杉德支付实现
├── SandpayClient.cs # 杉德客户端
└── SandpayOptions.cs # 杉德配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 🔧 核心配置类
# AlipayOptions(支付宝配置)
public class AlipayOptions
{
/// <summary>
/// 应用 Id
/// </summary>
public string AppId { get; set; }
/// <summary>
/// RSA 支付宝公钥
/// "公钥证书"方式时,留空
/// "普通公钥"方式时,必填
/// </summary>
public string AlipayPublicKey { get; set; }
/// <summary>
/// RSA 应用私钥
/// </summary>
public string AppPrivateKey { get; set; }
/// <summary>
/// 服务网关地址
/// 默认为:"https://openapi.alipay.com/gateway.do"
/// </summary>
public string ServerUrl { get; set; } = "https://openapi.alipay.com/gateway.do";
/// <summary>
/// 接口版本
/// 默认为:"1.0"
/// </summary>
public string Version { get; set; } = "1.0";
/// <summary>
/// 签名方式
/// 默认为:"RSA2"
/// </summary>
public string SignType { get; set; } = "RSA2";
/// <summary>
/// 应用公钥证书(证书文件路径/文本内容/Base64)
/// "公钥证书"方式时,必填
/// </summary>
public string AppCert { get; set; }
/// <summary>
/// 支付宝公钥证书(证书文件路径/文本内容/Base64)
/// "公钥证书"方式时,必填
/// </summary>
public string AlipayPublicCert { get; set; }
/// <summary>
/// 支付宝根证书(证书文件路径/文本内容/Base64)
/// "公钥证书"方式时,必填
/// </summary>
public string AlipayRootCert { get; set; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# WeChatPayOptions(微信支付配置)
public class WeChatPayOptions
{
/// <summary>
/// 支付结果通知回调 URL
/// </summary>
public string NotifyUrl { get; set; }
/// <summary>
/// 退款通知地址
/// </summary>
public string RefundNotifyUrl { get; set; }
/// <summary>
/// 应用号(公众平台 AppId/开放平台 AppId/小程序 AppId/企业微信 CorpId)
/// </summary>
public string AppId { get; set; }
/// <summary>
/// 应用密钥(企业微信 AppSecret 等)
/// </summary>
public string AppSecret { get; set; }
/// <summary>
/// 商户号
/// </summary>
public string MchId { get; set; }
/// <summary>
/// 子商户应用号(服务商模式)
/// </summary>
public string SubAppId { get; set; }
/// <summary>
/// 子商户号(服务商模式)
/// </summary>
public string SubMchId { get; set; }
/// <summary>
/// API 证书(.p12 文件路径或 Base64 编码)
/// </summary>
public string Certificate { get; set; }
/// <summary>
/// API 证书密码(默认为商户号)
/// </summary>
public string CertificatePassword { get; set; }
/// <summary>
/// API 密钥
/// </summary>
public string Key { get; set; }
/// <summary>
/// APIv3 密钥
/// </summary>
public string V3Key { get; set; }
/// <summary>
/// RSA 公钥(企业付款到银行卡时使用)
/// </summary>
public string RsaPublicKey { get; set; }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# 🏗️ 依赖注入
# 自动注册机制
// Payment.Integration/ServiceCollectionExtensions.cs
public static class ServiceCollectionExtensions
{
/// <summary>
/// 添加支付功能
/// </summary>
public static IServiceCollection AddPayment(
this IServiceCollection services,
IConfiguration cfg)
{
// 注册微信支付配置
var wechatConfig = services.Where(c =>
c.ServiceType == typeof(WechatConfig)).FirstOrDefault()
.ImplementationInstance as WechatConfig;
if (wechatConfig != null)
{
var ds = wechatConfig.DefaultServer;
WeChatPayOptions wpo = new WeChatPayOptions
{
AppId = ds.AppID,
AppSecret = ds.AppSecret,
MchId = ds.MchID,
Key = ds.PayKey,
Certificate = ds.SSlCertPath,
CertificatePassword = ds.SSlCertPassword,
NotifyUrl = ds.NotifyUrl,
RefundNotifyUrl = ds.RefundNotifyUrl,
V3Key = ds.V3Key,
RsaPublicKey = ds.RsaPublicKey,
SubAppId = ds.SubAppId,
SubMchId = ds.SubMchId
};
services.AddSingleton(wpo);
}
// 扫描并注册所有支付模块
var assemblyList = AssemblyHelper.LoadByNameContainsString(
$".Lib.Payment.");
if (assemblyList == null || !assemblyList.Any())
return services;
foreach (var assembly in assemblyList)
{
var types = assembly.GetTypes()
.Where(m => typeof(IPaymentServiceCollection).IsAssignableFrom(m))
.ToList();
foreach (var type in types)
{
try
{
((IPaymentServiceCollection)Activator.CreateInstance(type))
.AddPayment(services);
}
catch (Exception ex)
{
// 记录日志
}
}
}
return services;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# 💡 使用示例
# 1. 配置支付模块
// appsettings.json
{
"WeChatPay": {
"AppId": "wx1234567890abcdef",
"MchId": "1234567890",
"Key": "your-api-key-32-chars-long",
"Certificate": "/path/to/apiclient_cert.p12",
"CertificatePassword": "1234567890",
"NotifyUrl": "https://api.example.com/wechatpay/notify",
"RefundNotifyUrl": "https://api.example.com/wechatpay/refund-notify",
"V3Key": "your-v3-key-32-chars-long"
},
"Alipay": {
"AppId": "2021001234567890",
"AppPrivateKey": "MIIEvQIBADANBgkqhkiG9w0BAQEF...",
"AlipayPublicKey": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...",
"ServerUrl": "https://openapi.alipay.com/gateway.do",
"SignType": "RSA2"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 2. 注册服务
// Program.cs 或 Startup.cs
var builder = WebApplication.CreateBuilder(args);
// 添加支付服务
builder.Services.AddPayment(builder.Configuration);
var app = builder.Build();
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3. 支付宝扫码支付
public class AlipayPaymentService
{
private readonly IAlipayClient _alipayClient;
private readonly AlipayOptions _options;
private readonly ILogger<AlipayPaymentService> _logger;
public AlipayPaymentService(
IAlipayClient alipayClient,
IOptions<AlipayOptions> options,
ILogger<AlipayPaymentService> logger)
{
_alipayClient = alipayClient;
_options = options.Value;
_logger = logger;
}
/// <summary>
/// 创建扫码支付订单
/// </summary>
public async Task<AlipayTradePrecreateResponse> CreateQRCodePayment(
string outTradeNo,
decimal amount,
string subject,
string body = "")
{
var request = new AlipayTradePrecreateRequest
{
BizContent = new
{
out_trade_no = outTradeNo,
total_amount = amount.ToString("F2"),
subject = subject,
body = body
}
};
var response = await _alipayClient.ExecuteAsync(request);
if (!response.Success)
{
throw new AlipayException(
$"支付宝预创建失败:{response.SubCode} - {response.SubMsg}");
}
return response;
}
/// <summary>
/// 处理支付回调通知
/// </summary>
public async Task<bool> HandleNotify(HttpContext context)
{
var notifyClient = new AlipayNotifyClient(_options);
var notify = await notifyClient.GetNotifyAsync(context);
if (notify == null)
return false;
// 验证签名
if (!notifyClient.VerifySign(notify))
{
_logger.LogWarning("支付宝回调签名验证失败");
return false;
}
// 处理业务逻辑
if (notify.TradeStatus == "TRADE_SUCCESS" ||
notify.TradeStatus == "TRADE_FINISHED")
{
// 更新订单状态
await _orderService.UpdateOrderStatus(
notify.OutTradeNo,
OrderStatus.Paid,
notify.TradeNo);
}
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# 4. 微信支付(小程序)
public class WeChatPayService
{
private readonly IWeChatPayClient _wechatPayClient;
private readonly WeChatPayOptions _options;
private readonly ILogger<WeChatPayService> _logger;
public WeChatPayService(
IWeChatPayClient wechatPayClient,
IOptions<WeChatPayOptions> options,
ILogger<WeChatPayService> logger)
{
_wechatPayClient = wechatPayClient;
_options = options.Value;
_logger = logger;
}
/// <summary>
/// 创建小程序支付订单
/// </summary>
public async Task<WeChatPayUnifiedOrderResponse> CreateMiniProgramPayment(
string outTradeNo,
decimal amount,
string body,
string openId)
{
var request = new WeChatPayUnifiedOrderRequest
{
AppId = _options.AppId,
MchId = _options.MchId,
NonceStr = Guid.NewGuid().ToString("N"),
Body = body,
OutTradeNo = outTradeNo,
TotalFee = (int)(amount * 100), // 单位:分
SpbillCreateIp = GetClientIp(),
NotifyUrl = _options.NotifyUrl,
TradeType = "JSAPI",
OpenId = openId
};
var response = await _wechatPayClient.UnifiedOrderAsync(request);
if (response.ReturnCode != "SUCCESS" ||
response.ResultCode != "SUCCESS")
{
throw new WeChatPayException(
$"微信支付下单失败:{response.ReturnMsg} - {response.ErrCodeDes}");
}
return response;
}
/// <summary>
/// 获取小程序支付参数
/// </summary>
public WeChatPayMiniProgramPayModel GetMiniProgramPayParams(
string prepayId)
{
var timeStamp = WeChatPayUtility.GetTimestamp();
var nonceStr = Guid.NewGuid().ToString("N");
var paySign = WeChatPayUtility.CreatePaySign(
_options.AppId,
timeStamp,
nonceStr,
$"prepay_id={prepayId}",
_options.Key);
return new WeChatPayMiniProgramPayModel
{
TimeStamp = timeStamp,
NonceStr = nonceStr,
Package = $"prepay_id={prepayId}",
SignType = "MD5",
PaySign = paySign
};
}
/// <summary>
/// 处理支付回调通知
/// </summary>
public async Task<bool> HandleNotify(HttpContext context)
{
var notifyClient = new WeChatPayNotifyClient(_options);
var notify = await notifyClient.GetNotifyAsync(context);
if (notify == null)
return false;
// 验证签名
if (!notifyClient.VerifySign(notify))
{
_logger.LogWarning("微信支付回调签名验证失败");
return false;
}
// 处理业务逻辑
if (notify.ResultCode == "SUCCESS")
{
await _orderService.UpdateOrderStatus(
notify.OutTradeNo,
OrderStatus.Paid,
notify.TransactionId);
}
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# 5. 支付控制器
[Route("api/[controller]")]
[ApiController]
public class PaymentController : ModuleController
{
private readonly AlipayPaymentService _alipayService;
private readonly WeChatPayService _wechatPayService;
public PaymentController(
AlipayPaymentService alipayService,
WeChatPayService wechatPayService)
{
_alipayService = alipayService;
_wechatPayService = wechatPayService;
}
/// <summary>
/// 创建支付订单
/// </summary>
[HttpPost("create")]
public async Task<IResultModel> CreatePayment(
[FromBody] CreatePaymentRequest request)
{
var order = await _orderService.GetOrder(request.OrderId);
if (order == null)
return ResultModel.Error("订单不存在");
if (order.Status != OrderStatus.Pending)
return ResultModel.Error("订单状态不允许支付");
switch (request.PaymentChannel)
{
case PaymentChannel.AlipayQRCode:
var alipayResponse = await _alipayService.CreateQRCodePayment(
order.OrderNo,
order.Amount,
order.Subject,
order.Description);
return ResultModel.Success(new
{
qrCode = alipayResponse.QRCode,
outTradeNo = alipayResponse.OutTradeNo
});
case PaymentChannel.WeChatMiniProgram:
var wechatResponse = await _wechatPayService.CreateMiniProgramPayment(
order.OrderNo,
order.Amount,
order.Subject,
request.OpenId);
var payParams = _wechatPayService.GetMiniProgramPayParams(
wechatResponse.PrepayId);
return ResultModel.Success(payParams);
default:
return ResultModel.Error("不支持的支付方式");
}
}
/// <summary>
/// 支付宝回调通知
/// </summary>
[HttpPost("alipay/notify")]
public async Task<IActionResult> AlipayNotify()
{
var success = await _alipayService.HandleNotify(HttpContext);
if (success)
return Content("success");
else
return Content("fail");
}
/// <summary>
/// 微信支付回调通知
/// </summary>
[HttpPost("wechatpay/notify")]
public async Task<IActionResult> WeChatPayNotify()
{
var success = await _wechatPayService.HandleNotify(HttpContext);
if (success)
return WeChatPayNotifyClient.SuccessResponse();
else
return WeChatPayNotifyClient.FailResponse();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# 🔧 支付提供器对比
# Payment.Alipay(支付宝)
支持功能:
- ✅ 扫码支付(预创建)
- ✅ 手机网站支付
- ✅ 电脑网站支付
- ✅ APP 支付
- ✅ 小程序支付
- ✅ 退款
- ✅ 订单查询
- ✅ 交易关闭
- ✅ 异步通知
签名方式:
- RSA(已不推荐)
- RSA2(推荐)
- 公钥证书(推荐)
# Payment.WeChatPay(微信支付)
支持功能:
- ✅ 公众号支付
- ✅ 小程序支付
- ✅ APP 支付
- ✅ 扫码支付
- ✅ H5 支付
- ✅ 退款
- ✅ 企业付款
- ✅ 异步通知
API 版本:
- V2(旧版,仍广泛使用)
- V3(新版,更安全)
# Payment.Sandpay(杉德支付)
支持功能:
- ✅ 网关支付
- ✅ 快捷支付
- ✅ 代扣
- ✅ 退款
适用场景:
- 银行通道支付
- 特定行业支付需求
# 💡 最佳实践
# 1. 支付安全
public class PaymentSecurityHelper
{
/// <summary>
/// 验证回调 IP 白名单
/// </summary>
public static bool VerifyCallbackIP(string ip, List<string> whitelist)
{
// 支付宝回调 IP 白名单
// 微信支付回调 IP 白名单
return whitelist.Contains(ip);
}
/// <summary>
/// 防止重放攻击
/// </summary>
public static bool VerifyNonce(string nonce, string tradeNo, IMemoryCache cache)
{
var key = $"payment_nonce_{nonce}_{tradeNo}";
if (cache.TryGetValue(key, out _))
return false; // 重复请求
cache.Set(key, true, TimeSpan.FromMinutes(30));
return true;
}
/// <summary>
/// 验证订单金额
/// </summary>
public static bool VerifyAmount(
string orderNo,
decimal notifyAmount,
IOrderService orderService)
{
var order = orderService.GetOrderByNo(orderNo);
return order != null && order.Amount == notifyAmount;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# 2. 幂等性处理
public class PaymentIdempotencyHandler
{
private readonly IMemoryCache _cache;
private readonly ILogger<PaymentIdempotencyHandler> _logger;
public PaymentIdempotencyHandler(
IMemoryCache cache,
ILogger<PaymentIdempotencyHandler> logger)
{
_cache = cache;
_logger = logger;
}
/// <summary>
/// 处理幂等性
/// </summary>
public async Task<bool> HandleAsync(
string tradeNo,
string transactionId,
Func<Task> handler)
{
var key = $"payment_processed_{tradeNo}_{transactionId}";
if (_cache.TryGetValue(key, out _))
{
_logger.LogInformation("支付回调已处理,跳过:{TradeNo}", tradeNo);
return false; // 已处理
}
await handler();
// 标记为已处理(24 小时过期)
_cache.Set(key, true, TimeSpan.FromHours(24));
return true;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 3. 支付日志记录
public class PaymentLogService
{
private readonly ILogger<PaymentLogService> _logger;
public PaymentLogService(ILogger<PaymentLogService> logger)
{
_logger = logger;
}
public void LogPaymentRequest(
string channel,
string orderNo,
decimal amount,
object request)
{
_logger.LogInformation(
"支付请求 - 渠道:{Channel}, 订单:{OrderNo}, 金额:{Amount}, 请求:{@Request}",
channel,
orderNo,
amount,
request);
}
public void LogPaymentCallback(
string channel,
string orderNo,
string tradeNo,
bool success)
{
_logger.LogInformation(
"支付回调 - 渠道:{Channel}, 订单:{OrderNo}, 流水号:{TradeNo}, 成功:{Success}",
channel,
orderNo,
tradeNo,
success);
}
public void LogPaymentError(
string channel,
string orderNo,
Exception ex)
{
_logger.LogError(
ex,
"支付错误 - 渠道:{Channel}, 订单:{OrderNo}",
channel,
orderNo);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# 🔍 常见问题
# Q1: 支付宝证书模式如何配置?
// appsettings.json
{
"Alipay": {
"AppId": "2021001234567890",
"AppPrivateKey": "MIIEvQIBADANBgkqhkiG9w0BAQEFAAOCAQ8A...",
"AppCert": "/path/to/appCertPublicKey.crt",
"AlipayPublicCert": "/path/to/alipayCertPublicKey_RSA2.crt",
"AlipayRootCert": "/path/to/alipayRootCert.crt",
"SignType": "RSA2"
}
}
// 证书获取:
// 1. 登录支付宝开放平台
// 2. 进入"密钥管理"
// 3. 下载应用公钥证书、支付宝公钥证书、支付宝根证书
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Q2: 微信支付证书如何获取?
# 1. 登录微信支付商户平台
# 2. 账户中心 > API 安全 > 申请 API 证书
# 3. 下载证书文件(apiclient_cert.p12)
# 4. 设置证书密码(建议设置为商户号)
// appsettings.json
{
"WeChatPay": {
"AppId": "wx1234567890abcdef",
"MchId": "1234567890",
"Key": "your-api-key-32-chars-long",
"Certificate": "/path/to/apiclient_cert.p12",
"CertificatePassword": "1234567890"
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Q3: 如何处理支付回调超时?
public class PaymentCallbackRetryHandler
{
private readonly ILogger<PaymentCallbackRetryHandler> _logger;
public PaymentCallbackRetryHandler(
ILogger<PaymentCallbackRetryHandler> logger)
{
_logger = logger;
}
/// <summary>
/// 主动查询订单状态(回调超时备用方案)
/// </summary>
public async Task<bool> QueryOrderStatusAsync(
string channel,
string orderNo,
IOrderService orderService)
{
try
{
switch (channel)
{
case "Alipay":
var alipayResponse = await _alipayClient.QueryAsync(orderNo);
return alipayResponse.TradeStatus == "TRADE_SUCCESS";
case "WeChatPay":
var wechatResponse = await _wechatPayClient.QueryAsync(orderNo);
return wechatResponse.TradeState == "SUCCESS";
default:
return false;
}
}
catch (Exception ex)
{
_logger.LogError(ex, "查询订单状态失败:{OrderNo}", orderNo);
return false;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
# 📚 相关文档
# 🔗 参考链接
- 源代码 (opens new window) -
src/Framework/Payment - 支付宝开放平台 (opens new window)
- 微信支付开发文档 (opens new window)
最后更新: 2024-09-20