当前位置:   article > 正文

Java实现微信支付功能_wechatpay-java

wechatpay-java

微信实现支付功能与支付宝实现支付功能是相似的,接入前的准备工作,包括申请APPID、申请mchid、绑定APPID及mchid、配置API key、下载并配置商户证书等,具体可查看微信支付文档

接入前准备-APP支付 | 微信支付商户平台文档中心 (qq.com)正在上传…重新上传取消https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_5_1.shtmlicon-default.png?t=M5H6https://link.juejin.cn?target=https%3A%2F%2Fpay.weixin.qq.com%2Fwiki%2Fdoc%2Fapiv3%2Fopen%2Fpay%2Fchapter2_5_1.shtml之后需要将APP与微信支付进行绑定,文档如下:

看一下微信支付的流程图:

编辑微信支付的流程,同样与支付宝相似, 微信支付需要调微信生成预付单,然后由客户端发起真正的支付。

支付流程

基于APP支付来说,微信支付的大体流程:
1、APP客户端根据用户支付请求,将订单信息(订单号,金额等)传至后台服务器
2、后台服务器根据订单信息,拼装微信统一下单接口需要的请求参数。其中比较重要的参数为appidmch_idnonce_strsignout_trade_nototal_feenotify_url

这里参数拼装需要根据微信提供的签名算法
假设请求参数为:

  1. "appid""wxd930ea5d5a258f4f"
  2. "mch_id""10000100"
  3. "body""test"
  4. "nonce_str""ibuaiVcKdpRxkhJA"

需要将以上参数按照规则先拼装成String

  1. key值按照ASCII从小到大排序(A->Z),key=value形式并用&连接
String a = "appid=wxd930ea5d5a258f4f&mch_id=10000100&body=test&nonce_str=ibuaiVcKdpRxkhJA"
  1. 拼接API密钥 key 是商户平台设置的密钥key
signStr = a + "&key=192006250b4c09247ec02edce69f6a2d"
  1. MD5签名(转大写) 注:微信默认为MD5签名,也支持HMAC-SHA256签名方式
sign=MD5(signStr).toUpperCase()

然后sign继续按照规则(A->Z)拼装进String中。
java中可以用map完成排序

  1. Map<String, String> paramsMap = new TreeMap<String, String>(String::compareTo);
  2. paramsMap.put("appid", APP_APP_ID);
  3. paramsMap.put("sign",sign);

最后需要将参数转化成xml格式的string进行接口请求

  1. <xml>
  2. <appid>![CDATA[wxd930ea5d5a258f4f]]</appid>
  3. <mch_id>![CDATA[10000100]]</mch_id>
  4. <device_info>![CDATA[1000]]</device_info>
  5. <body>![CDATA[test]]</body>
  6. <nonce_str>![CDATA[ibuaiVcKdpRxkhJA]]</nonce_str>
  7. <sign>![CDATA[9A0A8659F005D6984697E2CA0A9CF3B7]]</sign>
  8. </xml>

微信支付请求参数

  1. Map<String, String> callWeChatPay = new HashMap<>();
  2. // 调用微信统一下单接口
  3. Map<String, String> requestPara = new HashMap<>();
  4. // 公众账号ID
  5. requestPara.put("appid", appid);
  6. // 商户号
  7. requestPara.put("mch_id", mch_id);
  8. // 商品描述
  9. requestPara.put("body", body);
  10. requestPara.put("out_trade_no", tradeNo);
  11. // 总金额
  12. requestPara.put("total_fee", amount.intValue() + "");
  13. // 终端IP
  14. requestPara.put("spbill_create_ip", "127.0.0.1");
  15. // 通知地址
  16. requestPara.put("notify_url", notify_url);
  17. // 交易类型
  18. requestPara.put("trade_type", "APP");
  19. //加密方式
  20. requestPara.put("sign_type", FreePayUtils.MD5);
  21. //标价币种
  22. requestPara.put("fee_type", "CNY");
  23. //订单失效时间
  24. requestPara.put("time_expire", DateUtil.addMinute("", 10, "yyyyMMddHHmmss"));
  25. //签名
  26. String sign = WechatPaykey(微信支付秘钥生成);
  27. //parseString2Xml
  28. String xmlData = FreePayUtils.parseString2Xml(requestPara, sign);
  29. //调用微信统一下单接口
  30. HttpSupport httpSupport = HttpSupport.makeConnect();
  31. String result = httpSupport.doPostBody("https://api.mch.weixin.qq.com/pay/unifiedorder", xmlData).result();
  32. //xmlToMap
  33. Map<String, String> returnMap = FreePayUtils.xmlToMap(result);
  34. String returnCode = returnMap.get("return_code");
  35. String resultCode = returnMap.get("result_code");
  36. if ("SUCCESS".equals(returnCode) && "SUCCESS".equals(resultCode)) {
  37. String prepayId = returnMap.get("prepay_id");
  38. //应用ID
  39. callWeChatPay.put("appid", waistcoat.getWechatAppid());
  40. //商户号
  41. callWeChatPay.put("partnerid", waistcoat.getWechatMchid());
  42. //预支付交易会话ID
  43. callWeChatPay.put("prepayid", prepayId);
  44. //扩展字段
  45. callWeChatPay.put("package", "Sign=WXPay");
  46. callWeChatPay.put("noncestr", FreePayUtils.generateNonceStr());
  47. callWeChatPay.put("timestamp", FreePayUtils.getCurrentTimestamp() + "");
  48. // 签名
  49. String appSign = FreePayUtils.generateSignature(callWeChatPay, waistcoat.getWechatPaykey());
  50. callWeChatPay.put("sign", appSign);

微信支付统一下单的接口地址为:api.mch.weixin.qq.com/pay/unified…
java中可以利用httpclient进行post调用。参数即之前拼接完成的带sign签名参数。
(需要将参数转化成xml格式的string进行接口请求)。
返回的数据包含了return_code、return_msg。return_code只有SUCCESS和FAIL,这是通信成功与否的标识,非业务标识。只有return_code是SUCCESS时,才会有其他数据返回包括result_code,sign等。若result_code业务标识也同样为SUCCESS时候才说明微信方预付单生成成功。这时会返回我们支付业务需要的prepay_id预支付会话id。 注意: 这里需要我们进行sign签名验证,以保证数据安全性。\

返回的数据是XML格式的,如下

  1. <xml>
  2. <appid><![CDATA[wx2421b1c4370ec43b]]></appid>
  3. <attach><![CDATA[支付测试]]></attach>
  4. <bank_type><![CDATA[CFT]]></bank_type>
  5. <fee_type><![CDATA[CNY]]></fee_type>
  6. <is_subscribe><![CDATA[Y]]></is_subscribe>
  7. <mch_id><![CDATA[10000100]]></mch_id>
  8. <nonce_str><![CDATA[5d2b6c2a8db53831f7eda20af46e531c]]></nonce_str>
  9. <openid><![CDATA[oUpF8uMEb4qRXf22hE3X68TekukE]]></openid>
  10. <out_trade_no><![CDATA[1409811653]]></out_trade_no>
  11. <result_code><![CDATA[SUCCESS]]></result_code>
  12. <return_code><![CDATA[SUCCESS]]></return_code>
  13. <sign><![CDATA[B552ED6B279343CB493C5DD0D78AB241]]></sign>
  14. <time_end><![CDATA[20140903131540]]></time_end>
  15. <total_fee>1</total_fee>
  16. <coupon_fee><![CDATA[10]]></coupon_fee>
  17. <coupon_count><![CDATA[1]]></coupon_count>
  18. <coupon_type><![CDATA[CASH]]></coupon_type>
  19. <coupon_id><![CDATA[10000]]></coupon_id>
  20. <coupon_fee><![CDATA[100]]></coupon_fee>
  21. <trade_type><![CDATA[JSAPI]]></trade_type>
  22. <transaction_id><![CDATA[1004400740201409030005092168]]></transaction_id>
  23. </xml>

所以拿到微信支付的结果之后,需要转换成自己需要的格式。

将这些数据返回给客户端,由客户端发起支付,就可以实现微信的支付功能。然后微信端会根据之前设置的notify_url异步通知地址,进行调用,通知服务端支付情况。

商户系统对于支付结果通知的内容一定要做签名验证,并校验返回的订单金额是否与商户侧的订单金额一致,防止数据泄漏导致出现“假通知”,造成资金损失。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/467392
推荐阅读
相关标签
  

闽ICP备14008679号