# Retrieve card tokenization results Use the `onTokenized` callback to monitor the outcome of tokenizing the payment card. For example, if you want to conduct a pre-payment risk check with the card's details and decide whether to proceed with 3D Secure authentication or cancel the payment. > **Information** > > Follow the [Getting started with Flow for mobile](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-mobile-app/get-started-with-flow-for-mobile.md) guide before you update your integration with the steps outlined on this page. --- ## Add the onTokenized event `Client side` The `onTokenized` [event](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-mobile-app/flow-for-mobile-library-reference/ios/componentcallback.md#onTokenized(TokenizationResult)) triggers when the card is tokenized and returns a [Request card metadata](https://api-reference.checkout.com/tag/Card-metadata/#operation/requestCardMetadata!c=200&path=scheme&t=response) response. Add the event to the initialization code for your Flow instance. Then, implement the event logic to customize the payment flow depending on the tokenization result. For example, the following code uses the outcome to perform a fraud check and cancels the payment if the check fails: **Android** ```java val callbacks = ComponentCallback( onTokenized = { tokenizationResult -> runBlocking { // Perform risk check with the tokenization result. For example, using a suspend function to // send the data to a third-party risk tool: val cardRiskCheckResult = performRiskCheck(tokenizationResult) if (cardRiskCheckResult.result == "abort") { CallbackResult.Rejected("This card is not supported.") } else { CallbackResult.Accepted } } } ) val configuration = CheckoutComponentConfiguration( componentCallback = callbacks ) ``` **iOS** ```swift let callbacks = CheckoutComponents.Callbacks(onTokenized: { tokenDetails in // Perform risk check with the tokenization result. For example, using an async function to // send the data to a third-party risk tool: cardRiskCheckResult = await performRiskCheck(tokenizeResult); if cardRiskCheckResult.result == "abort" { return .rejected(message: "This cards is not supported.") } return .accepted }) let configuration = CheckoutComponents.Configuration(..., callbacks: callbacks) ``` --- ## Add the handleSubmit event `Client side` The `handleSubmit` [event](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-mobile-app/flow-for-mobile-library-reference/ios/componentcallback.md#handleSubmit(SessionData)_:_APICallResult) enables you to submit a modified payment session. Add the event to the initialization code for your Flow for mobile configuration. Implement the callback logic to provide the payment submission data to your server-side integration: **Android** ```java suspend fun handleSubmit(sessionData: SessionData): ApiCallResult { handlePaymentSubmission() } val callback = ComponentCallback(handleSubmit = ::handleSubmit) ``` **iOS** ```swift let callbacks = CheckoutComponents.Callbacks(...handleSubmit: handleSubmit) let configuration = CheckoutComponents.Configuration(..., callbacks: callbacks) ``` --- ## Submit the modified payment session `Server side` Call the [Submit a payment session](https://api-reference.checkout.com/tag/Flow/#operation/SubmitPaymentSession) endpoint and provide the payment session ID as the `{id}` path parameter. In your request, provide the payment session data from the `handleSubmit` event in `session_data`. You can also modify any of the following fields: - `3ds` - `amount` - `items` - `reference` > **Information** > > Your base URL's `{prefix}` value is unique to your account and environment. To learn how to retrieve your base URLs for the sandbox and production environments, see [API endpoints](https://www.checkout.com/docs/developer-resources/api/api-endpoints.md). **Production** `POST` `https://{prefix}.api.checkout.com/payment-sessions/{id}/submit` **Sandbox** `POST` `https://{prefix}.api.sandbox.checkout.com/payment-sessions/{id}/submit` ### Request example ```json { "session_data": "{SESSION_DATA_FROM_FLOW}", "3ds": { "enabled": true } } ``` ### Response example ```json { "id": "pay_f2ws3hn4ijquzbytp3v5lsfxge", "status": "Action Required", "type": "card", "action": { "type": "3ds", "url": "http://3ds2.checkout.com/interceptor/sid_y3oqhf46pyzuxjbcn2giaqnb44" } } ``` --- ## Handle the payment response `Client side` You must provide the unmodified response to the `handleSubmit` event in the client-side integration. Flow handles any additional required actions.