266 行
7.1 KiB
Plaintext
266 行
7.1 KiB
Plaintext
<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>
|