Skip to Content

Settings

GET/settings

Description

Retrieve your business configuration: business mode (test or live), per-chain signer status, and the addresses you need to integrate, including your PaymentFactory address (required to sign direct payments) and your settlement address.

These values are stable. Fetch them once and store them with your config. You can also view them in your dashboard.

Headers

HeaderDescriptionRequired
AuthorizationBearer token with your API key. Required for API key authentication; omit when using dashboard session cookies.no

Example Request

const response = await fetch('https://checkout-api.exodus-int.com/settings', {
  headers: {
    Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
  },
});
 
const settings = await response.json();

Response

SUCCESSFUL RESPONSE
{
  "business_id": "biz_1234567890abcdef",
  "business_name": "Acme Store",
  "is_test": false,
  "settlement_type": "CRYPTO",
  "currency": null,
  "settlement_provider": null,
  "settlement_provider_id": null,
  "can_generate_key": false,
  "webhook_url": "https://yoursite.com/webhooks/exodus",
  "chain_configs": [
    {
      "chain_family": "evm",
      "signer_status": "active",
      "merchant_signer": "0x1234abcd1234abcd1234abcd1234abcd1234abcd",
      "settlement_address": "0xabcd1234abcd1234abcd1234abcd1234abcd1234",
      "factory_address": "0xfaceb00cfaceb00cfaceb00cfaceb00cfaceb00c"
    },
    {
      "chain_family": "solana",
      "signer_status": "active",
      "merchant_signer": "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",
      "settlement_address": "5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
      "factory_address": null
    }
  ]
}

Response Fields

FieldTypeDescription
business_idstringYour business identifier.
business_namestringYour business name.
is_testbooleantrue for a test business (testnets), false for a live business (mainnet).
settlement_typestring'CRYPTO' or 'FIAT'. How settlements are made for this business.
currencystring | nullSettlement currency. null for crypto settlement.
settlement_providerstring | nullThe settlement provider used for this business. null for crypto settlement.
settlement_provider_idstring | nullYour identifier with the settlement provider. null for crypto settlement.
can_generate_keybooleanWhether you can still generate a signing key for this business.
webhook_urlstring | nullThe configured webhook endpoint URL that receives event deliveries. null when webhooks are not configured.
chain_configsarrayOne entry per chain family (evm, solana).
chain_configs[].chain_familystring'evm' or 'solana'.
chain_configs[].signer_statusstring'not_configured', 'pending_activation', or 'active'. The addresses below are filled in as the config progresses to active.
chain_configs[].merchant_signerstring | nullThe signing-key address registered for this chain family.
chain_configs[].settlement_addressstring | nullWhere settled funds are sent for this chain family.
chain_configs[].factory_addressstring | nullEVM only: your PaymentFactory address, needed to sign direct payments. null until the config is active; always null for Solana (program-bound).

POST/settings

Register a merchant signer

Register the merchant signer and settlement address for a chain family, activating signed-request verification for that chain. Both addresses must be valid for the chosen chain family. Returns 201 with the updated merchant settings.

Headers

HeaderDescriptionRequired
AuthorizationBearer token with your API key. Required for API key authentication; omit when using dashboard session cookies.no
Content-Typeapplication/jsonyes

Body

FieldTypeDescription
merchant_signerstringRequired. The signing-key address. Must be a valid address for the chain family.
chain_familystring'evm' or 'solana'. Defaults to 'evm'.
settlement_addressstringRequired. Where settled funds are sent. Must be a valid address for the chain family.

Example Request

const response = await fetch('https://checkout-api.exodus-int.com/settings', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    merchant_signer: '0x1234abcd1234abcd1234abcd1234abcd1234abcd',
    chain_family: 'evm',
    settlement_address: '0xabcd1234abcd1234abcd1234abcd1234abcd1234',
  }),
});
 
const settings = await response.json();

Response

SUCCESSFUL RESPONSE
{
  "business_id": "biz_1234567890abcdef",
  "business_name": "Acme Store",
  "is_test": false,
  "settlement_type": "CRYPTO",
  "currency": null,
  "settlement_provider": null,
  "settlement_provider_id": null,
  "can_generate_key": false,
  "webhook_url": "https://yoursite.com/webhooks/exodus",
  "chain_configs": [
    {
      "chain_family": "evm",
      "signer_status": "active",
      "merchant_signer": "0x1234abcd1234abcd1234abcd1234abcd1234abcd",
      "settlement_address": "0xabcd1234abcd1234abcd1234abcd1234abcd1234",
      "factory_address": "0xfaceb00cfaceb00cfaceb00cfaceb00cfaceb00c"
    }
  ]
}

The response body matches the GET /settings response shape. See its Response Fields for a full description.

Returns 400 with error.type "validation_error" if merchant_signer or settlement_address is missing, or is not a valid address for the chosen chain_family.


PUT/settings

Update the settlement address

Update the settlement address for a chain family. New captures settle to the updated address. The address must be valid for the chosen chain family. Returns 200 with the updated merchant settings.

Headers

HeaderDescriptionRequired
AuthorizationBearer token with your API key. Required for API key authentication; omit when using dashboard session cookies.no
Content-Typeapplication/jsonyes

Body

FieldTypeDescription
chain_familystringRequired. 'evm' or 'solana'.
settlement_addressstringRequired. Where settled funds are sent. Must be a valid address for the chain family.

Example Request

const response = await fetch('https://checkout-api.exodus-int.com/settings', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    chain_family: 'evm',
    settlement_address: '0xabcd1234abcd1234abcd1234abcd1234abcd1234',
  }),
});
 
const settings = await response.json();

Response

SUCCESSFUL RESPONSE
{
  "business_id": "biz_1234567890abcdef",
  "business_name": "Acme Store",
  "is_test": false,
  "settlement_type": "CRYPTO",
  "currency": null,
  "settlement_provider": null,
  "settlement_provider_id": null,
  "can_generate_key": false,
  "webhook_url": "https://yoursite.com/webhooks/exodus",
  "chain_configs": [
    {
      "chain_family": "evm",
      "signer_status": "active",
      "merchant_signer": "0x1234abcd1234abcd1234abcd1234abcd1234abcd",
      "settlement_address": "0xabcd1234abcd1234abcd1234abcd1234abcd1234",
      "factory_address": "0xfaceb00cfaceb00cfaceb00cfaceb00cfaceb00c"
    }
  ]
}

The response body matches the GET /settings response shape. See its Response Fields for a full description.

Returns 400 with error.type "validation_error" if chain_family or settlement_address is missing, or the address is not valid for the chosen chain_family.


PATCH/settings

Update the webhook URL

Set or update the webhook endpoint URL that receives event deliveries. Pass null to disable webhooks. Omitting webhook_url from the body returns the currently configured URL without changing it.

The webhook signing secret is generated automatically the first time you configure a webhook URL. On that first-time generation the response also includes webhook_secret, shown in full only in that response — store it securely. Subsequent updates to the URL do not return the secret and do not change it; use POST /settings/webhook/secret to rotate it.

Headers

HeaderDescriptionRequired
AuthorizationBearer token with your API key. Required for API key authentication; omit when using dashboard session cookies.no
Content-Typeapplication/jsonyes

Body

FieldTypeDescription
webhook_urlstring | nullOptional. The webhook endpoint URL. Pass null to disable webhooks. Omit to leave the current URL unchanged.

Example Request

const response = await fetch('https://checkout-api.exodus-int.com/settings', {
  method: 'PATCH',
  headers: {
    Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    webhook_url: 'https://yoursite.com/webhooks/exodus',
  }),
});
 
const { webhook_url, webhook_secret } = await response.json();

Response

SUCCESSFUL RESPONSE
{
  "webhook_url": "https://yoursite.com/webhooks/exodus",
  "webhook_secret": "9f8c7b6a5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b"
}

Response Fields

FieldTypeDescription
webhook_urlstring | nullThe configured webhook URL. null when webhooks are disabled.
webhook_secretstringThe webhook signing secret. Only present when a secret is generated for the first time. Shown in full only in this response, so store it securely.

Returns 400 with error.type "validation_error" if webhook_url is not a reachable, valid URL.


POST/settings/webhook/secret

Regenerate the webhook secret

Issue a new webhook signing secret. Rotation is zero-downtime: your previous secret keeps working for 24 hours, so deliveries never fail while you roll out the new one. During that window every event is signed with both secrets, so an endpoint validating against either keeps accepting events. previous_secret_expires_at in the response tells you when the old secret stops working. See Rotating your webhook secret for the full flow.

Your webhook secret is otherwise stable. It is generated once when you first configure a webhook URL and does not change when you update the URL, so call this only when you intend to rotate it. A webhook URL must be configured first.

Headers

HeaderDescriptionRequired
AuthorizationBearer token with your API key. Required for API key authentication; omit when using dashboard session cookies.no

Example Request

const response = await fetch(
  'https://checkout-api.exodus-int.com/settings/webhook/secret',
  {
    method: 'POST',
    headers: {
      Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
    },
  },
);
 
const { webhook_secret, previous_secret_expires_at } = await response.json();

Response

SUCCESSFUL RESPONSE
{
  "webhook_secret": "9f8c7b6a5e4d3c2b1a0f9e8d7c6b5a4f3e2d1c0b9a8f7e6d5c4b3a2f1e0d9c8b",
  "previous_secret_expires_at": "2026-07-02T00:00:00.000Z"
}

Response Fields

FieldTypeDescription
webhook_secretstringThe new signing secret. Shown in full only in this response, so store it securely.
previous_secret_expires_atstring | nullISO 8601 timestamp when the previous secret stops being accepted (24 hours after rotation). During this window events are signed with both secrets. null when there was no previous secret to keep alive, for example the first time a secret is issued.

Returns 422 with error.type "cannot_process" and error.code "webhook_not_configured" if no webhook URL is configured for the business.


POST/settings/webhook/test

Send a test webhook

Deliver a sample event to your configured webhook URL so you can confirm the endpoint is reachable and your signature verification works. The delivery is synchronous and is not recorded in your webhook history.

The test payload is a regular subscription.charge_succeeded event filled with placeholder data, signed with your real webhook secret. It carries a top-level "livemode": false field that marks it as a test; this field is test-only and does not appear on live events. A webhook URL must be configured first.

Headers

HeaderDescriptionRequired
AuthorizationBearer token with your API key. Required for API key authentication; omit when using dashboard session cookies.no

Example Request

const response = await fetch(
  'https://checkout-api.exodus-int.com/settings/webhook/test',
  {
    method: 'POST',
    headers: {
      Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
    },
  },
);
 
const result = await response.json();

Response

SUCCESSFUL RESPONSE
{
  "object": "webhook_test",
  "delivered": true,
  "status": 200
}

delivered is true when your endpoint returned a 2xx status. If it returned another status, delivered is false and status carries the code your endpoint returned. If your endpoint could not be reached, delivered is false and error describes the failure. Returns 422 with error.type "cannot_process" and error.code "webhook_not_configured" if no webhook URL is configured.

Response Fields

FieldTypeDescription
objectstringAlways 'webhook_test'.
deliveredbooleanWhether your endpoint accepted the test delivery (2xx response).
statusnumberThe HTTP status your endpoint returned. Only present when a response was received.
errorstringDescribes the failure. Only present when the endpoint could not be reached.

Start building

XO

Request Demo

Schedule a call with our team

Select a product
Arrow right

Start building
Grateful

Contact Us

We're here to help