通过HBuilderX + 微信开发者工具构建,要确保微信开发者工具为最新版本,否则可能会导致运行错误。
<template>
<view class="content">
<image class="logo" src="/static/wx-pay-logo.png" mode="heightFix"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
<button type="primary" class="pay-btn" :loading="loading" :disabled="!canUsePay"
@click="paySubmit">立即支付</button>
</view>
</template>
<script setup>
import {
ref
} from 'vue';
const title = ref('微信小程序-支付测试')
// 立即支付按钮的加载状态
const loading = ref(false)
// canUsePay 控制立即支付按钮是否可店家
const canUsePay = ref(false)
// 组件范围内保存获取到的openid
const openid = ref('')
// 自己系统的API服务器域名URL,调测时根据实际情况修改
const apiDomain = 'http://192.168.124.8:8086/'
/*
* 打开界面就自动获取openid:
* 1. 调用微信小程序登录API,获取到登录凭证(code)https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html;
* 2. 需要把code传到自己服务器后台API来获取openid(这一步必须在服务端实现)https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html。
*/
uni.login({
onlyAuthorize: true,
success: (res) => {
console.log('login: ', res)
if (res.code) {
uni.request({
url: apiDomain + 'samples/api.php', // 自己服务器接口地址,请根据实际情况修改
data: {
action: 'mpCode2Session',
code: res.code
},
success: (res) => {
console.log('code: ', res)
if (res?.data?.data?.openid) {
canUsePay.value = true
openid.value = res.data.data.openid
} else {
uni.showToast({
icon: 'none',
title: 'Error: 获取openid失败,无法使用支付功能',
duration: 3000
})
}
}
})
}
}
})
/*
* 如果上面获取openid成功,那么点击立即支付按钮,就会执行这个函数调起支付;
* 如果上面没有获取到openid,那么立即支付按钮不可点击(disabled=true),也不会执行这个函数
*/
const paySubmit = () => {
loading.value = true
canUsePay.value = false
uni.request({
url: apiDomain + 'samples/Test.php',// 自己服务器微信支付下单接口地址,该接口返回小程序调起支付需要的参数,请根据实际情况修改
data: {
openid: openid.value
},
success: (res) => {
const result = res.data
if (result.code != 0) {
loading.value = false
canUsePay.value = true
uni.showToast({
icon: 'none',
title: result.msg ?? 'Error: 服务端下单失败',
})
} else {
const payInfo = result?.data?.pay_info
// 服务单微信支付下单成功,下面是微信小程序调起支付(微信官方文档:https://pay.weixin.qq.com/doc/v3/merchant/4012791898)
uni.requestPayment({
provider: 'wxpay',
timeStamp: payInfo.timeStamp,
nonceStr: payInfo.nonceStr,
package: payInfo.package,
signType: payInfo.signType,
paySign: payInfo.paySign,
success: function(res) {
// 支付成功,具体信息以下面代码运行时输出为准
console.log('success:' + JSON.stringify(res));
},
fail: function(err) {
// 用户取消支付 或 支付失败,具体信息以下面代码运行时输出为准
console.log('fail:' + JSON.stringify(err));
},
complete: function() {
// 接口调用结束的回调函数(调用成功、失败都会执行)
loading.value = false
canUsePay.value = true
}
});
}
}
})
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 160rpx;
width: 160rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
.pay-btn {
margin-top: 200rpx;
}
</style>