redirect -> callback -> credit flow is testable end-to-end * without any external credentials. Swap the PaymentGateway binding in * AppServiceProvider to replace it with a real driver. */ class FakePaymentGateway implements PaymentGateway { public function initiate(WalletDeposit $deposit): string { $deposit->update(['reference_id' => (string) Str::uuid()]); return route('api.wallet.deposits.callback', [ 'deposit' => $deposit->id, 'reference_id' => $deposit->reference_id, 'status' => 'success', ]); } public function verify(WalletDeposit $deposit, array $callbackPayload): bool { return $deposit->reference_id !== null && ($callbackPayload['reference_id'] ?? null) === $deposit->reference_id && ($callbackPayload['status'] ?? null) === 'success'; } }