/** * based on the pay form ,generate Trans, this method can be rewrite by the child class * * @return Trans 返回trans实例 */ public function getTrans() { $this->booking = Booking::findOne(['bid' => $this->booking_id, 'q_uid' => Yii::$app->user->identity['uid']]); if (empty($this->booking)) { $this->addError('booking_id', '指定的订单不存在'); return false; } //如果预定已经成功支付,则不允许用户进行第二次支付 if ($this->booking->status > BookingStatus::PAYSUCCESS) { $this->addError('booking_id', '订单已支付!'); return false; } if (empty($this->booking->trans_id)) { $this->trans = $this->generateTrans(); } else { $this->trans = Trans::findOne($this->booking->trans_id); } return $this->trans; }
/** * @brief 处理充值消息通知的action,对于notify来讲,不需要做页面跳转,只需要针对不同的支付方式返回对应的状态 * * @return public function * @retval * @see * @note * @author 吕宝贵 * @date 2015/12/09 23:30:24 **/ protected function processPayNotify($payChannelId) { $channels = PayChannel::find()->select(['id', 'name', 'alias'])->indexBy('id')->all(); //回调的时候,appId根据返回的参数来确定 $payment = new Payment($channels[$payChannelId]['alias']); //判断订单是否支付成功, 如果成功则进入成功处理逻辑 if ($payment->checkPayStatus() === false) { Yii::error('支付结果检查失败!'); $payment->replyFailureToServer(); exit; } $receivable = $payment->getReceivable(); if (!$receivable) { Yii::error('找不到对应的收款单!'); $payment->replyFailureToServer(); exit; } else { //如果收款单的付款成功事件已被处理,则直接返回服务器成功 if ($receivable->hasPaySucceeded()) { Yii::info('收款单已处理!'); $payment->replySuccessToServer(); exit; } } //如果checkPayStatus返回成功,代表支付成功,此时进行实际的业务处理 $transaction = Yii::$app->db->beginTransaction(); //设置支付的成功和失败回调函数,此处处理的主要是账户体系的逻辑 $handlers = ['paySuccessHandler' => [Yii::$app->account, 'processChargePaySuccess'], 'payFailHandler' => [Yii::$app->account, 'processPayFailure']]; $trans = null; //业务逻辑处理,此处应当判断订单是否成功 if ($transId = $payment->processNotify($handlers)) { //充值交易完成,在commit之后,需要回告给服务器 $transaction->commit(); $trans = Trans::findOne($transId); Yii::info('交易id为:' . $transId, 'account-pay-notify'); Yii::info('成功处理用户充值逻辑', 'account-pay-notify'); //如果交易存在关联的交易,则查询关联交易的信息,并尝试支付相应的关联订单,需要提供订单的回调函数 if ($trans->trans_id_ext) { //如果存在关联订单,需要开启新事务处理相关订单 Yii::info('存在关联交易,处理关联交易逻辑', 'account-pay-notify'); $transaction = Yii::$app->db->beginTransaction(); $transOrder = Trans::findOne($trans->trans_id_ext); if (!$transOrder) { $transaction->rollback(); Yii::warning('关联交易查询失败,并不存在该关联交易订单, 退出购买逻辑', 'account-pay-notify'); exit; } if (Yii::$app->account->pay($transOrder)) { //如果关联交易为产品购买 if ($transOrder->trans_type_id == Trans::TRANS_TYPE_TRADE) { $booking = Booking::findOne(['bid' => $transOrder->trans_id_ext]); if (!$booking) { $transaction->rollback(); Yii::warning('查询关联预订失败', 'account-pay-notify'); throw new LBUserException('查询关联订单信息失败', 2); exit; } Yii::info('关联预订信息获取成功', 'account-pay-notify'); $callbackData = ['bid' => $booking->bid, 'trans_id' => $booking->trans_id]; //此处的回调为业务上的订单处理回调 if (!Booking::processPaySuccess($callbackData)) { $transaction->rollback(); Yii::warning('关联预订处理操作失败', 'account-pay-notify'); throw new LBUserException('订单支付成功回调处理失败', 3); exit; } Yii::info('关联预订相关回调处理成功', 'account-pay-notify'); } $transaction->commit(); Yii::info('提交事务...', 'account-pay-notify'); //页面跳转逻辑 } else { $transaction->rollback(); Yii::error('用户付款失败', 'account-pay-notify'); exit; } } else { Yii::info('交易没有关联订单:', 'account-pay-notify'); Yii::info($trans); } } else { $transaction->rollback(); Yii::warning('处理支付成功失败...', 'account-pay-notify'); $payment->replyFailureToServer(); exit; } Yii::info('交易成功处理...', 'account-pay-notify'); $payment->replySuccessToServer(); exit; }