chore: 重新与HuaweiPay分支比较,起点

This commit is contained in:
Zhukj
2025-12-10 11:20:42 +08:00
parent 5bd0881946
commit f1c01833e4
10 changed files with 209 additions and 569 deletions

View File

@@ -4,7 +4,7 @@
<uni-popup ref="choosePaymentPopup" type="center" v-if="payInfo" :mask-click="false">
<view class="choose-payment-popup popup" @touchmove.prevent.stop>
<view class="popup-header">
<text class="tit">支付方式-测试</text>
<text class="tit">支付方式</text>
<text class="iconfont icon-close" @click="close()"></text>
</view>
<scroll-view scroll-y="true" class="popup-body">
@@ -51,13 +51,13 @@ import uniPopup from '@/components/uni-popup/uni-popup.vue';
import nsSwitch from '@/components/ns-switch/ns-switch.vue';
// #ifdef H5
import { Weixin } from 'common/js/wx-jssdk.js';
import {
Weixin
} from 'common/js/wx-jssdk.js';
// #endif
// ========== 引入三端支付工具类(核心:适配官方规范) ==========
import { getWechatPay } from '@/utils/wechat-pay.js';
import { getAlipayPay } from '@/utils/alipay-pay.js';
import { getHuaweiPay } from '@/utils/huawei-pay.js';
// 引入统一支付工具类
import { invokeWechatPay, invokeAlipay, invokeHuaweiPay } from '../../common/js/payCore.js';
export default {
name: 'payment',
@@ -76,24 +76,27 @@ export default {
return {
payIndex: 0,
payTypeList: [
// 所有端都显示微信支付
{
name: '微信支付',
icon: 'icon-weixin1',
type: 'wechatpay'
},
// 所有端都显示支付宝支付
// #ifdef H5 || MP-ALIPAY
{
name: '支付宝支付',
icon: 'icon-zhifubaozhifu-',
type: 'alipay'
},
// 所有端都显示华为支付
// #endif
// #ifdef H5 || MP-WEIXIN
{
name: '微信支付',
icon: 'icon-weixin1',
type: 'wechatpay'
},
// #endif
// #ifdef H5 || QUICKAPP-HUAWEI
{
name: '华为支付',
icon: 'icon-zhekou',
type: 'huaweipay'
},
// #endif
{
name: '线下支付',
icon: 'icondiy icon-yuezhifu',
@@ -112,17 +115,11 @@ export default {
//重置是否已完成没有完成不能调用api/pay/pay
resetPayComplete: true,
repeatFlag: false,
// ========== 支付工具类实例 ==========
wechatPay: null,
alipayPay: null,
huaweiPay: null
};
},
created(e) {
this.getPayType();
if (this.balanceUsable) this.getBalanceConfig();
// ========== 初始化三端支付工具类(填写官方申请的参数) ==========
this.initPayUtils();
},
computed: {
balanceDeduct() {
@@ -152,34 +149,6 @@ export default {
}
},
methods: {
// ========== 初始化支付工具类(核心:配置官方参数) ==========
initPayUtils() {
// 微信支付初始化(替换为你的微信官方参数)
this.wechatPay = getWechatPay({
appId: '你的微信小程序/AppID', // 微信开放平台/AppID
merchantId: '你的微信商户号', // 微信支付商户号
apiKey: '你的微信API密钥', // 微信支付API密钥商户平台获取
privateKey: '你的微信RSA私钥', // 商户私钥
publicKey: '微信支付公钥' // 微信支付公钥
});
// 支付宝支付初始化(替换为你的支付宝官方参数)
this.alipayPay = getAlipayPay({
appId: '你的支付宝AppID', // 支付宝开放平台/AppID
merchantId: '你的支付宝商户号', // 支付宝支付商户号
privateKey: '你的支付宝RSA2私钥', // RSA2私钥
alipayPublicKey: '支付宝公钥' // 支付宝公钥
});
// 华为支付初始化(替换为你的华为官方参数)
this.huaweiPay = getHuaweiPay({
appId: '你的华为AppID', // 华为开发者联盟AppID
merchantId: '你的华为商户号', // 华为支付商户号
publicKey: '华为支付公钥', // 华为支付公钥
privateKey: '你的华为商户私钥', // 华为商户私钥
env: 'sandbox' // 测试环境sandbox生产环境production
});
},
/**
* 父级页面onShow调用
*/
@@ -193,6 +162,7 @@ export default {
} else {
uni.removeStorageSync('offlinepay');
}
},
close() {
this.$emit('close');
@@ -294,156 +264,87 @@ export default {
// #ifdef H5
pay() {
var payType = this.payTypeList[this.payIndex];
var return_url = '';
if (this.payInfo.event == 'BlindboxGoodsOrderPayNotify') {
return_url = '/pages_promotion/blindbox/index?outTradeNo=';
} else {
return_url = '/pages_tool/pay/result?code=';
if (!payType || payType.type === 'offlinepay') {
// 线下支付仍使用原有逻辑
this.payOffline();
return;
}
this.$api.sendRequest({
url: '/api/pay/pay',
data: {
out_trade_no: this.payInfo.out_trade_no,
pay_type: payType ? payType.type : '',
return_url: encodeURIComponent(this.$config.h5Domain + return_url + this.payInfo.out_trade_no),
is_balance: this.isBalance
},
success: async res => { // 新增async支持异步调用
uni.hideLoading();
if (res.code >= 0) {
if (res.data.pay_success) {
this.paySuccess();
return;
}
switch (payType.type) {
// ========== 支付宝支付H5端符合官方RSA2规范 ==========
case 'alipay':
try {
this.repeatFlag = false;
const orderInfo = {
outTradeNo: this.payInfo.out_trade_no,
productName: '订单支付',
price: this.payMoney,
returnUrl: this.$config.h5Domain + return_url + this.payInfo.out_trade_no,
notifyUrl: this.$config.h5Domain + '/api/pay/alipay/notify'
};
// 创建支付宝订单带RSA2签名
const alipayRes = await this.alipayPay.h5Pay(orderInfo);
// 验证支付宝签名(官方规范)
const isAlipaySignValid = this.alipayPay.verifyResult(alipayRes, alipayRes.sign);
if (!isAlipaySignValid) {
this.$util.showToast({ title: '支付宝订单签名验证失败' });
return;
}
// 区分微信浏览器/普通浏览器
if (this.$util.isWeiXin()) {
var wx_alipay = encodeURIComponent(alipayRes.payUrl);
this.$util.redirectTo('/pages_tool/pay/wx_pay', {
wx_alipay: wx_alipay,
out_trade_no: this.payInfo.out_trade_no
}, '', 'redirectTo');
} else {
location.href = alipayRes.payUrl;
this.checkPayStatus();
}
} catch (error) {
this.$util.showToast({ title: '支付宝支付失败:' + error.message });
this.repeatFlag = false;
}
break;
// ========== 微信支付H5端符合官方JSSDK+签名规范) ==========
case 'wechatpay':
try {
this.repeatFlag = false;
const orderInfo = {
outTradeNo: this.payInfo.out_trade_no,
productName: '订单支付',
price: this.payMoney,
openid: this.$store.state.openid,
notifyUrl: this.$config.h5Domain + '/api/pay/wechat/notify',
returnUrl: this.$config.h5Domain + return_url + this.payInfo.out_trade_no,
url: uni.getSystemInfoSync().platform == 'ios' ? uni.getStorageSync('initUrl') : location.href
};
// 微信浏览器内JSSDK支付
if (this.$util.isWeiXin()) {
// 初始化JSSDK官方规范
await this.wechatPay.initJSSDK(orderInfo.url);
// 创建微信订单带HMAC-SHA256签名
const wxPayRes = await this.wechatPay.mpPay(orderInfo);
// 验证签名(官方规范)
const isWxSignValid = this.wechatPay.verifyResult(wxPayRes, wxPayRes.paySign);
if (!isWxSignValid) {
this.$util.showToast({ title: '微信订单签名验证失败' });
return;
}
// 唤起JSSDK支付
await this.wechatPay.h5Pay(wxPayRes);
this.paySuccess();
} else {
// 普通浏览器H5支付链接
const wxH5Res = await this.wechatPay.h5Pay(orderInfo);
console.log('普通浏览器微信支付链接:', wxH5Res.mweb_url);
location.href = wxH5Res.mweb_url;
this.checkPayStatus();
}
} catch (error) {
this.$util.showToast({ title: '微信支付失败:' + error.message });
this.resetpay();
this.repeatFlag = false;
}
break;
// 使用统一支付工具类进行支付
this.invokeUnifiedPay(payType.type);
},
// ========== 华为支付H5端符合官方RSA签名规范 ==========
case 'huaweipay':
try {
this.repeatFlag = false;
const orderInfo = {
productId: 'PROD_' + this.payInfo.out_trade_no,
productName: '订单支付',
price: this.payMoney
};
// 创建华为订单带RSA签名
const huaweiRes = await this.huaweiPay.h5Pay(orderInfo);
// 验证签名(官方规范)
const isHuaweiSignValid = this.huaweiPay.verifySignature(JSON.stringify(huaweiRes), huaweiRes.sign);
if (!isHuaweiSignValid) {
this.$util.showToast({ title: '华为订单签名验证失败' });
return;
}
console.log('华为支付跳转链接:', huaweiRes.payUrl);
location.href = huaweiRes.payUrl;
this.checkPayStatus();
} catch (error) {
this.$util.showToast({ title: '华为支付失败:' + error.message });
this.repeatFlag = false;
}
break;
/**
* 统一支付调用方法(使用新的支付工具类)
*/
async invokeUnifiedPay(payType) {
try {
let payResult;
const amount = this.payMoney;
const outTradeNo = this.payInfo.out_trade_no;
const subject = '订单支付';
// ========== 线下支付(保留原有逻辑) ==========
case 'offlinepay':
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.payInfo.out_trade_no
});
this.repeatFlag = false;
break;
}
} else {
this.$util.showToast({
title: res.message
});
this.repeatFlag = false;
}
},
fail: res => {
uni.hideLoading();
this.$util.showToast({
title: 'request:fail'
});
this.repeatFlag = false;
// 根据支付类型调用对应的支付方法
switch (payType) {
case 'wechatpay':
payResult = await invokeWechatPay(outTradeNo, amount, subject);
break;
case 'alipay':
payResult = await invokeAlipay(outTradeNo, amount, subject);
break;
case 'huaweipay':
payResult = await invokeHuaweiPay(outTradeNo, amount, subject);
break;
default:
throw new Error('不支持的支付方式');
}
// 处理H5支付跳转
if (payResult.code === 0 && payResult.data?.payUrl) {
// H5端直接跳转其他端需要在WebView中显示
const systemInfo = uni.getSystemInfoSync();
if (systemInfo.platform === 'web') {
window.location.href = payResult.data.payUrl;
this.checkPayStatus();
} else {
// 微信小程序/华为快应用中显示WebView
this.showPayWebView(payResult.data.payUrl);
}
} else if (payResult.code === 0) {
// 原生支付成功
this.paySuccess();
} else {
throw new Error(payResult.msg || '支付失败');
}
} catch (error) {
this.repeatFlag = false;
this.$util.showToast({
title: error.message || '支付失败'
});
}
},
/**
* 显示支付WebView用于微信小程序/华为快应用的H5支付
*/
showPayWebView(payUrl) {
// 这里可以打开一个新的WebView页面来显示支付
// 或者使用现有的跳转逻辑
this.$util.redirectTo('/pages/Pay/Pay', {
payUrl: payUrl,
outTradeNo: this.payInfo.out_trade_no
});
},
/**
* 线下支付处理(保留原有逻辑)
*/
payOffline() {
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.payInfo.out_trade_no
});
this.repeatFlag = false;
},
checkPayStatus() {
this.timer = setInterval(() => {
this.$api.sendRequest({
@@ -468,142 +369,17 @@ export default {
// #ifdef MP
pay() {
var payType = this.payTypeList[this.payIndex];
this.$api.sendRequest({
url: '/api/pay/pay',
data: {
out_trade_no: this.payInfo.out_trade_no,
pay_type: payType ? payType.type : '',
scene: uni.getStorageSync('is_test') ? 1175 : uni.getLaunchOptionsSync().scene,
is_balance: this.isBalance
},
success: async res => { // 新增async支持异步调用
uni.hideLoading();
if (res.code >= 0) {
if (res.data.pay_success) {
this.paySuccess();
this.repeatFlag = false;
return;
}
if (payType.type == 'offlinepay') {
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.payInfo.out_trade_no
});
this.repeatFlag = false;
} else {
try {
this.repeatFlag = false;
// ========== 华为支付小程序端跳转H5 ==========
if (payType.type == 'huaweipay') {
const orderInfo = {
productId: 'PROD_' + this.payInfo.out_trade_no,
productName: '订单支付',
price: this.payMoney
};
const huaweiRes = await this.huaweiPay.mpWeixinPay(orderInfo);
this.$util.redirectTo('/pages_tool/pay/wx_pay', {
wx_alipay: encodeURIComponent(huaweiRes.payUrl),
out_trade_no: this.payInfo.out_trade_no
});
} else {
// ========== 微信/支付宝小程序支付(符合官方验签规范) ==========
var payData = res.data.data;
// 验证支付参数签名(官方规范)
let isSignValid = false;
if (payType.type == 'wechatpay') {
isSignValid = this.wechatPay.verifyResult(payData, payData.paySign);
} else if (payType.type == 'alipay') {
isSignValid = this.alipayPay.verifyResult(payData, payData.sign);
}
if (!isSignValid) {
this.$util.showToast({ title: '支付参数签名验证失败' });
return;
}
if (!payType || payType.type === 'offlinepay') {
// 线下支付仍使用原有逻辑
this.$util.redirectTo('/pages_tool/pay/offlinepay', {
outTradeNo: this.payInfo.out_trade_no
});
this.repeatFlag = false;
return;
}
// #ifdef MP-WEIXIN
var scene = uni.getStorageSync('is_test') ? 1175 : uni.getLaunchOptionsSync().scene;
if ([1175, 1176, 1177, 1191, 1195].indexOf(scene) != -1) {
uni.requestOrderPayment({
timeStamp: payData.timeStamp,
nonceStr: payData.nonceStr,
package: payData.package,
signType: payData.signType,
paySign: payData.paySign,
success: res => {
this.paySuccess();
this.repeatFlag = false;
},
fail: res => {
this.flag = false;
if (res.errMsg == 'requestOrderPayment:fail cancel') {
this.$util.showToast({
title: '您已取消支付'
});
this.resetpay();
this.repeatFlag = false;
} else {
uni.showModal({
content: '支付失败,失败原因: ' + res.errMsg,
showCancel: false
});
setTimeout(() => {
this.close();
this.repeatFlag = false;
}, 1500)
}
}
});
return
}
// #endif
uni.requestPayment({
provider: payType.provider,
...payData,
success: res => {
this.paySuccess();
this.repeatFlag = false;
},
fail: res => {
this.flag = false;
if (res.errMsg == 'requestPayment:fail cancel') {
this.$util.showToast({
title: '您已取消支付'
});
this.resetpay();
this.repeatFlag = false;
} else {
uni.showModal({
content: '支付失败,失败原因: ' + res.errMsg,
showCancel: false
});
setTimeout(() => {
this.close();
this.repeatFlag = false;
}, 1500)
}
}
});
}
} catch (error) {
this.$util.showToast({ title: '支付失败:' + error.message });
this.repeatFlag = false;
}
}
} else {
this.$util.showToast({
title: res.message
});
this.repeatFlag = false;
}
},
fail: res => {
uni.hideLoading();
this.$util.showToast({
title: 'request:fail'
});
this.repeatFlag = false;
}
});
// 小程序端也使用统一支付工具类
this.invokeUnifiedPay(payType.type);
},
// #endif
/**
@@ -752,6 +528,8 @@ export default {
color: #00a0e9;
}
.icon-checkboxblank {
font-size: 40rpx;
color: $color-line;