<?php
namespace App\Jobs;
use App\Application\Services\Payouts\{PayoutSettlementService,PayoutStateMachine};use App\Domain\Blockchain\Contracts\BlockchainGateway;use App\Models\Payout;use Illuminate\Bus\Queueable;use Illuminate\Contracts\Queue\ShouldQueue;use Illuminate\Foundation\Bus\Dispatchable;use Illuminate\Queue\InteractsWithQueue;use Illuminate\Queue\SerializesModels;use Illuminate\Support\Facades\Cache;use Throwable;
final class SyncPayoutJob implements ShouldQueue {use Dispatchable,InteractsWithQueue,Queueable,SerializesModels;public int $tries=6;public function __construct(public int $payoutId){$this->onQueue('payouts');}public function backoff():array{return [10,30,90,300,900,1800];}public function handle(BlockchainGateway $gateway,PayoutSettlementService $settle):void{$lock=Cache::lock("payout-sync:{$this->payoutId}",120);if(!$lock->get())return;try{$p=Payout::findOrFail($this->payoutId);if($p->status!=='confirming'||!$p->provider_transfer_id)return;$t=$gateway->getTransfer($p->provider_transfer_id);$p->update(['tx_hash'=>$t->txHash?:$p->tx_hash]);if(in_array($t->status,['completed','confirmed','finished'],true)){$settle->complete($p);return;}if(in_array($t->status,['failed','rejected','cancelled'],true))throw new \DomainException("Provider transfer ended as {$t->status}.");$this->release($this->backoff()[min($this->attempts()-1,count($this->backoff())-1)]);}catch(\DomainException $e){$p->update(['status'=>'manual_review','failure_reason'=>$e->getMessage()]);}finally{$lock->release();}}}
