Java对接微信支付(史上最详细)
Java对接微信支付(史上最详细)
本文将介绍如何使用Java对接微信支付,包括获取支付参数、支付回调处理等步骤。本文适用于已经熟悉微信支付基本原理的读者。
开发环境
- JDK 1.8
- Maven
- Spring Boot 2.x
- 微信支付开发文档
第一步:获取支付参数
为了进行支付,我们需要先获取微信支付的参数信息,包括appid、商户id、支付密钥等。
配置文件
我们可以将这些参数信息放在一个配置文件中,以便后续使用。在Spring Boot中,可以通过application.yml或者application.properties文件配置。
wechat: appid: xxx # 微信公众号appid mchid: xxx # 商户id key: xxx # 支付密钥 notifyUrl: xxx # 支付回调地址
获取签名
获取到参数信息后,我们需要对其进行签名,以确保支付安全性。签名算法具体可以参考微信官方文档。
public static String sign(Map params, String key) { String signStr = SignUtil.createLinkString(params) + "&key=" + key; return MD5Util.md5(signStr).toUpperCase();}
其中,createLinkString方法用于将参数按照字典序拼接为一个字符串,MD5Util.md5方法用于生成MD5签名,toUpperCase方法用于将签名转换成大写。
第二步:生成支付参数
获取到签名后,我们需要根据支付金额、订单号等信息生成一个可以供客户端调用的支付参数。
统一下单接口
我们可以通过微信提供的统一下单接口生成支付参数。
public static Map unifiedOrder(String appid, String mchId, String key, String body, String outTradeNo, int totalFee, String spBillCreateIp, String notifyUrl, String tradeType, String openid) throws Exception { Map params = new HashMap<>(); params.put("appid", appid); params.put("mch_id", mchId); params.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", "")); params.put("body", body); params.put("out_trade_no", outTradeNo); params.put("total_fee", String.valueOf(totalFee)); params.put("spbill_create_ip", spBillCreateIp); params.put("notify_url", notifyUrl); params.put("trade_type", tradeType); params.put("openid", openid); params.put("sign", SignUtil.sign(params, key)); String xml = HttpUtil.post(UNIFIED_ORDER_URL, XmlUtil.mapToXml(params)); Map result = XmlUtil.xmlToMap(xml); if ("SUCCESS".equals(result.get("return_code")) && "SUCCESS".equals(result.get("result_code"))) { return result; } else { throw new Exception(result.get("return_msg")); }}
其中,UNIFIED_ORDER_URL为统一下单接口地址。HttpUtil.post方法用于发送POST请求并获取响应结果,XmlUtil.mapToXml和XmlUtil.xmlToMap方法用于将Map对象和XML字符串互相转换。
生成支付参数
统一下单接口返回的结果中包含了prepay_id,我们需要将其作为参数再次签名生成支付参数。
public static String createPayParams(String appId, String prepayId, String key) { Map params = new HashMap<>(); params.put("appId", appId); params.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000)); params.put("nonceStr", UUID.randomUUID().toString().replaceAll("-", "")); params.put("package", "prepay_id=" + prepayId); params.put("signType", "MD5"); params.put("paySign", SignUtil.sign(params, key)); return JsonUtil.toJson(params);}
其中,JsonUtil.toJson方法用于将Map对象转换成JSON字符串。
第三步:处理支付回调
当客户端支付完成后,微信会回调我们预先设置的支付回调地址,我们需要在该地址上接收并处理回调信息。
支付回调接口
我们可以将支付回调信息封装成一个实体类,用于接收并处理回调信息。
@Datapublic class PayNotify { private String return_code; private String return_msg; private String appid; private String mch_id; private String nonce_str; private String sign; private String result_code; private String openid; private String trade_type; private String bank_type; private Integer total_fee; private String fee_type; private String transaction_id; private String out_trade_no; private String attach; private String time_end;}
处理支付结果
接收到支付回调信息后,我们需要校验签名并处理支付结果。
@PostMapping("/pay/notify")public String payNotify(@RequestBody PayNotify payNotify) { Map params = new HashMap<>(); params.put("appid", payNotify.getAppid()); params.put("mch_id", payNotify.getMch_id()); params.put("nonce_str", payNotify.getNonce_str()); params.put("result_code", payNotify.getResult_code()); params.put("openid", payNotify.getOpenid()); params.put("trade_type", payNotify.getTrade_type()); params.put("bank_type", payNotify.getBank_type()); params.put("total_fee", payNotify.getTotal_fee().toString()); params.put("fee_type", payNotify.getFee_type()); params.put("transaction_id", payNotify.getTransaction_id()); params.put("out_trade_no", payNotify.getOut_trade_no()); params.put("attach", payNotify.getAttach()); params.put("time_end", payNotify.getTime_end()); String sign = SignUtil.sign(params, key); if (!sign.equals(payNotify.getSign())) { return " "; } // 处理支付结果 return " ";}
其中,key为支付密钥。
总结
本文介绍了使用Java对接微信支付的步骤,包括获取支付参数、生成支付参数、处理支付回调等。希望对大家有所帮助。
来源地址:https://blog.csdn.net/Ellis_li/article/details/131010470
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341