El mini programa WeChat Webview maneja problemas de pago

 Manejo de problemas de pago de Webview

La vista web en el mini programa WeChat puede hacer muchas cosas, pero todavía existen muchas limitaciones: por ejemplo, la interfaz de pago normal del mini programa no se puede utilizar en la vista web. Pero podemos usar webview para saltar a la página interna del miniprograma con parámetros, obtener estos parámetros en la página interna del miniprograma e iniciar el pago.
Aquí integramos información de Internet para hablar de este proceso.

Pasos frontales:


  ①: Después de hacer clic en el botón de pago, solicite el fondo de Java y obtenga los parámetros necesarios 'timeStamp', 'package', 'paySign', 'signType', 'nonceStr' para colgar el mini programa ②: salte a un punto determinado en el mini programa con
  parámetros Página
  ③: analiza directamente los parámetros al cargar la página del mini programa y abre la interfaz de pago: wx.requestPayment
  ④: procesa el resultado del pago, vuelve a la vista web u otras páginas
  


Visualización del código frontal:

1. vista web (dentro de html)

 <button id="buttom8xx">购买一年会员</button>
    <script type="text/javascript">
        $("#buttom8xx").click(function() {
            $.ajax({
                type : 'Get',
                url : "http://192.168.0.15:8080/carplatform/User/BecomeVip",
                dataType : 'json',
                contentType : "application/json;charset=UTF-8",
                success : function(data) {
                    if(data.state)
                    {
                      alert(data.payinform.package);
                      var pid=(data.payinform.package).split('=')[1];  //跳转到小程序时这个参数有等号,小程序只能获取到‘=’前面的字符,这里我们发送=后面字符,小程序里面自行拼凑
                                                                       //注意这个地方是有坑的,小程序在跳转传参时如果某一个参数key对应的内容形如“xxx=yyy”这中格式,                                                                     
                                                                       //我们在小程序页面解析参数时实际是只能获取到‘=’前面一部分,也就是‘xxx’
                var params = '?timeStamp='+data.payinform.timeStamp
                +'&package='+pid
                    +'&paySign='+data.payinform.paySign
                    +'&signType='+data.payinform.signType
                    +'&nonceStr='+data.payinform.nonceStr;
                var payurl='/pages/wxpay/wxpay'+params;
                //小程序跳转到指定的小程序页面.跳转不需要加载jssdk配置
                                 alert(payurl);
                wx.miniProgram.navigateTo({url: payurl}); //带参跳转到小程序内部页面
                 console.log(data);
                }
                else
                {
                                  alert(data.message);
                }
                }
            });
        });
    </script>

 wxpay.js en la página de pago del mini programa:

/**
   * 页面加载,获取支付参数直接吊起支付
   */
  onLoad: function (options) {
    var that = this;
    //页面加载调取微信支付(原则上应该对options的携带的参数进行签名计算,校验)
    var param = {
      "timeStamp": options.timeStamp,
      "package": 'prepay_id=' +options.package,//组装下参数
      "paySign": options.paySign,
      "signType": "MD5",
      "nonceStr": options.nonceStr
    }
    console.log(param);
    that.pay(param)//吊起支付
  },

 /**
 *  调起支付函数
 */
  pay: function (param) {
    wx.requestPayment({
      timeStamp: param.timeStamp,//时间搓
      nonceStr: param.nonceStr,//随机码
      package: param.package,//统一下单接口返回的  prepay_id
      signType: param.signType,//签名算法MD5
      paySign: param.paySign,//签名字符串
      success: function (res) {
        // success
        console.log(res)
        wx.navigateBack({
          delta: 1, // 回退前 delta(默认为1) 页面
          success: function (res) {
            wx.showToast({
              title: '支付成功',
              icon: 'success',
              duration: 2000
            })
          },
          fail: function (res) {
            // fail
            console.log(res)
          },
          complete: function (res) {
            // complete
            console.log(res)
          }
        })
      },
      fail: function (res) {
        // fail
        console.log("支付失败");
        console.log(res)
      },
      complete: function (res) {
        // complete
        console.log("pay complete");
        console.log(res)
      }
    })
  },

Lógica de fondo:

 ①: Calcule los parámetros de pago, llame a la interfaz de pedidos unificada del subprograma WeChat en segundo plano, obtenga el parámetro de pago prepay_id = xxx y luego calcule los parámetros necesarios para levantar la interfaz de pago del subprograma. No hay nada que decir al respecto. Simplemente escríbalo de acuerdo con la interfaz wx ②
 : Manejo de devolución de llamada.
  Tengo entendido que soy relativamente sensible a las cosas relacionadas con el dinero. Después de recibir la devolución de llamada de WeChat, no debemos realizar cambios en la base de datos o en la cuenta directamente en función de su estado. Aquí necesitamos verificarlo varias veces, si lo comparamos varias veces, la otra parte puede pensar que la otra parte realmente ha pagado. Para garantizar la seguridad de sus fondos, ¡también podría sacrificar parte del rendimiento del backend! ! ! Entonces, después de recibir la devolución de llamada, tomé los siguientes pasos
  : 1°: Para evitar que las devoluciones de llamada estén demasiado concentradas y causen confusión en los datos, utilicé un candado para determinar si una devolución de llamada ha sido procesada. Si no se ha procesado, no hay otra opción. Llegarán devoluciones de llamada (por supuesto, esto es obvio de un vistazo. Hay defectos. Específicamente, se debe establecer una cola para el procesamiento).
  2°: Verificación de la firma del parámetro de devolución de llamada
  3°: Determinar si varios métodos tienen éxito en los parámetros de devolución de llamada.
  4°: Después de que todo el estado y el estado de pago en los parámetros sean exitosos, verifique si el estado del pedido en nuestra base de datos ha sido pagado (principalmente para evitar que regresemos al 'ÉXITO' de WeChat si no lo recibió o algo así, causando que WeChat para continuar repitiendo notificaciones).
  5°: Obtenemos el número de pedido de WeChat en el parámetro y llamamos a la interfaz de consulta de pedidos de WeChat. Comprueba si realmente se ha pagado la devolución del pedido.
  6°: Modificar la base de datos y modificar el almacenamiento de la sesión. (La modificación de la sesión aquí se realiza a través del campo 'adjuntar' del paquete de datos del comerciante pasado por el ID de sesión del usuario cuando el usuario realiza un pedido. El ID de sesión se obtiene durante la devolución de llamada y el contenido de modificación de la sesión del usuario correspondiente se encuentra en nuestra clase de monitoreo. .)

    Código de devolución de llamada de pago en segundo plano de Java:

 // 成为会员,用户支付回调!
    @ResponseBody
    @RequestMapping(value = "User/wx/bvipback")
    public String Userwxbvipback(@RequestBody String request, HttpSession session) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, Exception {
        Map<String,String> result = new HashMap<>();
        
        if(!vip_paybackend)//一次还未处理完,收到其它回调,直接返回
        {
            result.put("return_code", "FAIL");
            return user_wxAPI.GetInstance().mapToXml(result);
        }
        else
        {
            vip_paybackend=false; //设置为正在处理,不予许其它回调进入
        }
        
        if(!user_wxAPI.GetInstance().CheckReturn(request))//验证签名是否一致,签名不一致直接返回
        {
            result.put("return_code", "FAIL");
            vip_paybackend=true;//可以接收下一次数据回调
            return user_wxAPI.GetInstance().mapToXml(result);
        }
        else
        {
            Map<String, String> data = user_wxAPI.GetInstance().xmlToMap(request);//转成map
            if (data.get("return_code").equals("FAIL"))//通讯为失败,直接返回
            {
                result.put("return_code", "FAIL");
                vip_paybackend=true;//可以接收下一次数据回调
                return user_wxAPI.GetInstance().mapToXml(result);
            }
            if (data.get("result_code").equals("FAIL"))//业务结果为失败,支付失败直接返回
            {
                result.put("return_code", "FAIL");
                vip_paybackend=true;//可以接收下一次数据回调
                return user_wxAPI.GetInstance().mapToXml(result);
            }
            if(data.get("result_code").equals("SUCCESS"))//业务结果成功,我们再次查询订单状态,在决定是否写入数据库
            {
                String transaction_id=data.get("transaction_id"); //得到这个微信订单号
                String out_trade_no=data.get("out_trade_no"); //得到这个商户订单号
                wxorder onewxorder=ordersdao.GetWXOrder(out_trade_no);//查询微信我们数据库订单状态
                if(!data.get("total_fee").equals(String.valueOf(onewxorder.wxorder_money)))//如果订单金额不匹配
                {
                    result.put("return_code", "FAIL");
                    vip_paybackend=true;//可以接收下一次数据回调
                    return user_wxAPI.GetInstance().mapToXml(result);
                }
                
                if(!onewxorder.wxorder_state.equals(1)) //如果不是未支付状态我们就返回
                {
                    result.put("return_code", "SUCCESS");
                    vip_paybackend=true;//可以接收下一次数据回调
                    return user_wxAPI.GetInstance().mapToXml(result);//告诉微信服务器,我已经处理过数据
                }
                
                Map<String, String> wxorder_infom=user_wxAPI.GetInstance().OrderQuery(transaction_id);//用微信订单号,订单查询
                if(wxorder_infom.get("return_code").equals("FAIL"))//查询订单失败了
                {
                    result.put("return_code", "FAIL");
                    vip_paybackend=true;//可以接收下一次数据回调
                    return user_wxAPI.GetInstance().mapToXml(result);
                }
                if(wxorder_infom.get("return_code").equals("SUCCESS")
                   &&wxorder_infom.get("result_code").equals("SUCCESS")
                   &&wxorder_infom.get("trade_state").equals("SUCCESS"))//查询订单返回三个success作为,支付成功的判断
                {
                    String session_id=wxorder_infom.get("attach");//商家数据包中获取用户sessionid
                    HttpSession usersession=MyHttpsessions.GetSession(session_id);
                    //修改微信订单状态,添加或者修改用户的会员时间,包括user自身
                    if(onewxorder.wxorder_state.equals(1))//如果是未支付状态,我们才进行数据库处理
                    {
                        onewxorder.wxorder_state=2;//状态改为已支付
                        onewxorder.wxorder_wxnum=transaction_id;//添加微信订单号
                        ordersdao.UpdateOneWxOrder_State(onewxorder);//跟新为已支付
                        Date user_endtime=ordersdao.saveviporder(onewxorder.wxorder_userid);//插入、跟新vip订单表
                        Userdao.UpdateUserEndtime(user_endtime, onewxorder.wxorder_userid);//跟新用户endtime
                        
                        //修改用户ession状态
                        User user=new User();
                        if(usersession!=null) user=(User) usersession.getAttribute("user");
                        user.setUser_bvip(1);//是vip
                        user.setUser_endtime(df.format(user_endtime));
                        usersession.setAttribute("user", user);
                        
                        result.put("return_code", "SUCCESS");
                        vip_paybackend=true;//可以接收下一次数据回调
                        return user_wxAPI.GetInstance().mapToXml(result);//告诉微信服务器,已经处理好数据
                    }
                }
                else 
                {
                    result.put("return_code", "FAIL");
                    vip_paybackend=true;//可以接收下一次数据回调
                    return user_wxAPI.GetInstance().mapToXml(result);
                }
            }
        }
        result.put("return_code", "FAIL");
        vip_paybackend=true;//可以接收下一次数据回调
        return user_wxAPI.GetInstance().mapToXml(result);
    }

 


 

Supongo que te gusta

Origin blog.csdn.net/qq_22824481/article/details/82258595
Recomendado
Clasificación