支付宝官方SDK不支持.NET 6+,因强依赖System.Web和旧版HttpContext;应改用HTTP客户端手动签名,注意参数排序、UTF-8编码、PKCS#8私钥及异步通知验签规范。

支付宝 SDK 官方不支持 .NET 6+ 的新项目类型
支付宝目前只维护了基于 net45 和早期 netcoreapp2.1 的 SDK(如 AlipaySDKNet),直接在 .NET 6/7/8 Web API 或 Minimal Hosting 模式下引用会报 Could not load file or assembly 'System.Web' 等错误。这不是你代码写错了,是 SDK 底层强依赖旧版 ASP.NET 生命周期和 HttpContext.Current。
实操建议:
- 放弃官方 SDK,改用轻量 HTTP 客户端手动签名——核心就三步:拼参数、排序、RSA2 签名
- 用
Alipay.AopSdk.Core的源码(GitHub 上有社区维护的 .NET Standard 分支),但注意它仍需自己补IHttpContextAccessor注入逻辑 - 若必须用 SDK,降级到
net6.0+Microsoft.AspNetCore.Mvc传统控制器模式(非 Minimal API),并启用兼容模式:services.AddControllersWithViews().AddNewtonsoftJson()
生成支付宝支付 URL 必须手动处理 sign 参数
支付宝网页支付(alipay.trade.page.pay)和扫码支付(alipay.trade.precreate)都要求所有业务参数 + 公共参数(app_id、method、format、charset、sign_type、timestamp、version)一起参与签名,漏一个或顺序错,返回 INVALID_PARAMETER 或 SIGNATURE_ERROR。
常见错误现象:
- URL 打开后提示“订单信息无效”,实际是
sign不对,不是金额或商品名填错了 - 本地调试正常,上线后失败——因为服务器时区/时间不同步导致
timestamp超过 15 分钟有效期 - 中文商品名没做
UTF-8编码再签名,导致验签失败
关键点:
- 签名前必须把所有参数按 key 字典序升序排列,拼成
key=value&key=value字符串(value 要UrlEncode) - 私钥用 PKCS#8 格式(不是 PKCS#1),OpenSSL 转换命令:
openssl pkcs8 -topk8 -inform PEM -in app_private_key.pem -outform PEM -nocrypt - 别用
HttpUtility.UrlEncode,它默认用系统编码;统一用Uri.EscapeDataString(value, Encoding.UTF8)
扫码收款返回的 qr_code 字段不能直接当图片 src
支付宝 alipay.trade.precreate 接口返回的是一个字符串格式的二维码内容(如 https://qr.alipay.com/xxx),不是图片二进制流,也不是 base64 图片。前端直接塞进 <img src="..." alt="C#怎么实现支付宝支付接口 C#如何对接支付宝API实现网页支付和扫码收款功能【支付】" > 会 404。
使用场景:
- 你得用前端 JS 库(如
qrcode.js)把qr_code字符串渲染成 canvas 或 img 元素 - 服务端也可以用
QrCode.Net或SkiaSharp生成 PNG 流返回给前端,但没必要——增加 IO 和带宽 - 别在后端拼 HTML 返回,微信/支付宝 App 内嵌浏览器不认自定义样式,扫码体验差
性能影响:
- 每次请求都调
alipay.trade.precreate生成新二维码,但支付宝限制单笔订单 2 小时内只能创建一次,重复调用返回旧结果,不会刷新 - 如果用户扫码后未付款,2 小时后该二维码自动失效,需重新调接口获取新
qr_code
异步通知(notify_url)必须严格校验签名且只返回 success
支付宝发来的 POST 通知里,所有字段都是字符串,包括 total_amount、out_trade_no,而且参数顺序完全随机。如果你用模型绑定(如 [FromForm])直接映射,sign 字段会被忽略或错位,导致验签失败。
实操建议:
- 用
Request.Form.Keys遍历全部键值对,过滤掉sign和sign_type,其余参与验签 - 验签前必须把 value 原样传入(不能 Trim、不能 ToLower、不能 JSON 序列化后再比)
- 通知地址必须是公网可访问的 HTTPS 接口,且响应体**只能是纯文本
success**(无空格、无换行、无 HTML 标签),否则支付宝会反复重发 - 务必记录原始通知日志(
Request.Body流),否则出问题根本没法对账
容易被忽略的地方:支付宝的通知可能延迟几分钟甚至更久,你的数据库事务不能卡在「收到通知才更新订单状态」——要先查订单是否已支付,避免重复处理。



















