chore: 重新与HuaweiPay分支比较,起点
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user