前期准備
H5支付V2版本
官方文檔
需要的參數
-
app_id:公眾號或者小程序申請
-
mch_id:在微信商戶平台申請
-
支付密鑰:申請后在商戶平台中設置支付密鑰和證書。這個記得保存,因為證書讓進行二次下載,找不到了只能重新設置。
-
SDK下載:官方SDK下載地址
官方流程圖
Java后台編寫WXPayConfig的實現類進行必要參數配置
/**
* 微信支付參數配置
*/
public class IWXPayConfig extends WXPayConfig {
private byte[] certData;
private String app_id = "自己的appid";
private String wx_pay_key = "自己的支付密鑰";
private String wx_pay_mch_id = "自己的商戶號";
/**
* 構造方法讀取證書, 通過getCertStream 可以使sdk獲取到證書
*/
public IWXPayConfig() throws Exception {
String certPath = "證書的路徑";
File file = new File(certPath);
InputStream certStream = new FileInputStream(file);
this.certData = new byte[(int) file.length()];
certStream.read(this.certData);
certStream.close();
}
@Override
protected String getAppID() {
return app_id;
}
@Override
public String getMchID() {
return wx_pay_mch_id;
}
@Override
protected String getKey() {
return wx_pay_key;
}
@Override
protected InputStream getCertStream() {
return new ByteArrayInputStream(this.certData);
}
@Override
protected IWXPayDomain getWXPayDomain() { // 這個方法需要這樣實現, 否則無法正常初始化WXPay
IWXPayDomain iwxPayDomain = new IWXPayDomain() {
@Override
public void report(String domain, long elapsedTimeMillis, Exception ex) {
}
@Override
public DomainInfo getDomain(WXPayConfig config) {
return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true);
}
};
return iwxPayDomain;
}
}
進行調用微信官方的SDK下單
public static Map placeAnOrder() throws Exception {
IWXPayConfig wxPayConfig = new IWXPayConfig();
WXPay wxPay = new WXPay(wxPayConfig);
Map<String, String> data = new HashMap<>();
data.put("body", "商品描述");
data.put("total_fee", "1"); // 訂單金額, 單位分
data.put("spbill_create_ip", "114.114.114.114"); // 下單ip
data.put("notify_url", "http://xxxxxxxx/payCallback"); // 訂單結果通知, 微信主動回調此接口
data.put("out_trade_no", "2016090910595900000028"); // 訂單唯一編號, 不允許重復
data.put("trade_type", "MWEB"); // 交易類型 MWEB--H5支付、JSAPI--小程序支付 每個類型需要參數不同
return wxPay.unifiedOrder(data);
}
訂單通知地址需要外網可以訪問,如果沒有可以用映射的方式映射本地的端口讓外網訪問。這里推薦免費的映射軟件:閃庫 這個軟件也是我開發時用的,主要是免費
調用后會返回數據這些數據官方文檔都有介紹不多說了。
其中最重要的一個就是mweb_url這個參數,這個就是支付地址了。如果直接訪問這個地址就會出現下方的錯誤信息:
這個官方也有解釋是因為請求頭中的referer為空導致的。
這個值是自己在商戶平台進行配置的地址。
這里面有個授權域名這個就是referer的值。這個值的意思就是告訴微信從哪里跳轉過來的。
在瀏覽器通過工具改以下這個值就可以正常訪問,但是如果是pc瀏覽器訪問的可能是空白頁面,這個時候F12看下應該是提示沒有解析什么的東西。這個是因為pc瀏覽器無法拉起微信客戶端進行支付。
在手機瀏覽器沒有辦法設置請求頭,所以只能進入自己設置的那個域名服務器設置個標簽進行跳轉了。然后就能進行支付了。這個真的會支付掉,我開發沒有找到如何微信的沙盒。
設置回調方法
/**
* 支付結果回調
*/
@RequestMapping(value = "/payCallback")
public String payCallback(HttpServletRequest request) {
Map<String, String> back = new HashMap(); // 校驗結果
String backXml = ""; // 校驗結果XML
try {
InputStream inStream = request.getInputStream();
ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inStream.read(buffer)) != -1) {
outSteam.write(buffer, 0, len);
}
outSteam.close();
inStream.close();
String result = new String(outSteam.toByteArray());
Map<String, String> map = WXPayUtil.xmlToMap(result);//xml轉map 微信SDK自帶
// 判斷簽名是否正確
if (WXPayUtil.isSignatureValid(data, wxPayConfig.getKey(), WXPayConstants.SignType.HMACSHA256)) { // 這里記得指定加密方式,因為下單默認的是h256方式,校驗默認是MD5方式
back.put("return_code", "SUCCESS");
if (BusinessStatus.SUCCESS.equals(map.get("result_code")));{ // 判斷支付成功
// 進行自己的業務處理
}
} else {
back.put("return_code", "FAIL");
back.put("return_msg", "參數格式校驗錯誤");
}
backXml = WXPayUtil.mapToXml(back);
} catch (Exception e) {
e.printStackTrace();
} finally {
return backXml;
}
}
這個方法微信可能多次調用,這個官方也有說明自己做好處理。
參考文章
本人開發后寫的博客,其中可能有遺漏的地方。有問題歡迎指出