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


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

    学无止境,精益求精

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

    首先来张API截图

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

    公共访问类:

    namespace PayCommon
    {
        public class WechatConstants
        {
            /// <summary>
            /// 微信V3支付密钥
            /// </summary>
            public const string WxAPIV3SecretKey = "";
            /// <summary>
            /// 微信支付证书路径
            /// </summary>
            public static string WxPayCertPath = AppConfigurtaionUtil.GetConfig("WechatOptions:CertPath");
            /// <summary>
            /// 微信支付Token前缀,使用v3支付api,用curl需要添加请求头,Authorization的类型必须为“WECHATPAY2-SHA256-RSA2048”  [可参考:https://blog.csdn.net/jzd161989/article/details/119868370]
            /// </summary>
            public const string WxPayTokenPrefix = "WECHATPAY2-SHA256-RSA2048";
            /// <summary>
            /// 微信支付加密方式
            /// </summary>
            public const string WxPaySignType = "HMAC-SHA256";
            /// <summary>
            /// 服務商模式 V3支付回調 
            /// </summary>
            public static string WxPayNotifyUrl = "https://portal.one5a.com/WechatPay/Api/V1/FwsV3Pay/WxPayBack";
            /// <summary>
            /// 微信支付Api URL
            /// </summary>
            public static string WxPayUrl = "https://api.mch.weixin.qq.com";
            /// <summary>
            /// 微信支付Api URL V3 jsapi支付 参考官方: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_1.shtml
            /// </summary>
            public static string WxPayOfJsapiUri = "/v3/pay/partner/transactions/jsapi";
            public static string WxPayOfJsapiUrl = $"{WxPayUrl}{WxPayOfJsapiUri}";
            /// <summary>
            /// URL:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_4_1.shtml 微信原生支付
            /// </summary>
            public static string WxPayOfNativeUri = "/v3/pay/partner/transactions/native";
            public static string WxPayOfNativeUrl = $"{WxPayUrl}{WxPayOfNativeUri}";
            /// <summary>
            /// 服务商模式:微信支付分账添加分账接收方 
            /// </summary>
            public static string WxPayOfShareAddReceiverUri = "/pay/profitsharingaddreceiver";
            public static string WxPayOfShareAddReceiverUrl = $"{WxPayUrl}{WxPayOfShareAddReceiverUri}";
            /// <summary>
            /// 微信分账接口
            /// </summary>
            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";
            /// <summary>
            /// 微商城统一下单支付回调URL
            /// </summary>
            public static string WxUnifiedPayNotifyUrl = "https://portal.one5a.com/WechatPay/Api/V1/Pay/WxPayBack";
            /// <summary>
            /// 微信支付退款
            /// </summary>
            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";
            /// <summary>
            /// 微信支付附加信息
            /// </summary>
            public const string OMPayAttach = "";
            public const string OMPayBody = "小程序支付,商城购买";
            /// <summary>
            /// 微信子商户相关参数,商户名称
            /// </summary>
            public const string MerchantName_2 = "";
            /// <summary>
            /// 微信支付服务商模式 子商户商户ID
            /// </summary>
            public const string MerchantId_2 = "";
            /// <summary>
            /// 微信支付 服务商商户名称
            /// </summary>
            public const string MerchantName = "";
            /// <summary>
            /// 微信支付 服务商模式子商户商户ID
            /// </summary>
            public const string MerchantId = "";
            /// <summary>
            /// 微信支付证书序列号
            /// </summary>
            public const string MerchantSerialNo = "66D729C81331C58AFDF7B7470108403C376B9890";
            /// <summary>
            /// 小程序APPID 
            /// </summary>
            public const string MerchantAppId = "";
            /// <summary>
            /// 小程序APP KEY
            /// </summary>
            public const string MerchantAppKey = "";
            /// <summary>
            /// 私钥
            /// </summary>
            public const string MerchantPrivateKey = @"";
    
    
    
    
    
            #region 子商户信息
            /// <summary>
            /// 子商户信息 分账接收方
            /// </summary>
            public static string zsfwsMchName = "";
            public static string fwsMchId = ""; //服务商商户ID   
            public static string fwsAppId  = ""; //服务器小程序APPID  
            public static string fwsAppSecret = "";//App密钥 
            #endregion
    
          
        }
    }
    View Code

    支付代码片段

    namespace PayCommon
    {
        public class WxPayExternal  
        {
            /// <summary>
            /// 微信支付 原生支付
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            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<NativePayResponse>(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));
                }
            }
    
            /// <summary>
            /// 服务商模式 分账相关
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            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 = $@"<xml>
                   <appid>{appid}</appid>
                   <mch_id>{mchid}</mch_id>
                   <sub_appid>{request.sub_appid}</sub_appid>
                   <sub_mch_id>{request.sub_mchid}</sub_mch_id>
                   <nonce_str>{nonce}</nonce_str> 
                   <out_order_no>{request.out_trade_no}</out_order_no>
                   <transaction_id>{request.transaction_id}</transaction_id>
                   <sign>{sign}</sign>
                   <sign_type>{WechatConstants.WxPaySignType}</sign_type>
                   <receivers>{receiversString}</receivers>
                </xml>";
                return HttpHelper.PostWithCert<ShareProfitResponse>(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 = $@"<xml>
       <mch_id>{mchid}</mch_id>
       <sub_mch_id>{request.sub_mchid}</sub_mch_id>
       <appid>{appid}</appid>
       <sub_appid>{request.sub_appid}</sub_appid>
       <nonce_str>{nonce}</nonce_str> 
       <sign>{sign}</sign>
       <sign_type>{WechatConstants.WxPaySignType}</sign_type>
       <receiver>{receiverJson}</receiver>
    </xml>";
                return HttpHelper.PostWithCert<ShareAddReciverReturnData>(WechatConstants.WxPayOfShareAddReceiverUrl, body);
            }
    
            /// <summary>
            /// JSAPI 预支付
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            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<JsApiPayResponse>(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;
            }
    
            /// <summary>
            /// 生成预支付信息
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            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<UnifiedPayResponse>(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;
            }
    
            /// <summary>
            /// 添加分账接收子商户
            /// </summary>
            /// <param name="receiver"></param>
            /// <returns></returns>
            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<UnifiedAddReceiveResult>(responseStr);
                }
                return result;
            }
    
            /// <summary>
            /// 分账相关
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            public static ShareProfitResponse UnifiedShareProfit(UnifiedShareProfitRequest request)
            {
                request.appid = WechatConstants.CustomerAppId;
                request.mch_id = WechatConstants.CustomerMchId;
                request.GenerateSign();
                return HttpHelper.PostWithCert<ShareProfitResponse>(WechatConstants.WxPayOfShareProfitUrl,
                    XmlHelper.ObjectToXML(request), WechatConstants.WxUnifiedPayCertPath, WechatConstants.CustomerMchId);
            }
    
            /// <summary>
            /// 需要证书
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            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<UnifiedRefundResponse>(WechatConstants.WxUnifiedPayOfRefundUrl,
                    XmlHelper.ObjectToXML(request), WechatConstants.WxUnifiedPayCertPath, WechatConstants.CustomerMchId);
            }
    
            /// <summary>
            /// 退款
            /// </summary>
            /// <param name="request"></param>
            /// <returns></returns>
            public static RefundResponse Refund(RefundRequest request)
            {
                request.notify_url = WechatConstants.WxRefundNotifyUrl;
                var requestBody = request.ToJson();
                var authInfo = BuildAuthAsync(WechatConstants.WxPayOfRefundUri, requestBody);
                return HttpHelper.PostWithToken<RefundResponse>(WechatConstants.WxPayOfRefundUrl, requestBody, GetToken(authInfo.Auth));
            }
        }
    }
    View Code

    项目架构

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

    @天才卧龙的博客

  • 相关阅读:
    solr开发从查询结果集中获取对象数据
    solr开发,提交索引数据的几种方式
    初识SolrJ开发, schema.xml的配置与服务初始化.
    实例介绍,如何在开发中将各层日志归类输出.
    springmvc整合redis架构搭建实例
    面试求职中你需要了解的Java面向对象
    整合Solr到Tomcat服务器,并配置IK分词
    formValidator输入验证、异步验证实例 + licenseImage验证码插件实例应用
    SpringMVC整合Mongodb开发,高级操作
    SpringMVC整合Mongodb开发 架构搭建
  • 原文地址:https://www.cnblogs.com/chenwolong/p/wxpay.html
Copyright © 2020-2023  润新知