0


微信公众号、微信小程序使用JsApi支付方式,前端vue+后端c#,详细介绍

微信支付有多种方式,本文章主要介绍JsApi支付,前端调用使用的是vue,后端使用的是c# webapi,后端使用了插件Senparc.Weixin.TenPayV3。

开发工具:
前端:hbuilder
后端:Visual Studio 2022

注意:
小程序和公众号区别:
1、后端配置global.json的时候,Appid用对应平台上申请的
2、后端代码没有什么区别
3、vue在生成预付订单后,调起手机支付输入密码页面有区别,由于开发工具用的是Hbuilder,小程序支付可以直接用官方的wx.requestPayment,公众号不支持这种写法,所以稍微有一点点区别,公众号直接用微信公众号官方方法就可以了,下文中有贴出代码。

微信商户平台配置
在微信商户平台开通JsApi接口
在这里插入图片描述

支付授权目录设置,注意路径要到你api的实际路径,不要只写到域名

在这里插入图片描述
API安全设置(后端配置需要TenPayV3_Key、TenPayV3_PrivateKey、TenPayV3_SerialNumber,都是在此页面设置的)
在这里插入图片描述

后端配置
我后端开发用的是Visual Studio 2022,要安装插件Senparc.Weixin.TenPayV3(盛派开发的)
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/2f6b7c4f0952467887b21a62df9c58bf.png

配置global.json

//Senparc.Weixin SDK 设置"SenparcWeixinSetting":{//以下为 Senparc.Weixin 的 SenparcWeixinSetting 微信配置//微信全局"IsDebug":true,//微信支付V3(新版)"TenPayV3_AppId":"xxxxxxxxx",// "TenPayV3_AppSecret":"xxxxxxxxx","TenPayV3_MchId":"xxxxxx",//商户号"TenPayV3_TenpayNotify":"http://cd.xxxxxxxxx.com/PayNotifyUrl",//支付成功后的回调"TenPayV3_PrivateKey":"xxxx....",//(新)证书私钥(在证书文件夹中,很长一串,自己去复制)"TenPayV3_SerialNumber":"xxxx...",//证书序列号(在商户平台申请证后,复制过来)"TenPayV3_ApiV3Key":"xxxxxxxxx",//(新)APIv3 密钥 跟上面的TenPayV3_Key填同一个},

在program.cs要注册Senparc,代码如下
先添加引用

usingSenparc.Weixin.AspNet;usingSenparc.Weixin.AspNet.RegisterServices;usingSenparc.Weixin.Entities;usingSenparc.Weixin.RegisterServices;usingSenparc.Weixin.TenPayV3;

继续在program.cs中添加注册代码

//Senparc.Weixin 注册(必须)
builder.Services.AddSenparcWeixinServices(builder.Configuration);var app = builder.Build();var senparcWeixinSetting = app.Services.GetService<IOptions<SenparcWeixinSetting>>()!.Value;//启用微信配置(必须)var registerService = app.UseSenparcWeixin(app.Environment,null/* 不为 null 则覆盖 appsettings  中的 SenpacSetting 配置*/,null/* 不为 null 则覆盖 appsettings  中的 SenpacWeixinSetting 配置*/,
    register =>{},(register, weixinSetting)=>{//注册公众号信息(可以执行多次,注册多个小程序)
        register.RegisterTenpayApiV3(weixinSetting,"【xxx项目名称】微信支付(ApiV3)");//自定义一个名字});

支付流程
1、前端vue调用后端api,生成一条状态为待支付的数据
2、待支付订单生成结果返回到前端,前端发起支付,跳转输入密码界面
3、输入密码成功付款后,自动触发后端支付成功回调函数,修改支付状态

vue(公众号)


```html
            //生成订单预支付信息
            Recharge() {
                let that = this
                var recharge = {
                    virtual_card_number: '123',
                    phone: this.memberinfo.phone,
                    recharge_money: this.renew_money,
                    recharge_type: this.renew_type,
                    openid: uni.getStorageSync('open_id')
                }//传输到后端api的参数,根据自己项目修改
                    get_prepay_id(recharge).then(res => {
                        this.prepay_result = res.data.data
                        if (typeof WeixinJSBridge == "undefined") {
                            if (document.addEventListener) {
                                document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
                            } else if (document.attachEvent) {
                                document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
                                document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
                            }
                        } else {
                            this.onBridgeReady();
                        }
                    })
        
            },
    onBridgeReady() {
          let that=this
          WeixinJSBridge.invoke(
            'getBrandWCPayRequest', {
                     "appId":that.prepay_result.appId ,   //公众号ID,由商户传入
                     "timeStamp":that.prepay_result.timeStamp,   //时间戳,自1970年以来的秒数    
                     "nonceStr": that.prepay_result.nonceStr,      //随机串    
                     "package": that.prepay_result.package,
                     "signType": that.prepay_result.signType,     //微信签名方式:    
                     "paySign":  that.prepay_result.paySign//微信签名
            },
            function(res){
              console.log('this.prepay_result',that.prepay_result)
              if(res.err_msg == "get_brand_wcpay_request:ok" ){
                // 使用者支付成功
                alert('支付成功');
              } else if(res.err_msg == "get_brand_wcpay_request:fail" ){
                // 使用者支付失败
                alert('支付失败');
              }
            }
          );
        }```

**
vue(小程序)

Recharge() {
                let that = this
                var recharge = {
                    virtual_card_number: '123',
                    phone: this.memberinfo.phone,
                    recharge_money: this.renew_money,
                    recharge_type: this.renew_type,
                    openid: uni.getStorageSync('open_id')
                }//传输到后端api的参数,根据自己项目修改
                    get_prepay_id(recharge).then(res => {
                            var  result = res.data.data
                            wx.requestPayment({
                            timeStamp: result.timeStamp,
                            nonceStr: result.nonceStr,
                            package: result.package,
                            signType: result.signType,
                            paySign: result.paySign,
                            success(res) {
                                console.log('支付成功', res)
                            },
                            fail(res) {
                                console.log('支付失败', res)
                            }
                        })
                    })
        
            },

**后端 WebApi
生成预支付订单

/// <summary>/// JsApi支付/// </summary>/// <param name="record">订单信息</param>/// <returns></returns>//发布到服务器iis时,选择应用池-鼠标右键–>高级设置–>进程模型–>加载用户配置文件–>设置为truepublicasyncTask<ApiReturnValue>GetPrepayid(c_recharge_record record){ApiReturnValue<wx_pay_param> apiresult =newApiReturnValue<wx_pay_param>();try{string HostIp ="xxxx.xx.xx.xxx";//生成订单10位序列号,此处用时间和随机数生成,商户根据自己调整,保证唯一record.sp_billno ="cz_"+SystemTime.Now.ToString("yyyyMMddHHmmss");record.recharge_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");var body ="智慧停车充值";int price =record.recharge_money*100;//单位:分//int price =1;//单位:分var basePayApis =newSenparc.Weixin.TenPayV3.Apis.BasePayApis(Config.SenparcWeixinSetting);var requestData =newSenparc.Weixin.TenPayV3.Apis.BasePay.TransactionsRequestData(Config.SenparcWeixinSetting.TenPayV3_AppId, Config.SenparcWeixinSetting.TenPayV3_MchId, body,record.sp_billno,newSenparc.Weixin.TenPayV3.Entities.TenpayDateTime(SystemTime.Now.AddMinutes(120).DateTime,false), HostIp, Config.SenparcWeixinSetting.TenPayV3_TenpayNotify,null,new(){ currency ="CNY", total = price },new(record.openid),null,null,null);var result =await basePayApis.JsApiAsync(requestData);if(result.ResultCode.Success ==true){var packageStr ="prepay_id="+ result.prepay_id;var jsApiUiPackage = TenPaySignHelper.GetJsApiUiPackage(Config.SenparcWeixinSetting.TenPayV3_AppId, result.prepay_id);wx_pay_param param =newwx_pay_param{
                 prepay_id = result.prepay_id,//预付_id
                 appId = Config.SenparcWeixinSetting.TenPayV3_AppId,//appId
                 timeStamp = jsApiUiPackage.Timestamp,//时间戳
                 nonceStr = jsApiUiPackage.NonceStr,//随机字符串,长度为32个字符以下
                 package = packageStr,// 统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id = ***
                 signType ="RSA",// 签名算法,应与后台下单时的值一致
                 paySign = jsApiUiPackage.Signature//签名};//插入一条订单
             DB.Insertable(record).ExecuteCommand();
             apiresult.data = param;}else{
             apiresult.code =500;
             apiresult.message = result.ResultCode.ErrorCode.ToString()+ result.ResultCode.ErrorMessage + result.ResultCode.Solution;}}catch(Exception ex){
         apiresult.code =500;
         apiresult.message = ex.Message;}return apiresult;}

支付回调函数

//支付成功后的回调[HttpPost("PayNotifyUrl")]publicasyncTask<ApiReturnValue>PayNotifyUrl(){ApiReturnValue api_result =newApiReturnValue();try{//获取微信服务器异步发送的支付通知信息var resHandler =newTenPayNotifyHandler(HttpContext);var orderReturnJson =await resHandler.AesGcmDecryptGetObjectAsync<OrderReturnJson>();//记录日志
          Senparc.Weixin.WeixinTrace.SendCustomLog("PayNotifyUrl 接收到消息", orderReturnJson.ToJson(true));//演示记录 transaction_id,实际开发中需要记录到数据库,以便退款和后续跟踪string out_trade_no = orderReturnJson.out_trade_no;//获取支付状态string trade_state = orderReturnJson.trade_state;//验证请求是否从微信发过来(安全)NotifyReturnData returnData =new();//验证可靠的支付状态if(orderReturnJson.VerifySignSuccess ==true&& trade_state =="SUCCESS"){
              returnData.code ="SUCCESS";//正确的订单处理/* 提示:
                  * 1、直到这里,才能认为交易真正成功了,可以进行数据库操作,但是别忘了返回规定格式的消息!
                  * 2、上述判断已经具有比较高的安全性以外,还可以对访问 IP 进行判断进一步加强安全性。
                  * 3、下面演示的是发送支付成功的模板消息提示,非必须。
                  */
              recharge_service.recharge_callback(out_trade_no);//这个方法自定义,我这里是直接去改变订单的状态为已支付}else{
              returnData.code ="FAILD";//错误的订单处理
              returnData.message ="验证失败";//此处可以给用户发送支付失败提示等}#region 记录日志(也可以记录到数据库审计日志中)var logDir = ServerUtility.ContentRootMapPath(string.Format("~/App_Data/TenPayNotify/{0}", SystemTime.Now.ToString("yyyyMMdd")));if(!Directory.Exists(logDir)){
              Directory.CreateDirectory(logDir);}var logPath = Path.Combine(logDir,string.Format("{0}-{1}-{2}.txt", SystemTime.Now.ToString("yyyyMMdd"), SystemTime.Now.ToString("HHmmss"), Guid.NewGuid().ToString("n").Substring(0,8)));using(var fileStream = System.IO.File.OpenWrite(logPath)){var notifyJson = orderReturnJson.ToString();await fileStream.WriteAsync(Encoding.Default.GetBytes(notifyJson),0, Encoding.Default.GetByteCount(notifyJson));
              fileStream.Close();}#endregion}catch(Exception ex){
          WeixinTrace.WeixinExceptionLog(newWeixinException(ex.Message, ex));throw;}return api_result;}
标签: 前端 微信 vue.js

本文转载自: https://blog.csdn.net/apple20150410/article/details/139288826
版权归原作者 一蓑烟雨*任平生 所有, 如有侵权,请联系我们删除。

“微信公众号、微信小程序使用JsApi支付方式,前端vue+后端c#,详细介绍”的评论:

还没有评论