微信签约
前段时间,由于业务需要接入微信代扣功能。 做代扣功能之前。用户需要调用微信客户端 进行免密代扣的签约。
大概流程如下:
在生成签约url后,调不起来微信webview问题整理如下:
1、微信代扣文档:https://pay.weixin.qq.com/wiki/doc/api/pap_jt_v2.php?chapter=19_1&index=2
2、微信官方文档中之处需要对notify_url 进行url编码,并且IOS编码两次。 当url编码后发现IOS端还是调不起来微信 webview。
- 后来经过,不断尝试,发现当我们contract_display_account为中文时,同样需要两次url encode;
- 同时生产签约参数的notify_url ,contract_display_account不能进行url编码
3、签约部分的代码逻辑如下:
1 private String generateSignInfo(WithholdContractRecordDO withholdContractRecordDO, PayChnlInfoDO payChnlInfoDO) throws Exception { 2 Map<String, String> signInfo = new HashMap<>(); 3 signInfo.put("appid", payChnlInfoDO.getChnlAppId()); 4 signInfo.put("contract_code", withholdContractRecordDO.getContractNo()); 5 signInfo.put("contract_display_account", withholdContractRecordDO.getContractUserName()); 6 signInfo.put("mch_id", payChnlInfoDO.getChnlMchtCd()); 7 signInfo.put("notify_url", wechatProperty.getSignNotifyUrl()); 8 signInfo.put("plan_id", payChnlInfoDO.getPlanId()); 9 signInfo.put("request_serial", DateUtils.format(new Date(), "yyMMddHHmmss") + withholdContractRecordDO.getId()); 10 signInfo.put("timestamp",String.valueOf(System.currentTimeMillis()).substring(0,10)); 11 signInfo.put("version", "1.0"); 12 if (PayServiceConstant.ReturnType.BACK.getCode().equals(withholdContractRecordDO.getReturnApp())) { 13 signInfo.put("return_app", "3"); 14 } 15 if (PayServiceConstant.ReturnType.BACK.getCode().equals(withholdContractRecordDO.getReturnWeb())) { 16 signInfo.put("return_web", "1"); 17 } 18 19 String sign = WXPayUtil.generateSignature(signInfo, payChnlInfoDO.getChnlMchtKey(), WXPayConstants.SignType.MD5); 20 StringBuffer result = new StringBuffer("https://api.mch.weixin.qq.com/papay/entrustweb?") 21 .append("appid=" + signInfo.get("appid")) 22 .append("&contract_code=" + signInfo.get("contract_code")) 23 .append("&mch_id=" + signInfo.get("mch_id")) 24 .append("&plan_id=" + signInfo.get("plan_id")) 25 .append("&request_serial=" + signInfo.get("request_serial")) 26 .append("×tamp=" + signInfo.get("timestamp")) 27 .append("&version=" + signInfo.get("version")) 28 .append("&sign=" + sign); 29 30 URLEncoder urlEncoder = new URLEncoder(); 31 String notifyUrl = urlEncoder.encode(signInfo.get("notify_url"), Charset.forName("UTF-8")); 32 String contractDisplayAccount = urlEncoder.encode(signInfo.get("contract_display_account"), Charset.forName("UTF-8")); 33 if ("IOS".equals(withholdContractRecordDO.getMobileType())) { 34 notifyUrl = urlEncoder.encode(notifyUrl, Charset.forName("UTF-8")); 35 contractDisplayAccount = urlEncoder.encode(contractDisplayAccount, Charset.forName("UTF-8")); 36 } 37 38 result.append("¬ify_url=" + notifyUrl); 39 result.append("&contract_display_account=" + contractDisplayAccount); 40 if (StringUtils.isNotBlank(signInfo.get("return_app"))) { 41 result.append("&return_app=" + signInfo.get("return_app")); 42 } 43 44 if (StringUtils.isNotBlank(signInfo.get("return_web"))) { 45 result.append("&return_web=" + signInfo.get("return_web")); 46 } 47 return result.toString(); 48 }