zoukankan      html  css  js  c++  java
  • 微信支付 (jsapi 方式)

    首先说注意几点,其实要说难不难,都是细节问题

    • 进行签名的参数注意大小写
    • 签名用的key是微信支付密钥,不是身份密钥
    • 返回给前端的预订单号格式一定要注意
    • 配置的安全域名一定是https的

    1  微信配置安全域名,这里不多说,自行百度

    2  后端引入微信支付依赖

      

    <!-- 微信支付 -->
    <dependency>
        <groupId>com.github.wxpay</groupId>
        <artifactId>wxpay-sdk</artifactId>
        <version>0.0.3</version>
    </dependency>

    3  前端向后端发请求支付,后端调用微信同一下单 api 接口,关键是签名,有十个参数是必须进行签名的,分别如下

    • body                支付项目描述
    • out_trade_no         我们自己生成的订单号
    • total_fee           支付金额,单位(分)
    • spbill_create_ip     付款客户的ip地址
    • notify_url          付款成功或失败的微信通知我们的地址,自己在后台创建一个回调地址
    • trade_type           因为我现在集成 jsapi 方式支付, 所以直接写 JSAPI 即可
    • openid              jsapi 方式支付必须携带此参数
    • appid               公众号ID,微信支付平台获取,在申请支付时微信提供的
    • mch_id              商户号,微信支付平台获取,在申请支付时微信提供的
    • nonce_str           随机字符串,有个 WXPayUtil 类有提供,也可以自己随便输入也行
    
    

    public PayDTO createUnifiedorder(MonitorTypeEnum type, String body, TradeType tradeType, String openid, String ip, String phone, String tradeNo) { log.info("进入微信支付"); Map<String, String> map = new HashMap<>(); map.put("body", body); // 参数1 map.put("out_trade_no", tradeNo); // 参数2 BigDecimal big = new BigDecimal(type.getFee()); map.put("total_fee", String.valueOf((int)(big.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue() * 100))); // 参数3 map.put("spbill_create_ip", ip); // 参数4 map.put("notify_url", notifyUrl); // 参数5 map.put("trade_type", tradeType.name()); // 参数6 map.put("openid", openid); // 参数7 try {
            // MyWXPayConfig 类是自己创建的,实现了 WXPayConfig 接口,里面定义了 appid, mchid 和 key, 这个key是微信支付密钥,不是身份密钥,千万不要搞错 MyWXPayConfig config
    = new MyWXPayConfig();
            // 这个类是微信提供的类,将上面的配置类传入即可 WXPay pay
    = new WXPay(config);
            // 调用微信提供的统一下单接口,他会自动将另外的三个参数传入(appid, mch_id, nonce_str)进行签名后,调用微信统一下单 api 接口,生成预支付订单 Map
    <String, String> returnMap = pay.unifiedOrder(map); log.info("微信预支付请求参数【{}】",JSON.toJSONString(map)); log.info("微信预支付返回结果【{}】", JSON.toJSONString(returnMap)); String returnCode = returnMap.get("return_code"); String resultCode = returnMap.get("result_code");
            // 判断生成预支付订单是否成功
    if("SUCCESS".equalsIgnoreCase(resultCode) && "SUCCESS".equalsIgnoreCase(returnCode)) { String sign = returnMap.get("sign"); // 取出需要参数 String nonceStr = returnMap.get("nonce_str"); String appid = returnMap.get("appid"); String trade_type = returnMap.get("trade_type"); String mchId = returnMap.get("mch_id"); String prepayId = returnMap.get("prepay_id"); String timeStamp = String.valueOf(System.currentTimeMillis() / 1000); PayDTO dto = new PayDTO(); Map<String, String> map1 = new HashMap<>();
              // 下面这几个参数是将返回给前端的字段进行签名并生成 sign 签名字段,然后字段连同签名一起返回给前端 map1.put(
    "appId", appid); map1.put("timeStamp", timeStamp); map1.put("nonceStr", nonceStr); map1.put("package", "prepay_id=" +prepayId); // 这个预订单号格式要注意 map1.put("signType","MD5"); String sign2 = WXPayUtil.generateSignature(map1, config.getKey());
              // 下面的参数是返回给前端的 dto.setNonceStr(nonceStr); dto.setAppid(appid); dto.setTradeType(trade_type); dto.setMchId(mchId); dto.setPrepayId(prepayId); dto.setTimeStamp(timeStamp);
    // 这个签名是传入前端的签名 dto.setSign(sign2); payTradeRecordService.updateTradeStatusByTradeNo(tradeNo, TradeStatusEnum.UNPAID); return dto; } } catch (Exception e) { log.error("生成微信签名错误", e); } return null; }

    4  前端拿到后端返回的参数后,就可以调起微信支付的页面

    // 请求微信支付
          fetchPayUnifiedorder(type, body) {
            let _this = this
            if (this.openId) {
              // 有openId用jsapi支付
              this.$http({
                url: this.$http.adornUrl('/weChat/pay/unifiedorder'),
                method: 'POST',
                data: this.$http.adornData({
                  openId: this.openId,
                  tradeType: 'JSAPI',
                  body: body,
                  type: type,
                  phone: this.phone
                })
              }).then(({ data }) => {
                if (data.code === 0) {
                  let pay = data.pay
            // 这个对象只有在微信内部打开的 h5 页面才有的对象 window.WeixinJSBridge.invoke(
    'getBrandWCPayRequest', { 'appId': pay.appid, // 公众号名称,由商户传入 'timeStamp': pay.timeStamp, // 时间戳,自1970年以来的秒数 'nonceStr': pay.nonceStr, // 随机串 'package': `prepay_id=${pay.prepayId}`, // 这里需要注意 'signType': 'MD5', // 微信签名方式 'paySign': pay.sign // 微信签名 }, function (res) { console.log('支付返回结果', res) if (res.err_msg === 'get_brand_wcpay_request:ok') { // 支付成功后查询订单信息 _this.fetchPaySuccessOrder() } else { _this.$swal({ icon: 'error', title: '支付失败', showConfirmButton: false, timer: 1500 }) } }) } else { _this.$swal({ icon: 'error', title: data.msg, showConfirmButton: false, timer: 1500 }) } }) } else { this.$swal({ icon: 'warning', title: '对不起,目前仅支持在微信APP内打开的网页进行支付', showConfirmButton: false, timer: 1500 }) } }

      不懂可以加我 QQ: 287475833

  • 相关阅读:
    第四讲动手动脑集课后作业
    第三讲课后作业
    课后作业01
    《大道至简》第一章伪代码读后感
    第八周学习进度条
    第七周学习进度条
    求一维联通数组的最大子数组之和
    求二维数组的最大联通子数组之和
    第六周学习进度条
    求一个数组的最大子数组之和
  • 原文地址:https://www.cnblogs.com/wujiaxing/p/13672299.html
Copyright © 2011-2022 走看看