微信扫码支付遇到的问题

1、沙箱环境需要调用接口生成一个沙箱的key,替换原来的key才行

代码如下

    /**
     * 获取沙箱的key(沙箱测试时需要获取沙箱key)
     * @return
     */
    public String getSandboxSignKey() {
        try {
            MyWXPayConfig config = getConfig();
            WXPay wxPay = getWXPay();
            Map<String, String> params = new HashMap<>();
            params.put("mch_id", config.getMchID());
            params.put("nonce_str", WXPayUtil.generateNonceStr());
            params.put("sign", WXPayUtil.generateSignature(params, config.getKey()));
            String strXML = wxPay.requestWithoutCert("/sandboxnew/pay/getsignkey",
                    params, config.getHttpConnectTimeoutMs(), config.getHttpReadTimeoutMs());
            if (StringUtils.isBlank(strXML)) {
                return null;
            }
            Map<String, String> response = WXPayUtil.xmlToMap(strXML);
            logger.info("微信生成沙箱签名接口调用成功:" + response);
            if ("SUCCESS".equals(response.get("return_code"))) {
                return response.get("sandbox_signkey");
            }
            return null;
        } catch (Exception e) {
            logger.error("微信生成沙箱签名接口调用失败", e);
            return null;
        }
    }

2、沙箱环境接口请求的url都带上/sandboxnew

例如,付款码支付URL:https://api.mch.weixin.qq.com/pay/micropay
变更为:https://api.mch.weixin.qq.com/sandboxnew/pay/micropay。

3、沙箱生成二维码后,返回的code_url是无效的,沙箱环境是忽略掉用户扫码支付这个过程(这个问题坑了我很久,官方文档细节都不说明的

文章:https://bbs.csdn.net/topics/392439936?page=1

4、沙箱环境需要跟着官方下载的测试用例去输入金额,否则会报错说金额不对

 

 

5、支付回调校验签名问题

签名算法不一致:https://blog.csdn.net/aoeace/article/details/84914445

WXPay的构造函数中,默认把非沙箱环境的签名加密方法设为HMACSHA256

   public WXPay(WXPayConfig config, String notifyUrl, boolean autoReport, boolean useSandbox) throws Exception {
        this.config = config;
        this.notifyUrl = notifyUrl;
        this.autoReport = autoReport;
        this.useSandbox = useSandbox;
        if (useSandbox) {
            this.signType = SignType.MD5;
        } else {
            this.signType = SignType.HMACSHA256;
        }

        this.wxPayRequest = new WXPayRequest(config);
    }

如果使用如下方法校验支付回调签名,由于微信没有返回sign_type的xml标签,导致默认会使用md5去生成签名做比对。所以使用该方法做签名校验,会一直返回false校验不通过。建议使用isResponseSignatureValid()即可

public boolean isPayResultNotifySignatureValid(Map<String, String> reqData) throws Exception {
        String signTypeInData = (String)reqData.get("sign_type");
        SignType signType;
        if (signTypeInData == null) {
            signType = SignType.MD5;
        } else {
            signTypeInData = signTypeInData.trim();
            if (signTypeInData.length() == 0) {
                signType = SignType.MD5;
            } else if ("MD5".equals(signTypeInData)) {
                signType = SignType.MD5;
            } else {
                if (!"HMAC-SHA256".equals(signTypeInData)) {
                    throw new Exception(String.format("Unsupported sign_type: %s", signTypeInData));
                }

                signType = SignType.HMACSHA256;
            }
        }

校验签名,因为支付回调的返回值默认没有

6、退款问题

(1)要下载api证书,并且加载到项目中,微信的sdk中。继承WXPayConfig后,可以重写getCertStream()方法,指定加载证书

    @Override
    public InputStream getCertStream() {
        //我是放在项目中
        Resource resource = new ClassPathResource("cert/apiclient_cert.p12");
        File file = null;
        try {
            file = resource.getFile();
            FileInputStream instream = new FileInputStream(file);
            return instream;
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("找不到证书文件", e);
        }
    }

7、退款回调问题

(1)退款回调的req_info需要进行解密

key是取之前生成下订单之类使用的密钥key

这里做AES-256-ECB解析时要注意会报错

java.security.InvalidKeyException: Illegal key size

参考文章:https://www.cnblogs.com/yaks/p/5608358.html

JAVA运行环境默认不允许256位密钥的AES加解密,解决方法就是修改策略文件

在官方网站下载JCE无限制权限策略文件

JDK7版本JCE下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

JDK8版本JCE下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

  • 下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt
  • 如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件
  • 如果安装了JDK,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件

实践:
以JDK8为例,系统为WIN10,替换上述security文件夹下\policy\limited文件夹和\policy\unlimited文件夹里面的local_policy.jar和US_export_policy.jar这两个文件。

若是在服务器上,则只有在security目录下有local_policy.jar和US_export_policy.jar,替换即可

    //参考微信的解密说明:参数一是base64解密过的密串,参数二是md5加密后转小写
    private String aes256Decode(byte[] base64Data,byte[] keyByte) throws Exception {
        String ALGORITHM = "AES";
        String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS7Padding";
        SecretKeySpec key = new SecretKeySpec(keyByte, ALGORITHM);
        Security.addProvider(new BouncyCastleProvider());
        Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING, "BC");
        cipher.init(Cipher.DECRYPT_MODE, key);
        return new String(cipher.doFinal(base64Data));
    }

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值