- V3支付回调验签失败?
求大侠帮忙看看原因,卡三天了,使用的是官方SDK验签 报文主体 { "id": "EV-2018022511223320873", "create_time": "2015-05-20T13:29:35+08:00", "resource_type": "encrypt-resource", "event_type": "TRANSACTION.SUCCESS", "summary": "支付成功", "resource": { "original_type": "transaction", "algorithm": "AEAD_AES_256_GCM", "ciphertext": "3TxpOF8YqF5Zy2cYQWrZNnmC1FWrxwIPvIv4WejUr+8ctmM6L3kxqQ6JS56S7JkVFMiCvfcMGkQFMtUifq09Wrt6+bNwMUNLKQ52zLyMLwS9uML2Y2Qmi1obactel3rwwTs+IXGir505F2eLBG9ruqtJxGd2dlsLQ+0Sl7OUA/mMCnxMXUhfwJC84lv2oZDC3T827Mzy0BQ5YmXfdpgOA0OCTl+OwokWMXJz2DiGafE1n0pqH/R0VgDyUCEAOb6l+dFRR7S0I1yVe7/6czAYp+i7mTgNrmudG7EgDoOVfGga9Wq9epO6PEew1ypK5M8PmIopNSzg34WEouFhOqvPZfi2paqib2gxexcqtniQQbdechavr4SH/3JSpg8Zbnnbeo3ClFDU7eRVO2FCAPQaMlcSmjU4zv2H98dvB9TnIyon/so+QwSo/ZwWMnTKeztviuYd5ICbrtzAPoeeDrPlYlB0pwlFT8Tz3lqC0QZWKvL0+FIj0+9P+2/JvZpr5aVrFosMI1Afb17P7zx69jnLFPFX0ph4AgBK/N8oRNg12uVqvJM3E07/4P7LWLKyrf9FySovQplbhlasAyOf5PWb3aBwEv19hr71uMvAyuCll39zhIZ9M1CZTcSLpuyeWDOUwt3Y7ww0mOMruvK5a5mREuowqfP/OVv73yX/mf/7MEo9wAvz2bNqAuS0c9xc2yn5EHN4rNSTgApcJh2OTNUVEZXu7sL04S/pKpApS4eXxTS1bnLeqVfk5rePQagXFXwMFJVfAPmLyMRLsBLpdc2lO2LIof+nx8HnqjHvKYnolRgJYAlUuHx1mdjsPrZreDjK12b3cBznrfC7gac+3VW4r42f2b533RCAvchchxb7l+sdzQSFImbxZ1IAZFO/ZozZEFFko2FypOh2SdZYigW6Rq6hxw8EFOrvp6GwKpkhGbb4xnQsGHupDAMte5QmiMb9M8KUP5DSIo7gCsO7FMWtXFrdetyQfLXsZ/CidA+JOlSGKL+8s/ISyajpl8YseGNhlq39Zci53GoQCETs/ixLPz4BOTeTLC9FASUoEGPKet+OvYhdo4Xlopbhs95jl6jjgZcT6Bkr5ivG2ocqi2aP5hpnnVDXq/OwXvdofTHxlp2oydlYo9xqXhg+emzSQ8woub6XXO22KOKuEcWMSCiSMWYm9gsP2v0QkCw54ZmJHuDoivV2jVrFQjdH9nO2m68SHj9I9PBj4eSbDG235d/gSxp6VrrH+UaP5b4fjZi4xZ+9Nr1oUAc1Z6RRqqvCVLY1DTMpp2H/aXr9gNUs8fL8kkfuiWEKTkcoW/JKTZjiizzbHEkXSU3+dm4AITiKWrdvSUs80OGg==", "associated_data": "certificate", "nonce": "4de73afd28b6" } } Wechatpay-Serial:71DE68330BFF41E22EB2E5DC6FBCFDB2B129991D Wechatpay-Timestamp:1432099775 Wechatpay-Nonce:c5ac7061fccab6bf3e254dcf98995b8c Wechatpay-Signature:a/JwSTUexccPzfrVDSsoGiozTRtFnAzsBjtCkSysUemFEpogr0ZSLRbAZlUrfnlqUALigms6JcnXnUinocooHQR6I1zn38H8n02r/GrBKHpqfHr6/YEdDrC/AlMs6O4ktiOYUwFatEKorexNYFwiDptyUW5beEFAFwNw4reCz99pj4/k/oLlhCFViBs775qQKiy4FTgzdJxHAw+6cbSU2/nHyB6F9gXwM9+IFBtjVwAPXkStXNLZOKvgGpmiYxTrw5wAiEJLijo6a9S+L6rU0B6oVX+nBKd61mV1v4tvHaRJs/dxe8hPlPApHVWqt6ntx7UC4+ChXZSg/JuJKzLY8w== 验签方法如下 @ApiOperation("支付通知") @PostMapping("/jsapiPay/notify") public String jsapiPayNotify(HttpServletRequest request, HttpServletResponse response) { // 应答对象 Map<String, String> map = new HashMap<>(); try { // 处理参数 String serialNumber = request.getHeader("Wechatpay-Serial"); String nonce = request.getHeader("Wechatpay-Nonce"); String timestamp = request.getHeader("Wechatpay-Timestamp"); String signature = request.getHeader("Wechatpay-Signature");// 请求头Wechatpay-Signature // 获取请求体 String body = HttpUtils.readData(request); // 构造微信请求体 NotificationRequest wxRequest = new NotificationRequest.Builder().withSerialNumber(serialNumber) .withNonce(nonce) .withTimestamp(timestamp) .withSignature(signature) .withBody(body) .build(); Notification notification = null; try { /** * 使用微信支付回调请求处理器解析构造的微信请求体 * 在这个过程中会进行签名验证,并解密加密过的内容 * 签名源码: com.wechat.pay.contrib.apache.httpclient.cert; 271行开始 * 解密源码: com.wechat.pay.contrib.apache.httpclient.notification 76行 * com.wechat.pay.contrib.apache.httpclient.notification 147行 使用私钥获取AesUtil * com.wechat.pay.contrib.apache.httpclient.notification 147行 使用Aes对称解密获得原文 */ notification = notificationHandler.parse(wxRequest); } catch (Exception e) { logger.error("通知验签失败"); //失败应答 response.setStatus(500); map.put("code", "ERROR"); map.put("message", "通知验签失败"); return JSON.toJSONString(map); } // 从notification中获取解密报文,并解析为HashMap // String plainText = notification.getDecryptData(); logger.info("通知验签成功"); //处理订单 // wxPayService.processOrder(plainText); wxPayService.processOrder(notification); //成功应答 response.setStatus(200); map.put("code", "SUCCESS"); map.put("message", "成功"); return JSON.toJSONString(map); } catch (Exception e) { e.printStackTrace(); //失败应答 response.setStatus(500); map.put("code", "ERROR"); map.put("message", "失败"); return JSON.toJSONString(map); } }
09-13 - 小程序订阅消息报错47003?
小程序订阅消息报错47003,argument invalid! data.character_string1.value i rid: 66e3da65-174ac864-3bc02079 data -> { "character_string1":{ "value":"PD20240905000008" }, "amount2":{ "value":¥0.01 }, "thing3":{ "value":"预付定金" }, "time9":{ "value":"2024年09月05日 14:00" }, "thing4":{ "value":"预付定金" } } 同事试过了不走接口正常可以发送,应该不是传参问题 /** * 支付订阅消息推送 * @param * @return * @throws Exception */ @ApiOperation("支付订阅消息推送") @GetMapping("/pushWxPayMsg") public Map<String, Object> pushWxPayMsg() { TuanBusinessPaymentDetailsEntity paymentDetailsEntity = tuanBusinessPaymentDetailsService.queryObject("PD20240905000008"); if (paymentDetailsEntity==null) { throw new RRException("该支付单不存在,请检查支付单号是否正确!"); } Gson gson = new Gson(); //创建订阅信息的模板内容 JSONObject data = new JSONObject(); data.put("character_string1", new JSONObject() {{ put("value", "PD20240905000008"); }}); data.put("amount2", new JSONObject() {{ put("value", "¥" + paymentDetailsEntity.getPayAmount().toString()); }}); data.put("thing3", new JSONObject() {{ put("value", paymentDetailsEntity.getPaymentDescription()); }}); data.put("time9", new JSONObject() {{ put("value", DateUtils.parseDateTime(paymentDetailsEntity.getPayTime(), DateUtils.yyyyMMddHHmmFormat)); }}); data.put("thing4", new JSONObject() {{ put("value", paymentDetailsEntity.getPaymentDescription()); }}); String requestURL = WxPayConfigV2.PAY_PUSH_URL + "?access_token=" + WxComUtil.getAccessToken().access_token; // 创建请求体 Map<String, String> requestBody = new HashMap<>(); requestBody.put("template_id", WxPayConfigV2.PAY_REMIND_SUBSCRIBE_TEMP_ID); requestBody.put("touser", "ot4cU7YgjtPGAghcrtNKpsqLRUbo"); requestBody.put("data", data.toJSONString()); requestBody.put("miniprogram_state", "trial"); requestBody.put("lang", "zh_CN"); HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); HttpEntity<Map<String, String>> requestEntity = new HttpEntity<>(requestBody, headers); try { ResponseEntity<String> responseEntity = restTemplate.exchange( requestURL, HttpMethod.POST, requestEntity, String.class ); Type mapType = new TypeToken<Map<String, Object>>(){}.getType(); Map<String, Object> res = gson.fromJson(responseEntity.getBody(), mapType); return res; } catch (Exception e) { Map<String, Object> res = new HashMap<>(); res.put("errCode",-1); res.put("errMsg","服务异常,请联系管理员..."); return res; } }
09-13