Accept a one-shot payment
The full happy-path for charging a customer once.
You want to charge a customer one time for one thing. Here's the entire flow, with both server and client code.
Server: create the session
metadata is round-tripped to your webhooks unchanged. Use it to correlate Strimz sessions back to your own resources.
Client: redirect to checkout
That's the entire client side. The customer lands on
strimz.finance/pay/<sessionId>, picks a wallet (Reown handles the
picker for every major one), and signs two typed-data messages: the token authorization and the Strimz PayIntent.
The signature is an EIP-3009 ReceiveWithAuthorization. Strimz's
relayer turns it into the on-chain payWithAuthorization call, pays
the gas itself, and settles the transfer. The customer never sees a
second prompt or pays gas. The fee split (platform fee to
FeeCollector, net to your payout) lands atomically in the same
transaction.
The full security model lives on the meta-tx flow page: what the customer signs, why the relayer cannot move funds on its own, how the signature expires.
Webhook: react when it confirms
Don't trust the redirect to successUrl for state changes. Anyone can navigate to that URL. The webhook is the source of truth.
Edge cases to know about
- Session expiry: 24 hours by default. If the customer doesn't pay in time, the session goes to
cancelledand you'll receivepayment.failed. Create a new session. - Customer changes their mind mid-checkout: they hit the back button, you see no webhook. Don't fulfill until you receive
payment.completed. The session sits inpendinguntil expiry. - Customer pays the same session twice: impossible. Each session is one on-chain
pay()call and the contract enforces therefis single-use. - Network reorg: the indexer waits 5 confirmations before flipping
confirmed. You won't get a flapping "confirmed to pending to confirmed" sequence.
What just happened on-chain
The customer's wallet signed an EIP-3009 authorisation. Strimz's
relayer wrapped it into a StrimzPayments.payWithAuthorization call
and broadcast the transaction. Arc settled it in under a second.
Your payoutAddress received amount - feeAmount USDC immediately.
The indexer picked up the PaymentExecuted event, matched its
ref to your PaymentSession.id, inserted a
Transaction(kind=one_shot, status=confirmed), and fired
payment.completed. End to end (the click to your webhook handler)
takes about 20 seconds.
