Repository navigation
v0.6.0
What's new
-
X402\Facilitator\DispatchingFacilitator— wraps anyFacilitatorClientand surfaces aPaymentOutcometo a singleonOutcomeclosure on every non-trivial outcome (VerifyRejected,VerifyError,SettleSucceeded,SettleFailed,SettleError):use X402\Facilitator\DispatchingFacilitator; use X402\Facilitator\PaymentOutcome; use X402\Facilitator\PaymentOutcomeKind; $facilitator = new DispatchingFacilitator( inner: CoinbaseFacilitator::default($psr18Client, $psr17), onOutcome: function (PaymentOutcome $outcome, array $context) use ($events): void { match ($outcome->kind) { PaymentOutcomeKind::SettleSucceeded => $events->dispatch(new PaymentSettled(...)), default => $events->dispatch(new PaymentRejected(...)), }; }, captureContext: fn (): array => ['user_id' => currentUser()?->id, 'ip' => clientIp()], resourceFormatter: fn (string $url): string => $registry->formatResource($url), );
Three optional ctor closures:
onOutcome(the listener),captureContext(no-arg, returns adopter-supplied context — request user id, IP, trace id — once per outcome),resourceFormatter(mapschallenge->resource ?? ''to the canonical resource string surfaced onPaymentOutcome::$resource).Listener / context-capture / formatter exceptions on
*-errorpaths are silently swallowed so the original facilitator throwable always propagates to the caller. Hook bugs on the slow path can't mask a transport / network failure that operations need to triage. -
X402\Facilitator\PaymentOutcome— snapshot DTO surfaced to theonOutcomeclosure. Carrieskind,signature,challenge,resource,reason,verify,settle,exception. Per-kind population documented on the class — adopters branch on$outcome->kindand consume the relevant result field. -
X402\Facilitator\PaymentOutcomeKind— string-backed enum (verify-rejected/verify-error/settle-succeeded/settle-failed/settle-error). ConstantsREASON_PREFIX_VERIFY_ERROR/REASON_PREFIX_SETTLE_ERRORfor the prefixed reason format. New cases may be added in any minor version (e.g. async-settlement support down the road), so adopters writingmatch ($outcome->kind) { ... }SHOULD include adefaultarm. -
X402\PaymentHistory\PaymentRowBuilder::fromOutcome()— static helper that turns aPaymentOutcomeinto a flat array row matching the laravel-x402x402_paymentsmigration shape:use X402\PaymentHistory\PaymentRowBuilder; $row = PaymentRowBuilder::fromOutcome($outcome, $context); // ['status' => 'settled', 'resource' => '...', 'payer' => '0x...', 'amount' => '10000', ...] Payment::query()->updateOrCreate(['transaction' => $row['transaction']], $row);
Constants:
STATUS_SETTLED,STATUS_REJECTED,DEFAULT_REASON_MAX_LENGTH = 255. Reason truncation defaults to 255 chars (matches the migration column width) — without it, a long*-errorreason exceeds the column and the audit-row write fails after the payment path already failed once. PassreplayKey: $extractedfrom the matchedReplayKeyExtractorfor scheme-aware nonce / payer extraction; falls back toPaymentSignature::authorization()for the EIP-3009 path.
Full Changelog: 0.5.1...0.6.0