本文介紹微信公衆号的JSAPI支付方式:
用大白話倒着說:
- 微信支付,最終要實作的是拉起微信支付jsapi提示使用者輸入密碼支付這筆訂單;
- 拉起微信支付jsapi需要的參數有公衆号id,時間戳,随機字元串,訂單詳情擴充字元串,簽名方式,簽名⑥個;
- 訂單詳情擴充字元串是統一下單接口傳回的prepay_id
- 在支付之前需要後端先調用統一下單接口向微信下一筆訂單,将傳回的訂單号告訴前端
- 後端要下單需要先知道為那個使用者下單,即需要使用者唯一辨別openId
- 要擷取openid又需要code,擷取code需要前端引導使用者進行授權操作;
一個最簡單的公衆号網頁支付流程為:使用者進入公衆号=>引導使用者授權=>将code傳給後端=>後端用code擷取openid=>後端下單=>告訴我們訂單号=>拉起微信支付jsapi完成支付;
微信支付業務流程時序圖

一. 場景介紹:
(商戶已有H5商城網站,使用者通過消息或掃描二維碼在微信内打開網頁時,可以調用微信支付完成下單購買的流程)
- 商戶下發圖文消息或者通過自定義菜單吸引使用者點選進入商戶網頁;
- 進入商戶網頁,使用者選擇購買,完成選購流程;
- 調起微信支付控件,使用者開始輸入支付密碼;
- 密碼驗證通過,支付成功。商戶背景得到支付成功的通知;
- 傳回商戶頁面,顯示購買成功。該頁面由商戶自定義;
- 微信支付公衆号下發支付憑證;
- 商戶公衆号下發消息,提示發貨成功。該步驟可選;
二. 互動細節:
- 使用者打開商戶網頁選購商品,發起支付,在網頁通過JavaScript調用getBrandWCPayRequest接口,發起微信支付請求,使用者進入支付流程
- 使用者成功支付點選完成按鈕後,商戶的前端會收到JavaScript的傳回值。商戶可直接跳轉到支付成功的靜态頁面進行展示
- 商戶背景收到來自微信開放平台的支付成功回調通知,标志該筆訂單支付成功。
三. 支付流程圖:
四.前端代碼:
1.引導使用者進入靜默授權頁面(回調連結一定要urlEncode,不然識别不出)
mounted() {
window.onload = function () {
window.location.href =
"https://open.weixin.qq.com/connect/oauth2/authorize?" +
"appid=xxxxxxxxx" +
"&redirect_uri=https%3A%2F%2Fxxx.xxx.xxx?" +
"&response_type=code" +
"&scope=snsapi_base" +
"&state=state";
}
2.進入支付頁面,請求接口,通過code換取openId:
mounted(){
this.code = this.$route.query.code;
},
getWeiXinData() {
getWeiXinOpenId({code: this.code}).then((res) => {
if (res.code === 1) {
this.openId = res.data.openId;
} else {
this.$message({
type: 'error',
message: res.msg
})
}
})
},
3.調用支付接口成功後,調用微信服務窗進行支付:
pay(this.obj).then((res) => {
this.data=JSON.stringify(res.data)
var { data , code} = res.data
if(code == "1"){
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
{
"appId":'xxx', //公衆号名稱,由商戶傳入
"timeStamp":data.timeStamp, //時間戳,自1970年以來的秒數
"nonceStr":data.nonceStr, //随機串
"package":data.package,
"signType":data.signType, //微信簽名方式:
"paySign":data.paySign //微信簽名
},
function(res){
if(res.err_msg=="get_brand_wcpay_request:cancel" ){
alert('已取消支付')
}
});
}).catch(e=>{
console.log(e);
})
五,後端代碼:
1.根據code換取openId
@GetMapping(value = "/getWeiXinOpenId")
public Result getWeiXinOpenId(String code) {
String requestUrl = url.replace("APPID",appId ).replace("SECRET" ,secret).replace("CODE", code);
String result = HttpServletUtils.get(requestUrl);
JSONObject jsonObject = JSONObject.parseObject(result);
String openId = jsonObject.getString("openid");
System.out.println(openId);
return success(openId);
}
2.下單接口:
@RequestMapping(value = "/pay", method = RequestMethod.POST)
public Result pay(@RequestBody PayBean bean) {
if (bean == null){
return failure("支付失敗! 參數異常!");
}
log.info("支付請求參數: " + bean.toString());
JSONObject jsonObject = service.pay(bean);
if (jsonObject.get("code").equals("0")){
return success(jsonObject.get("info"));
}
return failure(jsonObject.get("info").toString());
}
3.支付回調接口:
@RequestMapping(value = "/notify", method = RequestMethod.POST)
public String notify(HttpServletRequest req){
try {
req.setCharacterEncoding("utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String resString = XmlUtils.parseRequst(req);
return service.notify(resString);
}
六.微信公衆号和商戶平台的配置資訊:
- 申請公衆号:
微信公衆号支付流程 -
授權回調頁面域名:
接口權限-網頁賬号-擷取使用者基本資訊
微信公衆号支付流程 微信公衆号支付流程 -
公衆号支付支付目錄
商戶平台–>産品中心–>開發配置
微信公衆号支付流程 -
ip白名單
開發–>基本配置–>IP白名單
微信公衆号支付流程 5.設定支付密鑰app_key
帳戶中心——API安全——設定API密鑰
微信公衆号支付流程