苹果支付对接
步骤如下:
1.上架产品
首先需要在苹果网站上架对应的app产品,有对应的id和价格,名称等数据
2.前端拉起商品列表
用户登录app后,进入商品购买页面,前端拉起app在苹果网站上的商品列表信息
3.下单
用户点击'购买'操作,发送给服务端一条当前商品信息,服务端保存该商品的相关订单数据,并返回给前端一个内部业务订单号order_id
4. 购买
用户接收到服务端返回的内部订单号后发起苹果支付,支付完成后苹果会返回一个购买凭证信息,{"receipt-data" : "MIIT9wYJKoSL2JSDFsd……"},大概有8000+的长度,发送到客户端
5.发送凭证信息给服务器
前端拿到苹果返回的购买凭证信息后,将购买凭证、内部业务订单号order_id等信息传至服务端进行购买校验
6. 购买凭证校验以及后续业务逻辑处理
服务端向苹果发送校验购买凭证的请求,根据返回的结果,进行业务处理(改变订单状态等操作),最后返回校验结果给前端
校验结果状态码如下:
0 正常
21000 App Store不能读取你提供的JSON对象
21002 receipt-data域的数据有问题
21003 receipt无法通过验证
21004 提供的shared secret不匹配你账号中的shared secret
21005 receipt服务器当前不可用
21006 receipt合法,但是订阅已过期。服务器接收到这个状态码时,receipt数据仍然会解码并一起发送
21007 receipt是Sandbox receipt,但却发送至生产系统的验证服务
21008 receipt是生产receipt,但却发送至Sandbox环境的验证服务
7.返回客户端
前端拿到服务端返回的结果,视结果处理商品,比如: 返回校验成功的结果,前端需向苹果发送一条修改对应产品支付状态的消息,这样才能进行金额的结算操作
8.客服端代码
/** * 苹果手机支付回调处理: 用于处理商家订单状态等逻辑操作 */ public static function pay($params): bool {
//$input_data = '{"buddleId":"recharge_01","receiptData":"MIIULgYJKoZIhvcNAQcCoIIUHzCCFBsCAQExC...bV3L15A JAbVFEk7CLOJ7 oQr8WqvpIGu8v5rUkzEzXglAPwkg9BQZdfsew==","transactionId":"10423434320297269213"}';
$recharge_order = (new RechargeOrder())::withoutGlobalScope()->where('order_no','=',$params['order_no'])->find(); if(!$recharge_order){ throw new Exception('支付的订单号不存在:'.$params['order_no']); } //获取购买凭证 if (strlen($params['receipt_data']) < 20) { Log::info('购买凭证长度错误'); throwError('购买凭证长度错误'); } try { //验证购买凭证 $url = env('APPLE_PAY.is_sandbox') ? env('APPLE_PAY.url_sandbox') : env('APPLE_PAY.url_buy'); //获取验证请求地址 //todo 注意:返回的购买凭证里面如果有空格,把空格转换成+,不然校验不通过 $receiptDate = str_replace(" ", "+", $params['receipt_data']); //拼接校验信息 $data = [ "receipt-data" => $receiptDate ]; //转换成json字符串格式 $data = json_encode($data,JSON_UNESCAPED_UNICODE); //发送验证请求 $result = curl_post_https($url, $data); if (!$result) { throw new Exception('验证失败'); } $result = json_decode($result, true); if ($result['status'] != ApplePayCode::SUCCESS) { throw new Exception("验证失败,订单购买凭证状态为" . $result['status']); } //支付时间 $paid_at = $result['receipt']['in_app']['purchase_date']; //开始更新订单信息 $recharge_order->transaction_id = $params['transaction_id']; $recharge_order->pay_status = PayStatus::SUCCESS; $recharge_order->pay_time = gmt_to_date($paid_at); $recharge_order->save(); $res = (new OrderPay())->success($recharge_order); if(!$res){ throw new Exception('支付处理方法失败'); } return true; } catch (\Exception $e) { Log::info('苹果支付处理失败===='.$e->getMessage()); throwError('苹果支付处理失败'.$e->getMessage()); } }