11 changed files with 190 additions and 25 deletions
-
6app/Admin/Controllers/OrderController.php
-
38app/Admin/Controllers/OrderNotifyController.php
-
147app/Jobs/OrderChangedNotify.php
-
4app/Models/Order.php
-
5app/Models/OrderNotify.php
-
2app/Services/OutService.php
-
1composer.json
-
2database/migrations/2025_08_27_163509_create_orders_table.php
-
2database/migrations/2025_08_27_170155_create_order_notifies_table.php
-
2lang/zh_CN/order-notify.php
-
2lang/zh_CN/order.php
@ -0,0 +1,147 @@ |
|||
<?php |
|||
|
|||
namespace App\Jobs; |
|||
|
|||
use App\Models\MchApp; |
|||
use App\Models\Order; |
|||
use App\Models\OrderNotify; |
|||
use App\Services\OutService; |
|||
use Illuminate\Contracts\Queue\ShouldQueue; |
|||
use Illuminate\Foundation\Queue\Queueable; |
|||
use Illuminate\Support\Facades\Http; |
|||
use Illuminate\Support\Str; |
|||
use Throwable; |
|||
|
|||
class OrderChangedNotify implements ShouldQueue |
|||
{ |
|||
use Queueable; |
|||
|
|||
/** |
|||
* 可以尝试任务的次数 |
|||
* @var int |
|||
*/ |
|||
public int $tries = 8; |
|||
|
|||
/** |
|||
* 订单ID |
|||
* @var int |
|||
*/ |
|||
private int $orderId; |
|||
|
|||
/** |
|||
* 推送状态 |
|||
* @var int |
|||
*/ |
|||
private int $state; |
|||
|
|||
/** |
|||
* Create a new job instance. |
|||
*/ |
|||
public function __construct(int $orderId, int $state) |
|||
{ |
|||
$this->orderId = $orderId; |
|||
$this->state = $state; |
|||
} |
|||
|
|||
/** |
|||
* Execute the job. |
|||
*/ |
|||
public function handle(OutService $outService): void |
|||
{ |
|||
$order = Order::find($this->orderId); |
|||
|
|||
if (!$order) { |
|||
return; |
|||
} |
|||
|
|||
if (!$order->notify_url) { |
|||
return; |
|||
} |
|||
|
|||
$mchApp = MchApp::query() |
|||
->where('mch_no', $order->mch_no) |
|||
->where('app_id', $order->app_id) |
|||
->first(); |
|||
|
|||
if (!$mchApp) { |
|||
return; |
|||
} |
|||
|
|||
$params = [ |
|||
'mchNo' => $order->mch_no, |
|||
'appId' => $order->app_id, |
|||
'mchOrderNo' => $order->mch_order_no, |
|||
'transferId' => $order->transfer_id, |
|||
'amount' => (string) $order->amount, |
|||
'currency' => $order->currency, |
|||
'ifCode' => $order->if_code, |
|||
'entryType' => $order->entry_type, |
|||
'state' => (string) $this->state, |
|||
'accountNo' => $order->account_no, |
|||
'accountName' => $order->account_name, |
|||
'bankName' => $order->bank_name, |
|||
'transferDesc' => $order->transfer_desc, |
|||
'channelOrderNo' => $order->channel_order_no, |
|||
'errCode' => $order->errCode, |
|||
'errMsg' => $order->errMsg, |
|||
'extraParam' => $order->ext_param, |
|||
'createdAt' => $order->created_at->format('Uv'), |
|||
]; |
|||
|
|||
if ($this->state == 2) { |
|||
$params['success_time'] = $order->success_time->format('Uv'); |
|||
} |
|||
|
|||
$params['sign'] = $outService->makeSign($params, $mchApp->secret_key); |
|||
|
|||
$notify = new OrderNotify(); |
|||
$notify->order_id = $this->orderId; |
|||
$notify->state = $this->state; |
|||
$notify->push_time = now(); |
|||
$notify->push_body = http_build_query($params); |
|||
$notify->save(); |
|||
|
|||
try { |
|||
$options = [ |
|||
'allow_redirects' => false, |
|||
'timeout' => 10, |
|||
]; |
|||
|
|||
$response = Http::withOptions($options) |
|||
->withBody($notify->push_body, 'application/x-www-form-urlencoded') |
|||
->post($order->notify_url); |
|||
|
|||
$notify->response_code = $response->status(); |
|||
$notify->response_body = Str::limit($response->body(), 2000); |
|||
} catch (Throwable) { |
|||
$notify->response_code = 0; |
|||
$notify->response_body = ''; |
|||
} |
|||
|
|||
$notify->response_time = now(); |
|||
$notify->push_duration = round($notify->push_time->diffInSeconds($notify->response_time) * 1000); |
|||
$notify->save(); |
|||
|
|||
if ($notify->response_body !== 'success') { |
|||
$this->customRelease(); |
|||
} |
|||
} |
|||
|
|||
private function customRelease(): void |
|||
{ |
|||
// 下一次尝试的时间间隔
|
|||
$delayList = [ |
|||
1 => 60 * 2, |
|||
2 => 60 * 10, |
|||
3 => 60 * 10, |
|||
4 => 3600, |
|||
5 => 3600 * 2, |
|||
6 => 3600 * 6, |
|||
7 => 3600 * 15, |
|||
]; |
|||
|
|||
$currentAttempt = $this->attempts(); |
|||
|
|||
$this->release($delayList[$currentAttempt]); |
|||
} |
|||
} |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue