Private preview
KYC integration best practices Private preview
Reference integration flows and implementation patterns for the KYC tier system.
This page provides reference integration flows and best practices for implementing the KYC tier system. Before using these flows, read the KYC integration guide to understand the tier structure, API changes, and error codes.
For a working reference implementation, see the crypto-embedded-components-onramp sample app.
Screen overview
A typical onramp integration has the following screens:
| Screen | Purpose | Client SDK calls | Server calls |
|---|---|---|---|
| Login | Authenticate the customer and register or retrieve their crypto customer record. | registerLinkUser | GET /the relevant part of the product/:id |
| KYC | Collect and submit identity information for the required tier. | L0/L1: attachKYCInfo L2: verifyIdentity | GET /the relevant part of the product/:id |
| Wallet | Collect or select the customer’s destination wallet address. | Not applicable | GET /the relevant part of the product/:id/crypto_consumer_wallets |
| Payment | Collect the customer’s payment method. | createCryptoPaymentToken | Not applicable |
| Buy | Display transaction limits, confirm amount, and execute purchase. | Not applicable | GET /the relevant part of the product GET /the relevant part of the product POST /the relevant part of the product |
An onramp integration reuses the KYC screen across tiers and renders different fields depending on what’s needed:
- L0 : Name and address fields ( attachKYCInfo with firstName , lastName , address )
- Step-up to L1 : SSN and date of birth fields ( attachKYCInfo with dateOfBirth , idNumber , idType )
- L0 + L1 combined : All fields collected in a single KYC screen visit
- L2 : The Stripe-hosted identity document verification flow ( verifyIdentity ), available after L1 is verified
The reference app implements all screens in a single WizardView component:
- Login
- KYC
- Wallet
- Payment
- Buy
The KYC step renders different fields and submits information using the onramp SDK based on the KYC level.
Step-up detection strategy
We recommend using a proactive approach for detecting step-ups because it provides a better customer experience: you can display the limit and explain why additional verification is needed before the customer encounters an error. To implement this approach:
- On the buy screen, call GET /the relevant part of the product _ transaction _ limits before the customer confirms their purchase.
- Compare the customer’s desired amount against the returned limits for their current tier.
- If the amount exceeds the limit, prompt for step-up before attempting to create a session.
If you can’t implement proactive detection, you can use a reactive approach and attempt to create the session instead. If it returns a 400 error, retrieve the customer to determine the required tier and route the customer accordingly:
- crypto _ onramp _ missing _ minimum _ identity _ verification : The customer hasn’t submitted minimum identity information yet. Route to the KYC screen for L0.
- crypto _ onramp _ missing _ identity _ verification : L1 verification is required. Route to the KYC screen for L1.
- crypto _ onramp _ missing _ document _ verification : L2 verification is required. Route to the KYC screen for L2.
Note
crypto_onramp_missing_document_verification can also mean that risk rules require the customer to complete an identity challenge, even when the transaction amount is within the limit for their current tier.
Polling verification status
After submitting KYC information, poll GET /the relevant part of the product/:id until verification_status is verified or rejected for the relevant tier. L0 and L1 verification typically complete within a few seconds. L2 verification (document review) can take longer — adjust your polling interval and provide appropriate loading indicators for each tier.
For a reference implementation, see the refreshKycLevel function in the sample app.
Integration scenarios
The following scenarios cover the common KYC verification paths:
- L0 verification succeeds : Customer passes L0 and completes a purchase within L0 limits
- L0 succeeds, step-up to L1 : Customer passes L0 but needs L1 to complete a higher-value purchase
- L0 succeeds, step-up to L2 : Customer steps up from L0 to L1, then from L1 to L2
- L1 verification succeeds : Customer provides L0 and L1 information upfront
- L1 succeeds, step-up to L2 : Customer is L1-verified but needs L2 to complete a higher-value purchase
- L2 verification succeeds : Customer completes all three tiers upfront
- Handling verification failures
- L0 failure
- L1 failure
- L2 failure
L0 verification succeeds
When a verification succeeds, the customer provides basic identity information, passes L0 verification, and completes a purchase within L0 limits.
Recommended operations
- Login : Register or retrieve the crypto customer. Check kyc _ tiers to determine if KYC is already complete.
- KYC (L0) : Call attachKYCInfo with firstName , lastName , and address . Poll GET /the relevant part of the product/:id until the L0 tier verification _ status is verified or rejected .
- Wallet : Create or select a destination wallet.
- Payment : Call createCryptoPaymentToken to collect payment method.
- Buy : Call GET /the relevant part of the product _ transaction _ limits to display the customer’s available limits. Get a quote and create a session.
L0 succeeds, step-up to L1
In this flow, the customer passes L0 verification but attempts a purchase that exceeds L0 limits. The integration routes the customer back to the KYC screen, which collects SSN and date of birth for L1 verification.
Recommended operations
- Detect step-up to L1 : On the Buy screen, call GET /the relevant part of the product _ transaction _ limits . If the customer’s desired amount exceeds their L0 limit, or if creating a session returns crypto _ onramp _ missing _ identity _ verification , route the customer back to the KYC screen for L1.
- KYC (L1) : Call attachKYCInfo with dateOfBirth , idNumber , and idType . Poll until L1 verification _ status is verified or rejected .
- Return to Buy : After L1 verification succeeds, return the customer to the Buy screen. Refresh limits and proceed with the purchase.
L0 succeeds, step-up to L2
The customer passes L0 verification, exceeds L0 limits (triggering a step-up to L1), then exceeds L1 limits (triggering a step-up to L2). Each step-up returns to the same KYC screen, which renders different fields for each tier.
Recommended operations
- Detect step-up to L1 : On the Buy screen, call GET /the relevant part of the product _ transaction _ limits . If the amount exceeds the L0 tier limit, or if creating a session returns crypto _ onramp _ missing _ identity _ verification , route the customer to the KYC screen for L1.
- KYC (L1) : Call attachKYCInfo with dateOfBirth , idNumber , and idType . Poll until L1 verification _ status is verified .
- Return to Buy : After L1 verification succeeds, return the customer to the Buy screen. Call GET /the relevant part of the product _ transaction _ limits again to check the customer’s L1 tier limits.
- Detect step-up to L2 : If the amount exceeds the L1 tier limit, or if creating a session returns crypto _ onramp _ missing _ document _ verification , route the customer to the KYC screen for L2.
- KYC (L2) : Call verifyIdentity to present the Stripe-hosted identity verification flow. Poll GET /the relevant part of the product/:id until L2 verification _ status is verified or rejected .
- Return to Buy : After L2 verification succeeds, return the customer to the Buy screen with refreshed limits.
L1 verification succeeds
The customer provides L0 and L1 information upfront and passes both tiers. This approach collects more information initially but avoids step-up interruptions for moderate purchase amounts.
Recommended operations
- KYC (L0 + L1) : Call attachKYCInfo with all L0 and L1 fields in a single request: firstName , lastName , address , dateOfBirth , idNumber , idType . Poll until both L0 and L1 verification _ status values are verified .
- Buy : The customer has higher limits available. Fetch limits and proceed.
L1 succeeds, step-up to L2
The customer is L1-verified but attempts a purchase that exceeds L1 limits. The KYC screen shows the Stripe-hosted identity document verification flow.
Recommended operations
- Detect step-up to L2 : If the session creation returns crypto _ onramp _ missing _ document _ verification , or limits indicate the amount requires L2, route the customer to the KYC screen for L2.
- KYC (L2) : Call verifyIdentity . Poll until L2 is verified or rejected .
- Return to Buy : Refresh limits and complete the purchase.
L2 verification succeeds
The customer completes all three tiers upfront in a single KYC screen visit and purchases at the maximum L2 limits with no step-up interruptions. On the KYC screen, L1 form fields are collected and verified first, then verifyIdentity is called for L2 within the same screen.
Recommended operations
- KYC (L0 + L1) : Call attachKYCInfo with all L0 and L1 fields: firstName , lastName , address , dateOfBirth , idNumber , idType . Poll GET /the relevant part of the product/:id until L1 verification _ status is verified .
- KYC (L2) : Once L1 is verified, call verifyIdentity to present the Stripe-hosted identity document verification flow within the same KYC screen. Poll until L2 verification _ status is verified .
- Buy : With L2 verified, the customer has the maximum available limits. Fetch limits, get a quote, and create a session.
Handling verification failures
When verification fails at any tier, the verification_status is rejected and verification_errors contains details about the failure. Handle these cases based on the tier.
Transaction eligibility after a step-up failure
If a step-up fails, transaction eligibility depends on which tier failed.
- L2 failure with L1 previously verified : The customer can continue to transact within their L1 tier limits. Your integration should fall back to the Buy screen with L1 limits displayed.
- L1 failure with L0 previously verified : The customer can’t fall back to transacting within L0 limits. Once L1 verification information has been submitted, the customer must pass L1 verification before they can transact again. Your integration should prompt the customer to correct and resubmit their L1 information.
In general, submitting information for a higher tier is a one-way transition for L0 and L1. Design your step-up flows to clearly communicate to customers that providing L1 information (date of birth and SSN) replaces their L0 verification status and requires successful L1 verification to continue using the onramp.
L0 failure
If L0 verification fails, the customer can still proceed by completing L1 verification. L1 supersedes L0.
Prompt the customer to provide additional information (date of birth and SSN) to verify at L1.
L1 failure
If L1 verification fails, check the verification_errors field for details. Common causes include mismatched identity information. The customer can retry by calling attachKYCInfo again with corrected information.
Display a user-friendly error message based on verification_errors and allow the customer to correct and resubmit.
L2 failure
If L2 verification fails, the customer can retry the identity document upload. Call verifyIdentity again to present a new verification session.
Common L2 failures include blurry photos, expired documents, or selfie mismatches. Prompt the customer to retry with clearer images.
