支付宝记账本
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

147 lines
3.9 KiB

<?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]);
}
}