In fact, there have been a lot of cases about wechat payment online. Today, I would like to introduce some easy and easily ignored pits in wechat payment, refund and transfer. As for key, MCID, OPPID and certificate download, there are already comprehensive project dependencies on the web
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.03.</version>
</dependency>
Copy the code
The configuration class:
public class WXConfigUtil implements WXPayConfig {
private final byte[] certData;
private String mchId;
private String key;
public WXConfigUtil(String certPath, String key, String mchId) throws Exception {
// The path where the security certificate downloaded from wechat merchant platform is stored
File file = new File(certPath);
InputStream certStream = new FileInputStream(file);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] b = new byte[1024];
int n;
while((n = certStream.read(b)) ! = -1) {
bos.write(b, 0, n);
}
certStream.close();
bos.close();
// Load the read certificate into cerData(this step is almost useless in articles on the web)
this.certData = bos.toByteArray();
this.mchId = mchId;
this.key = key;
}
@Override
public String getAppID(a) {
return WechatConstant.APP_ID;
}
@Override
public String getMchID(a) {
return mchId;
}
@Override
public String getKey(a) {
return key;
}
@Override
public InputStream getCertStream(a) {
// Get the certificate on request
return new ByteArrayInputStream(this.certData);
}
@Override
public int getHttpConnectTimeoutMs(a) {
return 8000;
}
@Override
public int getHttpReadTimeoutMs(a) {
return 10000; }}Copy the code
In fact, the key configuration above is the configuration of certificate reading. There is no more nonsense, the following is the unified ordering interface processing: Payment :(here has app payment as an example)
Map<String, String> response;
try {
WXConfigUtil wxConfigUtil = new WXConfigUtil(certPath, key, mchid);
WXPay wxPay = new WXPay(wxConfigUtil);
Map<String, String> data = new HashMap<>();
// Randomly generate merchant order numbers
System.out.println("Merchant Order No. ------------" + orderNo);
/ / merchants
data.put("mch_id", wxConfigUtil.getMchID());
// Random string
data.put("nonce_str", WXPayUtil.generateNonceStr());
// Product description
data.put("body"."Description");
// Order number
data.put("out_trade_no", orderNo);
// Total amount (unit cent)
data.put("total_fee".100);
/ / terminal IP
data.put("spbill_create_ip"."124.xx.xx.xx");
// Callback address
data.put("notify_url", notifyUrl);
//appid
data.put("appid", wxConfigUtil.getAppID());
// Transaction type
data.put("trade_type"."APP");
data.put("attach", wechatVo.getUserId().toString());
// Generate a signature
String sign = WXPayUtil.generateSignature(data, wxConfigUtil.getKey(), WXPayConstants.SignType.MD5);
data.put("sign", sign);
String str = WXPayUtil.mapToXml(data);
System.out.println("Turn the map XML" + str);
System.out.println("The number I gave you is + data);
System.out.println("First signature ------------------" + sign);
// Use the official API to request a prepayment order
response = wxPay.unifiedOrder(data);
} catch (Exception e) {
e.printStackTrace();
return null;
}
// Return the result, which can be wrapped itself
return response;
Copy the code
Transfer from business to individual:
Map<String, String> restmap = null;
try {
WXConfigUtil wxConfigUtil = new WXConfigUtil(certPath, key, mchid);
WXPay wxPay = new WXPay(wxConfigUtil);
Map<String, String> param = new HashMap<String, String>();
// Public account appid
param.put("mch_appid", wxConfigUtil.getAppID());
/ / merchants
param.put("mchid", wxConfigUtil.getMchID());
// Random string
param.put("nonce_str", WXPayUtil.generateNonceStr());
// Merchant order number
param.put("partner_trade_no"."");
/ / users openid
param.put("openid", wechatVo.getOpenId());
// Check user name option OPTION_CHECK
param.put("check_name"."NO_CHECK");
param.put("amount"."");
// Enterprise payment description
param.put("desc"."withdraw");
// Server Ip address
param.put("spbill_create_ip"."124.xx.xx.xx");
param.put("sign", WXPayUtil.generateSignature(param, wxConfigUtil.getKey()));
// Carry the certificate request
String restxml = wxPay.requestWithCert("https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers", param, 15000.15000);
assertrestxml ! =null;
restmap = WXPayUtil.xmlToMap(restxml);
} catch (Exception e) {
System.err.println(e.getMessage());
}
// Return the request result
return restmap;
Copy the code
Refund:
HashMap<String, String> data = new HashMap<String, String>();
String orderNo = "VxRefund_" + System.currentTimeMillis();
try {
WXConfigUtil wxConfigUtil = new WXConfigUtil(certPath, key, mchid);
WXPay wxPay = new WXPay(wxConfigUtil);
data.put("appid", wxConfigUtil.getAppID());
data.put("mch_id", wxConfigUtil.getMchID());
data.put("nonce_str", WXPayUtil.generateNonceStr());
// wechat order Number serial number ____
data.put("transaction_id"."Payment serial number");
// Merchant refund slip No. refund slip no. ___
data.put("out_refund_no", orderNo);
// Payment amount. The amount submitted by wechat Pay cannot be numbered with a decimal point and is divided into units. It needs to be converted to a string type, otherwise the signature will fail
data.put("total_fee"."");
// Total amount of refund, total amount of order, in minutes, can only be an integer
data.put("refund_fee"."");
data.put("op_user_id", wxConfigUtil.getMchID());
//MD5 generates the signature, here is the first signature, used to call the unified order interface
String sign = WXPayUtil.generateSignature(data, wxConfigUtil.getKey());
// Generate a signature
data.put("sign", sign);
// Use the carrying certificate request
String s = wxPay.requestWithCert("https://api.mch.weixin.qq.com/secapi/pay/refund", data, 15000.15000);
Map<String, String> response = WXPayUtil.xmlToMap(s);
if ("SUCCESS".equals(returnCode) && returnCode.equals(resultCode)) {
// Todo's own business logic
} else {
return ResultInfo.error("Refund failed"); }}catch (Exception e) {
e.printStackTrace();
}
return ResultInfo.successful("Refund successful");
Copy the code
Unified callback:
StringBuilder sb = new StringBuilder();
try {
// Get the WX callback data
BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
String line = null;
new StringBuilder();
while((line = br.readLine()) ! =null) {
sb.append(line);
}
br.close();
} catch (IOException e) {
e.printStackTrace();
}
//sb is the XML returned by wechat
String notityXml = sb.toString();
System.out.println("= = = = = = = = = = = = = = = = = = = = = = WeChat pay logic to handle asynchronous results began to = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
WXConfigUtil config = null;
try {
config = new WXConfigUtil(certPath, key, mchid);
} catch (Exception e) {
e.printStackTrace();
}
WXPay wxpay = new WXPay(config);
String xmlBack = "";
Map<String, String> notifyMap = null;
try {
// Call the official SDK to convert map data
notifyMap = WXPayUtil.xmlToMap(notityXml);
System.out.println("Returned map----------------" + notifyMap);
// Verify that the signature is valid
System.out.println("Error code returned --------" + notifyMap.get("err_code") + "Error message returned --------" + notifyMap.get("err_code_des"));
if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {
/ / state
String returnCode = notifyMap.get("return_code");
// Merchant order number
String outTradeNo = notifyMap.get("out_trade_no");
String userId = notifyMap.get("attach");
if ("SUCCESS".equals(returnCode)) {
if(outTradeNo ! =null) {
// Business data persistence
String transactionId = notifyMap.get("transaction_id");
// Todo business logic
/ /...
System.err.println("-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- pay success -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --");
xmlBack = "<xml>" + "
" + "
" + "</xml> ";
} else {
xmlBack = "<xml>" + "
" + "
" + "</xml> "; }}}else {
If there is no sign field in the data, it is considered as a signature error
// Do you want to store failed data?
xmlBack = "<xml>" + "
" + "
" + "</xml> "; }}catch (Exception e) {
xmlBack = "<xml>" + "
" + "
" + "</xml> ";
}
return ResultInfo.successful(xmlBack);
Copy the code
The above is just some superficial business logic, hope to help you