receipt = $arr[0]; $this->product_id = $arr[1]; $this->uid = $arr[2]; # 剥离一下前缀 $this->cpOrderId = $arr[3]; $this->sandbox = ($arr[4] == '否') ? false : true; # ☄,客户端竟然传的"是"和"否". $this->callbackInfo = $arr[5]; $this->sign = $arr[6]; $this->notify_url = $arr[7]; } } /** * 到苹果后台进行支付凭证校验 * @param str $receipt */ function VerifyFromApple($receipt, $sandbox, &$appleResp) { $cfg = config_for_ios::Inst($sandbox); $url = $cfg->verifySession_url; $ret = HttpUtil::makeRequest($url, JsonUtil::encode(array('receipt-data' => $receipt))); if ($ret['result']) { # 发送成功 $data = JsonUtil::decode($ret['msg']); $in_app = $data->receipt->in_app[0]; $appleResp = array( 'status' => $data->status, // # 收据状态 'product_count' => $in_app->quantity, // # 收据->内购->数量 'product_id' => $in_app->product_id, // # 收据->内购->道具编号 'transaction_id' => $in_app->transaction_id, // # 收据->内购->交易编号 'purchase_date' => $in_app->purchase_date, // # 收据->内购->购买时间 'appid' => $data->receipt->app_item_id // # 收据->appId(sandbox下为0) ); if ($appleResp['status'] == 0) { # 验证结果为 valid if ($appleResp['appid'] == $cfg->appid # Appid合法 || ($sandbox && $appleResp['appid'] == 0)) { # 或者沙箱下面appid=0 CLog::pay("[IOS.notify] Apple后台验证通过." . $ret['msg']); return true; } else { CLog::pay("[IOS.notify] 凭证的Appid不符!." . $ret['msg']); } } else { CLog::pay("[IOS.notify] Apple后台验证失败." . $ret['msg']); } } else { # 通讯失败 CLog::pay("[IOS.notify] 与Apple后台通讯失败."); } return false; } try { HttpUtil::PostOnly(); // exit(); CLog::pay("[IOS.notify] 收到支付回调请求: " . HttpUtil::getQueryString()); $params = explode('&=&', HttpUtil::getQueryString()); # 提取参数 $notify = new iosNotify($params); $cfg = config_for_ios::Inst($notify->sandbox); # 配置信息 CLog::pay($notify); $sign = md5($notify->cpOrderId . $cfg->appkey); # 计算签名md5(cpOrderId+appkey) CLog::pay("[IOS.notify] " . "[签名原文]:" . $notify->sign); CLog::pay("[IOS.notify] " . "[签名结果]:" . $sign); if ($sign != $notify->sign) { # 验证签名 exit(payResp::err(2, "Invalied sign!")); # 退出 } $appleResp = null; # 苹果的返回值 if (!VerifyFromApple($notify->receipt, $notify->sandbox, $appleResp)) { # 到苹果后台验证支付凭证 exit(payResp::err(2, "Verify from apple server failed!")); # 退出 } $order = OrderNotice::reParse_IOSOrder($notify, $appleResp); # 将参数归一化到order // var_dump($order); if ($order != null) { if ($order->Check()) { # 订单校验 if (!$order->CheckDuplicateSdkOrder()) { # 渠道订单编号校验,防重放(简单修改)攻击 CLog::pay("[IOS.notify] [异常]:" . "重复的sdk_orderId!"); # 日志 exit(payResp::err(2, 'failure')); } else if ($order->status == 1) { # 订单状态, 1代表支付成功 $order->UpdateOrderStatus(); # 更新订单状态,->已付款 CLog::pay("[IOS.notify] [发货] 订单: " # 日志 . $order->cpOrderId . ", 金额: " . $order->amount); } else if ($order->status == 2) { # status为2(failed)的情况 $order->UpdateOrderStatus(); # 直接更新订单状态,->支付失败 CLog::pay("[IOS.notify] [不发货] 订单: " . $order->cpOrderId); } else { CLog::pay("[IOS.notify] [处理结果]: FAILURE (未知的支付状态)"); # 日志 exit(payResp::err(1, '重试')); } CLog::pay("[IOS.notify] [处理结果]:" . "SUCCESS"); # 日志 exit(payResp::ok('success')); } } CLog::pay("[IOS.notify] [处理结果]:" . "FAILURE"); # 日志 exit(payResp::err(2, 'failure')); } catch (Exception $e) { CLog::pay("[IOS.notify] " . $e->getMessage()); # 日志 exit(payResp::err(1, $e->getMessage())); # 未知异常, 告诉客户端可以重试 }