Shipeng.Payment 4.1.1

dotnet add package Shipeng.Payment --version 4.1.1
                    
NuGet\Install-Package Shipeng.Payment -Version 4.1.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Shipeng.Payment" Version="4.1.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Shipeng.Payment" Version="4.1.1" />
                    
Directory.Packages.props
<PackageReference Include="Shipeng.Payment" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Shipeng.Payment --version 4.1.1
                    
#r "nuget: Shipeng.Payment, 4.1.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Shipeng.Payment@4.1.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Shipeng.Payment&version=4.1.1
                    
Install as a Cake Addin
#tool nuget:?package=Shipeng.Payment&version=4.1.1
                    
Install as a Cake Tool

Shipeng.Payment

Shipeng.Payment 是支付能力集成包,包含两层能力:

  1. 统一支付抽象:面向微信、支付宝、银联、云闪付、银行网关和分账系统提供统一的请求模型、结果模型、Provider 接口和 Provider 工厂。
  2. 微信支付 V3 实现:当前已经落地微信支付 V3 的下单、查单、关单、退款、退款查询、回调验签、回调解密、JSAPI/小程序调起支付参数构建,以及元和分之间的金额转换。

这个包只处理支付基础设施,不处理业务订单、库存、权益、优惠券、发票、会员积分等业务逻辑。业务系统应先创建本地支付单、退款单或分账单,再调用本包请求支付通道;收到回调后,本包只负责通道侧解析和验签,业务状态变更由业务模块自己完成。

安装

dotnet add package Shipeng.Payment --version 4.1.1

适用场景

  • 小程序、公众号、后台管理系统、商城、服务平台需要接入微信支付 V3。
  • SaaS、平台型商城、服务平台需要预留支付宝、银联、云闪付、银行网关等多通道支付扩展点。
  • 分销、服务商、平台商户、供应商结算场景需要抽象分账请求、分账接收方和分账结果。
  • 业务金额以 decimal 元保存,但微信支付接口要求传 int 分。
  • 需要统一封装微信支付签名、证书、APIv3 回调解密和验签。
  • 希望支付能力从核心工具包中独立出来,只有需要支付的项目才引用支付包。

主要能力

统一支付抽象

  • PaymentChannel:支付通道枚举,包含 WeChatAlipayUnionPayCloudQuickPassBank
  • PaymentTradeType:交易场景枚举,包含 Web、App、Native、MiniProgram、JsApi、Barcode、Transfer。
  • PaymentTradeStatus:统一交易状态枚举,屏蔽不同厂商状态名差异。
  • MoneyAmount:金额模型,用最小货币单位保存金额,例如人民币分。
  • PaymentCreateRequest / PaymentCreateResult:统一下单请求和结果。
  • PaymentQueryResult:统一支付查询结果。
  • PaymentRefundRequest / PaymentRefundResult:统一退款请求和结果。
  • PaymentNotifyResult:统一回调解析结果。
  • IPaymentProvider:支付通道统一接口,定义下单、查单、关单、退款、退款查询、回调解析。
  • IPaymentProviderFactory:按 PaymentChannel 获取支付通道实现。
  • IProfitSharingProvider:统一分账接口,定义分账创建、查询和回退。
  • ProfitSharingRequest / ProfitSharingReceiver / ProfitSharingResult:分账请求、接收方和结果模型。

微信支付 V3

  • IWeChatPayService.CreatePayAsync:创建微信支付订单,支持 JSAPI/小程序支付和 Native 扫码支付。
  • IWeChatPayService.QueryByOutTradeNoAsync:根据商户订单号查询支付状态。
  • IWeChatPayService.QueryByTransactionIdAsync:根据微信支付订单号查询支付状态。
  • IWeChatPayService.CloseAsync:关闭未支付订单。
  • IWeChatPayService.RefundAsync:申请退款。
  • IWeChatPayService.QueryRefundByOutRefundNoAsync:根据商户退款单号查询退款状态。
  • IWeChatPayService.ParsePayNotify:解析支付成功回调,只负责验签、解密、反序列化。
  • IWeChatPayService.ParseRefundNotify:解析退款回调,只负责验签、解密、反序列化。
  • IWeChatPayService.VerifyNotifySignature:验证微信支付/退款回调签名。
  • IWeChatPayService.DecryptNotifyResource:使用 APIv3 密钥解密回调 resource。
  • IWeChatPayService.BuildNotifySuccess:构建微信回调成功响应。
  • IWeChatPayService.BuildNotifyFail:构建微信回调失败响应。
  • WeChatPayAmountHelper.ConvertYuanToFen:将业务金额“元”转换为微信支付需要的“分”。
  • WeChatPayAmountHelper.ConvertFenToYuan:将微信支付返回的“分”转换为业务展示常用的“元”。

多通道扩展

  • AlipayPaymentProvider:支付宝通道占位 Provider,应用应替换为对接支付宝 OpenAPI 的具体实现。
  • UnionPayPaymentProvider:银联通道占位 Provider,应用应替换为对接银联接口的具体实现。
  • CloudQuickPassPaymentProvider:云闪付通道占位 Provider,应用应替换为对接云闪付接口的具体实现。
  • BankPaymentProvider:银行网关占位 Provider,应用应替换为具体银行或聚合网关实现。

这些占位 Provider 会明确抛出 NotSupportedException,不会伪造成功结果。这样做是为了避免公共包在没有商户资料、证书、签名规范和验收环境的情况下假装完成厂商接口,反而给使用者造成生产风险。

统一支付抽象用法

注册基础支付工厂:

using Shipeng.Foundation.Payment;

builder.Services.AddShipengPayment();

微信支付可以直接注册并使用:

using Shipeng.Foundation.Payment;

builder.Services.AddWeChatPay(builder.Configuration);

IPaymentProvider provider = paymentProviderFactory.GetProvider(PaymentChannel.WeChat);

注册自己的通道实现:

builder.Services.AddScoped<IPaymentProvider, YourAlipayProvider>();
builder.Services.AddScoped<IPaymentProvider, YourUnionPayProvider>();

业务层按通道下单:

IPaymentProvider provider = paymentProviderFactory.GetProvider(PaymentChannel.Alipay);

PaymentCreateResult payResult = await provider.CreateAsync(new PaymentCreateRequest
{
    Channel = PaymentChannel.Alipay,
    TradeType = PaymentTradeType.Web,
    OutTradeNo = localPayOrder.PayNo,
    Subject = "商城订单",
    Amount = MoneyAmount.Cny(129900),
    NotifyUrl = "https://example.com/api/payment/alipay/notify",
    ReturnUrl = "https://example.com/pay/return"
});

统一退款:

PaymentRefundResult refundResult = await provider.RefundAsync(new PaymentRefundRequest
{
    Channel = PaymentChannel.Alipay,
    OutTradeNo = localPayOrder.PayNo,
    OutRefundNo = localRefundOrder.RefundNo,
    RefundAmount = MoneyAmount.Cny(3000),
    TotalAmount = MoneyAmount.Cny(129900),
    Reason = "用户取消订单"
});

统一分账:

var sharingRequest = new ProfitSharingRequest
{
    Channel = PaymentChannel.WeChat,
    OutTradeNo = localPayOrder.PayNo,
    OutOrderNo = localSharingOrder.SharingNo,
    UnfreezeRemainingAmount = true,
    Receivers =
    {
        new ProfitSharingReceiver
        {
            ReceiverId = "merchant_10001",
            ReceiverName = "服务商户",
            ReceiverType = "MERCHANT_ID",
            Amount = MoneyAmount.Cny(5000),
            Description = "服务费分账"
        }
    }
};

金额转换

微信支付金额单位是分,业务系统通常使用元。不要在业务代码里到处写 (int)(amount * 100),这样会带来四舍五入规则不一致和精度边界问题。

var totalFee = WeChatPayAmountHelper.ConvertYuanToFen(12.345m); // 1235
var refundFee = WeChatPayAmountHelper.ConvertYuanToFen(3.10m);  // 310
var yuan = WeChatPayAmountHelper.ConvertFenToYuan(1235);        // 12.35

WeChatPayAmountHelper.EnsurePositiveFen(totalFee, nameof(totalFee));

ConvertYuanToFen 的规则:

  • 参数单位是元,类型是 decimal
  • 金额不能小于 0。
  • 使用 MidpointRounding.AwayFromZero 四舍五入到分。
  • 转换后的分值不能超过 int.MaxValue
  • 支付和退款请求仍需要大于 0,业务可用 EnsurePositiveFen 做显式校验。

创建支付订单

var request = new CreateWeChatPayRequestModel
{
    outTradeNo = localPayOrder.PayNo,
    description = "农产品商城订单",
    totalFee = WeChatPayAmountHelper.ConvertYuanToFen(localPayOrder.PayAmount),
    openId = userOpenId,
    tradeType = WeChatPayTradeTypeEnum.JsApi
};

CreateWeChatPayDto result = await weChatPayService.CreatePayAsync(request);

// JSAPI/小程序支付:把 result.jsApiPay 返回给前端调起支付。
// Native 扫码支付:把 result.codeUrl 生成二维码给用户扫码。

参数说明:

  • outTradeNo:商户系统内部支付单号,同一个商户号下必须唯一。建议使用本地支付单号,不要直接使用业务订单号。
  • description:商品或订单标题,会展示在微信支付侧。
  • totalFee:支付金额,单位分,必须大于 0。
  • openId:JSAPI/小程序支付必传;Native 扫码支付不需要。
  • tradeType:支付类型,JsApi 用于小程序/公众号,Native 用于扫码支付。

申请退款

var refundRequest = new CreateWeChatRefundRequestModel
{
    outTradeNo = localPayOrder.PayNo,
    outRefundNo = localRefundOrder.RefundNo,
    reason = "用户取消订单",
    refundFee = WeChatPayAmountHelper.ConvertYuanToFen(localRefundOrder.RefundAmount),
    totalFee = WeChatPayAmountHelper.ConvertYuanToFen(localPayOrder.PayAmount),
    notifyUrl = "https://example.com/api/payment/wechat/refund-notify"
};

string refundJson = await weChatPayService.RefundAsync(refundRequest);

退款参数说明:

  • outTradeNo:创建支付订单时传给微信的商户订单号。
  • transactionId:微信支付订单号;如果同时传 transactionIdoutTradeNo,微信优先使用 transactionId
  • outRefundNo:商户退款单号,必须唯一。
  • refundFee:本次退款金额,单位分,必须大于 0。
  • totalFee:原支付订单总金额,单位分,不是剩余可退金额。
  • notifyUrl:退款结果回调地址,可为空;为空时建议主动查退款状态。

回调处理边界

本包的回调方法只做三件事:

  • 验证微信回调签名。
  • 使用 APIv3 密钥解密 resource。
  • 反序列化为支付或退款结果 DTO。

业务模块还必须自己完成:

  • 根据 out_trade_notransaction_id 查询本地支付单。
  • 校验支付单金额、状态、商户号、应用号是否匹配。
  • 使用事务或幂等锁更新本地订单、支付单、库存、权益等业务状态。
  • 处理重复回调,微信回调可能多次到达。
  • 回调处理成功后返回 BuildNotifySuccess();处理失败时返回 BuildNotifyFail(message) 让微信重试。

配置项

WeChatPayOptions 需要至少配置:

  • appId:小程序或公众号 AppId。
  • mchId:微信支付商户号。
  • serialNo:商户 API 证书序列号。
  • privateKeyPath:商户 API 私钥文件路径,支持绝对路径或相对路径。
  • apiV3Key:APIv3 密钥,必须是 32 字节。
  • notifyUrl:支付结果回调地址。
  • platformCertificatePath:微信支付平台证书路径;配置后可验证回调签名。

依赖边界

该包只引用当前模块需要的 NuGet 依赖:

  • Microsoft.Extensions.Options

发布检查

发布前建议执行:

dotnet restore
dotnet build -c Release

确认生成的 Shipeng.Payment.4.1.1.nupkg 中包含 README,且业务项目只在需要支付能力时引用本包。

API Reference / API 索引

nuget.org 当前只会直接渲染包的 READMERelease Notes,不会把包内 docs/API_REFERENCE.md 自动显示成一个独立页面标签。完整公开 API 索引已经随 NuGet 包打入 docs/API_REFERENCE.md,也可以在源码仓库中查看。

如果你正在 NuGet 页面阅读本文,请优先看本 README 的“主要类型”和示例;下载包后可在包内容中打开 docs/API_REFERENCE.md 查看完整公开类型、方法、属性和构造函数签名。

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.1.1 83 6/30/2026
4.1.0 86 6/30/2026

4.1.1 / 2026-06-30

English:
- Split the original monolithic foundation library into focused Shipeng.* NuGet packages so applications can reference only the capabilities they actually need.
- Added Shipeng.DatabaseMaintenance for SQL Server and MongoDB database maintenance. It supports non-destructive cleanup preview, SqlSugar entity scanning, MongoDB collection scanning from configuration or source declarations, keep lists, ignored prefixes, empty-scan protection, missing table preview, controlled SqlSugar CodeFirst table creation, SQL Server schema difference preview, safe missing-column creation, safe changed-column synchronization, explicit execution switches, and confirmation-code protected destructive/schema-changing execution.
- Improved Shipeng.Payment with a unified payment abstraction for WeChat, Alipay, UnionPay, Cloud QuickPass, bank gateways, and profit-sharing scenarios. WeChat Pay V3 remains the concrete built-in implementation; other channels expose stable provider contracts and explicit placeholders so applications can add real vendor SDK implementations without changing business code.
- Centralized common NuGet metadata in Directory.Build.props: target framework, version, authors, repository, license, README, XML documentation, warning policy, and release notes.
- Every package includes README.md, XML IntelliSense documentation, and docs/API_REFERENCE.md inside the generated nupkg.
- Updated README files to explain that nuget.org renders README and Release Notes directly but does not expose packaged docs/API_REFERENCE.md as a separate page tab.
- Release build validation: all projects build and pack successfully for net10.0 with 0 warnings and 0 errors.

中文:
- 将早期单体基础库拆分为职责更清晰的 Shipeng.* NuGet 包,业务项目可以按需引用认证、MongoDB、SqlSugar、EF Core、数据库索引、数据库维护、第三方集成、日志、映射、支付和混合分页能力。
- 新增 Shipeng.DatabaseMaintenance,用于 SQL Server 和 MongoDB 数据库维护。支持冗余表/集合预览清理、SqlSugar 实体扫描、MongoDB 配置集合扫描、源码集合声明扫描、保留名单、忽略前缀、空扫描保护、缺失表预览、受控 CodeFirst 自动建表、SQL Server 结构差异预览、缺失字段补齐、安全字段同步、显式执行开关和确认码保护。
- 增强 Shipeng.Payment,新增统一支付抽象,覆盖微信、支付宝、银联、云闪付、银行网关和分账场景。微信支付 V3 是当前内置可用实现;其他通道提供稳定 Provider 契约和明确占位实现,方便业务项目接入真实厂商 SDK。
- 将公共 NuGet 元数据统一集中到 Directory.Build.props,避免各项目 PropertyGroup 重复和不一致。
- 每个包都打入 README.md、XML IntelliSense 文档和 docs/API_REFERENCE.md。
- 所有 README 都补充说明:nuget.org 会直接显示 README 和 Release Notes,但不会把包内 docs/API_REFERENCE.md 自动显示为独立标签页。
- 已验证 Release 构建和打包,目标框架 net10.0,0 警告,0 错误。