【苹果内购】PHP支付结果验证
程序员文章站
2022-07-11 14:58:47
...
开发前推荐仔细看一下官方文档:
https://developer.apple.com/documentation/storekit/in-app_purchase
支付的流程基本是客户端完成的,客户端完成支付后将支付凭证传给服务端,用作服务端向appStore服务端做支付结果校验用。
代码如下:
public function validateInAppStore(Request $request)
{
try {
$input = $this->validate($request, [
'order_no' => 'required|integer|min:1',
'apple_receipt' => 'required|string',
'transaction_id'=> 'required|integer|min:1',
'is_sandbox' => 'required|bool',
'user_id' => 'required|integer|min:1'
]);
} catch (Exception $e) {
return $this->failed();
}
$appleReceipt = [
'receipt-data' => $input['apple_receipt'],
];
$model = new Apple();
$res = $model->validateInAppStore($input['order_no'], $appleReceipt, $input['transaction_id'], $input['is_sandbox']);
//验证通过或不通过后的业务代码
}
class Apple
{
public function validateInAppStore($orderNo, $appleReceipt, $transactionId, $isSandbox=0)
{
if ($isSandbox){
$url = config('apple.sandbox_url');
}else{
$url = config('apple.buy_url');
}
$res = json_decode(Func::curlPost($url, json_encode($appleReceipt)), true);
if (0 == $res['status']){
// 校验bundle_id
if ($res['receipt']['bundle_id'] != config('apple.bundle_id')){
return ["flag"=>false, "msg"=>"bundle ID不匹配"];
}
//校验订单
$orderM = new OrderApi();
$oRet = $orderM->appleProductId($orderNo);
if (empty($oRet['rtdata']) || empty($oRet['rtdata']['apple_product_id'])){
return ["flag"=>false, "msg"=>"订单信息不匹配"];
}
$productId = 0;
foreach ($res['receipt']['in_app'] as $k=>$v){
if ($transactionId == $v['transaction_id']){
$productId = $v['product_id'];
}
}
//校验商品
if ($oRet['rtdata']['apple_product_id'] != $productId){
return ["flag"=>false, "msg"=>"商品ID不符"];
}
}else{
switch ($res['status']){
case 21000:
return ['flag'=>false, "msg"=>"App Store无法读取您提供的JSON对象。"];
case 21002:
return ['flag'=>false, "msg"=>"receipt-data格式错误"];
case 21003:
return ['flag'=>false, "msg"=>"验证失败"];
case 21004:
return ['flag'=>false, "msg"=>"The shared secret you provided does not match the shared secret on file for your account."];
case 21005:
return ['flag'=>false, "msg"=>"The receipt server is not currently available."];
case 21007: {//This receipt is from the test environment
return self::validateInAppStore($orderNo, $appleReceipt, $transactionId, 1);
}
case 21008:{//This receipt is from the production environment
return self::validateInAppStore($orderNo, $appleReceipt, $transactionId, 0);
}
default:
return ['flag'=>false, "msg"=>"Internal data access error."];
}
}
return [
"flag"=>true,
"msg"=>"支付成功"
];
}
上一篇: postman 验证返回结果