2***@qq.com
2***@qq.com
  • 发布:2022-08-07 11:51
  • 更新:2023-08-22 17:39
  • 阅读:536

【报Bug】ios 15.6 wifi 内购支付异常 沙盒测试正常

分类:uni-app

产品分类: uniapp/App

PC开发环境操作系统: Windows

PC开发环境操作系统版本号: 11

HBuilderX类型: 正式

HBuilderX版本号: 3.5.3

手机系统: iOS

手机系统版本号: iOS 15

手机厂商: 苹果

手机机型: iOS 15.6

页面类型: vue

vue版本: vue2

打包方式: 云端

项目创建方式: HBuilderX

示例代码:
<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>

操作步骤:

预期结果:

实际结果:

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.

2022-08-07 11:51 负责人:DCloud_uniAD_HDX 分享
已邀请:
DCloud_uniAD_HDX

DCloud_uniAD_HDX

从错误上看是发生在服务器二次验证上,沙盒的验证和正式的地址不同

// 沙盒地址 https://sandbox.itunes.apple.com/verifyReceipt
// 正式地址 https://buy.itunes.apple.com/verifyReceipt

当前代码存在部分情况丢单问题,请使用文档提供的新方案和示例代码
文档地址: https://uniapp.dcloud.net.cn/api/plugins/payment.html#iap

s***@artboost.cn

s***@artboost.cn

解决没,我也遇到了审核被拒Guideline 2.1 - Performance - App Completeness的问题

  • 9***@qq.com

    同问题,请问解决了吗

    2023-10-21 15:02

要回复问题请先登录注册