前言
本文只聚焦支付逻辑:在一个 Vue 组件里同时兼容 Apple Pay、Google Pay 与钱海信用卡(Oceanpayment)。核心思路是"分三条链路获取 quickpayId,最后统一交给 processPayment"。
代码讲解
Apple Pay
ts
const createApplePaySession = () => {
const request = {
countryCode: PAYMENT_CONFIG.applePay.countryCode,
currencyCode: PAYMENT_CONFIG.applePay.currencyCode,
supportedNetworks: PAYMENT_CONFIG.applePay.supportedNetworks,
total: {
label: PAYMENT_CONFIG.applePay.displayName,
amount: parseFloat(currentPrice.value).toFixed(2),
type: "final"
}
};
return new Promise((resolve, reject) => {
const session = new ApplePaySession(3, request);
session.onvalidatemerchant = async () => {
const resp = await getApplePayMerchantValidation({
initiative: "web",
initiativeContext: "h5.tanlinkerp.cn",
merchantIdentifier: PAYMENT_CONFIG.applePay.merchantId
});
session.completeMerchantValidation(
typeof resp.data === "string" ? JSON.parse(resp.data) : resp.data
);
};
session.onpaymentauthorized = event => {
const token = event.payment?.token?.paymentData;
session.completePayment(token ? ApplePaySession.STATUS_SUCCESS : ApplePaySession.STATUS_FAILURE);
token ? resolve(token) : reject(new Error("Invalid payment data"));
};
session.oncancel = () => reject(new Error("User cancelled"));
session.onerror = err => reject(new Error(err.message));
session.begin();
});
};
图示说明:这段代码做两件事------1)在
onvalidatemerchant里向后端要merchantSession;2)在onpaymentauthorized中拿到paymentData并返回。
- 拿到
paymentData后,调用getGoogleOrAppleBindCard({ methods: "ApplePay", payAccountNumber: token })。 - 接口返回
quickpayId,再执行processPayment(quickpayId, "Apple Pay")。
Google Pay
ts
const createGooglePaySession = async () => {
const paymentsClient = new google.payments.api.PaymentsClient({
environment: PAYMENT_CONFIG.googlePay.environment
});
const paymentDataRequest = {
apiVersion: 2,
allowedPaymentMethods: [{
type: "CARD",
parameters: {
allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
allowedCardNetworks: ["MASTERCARD", "VISA"]
},
tokenizationSpecification: {
type: "PAYMENT_GATEWAY",
parameters: { gateway: "example", gatewayMerchantId: "exampleGatewayMerchantId" }
}
}],
transactionInfo: {
totalPriceStatus: "FINAL",
totalPrice: parseFloat(currentPrice.value).toFixed(2),
currencyCode: "USD"
},
merchantInfo: PAYMENT_CONFIG.googlePay
};
const paymentData = await paymentsClient.loadPaymentData(paymentDataRequest);
return paymentData.paymentMethodData.tokenizationData.token;
};
- Google Pay 只需要
loadPaymentData,但在展示入口之前最好调用paymentsClient.isReadyToPay()过滤不可用设备。 - 获取的
token走getGoogleOrAppleBindCard({ methods: "GooglePay" }),返回quickpayId后仍旧调用processPayment(quickpayId, "Google Pay")。
钱海信用卡
ts
const fetchUserCards = async () => {
const response = await getUserCards({ country: userCountry.value });
if (response.code === 200) {
userCards.value = response.data;
selectedCard.value = 0;
selectedPayment.value = "credit";
}
};
const handleSubmit = async () => {
if (selectedPayment.value === "credit") {
const quickpayId = userCards.value[selectedCard.value]?.quickPayId;
await processPayment(quickpayId, "Credit Card");
}
};
- 信用卡
quickpayId来自绑卡页(Oceanpayment SDK),支付页只负责取值并回传后端。 processPayment内部会拼payDetailId、backUrl、payMethod,调用getSubAndZf。返回payUrl时直接window.location.href = payUrl,否则跳paymentStatus。
关键知识点
- 统一出口 :所有方式都必须拿到
quickpayId才能进入processPayment,便于维护和埋点。 - 安全检查 :Apple/Google Pay 均需 HTTPS 或安全上下文,并提前检测
ApplePaySession、google.payments是否存在。 - 倒计时 + 状态恢复 :
startCountdown限制 15 分钟窗口,sessionStorage.paymentData保存payDetailId与金额,用于刷新/跳转后的恢复。 - SDK 加载 :Google Pay 通过
loadSDKs按需注入脚本;Apple Pay 无需额外脚本,但要处理商户验证超时。
最佳实践 / 扩展方案
- 错误分类:针对"用户取消""商户验证失败""绑定失败"分别提示并上报,方便排查。
- 动态排序 :根据设备或
userCountry调整支付方式顺序,例如 iOS 优先展示 Apple Pay。 - 离线兜底:倒计时结束时提示用户联系人工,避免订单遗失。
- 监控指标 :在
selectPayment、handleSubmit、processPayment打点,分析各通道转化。
小结
整合多支付的关键是把 Apple Pay、Google Pay、钱海信用卡看作三条"获取 quickpayId 的管道"。一旦拿到 quickpayId,就能统一交给 processPayment,并享受相同的倒计时、状态恢复和跳转逻辑。需要扩展新的支付方式时,遵循这套模式即可快速接入。