微信支付H5支付
h5 页面接入微信支付
需要配置白名单、商户需要关联、还需要配置支付的url等信息
- 1.判断环境
- 2.获取
code,把code传给后端获取openId - 3.通过
openId、bizType、mobile等业务信息调去后端接口获取支付信息 - 4.通过微信方法唤起支付
const WECHAT_APP_ID = "wx8888888"; // appId
const isWeixin = () => /MicroMessenger/i.test(navigator.userAgent);
const initAuth = async () => {
const code = route.query.code;
if (code) {
try {
const res = await getOpenid({ code });
const nextOpenid = res.msg || "";
if (nextOpenid) {
currentOpenid.value = nextOpenid;
return nextOpenid;
}
} catch (error) {
// code 失效时重新拉起授权
}
triggerAuth();
return "";
}
triggerAuth();
return "";
};
const triggerAuth = () => {
const url = new URL(window.location.href);
url.searchParams.delete("code");
url.searchParams.delete("state");
const redirect = encodeURIComponent(url.toString());
window.location.href =
`https://open.weixin.qq.com/connect/oauth2/authorize` +
`?appid=${WECHAT_APP_ID}` +
`&redirect_uri=${redirect}` +
`&response_type=code` +
`&scope=snsapi_base` +
`&state=weixin_h5#wechat_redirect`;
};
const waitForWeixinBridge = () =>
new Promise((resolve) => {
if (window.WeixinJSBridge) {
resolve(window.WeixinJSBridge);
return;
}
const onReady = () => {
document.removeEventListener("WeixinJSBridgeReady", onReady);
resolve(window.WeixinJSBridge);
};
document.addEventListener("WeixinJSBridgeReady", onReady, false);
});
const normalizePayParams = (payload) => {
if (!payload) {
return null;
}
if (
!payload.appId ||
!payload.timeStamp ||
!payload.nonceStr ||
!payload.prepayId ||
!payload.signType ||
!payload.paySign
) {
return null;
}
return {
appId: payload.appId,
timeStamp: String(payload.timeStamp),
nonceStr: payload.nonceStr,
package: `prepay_id=${payload.prepayId}`,
signType: payload.signType,
paySign: payload.paySign,
};
};
const invokeWeChatPay = async (payParams) => {
const bridge = await waitForWeixinBridge();
return new Promise((resolve, reject) => {
bridge.invoke("getBrandWCPayRequest", payParams, (res) => {
const errMsg = res?.err_msg || "";
if (errMsg.includes("ok")) {
resolve(res);
return;
}
if (errMsg.includes("cancel")) {
reject(new Error("cancel"));
return;
}
reject(new Error(errMsg || "pay failed"));
});
});
};
const stopPayQueryTimer = () => {
if (payQueryTimer) {
clearInterval(payQueryTimer);
payQueryTimer = null;
}
};
const fillActivationCode = (data) => {
if (data?.remark) {
registerForm.value.activationCode = data.remark;
}
};
const checkPayResult = async (orderSn, silent = false) => {
if (!orderSn) {
return false;
}
const res = await queryOrderStu({ orderSn });
const payload = res.data || {};
if (payload.orderStu) {
stopPayQueryTimer();
fillActivationCode(payload);
if (!silent) {
proxy.$message.success("支付成功,激活码已自动填充");
}
return true;
}
return false;
};
const startPayQueryTimer = (orderSn) => {
stopPayQueryTimer();
let currentCount = 0;
payQueryTimer = setInterval(async () => {
currentCount += 1;
if (currentCount > 30) {
stopPayQueryTimer();
proxy.$message.warning("支付结果查询超时,请稍后手动查询密钥");
return;
}
try {
await checkPayResult(orderSn);
} catch (error) {
if (currentCount >= 30) {
stopPayQueryTimer();
}
}
}, 3000);
};
const requestH5PayOrder = async (openid) => {
const res = await buyKey({
mobile: registerForm.value.username,
bizType: "ACT_CODE",
openid,
payType: "JSAPI",
source: "H5_weixin",
});
return res?.data || {};
};
const handleBuyH5Key = async () => {
if (!checkBuyKey()) {
return;
}
if (!isWeixin()) {
proxy.$modal.msgWarning("H5支付请在微信内打开当前页面");
return;
}
h5PayLoading.value = true;
try {
let openid = currentOpenid.value;
if (!openid) {
await initAuth();
return;
}
const orderInfo = await requestH5PayOrder(openid);
const orderSn = orderInfo.orderSn;
if (!orderSn) {
throw new Error("missing orderSn");
}
startPayQueryTimer(orderSn);
const payParams = normalizePayParams(orderInfo);
if (payParams) {
await invokeWeChatPay(payParams);
await checkPayResult(orderSn);
return;
}
if (orderInfo.codeUrl) {
window.location.href = orderInfo.codeUrl;
return;
}
proxy.$message.warning("订单已创建,请等待支付参数返回");
} catch (error) {
if (error?.message === "cancel") {
proxy.$message.warning("已取消支付");
} else {
proxy.$message.error("发起支付失败,请稍后重试");
}
stopPayQueryTimer();
} finally {
h5PayLoading.value = false;
}
};
onMounted(() => {
// 微信环境 且不是 locahost 才执行
if (isWeixin() && !location.host.includes("localhost")) {
initAuth();
}
});