Create a funding session
Returns an Apple Pay / Google Pay payment link for the amount you specify. Show it in your UI; when the user completes the payment the funds land in their wallet. The link is single-use and expires after 30 minutes. Requires a phone verification fresh within 60 days — see POST /api/v2/wallet/phone/start.
How it works
Ask for a funding session for an amount; we return acheckout_url. There are two kinds, picked with link_type:
hosted(default): an Agentcard-hosted payment page. Render it anywhere — an “Add funds” button, a QR code, a chat message — and the user opens it and pays with Apple Pay, Google Pay, or card. Safe to relay: the underlying payment order is created only when the user opens the page. Creating a hosted session is free; an unopened link costs nothing.embedded: an in-app payment link, minted immediately. Loadcheckout_urlin aWKWebView(iOS) or Android WebView and the user pays without leaving your app.
GET /api/v2/wallet/fund/{session_id} to know when — that endpoint is the source of truth for money; treat any client-side signal as advisory.
Requirements
- The user must be identity-verified. Funding reuses the user’s completed identity verification — there is no separate verification step inside checkout. If the user isn’t verified, create-session returns
422 kyc_required; run identity verification first, then retry. Other verification-related 422s:funding_profile_required— a one-time funding profile is missing (collect it, then retry).kyc_transfer_required— the user’s existing verification needs a one-time carry-over before funding (a single extra step, no re-verification).unsupported— the user’s verification can’t be used for funding (for example, a non-US user).
- Amount bounds come from the API. If the amount is out of range you get
422 amount_out_of_rangewithmin_amount_centsandmax_amount_centsin the response — read those rather than hardcoding limits. - Link lifetime.
hostedandembeddedlinks both stay openable for the session’s 30-minute window.
Embedded: in-app checkout
Create the session withlink_type: "embedded", hand checkout_url to your app, and load it in a WebView:
- Apple Pay renders inside a
WKWebViewon iOS 16+ (Apple Pay on the Web is supported inWKWebView, but not inSFSafariViewController— use aWKWebView). On older iOS the user pays with Google Pay or card. No domain verification is required on your side; the checkout runs on our Apple-registered domain and pops the native Apple Pay sheet in-app. - Google Pay works in a modern Android WebView; card is always available as a fallback.
- Completion: the page navigates to
/fund/successwhen the payment completes — observe that navigation to close your WebView — and the status endpoint is the authoritative confirmation. - Wallet-only sheet: append
&only=apple_pay(or&only=google_pay) to thecheckout_urlfragment to present just that wallet button with no card form. fee_centson the create response isnullwhen the fee is already included in the quoted total.
Mint on demand, not per render
Every embedded session creates a real payment order the moment you call the endpoint. Mint one only when the user has actually initiated payment (tapped “Add funds”), render it immediately, and create a fresh session for the next attempt if the link lapses. Don’t mint on page render or in retry loops — the API refuses excess pending sessions for the same user withtoo_many_pending_sessions.
- Never relay an embedded link through chat or email; link unfurlers can consume it and leave the user a dead page. Server → WebView, immediately, is the only safe path.
- The embedded
checkout_urlappears only on the create response; the status endpoint never re-serves it. If it lapsed, create a new session. - Test with sandbox-mode credentials — sandbox clients create TEST orders (never charged), so you can exercise the full WebView flow end to end before switching to live keys.
- On a physical device, cards must be in the platform wallet; simulators cannot show the Apple Pay sheet.
Authorizations
A platform access token. Get one on the Create an access token endpoint by exchanging your client_id + client_secret, then send it as Authorization: Bearer <token>. Tokens live one hour.
Body
The connected user's id.
Amount to fund, in USD cents.
google_pay with link_type "embedded" is accepted when the user's rail returns the web checkout style; on web rails embedded is Apple Pay only (422 payment_method_not_supported).
apple_pay, google_pay hosted returns an Agentcard-hosted payment page, safe to relay anywhere (chat, email, QR); the underlying payment order is created only when the user opens it, so unopened hosted sessions cost nothing. embedded creates a REAL payment order immediately and returns the raw single-use Apple Pay link for rendering inside your own in-app webview; it lives about 5 minutes, must never be relayed through chat (link unfurlers consume it), and counts toward the user's per-user payment limits even if never paid, so mint it only when the user initiates payment. Embedded sessions support payment_method apple_pay only (google_pay with embedded is rejected). Sandbox-mode credentials create TEST orders (never charged). Embedded responses carry checkout_style (web | web) — branch your rendering on it.
hosted, embedded Response
The funding session, with the payment link to show the user.
"funding_session"pending, processing, completed, failed, expired apple_pay, google_pay The payment link to show the user. hosted: an Agentcard-hosted page, present while the link can still be opened. embedded: the raw provider Apple Pay link, present ONLY on the create response; the poll endpoint never re-serves it, so load it in an in-app webview immediately, never relay it, and create a new session if it lapses.
region_not_supported, provider_error, null On the create response: hosted links stay openable for 30 minutes; embedded links are single-use and expire about 5 minutes after creation (create a new session instead of retrying a lapsed link). On the poll endpoint, expires_at always reflects the session's 30-minute fundability window, not the embedded link's shorter life.
Which kind of checkout_url this session carries. Returned only on the create response; the poll endpoint does not include it.
hosted, embedded Provider fee included in amount_cents, in USD cents. Returned only on the create response of embedded sessions (the order is priced at create time); absent on hosted sessions and on the poll endpoint. Null on the web checkout style (the fee is inside the quoted total).
Embedded create responses only. How to render checkout_url: 'web' — an Agentcard-hosted checkout page. Load it in a WKWebView (iOS) or Android WebView; on iOS 16+ the Apple Pay button renders in-app. The page navigates to /fund/success on completion.
web