ios苹果支付 坑 付款后凭证问题,in_app数据没有固定排序问题解决php

苹果支付写完后遇到了苹果订单号重复问题
是因为苹果拿到凭证后返回的数据是用户购买的所有数据的数组,而不是单次购买数据,之前看别人代码是取值第一个,还是会有这个错误,后来改成取值最后一个,也会有问题。这是为什么呢,我多次测试发现,苹果返回的in_app数据是没有固定排序的,所以需要咱自己手动排序后再取最新时间的就没有问题啦
贴代码

苹果官方文档地址(数据字段说明)https://developer.apple.com/documentation/appstorereceipts/responsebody

请求苹果:

/**
     * 验证AppStore内付
     * @param  string $receipt_data 付款后凭证
     * @return array                验证是否成功
     */
    public function validateApplePay($receipt_data)
    {
        $result = $this->postIosPay($receipt_data);
		
		//成功需要校验包名是否正确
        if ($result['status'] == 1 && config('pay.iospay.bundle_id') != $result['data']['receipt']['bundle_id']) {
            return [
                'status' => 0,
                'message' => '包名错误',
            ];
        }
        if ($result['status'] == 1) {//in_app按时间排序,苹果返回的数据排序是不稳定的,所以需要手动排序一下
            $in_app = $result['data']['receipt']['in_app'];
            array_multisort(array_column($in_app, 'purchase_date'),SORT_DESC,$in_app);
            $result['data']['receipt']['in_app'] = $in_app;
        }

        return $result;

    }

    //请求苹果接口
    public function postIosPay($receipt_data)
    {
        //小票信息
        $POSTFIELDS = ["receipt-data" => $receipt_data];
        //正式购买地址 沙盒购买地址

        $mode = config('pay.iospay.mode');//normal正式,dev沙盒

        if ($mode == 'normal') {
            $url = "https://buy.itunes.apple.com/verifyReceipt";
        } else if ($mode == 'dev') {
            $url = "https://sandbox.itunes.apple.com/verifyReceipt";
        } else {
            return false;
        }

        
        /**
         * 21000 App Store不能读取你提供的JSON对象
         * 21002 receipt-data域的数据有问题
         * 21003 receipt无法通过验证
         * 21004 提供的shared secret不匹配你账号中的shared secret
         * 21005 receipt服务器当前不可用
         * 21006 receipt合法,但是订阅已过期。服务器接收到这个状态码时,receipt数据仍然会解码并一起发送
         * 21007 receipt是Sandbox receipt,但却发送至生产系统的验证服务
         * 21008 receipt是生产receipt,但却发送至Sandbox环境的验证服务
         */
         //postRequest这是我封装的网络请求,大家没有封装的话可以使用curl进行请求
                //简单的curl
		        /*$ch = curl_init($url);
		        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		        curl_setopt($ch, CURLOPT_POST, 1);
		        curl_setopt($ch, CURLOPT_POSTFIELDS, $POSTFIELDS);
		        $result = curl_exec($ch);
		        curl_close($ch);
		        return $result;*/
        $html = postRequest($url,$POSTFIELDS);
        if ($html) {
            $data = json_decode($html, true);
            if ($data['status'] == '0') {
                return [
                    'status' => 1,
                    'message' => 'OK',
                    'data' => $data
                ];
            } else if ($data['status'] == '21000') {
                return [
                    'status' => 0,
                    'message' => 'App Store不能读取提供的JSON对象',
                ];
            } else if ($data['status'] == '21002') {
                return [
                    'status' => 0,
                    'message' => 'receipt-data域的数据有问题',
                ];
            } else if ($data['status'] == '21003') {
                return [
                    'status' => 0,
                    'message' => 'receipt无法通过验证',
                ];
            } else if ($data['status'] == '21004') {
                return [
                    'status' => 0,
                    'message' => '提供的shared secret不匹配你账号中的shared secret',
                ];
            } else if ($data['status'] == '21005') {
                return [
                    'status' => 2,
                    'message' => '苹果receipt服务器当前不可用',
                ];
            } else if ($data['status'] == '21007') {
                return [
                    'status' => 0,
                    'message' => 'receipt是Sandbox receipt,但却发送至生产系统的验证服务',
                ];
            }  else if ($data['status'] == '21008') {
                return [
                    'status' => 0,
                    'message' => 'receipt是生产receipt,但却发送至Sandbox环境的验证服务',
                ];
            }
        }
        return [
            'status' => 2,//2会走队列从新请求接口
            'message' => '未知的错误',
        ];
    }

得到苹果请求数据后还需要校验商品id(product_id)和订单号(transaction_id)不能重复

		//简单的校验说明
		$data = $result['data'];
		$in_app = $data['receipt']['in_app'];//所有的订单的信息
        $k = 0;//取值第几个
        $transaction_id = $in_app[$k]['transaction_id'];//订单号,需要校验自己数据库里有没有当前订单号
        $apple_id = $in_app[$k]['product_id'];//商品id,需要校验商品id和下单的商品id是否一致
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值