要接入微信支付,需要进行以下步骤:
-
注册微信支付账号并开通支付功能。
-
获取商户号和API密钥。
-
在代码中导入微信支付SDK,并创建统一下单API。
-
设置统一下单API的参数,包括商品描述、订单号、总金额、交易类型等。
-
发送请求并获取微信支付的预支付交易会话标识(prepay_id)。
-
生成签名并返回给客户端,客户端根据签名调用微信支付。
-
用户支付成功后,微信服务器会异步通知商户服务器,商户服务器需要对通知进行处理。
-
商户服务器需要验证通知的签名,并根据订单号更新订单状态。
以下是一个简单的示例代码:
public class WeixinPay {
// 统一下单API
private static final String UNIFIED_ORDER_API = "https://api.mch.weixin.qq.com/pay/unifiedorder";
// 商户号
private static final String MCH_ID = "your_mch_id";
// API密钥
private static final String API_KEY = "your_api_key";
/**
* 统一下单
*
* @param body 商品描述
* @param outTradeNo 订单号
* @param totalFee 总金额(分)
* @param tradeType 交易类型
* @return
* @throws Exception
*/
public static Map<String, String> unifiedOrder(String body, String outTradeNo, int totalFee, String tradeType) throws Exception {
Map<String, String> params = new HashMap<>();
params.put("appid", "your_appid");
params.put("mch_id", MCH_ID);
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", "127.0.0.1");
params.put("notify_url", "your_notify_url");
params.put("trade_type", tradeType);
params.put("sign", generateSign(params, API_KEY));
String xml = mapToXml(params);
String response = doPost(UNIFIED_ORDER_API, xml);
Map<String, String> resultMap = xmlToMap(response);
return resultMap;
}
/**
* 生成签名
*
* @param params
* @param apiKey
* @return
*/
private static String generateSign(Map<String, String> params, String apiKey) {
List<String> keys = new ArrayList<>(params.keySet());
Collections.sort(keys);
StringBuilder sb = new StringBuilder();
for (String key : keys) {
String value = params.get(key);
if (StringUtils.isNotBlank(value) && !"sign".equals(key) && !"key".equals(key)) {
sb.append(key).append("=").append(value).append("&");
}
}
sb.append("key=").append(apiKey);
return DigestUtils.md5Hex(sb.toString()).toUpperCase();
}
/**
* Map转XML
*
* @param params
* @return
* @throws Exception
*/
private static String mapToXml(Map<String, String> params) throws Exception {
Document document = DocumentHelper.createDocument();
Element root = document.addElement("xml");
for (Map.Entry<String, String> entry : params.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (StringUtils.isNotBlank(value)) {
root.addElement(key).addCDATA(value);
}
}
return document.asXML();
}
/**
* XML转Map
*
* @param xml
* @return
* @throws Exception
*/
private static Map<String, String> xmlToMap(String xml) throws Exception {
Map<String, String> resultMap = new HashMap<>();
Document document = DocumentHelper.parseText(xml);
Element root = document.getRootElement();
List<Element> elements = root.elements();
for (Element element : elements) {
resultMap.put(element.getName(), element.getTextTrim());
}
return resultMap;
}
/**
* 发送POST请求
*
* @param url
* @param data
* @return
* @throws Exception
*/
private static String doPost(String url, String data) throws Exception {
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new StringEntity(data, "UTF-8"));
CloseableHttpResponse response = httpClient.execute(httpPost);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
response.close();
httpClient.close();
return result;
}
}