`Laravel`版`小丑路人社区`改版中,与`Hyperf版小丑路人社区`数据互动,此版本改版中……尚未彻底完结!

Q:

APPStore支付配置与PHP验证流程

开发者中心

创建APP

APP信息

服务器回调地址:在APPStore输入用于接收App Store服务器通知的网址(URL)

如果需要支付购买商品,配置App 内购买项目

状态码

    [
        '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环境的验证服务'
    ];

苹果APP支付到服务端验证流程

1. 用户在app中点击购买;
2. app调用服务端接口生成订单;
3. app获取到服务端订单生成成功后弹出支付窗口;
4. 用户输入密码支付;
5. app接收支付后apple应用商店返回的支付凭证;
6. app将支付凭证传回服务器,调用服务器接口验证凭证是否有效;
7. app获取服务器端的验证结果,反馈用户支付结果状态。
  • 说明:
    • 苹果支付的商品,需要先在 itunes Connect 中配置APP内购项目,配置后对应会生成一个商品ID,在苹果APP端调用苹果支付时,就需要给苹果商店传送这个商品ID(product_id)参数
    • 然后支付过程是在苹果商店中进行,支付完成后,返回一个支付凭证给APP,表示支付完成,但一般会再次调用自己的服务器(商家服务器)端进行支付验证,这时候在服务器写个验证接口,判断凭证是否有效,如果有效,对应修改订单状态和购买的商品状态等等。

PHP服务端接收回调处理流程

  • 必须设置 服务器回调地址
  • 前端传给后端:交易号与订单号,后端通过凭证效验处理流程

PHP的demo

private function checkIosPay(string $receiptdata, string $product_id, string $transaction_id, &$item):bool
{
    // 查询票据是否支付的接口验证!
    if ($sanbox == true){ // 沙漏环境
        $url = 'https://sandbox.itunes.apple.com/verifyReceipt';  //沙漏
    }else{
        $url = 'https://buy.itunes.apple.com/verifyReceipt';      //正式
    }

    $http = new Http($url);
    //password 是验证秘钥
    $curl_data = [
        'receipt-data' => $receiptdata, // IOS支付相关信息
        // 'password'     => '',
    ];
    $result = json_decode($http->setContentType('application/json; charset=UTF-8')->addData($curl_data)->fetch(), true);
    if (!$result){
        $this->error = '支付凭证核验失败!';
        return false;
    }
    // stauts == 21007,沙漏环境的订单
    if ($result['status'] == 21007 && $sanbox == false){
        // 进入沙漏环境检测支付凭证
        return $this->checkIosPay($receiptdata, $product_id, $transaction_id, $item, true);
    }

    // 无效的bundle_id
    if(!in_array($result['receipt']['bundle_id'], ['com.wedding.hs'])) {
        $this->error = '无效的bundle_id:'. $result['receipt']['bundle_id'];
        return false;
    }

    // 判断购买是否成功
    if($result['status'] == 0){ // 支付成功
        //验证完成加入日志
        log_write(['verify_finish' => $result], 'IosReceipt');

        if(!empty($inAppData = $result['receipt']['in_app'])) {
            //多物品信息
            foreach ($inAppData as $product) {
                if ($product['product_id'] == $product_id && $product['transaction_id'] == $transaction_id){
                    $item = $product;
                    return true;
                }else{
                    continue;
                }
            }
        }
    }else if ($result['status'] == 21007){
        // 验证完成加入日志
        log_write(['verify_finish' => $result], 'IosReceipt');

        if(!empty($inAppData = $result['receipt']['in_app'])) {
            //多物品信息
            foreach ($inAppData as $product) {
                if ($product['product_id'] == $product_id && $product['transaction_id'] == $transaction_id){
                    $item = $product;
                    return true;
                }else{
                    continue;
                }
            }
        }
    }else{
        $this->error = '支付核验失败,状态码:' . $result['status'];
        return false;
    }
    $this->error = '尚未获取IOS支付数据,请稍后重试!';
    return false;
}

参考网址PHP验证IOS支付之后的凭证流程

技术分享
订阅

评论记录


评论/回复