> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://amer.developers.trustly.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://amer.developers.trustly.com/_mcp/server.

# Migrate from the JavaScript SDK to the In-App Browser

Use this integration guide to migrate to the Trustly in-app browser model. This lightweight model eliminates the need to embed a WebView or JavaScript SDK. Instead, the app builds the transaction URL, launches the secure browser, and processes the return redirect. Adopting this model reduces your app's payload size and minimizes ongoing maintenance by removing external SDK dependencies.

## Prerequisites

* **Trustly merchant credentials:** An active merchant account with your assigned `accessId` and `merchantId`.
* **Secure backend infrastructure:** A server environment capable of generating cryptographic request signatures (**HMAC-SHA256**) and handling Base64 (URL-safe) encoding.
* **Mobile application access:** Ability to modify your iOS or Android source code to register native URL schemes and handle deep-link intents.
* **Secure device storage:** A local storage solution within your app (such as Keychain for iOS or EncryptedSharedPreferences for Android) to securely persist user session tokens.

## Implementation workflow

The following diagram illustrates the communication workflow between your backend server, your mobile application, and the Trustly API. This architecture securely separates the backend payload generation and signature validation from the native OS browser authentication and deep-link redirect.

```mermaid
%%{
  init: {
    'theme': 'dark'
  }
}%%
sequenceDiagram
    participant Backend as Backend Server
    participant App as Mobile App
    participant Trustly as Trustly API

    Note over Backend: A
    Backend->>App: B
    App->>Trustly: C
    Note over App, Trustly: D
    Trustly-->>App: E
    App->>Backend: F
    Note over Backend: G
    Backend-->>App: H
```

|  Step | Action           | Description                                                                                                     |
| :---: | :--------------- | :-------------------------------------------------------------------------------------------------------------- |
| **A** | **Generate**     | The backend server generates the required transaction parameters.                                               |
| **B** | **Serialize**    | The backend converts the payload to JSON, Base64-encodes the token, and passes it to the app.                   |
| **C** | **Launch**       | The app launches a native in-app browser session using the designated Trustly endpoint.                         |
| **D** | **Authenticate** | The user completes the hosted authentication flow within the secure Trustly UI.                                 |
| **E** | **Redirect**     | Trustly executes a deep-link redirect back to the app using the registered URL scheme.                          |
| **F** | **Forward**      | The app parses the redirect query parameters and forwards them to the backend server.                           |
| **G** | **Verify**       | The backend validates the cryptographic HMAC signature of the returned parameters (excluding `trustlyContext`). |
| **H** | **Update**       | The backend updates the transaction state and returns the final status to the mobile app UI.                    |

## Update your implementation

Update your backend payload and app routing to launch Trustly in a secure native browser instead of an embedded WebView.

### Configure the base URL

To route the transaction and ensure you are interacting with the test or production environment, copy one of the following base URLs and add it to your application configuration:

* **Sandbox:** `https://sandbox.paywithmybank.com/frontend/mobile/establish`
* **Production:** `https://trustly.one/frontend/mobile/establish`

### Configure the UI

To show or hide a bank selection screen before checkout, append one of the following `widget` query parameters to your base URL:

* `widget=true`: Renders both the Bank Widget and the Checkout Lightbox.
* `widget=false`: Renders the Checkout Lightbox only.

To display the widget or lightbox, launch the establish URL in the native in-app browser session described above (`ASWebAuthenticationSession` on iOS, `CustomTabsIntent` on Android). The Trustly UI runs entirely within that session.

### Target Launch URL Format

```text
{BASE_URL}?widget={true|false}&token={token}
```

### Build and encode the payload

To generate the secure token required for the final transaction URL, assemble the following required properties into a dictionary or map on your backend before serializing it to a UTF-8 encoded JSON string and encoding it to Base64 (URL-safe):

#### Required properties

`accessId`, `merchantId`, `currency`, `amount`, `merchantReference`, `requestSignature`, `paymentType`, `returnUrl`, `cancelUrl`

#### Required nested properties

* `metadata`: Must contain `urlScheme` and `trustlyContext`.
* `customer`: Must contain `name`, and a nested `address` object containing `country`.

Object keys containing periods (for example, `customer.address.country`) must be structured as nested JSON objects before Base64 encoding.

### Payload example

```json
{
  "accessId": "mid_123456",
  "merchantId": "merch_789",
  "amount": "10.00",
  "returnUrl": "myapp://trustly_return",
  "cancelUrl": "myapp://trustly_cancel",
  "metadata": {
    "urlScheme": "myapp://trustly_oauth_return",
    "trustlyContext": "new"
  },
  "customer": {
    "name": "John Doe",
    "address": {
      "country": "US"
    }
  }
}
```

## Register a custom URL scheme

To automatically return users to your app after they complete or cancel a transaction, you register a unique URL scheme (for example, `myapp`) within your app's native configuration (such as your `AndroidManifest.xml` or `Info.plist`).

To instruct Trustly where to send the user based on their actions, add the following properties to your JSON payload:

```text
returnUrl = "myapp://trustly_return"
cancelUrl = "myapp://trustly_cancel"
```

## Process the redirect

To determine the outcome of the transaction and securely update your app's state, your application must intercept the return deep link and extract its query parameters.

### Example redirect URL

```text
myapp://trustly_return?transactionId=123&status=2&trustlyContext=abc
```

Extract the following parameters from the URL:

* **`status`:** Indicates the result of the checkout. A value of `2` means the transaction was successful.
* **`transactionId`:** The unique identifier for the specific transaction.
* **`trustlyContext`:** The persistent session identifier for the user.

### Signature verification

This step applies to the query parameters Trustly appends to your `returnUrl` or `cancelUrl` redirect — not to the `requestSignature` field in your establish payload. Your backend computes `requestSignature` when building the outbound establish token before launch. After the user returns to your app, your backend must separately validate the cryptographic signature of the returned redirect parameters.

To ensure the redirect data has not been tampered with, your backend must validate the cryptographic signature of the returned parameters. **You must exclude the `trustlyContext` parameter from your signature calculation.** Because this is a session token added by the routing layer, including it will cause your HMAC signature validation to fail. See the Trustly signature validation documentation for the hashing algorithm requirements.

## Manage user sessions with `trustlyContext`

The `trustlyContext` parameter acts as a persistent session identifier, enabling Trustly to recognize returning users and streamline their future transactions. To determine which value to pass in your backend payload based on the user's history, see the following table:

| User Scenario                              | `metadata.trustlyContext` Value            |
| :----------------------------------------- | :----------------------------------------- |
| **First transaction** (No prior token)     | `"new"`                                    |
| **Subsequent transactions** (Token exists) | Pass the last saved `trustlyContext` value |

### Handle the token lifecycle

To ensure Trustly successfully recognizes returning users across multiple checkouts, your application must continuously manage the `trustlyContext` session token. Implement the following steps to handle this identifier's lifecycle:

1. **Transmit:** Include the current `trustlyContext` value in your establish payload for every transaction initialization.
2. **Capture:** Extract the `trustlyContext` query parameter from the redirect URL when the user returns to your app.
3. **Persist:** Save the retrieved token locally in secure device storage so it is available for the next session.
4. **Fallback:** If a redirect does not return a new `trustlyContext` parameter, retain your previously saved value. Do not modify this string manually.

## Implementation checklist

To ensure your migration to the in-app browser is complete and ready for testing, use the following checklist to verify you have successfully implemented all the required steps:

* [ ] **Base URL:** Configure the base URL for your target environment (Sandbox or Production).
* [ ] **UI presentation:** Configure the UI presentation to show or hide the bank selection screen using the `widget` parameter.
* [ ] **Browser session:** Create and start a native in-app browser session — `ASWebAuthenticationSession` on iOS or `CustomTabsIntent` on Android — to open the establish URL and render the widget/lightbox.
* [ ] **URL scheme:** Register a custom URL scheme in your app's native configuration and define your `returnUrl` and `cancelUrl`.

- [ ] **Payload encoding:** Build and encode the payload into a Base64 URL-safe token, ensuring all required properties are included.
- [ ] **Token lifecycle:** Handle the token lifecycle by continuously transmitting, capturing, and persisting the `trustlyContext` session token.

* [ ] **Signature verification:** Process the redirect to extract the return parameters and securely verify the cryptographic signature of the redirect parameters on your backend. **Ensure you exclude `trustlyContext` from the calculation.**