diff --git a/app/Admin/Actions/Show/DealerWalletPay.php b/app/Admin/Actions/Show/DealerWalletPay.php
index 32b4f7b6..8ef3873d 100644
--- a/app/Admin/Actions/Show/DealerWalletPay.php
+++ b/app/Admin/Actions/Show/DealerWalletPay.php
@@ -18,7 +18,7 @@ class DealerWalletPay extends AbstractTool
*
* @var string
*/
- protected $style = 'btn-danger';
+ protected $style = 'btn-danger mr-1';
public function render()
{
@@ -27,6 +27,6 @@ class DealerWalletPay extends AbstractTool
->lg()
->title($this->title)
->body($form)
- ->button("style}\">{$this->title} ");
+ ->button("style}\">{$this->title}");
}
}
diff --git a/app/Admin/Actions/Show/DealerWalletRefuse.php b/app/Admin/Actions/Show/DealerWalletRefuse.php
index 134c99c2..e3a7b6f7 100644
--- a/app/Admin/Actions/Show/DealerWalletRefuse.php
+++ b/app/Admin/Actions/Show/DealerWalletRefuse.php
@@ -18,7 +18,7 @@ class DealerWalletRefuse extends AbstractTool
*
* @var string
*/
- protected $style = 'btn-warning';
+ protected $style = 'btn-warning mr-1';
public function render()
{
@@ -27,6 +27,6 @@ class DealerWalletRefuse extends AbstractTool
->lg()
->title($this->title)
->body($form)
- ->button("style}\">{$this->title} ");
+ ->button("style}\">{$this->title}");
}
}
diff --git a/app/Admin/Controllers/DealerWalletToBankLogController.php b/app/Admin/Controllers/DealerWalletToBankLogController.php
index 1a145466..9be4f41f 100644
--- a/app/Admin/Controllers/DealerWalletToBankLogController.php
+++ b/app/Admin/Controllers/DealerWalletToBankLogController.php
@@ -84,7 +84,7 @@ class DealerWalletToBankLogController extends AdminController
$show->field('rate')->append('%');
$show->field('service_amount')->prepend('¥');
$show->field('account_amount')->prepend('¥');
- $show->field('status')->as(function ($v) {
+ $show->field('status')->unescape()->as(function ($v) {
$text = $this->status->text();
$background = $this->status->color();
@@ -92,6 +92,9 @@ class DealerWalletToBankLogController extends AdminController
});
$show->field('pay_image')->image();
$show->field('remarks');
+ if ($show->model()->isFailed()) {
+ $show->field('failed_reason');
+ }
$show->divider('收款信息-银行');
$show->field('bank_user_name', '银行-收款人')->as(function () {
$payInfo = $this->getPayInfo();
@@ -141,7 +144,8 @@ class DealerWalletToBankLogController extends AdminController
->tools(function (Show\Tools $tools) use ($show) {
$tools->disableEdit();
$tools->disableDelete();
- if ($show->model()->isPending() && Admin::user()->can('dcat.admin.dealer_wallet_to_bank_logs.verify')) {
+
+ if (in_array($show->model()->status, [DealerWalletToBankLogStatus::Pending, DealerWalletToBankLogStatus::Failed]) && Admin::user()->can('dcat.admin.dealer_wallet_to_bank_logs.verify')) {
$tools->append(new DealerWalletRefuse());
$tools->append(new DealerWalletPay());
}
diff --git a/app/Admin/Forms/DealerWalletPay.php b/app/Admin/Forms/DealerWalletPay.php
index e3f96381..2cb69eb5 100644
--- a/app/Admin/Forms/DealerWalletPay.php
+++ b/app/Admin/Forms/DealerWalletPay.php
@@ -2,7 +2,9 @@
namespace App\Admin\Forms;
+use App\Enums\DealerWalletToBankLogPayWay;
use App\Enums\DealerWalletToBankLogStatus;
+use App\Exceptions\BizException;
use App\Models\DealerWalletToBankLog;
use Carbon\Carbon;
use Dcat\Admin\Contracts\LazyRenderable;
@@ -38,12 +40,25 @@ class DealerWalletPay extends Form implements LazyRenderable
try {
DB::beginTransaction();
- $log = DealerWalletToBankLog::findOrFail($id);
- $log->update([
- 'pay_info' => $log->getPayInfo(),
- 'pay_image' => $input['pay_image'] ?? null,
- 'status' => DealerWalletToBankLogStatus::Success,
- ]);
+
+ $log = DealerWalletToBankLog::lockForUpdate()->findOrFail($id);
+
+ if (! in_array($log->status, [DealerWalletToBankLogStatus::Pending, DealerWalletToBankLogStatus::Failed])) {
+ throw new BizException('提现记录状态异常');
+ }
+
+ $log->pay_info = $log->user->dealer->pay_info;
+ $log->pay_image = $input['pay_image'] ?? null;
+ $log->pay_way = $input['pay_way'];
+ if ($log->pay_way == DealerWalletToBankLogPayWay::Offline) {
+ $log->pay_at = now();
+ $log->status = DealerWalletToBankLogStatus::Success;
+ } else {
+ $log->pay_sn = serial_number();
+ $log->status = DealerWalletToBankLogStatus::Passed;
+ }
+ $log->save();
+
DB::commit();
} catch (Throwable $th) {
DB::rollBack();
@@ -61,6 +76,10 @@ class DealerWalletPay extends Form implements LazyRenderable
*/
public function form()
{
+ $this->hidden('pay_way')->value(DealerWalletToBankLogPayWay::Offline->value);
+ // $this->select('pay_way')
+ // ->options(DealerWalletToBankLogPayWay::texts())
+ // ->required();
$this->image('pay_image')
->move('dealer-pay/'.Carbon::now()->toDateString())
->saveFullUrl()
diff --git a/app/Console/Commands/Dealer/WalletToBankCommand.php b/app/Console/Commands/Dealer/WalletToBankCommand.php
new file mode 100644
index 00000000..4feaeffb
--- /dev/null
+++ b/app/Console/Commands/Dealer/WalletToBankCommand.php
@@ -0,0 +1,92 @@
+chunkById(1, function ($logs) use ($yeePayService) {
+ foreach ($logs as $log) {
+ try {
+ $result = $yeePayService->request('accountpay.behalf.Pay', [
+ 'payerOutUserId' => '21102510220227100003' ?: config('services.yeepay.partner_id'),
+ 'merchOrderNo' => $log->pay_sn,
+ 'tradeName' => '批零提现',
+ 'payeeUserName' => data_get($log->pay_info, 'bank.user_name'),
+ 'bankCardNo' => data_get($log->pay_info, 'bank.bank_number'),
+ 'bankCode' => Bank::tryFromBankName(data_get($log->pay_info, 'bank.bank_name'))?->name,
+ 'bankCardType' => 'DEBIT_CARD',
+ 'amount' => $log->account_amount,
+ 'feeRole' => 'PAYER',
+ 'tradeMemo' => '批零提现',
+ 'context' => json_encode(['type' => 'dealer_wallet_to_bank']),
+ ]);
+
+ // 如果交易超时,重新发起支付
+ if ($result['resultCode'] === 'TIME_OUT') {
+ continue;
+ }
+
+ if ($result['orderStatus'] === 'SUCCESS') {
+ $log->update([
+ 'status' => DealerWalletToBankLogStatus::Success,
+ 'pay_at' => now(),
+ 'failed_reason' => null,
+ ]);
+ } elseif ($result['orderStatus'] === 'FAIL') {
+ $log->update([
+ 'status' => DealerWalletToBankLogStatus::Failed,
+ 'failed_reason' => '交易失败',
+ ]);
+ } else {
+ $log->update([
+ 'status' => DealerWalletToBankLogStatus::Paying,
+ 'failed_reason' => null,
+ ]);
+ }
+ } catch (YeePayException $e) {
+ $log->update([
+ 'status' => DealerWalletToBankLogStatus::Failed,
+ 'failed_reason' => $e->getMessage(),
+ ]);
+ } catch (Throwable $e) {
+ throw $e;
+ }
+ }
+ });
+
+ sleep(60);
+ }
+ }
+}
diff --git a/app/Endpoint/Callback/Http/Controllers/YeePayNotifyController.php b/app/Endpoint/Callback/Http/Controllers/YeePayNotifyController.php
index fedc181a..87739334 100644
--- a/app/Endpoint/Callback/Http/Controllers/YeePayNotifyController.php
+++ b/app/Endpoint/Callback/Http/Controllers/YeePayNotifyController.php
@@ -2,7 +2,9 @@
namespace App\Endpoint\Callback\Http\Controllers;
+use App\Enums\DealerWalletToBankLogStatus;
use App\Enums\WalletToBankLogStatus;
+use App\Models\DealerWalletToBankLog;
use App\Models\WalletToBankLog;
use App\Services\YeePayService;
use Exception;
@@ -45,9 +47,11 @@ class YeePayNotifyController extends Controller
$orderNo = $request->input('merchOrderNo');
$orderStatus = $request->input('orderStatus');
- $context = (array) json_decode($request->input('context'), true);
- if (Arr::get($context, 'type') === 'wallet_to_bank') {
+ $context = (array) json_decode($request->input('context'), true);
+ $contextType = Arr::get($context, 'type');
+
+ if ($contextType === 'wallet_to_bank') {
$log = WalletToBankLog::where('pay_sn', $orderNo)->first();
if ($log === null) {
@@ -70,6 +74,29 @@ class YeePayNotifyController extends Controller
'failed_reason' => $request->input('resultMessage').'#'.$resultCode,
]);
}
+ } elseif ($contextType === 'dealer_wallet_to_bank') {
+ $log = DealerWalletToBankLog::where('pay_sn', $orderNo)->first();
+
+ if ($log === null) {
+ return;
+ }
+
+ if ($log->status !== DealerWalletToBankLogStatus::Paying) {
+ return;
+ }
+
+ if ($orderStatus === 'SUCCESS') {
+ $log->update([
+ 'status' => DealerWalletToBankLogStatus::Success,
+ 'pay_at' => Carbon::parse($request->input('finishTime')),
+ 'failed_reason' => null,
+ ]);
+ } elseif ($orderStatus === 'FAIL') {
+ $log->update([
+ 'status' => DealerWalletToBankLogStatus::Failed,
+ 'failed_reason' => $request->input('resultMessage').'#'.$resultCode,
+ ]);
+ }
}
}
diff --git a/app/Enums/DealerWalletToBankLogPayWay.php b/app/Enums/DealerWalletToBankLogPayWay.php
new file mode 100644
index 00000000..4dc66ea3
--- /dev/null
+++ b/app/Enums/DealerWalletToBankLogPayWay.php
@@ -0,0 +1,38 @@
+ '#5b69bc',
+ static::Behalf => '#21b978',
+ };
+ }
+
+ /**
+ * @return string
+ */
+ public function text(): string
+ {
+ return static::texts()[$this->value];
+ }
+
+ /**
+ * @return array
+ */
+ public static function texts(): array
+ {
+ return [
+ static::Offline->value => '线下',
+ static::Behalf->value => '代付',
+ ];
+ }
+}
diff --git a/app/Models/DealerWalletToBankLog.php b/app/Models/DealerWalletToBankLog.php
index 90d3eed6..52132eed 100644
--- a/app/Models/DealerWalletToBankLog.php
+++ b/app/Models/DealerWalletToBankLog.php
@@ -2,6 +2,8 @@
namespace App\Models;
+use App\Casts\JsonArray;
+use App\Enums\DealerWalletToBankLogPayWay;
use App\Enums\DealerWalletToBankLogStatus;
use Dcat\Admin\Traits\HasDateTimeFormatter;
use Illuminate\Database\Eloquent\Factories\HasFactory;
@@ -12,7 +14,15 @@ class DealerWalletToBankLog extends Model
use HasFactory;
use HasDateTimeFormatter;
+ protected $attributes = [
+ 'pay_way' => DealerWalletToBankLogPayWay::Offline,
+ 'status' => DealerWalletToBankLogStatus::Pending,
+ ];
+
protected $casts = [
+ 'pay_info' => JsonArray::class,
+ 'pay_at' => 'datetime',
+ 'pay_way' => DealerWalletToBankLogPayWay::class,
'status' => DealerWalletToBankLogStatus::class,
];
@@ -27,6 +37,12 @@ class DealerWalletToBankLog extends Model
'rate',
'service_amount',
'account_amount',
+ 'pay_info',
+ 'pay_image',
+ 'pay_sn',
+ 'pay_way',
+ 'pay_at',
+ 'failed_reason',
];
/**
@@ -53,6 +69,11 @@ class DealerWalletToBankLog extends Model
return $this->status === DealerWalletToBankLogStatus::Pending;
}
+ public function isFailed()
+ {
+ return $this->status === DealerWalletToBankLogStatus::Failed;
+ }
+
/**
* 获取用户的打款信息
*
@@ -60,7 +81,7 @@ class DealerWalletToBankLog extends Model
*/
public function getPayInfo()
{
- if ($this->isPending()) {//待打款订单显示发货人收款信息
+ if ($this->isPending() || $this->isFailed()) {//待打款订单显示发货人收款信息
$payInfo = $this->user->dealer->pay_info;
} else {
$payInfo = $this->pay_info;
diff --git a/database/migrations/2022_04_13_104039_add_pay_columns_to_dealer_wallet_to_bank_logs_table.php b/database/migrations/2022_04_13_104039_add_pay_columns_to_dealer_wallet_to_bank_logs_table.php
new file mode 100644
index 00000000..8bc680ae
--- /dev/null
+++ b/database/migrations/2022_04_13_104039_add_pay_columns_to_dealer_wallet_to_bank_logs_table.php
@@ -0,0 +1,37 @@
+string('pay_sn')->nullable()->comment('支付单号');
+ $table->tinyInteger('pay_way')->default(1)->comment('支付方式: 1 线下, 2 代付');
+ $table->timestamp('pay_at')->nullable()->comment('支付时间');
+ $table->text('failed_reason')->nullable()->comment('失败原因');
+
+ $table->unique('pay_sn');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('dealer_wallet_to_bank_logs', function (Blueprint $table) {
+ $table->dropColumn(['pay_sn', 'pay_way', 'failed_reason', 'pay_at']);
+ });
+ }
+}
diff --git a/resources/lang/zh_CN/dealer-wallet-to-bank-log.php b/resources/lang/zh_CN/dealer-wallet-to-bank-log.php
index 22108113..2b959ddc 100644
--- a/resources/lang/zh_CN/dealer-wallet-to-bank-log.php
+++ b/resources/lang/zh_CN/dealer-wallet-to-bank-log.php
@@ -17,6 +17,8 @@ return [
'account_amount' => '到账金额',
'status' => '状态',
'remarks' => '备注',
+ 'failed_reason' => '失败原因',
+ 'pay_way' => '支付方式',
],
'options' => [
],