diff --git a/app/Console/Commands/OrderProfitCommand.php b/app/Console/Commands/OrderProfitCommand.php index 4cc328cd..3df5cdaf 100644 --- a/app/Console/Commands/OrderProfitCommand.php +++ b/app/Console/Commands/OrderProfitCommand.php @@ -42,7 +42,6 @@ class OrderProfitCommand extends Command */ public function handle() { - $service = new DistributeService(); $now = now(); @@ -63,28 +62,17 @@ class OrderProfitCommand extends Command ->limit(10) ->get(); - // 修改提成记录的状态为 等待结算 - OrderProfit::whereIn('order_id', $orders->pluck('id'))->where('status', 0)->update(['status' => 4]); - - // 获取 等待结算 的提成记录, 按照 user_id 分组 - OrderProfit::where('status', 4)->chunk(50, function ($list) use ($service) { - $list = $list->groupBy('user_id'); - foreach($list as $id => $items) { - try { - DB::beginTransaction(); - $service->wechatTransfers($items); - DB::commit(); - } catch (\Exception $e) { - DB::rollBack(); - $this->error($e->getMessage()); - } - } - }); - - // 没有待付款的提成记录 - foreach($orders as $item) { - if (!$item->profits()->where('status', 4)->exists()) { - $item->update(['profit_paid' => $now]); + foreach ($orders as $order) { + try { + DB::beginTransaction(); + $service->wechatShare($order); + // 分账成功, 更新订单状态 + $order->update(['profit_paid' => $now]); + DB::commit(); + } catch (\Exception $e) { + DB::rollBack(); + report($e); + $this->error($e->getMessage()); } } diff --git a/app/Enums/PayWay.php b/app/Enums/PayWay.php index 45941364..c6901a7d 100644 --- a/app/Enums/PayWay.php +++ b/app/Enums/PayWay.php @@ -12,6 +12,7 @@ enum PayWay: string { case WxpayJsApi = 'wxpay_jsapi'; case WxpayMiniProgram = 'wxpay_mp'; case WxpayTransfer = 'wxpay_transfer'; + case WxPayShare = 'wx_pay_share'; // 阿里支付 case AlipayApp = 'alipay_app'; @@ -21,7 +22,7 @@ enum PayWay: string { static::Offline => '#5b69bc', static::Balance => '#dda451', static::Wallet => '#ff8acc', - static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram, static::WxpayTransfer => '#21b978', + static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram, static::WxpayTransfer, static::WxPayShare => '#21b978', static::AlipayApp => '#3085d6', default => '#ea5455', }; @@ -33,7 +34,7 @@ enum PayWay: string { static::Offline => 'offline', static::Balance => 'balance', static::Wallet => 'wallet', - static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram => 'wxpay', + static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram, static::WxPayShare => 'wxpay', static::AlipayApp => 'alipay', }; } @@ -44,7 +45,7 @@ enum PayWay: string { static::Offline => '线下', static::Balance => '余额', static::Wallet => '可提', - static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram => '微信支付', + static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram, static::WxPayShare => '微信支付', static::AlipayApp => '支付宝', default => 'Unknown', }; @@ -64,6 +65,7 @@ enum PayWay: string { static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram => '微信支付', static::AlipayApp => '支付宝', static::WxpayTransfer => '微信企业付款', + static::WxPayShare => '微信分账', }; } diff --git a/app/Services/DistributeService.php b/app/Services/DistributeService.php index 6effaef5..81703a78 100644 --- a/app/Services/DistributeService.php +++ b/app/Services/DistributeService.php @@ -2,6 +2,7 @@ namespace App\Services; +use App\Enums\PayWay; use App\Models\{User, Order, SalesValueLog, Agent, OrderProfit, SocialiteUser}; use App\Services\Payment\WxpayService; use App\Enums\SocialiteType; @@ -69,9 +70,9 @@ class DistributeService /** * 根据订单, 添加返现记录 * - * @param \App\Models\Order $order + * @param Order $order * - * @return \App\Models\OrderProfit + * @return \Illuminate\Database\Eloquent\Collection */ public function storeByOrder(Order $order) { @@ -80,7 +81,7 @@ class DistributeService // 上级返利 $parentIds = array_reverse($user->userInfo->parent_ids); - // 按照推荐的顺序,第一位是直属推荐人 + // 按照推荐的顺序, 第一位是直属推荐人 $parents = User::with(['userInfo', 'agent'])->whereIn('id', $parentIds)->get()->sortBy(fn($item) => array_search($item->id, $parentIds)); // 过滤掉 不是代理身份 的用户 // 过滤掉 相同等级 的 后者 用户 @@ -214,6 +215,38 @@ class DistributeService $this->success($filtered, $result); } + /** + * 微信分账 + * + * @return void + */ + public function wechatShare(Order $order) + { + $receivers = []; + $sn = serial_number(); + $list = $order->profits; + foreach ($list as $item) { + $openid = SocialiteUser::where('socialite_type', SocialiteType::WechatMiniProgram->value)->where('user_id', $item->user_id)->value('socialite_id'); + if (!$openid) { + throw new BizException('用户 '.$item->user_id.' 没有 openid'); + } + $item->update(['pay_way' => PayWay::WxPayShare, 'pay_no' => $sn, 'status' => 1]); + array_push($receivers, [ + "type" => "PERSONAL_OPENID", + "account" => $openid, + "amount" => $item->money * 100, + "description" => "推荐返利" + ]); + } + + $result = (new WxpayService())->share($order->out_trade_no, $sn, $receivers); + + $status = data_get($result, 'status'); + if ($status == 'FINISHED') { + $this->success($list, $result); + } + } + /** * 支付成功 * diff --git a/app/Services/OrderService.php b/app/Services/OrderService.php index e2224f6e..36fc7008 100644 --- a/app/Services/OrderService.php +++ b/app/Services/OrderService.php @@ -237,12 +237,12 @@ class OrderService /** * 门店直接下单 - * + * * @param User $user * @param int $storeId * @param array $products 商品信息 [{sku_id, quantity}] * @param array $params {coupon_id: 优惠券id, desk: 桌号id} - * + * * @return Order * @throws BizException */ @@ -987,15 +987,15 @@ class OrderService $pass = false; foreach ($products as $item) { $sku = $item['sku']; - - if ($coupon->isSupport($sku)) { + $support = $coupon->isSupport($sku); + if ($support) { $pass = true; } $amount = $item['total_amount'] - $item['vip_discount_amount']; // 仅保留商品真实总额大于0的商品 - if ($amount > 0) { + if ($amount > 0 && $support) { $amounts[$sku->id] = $amount; } } @@ -1198,6 +1198,7 @@ class OrderService 'out_trade_no' => $payLog->pay_sn, 'total_fee' => $order->total_amount, 'trade_type' => $tradeType->value, + 'profit_sharing' => 'Y', ]; if ($tradeType === WxpayTradeType::JSAPI) { @@ -1361,7 +1362,7 @@ class OrderService /** * 打印订单小票 - * + * * @param Order $order 订单 * @return array 打印结果 [{code: 0(成功), msg: ''}, ...] * @throws BizException diff --git a/app/Services/Payment/WxpayService.php b/app/Services/Payment/WxpayService.php index 5fc4c9ce..45f81530 100644 --- a/app/Services/Payment/WxpayService.php +++ b/app/Services/Payment/WxpayService.php @@ -25,9 +25,7 @@ class WxpayService public function pay(array $params, ?string $payment = null): array { if (! isset($params['notify_url'])) { - $path = route('wxpay.paid_notify', ['payment' => $payment ?: 'default'], false); - - $params['notify_url'] = url($path, [], true); + $params['notify_url'] = route('wxpay.paid_notify', ['payment' => $payment ?: 'default']); } if (! isset($params['trade_type'])) { @@ -101,6 +99,50 @@ class WxpayService return $result; } + /** + * 微信支付-单次分账 + * + * @param $order_sn string 商户订单号 + * @param $share_sn string 分账订单号 + * @param $receivers array 接收方{} + * @return mixed + */ + public function share(string $order_sn, string $share_sn, array $receivers): mixed + { + $config = config('wechat.payment.transfer'); + $app = Factory::payment($config); + + // 添加分账接收方 + foreach ($receivers as $receiver) { + $app->profit_sharing->addReceiver([ + "type" => $receiver['type'], + "account" => $receiver['account'], + "relation_type" => "DISTRIBUTOR" + ]); + } + + $result = $app->profit_sharing->share($order_sn, $share_sn, $receivers); + + $this->validateResult($result); + + return $result; + } + + /** + * 微信支付-查询分账结果 + * + * @param string $order_sn + * @param string $share_sn + * @return mixed + */ + public function queryShare(string $order_sn, string $share_sn) + { + $config = config('wechat.payment.transfer'); + $app = Factory::payment($config); + + return $app->profit_sharing->query($order_sn, $share_sn); + } + /** * 根据商户订单号退款 * diff --git a/tests/Feature/ExampleTest.php b/tests/Feature/ExampleTest.php index 3a014d84..9aea456a 100644 --- a/tests/Feature/ExampleTest.php +++ b/tests/Feature/ExampleTest.php @@ -2,8 +2,10 @@ namespace Tests\Feature; +use App\Services\DistributeService; +use Illuminate\Support\Facades\DB; use Tests\TestCase; -use App\Services\PrintService; +use App\Models\Order; class ExampleTest extends TestCase { @@ -14,17 +16,17 @@ class ExampleTest extends TestCase */ public function test_example() { - dd(PrintService::make()->template('00596456352258754', 'a4fcc59f40fd438d9afdd4fc2e9b99fc', [ - 'name' => '乡村基', - 'sn' => '20230223133856127032', - 'time' => '2023-02-23 13:38:56', - 'desk' => '10号桌', - 'products' => [ - ['name' => '香草拿铁(大杯)', 'price' => '32.00', 'amount' => '1', 'money' => '32.00'], - ['name' => '西瓜汁(大杯)', 'price' => '18.00', 'amount' => '1', 'money' => '18.00'], - ], - 'total' => '50.00', - 'remarks' => '打包' - ])); + // $order = Order::where('sn', '20230813185220618108')->first(); + // try { + // DB::beginTransaction(); + // (new DistributeService())->wechatShare($order); + // $order->update(['profit_paid' => now()]); + // DB::commit(); + // } catch (\Exception $e) { + // DB::rollBack(); + // report($e); + // } + dump(route('wxpay.paid_notify', ['payment' => 'default'])); + $this->assertTrue(true); } }