ThinkPHP5對接IOS蘋果支付代碼
ThinkPHP5使用IOS支付流程:
1、前端在調(diào)起蘋果支付前,先請求到服務端,服務端先生成一條充值記錄,但是狀態(tài)為:未支付;然后把這個訂單id發(fā)給前端。
2、前端在支付完成的時候,會收到蘋果的支付憑證,將此憑證和訂單id回傳給服務端。訂單id的作用是用來確定是哪一筆。支付憑證是拿來校驗是否支付成功。檢驗成功后,自己的業(yè)務邏輯(將該條訂單的狀態(tài)改為已支付,然后加余額或延長會員時間)
ThinkPHP5接口代碼
<?php namespace app\index\controller\v1\ios; use app\index\controller\Base; use fast\Random; use think\Db; use think\Request; class Applepay extends Base { /** * 獲取套餐 * @return \think\response\Json */ public function getpackage(){ $t=[ ['id'=>1,'money'=>12], ['id'=>2,'money'=>68], ['id'=>3,'money'=>128], ['id'=>4,'money'=>198], ['id'=>5,'money'=>588], ['id'=>6,'money'=>1098], ]; return json(['code'=>'1','message'=>'','data'=>$t]); } /** * 蘋果下單 */ public function setorder(){ $param = $this->ios_data(); if(!isset($param['userid'])){ return json(['code'=>0,'message'=>'請傳遞用戶id']); } // $this->checkToken(); // if(!isset($param['num'])){ // json(['code'=>0,'message'=>'請選擇結(jié)藤幣數(shù)量'])->send();exit; // } if(!isset($param['money'])){ return json(['code'=>0,'message'=>'請傳遞支付金額']); } // if(!isset($param['type'])){//0=微信支付,1=支付寶支付 4=蘋果支付 // return json(['code'=>0,'message'=>'請選擇支付方式']); // } $userinfo = $this->userinfo($param['userid']); // $jt_member_row = Db::name(self::JT_MEMBER)->where('id',$userinfo['jt_member_id'])->find(); //計算實際支付金額 // $money = $param['num'] * ($jt_member_row['discount']/100); // $money = $param['num'] * ($jt_member_row['discount']/100); // if($money!=$param['money']){ // json(['code'=>0,'message'=>'所支付金額不符'])->send();exit; // } $order_id=Random::build('alnum',20); $add_db = [ 'order_type' => 4, 'user_id' => $param['userid'], 'fee' => $param['money']*100,//數(shù)據(jù)庫單位為分 'open_id' => $userinfo['open_id'], 'add_time' => time(), 'jt_point' => $param['money'], 'purchase_type'=>8, 'order_status'=>0, 'order_id'=>$order_id ]; $res = Db::table('order')->insert($add_db,false,true); if(!$res){ return json(['code'=>0,'message'=>'支付訂單創(chuàng)建失敗']); }else{ return json(['code'=>1,'message'=>'訂單創(chuàng)建成功','data'=>$add_db]); } } /** * @title 驗證支付票據(jù) 完成訂單接口 */ public function verifyReceipt() { $param = $this->ios_data(); // // $receipt = Request::instance()->param('receipt'); //票據(jù) // $orderSn = Request::instance()->param('order_id'); //訂單號 $receipt=$param['receipt']; $orderSn=$param['order_id']; $ck=Db::table('order')->where(array('order_id'=>$orderSn))->find(); if($ck){ if($ck['order_status']==3){ return json(['code'=>0,'message'=>'訂單已成功支付,請勿重復發(fā)起申請']); } } //判斷訂單是否存在 檢查狀態(tài) //寫入日志 查看票據(jù)格式 記錄日志的方法 這個方法不貼出來了 // Tool::callAddLog('request-param',json_encode(['receipt'=>$receipt,'orderSn'=>$orderSn])); trace('receipt**************************************************'); trace($receipt); trace('receipt**************************************************'); trace('orderSn&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'); trace($orderSn); trace('orderSn&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'); //password 是驗證秘鑰 $jsonItem = json_encode(['receipt-data'=>$receipt]); // $jsonItem = json_encode(['receipt-data'=>$receipt, 'password'=>'XXXXXXXXXXXXXXXX']); //$url= 'https://buy.itunes.apple.com/verifyReceipt'; //正式 $url= 'https://sandbox.itunes.apple.com/verifyReceipt'; //測試 //模擬post提交 下面會貼出來 $result = $this->http_post_json($jsonItem,$url); trace('orderS$result$result$result$result$result$result$result$result$result$result$result$result$result$result$result$result'); trace($result); trace('orderS$result$result$result$result$result$result$result$result$result$result$result$result$result$result$result$result'); if($result['status'] !== 0){ //驗證失敗 返回app錯誤狀態(tài) return json(['code'=>0,'message'=>'秘鑰驗證失敗']); } //驗證完成加入日志 // Tool::callAddLog('verifyReceipt_finish',json_encode($result)); trace('success&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'); trace($result); trace('success&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'); //找出時間最大的數(shù)組 $receiptitem = $result['receipt']['in_app']; //這個是排序的方法 下面回帖出來 蘋果會把這個會員往期的訂單信息全部返回,需要找出來最近的那一組信息 $item = $this->arraySort($receiptitem,'purchase_date','desc'); //判斷一下過期時間 延長會員時間 $orderThird = $item['transaction_id']; //本次訂閱的訂單號 $orderThirdFirst = $item['original_transaction_id']; //這個是原始訂單號 $orderinfo=Db::table('order')->where(array('order_id'=>$orderSn))->find(); if($orderThird == $orderThirdFirst){ //首次訂閱 兩個相等 /*業(yè)務邏輯*/ Db::startTrans(); try { /*更新訂單*/ Db::commit(); return json(['code'=>1,'message'=>'支付成功1']); } catch (Exception $e) { Db::rollback(); return json(['code'=>0,'message'=>'支付失敗1']); } }else{ //判斷過期時間和當前時間比較 expires_date_ms是毫秒單位 if($item['expires_date_ms']/1000 > time()){ /*業(yè)務邏輯*/ Db::startTrans(); try { /*更新訂單*/ Db::commit(); } catch (Exception $e) { Db::rollback(); } }else{ //過期處理 票據(jù)失效 } } // 接下來處理訂單業(yè)務邏輯,處理訂單,修改訂單信息,original_transaction_id 把這個單號和存入訂單信息, // 在異步回調(diào)的時候根據(jù)這個單號來查找訂單信息來判斷是哪個用戶, // 蘋果票據(jù)里面也有產(chǎn)品product_id,是app_store的產(chǎn)品id,不是自己業(yè)務的產(chǎn)品id, // 可以在后臺把自己的產(chǎn)品ID和 product_id 關(guān)聯(lián),處理業(yè)務邏輯。 } //模擬post提交 public static function http_post_json($json,$url) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $json); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); //這兩行一定要加,不加會報SSL 錯誤 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); $response = curl_exec($ch); $errno = curl_errno($ch); $errmsg = curl_error($ch); curl_close($ch); $data = json_decode($response, true); return $data; } //查找最新數(shù)據(jù)的方法 public static function arraySort($arr,$key,$type='asc') { $keyArr = []; // 初始化存放數(shù)組將要排序的字段值 foreach ($arr as $k => $v) { $keyArr[$k] = $v[$key]; // 循環(huán)獲取到將要排序的字段值 } if ($type == 'asc') { asort($keyArr); // 排序方式,將一維數(shù)組進行相應排序 } else { arsort($keyArr); } foreach ($keyArr as $k => $v) { $newArray[$k] = $arr[$k]; // 循環(huán)將配置的值放入響應的下標下 } $newArray = array_merge($newArray); // 重置下標 return $newArray[0]; // 數(shù)據(jù)返回 } /** * 異步回調(diào) */ public function applePayReceive(){ $str = file_get_contents('php://input'); trace('request-param……………………………………………………………………………………………………'); trace($str); trace('request-param……………………………………………………………………………………………………'); //寫入通知日志 $jsonItem = json_decode($str,true); if($jsonItem['notification_type'] == 'RENEWAL' || $jsonItem['notification_type'] == 'DID_CHANGE_RENEWAL_STATUS'){ if($jsonItem['notification_type'] == 'DID_CHANGE_RENEWAL_STATUS'){ if($jsonItem['auto_renew_status'] == 'true'){ //第一次夠買的時候 不處理通知 die; } $expires_date = $jsonItem['latest_receipt_info']['expires_date']; $expires_date = $expires_date/1000; // Tool::asynAddLog('request-param',$expires_date.'----'.time()); trace('request-param&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'); trace($expires_date); trace('request-param&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&'); if($expires_date > time()){ }else{ //時間不對 不處理 } } //處理訂閱產(chǎn)品的業(yè)務邏輯 echo '完成!';die; } } }
IOS內(nèi)購接口返回參數(shù)示例
[ log ] array ( 'receipt' => array ( 'receipt_type' => 'ProductionSandbox', 'adam_id' => 0, 'app_item_id' => 0, 'bundle_id' => 'com.spanish.jietengshe', 'application_version' => '1.2', 'download_id' => 0, 'version_external_identifier' => 0, 'receipt_creation_date' => '2020-06-02 09:03:31 Etc/GMT', 'receipt_creation_date_ms' => '1591088611000', 'receipt_creation_date_pst' => '2020-06-02 02:03:31 America/Los_Angeles', 'request_date' => '2020-06-02 09:03:40 Etc/GMT', 'request_date_ms' => '1591088620543', 'request_date_pst' => '2020-06-02 02:03:40 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' => array ( 0 => array ( 'quantity' => '1', 'product_id' => '1', 'transaction_id' => '1000000673581721', 'original_transaction_id' => '1000000673581721', 'purchase_date' => '2020-06-02 08:56:34 Etc/GMT', 'purchase_date_ms' => '1591088194000', 'purchase_date_pst' => '2020-06-02 01:56:34 America/Los_Angeles', 'original_purchase_date' => '2020-06-02 08:56:34 Etc/GMT', 'original_purchase_date_ms' => '1591088194000', 'original_purchase_date_pst' => '2020-06-02 01:56:34 America/Los_Angeles', 'is_trial_period' => 'false', ), 1 => array ( 'quantity' => '1', 'product_id' => '2', 'transaction_id' => '1000000673586536', 'original_transaction_id' => '1000000673586536', 'purchase_date' => '2020-06-02 09:03:31 Etc/GMT', 'purchase_date_ms' => '1591088611000', 'purchase_date_pst' => '2020-06-02 02:03:31 America/Los_Angeles', 'original_purchase_date' => '2020-06-02 09:03:31 Etc/GMT', 'original_purchase_date_ms' => '1591088611000', 'original_purchase_date_pst' => '2020-06-02 02:03:31 America/Los_Angeles', 'is_trial_period' => 'false', ), ), ), 'status' => 0, 'environment' => 'Sandbox', )
到此這篇關(guān)于ThinkPHP5對接IOS蘋果支付代碼的文章就介紹到這了,更多相關(guān)ThinkPHP5使用IOS支付內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
PHP將英文數(shù)字轉(zhuǎn)換為阿拉伯數(shù)字實例講解
在本篇文章里小編給大家分享了關(guān)于PHP將英文數(shù)字轉(zhuǎn)換為阿拉伯數(shù)字實例內(nèi)容,有興趣的朋友們可以參考學習下。2019-01-01ThinkPHP實現(xiàn)二級循環(huán)讀取的方法
這篇文章主要介紹了ThinkPHP實現(xiàn)二級循環(huán)讀取的方法,是ThinkPHP基于數(shù)組的數(shù)據(jù)庫操作中非常常見的技巧,需要的朋友可以參考下2014-11-11Codeigniter的一些優(yōu)秀特性總結(jié)
本文總結(jié)了一下Codeigniter的一些優(yōu)秀特性,算是個人的一些心得分享,推薦給大家。2015-01-01