以 Payment 域为例,演示从安装到运行的完整流程。5 分钟内完成一次支付宝下单。
1. 创建项目并安装包
dotnet new web -n MyPaymentAppcd MyPaymentApp
# ① 安装支付宝支付包(含传递依赖:抽象层 + Core + Compatibility + RequestLogging)dotnet add package Bitzsoft.Integrations.Payment.Alipay2. 配置密钥
# ① 密钥不进 Git,用 user-secrets 管理dotnet user-secrets initdotnet user-secrets set "Alipay:AppId" "2021000..."dotnet user-secrets set "Alipay:AppPrivateKey" "MIIEvQIBADANB..."dotnet user-secrets set "Alipay:AlipayPublicKey" "MIIBIjANBg..."dotnet user-secrets set "Alipay:NotifyUrl" "https://your-domain.com/callback/alipay"3. 注册服务
using Bitzsoft.Integrations.Payment;using Bitzsoft.Integrations.Payment.Models;
var builder = WebApplication.CreateBuilder(args);
// ① 注册支付宝支付服务,自动挂载 HttpClient 审计日志builder.Services.AddBitzsoftAlipayPayment(builder.Configuration.GetSection("Alipay"));
var app = builder.Build();
// ② 下单端点app.MapPost("/api/pay", async (IPaymentProvider payment, PaymentOrderRequest request) =>{ // ③ IPaymentProvider 是统一接口——换厂商只改配置,这段代码不动 var result = await payment.CreateOrderAsync(request); return result.IsSuccess ? Results.Ok(result.Data) : Results.BadRequest(new { result.ErrorCode, result.ErrorMessage });});
// ④ 回调端点——支付宝异步通知app.MapPost("/callback/alipay", async (HttpContext ctx, IPaymentProvider payment) =>{ var body = await new StreamReader(ctx.Request.Body).ReadToEndAsync(); var payload = new CallbackPayload { Body = body, QueryString = ctx.Request.QueryString.Value, };
// ⑤ 验证回调签名并解析内容 var result = await payment.VerifyCallbackAsync(payload); if (!result.IsSuccess) return Results.Text("fail");
var data = result.Data!; Console.WriteLine($"订单 {data.OutTradeNo} 支付 {data.PaidAmount / 100m:F2} 元"); return Results.Text("success"); // ① 必须返回 "success",否则支付宝会重复通知});
app.Run();4. 发起支付
# 发起一笔电脑网站支付curl -X POST http://localhost:5000/api/pay \ -H "Content-Type: application/json" \ -d '{ "outTradeNo": "ORDER-20260801-001", "totalAmount": 100, "subject": "测试商品", "scene": "Web" }'响应中的 payUrl 就是支付宝收银台跳转地址,用户扫码或登录后完成支付。
{ "isSuccess": true, "data": { "outTradeNo": "ORDER-20260801-001", "payUrl": "https://openapi.alipay.com/gateway.do?...", "rawResponse": "https://openapi.alipay.com/gateway.do?..." }}5. 查询订单状态
// 查询订单——适合轮询或对账时调用app.MapGet("/api/pay/status/{outTradeNo}", async ( string outTradeNo, IPaymentProvider payment) =>{ var result = await payment.QueryStatusAsync(outTradeNo);
// ① 失败时检查 ErrorCode 和 ErrorMessage if (!result.IsSuccess) return Results.BadRequest(new { result.ErrorCode, result.ErrorMessage });
var data = result.Data!; return Results.Ok(new { data.OutTradeNo, data.TradeNo, Status = data.Status.ToString(), // Success / Pending / Closed data.PaidAmount, // 同样以分为单位 data.PaidAt, });});6. 申请退款
app.MapPost("/api/pay/refund", async (IPaymentProvider payment, RefundRequest request) =>{ // ① 支持全额退款与部分退款(通过 RefundAmount 控制) var result = await payment.RefundAsync(request); return result.IsSuccess ? Results.Ok(result.Data) : Results.BadRequest(new { result.ErrorCode, result.ErrorMessage });});7. 验证结果
# 构建并运行dotnet builddotnet run
# 健康检查(如果你注册了 health checks)curl http://localhost:5000/api/pay/status/ORDER-20260801-001多厂商路由(进阶)
如果同时接入支付宝和微信支付,改用聚合包 + Resolver:
dotnet add package Bitzsoft.Integrations.Payment.All{ "Payment": { "Alipay": { "AppId": "...", "AppPrivateKey": "..." }, "WeChatPay": { "AppId": "...", "MchId": "..." } }}// ① 一行注册全部builder.Services.AddBitzsoftPaymentAll(builder.Configuration);
// ② 注入 Resolver 按需路由app.MapPost("/api/pay/{provider}", async ( string provider, IIntegrationProviderResolver<IPaymentProvider> providers, PaymentOrderRequest request) =>{ // ③ provider 传入 "Alipay" 或 "WeChatPay"(大小写不敏感) var payment = providers.GetRequired(provider); var result = await payment.CreateOrderAsync(request); return result.IsSuccess ? Results.Ok(result.Data) : Results.BadRequest(result.ErrorMessage);});常见问题
| 现象 | 原因 | 处理 |
|---|---|---|
IntegrationProviderResolutionException | Provider ID 不存在或拼写错误 | 检查 provider 参数大小写,确认配置节已写入 |
回调验签失败 SIGN_VERIFY_FAILED | 签名算法或公钥不匹配 | 确认 AlipayPublicKey 是支付宝公钥(不是应用公钥) |
HTTP_ERROR | 网络或网关不可达 | 检查网关地址、网络代理和超时配置 |
| 支付宝重复通知 | 回调未返回 success | 确保回调端点返回纯文本 success |
下一步
- 架构总览:理解三层包模式和依赖链。
- 编码约定:了解命名、Options 和错误处理约定。
- 支付宝实现详解:走读 AlipayPaymentProvider 完整实现。
- 新增厂商 Provider 指南:从零接入一家新厂商。