IOS苹果内购流程,PHP苹果支付验证,PHP后端验证票据

一,苹果内购流程

1. 选择商品或服务

通过接口获取商品或服务列表
注意 product_id 需要根据 app store 定义填写(非平台内商品/服务的ID)
这里需要后端提供商品/服务列表接口, 前端处理用户操作逻辑

2. 确认支付并调用接口创建订单记录

调起支付前向后端发送创建订单记录请求
后面验证支付结果需要订单信息

3. 调起APP内苹果支付并进行购买支付流程

已经调起了苹果支付由用户完成操作

4. 向服务器发起验证凭证以及支付结果的请求

最后拿到用户操作后返回 receipt 票据字段和订单号提交给后端接口处理验证
返回 code: 0 则为验证成功

二,验证返回的状态码


	验证返回的状态码
	0     验证成功
	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环境的验证服务

三,服务端处理

1. 创建订单记录

	/**
	*	IOS创建订单
	*/
 	public function iosCreateOrder()
    {
        // 参数
        $params = [
        	'product_id' => 1,
		];
        // 处理订单所需数据组合
        $data = [];
        // 处理创建订单逻辑
	        // 调用模型创建订单
        // 返回订单号
        return [
            'order_number' => $data['order_number'],
        ];
    }

2. 验证票据

	/**
	* 苹果订单验证
	* 验证返回的状态码
	* 0     验证成功
	* 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环境的验证服务
	*/
	public function iosVerify()
	{
        // 包名
        $bundleId = '';
        $receipt = ''; // 票据
        $orderNumber = ''; // 当前交易单号
        // 返回信息定义
        $resultMsg = [
            'code' => 400,
            'message' => '支付验证失败',
        ];
        // 验证票据结果
        $result = $this->iosVerifyTickets($receipt);
        // 沙盒模式
        if ($result['status'] == 21007) {
            $result = $this->iosVerifyTickets($receipt, true);
        }
        if (!is_array($result)) {//大概率是超时
            $resultMsg['code'] = 403;
        }
        if ($result['status'] == 0) {//验证成功
            if ($result['receipt']['bundle_id'] != $bundleId) {
                // 包名验证错误
                $resultMsg['message'] = 'APP_KEY 验证错误';
                $resultMsg['code'] = 401;
            }
            //当订购一个套餐后再次订购此套餐可能会出现这种情况,非常规操作
            if (empty($transaction)) {
                $resultMsg['code'] = 402;
            }
            // 开启事务
            try {
                // 更新订单信息
                // 提交事务
            } catch (Exception $e) {
            	// 事务回退
            }
        } else {
            $resultMsg['code'] = 400;
        }
        return response()->json($resultMsg);
    }

	/**
     * ios验证票据
     * @param string $receipt
     * @param false $sandbox
     * @return array|int|mixed
     * @throws Exception
     */
    protected function iosVerifyTickets(string $receipt, bool $sandbox = false)
    {
        if ($sandbox) {
            $url = 'https://sandbox.itunes.apple.com/verifyReceipt'; // 测试环境
        } else {
            $url = 'https://buy.itunes.apple.com/verifyReceipt'; // 正式环境
        }
        $params = json_encode(array("receipt-data" => $receipt));
        $curl = curl_init($url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        $data = curl_exec($curl);
        $errno = curl_errno($curl);
        curl_close($curl);
        $data = json_decode($data, true);
        if (!is_array($data)) { // 开发过程中经常遇到curl 35错误码,或者28超时
            return $errno;
        }
        return $data;
    }
    
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是 PHP 代码实现 iOS 内购订单验证的示例: ```php <?php // 定义 app id 和 app secret $app_id = 'your_app_id'; $app_secret = 'your_app_secret'; // 获取验证请求参数 $receipt = $_POST['receipt']; $password = $_POST['password']; // 发送验证请求到 Apple 服务器 $url = 'https://buy.itunes.apple.com/verifyReceipt'; // 正式环境 //$url = 'https://sandbox.itunes.apple.com/verifyReceipt'; // 沙盒环境 $data = json_encode(array('receipt-data' => $receipt, 'password' => $password)); $options = array( 'http' => array( 'header' => "Content-type: application/json\r\n", 'method' => 'POST', 'content' => $data ) ); $context = stream_context_create($options); $result = file_get_contents($url, false, $context); // 解析验证结果 $response = json_decode($result, true); if ($response['status'] == 0) { // 验证成功 $latest_receipt_info = $response['latest_receipt_info']; $transaction_id = $latest_receipt_info[0]['transaction_id']; $product_id = $latest_receipt_info[0]['product_id']; $purchase_date = $latest_receipt_info[0]['purchase_date']; // TODO: 在这里处理订单验证成功后的逻辑 } else { // 验证失败 $error_code = $response['status']; $error_message = $response['status_message']; // TODO: 在这里处理订单验证失败后的逻辑 } ?> ``` 以上代码中,首先定义了 app id 和 app secret,然后获取了验证请求参数 receipt 和 password,接着发送验证请求到 Apple 服务器,并解析验证结果。如果验证成功,可以获取到订单的相关信息,如 transaction_id、product_id 和 purchase_date 等,可以在这里处理订单验证成功后的逻辑;如果验证失败,可以获取到错误码和错误信息,可以在这里处理订单验证失败后的逻辑。需要注意的是,验证请求需要发送到正式环境或者沙盒环境,根据实际情况选择相应的 URL 即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值