'充值', self::TYPE_WITHDRAW_DEC => '提现', self::TYPE_ORDER_PAY_DEC => '订单支付', self::TYPE_ORDER_RECEIVE_ADD => '订单收款', self::TYPE_ORDER_REFUND_SUB => '订单退款', self::TYPE_BALANCE_TO_SECURITY => '余额转保证金', self::TYPE_SECURITY_TO_BALANCE => '保证金转余额', self::TYPE_DISPUTE_ADD => '纠纷加款', self::TYPE_DISPUTE_SUB => '纠纷扣款', self::TYPE_TRANSACTION_FEE_SUB => '交易手续费扣除', self::TYPE_TRANSACTION_FEE_ADD => '交易手续费增加', self::TYPE_ADMIN_ADD => '管理员加款', self::TYPE_ADMIN_SUB => '管理员扣款', self::TYPE_TRANSFER_TO_USER_DEC => '转账给用户', self::TYPE_TRANSFER_RECEIVE_ADD => '转账收款', self::TYPE_ORDER_DISPUTE_FEE_DEC => '纠纷仲裁费用扣除', self::TYPE_ORDER_DISPUTE_FEE_ADD => '纠纷仲裁费用退还', ]; const STATUS_WAIT = 1; const STATUS_PROCESSING = 2; const STATUS_SUCCESS = 3; const STATUS_FAIL = 4; const STATUS_DELAY_PAYMENT = 5; const STATUS = [ self::STATUS_WAIT => '等待处理', self::STATUS_PROCESSING => '处理中', self::STATUS_SUCCESS => '成功', self::STATUS_FAIL => '失败', self::STATUS_DELAY_PAYMENT => '延期到账', ]; const SOURCE_PARAMS_BALANCE = 1; const SOURCE_PARAMS_SECURITY = 2; const SOURCE_PARAMS = [ self::SOURCE_PARAMS_BALANCE => '余额', self::SOURCE_PARAMS_SECURITY => '保证金', ]; function getDelayPayList($datetime, $col = ['*']): \Illuminate\Database\Eloquent\Collection|array { return $this->newQuery()->where('status', self::STATUS_DELAY_PAYMENT)->where('delay_payment_time', '<=', $datetime)->limit(100)->get($col); } //纠纷仲裁费用退还 function typeOrderDisputeFeeAdd($uid, $currency_code, $amount, $remark = null): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(abs($amount)); //正数 $bean->setType(self::TYPE_ORDER_DISPUTE_FEE_ADD); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //变更余额 $res = $oCustomerWalletBalanceModel->addAvailableAmount($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('order dispute fee add fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //纠纷仲裁费用扣除 function typeOrderDisputeFeeDec($uid, $currency_code, $amount, $remark = null): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(-abs($amount)); //账变负数 $bean->setType(self::TYPE_ORDER_DISPUTE_FEE_DEC); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); if (Math::bcComp($resWalletBalanceModel->available_amount, abs($bean->getAmount())) != -1) throw new ModelException('balance not enough'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //变更余额 $res = $oCustomerWalletBalanceModel->subAvailableAmount($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('order dispute fee dec fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //处理延期账变 function dealDelayPaymentTransactionCmd(): void { $datetimeNow = Times::getNowDateTime(); $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); while (true) { $resList = $this->getDelayPayList($datetimeNow, ['id']); if ($resList->isEmpty()) { break; } foreach ($resList as $itemId) { try { DB::beginTransaction(); $item = $this->findItem($itemId->id); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findItem($item->wallet_id); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $updateItem = [ 'id' => $item->id, 'status' => self::STATUS_SUCCESS, 'updated_at' => Times::getNowDateTime(), ]; $res = $this->updateItem($updateItem); if (!$res) throw new ModelException('updateItem fail'); $res = $oCustomerWalletBalanceModel->unFrozenAmount($item->wallet_id, $item->amount); if (!$res) throw new ModelException('unFrozenAmount fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); } } } } //转账给用户 function typeTransferToUser($uid, $target_uid, $currency_code, $amount, $remark = null): bool { $senderWalletTransactionBean = new CustomerWalletBalanceTransactionBean(); $receiverWalletTransactionBean = new CustomerWalletBalanceTransactionBean(); $senderWalletTransactionBean->setUid($uid); $senderWalletTransactionBean->setTargetUid($target_uid); $senderWalletTransactionBean->setCurrencyCode($currency_code); $senderWalletTransactionBean->setAmount(-abs($amount)); //账变负数 $senderWalletTransactionBean->setType(self::TYPE_TRANSFER_TO_USER_DEC); $senderWalletTransactionBean->setStatus(self::STATUS_SUCCESS); $senderWalletTransactionBean->setRemark($remark); $receiverWalletTransactionBean->setUid($target_uid); $receiverWalletTransactionBean->setTargetUid($uid); $receiverWalletTransactionBean->setCurrencyCode($currency_code); $receiverWalletTransactionBean->setAmount(abs($amount)); //账变正数 $receiverWalletTransactionBean->setType(self::TYPE_TRANSFER_RECEIVE_ADD); $receiverWalletTransactionBean->setStatus(self::STATUS_SUCCESS); $receiverWalletTransactionBean->setRemark($remark); try { DB::beginTransaction(); //查询发送人余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resSenderWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($senderWalletTransactionBean->getUid(), $senderWalletTransactionBean->getCurrencyCode()); if (!$resSenderWalletBalanceModel) throw new ModelException('sender wallet not found'); //查询接收人余额 $resReceiverWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($receiverWalletTransactionBean->getUid(), $receiverWalletTransactionBean->getCurrencyCode()); if (!$resReceiverWalletBalanceModel) throw new ModelException('receiver wallet not found'); //检查发送人余额是否足够 if (Math::bcComp($resSenderWalletBalanceModel->available_amount, abs($senderWalletTransactionBean->getAmount())) != -1) throw new ModelException('balance not enough'); $senderWalletTransactionBean->setWalletId($resSenderWalletBalanceModel->id); $senderWalletTransactionBean->setBeforeTotalAmount($resSenderWalletBalanceModel->total_amount); $senderWalletTransactionBean->setAfterTotalAmount(Math::bcAdd($resSenderWalletBalanceModel->total_amount, $senderWalletTransactionBean->getAmount())); //发送人新增账变 $res = $this->addTransaction($senderWalletTransactionBean); if (!$res) throw new ModelException('addTransaction fail'); //发送人变更余额 $res = $oCustomerWalletBalanceModel->subAvailableAmount($senderWalletTransactionBean->getWalletId(), $senderWalletTransactionBean->getAmount()); if (!$res) throw new ModelException('transfer to user dec fail'); //接收人账变 $receiverWalletTransactionBean->setWalletId($resReceiverWalletBalanceModel->id); $receiverWalletTransactionBean->setBeforeTotalAmount($resReceiverWalletBalanceModel->total_amount); $receiverWalletTransactionBean->setAfterTotalAmount(Math::bcAdd($resReceiverWalletBalanceModel->total_amount, $receiverWalletTransactionBean->getAmount())); //接收人新增账变 $res = $this->addTransaction($receiverWalletTransactionBean); if (!$res) throw new ModelException('addTransaction fail'); //接收人变更余额 $res = $oCustomerWalletBalanceModel->addAvailableAmount($receiverWalletTransactionBean->getWalletId(), $receiverWalletTransactionBean->getAmount()); if (!$res) throw new ModelException('transfer receive add fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //管理员扣除 function typeAdminSub($uid, $currency_code, $amount, $remark = null): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(-abs($amount)); //账变负数 $bean->setType(self::TYPE_ADMIN_SUB); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); if (Math::bcComp($resWalletBalanceModel->available_amount, abs($bean->getAmount())) != -1) throw new ModelException('balance not enough'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //变更余额 $res = $oCustomerWalletBalanceModel->subAvailableAmount($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('admin sub fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //管理员增加 function typeAdminAdd($uid, $currency_code, $amount, $remark = null): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(abs($amount)); //正数 $bean->setType(self::TYPE_ADMIN_ADD); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //变更余额 $res = $oCustomerWalletBalanceModel->addAvailableAmount($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('admin add fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //手续费增加 function typeTransactionFeeAdd($uid, $currency_code, $amount, $remark = null): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(abs($amount)); //正数 $bean->setType(self::TYPE_TRANSACTION_FEE_ADD); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //变更余额 $res = $oCustomerWalletBalanceModel->addAvailableAmount($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('transaction fee add fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //手续费扣除 function typeTransactionFeeSub($uid, $currency_code, $amount, $remark = null): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(-abs($amount)); //账变负数 $bean->setType(self::TYPE_TRANSACTION_FEE_SUB); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //变更余额 //检查余额是否足够 if (Math::bcComp($resWalletBalanceModel->available_amount, abs($bean->getAmount())) != -1) { //从余额中扣除 $bean->setSourceParams(self::SOURCE_PARAMS_BALANCE); $res = $oCustomerWalletBalanceModel->subAvailableAmount($bean->getWalletId(), $bean->getAmount()); } else if (Math::bcComp($resWalletBalanceModel->security_amount, abs($bean->getAmount())) != -1) { //从保证金中扣除 $bean->setSourceParams(self::SOURCE_PARAMS_SECURITY); $res = $oCustomerWalletBalanceModel->subSecurityAmount($bean->getWalletId(), $bean->getAmount()); } else { throw new ModelException('balance and security not enough'); } if (!$res) throw new ModelException('transaction fee sub fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //仲裁判罚扣除 function typeDisputeSub($uid, $currency_code, $amount, $target_post_order_dispute_id, $remark = null): bool|int { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(-abs($amount)); //账变负数 $bean->setType(self::TYPE_DISPUTE_SUB); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); $bean->setTargetPostOrderDisputeId($target_post_order_dispute_id); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 $resModel = $this->addTransaction($bean); if (!$resModel) throw new ModelException('addTransaction fail'); //变更余额 //检查余额是否足够 if (Math::bcComp($resWalletBalanceModel->available_amount, abs($bean->getAmount())) != -1) { //从余额中扣除 $bean->setSourceParams(self::SOURCE_PARAMS_BALANCE); $res = $oCustomerWalletBalanceModel->subAvailableAmount($bean->getWalletId(), $bean->getAmount()); } else if (Math::bcComp($resWalletBalanceModel->security_amount, abs($bean->getAmount())) != -1) { //从保证金中扣除 $bean->setSourceParams(self::SOURCE_PARAMS_SECURITY); $res = $oCustomerWalletBalanceModel->subSecurityAmount($bean->getWalletId(), $bean->getAmount()); } else { throw new ModelException('balance and security not enough'); } if (!$res) throw new ModelException('dispute sub fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return $resModel->id; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //仲裁判罚增加 function typeDisputeAdd($uid, $currency_code, $amount, $target_post_order_dispute_id, $remark = null): bool|int { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(abs($amount)); //正数 $bean->setType(self::TYPE_DISPUTE_ADD); $bean->setStatus(self::STATUS_SUCCESS); $bean->setRemark($remark); $bean->setTargetPostOrderDisputeId($target_post_order_dispute_id); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 $resModel = $this->addTransaction($bean); if (!$resModel) throw new ModelException('addTransaction fail'); //变更余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $res = $oCustomerWalletBalanceModel->addAvailableAmount($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('dispute add fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return $resModel->id; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //押金转余额 function typeSecurityToBalance($uid, $currency_code, $amount): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(abs($amount)); //正数 $bean->setType(self::TYPE_SECURITY_TO_BALANCE); $bean->setStatus(self::STATUS_SUCCESS); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //检查保证金是否足够 if (Math::bcComp($resWalletBalanceModel->security_amount, abs($bean->getAmount())) == -1) throw new ModelException('security not enough'); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //变更余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $res = $oCustomerWalletBalanceModel->securityToBalance($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('securityToBalance fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //余额转押金 function typeBalanceToSecurity($uid, $currency_code, $amount): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(-abs($amount)); //账变负数 $bean->setType(self::TYPE_BALANCE_TO_SECURITY); $bean->setStatus(self::STATUS_SUCCESS); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //检查余额是否足够 if (Math::bcComp($resWalletBalanceModel->available_amount, abs($bean->getAmount())) == -1) throw new ModelException('balance not enough'); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //变更余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $res = $oCustomerWalletBalanceModel->balanceToSecurity($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('balanceToSecurity fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //订单支付 function typeOrderPay(CustomerUserPostOrderBean $orderBean): bool { //初始检测 if ($orderBean->getBuyerCurrencyCode() != $orderBean->getSellerCurrencyCode()) throw new ModelException('currency_code not match'); if ($orderBean->getBuyerUid() == $orderBean->getSellerUid()) throw new ModelException('buyer_uid can not match seller_uid'); if ($orderBean->getAmount() <= 0) throw new ModelException('amount error'); $orderBean->setAmount(abs($orderBean->getAmount())); //限制正数 $buyerWalletTransactionBean = new CustomerWalletBalanceTransactionBean(); $sellerWalletTransactionBean = new CustomerWalletBalanceTransactionBean(); //买家初始化 $buyerWalletTransactionBean->setType(self::TYPE_ORDER_PAY_DEC); $buyerWalletTransactionBean->setStatus(self::STATUS_SUCCESS); $buyerWalletTransactionBean->setAmount(-$orderBean->getAmount()); //负数 $buyerWalletTransactionBean->setUid($orderBean->getBuyerUid()); $buyerWalletTransactionBean->setCurrencyCode($orderBean->getBuyerCurrencyCode()); $buyerWalletTransactionBean->setTargetPostOrderId($orderBean->getId()); //卖家初始化 $sellerWalletTransactionBean->setType(self::TYPE_ORDER_RECEIVE_ADD); $sellerWalletTransactionBean->setStatus(self::STATUS_DELAY_PAYMENT); $sellerWalletTransactionBean->setAmount($orderBean->getAmount()); //正数 $sellerWalletTransactionBean->setUid($orderBean->getSellerUid()); $sellerWalletTransactionBean->setCurrencyCode($orderBean->getSellerCurrencyCode()); $sellerWalletTransactionBean->setTargetPostOrderId($orderBean->getId()); //@@计算订单延期到账时间 $delay_payment_time = Times::getNowDateTimeAddDays(1); $sellerWalletTransactionBean->setDelayPaymentTime($delay_payment_time); try { DB::beginTransaction(); //查询买家余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resBuyerWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($buyerWalletTransactionBean->getUid(), $buyerWalletTransactionBean->getCurrencyCode()); //检查买家余额是否足够 if (Math::bcComp($resBuyerWalletBalanceModel->available_amount, abs($orderBean->getAmount())) == -1) throw new ModelException('buyer balance not enough'); //设置买家卖家钱包id $buyerWalletTransactionBean->setWalletId($resBuyerWalletBalanceModel->id); $buyerWalletTransactionBean->setBeforeTotalAmount($resBuyerWalletBalanceModel->total_amount); $buyerWalletTransactionBean->setAfterTotalAmount(Math::bcAdd($resBuyerWalletBalanceModel->total_amount, $buyerWalletTransactionBean->getAmount())); //设置卖家卖家钱包id $resSellerWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($sellerWalletTransactionBean->getUid(), $sellerWalletTransactionBean->getCurrencyCode()); if (!$resSellerWalletBalanceModel) throw new ModelException('seller wallet not found'); $sellerWalletTransactionBean->setWalletId($resSellerWalletBalanceModel->id); $sellerWalletTransactionBean->setBeforeTotalAmount($resSellerWalletBalanceModel->total_amount); $sellerWalletTransactionBean->setAfterTotalAmount(Math::bcAdd($resSellerWalletBalanceModel->total_amount, $sellerWalletTransactionBean->getAmount())); //买家新增账变 $resBuyerTransaction = $this->addTransaction($buyerWalletTransactionBean); if (!$resBuyerTransaction) throw new ModelException('buyer addTransaction fail'); $buyerWalletTransactionBean->setId($resBuyerTransaction->id); //买家变更余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $res = $oCustomerWalletBalanceModel->subAvailableAmount($buyerWalletTransactionBean->getWalletId(), $buyerWalletTransactionBean->getAmount()); if (!$res) throw new ModelException('buyer order pay fail'); //卖家新增账变 $resSellerTransaction = $this->addTransaction($sellerWalletTransactionBean); if (!$resSellerTransaction) throw new ModelException('seller addTransaction fail'); $sellerWalletTransactionBean->setId($resSellerTransaction->id); //卖家变更余额 $res = $oCustomerWalletBalanceModel->addFrozenAmount($sellerWalletTransactionBean->getWalletId(), $sellerWalletTransactionBean->getAmount()); if (!$res) throw new ModelException('seller order receive fail'); //更新订单状态 $oCustomerUserPostOrderModel = new CustomerUserPostOrderModel(); $updateItem = [ 'id' => $orderBean->getId(), 'pay_status' => CustomerUserPostOrderModel::PAY_STATUS_PAID, 'buyer_wallet_transaction_id' => $buyerWalletTransactionBean->getId(), 'seller_wallet_transaction_id' => $sellerWalletTransactionBean->getId(), 'updated_at' => Times::getNowDateTime(), ]; $res = $oCustomerUserPostOrderModel->updateItem($updateItem); if (!$res) throw new ModelException('updateItem fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //发起提现 function typeWithdrawFirst($uid, $currency_code, $amount): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(-abs($amount)); //负数 $bean->setUid($uid); $bean->setType(self::TYPE_WITHDRAW_DEC); $bean->setStatus(self::STATUS_PROCESSING); try { DB::beginTransaction(); //获取提现手续费 $oTableCustomerSettingCache = new TableCustomerSettingCache(); $withdraw_fee = $oTableCustomerSettingCache->getWithdrawFeeAmount(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); //检查余额是否足够 if (Math::bcComp(Math::bcSub($resWalletBalanceModel->available_amount, $withdraw_fee), abs($bean->getAmount())) == -1) throw new ModelException('balance not enough'); $bean->setFeeAmount($withdraw_fee); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount($resWalletBalanceModel->total_amount); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //先扣除手续费 $res = $this->typeTransactionFeeSub($uid, $currency_code, $withdraw_fee, $res->id . ' withdraw fee'); if (!$res) throw new ModelException('withdraw fee fail'); //变更余额 //先冻结,等回调成功再扣减 $res = $oCustomerWalletBalanceModel->frozenAmount($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('withdraw fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); //@@发送到提现通知钱包队列 return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //提现回调 function typeWithdrawSecondCallback($id, $status, $remark = null): bool { try { DB::beginTransaction(); $resModel = $this->findItem($id); if (!$resModel) throw new ModelException('transaction not found'); if ($resModel->status != self::STATUS_PROCESSING) throw new ModelException('transaction status error'); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findItem($resModel->wallet_id); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); if ($status == self::STATUS_SUCCESS) { //扣减冻结金额 $res = $oCustomerWalletBalanceModel->subFrozenAmount($resModel->wallet_id, $resModel->amount); if (!$res) throw new ModelException('withdraw fail'); //更新账变状态 $updateItem = [ 'id' => $id, 'status' => self::STATUS_SUCCESS, 'updated_at' => Times::getNowDateTime(), 'before_total_amount' => $resWalletBalanceModel->total_amount, 'after_total_amount' => Math::bcAdd($resWalletBalanceModel->total_amount, $resModel->amount) ]; if (!empty($remark)) $updateItem['remark'] = $remark; $res = $this->updateItem($updateItem); if (!$res) throw new ModelException('updateItem fail'); } else { //失败 //解冻 $res = $oCustomerWalletBalanceModel->unFrozenAmount($resModel->wallet_id, $resModel->amount); if (!$res) throw new ModelException('withdraw fail'); //更新账变状态 $updateItem = [ 'id' => $id, 'status' => self::STATUS_FAIL, 'updated_at' => Times::getNowDateTime(), ]; if (!empty($remark)) $updateItem['remark'] = $remark; $res = $this->updateItem($updateItem); if (!$res) throw new ModelException('updateItem fail'); //返还手续费 $res = $this->typeTransactionFeeAdd($resModel->uid, $resModel->currency_code, $resModel->fee_amount, $resModel->id . ' withdraw fail return fee'); if (!$res) throw new ModelException('withdraw fail return fee fail'); } DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__ . ' ' . 'rollBack', $e, func_get_args()); return false; } } //充值 function typeRecharge($uid, $currency_code, $amount): bool { $bean = new CustomerWalletBalanceTransactionBean(); $bean->setUid($uid); $bean->setCurrencyCode($currency_code); $bean->setAmount(abs($amount)); //正数 $bean->setUid($uid); $bean->setType(self::TYPE_RECHARGE_ADD); $bean->setStatus(self::STATUS_SUCCESS); try { DB::beginTransaction(); //查询用户余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oCustomerWalletBalanceModel->findByUidCurrencyCode($bean->getUid(), $bean->getCurrencyCode()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setWalletId($resWalletBalanceModel->id); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); $bean->setAfterTotalAmount(Math::bcAdd($resWalletBalanceModel->total_amount, $bean->getAmount())); //新增账变 $res = $this->addTransaction($bean); if (!$res) throw new ModelException('addTransaction fail'); //变更余额 $oCustomerWalletBalanceModel = new CustomerWalletBalanceModel(); $res = $oCustomerWalletBalanceModel->addAvailableAmount($bean->getWalletId(), $bean->getAmount()); if (!$res) throw new ModelException('recharge fail'); DB::commit(); Logs::SuccLog(__FUNCTION__, func_get_args()); return true; } catch (\Exception $e) { DB::rollBack(); Logs::ErrLog(__FUNCTION__.'typeRecharge error rollBack', $e); return false; } } function addTransaction(CustomerWalletBalanceTransactionBean &$bean): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder|bool { if (!$bean->getWalletId()) throw new ModelException('wallet_id is required'); if (!$bean->getType()) throw new ModelException('type is required'); if (!$bean->getStatus()) $bean->setStatus(self::STATUS_WAIT); if (empty($bean->getUid()) || empty($bean->getBeforeTotalAmount())) { $oWalletBalanceModel = new CustomerWalletBalanceModel(); $resWalletBalanceModel = $oWalletBalanceModel->findItem($bean->getWalletId()); if (!$resWalletBalanceModel) throw new ModelException('wallet not found'); $bean->setUid($resWalletBalanceModel->uid); $bean->setBeforeTotalAmount($resWalletBalanceModel->total_amount); } $bean->setCreatedAt(Times::getNowDateTime()); $bean->setUpdatedAt(Times::getNowDateTime()); return $this->addItem($bean->toArrayNotNull()); } }