netCore 接入微信支付<小程序,APP,H5>,内含普通支付,微信V3支付,服务商模式【支付,支付回写,退款,分账给个人,服务商模式支付,服务商模式支付回写,服务商模式分账给子商户,


十年河东,十年河西,莫欺少年穷

学无止境,精益求精

项目下载地址:https://download.csdn.net/download/bbwolong/82007689

首先来张API截图

 然后简单分享下代码片段:

公共访问类:

namespace PayCommon
{
    public class WechatConstants
    {
        /// 
        /// 微信V3支付密钥
        /// 
        public const string WxAPIV3SecretKey = "";
        /// 
        /// 微信支付证书路径
        /// 
        public static string WxPayCertPath = AppConfigurtaionUtil.GetConfig("WechatOptions:CertPath");
        /// 
        /// 微信支付Token前缀,使用v3支付api,用curl需要添加请求头,Authorization的类型必须为“WECHATPAY2-SHA256-RSA2048”  [可参考:https://blog.csdn.net/jzd161989/article/details/119868370]
        /// 
        public const string WxPayTokenPrefix = "WECHATPAY2-SHA256-RSA2048";
        /// 
        /// 微信支付加密方式
        /// 
        public const string WxPaySignType = "HMAC-SHA256";
        /// 
        /// 服務商模式 V3支付回調 
        /// 
        public static string WxPayNotifyUrl = "https://portal.one5a.com/WechatPay/Api/V1/FwsV3Pay/WxPayBack";
        /// 
        /// 微信支付Api URL
        /// 
        public static string WxPayUrl = "https://api.mch.weixin.qq.com";
        /// 
        /// 微信支付Api URL V3 jsapi支付 参考官方: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_1.shtml
        /// 
        public static string WxPayOfJsapiUri = "/v3/pay/partner/transactions/jsapi";
        public static string WxPayOfJsapiUrl = $"{WxPayUrl}{WxPayOfJsapiUri}";
        /// 
        /// URL:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_1.shtml 微信原生支付
        /// 
        public static string WxPayOfNativeUri = "/v3/pay/partner/transactions/native";
        public static string WxPayOfNativeUrl = $"{WxPayUrl}{WxPayOfNativeUri}";
        /// 
        /// 服务商模式:微信支付分账添加分账接收方 
        /// 
        public static string WxPayOfShareAddReceiverUri = "/pay/profitsharingaddreceiver";
        public static string WxPayOfShareAddReceiverUrl = $"{WxPayUrl}{WxPayOfShareAddReceiverUri}";
        /// 
        /// 微信分账接口
        /// 
        public static string WxPayOfShareProfitUri = "/secapi/pay/profitsharing";
        public static string WxPayOfShareProfitUrl = $"{WxPayUrl}{WxPayOfShareProfitUri}";
        //对应微信地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
        public static string WxPayOfUnifiedUrl = $"{WxPayUrl}/pay/unifiedorder";
        //写在配置文件内的AppID是小程序APPID --有商户平台关联
        public static string CustomerAppId = "";
        //写在配置文件内的MchId是商户的 MchId 
        public static string CustomerMchId = "";
        //商户平台Api密钥
        public static string CustomerKey = "";
       //微商城退款需要证书,证书路径 
        public static string WxUnifiedPayCertPath = @"xxx\apiclient_cert.p12";
        /// 
        /// 微商城统一下单支付回调URL
        /// 
        public static string WxUnifiedPayNotifyUrl = "https://portal.one5a.com/WechatPay/Api/V1/Pay/WxPayBack";
        /// 
        /// 微信支付退款
        /// 
        public static string WxUnifiedRefundNotifyUrl = "https://portal.one5a.com/WechatPay/Api/V1/Pay/WxRefundBack";//todo
        public static string WxUnifiedPayOfRefundUrl = $"{WxPayUrl}/secapi/pay/refund";
        public static string WxPayOfRefundUri = "/v3/refund/domestic/refunds";
        public static string WxPayOfRefundUrl = $"{WxPayUrl}{WxPayOfRefundUri}";
        public static string WxRefundNotifyUrl = "https://portal.one5a.com/WechatPay/Api/V1/FwsV3Pay/RefundBack";
        /// 
        /// 微信支付附加信息
        /// 
        public const string OMPayAttach = "";
        public const string OMPayBody = "小程序支付,商城购买";
        /// 
        /// 微信子商户相关参数,商户名称
        /// 
        public const string MerchantName_2 = "";
        /// 
        /// 微信支付服务商模式 子商户商户ID
        /// 
        public const string MerchantId_2 = "";
        /// 
        /// 微信支付 服务商商户名称
        /// 
        public const string MerchantName = "";
        /// 
        /// 微信支付 服务商模式子商户商户ID
        /// 
        public const string MerchantId = "";
        /// 
        /// 微信支付证书序列号
        /// 
        public const string MerchantSerialNo = "66D729C81331C58AFDF7B7470108403C376B9890";
        /// 
        /// 小程序APPID 
        /// 
        public const string MerchantAppId = "";
        /// 
        /// 小程序APP KEY
        /// 
        public const string MerchantAppKey = "";
        /// 
        /// 私钥
        /// 
        public const string MerchantPrivateKey = @"";





        #region 子商户信息
        /// 
        /// 子商户信息 分账接收方
        /// 
        public static string zsfwsMchName = "";
        public static string fwsMchId = ""; //服务商商户ID   
        public static string fwsAppId  = ""; //服务器小程序APPID  
        public static string fwsAppSecret = "";//App密钥 
        #endregion

      
    }
}

支付代码片段

namespace PayCommon
{
    public class WxPayExternal  
    {
        /// 
        /// 微信支付 原生支付
        /// 
        /// 
        /// 
        public static NativePayResponse NativePrePay(NativePayRequest request)
        {
            NativePayResponse result = null;
            request.sp_appid = WechatConstants.MerchantAppId;
            request.sp_mchid = WechatConstants.MerchantId;
            request.notify_url = WechatConstants.WxPayNotifyUrl;
            request.settle_info = new NativePaySettle
            {
                profit_sharing = true
            };
            var requestBody = request.ToJson();
            var authInfo = BuildAuthAsync(WechatConstants.WxPayOfNativeUri, requestBody);
            result = HttpHelper.PostWithToken(WechatConstants.WxPayOfNativeUrl, requestBody, GetToken(authInfo.Auth));
            return result;
        }

        private static SignInfo BuildAuthAsync(string uri, string body)
        {
            var method = "POST";
            var info = new SignInfo
            {
                timeStamp = DateTimeOffset.Now.ToUnixTimeSeconds().ToString(),
                nonceStr = Path.GetRandomFileName(),
            };

            string message = $"{method}\n{uri}\n{info.timeStamp}\n{info.nonceStr}\n{body}\n";
            var signedValue = Sign(message);
            info.Auth = $"mchid=\"{WechatConstants.MerchantId}\",nonce_str=\"{info.nonceStr}\",timestamp=\"{info.timeStamp}\",serial_no=\"{WechatConstants.MerchantSerialNo}\",signature=\"{signedValue}\"";
            return info;
        }

        private static string GetToken(string auth)
        {
            return $"{WechatConstants.WxPayTokenPrefix} {auth}";
        }

        private static string Sign(string message)
        {
            string privateKey = WechatConstants.MerchantPrivateKey;
            byte[] keyData = Convert.FromBase64String(privateKey);
            using (CngKey cngKey = CngKey.Import(keyData, CngKeyBlobFormat.Pkcs8PrivateBlob))
            using (RSACng rsa = new RSACng(cngKey))
            {
                byte[] data = System.Text.Encoding.UTF8.GetBytes(message);
                return Convert.ToBase64String(rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
            }
        }

        /// 
        /// 服务商模式 分账相关
        /// 
        /// 
        /// 
        public static ShareProfitResponse ShareProfit(ShareProfitRequest request)
        {
            var result = new ShareProfitResponse();
            var receivers = new ReceiverInfo[] {//分账接收方列表
                            new ReceiverInfo
                            {
                                account = WechatConstants.MerchantId,
                                name = WechatConstants.MerchantName,
                                amount = request.amount,
                                description = "分给商户"+WechatConstants.MerchantName
                            }
                            ,
                              new ReceiverInfo
                            {
                                account = WechatConstants.fwsMchId,
                                name = WechatConstants.zsfwsMchName,
                                amount = request.amount,
                                description = "分给商户"+WechatConstants.zsfwsMchName
                            }
                        };
            foreach (var receiver in receivers)
            {
                var receiverResult = AddReceiver(request, receiver);
                if (receiverResult.IsNull() || !receiverResult.IsSuccess)
                {
                    return result.Fail("微信分账添加接收方失败");
                }
            }
            var receiversString = receivers.ToJson();
            var nonce = Path.GetRandomFileName();
            var appid = WechatConstants.MerchantAppId;
            var mchid = WechatConstants.MerchantId;
            var appKey = WechatConstants.MerchantAppKey;
            string strA = $"appid={appid}&mch_id={mchid}"
                + $@"&nonce_str={nonce}&out_order_no={request.out_trade_no}&receivers={receiversString}&sign_type={WechatConstants.WxPaySignType}"
                + $@"&sub_appid={request.sub_appid}&sub_mch_id={request.sub_mchid}&transaction_id={request.transaction_id}&key={appKey}";
            string sign = WxPayHelper.HmacSHA256(strA, appKey).ToUpper();//签名
            var body = $@"
               {appid}
               {mchid}
               {request.sub_appid}
               {request.sub_mchid}
               {nonce} 
               {request.out_trade_no}
               {request.transaction_id}
               {sign}
               {WechatConstants.WxPaySignType}
               {receiversString}
            ";
            return HttpHelper.PostWithCert(WechatConstants.WxPayOfShareProfitUrl, body);
        }

        private static ShareAddReciverReturnData AddReceiver(ShareProfitRequest request, ReceiverInfo receiver)
        {
            var nonce = Path.GetRandomFileName();
            var receiverJson = receiver.ToJson();
            var appid = WechatConstants.MerchantAppId;
            var mchid = WechatConstants.MerchantId;
            //签名算法
            string strA = $@"appid={appid}&mch_id={mchid}"
                + $@"&nonce_str={nonce}&receiver={receiverJson}&sign_type={WechatConstants.WxPaySignType}"
                + $@"&sub_appid={request.sub_appid}&sub_mch_id={request.sub_mchid}&key={WechatConstants.MerchantAppKey}";
            string sign = WxPayHelper.HmacSHA256(strA, WechatConstants.MerchantAppKey).ToUpper();//签名

            var body = $@"
   {mchid}
   {request.sub_mchid}
   {appid}
   {request.sub_appid}
   {nonce} 
   {sign}
   {WechatConstants.WxPaySignType}
   {receiverJson}
";
            return HttpHelper.PostWithCert(WechatConstants.WxPayOfShareAddReceiverUrl, body);
        }

        /// 
        /// JSAPI 预支付
        /// 
        /// 
        /// 
        public static SignInfo JsApiPrePay(JsApiPayRequest request)
        {
            request.sp_appid = WechatConstants.MerchantAppId;
            request.sp_mchid = WechatConstants.MerchantId;
            request.notify_url = WechatConstants.WxPayNotifyUrl;
            if (request.settle_info.IsNull())
            {
                //是否分账
                request.settle_info = new JsApiPaySettle
                {
                    profit_sharing = true
                };
            }
            var requestBody = request.ToJson();
            var authInfo = BuildAuthAsync(WechatConstants.WxPayOfJsapiUri, requestBody);
            authInfo.OutTradNo = request.out_trade_no;
            var response = HttpHelper.PostWithToken(WechatConstants.WxPayOfJsapiUrl, requestBody, GetToken(authInfo.Auth));
            Asserts.Assert(response.NotNull() && response.code.IsNullOrWhiteSpace(), response?.message ?? "");
            //参考 JSAPI调起支付API  https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_1_4.shtml
            authInfo.package = $"prepay_id={response.prepay_id}";
            authInfo.paySign = Sign($"{request.sub_appid}\n{authInfo.timeStamp}\n{authInfo.nonceStr}\n{authInfo.package}\n");
            return authInfo;
        }

        /// 
        /// 生成预支付信息
        /// 
        /// 
        /// 
        public static UnifiedPayResult UnifiedPrePay(UnifiedPayRequest request)
        {
            UnifiedPayResult result = null;
            request.appid = WechatConstants.CustomerAppId;
            request.mch_id = WechatConstants.CustomerMchId;
            request.notify_url = WechatConstants.WxUnifiedPayNotifyUrl;
            request.GenerateSign();
            var responseStr = HttpHelper.Post(WechatConstants.WxPayOfUnifiedUrl, XmlHelper.ObjectToXML(request));
            if (responseStr.NotNullOrWhiteSpace())
            {
                var response = XmlHelper.XMLToObject(responseStr);
                if (response.IsSuccess)
                {
                    var time = TimeHelper.GetTimestamp().ToString();
                    result = new UnifiedPayResult
                    {
                        nonceStr = request.nonce_str,
                        timeStamp = time,
                        package = $"prepay_id={response.prepay_id}",
                        paySign = WxPayHelper.MD5($"appId={request.appid}&nonceStr={request.nonce_str}&package=prepay_id={response.prepay_id}&signType=MD5&timeStamp={time}&key={WechatConstants.CustomerKey}")
                    };
                }
            }
            return result;
        }

        /// 
        /// 添加分账接收子商户
        /// 
        /// 
        /// 
        public static UnifiedAddReceiveResult UnifiedAddReceiver(WXReceiver receiver)
        {
            UnifiedAddReceiveResult result = null;
            var request = new UnifiedAddReceiverRequest
            {
                appid = WechatConstants.CustomerAppId,
                mch_id = WechatConstants.CustomerMchId,
                receiver = receiver.ToJson()
            };
            request.GenerateSign();
            var responseStr = HttpHelper.Post(WechatConstants.WxPayOfShareAddReceiverUrl, XmlHelper.ObjectToXML(request));
            if (responseStr.NotNullOrWhiteSpace())
            {
                result = XmlHelper.XMLToObject(responseStr);
            }
            return result;
        }

        /// 
        /// 分账相关
        /// 
        /// 
        /// 
        public static ShareProfitResponse UnifiedShareProfit(UnifiedShareProfitRequest request)
        {
            request.appid = WechatConstants.CustomerAppId;
            request.mch_id = WechatConstants.CustomerMchId;
            request.GenerateSign();
            return HttpHelper.PostWithCert(WechatConstants.WxPayOfShareProfitUrl,
                XmlHelper.ObjectToXML(request), WechatConstants.WxUnifiedPayCertPath, WechatConstants.CustomerMchId);
        }

        /// 
        /// 需要证书
        /// 
        /// 
        /// 
        public static UnifiedRefundResponse UnifiedRefund(UnifiedRefundRequest request)
        {
            request.appid = WechatConstants.CustomerAppId;
            request.mch_id = WechatConstants.CustomerMchId;
            request.notify_url = WechatConstants.WxUnifiedRefundNotifyUrl;
            request.GenerateSign();
            return HttpHelper.PostWithCert(WechatConstants.WxUnifiedPayOfRefundUrl,
                XmlHelper.ObjectToXML(request), WechatConstants.WxUnifiedPayCertPath, WechatConstants.CustomerMchId);
        }

        /// 
        /// 退款
        /// 
        /// 
        /// 
        public static RefundResponse Refund(RefundRequest request)
        {
            request.notify_url = WechatConstants.WxRefundNotifyUrl;
            var requestBody = request.ToJson();
            var authInfo = BuildAuthAsync(WechatConstants.WxPayOfRefundUri, requestBody);
            return HttpHelper.PostWithToken(WechatConstants.WxPayOfRefundUrl, requestBody, GetToken(authInfo.Auth));
        }
    }
}

项目架构

 下载地址:https://download.csdn.net/download/bbwolong/82007689

@天才卧龙的博客