PHP驗證IOS原生支付是否成功(代碼全篇)

  • 前言
    IOS原生支付後,須要調用服務端接口進行驗證,檢測是否真正的支付成功!
<?php
class ApplePay
{
    /** 環境配置(建議提成配置)
     * @var bool
     */
    private $sandbox = false ;

    /** result as json
     * @param int $code
     * @param string $msg
     * @param array $data
     * @return string
     */
    private function jsonRet(int $code=200, string $msg='', array $data = [])
    {
        $result = [
            'code' => $code ,
            'message' => $msg ,
            'data' => $data ,
        ] ;
        return json_encode($result,true);
    }

    /** code400
     * @param string $msg
     * @return string
     */
    private function code400( $msg = '參數錯誤!' )
    {
        return $this->jsonRet(400,$msg);
    }

    /** code200
     * @param string $msg
     * @return string
     */
    private function code200( $msg = '操做成功!')
    {
        return $this->jsonRet(200,$msg);
    }

    /** log
     * @param $info
     */
    private function log($info)
    {
        //log info
    }

    /** ios apple 支付驗證
     * @return string
     */
    public function apple()
    {
        //蘋果支付認證的憑證(base64後的數據)
        $receipt = $_POST('receipt') ;
        if(empty($receipt)) {
            return $this->code400() ;
        }
        //環境配置
        if($this->sandbox) {
            $endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt';//沙箱地址
        } else {
            $endpoint = 'https://buy.itunes.apple.com/verifyReceipt';//真實運營地址
        }
        //數據組裝
        //$receipt ='MIITg45+CLLy37vkb0ADflcoqEY/3mH1Rc9rC4q3/O7eG/sT7MntcVH1gc8GiEuZZ1T0Qormu2TFRrg866YxxI0LVfxzQ==';
        $postData = json_encode(
            array('receipt-data' => $receipt)
            ,JSON_UNESCAPED_SLASHES);
        //日誌記錄
        $this->log($postData);
        //curl操做
        $ch = curl_init($endpoint);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);  //這兩行必定要加,不加會報SSL 錯誤
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        $response = curl_exec($ch);
        $errno    = curl_errno($ch);
        curl_close($ch);
        if ($errno != 0) {
            return $this->code400('curl請求有錯誤!') ;
        } else {
            $data = json_decode($response, true);
            if (!is_array($data)) {
                return $this->code400('數據錯誤!') ;
            }
            //判斷購買是否成功
            if (!isset($data['status']) || $data['status'] != 0) {
                return $this->code400('無效的iOS支付數據!') ;
            }
            //無效的bundle_id
            if(!in_array($data['receipt']['bundle_id'],['ios申請的bundle_id相似於支付的app_id'])) {
                return $this->code400('無效的bundle_id:'.$data['receipt']['bundle_id']) ;
            }
            //多物品購買時
            // in_app爲多個(坑)
            // ios一次支付可能返回多個,多是上次成功後沒有及時返回,此次成功後會把上次或上上次成功的返回
            if(!empty($inAppData = $data['receipt']['in_app'])) {
                //產品配置,對應ios申請的product_id eg : yw_6 支付6元
                $productB = ['yw_6'];
                //多物品信息
                foreach ($inAppData as $product) {
                    //訂單重複驗證
                    $appleData = $product->check('自身業務去重');
                    if($appleData) {
                        continue ;
                        //return $this->code400('交易單號重複,請不要重複驗證!id:'.$transactionId) ;
                    }
                    if(isset($productB[$product['product_id']])) {
                        $productId = $product['product_id'];
                        $money = $productB[$productId] ;
                        if(!$money) {
                            return $this->code400('沒有找到對應產品的金額,ID:'.$product['product_id']) ;
                        }
                        //業務邏輯處理
                        //加餘額,記錄資金日誌之類的操做
                        $product['add_balance'] = true ;
                    }
                    //環境
                    $product['is_sandbox']   = $this->sandbox ;
                    //數據
                    $product['receipt_data']  = $receipt ;
                    //時間
                    $product['time']         = date('YmdHis') ;
                    //返回碼
                    $product['err_no']       = '200' ;
                    //save $product 保存數據
                }
            }
            //根據自身需求返回數據
            $returnData = [] ;
            return $this->code200($returnData) ;
        }
    }
}
相關文章
相關標籤/搜索