微信支付V3 小程序支付API Java版
短信预约 -IT技能 免费直播动态提醒
本文目的:快速接通微信支付V3 无需关注细节,实现支付功能,修改配置即可调用
文章目录
接入准备
申请APPID,申请mchid,绑定APPID及mchid,设置APIV3密钥,下载并配置商户证书
微信支付流程整理(小程序版)
- 前端获取登录凭证(wx.login)
- 服务端换取用户openId(code2Session)
- 创建微信支付订单(/v3/pay/transactions/jsapi)
- 回调服务端
提示:以下是本篇文章正文内容,下面案例可供参考
一、导入微信支付扩展包
<!--微信支付--> <dependency> <groupId>com.github.wechatpay-apiv3</groupId> <artifactId>wechatpay-apache-httpclient</artifactId> <version>0.4.7</version> </dependency>
二、微信支付工具类
1.签名工具类
代码如下(示例):
@Componentpublic class WxSignUtil { protected static final SecureRandom RANDOM = new SecureRandom(); public static String WxAppPayTuneUp(String prepayId, String appId, String mch_id, String privateKey) throws Exception { if (StringUtils.isNotBlank(prepayId)) { long timestamp = System.currentTimeMillis() / 1000; String nonceStr = generateNonceStr(); //加载签名 String packageSign = sign(buildMessage(appId, timestamp, nonceStr, prepayId).getBytes(), privateKey); JSONObject jsonObject = new JSONObject(); jsonObject.put("appId", appId); jsonObject.put("prepayId", prepayId); jsonObject.put("timeStamp", timestamp); jsonObject.put("nonceStr", nonceStr); jsonObject.put("package", "Sign=WXPay"); jsonObject.put("signType", "RSA"); jsonObject.put("sign", packageSign); jsonObject.put("partnerId", mch_id); return jsonObject.toJSONString(); } return ""; } public static String sign(byte[] message, String privateKey) throws NoSuchAlgorithmException, SignatureException, IOException, InvalidKeyException { //签名方式 Signature sign = Signature.getInstance("SHA256withRSA"); //私钥 sign.initSign(PemUtil .loadPrivateKey(privateKey)); sign.update(message); return Base64.getEncoder().encodeToString(sign.sign()); } //生成随机字符串 微信底层的方法,直接copy出来了 protected static String generateNonceStr() { char[] nonceChars = new char[32]; for (int index = 0; index < nonceChars.length; ++index) { nonceChars[index] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".charAt(RANDOM.nextInt("0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".length())); } return new String(nonceChars); } public static String buildMessage(String appId, long timestamp, String nonceStr, String prepay_id) { return appId + "\n" + timestamp + "\n" + nonceStr + "\n" + "prepay_id="+prepay_id + "\n"; }}
2.微信支付工具类
代码如下(示例):
@Slf4j@Componentpublic class WxMiniPayUtils { public static CloseableHttpClient httpClient; public static Verifier verifier; public static void initWXPayClient() throws IOException { try { // 加载商户私钥(privateKey:私钥字符串) PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey({{微信支付私钥字符串}}); // 也可使用证书 查询商户证书序列号// X509Certificate wechatPayCert = PemUtil.loadCertificate(new ByteArrayInputStream(StaticVariable.WX_PAY_CERT.getBytes(StandardCharsets.UTF_8)));// String serialNo = wechatPayCert.getSerialNumber().toString(16).toUpperCase(); String serialNo ={{微信支付商户证书序列号}}; //merchantId:商户号,serialNo:商户证书序列号 // 获取证书管理器实例 CertificatesManager certificatesManager = CertificatesManager.getInstance(); // 向证书管理器增加需要自动更新平台证书的商户信息 certificatesManager.putMerchant({{微信支付-商户号}}, new WechatPay2Credentials({{微信支付-商户号}}, new PrivateKeySigner(serialNo, merchantPrivateKey)), {{微信支付-v3 密钥}}.getBytes(StandardCharsets.UTF_8)); // 从证书管理器中获取verifier //版本>=0.4.0可使用 CertificatesManager.getVerifier(mchId) 得到的验签器替代默认的验签器。 // 它会定时下载和更新商户对应的微信支付平台证书 (默认下载间隔为UPDATE_INTERVAL_MINUTE)。 verifier = certificatesManager.getVerifier({{微信支付-商户号}}); //创建一个httpClient httpClient = WechatPayHttpClientBuilder.create() .withMerchant({{微信支付-商户号}}, serialNo, merchantPrivateKey) .withValidator(new WechatPay2Validator(verifier)).build(); } catch (IOException e) { e.printStackTrace(); log.error("加载秘钥文件失败"); } catch (GeneralSecurityException e) { e.printStackTrace(); log.error("获取平台证书失败"); } catch (Exception e) { e.printStackTrace(); } } public static void closeWXClient() throws IOException { if (httpClient != null) { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } public static String creatOrderJSAPI(String openId,String orderId,Integer amount,String description) throws Exception { try { initWXPayClient(); HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"); httpPost.addHeader("Accept", "application/json"); httpPost.addHeader("Content-type", "application/json; charset=utf-8"); String reqdata = "{" + "\"amount\": {" + "\"total\": "+amount+"," + "\"currency\": \"CNY\"" + "}," + "\"mchid\": \""+{{微信支付-商户号}}+"\"," + "\"description\": \""+description+"\"," + "\"notify_url\": \""+{{微信支付-回调地址}}+"\"," + "\"payer\": {" + "\"openid\": \""+openId+"\"" + "}," + "\"out_trade_no\": \""+orderId+"\"," + "\"goods_tag\": \"WXG\"," + "\"appid\": \""+{{微信APPID}}+"\"" + "}"; httpPost.setEntity(new StringEntity(reqdata, "utf-8")); CloseableHttpResponse response = httpClient.execute(httpPost); String bodyAsString = EntityUtils.toString(response.getEntity()); return bodyAsString; }catch (Exception e){ e.printStackTrace(); log.error("创建微信支付订单失败"); }finally { closeWXClient(); } return ""; }}
三、创建订单
代码如下(示例):
String response= WxMiniPayUtils.creatOrderJSAPI({{用户openId}}, {{订单id}},{{订单金额}},{{订单描述}});JSONObject jsonObject= JSONObject.fromObject(response);if (jsonObject.containsKey("prepay_id")){}
创建微信支付订单,微信会返回 prepay_id (预下单id)用于前端调起支付
四、调起支付
前端通过prepay_id调起支付
五、支付回调
Controller代码如下(示例):
@ApiOperation(value = "微信支付回调", notes = "微信支付回调")@PostMapping(value = "wxAppPayNotify.do")public String wxAppPayNotify( @RequestHeader("Wechatpay-Serial") String wechatpaySerial, @RequestHeader("Wechatpay-Signature") String wechatpaySignature, @RequestHeader("Wechatpay-Timestamp") String wechatpayTimestamp, @RequestHeader("Wechatpay-Nonce") String wechatpayNonce, @RequestBody String callback) throws Exception { return Service.wxAppPayNotify(wechatpaySerial,wechatpaySignature,wechatpayTimestamp,wechatpayNonce,callback);}
验签和解密并返回通知
Servicer代码如下(示例):
@Overridepublic String wxAppPayNotify(String wechatpaySerial, String wechatpaySignature, String wechatpayTimestamp, String wechatpayNonce, String callback) throws Exception {//按照文档要求拼接验签串String verifySignature = wechatpayTimestamp + "\n"+ wechatpayNonce + "\n" + callback + "\n";//使用官方验签工具进行验签boolean verify1 = WxMiniPayUtils.verifier.verify(wechatpaySerial, verifySignature.getBytes(), wechatpaySignature);//判断验签的结果if (!verify1) {//验签失败,应答接口com.alibaba.fastjson.JSONObject jsonResponse = new com.alibaba.fastjson.JSONObject();jsonResponse.put("code", "FAIL");jsonResponse.put("message", "失败");return jsonResponse.toString();}JSONObject parseObject = JSONObject.parseObject(callback);if ("TRANSACTION.SUCCESS".equals(parseObject.getString("event_type"))&& "encrypt-resource".equals(parseObject.getString("resource_type"))) {//通知的类型,支付成功通知的类型为TRANSACTION.SUCCESS//通知的资源数据类型,支付成功通知为encrypt-resourceJSONObject resourceJson = JSONObject.parseObject(parseObject.getString("resource"));String associated_data = resourceJson.getString("associated_data");String nonce = resourceJson.getString("nonce");String ciphertext = resourceJson.getString("ciphertext");//解密,如果这里报错,就一定是APIv3密钥错误AesUtil aesUtil = new AesUtil({{微信支付-v3 密钥}}.getBytes());String resourceData = aesUtil.decryptToString(associated_data.getBytes(), nonce.getBytes(), ciphertext);System.out.println("解密后=" + resourceData);//dosomething 处理业务JSONObject resource =JSONObject.fromObject(resourceData);if (resource.containsKey("out_trade_no")){}}JSONObject jsonResponse = new JSONObject();jsonResponse.put("code", "SUCCESS");jsonResponse.put("message", "成功");return jsonResponse.toString();}
总结
网上的微信支付V3 教程无需看太多 ,专注官方文档
参考文档:https://www.cnblogs.com/cchilei/p/16077207.html
https://blog.csdn.net/m0_59588838/article/details/127204694
来源地址:https://blog.csdn.net/weixin_41476211/article/details/128496850
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341