PHP对接苹果支付全流程

简介: PHP对接苹果支付全流程
对接苹果支付流程上相较于微信或者支付宝来说 后端做的代码是非常少的 但是需要注意的点很多

对于支付 最重要的是知道这笔支付到底是不是真正意义上成交了,以及成交价格是否对应我们的商品价格 这是我们需要去判断的

苹果支付对于微信支付和支付宝支付来说,有本质的区别。苹果支付的商品需要现在appstore里面去上架。所以整个支付流程如下

APP内请求苹果SDK发起支付。并完成购买。支付成功之后APP端会传一段receipt_data(同时需要带上APP支付成功的交易单号)给后端去做验证。后端拿到这个数据之后,会再次请求苹果服务器去解析数据。

结构如下:

{
    "receipt": {
        "receipt_type": "ProductionSandbox",
        "adam_id": 0,
        "app_item_id": 0,
        "bundle_id": "申请苹果支付时的串号 固定的值",
        "application_version": "24",
        "download_id": 0,
        "version_external_identifier": 0,
        "receipt_creation_date": "2022-02-18 08:02:19 Etc/GMT",
        "receipt_creation_date_ms": "1645171339000",
        "receipt_creation_date_pst": "2022-02-18 00:02:19 America/Los_Angeles",
        "request_date": "2022-02-23 13:21:51 Etc/GMT",
        "request_date_ms": "1645622511107",
        "request_date_pst": "2022-02-23 05:21:51 America/Los_Angeles",
        "original_purchase_date": "2013-08-01 07:00:00 Etc/GMT",
        "original_purchase_date_ms": "1375340400000",
        "original_purchase_date_pst": "2013-08-01 00:00:00 America/Los_Angeles",
        "original_application_version": "1.0",
        "in_app": [
            {
                "quantity": "1",
                "product_id": "10000",#产品ID
                "transaction_id": "1000000972016787", ##交易单号
                "original_transaction_id": "1000000972016787",
                "purchase_date": "2022-02-18 08:02:19 Etc/GMT",
                "purchase_date_ms": "1645171339000",
                "purchase_date_pst": "2022-02-18 00:02:19 America/Los_Angeles",
                "original_purchase_date": "2022-02-18 08:02:19 Etc/GMT",
                "original_purchase_date_ms": "1645171339000",
                "original_purchase_date_pst": "2022-02-18 00:02:19 America/Los_Angeles",
                "is_trial_period": "false",
                "in_app_ownership_type": "PURCHASED"#交易状态
            },
            {
                "quantity": "1",
                "product_id": "betterwe_camp_21",
                "transaction_id": "1000000970947758",
                "original_transaction_id": "1000000970947758",
                "purchase_date": "2022-02-17 07:26:24 Etc/GMT",
                "purchase_date_ms": "1645082784000",
                "purchase_date_pst": "2022-02-16 23:26:24 America/Los_Angeles",
                "original_purchase_date": "2022-02-17 07:26:24 Etc/GMT",
                "original_purchase_date_ms": "1645082784000",
                "original_purchase_date_pst": "2022-02-16 23:26:24 America/Los_Angeles",
                "is_trial_period": "false",
                "in_app_ownership_type": "PURCHASED"
            },
        ]
    },
    "environment": "Sandbox",
    "status": 0
}

订单总共如下几种状态

状态 描述
Purchased 购买成功
Restored 恢复购买
Failed 失败
Deferred 等待确认,儿童模式需要询问家长同意

1) app从服务器获取产品标识列表

2) app从app store 获取产品信息

3) 用户选择需要购买的产品

4) app 发送 支付请求到app store

5) app store 处理支付请求,返回transaction信息

6) app 将transaction receipt 发送到服务器

7) 服务器收到收据后发送到app stroe验证收据的有效性

8) app store 返回收据的验证结果

9) 根据app store 返回的结果决定用户是否购买成功

基本的支付校验流程如下:
在这里插入图片描述
下面贴上具体的业务逻辑代码

 public function actionsApplepay($receipt_data, $order_number, $transaction_id, $order_info, $is_test){
        $ret = array();
        $ret['status'] = 200;
        $ret['msg'] = "ok";
        try{

                //修改状态为校验中
                (new Order())::updateAppleOrderIsPaying($order_number);

                if ($is_test == 1) {    //沙盒购买地址
                    $url = "https://sandbox.itunes.apple.com/verifyReceipt";
                }else{  //正式购买地址
                    $url = "https://buy.itunes.apple.com/verifyReceipt";
                }

                $receipt_data = str_replace(' ',"+", $receipt_data);
                $post_data = json_encode(array("receipt-data" => $receipt_data));
                $response = https_request($url, $post_data);
                $res = json_decode($response, true);

                $err_msg = array(
                    '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环境的验证服务'
                );

                // 判断是否购买成功
                if(intval($res['status']) === 0){
                    //支付成功 更改订单状态
                    if($res['receipt']['bundle_id'] != 'xxxx'){

                        throw new Exception('非法请求!', -1);

                    }
                    $pay_status = false;//默认支付为失败态
                    if(count($res['receipt']['in_app'])){

                        foreach ($res['receipt']['in_app'] as $apple_order){

                            //满足二次验证的商品和客户端的商品一致 且 apple订单号一致 且支付状态为 PURCHASED 方式
                            if($apple_order['product_id'] == $order_info['goods_id'] && $apple_order['transaction_id'] == $transaction_id && $apple_order['in_app_ownership_type'] == 'PURCHASED'){
                                //如果查询到里面有满足条件的 将状态置为true
                                $pay_status = true;

                            }

                        }

                    }

                    if($pay_status == true){

                        $update_order_info_res = (new Order())->updateOrderIsPaySuccess($order_number, 3, $transaction_id);

                        if($update_order_info_res['status'] != 200){

                            throw new Exception($update_order_info_res['msg'], $update_order_info_res['status']);

                        }
                    }else{

                        throw new Exception('未查询到当前订单的支付成功记录', -3);

                    }

                }else{

                    //沙盒情况下直接走完流程
                    if($res['status'] == 21007){

                        $update_order_info_res = (new Order())->updateOrderIsPaySuccess($order_number, 3, 'XXXXXXXXXX-SANDBOX');

                        if($update_order_info_res['status'] != 200){

                            throw new Exception($update_order_info_res['msg'], $update_order_info_res['status']);

                        }


                    }else{

                        (new Order())::recordOrderErrorLog($order_number, '购买失败 status:'.$res['status'].' - '.@$err_msg[$res['status']].'receipt_data:'.$receipt_data);
                        throw new Exception('购买失败 status:'.$res['status'].' - '.@$err_msg[$res['status']], $res['status']);

                    }



                }

        }catch (Exception $e) {
            //修改状态为校验中
            (new Order())::updateAppleOrderIsNoPaying($order_number);
            $ret['status'] = $e->getCode();
            $ret['msg'] = $e->getMessage();
        }

        return $ret;
    }

上面为具体的业务逻辑代码

相关文章
|
6月前
|
安全 关系型数据库 MySQL
PHP手术麻醉临床信息管理系统源码 术前、术中、术后全流程管理
麻醉文书是用于管理患者手术全过程的文书。 麻醉同意:医院麻醉知情同意书的填写和编辑; 病案查询:可以通过搜索框搜索患者查询病案; 申请手术:手术申请单的填写和打印; 风险评估:医院手术风险评估表的书写和编辑。
78 0
|
关系型数据库 MySQL 应用服务中间件
Mac PHP-Nginx-Mysql 本地开发日常启动流程
Mac PHP-Nginx-Mysql 本地开发日常启动流程
68 1
|
4月前
|
人工智能 API 语音技术
PHP对接百度语音识别技术
PHP对接百度语音识别技术
98 1
|
5月前
|
PHP 开发工具
php免费用免认证的微信支付宝支付
php免费用免认证的微信支付宝支付
41 5
|
5月前
|
存储 Linux PHP
PHP云盘网盘系统源码+快速对接多家云存储+全新一键安装版
快速对接多家云存储,支持七牛、又拍云、阿里云OSS、AWS S3、Onedrive、自建远程服务器,当然,还有本地存储。 自定义主题配色。 图片、音频、视频、文本、Markdown、Ofiice文档 在线预览。 移动端全站响应式布局。 文件、目录分享系统,可创建私有分享或公开分享链接。 用户个人主页,可查看用户所有分享。 多用户系统、用户组支持。 初步完善的后台,方便管理。 拖拽上传、分片上传、断点续传、下载限速(*实验性功能)。 多上传策略,可为不同用户组分配不同策略。 用户组基础权限设置、二步验证。 WebDAV协议支持。
133 2
|
5月前
|
PHP 移动开发 安全
PHP应用如何对接微信公众号JSAPI支付
本文介绍了微信支付的多种方式,包括JSAPI支付、APP支付、Native支付、付款码支付和H5支付。
60 8
|
5月前
|
存储 程序员 API
老程序员分享:PHP对接饿了么开放平台【企业】接单
老程序员分享:PHP对接饿了么开放平台【企业】接单
|
6月前
|
PHP
【PHP入门】2.2 流程控制
【PHP入门】2.2 流程控制
【PHP入门】2.2 流程控制
|
6月前
|
前端开发 JavaScript 测试技术
【PHP开发专栏】PHP Web开发基础与流程
【4月更文挑战第29天】本文介绍了PHP Web开发的基础和流程,帮助初学者入门。内容包括Web服务器与PHP解释器的工作原理、HTML/CSS/JavaScript基础知识、PHP语法与数据库操作。开发流程涵盖项目规划、环境搭建、数据库设计、代码编写、测试与调试,以及部署与维护。此外,文中还强调了使用框架、代码组织、安全性及性能优化等进阶知识和最佳实践,旨在培养优秀PHP开发者。
96 0
|
6月前
|
安全 关系型数据库 MySQL
【PHP】医院HIS手术麻醉临床信息管理系统源码 实现术前、术中、术后全流程管理
【PHP】医院HIS手术麻醉临床信息管理系统源码 实现术前、术中、术后全流程管理
94 0