zoukankan      html  css  js  c++  java
  • Java 后端微信小程序支付demo (网上说的坑里面基本上都有)

    Java 后端微信小程序支付

    一、遇到的问题

    1. 商户号该产品权限未开通,请前往商户平台>产品中心检查后重试

    2.签名错误

    3.已经调起微信统一下单接口,可以拿到预支付ID,但是前端支付的时候出现 支付验证签名失败

    网上的问题基本上就是这三类下面说解决方案。

    第一个问题:商户号的问题,微信app支付与微信小程序支付的商户号不同,微信app内支付与微信开放平台内的商户号绑定,微信小程序支付是与微信公众平台内的商户号绑定。

    第二个问题:签名错误, 第一次签名需要的appid mchid key 分别对应的是小程序的appid、微信公众平台绑定的商户号、以及商户平台的密钥(重要的事情说三遍:商户平台的!商户平台的!商户平台的!)。

    这里重点说下商户平台的密钥(当时就是因为密钥的问题耽误了不少时间):具体请看图(商户平台--->账户中心--->API安全---->设置密钥)

    第三个问题:支付验证签名失败 这个就得需要严格执行小程序支付文档中的生成签名的规则。参数字段大小写、顺序一定要对(切记,切记,切记)

    如果能把以上都注意到了,那基本上没什么问题了。下面是我自己写的demo供大家参考,有什么问题可以留言。

    二、demo 事例

    1.下载商户的证书(在问题2的截图中已经展示下载的位置)放在resources下的cert目录下(cert目录需要自己手动建)

    2.实现微信的 WXPayConfig接口

     1 package com.ieou.franky.payCenter.common;
     2 
     3 import com.github.wxpay.sdk.WXPayConfig;
     4 import org.apache.commons.io.IOUtils;
     5 
     6 import java.io.ByteArrayInputStream;
     7 import java.io.InputStream;
     8 
     9 public class MiniprogramConfig implements WXPayConfig{
    10 
    11     private byte[] certData;
    12 
    13     public MiniprogramConfig() throws Exception {
    14         InputStream certStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("cert/miniProgram/apiclient_cert.p12");
    15         this.certData = IOUtils.toByteArray(certStream);
    16         certStream.close();
    17     }
    18 
    19     @Override
    20     public String getAppID() {
    21         return "wx6db448a73f8a6666";
    22     }  //小程序appid
    23 
    24     @Override
    25     public String getMchID() {
    26         return "1500669999";
    27     }  //商户号
    28 
    29     /** 商户平台-账户中心-API安全中的密钥 */
    30     @Override
    31     public String getKey() {
    32         return "1add1a30ac87aa77yyy2db72f57a237577777";
    33     }
    34 
    35     @Override
    36     public InputStream getCertStream() {
    37         return new ByteArrayInputStream(this.certData);
    38     }
    39 
    40     @Override
    41     public int getHttpConnectTimeoutMs() {
    42         return 0;
    43     }
    44 
    45     @Override
    46     public int getHttpReadTimeoutMs() {
    47         return 0;
    48     }
    49 }

    3.调用微信统一下单接口并且实现签名

     1 private Map<String, String> createMiniProgramTradePay(WxpayTradeAppPayModel model,String notifyUrl) throws Exception {
     2         MiniprogramConfig config = new MiniprogramConfig();
     3 
     4         WXPay wxpay = new WXPay(config);
     5 
     6         Map<String, String> data = new HashMap<>();
     7         data.put("appid",config.getAppID());
     8         data.put("mch_id",config.getMchID());
     9         data.put("body",model.getBody());
    10         data.put("out_trade_no", model.getOutTradeNo());
    11         data.put("device_info", "");
    12         data.put("fee_type", "CNY");
    13         data.put("total_fee", model.getTotalFee());
    14         data.put("spbill_create_ip", "127.0.0.1");
    15         data.put("notify_url", notifyUrl);
    16         data.put("trade_type", "JSAPI");
    17         data.put("openid",model.getOpenId());
    18 //        data.put("nonce_str","1add1a30ac87aa2db72f57a2375d8fec");
    19         String sign = WXPayUtil.generateSignature(data, config.getKey());
    20         data.put("sign",sign);
    21 
    22         Map<String, String> resp = wxpay.unifiedOrder(data);
    23         if ("SUCCESS".equals(resp.get("return_code"))) {
    24             //再次签名
    25             /** 重要的事情说三遍  小程序支付 所有的字段必须大写 驼峰模式 严格按照小程序支付文档
    26              *https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=3#
    27              * ******* 我当初就因为timeStamp中S没大写弄了3个小时 **********
    28              * */
    29             Map<String, String> reData = new HashMap<>();
    30             reData.put("appId", config.getAppID());
    31             reData.put("nonceStr", resp.get("nonce_str"));
    32             String newPackage = "prepay_id=" + resp.get("prepay_id");
    33             reData.put("package", newPackage);
    34             reData.put("signType","MD5");
    35             reData.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
    36 
    37             String newSign = WXPayUtil.generateSignature(reData, config.getKey());
    38             resp.put("paySign",newSign);
    39             resp.put("timeStamp", reData.get("timeStamp"));
    40             return resp;
    41         } else {
    42             throw new FrankyErrorException(resp.get("return_msg"));
    43         }
    44 
    45     }

    说明:这里只是说明小程序支付与微信app内支付的不同和遇到的问题,有关里面用到微信的SDK,请看上一篇文章。

    到这一步java 后端代码就差不多了,前端拿到返回的字段调起支付接口。

  • 相关阅读:
    理解HashSet及使用
    Java 集合类详解
    Java-泛型编程-使用通配符? extends 和 ? super
    回调函数及其用法
    log4j.properties 详解与配置步骤
    约瑟夫环
    泛型的约束与局限性
    把代码字体加大的办法
    System.arraycopy方法
    泛型数组列表与反射
  • 原文地址:https://www.cnblogs.com/wang-yaz/p/8697681.html
Copyright © 2011-2022 走看看