前段時間,由於業務需要接入微信代扣功能。 做代扣功能之前。用戶需要調用微信客戶端 進行免密代扣的簽約。
大概流程如下:
在生成簽約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 }