> ## Documentation Index
> Fetch the complete documentation index at: https://docs.meshconnect.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Use Mesh's callback functions

By the end of this guide, you'll understand how to use each SDK callback function to respond to key events in the user journey.

<Check>
  **Before you start**

  * You have the Mesh SDK initialized and launching (see [Launch the Mesh SDK](/build/launch-sdk))
</Check>

## Overview

When a user interacts with Link, Mesh fires SDK events that you can respond to in your app. The four callback functions below cover the most important moments in the user journey: connecting an account, completing a transfer, exiting, and responding to granular in-flow events.

## SDK callback functions

| SDK callback function          | Description                                                                                                                                                                                                          | Key uses                                                                                                                                                                                                          | Payload details                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **`onIntegrationConnected()`** | Allows you to run specific business logic when the user has successfully completed connecting an account.                                                                                                            | Capture accessTokens to:<br />• pass to Mesh SDK for a return-user experience<br />• pass to Mesh endpoints to get user deposit addresses or balances                                                             | • **`accessToken`**: the access and refresh tokens to the connected account with some basic metadata about the account and tokens<br />• **`brokerBrandInfo`**: links to icons and logos for the connected integration                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| **`onTransferFinished()`**     | Allows you to run specific business logic when the user has successfully completed a transfer.                                                                                                                       | Show user a banner or notification acknowledging a pending transaction. Example: *"Your `99.99` `USDC` deposit is `pending` and will be credited to your account when it receives enough network confirmations."* | • **`status`**: pending / succeeded / failed<br />• **`userId`**: A unique, client-specific user identifier<br />• **`transactionId`**: A unique, client-specific transfer identifier<br />• **`txId`**: A unique, exchange-specific transfer identifier<br />• **`transferId`**: A unique, Mesh-specific transfer identifier<br />• **`txHash?`**: A unique blockchain identifier<br />• **`fromAddress`**: Address transfer is sent from<br />• **`toAddress`**: Address transfer is sent to<br />• **`symbol`**: Symbol of asset being transferred<br />• **`amount`**: Amount being transferred<br />• **`amountInFiat`**: Fiat equivalent of transfer amount<br />• **`totalAmountInFiat`**: Total amount transferred, including transfer-related fees<br />• **`networkId`**: Selected network identifier<br />• **`networkName`**: Selected network name<br />• **`refundAddress`**: The address that the user can receive back to |
| **`onExit()`**                 | Allows you to run specific business logic when the user has exited Link at some point.                                                                                                                               | Show the user some experience when they exit Link without successfully completing a transfer.                                                                                                                     | • **`errorMessage`**: Descriptive error message, if applicable<br />• **`summary`**: // optional<br />• **`page`**: the page the user was on when they exited<br />• **`selectedIntegration`**: Name and `Id` of integration<br />• **`transfer`**: `previewId` and other details about the transfer preview                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| **`onEvent()`**                | Allows you to run specific business logic in more granular scenarios, like when the user exits Link from specific parts in the user journey. The events that can be used in this callback function are listed below. |                                                                                                                                                                                                                   | Different payload structure for different events                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |

## SDK-specific instructions for setting up callback functions

<AccordionGroup>
  <Accordion icon="https://mintcdn.com/mesh-40/Y-QnDCJ7fcNNqJ5o/images/icons/web.svg?fit=max&auto=format&n=Y-QnDCJ7fcNNqJ5o&q=85&s=6fd7faf20edd7e5cec27f3550deb55ef" title="Web SDK initialization structure" width="24" height="24" data-path="images/icons/web.svg">
    ```javascript theme={null}
    const connection = createLink({
      renderType: 'overlay', // Opens SDK on top of your web app
      theme: 'system', // Possible values: 'system', 'dark', 'light'
      language: 'system', // See "Multi-language support" guide
      displayFiatCurrency: 'USD', // See "Fiat currency support" guide
      accessTokens: accessTokens, // See "Supercharge return users" guide
      onIntegrationConnected: payload => {
        // Payload contains integration tokens that can be passed to SDK for a return user experience, or calling certain Mesh APIs
        console.log('[MESH LINK integration connected]', payload)
      },
      onTransferFinished: payload => {
        // Called after a transfer flow completes successfully
        console.log('[MESH LINK transfer finished]', payload)
      },
      onExit: () => {
        // Called when Link is closed
        console.log('[MESH LINK exited]')
      },
      onEvent: ev => {
        // Allows you to handle other specific events
        console.log('[MESH LINK event]', ev)
      }
    })

    connection.openLink(linkToken) // Opens a popup that overlays your app
    ```
  </Accordion>

  <Accordion icon="https://mintcdn.com/mesh-40/Y-QnDCJ7fcNNqJ5o/images/icons/apple.svg?fit=max&auto=format&n=Y-QnDCJ7fcNNqJ5o&q=85&s=3ea087c17aff5ef105e1f1e3cc39de58" title="iOS Native SDK initialization structure" width="24" height="24" data-path="images/icons/apple.svg">
    ```swift theme={null}
    func launchMeshLink(
        linkToken: String,
        viewController: UIViewController,
        accessTokens: [IntegrationAccessToken]? = nil
    ) {
        var linkHandler: LinkHandler?

        let settings = LinkSettings(
            accessTokens: accessTokens, // See "Supercharge return users" guide
            language: "system", // See "Multi-language support" guide
            displayFiatCurrency: "USD", // See "Fiat currency support" guide
            theme: .system // Possible values: 'system', 'dark', 'light'
        )

        // Called after a user connects an exchange, wallet, or other integration.
        let onIntegrationConnected: (LinkPayload) -> Void = { linkPayload in
            switch linkPayload {
            case .accessToken(let accessTokenPayload):
                print(accessTokenPayload)
            case .delayedAuth(let delayedAuthPayload):
                print(delayedAuthPayload)
            @unknown default:
                print("unknown LinkPayload")
            }
        }

        // Called after a transfer flow completes successfully or fails.
        let onTransferFinished: (TransferFinishedPayload) -> Void = { transferFinishedPayload in
            switch transferFinishedPayload {
            case .success(let successPayload):
                print(successPayload)
            case .error(let errorPayload):
                print(errorPayload)
            @unknown default:
                print("unknown TransferFinishedPayload")
            }
        }

        // Called throughout the Link flow so you can track user progress.
        let onEvent: ([String: Any]?) -> Void = { payload in
            print("Event: \(payload ?? [:])")
        }

        // Called when the user exits Link
        let onExit: (Bool?) -> Void = { showAlert in
            // showAlert is true when 'x' button is tapped
            // showAlert is false when 'Done' button is tapped on a Transfer Success screen
            if showAlert ?? false {
                // in case a custom alert is implemented, linkHandler?.closeLink() must be called to close Link
                linkHandler?.showExitAlert() // default Exit alert
            } else {
                linkHandler?.closeLink()
            }
        }

        let configuration = LinkConfiguration(
            linkToken: linkToken,
            settings: settings,
            disableDomainWhiteList: false,
            onIntegrationConnected: onIntegrationConnected,
            onTransferFinished: onTransferFinished,
            onEvent: onEvent,
            // onExit is optional, a default alert is shown in case onExit is omitted
            onExit: onExit
        )

        let result = configuration.createHandler()

        // createHandler validates the configuration before Link is presented.
        switch result {
        case .success(let handler):
            linkHandler = handler
            // Present Link from the current UIViewController.
            handler.present(in: viewController)
        case .failure(let error):
            print(error)
        @unknown default:
            print("unknown LinkResult")
        }
    }
    ```
  </Accordion>

  <Accordion icon="https://mintcdn.com/mesh-40/Y-QnDCJ7fcNNqJ5o/images/icons/android.svg?fit=max&auto=format&n=Y-QnDCJ7fcNNqJ5o&q=85&s=0bbbb8fb34fea77c1a25aaa3c9d5dacc" title="Android Native SDK initialization structure" width="24" height="24" data-path="images/icons/android.svg">
    ```kotlin theme={null}
    // Register the Link launcher as an Activity or Fragment property
    private val linkLauncher = registerForActivityResult(LaunchLink()) { result ->
        when (result) {
            is LinkSuccess -> {
                // Called when Link returns payloads, such as a connected account or completed transfer.
                Log.i(LOG_TAG, "LinkSuccess: ${result.payloads}")
            }
            is LinkExit -> {
                // Called when Link exits without payloads, including user exits or errors.
                Log.i(LOG_TAG, "LinkExit: ${result.errorMessage}")
            }
        }
    }

    private fun launchMeshLink(linkToken: String, accessTokens: List<IntegrationAccessToken>? = null) {
        // Create LinkConfiguration
        val configuration = LinkConfiguration(
            token = linkToken, // Link token returned by the Mesh backend
            theme = LinkTheme.SYSTEM, // Possible values: 'system', 'dark', 'light'
            language = "system", // See "Multi-language support" guide
            displayFiatCurrency = "USD", // See "Multi-language support" guide
            accessTokens = accessTokens, // See "Supercharge return users" guide
        )

        // Launch
        linkLauncher.launch(configuration)
    }
    ```
  </Accordion>

  <Accordion icon="https://mintcdn.com/mesh-40/Y-QnDCJ7fcNNqJ5o/images/icons/react.svg?fit=max&auto=format&n=Y-QnDCJ7fcNNqJ5o&q=85&s=162ed81498b01d342d25c427bd7bd5c7" title="ReactNative SDK initialization structure" width="24" height="24" data-path="images/icons/react.svg">
    ```javascript theme={null}
    return (
      <LinkConnect
        linkToken={linkToken}
        settings={{
          language: 'system', // See "Multi-language support" guide
          displayFiatCurrency: 'USD', // See "Fiat currency support" guide
          accessTokens, // See "Supercharge return users" guide
        }}
        onIntegrationConnected={(payload: LinkPayload) => {
          // Payload contains integration tokens that can be passed to SDK for a return user experience, or calling certain Mesh APIs
          console.log('[MESH LINK integration connected]', payload);
        }}
        onTransferFinished={(payload: TransferFinishedPayload) => {
          // Called after a transfer flow completes successfully or fails.
          console.log('[MESH LINK transfer finished]', payload);
        }}
        onEvent={(event: LinkEventType) => {
          // Allows you to handle other specific events
          console.log('[MESH LINK event]', event);
        }}
        onExit={(err?: string) => {
          // Called when Mesh Link exits, completes, is closed by the user, or fails during setup.
          console.log('[MESH LINK exited]');
        }}
      />
    );
    ```
  </Accordion>

  <Accordion icon="https://mintcdn.com/mesh-40/Y-QnDCJ7fcNNqJ5o/images/icons/flutter.svg?fit=max&auto=format&n=Y-QnDCJ7fcNNqJ5o&q=85&s=efe91e3117513e06731a5bbf7321efd0" title="Flutter SDK initialization structure" width="24" height="24" data-path="images/icons/flutter.svg">
    ```dart theme={null}
    Future<void> _showMeshLinkPage(
        String linkToken, {
        List<IntegrationAccessToken> accessTokens = const [],
    }) async {
      // Show MeshSdk
      final result = await MeshSdk.show(
        context,
        configuration: MeshConfiguration(
          language: 'system', // See "Multi-language support" guide
          displayFiatCurrency: 'USD', // See "Fiat currency support" guide
          theme: ThemeMode.system,
          integrationAccessTokens: accessTokens, // See "Supercharge return users" guide
          linkToken: linkToken,
          onEvent: (event) {
            // Allows you to handle other specific events
            print('Mesh event: $event');
          },
          onError: (errorType) {
            // Callback for when Mesh Link exits due to an error
            print('Mesh exit: $errorType');
          },
          onSuccess: (payload) {
            // Callback for when the Mesh Link is successfully completed
            print('Mesh success: ${payload.page}');
          },
          onIntegrationConnected: (integration) {
            // Payload contains integration tokens that can be passed to SDK for a return user experience, or calling certain Mesh APIs
            print('Integration connected: $integration');
          },
          onTransferFinished: (transfer) {
            // Called after a transfer flow completes successfully or fails.
            print('Transfer finished: $transfer');
          },
        ),
      );

      // Handle the result
      switch (result) {
        case MeshSuccess():
          print('Mesh link finished successfully');
        case MeshError():
          print('Mesh link error: ${result.type}');
      }

      // Alternatively, use `when` method
      result.when(
        success: (success) {
          final payload = success.payload;
          print('Mesh link success: ${payload.page}');
        },
        error: (error) {
          final errorType = error.type;
          print('Mesh link error: $errorType');
        },
      );
    }
    ```
  </Accordion>
</AccordionGroup>

## What's next

Next up: [Supercharge return-users](/build/return-users) — once you're capturing `accessTokens` via `onIntegrationConnected`, you're ready to set up Mesh Managed Tokens for a seamless return-user experience.

***

<Accordion title="AI coding reference (llms.txt)">
  *AI coding reference — a compact summary of this page's APIs, parameters, and patterns for use by AI coding assistants (following the [llms.txt standard](https://llmstxt.org/)). Human readers can safely ignore this.*

  **llms.txt — Use Mesh's callback functions**

  The 4 SDK callback functions for responding to key user journey events. Wire all 4 in every SDK initialization.

  **onIntegrationConnected(payload)** — fires when user connects an exchange or wallet.
  Key payload: `accessToken.accountTokens[].tokenId` (store this for MMT) | `accessToken.brokerType` | `brokerBrandInfo` (icons/logos)

  **onTransferFinished(payload)** — fires when transfer flow completes. Use for immediate UI updates only; use webhooks for business logic.
  Key payload: `status` (pending/succeeded/failed) | `userId` | `transactionId` | `txId` (exchange-specific) | `transferId` (Mesh-specific) | `txHash` | `symbol` | `amount` | `amountInFiat` | `totalAmountInFiat` | `fromAddress` | `toAddress` | `refundAddress` | `networkId` | `networkName`

  **onExit()** — fires when user closes Link at any point.
  Key payload: `errorMessage` | `summary.page` | `selectedIntegration` (name + Id) | `transfer.previewId`

  **onEvent(ev)** — fires for granular in-flow events. Use for analytics and specific UX logic. See Mesh SDK events guide for full event list.

  **Critical**: `onTransferFinished` fires when the provider acknowledges the request — not when it confirms on-chain. Always use webhooks for final confirmation before crediting users or releasing inventory.

  **Web SDK — canonical initialization with all 4 callbacks**:

  ```javascript theme={null}
  const connection = createLink({
    renderType: 'overlay', // Opens SDK on top of your web app
    theme: 'system', // Possible values: 'system', 'dark', 'light'
    language: 'system', // See "Multi-language support" guide
    displayFiatCurrency: 'USD', // See "Fiat currency support" guide
    accessTokens: accessTokens, // See "Supercharge return users" guide
    onIntegrationConnected: payload => {
      // Payload contains integration tokens that can be passed to SDK for a return user experience, or calling certain Mesh APIs
      console.log('[MESH LINK integration connected]', payload)
    },
    onTransferFinished: payload => {
      // Called after a transfer flow completes successfully
      console.log('[MESH LINK transfer finished]', payload)
    },
    onExit: () => {
      // Called when Link is closed
      console.log('[MESH LINK exited]')
    },
    onEvent: ev => {
      // Allows you to handle other specific events
      console.log('[MESH LINK event]', ev)
    }
  })

  connection.openLink(linkToken) // Opens a popup that overlays your app
  ```
</Accordion>
