Create a SetupIntent server-side via POST /v1/setup_intents with payment_method_types=['us_bank_account'], customer ID, and usage='off_session' to indicate the PaymentMethod will be used when the customer is not present
Include mandate_data.customer_acceptance with type, online acceptance details (IP address, user agent), and accepted_at timestamp to record mandate consent
Collect and verify the bank account through either Financial Connections (instant) or microdeposit verification; confirm the SetupIntent once verification is complete
On setup_intent.succeeded webhook receipt, store the resulting PaymentMethod ID for future use against that Customer
For off-session charges, create a PaymentIntent with the stored PaymentMethod ID, customer ID, and off_session=true; Stripe uses the previously collected mandate
Include a statement_descriptor_suffix on future PaymentIntents so customers can identify the charge on their bank statement
Known gotchas
The mandate collected via the SetupIntent must be explicitly shown to and accepted by the customer; Stripe does not display mandate text in the direct API flow — you are responsible for rendering it
usage='off_session' must be set at SetupIntent creation time; it affects how Stripe handles authentication and mandate requirements for future charges
If the bank account is not verified before SetupIntent confirmation (e.g., microdeposit not yet completed), the SetupIntent stays in 'requires_action' until the customer verifies
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp