共计 2679 个字符,预计需要花费 7 分钟才能阅读完成。
前言 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) ;
}
}
}