文件
OmniCard/mpuniapp/pages/API/request-payment/request-payment.uvue

266 行
7.1 KiB
Plaintext

此文件含有模棱两可的 Unicode 字符

此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。

<template>
<page-head title="发起支付"></page-head>
<view class="uni-common-mt payment-content">
<text>如对当前页面的支付示例功能有任何疑问,通过电子邮件:service@dcloud.io 联系我们</text>
</view>
<view class="payment-content">
<template v-if="providerList.length > 0">
<button class="payment-button" type="primary" v-for="(item, index) in providerList" :key="index" @click="requestPaymentByItem(item)">{{ item.name }}</button>
</template>
<template v-else>
<button class="payment-button" type="primary">请先在 manifest.json 配置勾选微信支付、支付宝</button>
</template>
</view>
</template>
<script setup lang="uts">
export type PayItem = { id: string; name: string; provider?: UniProvider };
type DataType = {
btnText: string;
btnType: string;
orderInfo: string;
errorCode: number;
errorMsg: string;
complete: boolean;
fail: boolean;
outTradeNo: string;
openid: string;
};
type PaymentOptions = {
provider: string;
orderInfo: string;
errorTitle?: string;
};
// 支付订单请求地址
const UNI_PAY_API_URL = 'https://env-00jxt67zj8kj.dev-hz.cloudbasefunction.cn/uni-pay-api';
const providerList = ref([] as PayItem[]);
const defaultData: DataType = {
btnText: '支付宝支付',
btnType: 'primary',
orderInfo: '',
errorCode: 0,
errorMsg: '',
complete: false,
fail: false,
outTradeNo: '',
openid: '',
};
const data = reactive(defaultData);
const bundleId = ref('');
const getPaymentBundleId = (): string => {
let bundleId: string | null = '';
// #ifdef APP-ANDROID
bundleId = uni.getAppBaseInfo().packageName;
// #endif
// #ifdef APP-IOS
bundleId = uni.getAppBaseInfo().bundleId;
// #endif
// #ifdef APP-HARMONY
bundleId = uni.getAppBaseInfo().bundleName;
// #endif
// #ifdef MP-WEIXIN
bundleId = uni.getAccountInfoSync().miniProgram.appId;
// #endif
return bundleId ?? '';
};
const requestPaymentByOrderInfo = (options: PaymentOptions) => {
uni.requestPayment({
provider: options.provider,
orderInfo: options.orderInfo,
// #ifdef MP-WEIXIN
// 微信小程序需使用...结构参数
...JSON.parse(options.orderInfo),
// #endif
success: (res) => {
console.log(JSON.stringify(res));
uni.showToast({ icon: 'success', title: '支付成功' });
},
fail: (res) => {
console.log(JSON.stringify(res));
data.errorCode = res.errCode;
const title = options.errorTitle == null ? 'errorCode:' + data.errorCode : options.errorTitle;
uni.showToast({ icon: 'error', title });
},
});
};
// #ifdef MP-WEIXIN
// 获取微信小程序openid,用于发起支付
const getOpenId = async (): Promise<void> => {
let code = '';
await new Promise<void>((resolve, reject) => {
uni.login({
provider: 'weixin',
success: (res) => {
code = res.code;
resolve();
},
fail: (err) => {
reject(err);
},
});
});
await new Promise<void>((resolve, reject) => {
uni.request({
url: `${UNI_PAY_API_URL}/getOpenId`,
method: 'GET',
data: {
code,
bundleId: bundleId.value,
},
success: (res) => {
const responseData = res.data as UTSJSONObject;
data.openid = responseData['openid'] as string;
console.log('openid: ', data.openid);
resolve();
},
fail: (err) => {
console.error('request-err', err);
reject(err);
},
});
});
};
// #endif
const requestPaymentByItem = async (e: PayItem): Promise<void> => {
const provider = e.id;
const appProvider = e.provider;
const supportCheckWeChat = appProvider != null || provider == 'alipay';
let requestData = {} as UTSJSONObject;
let paymentProvider = provider;
if (supportCheckWeChat && provider == 'wxpay' && appProvider != null) {
const wxProvider = appProvider as UniPaymentWxpayProvider;
if (wxProvider.isWeChatInstalled == false) {
uni.showToast({ title: '本设备中未找到微信', icon: 'error' });
return;
}
}
uni.showLoading({ title: '请求中...', mask: true });
const random = Math.floor(Math.random() * 9000) + 1000;
data.outTradeNo = `test${Date.now()}${random}`;
requestData = {
provider: paymentProvider,
outTradeNo: data.outTradeNo,
bundleId: bundleId.value,
totalFee: 1,
} as UTSJSONObject;
// #ifdef MP-WEIXIN
try {
if (data.openid == '') {
await getOpenId();
}
requestData.openid = data.openid;
} catch (err) {
uni.showToast({ title: '获取微信openid失败', icon: 'error' });
uni.hideLoading();
return;
}
// #endif
uni.request({
url: `${UNI_PAY_API_URL}/getOrderInfo`,
method: 'GET',
data: requestData,
timeout: 6000,
success: (res) => {
uni.hideLoading();
const responseData = res.data as UTSJSONObject;
const errCode = responseData['errCode'] as number;
if (errCode != 0) {
uni.showModal({ title: '提示', content: responseData['errMsg'] as string, showCancel: false });
return;
}
const orderInfo = responseData['orderInfo'] as string;
console.log('orderInfo: ', orderInfo);
data.orderInfo = orderInfo;
requestPaymentByOrderInfo({
provider: paymentProvider,
orderInfo,
errorTitle: '支付失败',
});
},
fail: (err) => {
uni.hideLoading();
console.error('request-err', err);
},
});
};
onLoad(() => {
// 获取包名或appid
bundleId.value = getPaymentBundleId();
// #ifdef APP
const providerOptions: GetProviderSyncOptions = {
service: 'payment',
};
let provider = uni.getProviderSync(providerOptions);
provider.providerObjects.forEach((value: UniProvider) => {
if (value.id == 'alipay' || value.id == 'wxpay') {
const payItem: PayItem = {
name: value.description,
id: value.id,
provider: value,
};
providerList.value.push(payItem);
}
});
// #endif
// #ifdef MP-WEIXIN
const payItem: PayItem = {
name: '微信支付',
id: 'wxpay',
};
providerList.value.push(payItem);
// #endif
});
// 自动化测试使用
const jest_pay = () => {
uni.requestPayment({
provider: 'alipay',
orderInfo: data.orderInfo,
fail: (res: RequestPaymentFail) => {
data.errorCode = res.errCode;
data.complete = true;
data.fail = true;
},
success: (res: RequestPaymentSuccess) => {
console.log(JSON.stringify(res));
data.complete = true;
data.fail = false;
},
} as RequestPaymentOptions);
};
defineExpose({
data,
jest_pay,
});
</script>
<style>
.payment-content {
padding: 0 10px;
}
.payment-button {
margin-top: 20px;
}
</style>