| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336 |
- <?php
- namespace addons\YunfastPay\common\services;
- use addons\Store\common\services\MerchantService;
- use addons\YunfastPay\common\models\PaymentOrder;
- use addons\YunfastPay\common\models\SplitbillItem;
- use addons\YunfastPay\common\models\SplitbillLog;
- use addons\YunfastPay\common\services\trans\nocash\SplitBillTrans;
- use addons\YunfastPay\common\services\trans\TransAbstract;
- use common\enums\RabbitMqEnum;
- use Exception;
- use Yii;
- /**
- * 分账
- * @package addons\YunfastPay\common\services
- */
- class SplitBillService extends BaseService
- {
- /**
- * @var int
- */
- protected $storeId;
- /**
- * @var SettingService
- */
- protected $settingService;
- /**
- * 分账子项数据
- *
- * @var array
- */
- protected $itemLog;
- /**
- * @var YunPayService
- */
- protected $yunPayService;
- /**
- * @var PaymentOrder
- */
- protected $payment;
- /**
- * @var string
- */
- protected $orderNo;
- /**
- * 银典收取的手续费
- *
- * @var float
- */
- protected $fee = 0;
- /**
- * 扣除手续费比例
- */
- protected const FEE = 0.005;
- public function init()
- {
- $this->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);
- }
- }
|