二 微信支付分对接(java)

1.支付分对接时注意的坑

创建支付分订单API    https://api.mch.weixin.qq.com/v3/payscore/serviceorder

修改订单金额API       https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/modify

取消支付分订单API    https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/cancel

完结支付分订单API    https://api.mch.weixin.qq.com/v3/payscore/serviceorder/{out_order_no}/complete

注:划删除线的部分是在url上拼接path的,并且传输时param不可包含 out_order_no这个参数。

所以,我作了如下处理:


根据api替换参数,并且移除param的out_order_no

回调处理 :

@PostMapping("/confirmNotify")

@ResponseBody

public JSONObjectconfirmNotify(HttpServletRequest request){

try{

ServletInputStream servletInputStream = request.getInputStream();

        int contentLength = request.getContentLength();

        byte[] callBackInBytes =new byte[contentLength];

        servletInputStream.read(callBackInBytes, 0, contentLength);

        String callBackIn =new String(callBackInBytes, StandardCharsets.UTF_8);

        logger.info("【微信支付分回调】{}" , callBackIn);

        JSONObject notifyIn = JSONObject.parseObject(callBackIn);

        if (notifyIn ==null) {

logger.info("支付回调失败,参数不正确,反序列化失败");

        }

//解密回调信息

        assert notifyIn !=null;

        JSONObject resource = notifyIn.getJSONObject("resource");

        byte[] key = (wxConfig.IV3KEY).getBytes(StandardCharsets.UTF_8);

        ApiV3Util aesUtil =new ApiV3Util(key);

        String decryptToString = aesUtil.decryptToString(resource.getString("associated_data").getBytes(StandardCharsets.UTF_8), resource.getString("nonce").getBytes("UTF-8"), resource.getString("ciphertext"));

        if (StringUtils.isEmpty(decryptToString)) {

logger.info("支付回调失败,参数解密错误");

        }

logger.info("【支付分支付回调解密结果:】" + decryptToString);

        // 用户确认成功

        if ("PAYSCORE.USER_CONFIRM".equals(notifyIn.get("event_type"))) {

JSONObject json=JSONObject.parseObject(decryptToString);

            if("USER_CONFIRM".equals(json.getString("state_description"))){

logger.info("用户确认成功[【YES】],解密数据{}",json);

                return payPointService.receiveBack(0,json);

            }

}

// 支付成功

        if ("PAYSCORE.USER_PAID".equals(notifyIn.get("event_type"))) {

JSONObject json=JSONObject.parseObject(decryptToString);

            if("MCH_COMPLETE".equals(json.getString("state_description"))){

logger.info("用户支付成功[【YES】],解密数据{}",json);

                return payPointService.receiveBack(1,json);

            }

}

}catch (Exception e) {

logger.error("微信支付回调处理异常," + e.toString());

        e.printStackTrace();

    }

return null;

}

注意:此处的IPV3key是IPV3支付密钥,从商户获取。

APIV3解密Util

回调包含了用户确认支付分免押和支付回调,

用户确认即可执行业务操作,例如:使用免押充电宝的弹出,使用共享单车的开锁等。

支付回调则需要根据扣款金额校验,微信API都是以分为单位

使用传输时乘以100,使用BigDecimal.multiply(new BigDecimal(100)).setScale(0);

解密时除以100,使用BigDecimal.divide(new BigDecimal(100));

小数点可以自己控制,如果使用int或double容易造成精度丢失,涉及金钱务必使用BigDecimal;

另外如有扣费需要存储扣费凭证(交易单号,支付分API使用基础的微信退款),包裹了很多层

json数据为解密后的支付订单回调数据;

JSONObject collection = JSONObject.parseObject(JSONObject.toJSONString(json.get("collection")));

JSONArray details = JSONObject.parseArray(collection.getString("details"));

String finish_transaction_id =null;

if (details.size() ==1) {

for (Object de : details) {

JSONObject jsons = JSONObject.parseObject(JSONObject.toJSONString(de));

        finish_transaction_id = jsons.getString("transaction_id");

    }

}

再把finish_transaction_id存储;

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容