# LLM Backend Integration

````
# Backend Integration Documentation

## Table of Contents

* [Reference/data-api.md](#referencedata-apimd)
* [Reference/webhooks.md](#referencewebhooksmd)
* [Introduction/supported-coins-and-blockchains.md](#introductionsupported-coins-and-blockchainsmd)

---

## SOURCE: Reference/data-api.md

# Endpoint specification

Data API allows partners to retrieve information about your users and any orders associated with your Partner ID. It also includes support for direct user creation if enabled for your Partner ID.

**Endpoint URLs:**

### Sandbox

| Endpoint | URL | Method |
| :--- | :--- | :--- |
| Orders | `https://partner-sandbox.wert.io/api/external/orders` | `GET` |
| Users | `https://partner-sandbox.wert.io/api/external/users` | `GET` |
| User Create | `https://partner-sandbox.wert.io/api/external/users/create` | `POST` |
| Card Register | `https://cards-reg-iframe-sandbox.wert.io/api/v1/partner/register` | `POST` |

### Production

| Endpoint | URL | Method |
| :--- | :--- | :--- |
| Orders | `https://partner.wert.io/api/external/orders` | `GET` |
| Users | `https://partner.wert.io/api/external/users` | `GET` |
| User Create | `https://partner.wert.io/api/external/users/create` | `POST` |
| Card Register | `https://cards.wert.io/api/v1/partner/register` | `POST` |

---

# Authentication

To authenticate your requests, include your API key in the HTTP header of every request.

| Header Key | Value |
| :--- | :--- |
| `X-Api-Key` | `your-unique-api-key` |

> **⚠️ Warning**
>
> **Your API key carries many privileges, so keep it secure.**
>
> Your API key is provided exclusively by Wert during onboarding. **Store it safely in your backend.**
>
> Never share your key. If you suspect a compromise, contact us immediately to issue a new one.
>
> **Note:** Sandbox and Production keys are **unique** to their respective environments and are not interchangeable.

---

# API Reference

## Get orders

Get detailed orders data associated with your partner account.

### Request Details

#### Endpoint: `GET /api/external/orders`

👉 Refer to [endpoints table](https://docs.wert.io/docs/data-api#endpoint-specification) for a full link.

#### Parameters

Configure your request using the parameters below to search and filter order results.

| Parameter | Description | Possible Values |
| :--- | :--- | :--- |
| `limit` | The number of orders you want to retrieve.<br><br>Defaults to `10`. | `0` to `20` |
| `cursor_id` | Fetches the next page of results using the `next_cursor_id` from a previous response.<br><br>Defaults to an empty string. | `01KAQWBNWWGG06HR5T9Z35A3WD` |
| `search_by` | Allows setting `order_id`, `click_id`, or `external_order_id` to find specific orders. | Comma-separated order IDs, click IDs, or external order IDs, for example `2FX6Yz`. |
| `order_by` | Sets the order as ascending or descending.<br><br>Defaults to `desc`. | `asc` / `desc` |
| `start_date` | Filters orders with `created_at` after this timestamp. | `YYYY-MM-DDTHH:MM:SSZ`, for example `2025-11-19T23:59:59.00Z`. |
| `end_date` | Filters orders with `created_at` up to this timestamp. | `YYYY-MM-DDTHH:MM:SSZ` |

> **💡 Info**
>
> **Date filtering reference**
>
> - Use `start_date` and `end_date` together to return orders for a specific period.
> - Use a narrow time range if you have a high volume of orders. The maximum is **20 orders** per request.

---

#### Example Requests

```bash
# 1. Get the 10 most recent orders (default)
curl -X GET 'https://partner-sandbox.wert.io/api/external/orders' \
  -H 'X-Api-Key: your-unique-api-key'

# 2. Retrieve 20 orders using a cursor and ascending order
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/orders' \
  -H 'X-Api-Key: your-unique-api-key' \
  -d 'limit=20' \
  -d 'cursor_id=01KAQWBNWWGG06HR5T9Z35A3WD' \
  -d 'order_by=asc'

# 3. Search for orders using a single click_id
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/orders' \
  -H 'X-Api-Key: your-unique-api-key' \
  -d 'search_by=click_id'

# 4. Search for orders using a single external_order_id
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/orders' \
  -H 'X-Api-Key: your-unique-api-key' \
  -d 'search_by=2FX6Yz'

# 5. Search using multiple click_ids and order_ids
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/orders' \
  -H 'X-Api-Key: your-unique-api-key' \
  -d 'search_by=click_id1,click_id2,order_id1,order_id2'

# 6. Filter orders by status
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/orders' \
  -H 'X-Api-Key: your-unique-api-key' \
  -d 'status=failed'

# 7. Filter orders by date range
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/orders' \
  -H 'X-Api-Key: your-unique-api-key' \
  -d 'start_date=2025-11-19T00:00:00Z' \
  -d 'end_date=2025-11-19T23:59:59Z'

# 8. Filter orders by status and commodity
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/orders' \
  -H 'X-Api-Key: your-unique-api-key' \
  -d 'status=failed' \
  -d 'commodity=tt_amoy.erc-20.polygon'
```

### Response Details

#### Orders Response

Upon a successful request, the response includes the following fields:

| Variable | Description |
| :--- | :--- |
| `success` | Indicates if the request was successfully processed. |
| `data` | An array containing the retrieved order objects. See [order object](https://docs.wert.io/docs/data-api#order-object). |
| `next_cursor_id` | The cursor string used to fetch the next page of results. |
| `total` | The total count of orders matching the search criteria. |

---

#### Order Object

> **💡 Info**
>
> The following fields represent the schema for each order in the data array. Parameters marked as filterable can be used to customize your queries by using the filter name shown in the table.

| Variable | Description | Filterable | Filter Name |
| :--- | :--- | :--- | :--- |
| `order_id` | The unique identifier for the order in Wert's database. | Yes | `search_by` |
| `click_id` | The identifier you pass to Wert when you initialise the widget. | Yes | `search_by` |
| `currency` | The base currency for the order. | No | - |
| `currency_amount` | The value of the order in the base currency. | No | - |
| `external_order_id` | The unique identifier for an order. Used in partner dashboard and customer emails. | Yes | `search_by` |
| `crypto` | The crypto asset purchased or sent to the smart contract. | Yes | `commodity` |
| `crypto_amount` | The amount of the crypto asset purchased or sent to the smart contract. | No | - |
| `user_id` | The unique identifier for the user in Wert's database. | Yes | `user_ids` |
| `status` | The status of the order. See [statuses](https://docs.wert.io/docs/data-api#order-status). | Yes | `status` |
| `card_id` | The unique identifier for the card used in Wert's database. | Yes | `card_id` |
| `created_at` | Timestamp of when the order was created (UTC). | No | - |
| `changed_at` | Timestamp of when the order was last updated (UTC). | No | - |
| `partner_fee` | The USD amount of fees collected as partner revenue. | No | - |
| `partner_fee_percent` | The percentage of fees collected as partner revenue. | No | - |
| `wert_fee` | The USD amount of fees collected as Wert revenue. | No | - |
| `wert_fee_percent` | The percentage of fees collected as Wert revenue. | No | - |
| `tx_id` | Blockchain transaction hash. | Yes | `tx_id` |
| `processed_through` | The acquirer who processed the card payment. | No | - |
| `card_brand` | Visa or Mastercard. | No | - |
| `fail_reason` | Payment error code. Refer to [error code](https://docs.wert.io/docs/data-api#payment-error-codes) descriptions. | Yes | `fail_reason` |
| `payment_type` | Authentication method of the payment, for example `3ds_v2`. | Yes | `payment_type` |
| `additional_data` | Additional information. | No | - |
| `address` | The address specified for the order. | No | - |
| `sc_input_data` | Smart contract input data sent in the transaction. | No | - |

---

#### Example Response

```json
{
    "success": true,
    "data": [
        {
            "order_id": "01HNWX0HSK85WW9W5A3RZS1BBH",
            "click_id": "82960ad6-e52c-48b1-9293-5658709da384",
            "currency": "usd",
            "currency_amount": 1.07,
            "crypto": "matic.simple.polygon",
            "crypto_amount": 1.28928444,
            "external_order_id": "62no2X",
            "user_id": "01HNWWXZ8FQ9FSH08A8ACHH7K1",
            "status": "success",
            "card_id": "01HNWWZ6E1T0BJT46H35M42JT7",
            "created_at": "2024-02-05 15:08:29",
            "changed_at": "2024-02-05 15:08:32",
            "tx_id": "0xbef4262a7c56f64423b80e4342ee4309595dcdb78d8c201fd752dc1d9c29c19e",
            "processed_through": "safecharge",
            "card_brand": "VISA",
            "fail_reason": "",
            "payment_type": "non_3ds",
            "additional_data": null,
            "address": "0xAA453aD5c9CF7F04bFe0DfdD12b27504AFdb800b"
        },
        {
            "order_id": "01HMXQ6AN3XKQAZHPRSM13ED3X",
            "click_id": "click_id",
            "currency": "usd",
            "currency_amount": 5,
            "crypto": "tt_goerli.erc-20.ethereum",
            "crypto_amount": 4.36051815,
            "external_order_id": "62no2X",
            "user_id": "01HMVWY6V7B9ZHA6P2C48AP5C7",
            "status": "failed",
            "card_id": "01HMVX1NJB6QDW5YKXA13HB2CG",
            "created_at": "2024-01-24 12:30:20",
            "changed_at": "2024-01-24 12:30:27",
            "tx_id": "",
            "card_brand": "VISA",
            "fail_reason": "4007",
            "payment_type": "unknown",
            "additional_data": null,
            "address": "0xAA453aD5c9CF7F04bFe0DfdD12b27504AFdb800b"
        }
    ],
    "next_cursor_id": "01KAQWBNWWGG06HR5T9Z35A3WD",
    "total": 2
}
```

---

#### Order Status

The following order statuses are available:

| Status | Description |
| :--- | :--- |
| success | The order was successful and has been sent on the blockchain |
| failed | The order has failed and will not be sent on the blockchain |
| cancelled | The payment for the order was processed but the order was later cancelled |
| pending | The order is being processed but it hasn't been sent on the blockchain |
| progress | The order is being processed but payment has not yet been completed |
| created | The order has been created but payment has not yet been processed |

---

#### Payment Error Codes

The following table identifies the specific cause of transaction failures returned in the `fail_reason` field in [order object](https://docs.wert.io/docs/data-api#order-object). Use these codes to provide accurate troubleshooting steps to your users.

| Error Code | Description |
| :--- | :--- |
| `4000` | We weren’t able to charge the user’s card and the order was not completed. The user can try again. |
| `4001` | The transaction failed due to an incorrect CVV/CVC. The user can try again ensuring they enter the correct CVV/CVC. |
| `4002`<br>`4010`<br>`4012` | Payment was declined by the card issuer. The user should contact them for further details. |
| `4003` | Incorrect card details. The user can try again ensuring they enter valid card details. |
| `4004` | Insufficient balance. The user should add funds to their card and try again. |
| `4005` | Card limit was exceeded. The user should use a different card to complete their purchase. |
| `4011` | Card validation failed. The user can add a valid card and try again. |
| `4013` | Payment was declined due to risk assessment. |
| `4014` | Name on the bank payment account doesn't match the verified identity. The user should contact support for further assistance. |
| `4015` | Payment wasn't received within the expected time. |
| `4016` | Payment was received after the order timeout period. Funds will be refunded shortly. |
| `4017` | Payment amount doesn't match the order amount. |
| `4018` | Payment was canceled by the user. No funds were charged. |

## Get users

Fetch detailed users data you have created or served.

### Request Details

#### Endpoint: `GET /api/external/users`

👉 Refer to [endpoints table](https://docs.wert.io/docs/data-api#endpoint-specification) for a full link.

#### Parameters

Configure your request using the parameters below to search and filter user results.

| Parameter | Description | Possible Values |
| :--- | :--- | :--- |
| `limit` | The number of users you want to retrieve. | `0` to `20` |
| `offset` | Skips the specified number of users.<br><br>Defaults to `0`. | `10` |
| `order_by` | Sets the order as ascending or descending.<br><br>Defaults to `desc`. | `asc` / `desc` |
| `from` | Filters users with `created_at` after this timestamp. | `YYYY-MM-DDTHH:MM:SSZ`, for example `2025-11-19T23:59:59.00Z`. |
| `to` | Filters users with `created_at` up to this timestamp. | `YYYY-MM-DDTHH:MM:SSZ` |

> **💡 Info**
>
> **Date filtering reference**
>
> - Use `from` and `to` together to return users for a specific period.
> - Use a narrow time range if you have a high number of users. The maximum is **20 users** per request.

---

#### Example request

```bash
# 1. Get the most recent users (Default)
curl -X GET 'https://partner-sandbox.wert.io/api/external/users' \
-H 'X-Api-Key: your-unique-api-key'

# 2. Retrieve 20 users from a specific offset
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/users' \
-H 'X-Api-Key: your-unique-api-key' \
-d 'limit=20' \
-d 'offset=20'

# 3. Search for a specific user by ID
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/users' \
-H 'X-Api-Key: your-unique-api-key' \
-d 'user_ids=user_id'

# 4. Search for multiple users (comma-separated IDs)
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/users' \
-H 'X-Api-Key: your-unique-api-key' \
-d 'user_ids=user_id1,user_id2,user_id3'

# 5. Filter users by KYC status (e.g., success)
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/users' \
-H 'X-Api-Key: your-unique-api-key' \
-d 'lkyc_status=success'

# 6. Filter by date range (When users were created)
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/users' \
-H 'X-Api-Key: your-unique-api-key' \
-H 'Content-Type: application/json' \
-d 'from=2025-11-20T00:00:00.00Z' \
-d 'to=2025-11-20T23:59:59.00Z'

# 7. Filter users by phone country
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/users' \
-H 'X-Api-Key: your-unique-api-key' \
-d 'phone_country=RU'

# 8. Filter users by kyc country
curl -X GET -G 'https://partner-sandbox.wert.io/api/external/users' \
-H 'X-Api-Key: your-unique-api-key' \
-d 'kyc_country=RUS'
```

### Response Details

#### Users Response

Upon a successful request, the response includes the following fields:

| Variable | Description |
| :--- | :--- |
| `success` | Indicates if the request was successfully processed. |
| `data` | An array containing the retrieved user objects. See [user object](https://docs.wert.io/docs/data-api#user-object). |
| `total` | The total count of users matching the search criteria. |

---

#### User Object

> **💡 Info**
>
> The following fields represent the schema for each user in the data array. Parameters marked as filterable can be used to customize your queries by using the filter name shown in the table.

| Variable | Description | Filterable | Filter Name |
| :--- | :--- | :--- | :--- |
| `user_id` | User's Wert ID. | Yes | `user_ids` |
| `country` | User's KYC country. [alpha3](https://www.nationsonline.org/oneworld/country_code_list.htm) | Yes | `kyc_country` |
| `phone` | User's masked phone number. | No | - |
| `phone_country` | User's phone country. [alpha2](https://www.nationsonline.org/oneworld/country_code_list.htm) | Yes | `phone_country` |
| `lkyc_status` | User's non-document verification status. | Yes | `lkyc_status` |
| `fkyc_status` | User's document verification status. | Yes | `fkyc_status` |
| `banned` | Indicates whether the user is banned by Wert. | No | - |
| `created_at` | Date and time of the user's creation (UTC). | Yes | `to` / `from` |
| `limits.crypto_remaining` | The user's current crypto limit left in USD. Zero if no KYC or active KYC is not success. | No | - |
| `limits.crypto_spending` | How much in USD the user has already spent from the current crypto limits. | No | - |
| `limits.digital_goods_remaining` | The user's current NFT limit left in USD. Zero if no KYC or active KYC is not success. | No | - |
| `limits.digital_goods_spending` | How much in USD the user has already spent from the current NFT limits. | No | - |
| `linked_payment_methods` | An array of objects representing the user's saved payment options. See [linked payment methods object](https://docs.wert.io/docs/data-api#linked-payment-methods). | No | - |

---

#### Linked Payment Methods

| Variable | Description |
| :--- | :--- |
| `linked_payment_methods.cards[].brand` | Payment method brand. |
| `linked_payment_methods.cards[].card_id` | Payment method card ID associated with Wert. |
| `linked_payment_methods.cards[].created_at` | Payment method creation date. |
| `linked_payment_methods.cards[].last_digits` | Payment method last digits. |
| `linked_payment_methods.method` | Payment method. |

---

#### Example Response

```json
{
  "data": [
      {
          "country": "DEU",
          "created_at": "2025-11-19T11:21:48.200421Z",
          "fkyc_status": "retry",
          "limits": {
              "crypto_remaining": "0",
              "crypto_spending": "0",
              "digital_goods_remaining": "0",
              "digital_goods_spending": "0"
          },
          "linked_payment_methods": [
              {
                  "cards": [
                      {
                          "brand": "VISA",
                          "card_id": "01KADXN9TN3QEMG9DHWX6G7Y0S",
                          "created_at": "2025-11-19T11:23:09.526895Z",
                          "last_digits": "1000"
                      }
                  ],
                  "method": "bank_card"
              }
          ],
          "lkyc_status": "failed",
          "phone": "+49*****356",
          "phone_country": "DE",
          "user_id": "01KADXJS47C9B1WG8V3ZNM2SV7"
      },
      {
          "country": "DEU",
          "created_at": "2025-11-19T11:19:44.098153Z",
          "fkyc_status": "not initiated",
          "limits": {
              "crypto_remaining": "6000",
              "crypto_spending": "0",
              "digital_goods_remaining": "6000",
              "digital_goods_spending": "0"
          },
          "linked_payment_methods": [],
          "lkyc_status": "success",
          "phone": "+49*****355",
          "phone_country": "DE",
          "user_id": "01KADXEZZQF8DQEPP4AE28SKBX"
      },
      {
          "country": "DEU",
          "created_at": "2025-11-19T11:14:42.380854Z",
          "fkyc_status": "not initiated",
          "limits": {
              "crypto_remaining": "6000",
              "crypto_spending": "0",
              "digital_goods_remaining": "6000",
              "digital_goods_spending": "0"
          },
          "linked_payment_methods": [],
          "lkyc_status": "success",
          "phone": "+49*****354",
          "phone_country": "DE",
          "user_id": "01KADX5RRHCHDMPFWEEFX2YDS6"
      }
  ],
  "success": true,
  "total": 3
}
```

## Create User

Create users via the API. This will generate a Wert profile for the user and initiate Light KYC on their behalf. If the KYC check is successful, the user will be taken directly to the payment step in the widget. Contact our support team to request this feature for your Partner ID.

### Request Details

#### Endpoint: `POST /api/external/users/create`

👉 Refer to [endpoints table](https://docs.wert.io/docs/data-api#endpoint-specification) for a full link.

> **❗️ Error**
>
> Non-English characters should be standardized to English before passing to API.

#### Parameters

Configure your request using the parameters below to create user via API.

| Property | Required | Validation |
| :--- | :--- | :--- |
| **has_accepted_terms_of_service** | ✅ | possible values: `true`, `false` |
| **phone** | ✅ | +1234567890 |
| **email** | ✅ | [john.doe@example.com](mailto:john.doe@example.com) |
| **first_name** | ✅ | 2–30 characters; A-Z, a-z, 0-9; No special characters (?, @, #, $, etc.); Cannot be all numeric |
| **middle_name** | Optional | 2–30 characters; A-Z, a-z, 0-9; No special characters (?, @, #, $, etc.); Cannot be all numeric |
| **last_name** | ✅ | 2–30 characters; A-Z, a-z, 0-9; No special characters (?, @, #, $, etc.); Cannot be all numeric |
| **date_of_birth** | ✅ | format: `YYYY-MM-DD` |
| **country_of_residence** | ✅ | [alpha3](https://www.nationsonline.org/oneworld/country_code_list.htm) country code; |
| **state_of_residence** | ✅ | [alpha2](https://www.iso.org/obp/ui/#iso:code:3166:US) US state code; |

---

#### Example request

Example of user data to create a user with Wert and initiate an automatic LKYC.

```bash
curl -X POST 'https://partner.wert.io/api/external/users/create' \
 -H 'X-Api-Key: your-unique-api-key' \
 -H 'Content-Type: application/json' \
 -d '{
   "has_accepted_terms_of_service": true,
   "phone": "+1234567890",
   "email": "john.doe@example.com",
   "first_name": "John",
   "middle_name": "Paul",
   "last_name": "Doe",
   "date_of_birth": "1990-01-01",
   "country_of_residence": "USA",
   "state_of_residence": "CA"
 }'
```

### Response Details

Possible response from User Creation endpoint. Refer to [user creation error codes](https://docs.wert.io/docs/data-api#user-creation-error-codes) for more details.

#### Status: 200 (OK)

```json
{
    "created_at": "string",
    "user_id": "string"
}
```

#### Status: 400 (Bad Request)

```json
{
    "field": "phone",
    "message": "Invalid phone format"
}
```

```json
{
    "field": "email",
    "message": "Invalid email format"
}
```

```json
{
    "field": "date_of_birth",
    "message": "Invalid date_of_birth format"
}
```

```json
{
    "field": "first_name",
    "message": "Invalid first_name format"
}
```

```json
{
    "field": "country_of_residence",
    "message": "Invalid country_of_residence format"
}
```

#### Status: 401 (Unauthorized)

```json
{
    "message": "ERR_UNAUTHORIZED"
}
```

#### Status: 403 (Forbidden)

```json
{
    "field": "has_accepted_terms_of_service",
    "message": "user must accept the terms of service"
}
```

```json
{
    "field": "country_of_residence",
    "message": "restricted country"
}
```

```json
{
    "field": "partner_id",
    "message": "user creation is not allowed"
}
```

#### Status: 409 (Conflict)

```json
{
    "message": "A user with this phone already exists",
    "user_id": "{user_id}",
    "created_at": "{creation date and time}"
}
```

---

#### User Creation Error Codes

| Error code | Description |
| :--- | :--- |
| `400` | Bad request. Ensure all required fields are present and meet validation criteria. |
| `401` | Unauthorized. Check your API key or contact support. |
| `403` | Forbidden. Ensure the user is 18+ years old, country and state are supported, and the user has accepted the terms and conditions. |
| `409` | Conflict. A user with the same phone number may already exist. |
| `429` | Too Many Requests. Retry later. |
| `500` | Internal Server Error. |

## Card Register

Allows you to register users cards directly from your backend. This requires PCI DSS certification, please get in touch with Wert team to request this feature for your Partner ID. Only works for users who have been created by the user creation API above.

### Request Details

#### Endpoint: `POST /api/v1/partner/register`

👉 Refer to [endpoints table](https://docs.wert.io/docs/data-api#endpoint-specification) for a full link.

#### Parameters

Configure your request using the parameters below to register a card for an existing user.

| Property | Required | Validation |
| :--- | :--- | :--- |
| **card_number** | ✅ | String, 12–19 |
| **exp_month** | ✅ | 2 digits, only numbers |
| **exp_year** | ✅ | 4 digits, only numbers |
| **user_id** | ✅ | Must match an existing user in database |
| **billing_address.country** | ✅ | [alpha2](https://www.nationsonline.org/oneworld/country_code_list.htm) country code |
| **billing_address.state** | Conditional | Required for USA & Canada only; Not required for other countries; [alpha2](https://www.iso.org/obp/ui/#iso:code:3166:US) state code |
| **billing_address.postal_code** | ✅ | 2–10 characters; `^[a-zA-Z0-9[:space:]-]*`; Character “-” is allowed |
| **billing_address.city** | ✅ | String, 2–25 characters; A–Z, a–z, 0–9; No special or non-English characters; Cannot be all numeric |
| **billing_address.street** | ✅ | String, 2–35 characters; A–Z, a–z, 0–9; No special or non-English characters; Cannot be all numeric; Spaces allowed |

---

#### Example request

Example of card data registered on behalf of an existing user.

```bash
curl --location 'https://cards.wert.io/api/v1/partner/register' \
  --header 'x-api-key: your-unique-api-key' \
  --header 'Content-Type: application/json' \
  --data '{
    "card_number": "4001590000000001",
    "exp_month": "01",
    "exp_year": "2029",
    "user_id": "{user_id}",
    "billing_address": {
      "country": "AD",
      "postal_code": "11111",
      "city": "City",
      "street": "Street house number 6"
    }
  }'
```

### Response Details

Possible responses from Card Register endpoint.

#### Status: 200 (OK)

```json
{
  "card_id": "string"
}
```

#### Status: 400 (Bad Request)

##### Card details validation

```json
{
  "status": "error",
  "error_description": "Invalid card"
}
```

```json
{
  "status": "error",
  "error_description": "Invalid exp month"
}
```

```json
{
  "status": "error",
  "error_description": "Invalid year"
}
```

```json
{
  "status": "error",
  "error_description": "Card expired"
}
```

##### Billing address & business validation

```json
{
  "code": 121,
  "status": "error",
  "error_description": "invalid billing address information",
  "request_id": "string"
}
```

```json
{
  "code": 109,
  "status": "error",
  "error_description": "attempt to register more cards than allowed"
}
```

```json
{
  "code": 113,
  "status": "error",
  "error_description": "card already registered"
}
```

```json
{
  "code": 309,
  "status": "error",
  "error_description": "user not found"
}
```

```json
{
  "code": 310,
  "status": "error",
  "error_description": "user banned"
}
```

#### Status: 403 (Forbidden)

```json
{
  "code": 1022,
  "status": "error",
  "error_description": "restricted action"
}
```

```json
{
  "code": 1023,
  "status": "error",
  "error_description": "partner not allowed"
}
```

```json
{
  "code": 9002,
  "status": "error",
  "error_description": "invalid partner key"
}
```

```json
{
  "code": 1006,
  "status": "error",
  "error_description": "partner is blocked"
}
```

---

## SOURCE: Reference/webhooks.md

To receive notifications about various events undertaken by the user while they use the widget, you will need to set up an endpoint that accepts payloads sent by Wert. Your endpoint will receive **POST** requests with **content-type application/json**.

> **📘 Info**
>
> While it’s not common, **webhooks can fail**, and we don’t recommend that any of our partners rely solely on them. You have access to on-chain data, and we have [listeners](https://docs.wert.io/docs/listerners-object) and the [data API](https://docs.wert.io/docs/data-api); **you should have redundancy in these situations.**

> **❗️ Error**
>
> We require your webhook server to return HTTP **2xx** status on **ALL** received events. Any other HTTP status code like (4xx or 5xx) will be treated as **NOT** received and will automatically disable webhooks to your server. Please do not return any other HTTP status code that is related to your internal server side logic.
>
> Webhook responses (**2xx**) must be sent within 5 seconds. To ensure stability, your endpoint should be asynchronous. Instead of processing data synchronously, your server should return a 2xx status first and handle the internal logic separately. Any delay beyond 5 seconds (Status Code **0**) will be treated as a failure and lead to automatic disabling of your webhooks.
>
> The system will make **5 retries** of a failed webhook (non-2xx response) at intervals of **5m, 1h, 2h, 4h, and 8h**. If all 5 retries fail, webhook delivery to your site will be **disabled** until manually re-enabled.
>
> You may re-enable webhook sending at [https://partner.wert.io](https://partner.wert.io) or [https://partner-sandbox.wert.io](https://partner-sandbox.wert.io).

# Configuring the webhook endpoint

The webhook endpoint can be set up on `Partner Dashboard -> Webhooks -> Webhook URL`. Make sure you save the endpoint by clicking “Save”.

From this page, you will also be able to see a log of all events that have been sent.

# Wert module lifecycle

To get an overview of the entire module, the actions that can lead to certain events occurring, and further details for each transaction status, please see this graphic:

![Wert module lifecycle](https://files.readme.io/1edff52829215701e4cd386dcb0d7d635b90d05ad3194446575951961e4e2684-Webhooks_1.png)

# Events

The following events are available:

> **📘 Info**
>
> Be sure to click on each event to see the respective return data.

### Registration Event

> **📘 Info**
>
> Triggered when a new user on your website creates a new Wert profile.

#### Fiat OnRamp Order

```json
{
  "type": "registration",
  "click_id": "click_id",
  "hpp_session_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "initiated"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "registration",
  "click_id": "click_id",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "initiated"
      }
    }
  }
}
```

### Login Event

> **📘 Info**
>
> Triggered when an existing user logs into Wert on your website.

#### Fiat OnRamp Order

```json
{
  "type": "login",
  "click_id": "click_id",
  "hpp_session_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "initiated"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "login",
  "click_id": "click_id",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "initiated"
      }
    }
  }
}
```

### Logout Event

> **📘 Info**
>
> Triggered when an existing user logs out of Wert on your website.

#### Fiat OnRamp Order

```json
{
  "type": "logout",
  "click_id": "click_id",
  "hpp_session_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "initiated"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "logout",
  "click_id": "click_id",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "initiated"
      }
    }
  }
}
```

### Card Added Event

> **📘 Info**
>
> Triggered when a user adds a new bank card.

#### Fiat OnRamp Order

```json
{
  "type": "card_added",
  "click_id": "click_id",
  "hpp_session_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "initiated"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "card_added",
  "click_id": "click_id",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "initiated"
      }
    }
  }
}
```

### Verify Start Event

> **📘 Info**
>
> Triggered when a user starts the verification process.

#### Fiat OnRamp Order

```json
{
  "type": "verify_start",
  "click_id": "click_id",
  "hpp_session_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "verify_start",
  "click_id": "click_id",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

### Verify Retry Event

> **📘 Info**
>
> Triggered when a user needs to re-upload documents to finish verification.

#### Fiat OnRamp Order

```json
{
  "type": "verify_retry",
  "click_id": "click_id",
  "hpp_session_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "retry"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "verify_retry",
  "click_id": "click_id",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "retry"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

### Verify Failed Event

> **📘 Info**
>
> Triggered when a user needs to re-upload documents to finish verification.

#### Fiat OnRamp Order

```json
{
  "type": "verify_failed",
  "reject_type": "<REJECT_TYPE_ENUM>",
  "click_id": "click_id",
  "hpp_session_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "failed"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "verify_failed",
  "reject_type": "<REJECT_TYPE_ENUM>",
  "click_id": "click_id",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "initiated"
      },
      "lkyc": {
        "state": "failed"
      }
    }
  }
}
```

#### Rejection Types (`REJECT_TYPE_ENUM`)

| Rejection Category | Rejection Type Value | Description |
| :--- | :--- | :--- |
| **LKYC Age** | `LKYC_FAILED_AGE` | User does not meet the age requirement for LKYC. |
| **FKYC Age** | `FKYC_FAILED_AGE` | User does not meet the age requirement for FKYC. |
| **LKYC Country** | `LKYC_FAILED_UNSUPPORTED_COUNTRY` | User's country is not supported for LKYC. |
| **FKYC Country** | `FKYC_FAILED_UNSUPPORTED_COUNTRY` | User's country is not supported for FKYC. |
| **LKYC State** | `LKYC_FAILED_UNSUPPORTED_STATE` | User's specific state/region is not supported for LKYC. |
| **FKYC State** | `FKYC_FAILED_UNSUPPORTED_STATE` | User's specific state/region is not supported for FKYC. |
| **LKYC Duplicate** | `LKYC_FAILED_DUPLICATE` | An existing LKYC record already exists for this user. |
| **FKYC Duplicate** | `FKYC_FAILED_DUPLICATE` | An existing FKYC record already exists for this user. |
| **LKYC General** | `LKYC_FAILED_GENERAL` | Generic failure for LKYC that does not fall under specific categories. |
| **FKYC General** | `FKYC_FAILED_GENERAL` | Generic failure for FKYC that does not fall under specific categories. |
| **FKYC Spam** | `FKYC_FAILED_SPAM` | FKYC attempt flagged as spam or fraudulent activity. |

### Verify Success Event

> **📘 Info**
>
> Triggered when a user successfully passes KYC verification.

#### Fiat OnRamp Order

```json
{
  "type": "verify_success",
  "click_id": "click_id",
  "hpp_session_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "success"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "verify_success",
  "click_id": "click_id",
  "user": {
    "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
    "verification_status": {
      "fkyc": {
        "state": "success"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

### Payment Started Event

> **📘 Info**
>
> Triggered when a user initiates a purchase (pressed “Confirm and Pay”), and a request was sent to the payment acquirer.

#### Fiat OnRamp Order

```json
{
  "type": "payment_started",
  "click_id": "click_id",
  "hpp_session_id": "378dbbf4-4c8c-4520-bdc7-d50da9a9486e",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": null,
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "payment_started",
  "click_id": "click_id",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": null,
    "partner_data": {
      "sc_address": "0x4d6F96ACc38576de63b353455aC110FafF9bC93D",
      "sc_input_data": "0xd095362f0000690d4c21a2c288a6877d048c05b0b1805c322"
    },
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

### Order Complete Event

> **📘 Info**
>
> Triggered when an order receives “Success” status.
>
> For further details on order statuses, see the [lifecycle diagram](https://docs.wert.io/docs/webhooks#wert-module-lifecycle).

#### Fiat OnRamp Order

```json
{
  "type": "order_complete",
  "click_id": "click_id",
  "hpp_session_id": "378dbbf4-4c8c-4520-bdc7-d50da9a9486e",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": "0xbc3e65059d975ee06ef1b61f668eb5a10fcce148881631dba03",
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "order_complete",
  "click_id": "click_id",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": "0xbc3e65059d975ee06ef1b61f668eb5a10fcce148881631dba03",
    "partner_data": {
      "sc_address": "0x4d6F96ACc38576de63b353455aC110FafF9bC93D",
      "sc_input_data": "0xd095362f0000690d4c21a2c288a6877d048c05b0b1805c322"
    },
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

### Order Failed Event

> **📘 Info**
>
> An order receives “Failed” status.
>
> For further details on order statuses, see the [lifecycle diagram](https://docs.wert.io/docs/webhooks#wert-module-lifecycle).

#### Fiat OnRamp Order

```json
{
  "type": "order_failed",
  "click_id": "click_id",
  "hpp_session_id": "378dbbf4-4c8c-4520-bdc7-d50da9a9486e",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": null,
    "error_code": "Contact bank",
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "order_failed",
  "click_id": "click_id",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": null,
    "partner_data": {
      "sc_address": "0x4d6F96ACc38576de63b353455aC110FafF9bC93D",
      "sc_input_data": "0xd095362f0000690d4c21a2c288a6877d048c05b0b1805c322"
    },
    "error_code": "Contact bank",
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

### Order Cancelled Event

> **📘 Info**
>
> Triggered when an order receives “Cancelled” status.
>
> For further details on order statuses, see the [lifecycle diagram](https://docs.wert.io/docs/webhooks#wert-module-lifecycle).

#### Fiat OnRamp Order

```json
{
  "type": "order_cancelled",
  "click_id": "click_id",
  "hpp_session_id": "378dbbf4-4c8c-4520-bdc7-d50da9a9486e",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": null,
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "order_cancelled",
  "click_id": "click_id",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": null,
    "partner_data": {
      "sc_address": "0x4d6F96ACc38576de63b353455aC110FafF9bC93D",
      "sc_input_data": "0xd095362f0000690d4c21a2c288a6877d048c05b0b1805c322"
    },
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

### Transfer Started Event

> **⚠️ Warning**
>
> Triggered after 1 network/block confirmation.

#### Fiat OnRamp Order

```json
{
  "type": "transfer_started",
  "click_id": "click_id",
  "hpp_session_id": "378dbbf4-4c8c-4520-bdc7-d50da9a9486e",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": "0xbc3e65059d975ee06ef1b61f668eb5a10fcce148881631dba03",
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

#### NFT Checkout Order

```json
{
  "type": "transfer_started",
  "click_id": "click_id",
  "order": {
    "id": "01K8VRXKKFDXP63RM1R6XPF0ZX",
    "base": "USDC",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": "0xbc3e65059d975ee06ef1b61f668eb5a10fcce148881631dba03",
    "partner_data": {
      "sc_address": "0x4d6F96ACc38576de63b353455aC110FafF9bC93D",
      "sc_input_data": "0xd095362f0000690d4c21a2c288a6877d048c05b0b1805c322"
    },
    "external_order_id": "62no2X"
  },
  "user": {
    "user_id": "01K8K85AR99RMBCCSRM25Z6X9H",
    "verification_status": {
      "fkyc": {
        "state": "progress"
      },
      "lkyc": {
        "state": "success"
      }
    }
  }
}
```

### Test Event

> **📘 Info**
>
> Triggered by providing a callback URL in the Partner Account/Webhooks tab and pressed “Test” to receive a test webhook.

```json
{
  "type": "test",
  "click_id": "test_click_id",
  "order": {
    "id": "",
    "base": "POL",
    "base_amount": "21.91339134",
    "quote": "EUR",
    "quote_amount": "20",
    "address": "0x3833b0d65412268d3C06C1a860462AEE96552cD8",
    "transaction_id": "0xbc3e65059d975ee06ef1b61f668eb5a10fcce148881631dba03"
  }
}
```

### OTP Status Event

> **📘 Info**
>
> Triggered when a user requests an SMS verification code. Fires once when the code is requested, and again when the send succeeds or fails.
>
> Each tap on "Send code" produces **its own sequence** (typically `requested` → `success`, or `requested` → `failed`). Resend three times → three sequences.

#### Fiat OnRamp Order

```json
{
  "type": "otp_status",
  "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
  "click_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "phone_country_code": "US",
  "status": "requested"
}
```

```json
{
  "type": "otp_status",
  "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
  "click_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "phone_country_code": "US",
  "status": "success"
}
```

```json
{
  "type": "otp_status",
  "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
  "click_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "status": "failed",
  "status_detail": "The phone number is not assigned to a mobile line."
}
```

#### NFT Checkout Order

```json
{
  "type": "otp_status",
  "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
  "click_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "phone_country_code": "US",
  "status": "requested"
}
```

```json
{
  "type": "otp_status",
  "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
  "click_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "phone_country_code": "US",
  "status": "success"
}
```

```json
{
  "type": "otp_status",
  "user_id": "01K8W7CY66TG9YYJQ14EGTDSCQ",
  "click_id": "b4e0c295-5379-480c-bdba-c2183992e44c",
  "status": "failed",
  "status_detail": "The phone number is not assigned to a mobile line; Prelude only supports mobile numbers."
}
```

#### Payload fields

| Field | Required | Description |
| :--- | :--- | :--- |
| `type` | Always | Fixed string: `otp_status`. |
| `user_id` | Always | Wert user ULID. |
| `click_id` | Always | Click ID from the widget session. Empty string if not set. |
| `phone_country_code` | When available | ISO 3166-1 alpha-2 country code. Omitted if the phone country couldn't be resolved. |
| `status` | Always | One of: `requested`, `success`, `failed` (see below). |
| `status_detail` | On failure | Human-readable reason the OTP couldn't be sent. Not a stable enum — don't match on exact wording for automation. |

#### `status` values

| Value | Description |
| :--- | :--- |
| `requested` | User tapped "Send code" and the request was accepted. |
| `success` | SMS provider accepted the send. |
| `failed` | OTP could not be sent (invalid number, non-mobile line, provider error, etc.). Check `status_detail` for details. |

> **📘 Info**
>
> This event does not include `hpp_session_id` or a nested `user` object — it's intentionally minimal compared to other webhook events.

---

## SOURCE: Introduction/supported-coins-and-blockchains.md

# Production

| Cryptocurrency | Available networks | ‘commodity’ option | 'network' option | Supported for smart contracts | Decimal Precision |
| :--- | :--- | :--- | :--- | :--- | :--- |
| Aavegotchi | Polygon | 'GHST' | 'polygon' | Yes | 18 |
| Arbitrum | Arbitrum | 'ARB' | 'arbitrum' | Yes | 18 |
| AVAX | Avalanche | 'AVAX' | 'avalanche' | Yes | 18 |
| Binance Coin | Binance | 'BNB' | 'bsc' | Yes | 18 |
| Bitcoin | Bitcoin | 'BTC' | 'bitcoin' | No | 8 |
| Bone ShibaSwap | Shibarium | 'BONE' | 'shibarium' | Yes | 18 |
| Concordium | Concordium | 'CCD' | 'concordium' | Yes | 5 |
| cUSDT | Ethereum | 'CUSDT' | 'mainnet' | No | 6 |
| Ethereum | Ethereum Arbitrum Base Hemi | 'ETH' | 'ethereum' 'arbitrum' 'base' 'hemi' | Yes | 18 |
| EUROe | Concordium | 'EUROE' | 'mainnet' | No | 6 |
| GPRO | Polygon | 'GPRO' | 'polygon' | Yes | 18 |
| Hemi | Hemi | 'HEMI' | 'hemi' | Yes | 18 |
| LayerAI | Ethereum Binance | 'LAI' | 'ethereum' 'bsc' | No | 18 |
| LimeWire | Ethereum | 'LMWR' | 'ethereum' | Yes | 18 |
| MANA | Polygon Ethereum | 'MANA' | 'polygon' 'ethereum' | Yes | 18 |
| NEAR | Near | 'NEAR' | 'near' | Yes | 8 |
| opBNB | opBNB | 'OPBNB' | 'opbnb' | Yes | 18 |
| POL | Polygon | 'POL' | 'polygon' | Yes | 18 |
| Rootstock BTC | Rootstock | 'RBTC' | 'rootstock' | Yes | 18 |
| Stacks | Stacks | 'STX' | 'stacks' | No | 6 |
| Solana | Solana | 'SOL' | 'solana' | Yes | 9 |
| Tezos | Tezos | 'XTZ' | 'tezos' | Yes | 6 |
| Tezos | Etherlink | 'XTZ' | 'etherlink' | Yes | 18 |
| TFUEL | Theta | 'TFUEL' | 'theta' | Yes | 18 |
| TON | The Open Network | 'TON' | 'ton' | Yes | 8 |
| USDC | Arbitrum Base Ethereum Avalanche Shibarium Solana Polygon Hemi Etherlink | 'USDC' | 'arbitrum' 'base' 'ethereum' 'avalanche' 'shibarium' 'solana' 'polygon' 'hemi' 'etherlink' | Yes | 6 |
| USDSM | Etherlink | 'USDSM' | 'etherlink' | Yes | 18 |
| USDT | Polygon Ethereum Binance TON Hemi | 'USDT' | 'polygon' 'ethereum' 'bsc' 'ton' 'hemi' | Yes | 6 6 18 6 6 |
| Vyvo | Vyvo | 'VSC' | 'vyvo' | Yes | 5 |
| Wrapped Ether | Polygon | 'WETH' | 'polygon' | Yes | 18 |
| XCAD | opBNB Binance | 'XCAD' | 'opbnb' 'bsc' | Yes | 18 |

# Sandbox

| Cryptocurrency | Available networks | ‘commodity’ option | 'network' option | Decimal Precision |
| :--- | :--- | :--- | :--- | :--- |
| Binance | BSC | 'BNB' | 'bsc' | 18 |
| BONE | Puppynet | 'BONE' | 'puppynet' | 18 |
| Concordium | Concordium | 'CCD' | 'concordium' | 18 |
| cUSDC | Sepolia | 'cUSDC' | 'sepolia' | 6 |
| Ethereum | Sepolia Base Arbitrum | 'ETH' | 'sepolia' 'base_sepolia' 'arbitrum_sepolia' | 18 |
| EUROe | Concordium | 'EUROe' | 'concordium' | 18 |
| Hemi | Hemi | 'HEMI' | 'hemi' | 18 |
| POL | Amoy | 'POL' | 'amoy' | 18 |
| Solana | Solana | 'SOL' | 'solana' | 9 |
| Test Token | Amoy BSC KuCoin Base Arbitrum Sepolia opBNB Puppynet Hemi Etherlink | 'TT' | 'amoy' 'bsc' 'kucoin' 'base_sepolia' 'arbitrum_sepolia' 'sepolia' 'opbnb' 'puppynet' 'hemi' 'etherlink' | 18 |
| Test Token | Solana | 'TT' | 'solana' | 9 |
| Tezos | Ghostnet | 'XTZ' | 'ghostnet', 'etherlink' | 6 |
| opBNB | opBNB | 'opBNB' | 'opbnb' | 18 |
| USDSM | Etherlink | 'usdsm' | 'etherlink' | 18 |

## Test Token contracts

Test Token is the only ERC-20 token available in sandbox. It’s a standard ERC-20 token, which can be used to test the interaction of ERC-20 tokens against your smart contract.

If you need to acquire some Test Tokens for your own testing, you can simulate a purchase on sandbox to transfer some to you. You will not be charged for this purchase and we ask that you send the tokens back once you have finished testing.

> **ℹ️ Info**
>
> Test Token contracts are deployed at the following addresses:
>
> Arbitrum Sepolia network - `0x103EF343661335B85BE98EfEfF7f726Be7CeeeDE`
>
> Ethereum Sepolia network - `0x42D8BCf255125BB186459AF66bB74EEF8b8cC391`
>
> Polygon Amoy network - `0x834bBE71a0a5C91A4Aff10Df400A963D95AD4775`
>
> Binance Smart Chain - `0x4C07B79C3D8954A51Efc342EdA5D08f8b1f9ceC4`
>
> Base Sepolia network - `0x3bE123Ff0ec7c0717D6C05C8957EA7880e2FfDcb`
>
> Puppynet - `0x4C07B79C3D8954A51Efc342EdA5D08f8b1f9ceC4`
>
> Solana - `Hza3mZYRv7ZZw2xo1kvWvD4YXLnhA47JtTZBhgr8LTU7`
>
> Hemi - `0x33e8Bf90e1aafcE42490e05880810f6d09699e02`
````

<br />