6
0
Fork 0

wx_share finish

base
panliang 2023-10-23 13:34:30 +08:00
parent 6e9d4633a8
commit f2bb712dd5
11 changed files with 146 additions and 22 deletions

View File

@ -0,0 +1,34 @@
<?php
namespace App\Admin\Actions\Order;
use App\Models\Order;
use App\Services\Payment\WxpayService;
use Dcat\Admin\Grid\RowAction;
class RowWxShareFinish extends RowAction
{
protected $title = '解冻资金';
public function handle()
{
$order = Order::findOrFail($this->primaryKey);
$service = new WxpayService();
$sn = serial_number();
$result = $service->finishShare($order->out_trade_no, $sn);
if (data_get($result, 'return_code') != 'SUCCESS') {
return $this->response()->error(data_get($result, 'return_msg'));
}
if (data_get($result, 'result_code') != 'SUCCESS') {
return $this->response()->error(data_get($result, 'err_code') . ':' . data_get($result, 'err_code_des'));
}
$attributes = ['finish_sn' => $sn, 'status' => 'Y'];
$order->update($order->wx_share ? array_merge($order->wx_share, $attributes) : $attributes);
return $this->response()->success('成功!');
}
public function confirm()
{
return ['确定要解冻资金?', '解冻资金后将无法进行分账'];
}
}

View File

@ -5,6 +5,7 @@ namespace App\Admin\Controllers;
use App\Admin\Actions\Grid\Exports\ShippingOrder as ExportShippingOrder;
use App\Admin\Actions\Grid\KuaidiInfo;
use App\Admin\Actions\Grid\OrderSetTag;
use App\Admin\Actions\Order\RowWxShareFinish;
use App\Admin\Actions\Show\OrderConsigneeInfo;
use App\Admin\Actions\Show\OrderCreatePackage;
use App\Admin\Actions\Show\OrderPay;
@ -253,24 +254,30 @@ class OrderController extends AdminController
$filter->like('pay_sn')->width(3);
});
$grid->tools(function (Grid\Tools $tools) {
if (Admin::user()->can('dcat.admin.orders.export_shipping_orders')) {
$user = Admin::user();
$grid->tools(function (Grid\Tools $tools) use ($user) {
if ($user->can('dcat.admin.orders.export_shipping_orders')) {
$tools->append(new ExportShippingOrder());
}
if (Admin::user()->can('dcat.admin.orders.export_order_products')) {
if ($user->can('dcat.admin.orders.export_order_products')) {
$tools->append(new ExportProduct());
}
});
$grid->actions(function (Grid\Displayers\Actions $actions) {
if (Admin::user()->can('dcat.admin.orders.show')) {
$grid->actions(function (Grid\Displayers\Actions $actions) use ($user) {
$row = $actions->row;
if ($user->can('dcat.admin.orders.show')) {
$actions->disableView(false);
}
if (Admin::user()->can('dcat.admin.orders.tags')) {
if ($user->can('dcat.admin.orders.tags')) {
$actions->append(new OrderSetTag());
}
if (data_get($row->wx_share, 'status') != 'Y') {
$actions->append(new RowWxShareFinish());
}
});
$grid->footer(function ($collection) use ($grid) {

View File

@ -189,7 +189,7 @@ class OrderController extends AdminController
$show->field('cost_price')->as(fn ($value) => bcdiv($value, 100, 2));
$show->field('profit_price')->as(fn () => round(($this->total_amount - $this->cost_price) / 100, 2, PHP_ROUND_HALF_DOWN));
$show->field('vip_discount_amount')->as(fn ($v) => bcdiv($v, 100, 2))->prepend('- ¥');
// 优惠券
$show->field('user_coupon_id')->as(fn() => data_get($this->userCoupon, 'coupon_name'));
$show->field('coupon_discount_amount')->as(fn($value) => bcdiv($value, 100, 2))->prepend('- ¥');
@ -199,11 +199,11 @@ class OrderController extends AdminController
$show->field('total_amount')->as(fn($value) => bcdiv($value, 100, 2))->prepend('¥');
$show->field('sales_value');
$show->field('order_status')->as(fn() => $this->order_status)->using($this->statusMap)->dot($this->statusColor);
$show->field('pay_way')->as(fn() => $this->pay_way?->mallText())->circleDot(PayWay::colors());
$show->field('pay_way')->as(fn() => $this->pay_way?->text())->circleDot(PayWay::colors());
$show->field('created_at');
$show->field('pay_at');
$show->field('completed_at');
if ($model->source_type == Desk::class) {
$show->field('desk_id')->as(fn() => data_get($model->source, 'name'));
}

View File

@ -76,6 +76,7 @@ enum PayWay: string {
static::WxpayH5->value => '#21b978',
static::WxpayJsApi->value => '#21b978',
static::WxpayMiniProgram->value => '#21b978',
static::WxPayShare->value => '#21b978',
// 支付宝
static::AlipayApp->value => '#3085d6',
];

View File

@ -2,8 +2,10 @@
namespace App\Listeners;
use App\Enums\PayWay;
use App\Models\Order;
use App\Services\DistributeService;
use App\Services\Payment\WxpayService;
use Exception;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
@ -33,9 +35,27 @@ class OrderDistribute
try {
DB::beginTransaction();
$service = new DistributeService();
$service->storeByOrder($order);
$profits = $service->storeByOrder($order);
DB::commit();
// 如果没有提成记录
if ($profits->count() <= 0 && in_array($order->pay_way, [PayWay::WxpayApp, PayWay::WxpayH5, PayWay::WxpayJsApi, PayWay::WxpayMiniProgram])) {
// 解冻资金
$sn = serial_number();
$result = (new WxpayService())->finishShare($order->out_trade_no, $sn);
if (data_get($result, 'return_code') != 'SUCCESS') {
logger()->error('微信分账-解冻资金失败', $result);
}
else if (data_get($result, 'result_code') != 'SUCCESS') {
logger()->error('微信分账-解冻资金失败', $result);
} else {
$attributes = ['finish_sn' => $sn, 'status' => 'Y'];
$order->update($order->wx_share ? array_merge($order->wx_share, $attributes) : $attributes);
}
}
} catch (Exception $e) {
logger('添加提成记录失败');
logger()->error($e);
DB::rollBack();
}
}

View File

@ -59,6 +59,7 @@ class Order extends Model
'profit_paid' => 'datetime',
'status' => 'int',
'is_change' => 'bool',
'wx_share' => 'json',
];
/**
@ -100,6 +101,7 @@ class Order extends Model
'cost_price',
'profit_paid',
'point_discount_amount',
'wx_share',
];
/**

View File

@ -241,6 +241,9 @@ class DistributeService
$result = (new WxpayService())->share($order->out_trade_no, $sn, $receivers);
$attributes = ['share_sn' => $sn, 'status' => 'N'];
$order->update($order->wx_share ? array_merge($order->wx_share, $attributes) : $attributes);
$status = data_get($result, 'status');
if ($status == 'FINISHED') {
$this->success($list, $result);

View File

@ -1267,6 +1267,9 @@ class OrderService
PayWay::WxpayMiniProgram => 'mini_program',
default => 'default',
});
// 更新订单冻结状态
$order->update(['wx_share' => $order->wx_share ? array_merge($order->wx_share, ['status' => 'Y']) : ['status' => 'Y']]);
} elseif ($payLog->isAlipay()) {
$params = [
'subject' => app_settings('app.app_name').'-商城订单',

View File

@ -5,7 +5,10 @@ namespace App\Services\Payment;
use App\Enums\WxpayTradeType;
use App\Exceptions\WeChatPayException;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use EasyWeChat\Payment\Application;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Arr;
class WxpayService
@ -154,6 +157,31 @@ class WxpayService
return $app->profit_sharing->query($transaction_id, $share_sn);
}
/**
* 微信支付-完结分账, 解冻订单剩余资金
*
* @param string $transaction_id 微信支付流水号
* @param string $out_trade_sn 分账订单号, 自动生成
* @return mixed
*/
public function finishShare(string $transaction_id, string $out_trade_sn)
{
$app = $this->payment();
// 服务商模式 (子商户)
$appId = config('wechat.payment.sub.app_id');
$mchId = config('wechat.payment.sub.mch_id');
if ($appId && $mchId) {
$app->setSubMerchant($mchId, $appId);
}
return $app->profit_sharing->markOrderAsFinished([
'transaction_id' => $transaction_id,
'out_order_no' => $out_trade_sn,
'description' => '订单分账完结, 解冻资金'
]);
}
/**
* 根据商户订单号退款
*

View File

@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddWxShareToOrders extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
// status: Y/N, 分账状态, Y: 开始分账, N: 已经完结(解冻资金)
// share_sn: 20230xxxxx, 分账订单号
// finish_sn: 20230xxxxx, 完结分账订单号
$table->json('wx_share')->nullable()->comment('微信分账信息');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn(['wx_share']);
});
}
}

View File

@ -2,6 +2,7 @@
namespace Tests\Feature;
use App\Enums\PayWay;
use App\Services\DistributeService;
use App\Services\Payment\WxpayService;
use Illuminate\Support\Facades\DB;
@ -17,18 +18,8 @@ class ExampleTest extends TestCase
*/
public function test_example()
{
// $order = Order::findOrFail(3146);
// try {
// DB::beginTransaction();
// (new DistributeService())->wechatShare($order);
// $order->update(['profit_paid' => now()]);
// DB::commit();
// } catch (\Exception $e) {
// DB::rollBack();
// report($e);
// }
$result = (new WxpayService())->queryShare('4200002029202310133548206841', '20231013084421898946');
dump($result);
$result = ['status' => 'N', 'sn' => '21322132'];
dump($result ? array_merge($result, ['status' => 'Y']) : ['status' => 'Y']);
$this->assertTrue(true);
}
}