6
0
Fork 0

test wx share

base
panliang 2023-10-11 13:08:47 +08:00
parent 61118088c8
commit a29c9ccabf
6 changed files with 119 additions and 51 deletions

View File

@ -42,7 +42,6 @@ class OrderProfitCommand extends Command
*/ */
public function handle() public function handle()
{ {
$service = new DistributeService(); $service = new DistributeService();
$now = now(); $now = now();
@ -63,28 +62,17 @@ class OrderProfitCommand extends Command
->limit(10) ->limit(10)
->get(); ->get();
// 修改提成记录的状态为 等待结算 foreach ($orders as $order) {
OrderProfit::whereIn('order_id', $orders->pluck('id'))->where('status', 0)->update(['status' => 4]); try {
DB::beginTransaction();
// 获取 等待结算 的提成记录, 按照 user_id 分组 $service->wechatShare($order);
OrderProfit::where('status', 4)->chunk(50, function ($list) use ($service) { // 分账成功, 更新订单状态
$list = $list->groupBy('user_id'); $order->update(['profit_paid' => $now]);
foreach($list as $id => $items) { DB::commit();
try { } catch (\Exception $e) {
DB::beginTransaction(); DB::rollBack();
$service->wechatTransfers($items); report($e);
DB::commit(); $this->error($e->getMessage());
} 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]);
} }
} }

View File

@ -12,6 +12,7 @@ enum PayWay: string {
case WxpayJsApi = 'wxpay_jsapi'; case WxpayJsApi = 'wxpay_jsapi';
case WxpayMiniProgram = 'wxpay_mp'; case WxpayMiniProgram = 'wxpay_mp';
case WxpayTransfer = 'wxpay_transfer'; case WxpayTransfer = 'wxpay_transfer';
case WxPayShare = 'wx_pay_share';
// 阿里支付 // 阿里支付
case AlipayApp = 'alipay_app'; case AlipayApp = 'alipay_app';
@ -21,7 +22,7 @@ enum PayWay: string {
static::Offline => '#5b69bc', static::Offline => '#5b69bc',
static::Balance => '#dda451', static::Balance => '#dda451',
static::Wallet => '#ff8acc', 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', static::AlipayApp => '#3085d6',
default => '#ea5455', default => '#ea5455',
}; };
@ -33,7 +34,7 @@ enum PayWay: string {
static::Offline => 'offline', static::Offline => 'offline',
static::Balance => 'balance', static::Balance => 'balance',
static::Wallet => 'wallet', 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', static::AlipayApp => 'alipay',
}; };
} }
@ -44,7 +45,7 @@ enum PayWay: string {
static::Offline => '线下', static::Offline => '线下',
static::Balance => '余额', static::Balance => '余额',
static::Wallet => '可提', static::Wallet => '可提',
static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram => '微信支付', static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram, static::WxPayShare => '微信支付',
static::AlipayApp => '支付宝', static::AlipayApp => '支付宝',
default => 'Unknown', default => 'Unknown',
}; };
@ -64,6 +65,7 @@ enum PayWay: string {
static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram => '微信支付', static::WxpayApp, static::WxpayH5, static::WxpayJsApi, static::WxpayMiniProgram => '微信支付',
static::AlipayApp => '支付宝', static::AlipayApp => '支付宝',
static::WxpayTransfer => '微信企业付款', static::WxpayTransfer => '微信企业付款',
static::WxPayShare => '微信分账',
}; };
} }

View File

@ -2,6 +2,7 @@
namespace App\Services; namespace App\Services;
use App\Enums\PayWay;
use App\Models\{User, Order, SalesValueLog, Agent, OrderProfit, SocialiteUser}; use App\Models\{User, Order, SalesValueLog, Agent, OrderProfit, SocialiteUser};
use App\Services\Payment\WxpayService; use App\Services\Payment\WxpayService;
use App\Enums\SocialiteType; 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) public function storeByOrder(Order $order)
{ {
@ -80,7 +81,7 @@ class DistributeService
// 上级返利 // 上级返利
$parentIds = array_reverse($user->userInfo->parent_ids); $parentIds = array_reverse($user->userInfo->parent_ids);
// 按照推荐的顺序第一位是直属推荐人 // 按照推荐的顺序, 第一位是直属推荐人
$parents = User::with(['userInfo', 'agent'])->whereIn('id', $parentIds)->get()->sortBy(fn($item) => array_search($item->id, $parentIds)); $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); $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);
}
}
/** /**
* 支付成功 * 支付成功
* *

View File

@ -237,12 +237,12 @@ class OrderService
/** /**
* 门店直接下单 * 门店直接下单
* *
* @param User $user * @param User $user
* @param int $storeId * @param int $storeId
* @param array $products 商品信息 [{sku_id, quantity}] * @param array $products 商品信息 [{sku_id, quantity}]
* @param array $params {coupon_id: 优惠券id, desk: 桌号id} * @param array $params {coupon_id: 优惠券id, desk: 桌号id}
* *
* @return Order * @return Order
* @throws BizException * @throws BizException
*/ */
@ -987,15 +987,15 @@ class OrderService
$pass = false; $pass = false;
foreach ($products as $item) { foreach ($products as $item) {
$sku = $item['sku']; $sku = $item['sku'];
$support = $coupon->isSupport($sku);
if ($coupon->isSupport($sku)) { if ($support) {
$pass = true; $pass = true;
} }
$amount = $item['total_amount'] - $item['vip_discount_amount']; $amount = $item['total_amount'] - $item['vip_discount_amount'];
// 仅保留商品真实总额大于0的商品 // 仅保留商品真实总额大于0的商品
if ($amount > 0) { if ($amount > 0 && $support) {
$amounts[$sku->id] = $amount; $amounts[$sku->id] = $amount;
} }
} }
@ -1198,6 +1198,7 @@ class OrderService
'out_trade_no' => $payLog->pay_sn, 'out_trade_no' => $payLog->pay_sn,
'total_fee' => $order->total_amount, 'total_fee' => $order->total_amount,
'trade_type' => $tradeType->value, 'trade_type' => $tradeType->value,
'profit_sharing' => 'Y',
]; ];
if ($tradeType === WxpayTradeType::JSAPI) { if ($tradeType === WxpayTradeType::JSAPI) {
@ -1361,7 +1362,7 @@ class OrderService
/** /**
* 打印订单小票 * 打印订单小票
* *
* @param Order $order 订单 * @param Order $order 订单
* @return array 打印结果 [{code: 0(成功), msg: ''}, ...] * @return array 打印结果 [{code: 0(成功), msg: ''}, ...]
* @throws BizException * @throws BizException

View File

@ -25,9 +25,7 @@ class WxpayService
public function pay(array $params, ?string $payment = null): array public function pay(array $params, ?string $payment = null): array
{ {
if (! isset($params['notify_url'])) { if (! isset($params['notify_url'])) {
$path = route('wxpay.paid_notify', ['payment' => $payment ?: 'default'], false); $params['notify_url'] = route('wxpay.paid_notify', ['payment' => $payment ?: 'default']);
$params['notify_url'] = url($path, [], true);
} }
if (! isset($params['trade_type'])) { if (! isset($params['trade_type'])) {
@ -101,6 +99,50 @@ class WxpayService
return $result; 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);
}
/** /**
* 根据商户订单号退款 * 根据商户订单号退款
* *

View File

@ -2,8 +2,10 @@
namespace Tests\Feature; namespace Tests\Feature;
use App\Services\DistributeService;
use Illuminate\Support\Facades\DB;
use Tests\TestCase; use Tests\TestCase;
use App\Services\PrintService; use App\Models\Order;
class ExampleTest extends TestCase class ExampleTest extends TestCase
{ {
@ -14,17 +16,17 @@ class ExampleTest extends TestCase
*/ */
public function test_example() public function test_example()
{ {
dd(PrintService::make()->template('00596456352258754', 'a4fcc59f40fd438d9afdd4fc2e9b99fc', [ // $order = Order::where('sn', '20230813185220618108')->first();
'name' => '乡村基', // try {
'sn' => '20230223133856127032', // DB::beginTransaction();
'time' => '2023-02-23 13:38:56', // (new DistributeService())->wechatShare($order);
'desk' => '10号桌', // $order->update(['profit_paid' => now()]);
'products' => [ // DB::commit();
['name' => '香草拿铁(大杯)', 'price' => '32.00', 'amount' => '1', 'money' => '32.00'], // } catch (\Exception $e) {
['name' => '西瓜汁(大杯)', 'price' => '18.00', 'amount' => '1', 'money' => '18.00'], // DB::rollBack();
], // report($e);
'total' => '50.00', // }
'remarks' => '打包' dump(route('wxpay.paid_notify', ['payment' => 'default']));
])); $this->assertTrue(true);
} }
} }