<template>
<view>
<u-cell title="TT币余额" @click="showRecharge=true" size="large" class="card" :isLink="true" :border="false" value="充值">
<view slot="label" class="label">
{{$store.state.userInfo.coin}}
</view>
</u-cell>
<view class="cell-group-title">
明细
</view>
<u-cell-group title="" :border="false">
<view class="cell-group">
<u-cell class="cell-group-box" title="充值" size="large" label="苹果内购" v-for="(recharge,index) in rechargeList" :key="recharge.id"
:border="false">
<view slot="value" style="text-align: right">
<view style="font-size: 1.5em;color:red;">+{{recharge.tt_num}}</view>
<view style="color:#888888">{{recharge.create_at}}</view>
</view>
</u-cell>
</view>
</u-cell-group>
<view class="">
<u-loadmore height="50" fontSize="24" :status="status" />
</view>
<u-popup :show="showRecharge" @close="closeRecharge">
<view class="recharge-box">
<view class="title">TT币充值</view>
<u-grid :border="false" col="3">
<u-grid-item v-for="(item,index) in product_list" :key="index" sytle="text-align: center;">
<view class="product-item">
<view class="product-box" @click="selectProduct(index)" :class="index==current?'active':''">
<view class="numbox">
<text class="num">{{item.tt_num}}</text>
<text class="unit">TT币</text>
</view>
<text class="price">{{item.price}}美元</text>
</view>
</view>
</u-grid-item>
</u-grid>
<view class="sumbit">
<u-button type="error" :text="submitText" @click="requestPayment"></u-button>
<view class="agree">充值代表已阅读并同意<text class="xieyi">《用户充值协议》</text></view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
export default {
name: "bill",
data(){
return {
current: 0,// 商品列表选中的下标
iap: null, // 支付通道
ids: [], // 应用内购项目产品 ID 数组
product_list: [],
showRecharge:false,
submitText:'',
rechargeList:[],
page:1,
status:'loadmore'
}
},
onReady() {
this.initPay()
this.getRechargeList()
},
// 上拉刷新
onReachBottom(){
this.getRechargeList()
},
methods:{
initPay(){
// #ifdef APP-PLUS
plus.payment.getChannels(res => {
let channel = res.find(i => i.id === 'appleiap')
this.iap = channel ? channel : null
this.fetchData()
}, function(e) {
plus.nativeUI.alert("获取支付通道失败,请稍后重试。", function() {}, "提示");
})
// #endif
},
// 获取内购项目列表
requestOrder() {
/*uni.showLoading({
title: '检测支付环境...'
})*/
// #ifdef APP-PLUS
this.iap.requestOrder(
this.ids,
res => {
uni.hideLoading()
},
(errormsg) => {
uni.hideLoading()
plus.nativeUI.alert("获取应用内购项目失败,请稍后重试。1", function(e) {}, "提示");
}
)
// #endif
},
fetchData() {
uni.$u.http.get('/recharge/productList').then(res => {
res.data.forEach(item=>{
this.ids.push(item.product_id)
})
this.product_list=res.data
this.setSummitText()
this.requestOrder()
})
},
closeRecharge(e){
this.showRecharge=false
},
setSummitText(){
if(this.product_list.length>0){
this.submitText="立即充值"+this.product_list[this.current].price+"美元"
}
},
selectProduct(idx){
this.current=idx
this.setSummitText()
},
/* ios内购 */
requestPayment() {
let self = this;
uni.showLoading({
title: '支付中请勿关闭...'
})
uni.requestPayment({
provider: 'appleiap',
orderInfo: {
productid: this.product_list[this.current].product_id
},
success: (e) => {
this.showRecharge=false
/*uni.showModal({
content: "支付成功",
showCancel: false
})*/
const data={
productid:e.payment.productid,
quantity:e.payment.quantity,
transactionDate:e.transactionDate,
transactionIdentifier:e.transactionIdentifier,
receipt_data:e.transactionReceipt
}
uni.$u.http.post('/recharge/validateApplePay',data).then(res=>{
console.log(res)
uni.hideLoading()
uni.showToast({
title:res.msg,
icon:'none'
})
if(res.code==200){
this.$store.dispatch('getUserInfo')
this.reloadRechargeList()
}
}).catch(e=>{
uni.hideLoading()
})
},
fail: (e) => {
uni.hideLoading()
uni.showModal({
content: "支付失败,原因为: " + e.errMsg,
showCancel: false
})
},
complete: () => {
uni.hideLoading()
this.loading = false;
}
})
},
getRechargeList(){
let url=`/recharge/getList?limit=20&page=${this.page}`
this.status='loading'
return uni.$u.http.get(url).then(({data,msg})=>{
this.rechargeList = [...this.rechargeList,...data.list];
if(data.list.length==0){
this.status='nomore'
}else{
this.status='loadmore'
this.page++
}
}).catch(({msg})=>{
this.status='loadmore'
})
},
reloadRechargeList(){
this.page=1
this.status='loadmore'
this.rechargeList=[]
this.getRechargeList()
}
}
}
</script>
<style lang="scss" scoped>
.card {
background-color: #fdc615;
margin: 1em;
border-radius: 15px;
.label {
height: 20vh;
line-height: 17vh;
font-size: 2.5em;
color: #ffffff;
}
}
.cell-group-title {
width: 94%;
margin: 0 auto;
margin-top: 64rpx;
font-size: 36rpx;
font-family: Adobe Heiti Std;
font-weight: normal;
color: #1A1A1A;
}
.cell-group {
width: 94%;
margin: 0 auto;
.cell-group-box {
margin-top: 30rpx;
box-shadow: 0 0 20rpx 2rpx #ccc;
border-radius: 10rpx;
}
}
.recharge-box{
background-color: #ffffff;
width: 710rpx;
padding: 20rpx;
.title{
color: #000;
font-weight: bold;
padding: 20rpx 20rpx;
font-size: 32rpx;
text-align: center;
}
.product-item{
padding-top: 20rpx;
.product-box{
flex: 1;
height: 120rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #f0f0f0;
width: 180rpx;
border-radius: 20rpx;
.numbox{
.num{
color: #000;
font-size: 40rpx;
font-weight: bold;
}
.unit{
color: #000;
font-size: 26rpx;
font-weight: bold;
}
}
.price{
color: #666;
font-size: 24rpx;
}
}
.active{
border: 1px solid #fdc615;
}
}
.sumbit{
padding: 50rpx 20rpx 30rpx 20rpx;
.agree{
text-align: center;
margin-top: 10rpx;
font-size: 24rpx;
color: #999;
.xieyi{
color: #2b85e4;
}
}
}
}
</style>
- 发布:2022-08-07 11:51
- 更新:2023-08-22 17:39
- 阅读:816
产品分类: uniapp/App
PC开发环境操作系统: Windows
PC开发环境操作系统版本号: 11
HBuilderX类型: 正式
HBuilderX版本号: 3.5.3
手机系统: iOS
手机系统版本号: iOS 15
手机厂商: 苹果
手机机型: iOS 15.6
页面类型: vue
vue版本: vue2
打包方式: 云端
项目创建方式: HBuilderX
示例代码:
操作步骤:
无
无
预期结果:
无
无
实际结果:
无
无
bug描述:
Guideline 2.1 - Performance - App Completeness
We found that your in-app purchase products exhibited one or more bugs when reviewed on iPad running iOS 15.6 on Wi-Fi.
Next Steps
When validating receipts on your server, your server needs to be able to handle a production-signed app getting its receipts from Apple’s test environment. The recommended approach is for your production server to always validate receipts against the production App Store first. If validation fails with the error code "Sandbox receipt used in production," you should validate against the test environment instead.
Resources
You can learn more about testing in-app purchase products in your development sandbox environment in App Store Connect Developer Help.
For more information on receipt validation, please see What url should I use to verify my receipt? in the In-App Purchase FAQ.
Learn how to generate a receipt validation code in App Store Connect Developer Help.
从错误上看是发生在服务器二次验证上,沙盒的验证和正式的地址不同
// 沙盒地址 https://sandbox.itunes.apple.com/verifyReceipt
// 正式地址 https://buy.itunes.apple.com/verifyReceipt
当前代码存在部分情况丢单问题,请使用文档提供的新方案和示例代码
文档地址: https://uniapp.dcloud.net.cn/api/plugins/payment.html#iap