ThinkPHP5對接IOS蘋果支付代碼
ThinkPHP5使用IOS支付流程:
1、前端在調(diào)起蘋果支付前,先請求到服務(wù)端,服務(wù)端先生成一條充值記錄,但是狀態(tài)為:未支付;然后把這個(gè)訂單id發(fā)給前端。
2、前端在支付完成的時(shí)候,會收到蘋果的支付憑證,將此憑證和訂單id回傳給服務(wù)端。訂單id的作用是用來確定是哪一筆。支付憑證是拿來校驗(yàn)是否支付成功。檢驗(yàn)成功后,自己的業(yè)務(wù)邏輯(將該條訂單的狀態(tài)改為已支付,然后加余額或延長會員時(shí)間)
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();
//計(jì)算實(shí)際支付金額
// $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 驗(yàn)證支付票據(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ù)發(fā)起申請']);
}
}
//判斷訂單是否存在 檢查狀態(tài)
//寫入日志 查看票據(jù)格式 記錄日志的方法 這個(gè)方法不貼出來了
// Tool::callAddLog('request-param',json_encode(['receipt'=>$receipt,'orderSn'=>$orderSn]));
trace('receipt**************************************************');
trace($receipt);
trace('receipt**************************************************');
trace('orderSn&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&');
trace($orderSn);
trace('orderSn&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&');
//password 是驗(yàn)證秘鑰
$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){
//驗(yàn)證失敗 返回app錯(cuò)誤狀態(tài)
return json(['code'=>0,'message'=>'秘鑰驗(yàn)證失敗']);
}
//驗(yàn)證完成加入日志
// Tool::callAddLog('verifyReceipt_finish',json_encode($result));
trace('success&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&');
trace($result);
trace('success&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&');
//找出時(shí)間最大的數(shù)組
$receiptitem = $result['receipt']['in_app'];
//這個(gè)是排序的方法 下面回帖出來 蘋果會把這個(gè)會員往期的訂單信息全部返回,需要找出來最近的那一組信息
$item = $this->arraySort($receiptitem,'purchase_date','desc');
//判斷一下過期時(shí)間 延長會員時(shí)間
$orderThird = $item['transaction_id']; //本次訂閱的訂單號
$orderThirdFirst = $item['original_transaction_id']; //這個(gè)是原始訂單號
$orderinfo=Db::table('order')->where(array('order_id'=>$orderSn))->find();
if($orderThird == $orderThirdFirst){ //首次訂閱 兩個(gè)相等
/*業(yè)務(wù)邏輯*/
Db::startTrans();
try {
/*更新訂單*/
Db::commit();
return json(['code'=>1,'message'=>'支付成功1']);
} catch (Exception $e) {
Db::rollback();
return json(['code'=>0,'message'=>'支付失敗1']);
}
}else{
//判斷過期時(shí)間和當(dāng)前時(shí)間比較 expires_date_ms是毫秒單位
if($item['expires_date_ms']/1000 > time()){
/*業(yè)務(wù)邏輯*/
Db::startTrans();
try {
/*更新訂單*/
Db::commit();
} catch (Exception $e) {
Db::rollback();
}
}else{
//過期處理 票據(jù)失效
}
}
// 接下來處理訂單業(yè)務(wù)邏輯,處理訂單,修改訂單信息,original_transaction_id 把這個(gè)單號和存入訂單信息,
// 在異步回調(diào)的時(shí)候根據(jù)這個(gè)單號來查找訂單信息來判斷是哪個(gè)用戶,
// 蘋果票據(jù)里面也有產(chǎn)品product_id,是app_store的產(chǎn)品id,不是自己業(yè)務(wù)的產(chǎn)品id,
// 可以在后臺把自己的產(chǎn)品ID和 product_id 關(guān)聯(lián),處理業(yè)務(wù)邏輯。
}
//模擬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); //這兩行一定要加,不加會報(bào)SSL 錯(cuò)誤
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ù)組進(jìn)行相應(yīng)排序
} else {
arsort($keyArr);
}
foreach ($keyArr as $k => $v) {
$newArray[$k] = $arr[$k]; // 循環(huán)將配置的值放入響應(yīng)的下標(biāo)下
}
$newArray = array_merge($newArray); // 重置下標(biāo)
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'){
//第一次夠買的時(shí)候 不處理通知
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{
//時(shí)間不對 不處理
}
}
//處理訂閱產(chǎn)品的業(yè)務(wù)邏輯
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)文章
smarty中改進(jìn)truncate使其支持中文的方法
這篇文章主要介紹了smarty中改進(jìn)truncate使其支持中文的方法,涉及針對Smarty源碼中truncate源文件進(jìn)行函數(shù)功能擴(kuò)展的相關(guān)技巧,需要的朋友可以參考下2016-05-05
PHP將英文數(shù)字轉(zhuǎn)換為阿拉伯?dāng)?shù)字實(shí)例講解
在本篇文章里小編給大家分享了關(guān)于PHP將英文數(shù)字轉(zhuǎn)換為阿拉伯?dāng)?shù)字實(shí)例內(nèi)容,有興趣的朋友們可以參考學(xué)習(xí)下。2019-01-01
ThinkPHP實(shí)現(xiàn)二級循環(huán)讀取的方法
這篇文章主要介紹了ThinkPHP實(shí)現(xiàn)二級循環(huán)讀取的方法,是ThinkPHP基于數(shù)組的數(shù)據(jù)庫操作中非常常見的技巧,需要的朋友可以參考下2014-11-11
關(guān)于PHP定時(shí)發(fā)送服務(wù)的解決辦法
這篇文章主要介紹了關(guān)于PHP定時(shí)發(fā)送服務(wù)的解決辦法,需要的朋友可以參考下2017-04-04
Codeigniter的一些優(yōu)秀特性總結(jié)
本文總結(jié)了一下Codeigniter的一些優(yōu)秀特性,算是個(gè)人的一些心得分享,推薦給大家。2015-01-01
Laravel5.5 動(dòng)態(tài)切換多語言的操作方式
今天小編就為大家分享一篇Laravel5.5 動(dòng)態(tài)切換多語言的操作方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-10-10

