/** * @brief 退款操作,会根据交易的具体形态来判断退款方法,仅用户之间的交易支持退款,充值和提现不支持退款 * * @return public function * @retval * @see * @note * @author 吕宝贵 * @date 2015/11/30 10:32:54 **/ public function refundTrans($transId) { $trans = Trans::findOne($transId); if (empty($trans)) { //此处可记录错误日志,或者写错误信息 Yii::$app->warning('没有此交易记录'); return false; } //仅用户之间的交易支持退款 if ($trans->type != Trans::TRANS_TYPE_TRADE) { Yii::$app->warning('仅用户之间的交易支持退款'); return false; } //如果已经在走退款流程,则直接抛出异常 if ($trans->status === Trans::PAY_STATUS_REFUNDED) { Yii::$app->warning('退款已在进行中,或者已完成退款'); } //根据交易的不同状态进行退款 switch ($trans->status) { case Trans::PAY_STATUS_SUCCEEDED: //从担保账号中退款,由于交易没有达成,分润也没有做,直接退款即可 $vouchAccount = UserAccount::findOne($vouchAccountId); if (!$vouchAccount->minus($money)) { return false; } break; case Trans::PAY_STATUS_FINISHED: //获取卖家账号,并退款 $sellerAccount = UserAccount::findOne($vouchAccountId); if (!$sellerAccount->minus($money)) { return false; } break; default: return false; } //对于finishRefundTrans,需要区分交易状态,SUCCEEDED状态只返还用户钱款即可,FINISHED状态需要退利润等 if ($this->finishRefundTrans($trans)) { return true; } else { return false; } }
/** * @brief * * @return * @retval * @author 吕宝贵 * @date 2015/12/05 12:45:52 **/ protected function processFee($action, $trans) { $feeAccount = UserAccount::getFeeAccount(); switch ($action) { case 'pay': $this->plus($feeAccount->uid, $trans->fee, $trans->id, '手续费收入'); break; case 'refund': $this->minus($feeAccount->uid, $trans->fee, $trans->id, '手续费退款'); break; default: break; } }
/** * @brief * * @return protected function * @retval * @see * @note * @author 吕宝贵 * @date 2015/12/05 12:45:03 **/ protected function processProfit($action, $money, $reason) { $profitAccount = UserAccount::findOne($globalProfitAccountId); switch ($action) { case 'pay': $profitAccount->plus($money, $reason); break; case 'refund': $profitAccount->minus($money, $reason); break; default: break; } }
/** * @brief 退款操作,会根据交易的具体形态来判断退款方法,仅用户之间的交易支持退款,充值和提现不支持退款 * * @return public function * @retval * @see * @note * @author 吕宝贵 * @date 2015/11/30 10:32:54 **/ public function refundTrans($transId) { $trans = Trans::findOne($transId); if (empty($trans)) { //此处可记录错误日志,或者写错误信息 Yii::$app->warning('没有此交易记录'); return false; } //仅用户之间的交易支持退款 if (!$trans->transType->refundable) { Yii::$app->warning('此种交易不支持退款'); return false; } //如果已经在走退款流程,则直接抛出异常 if ($trans->status === Trans::PAY_STATUS_REFUNDED) { Yii::$app->warning('退款已在进行中,或者已完成退款'); } //根据交易的不同状态进行退款 switch ($trans->status) { case Trans::PAY_STATUS_SUCCEEDED: //从担保账号中退款,由于交易没有达成,分润也没有做,直接退款即可 $vouchAccount = $this->getVouchAccount(); if (!$vouchAccount->minus($money, $trans, '担保交易担保账号退款')) { return false; } break; case Trans::PAY_STATUS_FINISHED: //获取卖家账号,并退款,如果卖方收款但是余额不足,无法退款。后期可以采用保证金方式,目前不支持此种退款 $sellerAccount = UserAccount::findOne($trans->to_uid); if (!$sellerAccount->minus($money, $trans, '产品交易退款')) { return false; } break; default: $this->addError('display-error', '此种支付状态下的交易无法申请退款'); return false; } //对于finishRefundTrans,需要区分交易状态,SUCCEEDED状态只返还用户钱款即可,FINISHED状态需要退利润等 if ($this->finishRefundTrans($trans)) { return true; } else { return false; } }
/** * @brief 退款操作,会根据交易的具体形态来判断退款方法,仅用户之间的交易支持退款,充值和提现不支持退款 * * @return public function * @retval * @see * @note * @author 吕宝贵 * @date 2015/11/30 10:32:54 **/ public function refundTrans($transId, $refundMoney) { $trans = Trans::findOne($transId); if (empty($trans)) { //此处可记录错误日志,或者写错误信息 Yii::$app->warning('没有此交易记录'); $this->addError(__METHOD__, '不存在transId指定的交易'); return false; } //仅用户之间的交易支持退款 if (!$trans->transType->refundable) { Yii::$app->warning('此种交易不支持退款'); $this->addError(__METHOD__, '该类型的交易不支持退款,仅用户之间的担保交易支持退款'); return false; } //如果已经在走退款流程,则直接抛出异常 if ($trans->status === Trans::PAY_STATUS_REFUNDED) { Yii::$app->warning('退款已在进行中,或者已完成退款'); $this->addError(__METHOD__, '退款已在进行中,请勿重复退款'); return false; } //退款金额大小判断:退款金额需要大于0,同时退款金额不能超过交易总金额 if ($refundMoney >= 0) { if ($refundMoney > $trans->total_money) { $this->addError(__METHOD__, '退款金额不能大于交易总金额'); return false; } else { $trans->earnest_money = $trans->total_money - $refundMoney; $trans->refunded_money = $refundMoney; } } else { $this->addError('display-error', '退款金额需要大于0,并且不能超过订单总金额!'); return false; } //根据交易的不同状态进行退款 switch ($trans->status) { case Trans::PAY_STATUS_SUCCEEDED: //从担保账号中退款,由于交易没有达成,分润也没有做,直接退款即可 $vouchAccount = UserAccount::getVouchAccount(); if (!$this->minus($vouchAccount->uid, $trans->total_money, $trans->id, '担保交易担保账号退款')) { $this->addError(__METHOD__, '担保账号退款失败'); return false; } //如果交易存在保证金,则直接在退款同时将保证金打款给hug if ($trans->earnest_money > 0) { $sellerAccount = $this->getUserAccount($trans->to_uid); if (!$this->plus($sellerAccount->uid, $trans->earnest_money, $trans->id, '产品退款订金收入')) { $this->addError(__METHOD__, '给卖家打款保证金时出错'); return false; } } break; case Trans::PAY_STATUS_FINISHED: //TODO //获取卖家账号,并退款,如果卖方收款但是余额不足,无法退款。后期可以采用保证金方式,目前不支持此种退款 return false; $sellerAccount = $this->getUserAccount($trans->to_uid); if (!$sellerAccount->minus($trans->money, $trans, '产品交易退款')) { return false; } break; default: $this->addError('display-error', '此种支付状态下的交易无法申请退款'); return false; } //对于finishRefundTrans,需要区分交易状态,SUCCEEDED状态只返还用户钱款即可,FINISHED状态需要退利润等 if ($this->finishRefundTrans($trans)) { $transLog = new TransLog(); $transLog->action = '交易退款'; $transLog->money = $refundMoney; $transLog->currency = $trans->currency; $transLog->trans_id = $trans->id; if ($transLog->save()) { return true; } else { return false; } } else { return false; } }
/** * @brief 退款的后续处理操作,完成交易和付款成功有不同的退款逻辑, 此方法主要完成退款后买方和手续费等处理操作 * * @return protected function * @retval * @see * @note * @author 吕宝贵 * @date 2015/12/06 18:02:59 **/ protected function finishRefundTrans($trans) { //退款是否收取手续费,可以在这里做逻辑判断,此处退款退给用户多少钱,需要确定 $buyerAccount = UserAccount::findOne($trans->from_uid); if (!$buyerAccount->plus($trans->total_money - $trans->earnest_money, $trans, '产品退款')) { return false; } //对于支付交易已经完成的订单,需要退款手续费,利润,还有保证金等操作,一期先不做。 if ($trans->status = Trans::PAY_STATUS_FINISHED) { throw new Exception('对不住,交易处于此种状态目前并不支持退款操作, 请联系客服人员'); } //保存交易状态 $trans->status = Trans::PAY_STATUS_REFUNDED; $trans->save(); return true; }