Server Integration
Overview
If you want full control of the payment flow — your own retry logic, your own transaction bookkeeping, your own 3-D Secure presentation — you can submit the wallet token to the CrissCross API yourself instead of letting the SDK do it.
You still use the wallets SDK to render the button and obtain the token. Only the wallet running on the customer’s device can produce one, and it cannot be produced server-side. What changes is that the SDK hands the token to you rather than submitting it.
This is the most involved wallet integration and it carries the most ways to get a payment stuck. Unless you need control that React Integration does not give you, use that instead — it makes the same calls described here.
Pre-requisites
- Apple Pay and Google Pay enabled on your account.
- Your payment domains registered and verified. See Wallet Configuration.
- A checkout session created with
integrationType: "direct".
The flow
Render the button and capture the token
Initialise the SDK in manual mode, which suppresses submission and hands you the token — and, for Apple Pay, makes the merchant validation yours to route:
onValidateMerchant must resolve with the merchantSession object exactly as CrissCross returned it — the wallet sheet will not release a token until it does. Step 2 covers the endpoint behind /api/wallet-merchant-session.
token is already base64-encoded and safe to transport as a string. deviceFingerprint is required for fraud screening — pass it through unaltered.
Validate the merchant session (Apple Pay only)
Apple requires a server-side merchant validation before the wallet sheet will release a token. In manual mode this is yours to make.
onValidateMerchant gives you a validationUrl. Forward it to CrissCross from your server — never from the browser, since this call uses your OAuth credentials:
Response:
Return merchantSession to the browser unaltered, as JSON. Do not re-serialise its fields, reorder them, or log it — Apple validates it as an opaque whole and it is short-lived.
Note what you do not send: no merchant identifier, no domain, no certificate. CrissCross resolves all of it from sessionId. Google Pay has no equivalent step.
Pass validationUrl through exactly as the wallet issued it. CrissCross accepts it only if it is an HTTPS URL on an Apple Pay validation host and rejects anything else with 422, so a rewritten or constructed URL will fail rather than be requested.
Submit the payment
Handle the response
A payment needing 3-D Secure returns PENDING with an authState:
Send the customer to redirectUrl. They return to the session’s redirectUrl when the challenge resolves. Most wallet payments are exempt from 3-D Secure, because the device authentication already satisfies strong customer authentication — so treat this as a path you must support, not the common case.
Confirm on the webhook
The webhook is the authoritative outcome. Match it on sessionId or merchantReference, verify its signature, and only then fulfil. See Webhook Events.
Things that will bite you
- A wallet token is single-use and short-lived. You cannot store it, retry with it after a decline, or submit it twice. A retry means a new tap on the wallet button and a new token.
- The merchant session is also single-use. Fetch a fresh one per wallet sheet; do not cache it.
- Never log tokens or merchant sessions. They are payment credentials for as long as they are valid.
- Do not transform the token. It arrives base64-encoded from the SDK and must reach CrissCross exactly as it left the wallet.
Additional resources
- React Integration — the same flow with these calls handled for you.
- Wallet Configuration — registering your payment domains.
- Digital Wallets — supported workflows, refunds and reconciliation.
- Full and Partial Refunds — refunding a wallet payment.