java 对接 微信小程序支付
时间: 2023-09-25 19:13:29 浏览: 115
要在 Java 中对接微信小程序支付,你需要完成以下步骤:
1. 获取微信支付的 API 密钥和商户号,以及小程序 appID 和 appSecret。
2. 在小程序开发者工具中创建支付统一下单接口,并记录好接口地址。
3. 在 Java 中编写代码,向微信支付下单接口发送请求,并获取返回的 prepay_id。
4. 将 prepay_id 和其他参数按照微信支付要求的格式进行签名,并返回给前端。
5. 前端通过微信小程序支付 API 调起支付界面,用户完成支付后,微信服务器会向商户服务器发送支付结果通知。
6. 商户服务器接收到支付结果通知后,需要进行签名验证和订单处理。
以下是一份示例代码,可以帮助你完成微信小程序支付的对接:
```java
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
public class WechatPayment {
private String appid; // 小程序 ID
private String mch_id; // 商户号
private String key; // API 密钥
public WechatPayment(String appid, String mch_id, String key) {
this.appid = appid;
this.mch_id = mch_id;
this.key = key;
}
public Map<String, String> unifiedorder(String body, String out_trade_no, int total_fee, String spbill_create_ip, String notify_url) throws Exception {
SortedMap<String, String> params = new TreeMap<String, String>();
params.put("appid", appid);
params.put("mch_id", mch_id);
params.put("nonce_str", getRandomString(32));
params.put("body", body);
params.put("out_trade_no", out_trade_no);
params.put("total_fee", String.valueOf(total_fee));
params.put("spbill_create_ip", spbill_create_ip);
params.put("notify_url", notify_url);
params.put("trade_type", "JSAPI");
params.put("openid", "用户的 openid");
String sign = createSign(params);
params.put("sign", sign);
String xml = mapToXml(params);
String responseXml = HttpUtils.post("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(responseXml.getBytes()));
Element rootElement = document.getDocumentElement();
String return_code = getElementValue(rootElement, "return_code");
String result_code = getElementValue(rootElement, "result_code");
String prepay_id = getElementValue(rootElement, "prepay_id");
if ("SUCCESS".equals(return_code) && "SUCCESS".equals(result_code) && prepay_id != null) {
Map<String, String> result = new HashMap<String, String>();
result.put("prepay_id", prepay_id);
String nonce_str = getRandomString(32);
result.put("nonceStr", nonce_str);
result.put("timeStamp", String.valueOf(System.currentTimeMillis() / 1000));
result.put("signType", "MD5");
result.put("package", "prepay_id=" + prepay_id);
sign = createSign(result);
result.put("paySign", sign);
return result;
} else {
throw new Exception(getElementValue(rootElement, "return_msg"));
}
}
private String createSign(Map<String, String> params) throws NoSuchAlgorithmException {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : params.entrySet()) {
if (entry.getValue() != null && entry.getValue().length() > 0 && !"sign".equals(entry.getKey()) && !"key".equals(entry.getKey())) {
sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
}
}
sb.append("key=").append(key);
MessageDigest md = MessageDigest.getInstance("MD5");
md.update(sb.toString().getBytes());
byte[] digest = md.digest();
StringBuilder signBuilder = new StringBuilder();
for (byte b : digest) {
String hex = Integer.toHexString(b & 0xff);
if (hex.length() == 1) {
signBuilder.append("0");
}
signBuilder.append(hex);
}
return signBuilder.toString().toUpperCase();
}
private String mapToXml(Map<String, String> params) {
StringBuilder sb = new StringBuilder();
sb.append("<xml>");
for (Map.Entry<String, String> entry : params.entrySet()) {
sb.append("<").append(entry.getKey()).append(">");
sb.append(entry.getValue());
sb.append("</").append(entry.getKey()).append(">");
}
sb.append("</xml>");
return sb.toString();
}
private String getElementValue(Element element, String tagName) {
Element childElement = (Element) element.getElementsByTagName(tagName).item(0);
if (childElement != null) {
return childElement.getTextContent();
}
return null;
}
private String getRandomString(int length) {
String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
StringBuilder sb = new StringBuilder();
for (int i = 0; i < length; i++) {
sb.append(str.charAt((int) (Math.random() * str.length())));
}
return sb.toString();
}
}
```
其中,HttpUtils.post() 方法用于发送 HTTP POST 请求,你需要自己实现。在 unifiedorder() 方法中,我们按照微信支付要求的格式构造请求参数,并对参数进行签名。然后向微信支付下单接口发送请求,获取 prepay_id。最后,我们将 prepay_id 和其他参数按照微信支付要求的格式进行签名,并返回给前端。
阅读全文