settingService = new SettingService(['mall_id' => $this->mall_id]); $this->yunPayService = new YunPayService(['mall_id' => $this->mall_id]); } /** * 进行分账 * * @param array $data * [ * order_no => 订单号 * amount_received => 分配金额 * user_id => 用户ID * store_id => 店铺ID * mall_id => 商城ID * type => 订单类型 * ] * @return void */ public function divide(array $data) { try { $this->getPaymentOrder($data['order_no']); // 设置手续费 $this->setYunfastFeeAmount(); // 获取分账数据 $this->yunPayService->setStoreId($data['store_id']); $trans = $this->getSplitBillTrans($data['store_id'], (float)$data['amount_received']); // 是否已经分账 if ($this->payment->isSplitBill()) { return true; } $res = $this->yunPayService->sendPayRq($trans); $id = $this->addSplitBillLog($res); } catch (Exception $e) { Yii::error($e->getMessage()); return false; } return true; } /** * 添加分账记录 * * @return int|false */ public function addSplitBillLog(array $res) { $req_data = $this->yunPayService->getReqData(); $t = Yii::$app->db->beginTransaction(); try { // 设置分账 if ($res['resCode'] == 'SUCCESS') { $this->payment->splitBill(); } // 添加分账记录 $log = SplitbillLog::addLog([ 'mall_id' => $this->mall_id, 'order_no' => $this->getOrderNo(), 'payment_id' => $this->payment->id, 'req_data' => $req_data, 'res_data' => $res, 'status' => $res['resCode'] == 'SUCCESS' ? 1 : 0, ]); // 分账子项记录 foreach ($this->itemLog as $item) { $model = SplitbillItem::addLog([ 'mall_id' => $this->mall_id, 'log_id' => $log->id, 'store_id' => $item['store_id'], 'amount' => $item['item10'], 'role' => $item['item2'], 'mcht_cd' => $item['item3'], 'fee_party' => $item['item4'], ]); $this->storeFastAgent($model); } $t->commit(); return $log->id; } catch (Exception $e) { $t->rollBack(); Yii::error('添加分账记录 ' . $e->getLine() . $e->getMessage()); } return false; } /** * 商家快速到账 * * @param SplitbillItem $item * @return void */ private function storeFastAgent($item) { // 添加快速到账任务 if (!empty($item) && ($item->store_id > 0)) { $data = [ 'id' => $item->id, 'mall_id' => $item->mall_id, ]; Yii::$app->services ->rabbitMq ->delay(10, $data, HandleMqService::class, 'handleStoreAgent'); } } /** * 获取分账 * * @param string $order_no * @param integer $store_id * @param float $amount * @return SplitBillTrans */ public function getSplitBillTrans( int $store_id, float $amount ) { $trans = new SplitBillTrans( $this->settingService->getOrgCd(), $this->getOrderNo(), $this->payment->getOglOrdId() ); // 获取分给门店的费用 $store_amount = $this->getStoreAmount($amount); $this->setSplitBillItemData($trans, $store_id, $store_amount); $this->setLeftSplitBillItemData($trans); return $trans; } /** * 获取分给门店的费用 * * @return float */ protected function getStoreAmount(float $amount) { // 暂时门店承担 $store_amount = bcsub($amount, $this->fee, 2); return $store_amount > 0 ? $store_amount : $amount; } /** * 判断是否全部给了门店 * * @param float $amount * @return boolean */ protected function isAllToStore(float $amount) { return $amount == $this->payment->amount; } /** * 设置剩下的金额分账给平台 * * @param SplitBillTrans $trans * @return void */ public function setLeftSplitBillItemData(SplitBillTrans $trans) { $left = $this->getLeftAmount($trans); if ($left > 0) { $this->setSplitBillItemData($trans, 0, $left); } } /** * 获取支付订单 * * @param string $order_no * @return void */ public function getPaymentOrder($order_no) { $this->payment = PaymentOrder::getPaymentByCashierOrderNo($order_no); if (empty($this->payment)) { throw new Exception('当前支付方式不支持'); } } /** * 获取店铺分账数据 * * @return string */ public function getStoreMchtCd(int $store_id) { // 当店铺ID为0 返回平台mchtId if ($store_id == 0) return $this->settingService->getMchtCd(); $merchant = new MerchantService(['mall_id' => $this->mall_id, 'store_id' => $store_id]); return $merchant->getMchtCd(); } /** * 设置子项分账数据 * * @param TransAbstract $trans * @param integer $store_id * @param float $amount * @return void */ public function setSplitBillItemData( TransAbstract $trans, int $store_id, float $amount ) { if ($amount > 0) { $trans->setSplitBillItem( $this->getStoreMchtCd($store_id), $amount ); $this->itemLog[] = array_merge( $trans->getSplitBillItem(), [ 'store_id' => $store_id ] ); } } /** * 设置银典收取的手续费 * * @return void */ protected function setYunfastFeeAmount() { $this->fee = round(bcmul($this->payment->amount, static::FEE, 3), 2); } /** * 获取分账之后剩下的金额(分给平台用) * * @return float */ protected function getLeftAmount(SplitBillTrans $trans) { $totalAmount = array_sum(array_column($trans->getSplitBill(), 'item10')); return bcsub($this->getTotalAmount(), $totalAmount, 3); } /** * 获取一共可以分配的金额 * * @return float */ protected function getTotalAmount() { return bcsub($this->payment->amount, $this->fee, 2); } /** * 获取一个订单号 * * @return string */ protected function getOrderNo() { return 'BS' . date('YmdHis') . mt_rand(100, 999); } }