流程:
1、前端在调起苹果支付前,先请求到服务端,服务端先生成一条充值记录,但是状态为:未支付;然后把这个订单id发给前端。
2、前端在支付完成的时候,会收到苹果的支付凭证,将此凭证和订单id回传给服务端。订单id的作用是用来确定是哪一笔。支付凭证是拿来校验是否支付成功。检验成功后,自己的业务逻辑(将该条订单的状态改为已支付,然后加余额或延长会员时间)
在这我也说一下前端可能会遇到的一个问题,方便有遇到的,可以参考。
直接编译到苹果手机上,会一直发起失败。我们这边的解决方法是,打包出来,然后发到苹果的【TestFlight】上,然后就可以正常发起了。
而且这时候发起的支付,可以无限支付,因为是沙盒环境,不会扣费
后端在苹果支付的过程中,只需要做两步操作:
第一步:生成一条充值记录
第二部:接收到前端的支付凭证后,校验支付凭证,然后实现自己的业务逻辑
以下是苹果支付的验证。(创建订单的接口,不用特殊处理,只要生成一条未支付的订单记录就行(直接insert一条记录)。这里就不贴代码了)
'App Store无法读取你提供的JSON数据', 21002 => '收据数据不符合格式', 21003 => '收据无法被验证', 21004 => '你提供的共享密钥和账户的共享密钥不一致', 21005 => '收据服务器当前不可用', 21006 => '收据是有效的,但订阅服务已经过期。当收到这个信息时,解码后的收据信息也包含在返回内容中', 21007 => '收据信息是测试用(sandbox),但却被发送到产品环境中验证', 21008 => '收据信息是产品环境中使用,但却被发送到测试环境中验证' ]; public function _initialize() { parent::_initialize(); $this->model = model('app\\common\\model\\activity\\Order'); } public function verifyReceipt() { $receipt = $this->request->param('receipt/s', ''); if (empty($receipt)) { $this->error('订单错误'); } $this->orderNum = $this->request->param('order_id/s', ''); $order = $this->model->where(array('order_id' => $this->orderNum))->find(); if (empty($order)) { $this->error('订单错误'); } if ($order['state'] == 1) { $this->error('订单已成功支付,请确认'); } $time = time(); file_put_contents("notifyLog/notifyProcessLog".date("Ymd", $time).".log", "\n" . date("Y-m-d H:i:s", $time) . ",支付凭证:" . $receipt, FILE_APPEND); $jsonItem = json_encode(['receipt-data' => $receipt]); $url = 'https://buy.itunes.apple.com/verifyReceipt'; //正式 //模拟post提交(下面会贴出来),将前端获取到的凭证,去和苹果换取详细的支付信息 $result = $this->http_post_json($jsonItem, $url); if ($result['status'] == '21007') { //验证失败 返回app错误状态 $url = 'https://sandbox.itunes.apple.com/verifyReceipt'; //测试 $result = $this->http_post_json($jsonItem, $url); } file_put_contents("notifyLog/notifyProcessLog".date("Ymd", $time).".log", "\n" . date("Y-m-d H:i:s", $time) . ",order:" . var_export($result, true), FILE_APPEND); //如果检测到 等于 0 就是支付成功,其他的错误码去获取对应错误信息 if ($result['status'] !== 0) { //验证失败 返回app错误状态 $this->error($this->appleCode[$result['status']]); } //接下来就是做自己的业务逻辑 $this->success('充值成功'); } //模拟post提交 public 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; }}
接下来主要就是自己的业务逻辑了,自己亲测可用。验证的步骤做的不够详细,可以自己根据逻辑详细做验证。最后祝大家都能写码无bug
来源地址:https://blog.csdn.net/duyinyin/article/details/128696349