This tutorial uses Sandbox UAT examples. First request a platform
client_id and client_secret from Clink as described in How to get platform credentials. The emails, user IDs, and tokens in the examples are placeholders.1. Prepare the environment and platform credentials
Clink configures credentials separately for each environment. Do not mix Sandbox UAT and Production tokens, user connections, payment methods, or card associations.
The RESTful API uses the platform
client_id and client_secret issued through Pre-registration, and shares the same platform client with MCP. For how to apply, what Clink registers, and the RSA public key, see How to get platform credentials. During onboarding, register the redirect_uri used for first-time user authorization and the Portal scopes portal:read portal:write.
In addition to the platform credentials, your backend also stores CLINK_API_BASE_URL. Keep user tokens, decrypted card fields, and payment credentials only on a trusted server. Do not put them in browser code, URLs, logs, Agent input, or ordinary business messages.
2. Get a platform token
Call the OAuth token endpoint with the platform credentials. The platform token is used only on the server to manage user connections and exchange for Portal Tokens. It cannot call user Portal APIs directly, and it cannot replace user authorization.expires_in in the response, and get a new one after it expires.
3. Get a Portal Token for a user
The Customer Portal API uses a Portal Token that represents a single Clink user. First verify the user’s email in your system, and associate the Clink user with a stable platform user ID. New users, and users who already have a valid authorization for the current platform, only needemail. When an existing Clink user authorizes the current platform for the first time, the redirect and PKCE fields are also required. We recommend generating a random state and a PKCE code_verifier before every request, computing the S256 code_challenge, and temporarily binding them to the platform user:
Authorized user
If the user is new, or has already completed authorization for the current platform, the endpoint returns a Portal Token:customer_id. Use it when calling the Customer Portal API:
User authorization required
If Clink finds the user but the current platform does not yet have a valid authorized connection, the response is:authorization_url unchanged to the corresponding user. After the user completes the OAuth callback, confirm that state belongs to the platform user who initiated the request and validate iss, then call the Portal Token endpoint again to get the token. Do not skip authorization, do not modify the authorization URL, and do not hand the authorization link to the model to rewrite. If the user cancels or denies authorization, initiate a new authorization request.
A Portal Token can access only the current user’s data. It cannot call /mcp, and an MCP user token cannot call /agent/platform/**.
Token expiry and renewal
A Portal Token has only an access token and no refresh token. After it expires, use the platform token to call the Portal Token endpoint again for a new one. If the current platform’s authorization for that user is no longer valid, the endpoint returnsauthorization_required again. The platform token is always the source of authority for getting user tokens and must be stored only on the server.
4. Persist user tokens on the server
A Portal Token is a server-side credential that represents a single user. After getting or refreshing it, the platform must persist the token, its expiry time,customer_id, and the granted scopes, encrypted and keyed by platform user and environment. Do not keep them only in the current request or in Agent process memory.
- Use your platform’s own stable user ID as the primary key. Do not use the email as the primary key, and do not reuse tokens across users or environments.
- Before calling a Portal API, read the token from secure server-side storage and check
expires_in. After it expires, exchange for a new one with the platform token. Portal Tokens have no refresh token. - Update the storage atomically when the token is refreshed or re-exchanged, so concurrent requests do not overwrite the new token. When authorization becomes invalid, delete the invalid local token and guide the user through authorization again.
- Use the token only on a trusted server. Do not write it into browser code, URLs, logs, Agent input, ordinary business messages, or client-side storage.
5. Read the account and payment methods
Use the Portal Token to verify the current user’s status:url from the response to the user unchanged, and treat it as a credential: do not forward it, screenshot it, or write it to logs. After the user completes the Clink-hosted page, read the payment methods again. A bind session does not create a purchase authorization. To add a card and authorize in one step, see “Add a card and authorize” in the next step. Do not collect real card numbers or CVV on platform pages.
6. Create a purchase authorization
Browser Pay first requires an active purchase authorization (instruction) that applies to this purchase.payment_instrument_id determines the signing mode:
instruction_id, status, activation_url, and activation_expires_at. Activation steps:
- Send
activation_urlonly to the target user, and open it in the user’s own browser. It is an activation link, not a Portal Token, but anyone who has the link can obtain the user’s Clink browser session while it is valid. Do not forward it, screenshot it, or write it to logs. - Poll
GET /agent/platform/authorizations/{instructionId}untilstatusisACTIVE. - Read the
mandate_idthat covers this purchase from the instruction. Use it in the next step when you get the credential.
CREATED or PENDING and does not authorize any spending. request_id is the idempotency key: retrying with exactly the same parameters within 24 hours returns the same instruction, and reusing the same request_id with different parameters returns 409. For all fields, see the Portal API reference.
To view the current user’s authorizations:
7. Get a payment credential with Browser Pay
The merchant browser first reads the amount, currency, merchant information, and order identifier from the final checkout page. The platform backend then requests a one-time payment credential with the active instruction’sinstruction_id, the mandate_id that covers this purchase, and this real checkout information.
The Browser Pay credential endpoint is part of the Portal API:
amount is a decimal string in major currency units, and merchant_url must be the HTTPS checkout page URL. client_reference_id is the idempotency key for this purchase: save it and use the same value when you report the result. Retrying with the same parameters returns the same credential and does not issue a new one. For optional fields such as product details products and shipping address shipping_address, see the Portal API reference.
The response mode depends on whether the platform has registered a public key with Clink:
Use decrypted or plaintext card fields only briefly inside a controlled checkout executor. Do not write them to logs, databases, model context, or browser local storage, and do not keep them after checkout. Use the expiry in the decrypted payload to determine how long the credential is usable;
expires_at is only an estimate. If the credential response times out, retry with the same client_reference_id to retrieve the original credential. Do not create a new authorization.
8. Complete payment on the merchant page
Your browser executor is responsible for:- Opening the merchant checkout page and reading the final amount, currency, and merchant information.
- Confirming that this information exactly matches the purchase authorization and the payment credential request.
- Using the credential in a trusted payment-fill component, without exposing real card fields to the model or ordinary logs.
- Submitting the merchant order and reading the final result from the merchant page or order API.
- Calling the payment result endpoint once the result is clear.
9. Confirm the payment result
After you confirm the merchant result, report it with the sameclient_reference_id. This is the only entry point for confirming the transaction result:
Reporting rules:
- Report the final result within 24 hours of credential issuance (before
report_deadline). Late reports return410. - For
FAILEDandNOT_SUBMITTED, you can includefailure_reason, such asCARD_DECLINED,AMOUNT_CHANGED, orBUYER_CANCELLED. paid_amountandcurrency_codemust be sent together. If they do not match the authorized amount, the response returnspaid_amount_mismatch: true.- Reporting a failure after a success has been recorded (or the reverse) returns
409(result_already_reported).
Related documentation
- How to get platform credentials: request a
client_idandclient_secret, and compare the three registration methods. - Agent Portal overview: capability boundaries, token types, and the API list.
- Portal token: request, response, and authorization status for exchanging a user Portal Token.
- Portal APIs: account, payment method, purchase authorization, credential, result, order, and settings APIs.
- Browser Pay guide: merchant browser checkout, credential protection, and result recovery.
- Encrypted credential decryption: examples of decrypting
key/payload. - How to integrate MCP: integrate Browser Pay through MCP + OAuth.
- How to integrate Vault SDK: an SDK integration in which the Agent handles only placeholder cards.