Skip to main content
This guide walks you through the basics of accepting USDC on your site or in your app with Managed Payments stablecoin payins. You create payment intents, show a deposit address, your customer sends USDC, and Circle links the onchain payment to your intent. The steps use a continuous payment intent, which is the default pattern and fits a stable receive address per merchant or sub-wallet.
The alternative Quickstart: Crypto Deposits walkthrough covers a transient payment intent instead (amount and time window set on create). Use that guide when you want a one-time, expiring checkout-style intent.

Prerequisites

Before you start, ensure you have:
  • Aligned with Circle on your Managed Payments onboarding model (Direct or Intermediary).
  • Completed Managed Payments onboarding, depending on your preferred model, with Circle and have API credentials for the environment you target. The cURL examples use the sandbox host api-sandbox.circle.com.
  • Roles that allow creating and reading payment intents and payments in your setup. Circle assigns roles during onboarding.
  • Sub-wallets or any other structure your setup requires so each continuous intent ties to the right merchant or segment. See Managed Payments and the Stablecoin Accounts API if you create accounts first.
  • (Optional) A webhook receiver or queue to handle payment intent and payment events. Follow the notifications quickstart.
  • (Optional) For an end-to-end test, a payer wallet with USDC and native gas on the chain you set on the intent (for example Sepolia ETH when the intent uses an Ethereum test chain).

Sequence diagram

Continuous payins use settlement currency and chain on create; you may see active instead of pending when the address is ready.

Steps

  1. Set up payment intent to pay with stablecoin
  2. Acquire blockchain address customer will pay to
  3. Customer pays
  4. Receive payment

1. Pay with stablecoin

Once the customer reaches checkout and confirms they would like to pay with USDC on Ethereum, your system sends Circle a request to create a payment intent. In this continuous payment intent you specify the settlement currency and chain (no fixed charge amount on create). Create a payment intent:
curl --location --request POST 'https://api-sandbox.circle.com/v1/paymentIntents' \
--header 'X-Requested-Id: ${GUID}' \
--header 'Authorization: Bearer ${YOUR_API_KEY}' \
--header 'Content-Type: application/json' \
--data-raw '{
  "idempotencyKey": "17607606-e383-4874-87c3-7e46a5dc03dd",
  "settlementCurrency": "USD",
  "paymentMethods": [
    {
      "type": "blockchain",
      "chain": "ETH"
    }
  ]
}'
Response
{
  "data": {
    "type": "continuous",
    "id": "e7b49cb6-1f78-4a0f-8fd6-35fc74dca335",
    "amountPaid": {
      "amount": "0.00",
      "currency": "USD"
    },
    "amountRefunded": {
      "amount": "0.00",
      "currency": "USD"
    },
    "settlementCurrency": "USD",
    "paymentMethods": [
      {
        "type": "blockchain",
        "chain": "ETH"
      }
    ],
    "timeline": [
      {
        "status": "created",
        "time": "2026-03-23T17:41:19.986668Z"
      }
    ],
    "createDate": "2026-03-23T17:41:19.979669Z",
    "updateDate": "2026-03-23T17:41:19.979669Z",
    "merchantWalletId": "1000700366",
    "currency": "USD"
  }
}
Webhook notification
{
  "clientId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291",
  "notificationType": "paymentIntents",
  "version": 1,
  "customAttributes": {
    "clientId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291"
  },
  "paymentIntent": {
    "type": "continuous",
    "id": "e7b49cb6-1f78-4a0f-8fd6-35fc74dca335",
    "amountPaid": {
      "amount": "0.00",
      "currency": "USD"
    },
    "amountRefunded": {
      "amount": "0.00",
      "currency": "USD"
    },
    "settlementCurrency": "USD",
    "paymentMethods": [
      {
        "type": "blockchain",
        "chain": "ETH"
      }
    ],
    "timeline": [
      {
        "status": "created",
        "time": "2026-03-23T17:41:19.986668Z"
      }
    ],
    "createDate": "2026-03-23T17:41:19.979669Z",
    "updateDate": "2026-03-23T17:41:19.979669Z",
    "merchantWalletId": "12345",
    "currency": "USD"
  }
}

2. Acquire blockchain address customer will pay to

For security reasons, the API does not return the deposit blockchain address in the create response. To retrieve the blockchain deposit address, you have two options:
  1. Subscribe to webhook notifications
  2. Poll Circle APIs

Option 1: Webhook notification

To receive webhook notifications, follow the steps in the notifications quickstart. After you subscribe to notifications, you receive updates for the payment intent whenever the resource is updated. In this case, when the paymentMethods.address is set, a notification is sent with a new timeline object with a status of active.
Payment intent webhook notification
{
  "clientId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291",
  "notificationType": "paymentIntents",
  "version": 1,
  "customAttributes": {
    "clientId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291"
  },
  "paymentIntent": {
    "type": "continuous",
    "id": "e7b49cb6-1f78-4a0f-8fd6-35fc74dca335",
    "amountPaid": {
      "amount": "0.00",
      "currency": "USD"
    },
    "amountRefunded": {
      "amount": "0.00",
      "currency": "USD"
    },
    "settlementCurrency": "USD",
    "paymentMethods": [
      {
        "type": "blockchain",
        "chain": "ETH",
        "address": "0xfd5a9f666d96022d13a73e3638fb7ec958696fbe"
      }
    ],
    "fees": [
      {
        "type": "blockchainLeaseFee",
        "amount": "0.00",
        "currency": "USD"
      }
    ],
    "timeline": [
      {
        "status": "active",
        "time": "2026-03-23T17:41:23.450386Z"
      },
      {
        "status": "created",
        "time": "2026-03-23T17:41:19.986668Z"
      }
    ],
    "createDate": "2026-03-23T17:41:19.979669Z",
    "updateDate": "2026-03-23T17:41:23.405690Z",
    "merchantWalletId": "12345",
    "currency": "USD"
  }
}

Option 2: Poll payment intent endpoint

If you prefer to poll get a payment intent, send GET requests until you receive paymentMethods.address. Retrieve payment intent:
curl --location --request GET 'https://api-sandbox.circle.com/v1/paymentIntents/{id}' \
--header 'X-Requested-Id: ${GUID}' \
--header 'Authorization: Bearer ${YOUR_API_KEY}'
Response
{
  "data": {
    "type": "continuous",
    "id": "e7b49cb6-1f78-4a0f-8fd6-35fc74dca335",
    "amountPaid": {
      "amount": "0.00",
      "currency": "USD"
    },
    "amountRefunded": {
      "amount": "0.00",
      "currency": "USD"
    },
    "settlementCurrency": "USD",
    "paymentMethods": [
      {
        "type": "blockchain",
        "chain": "ETH",
        "address": "0xfd5a9f666d96022d13a73e3638fb7ec958696fbe"
      }
    ],
    "fees": [
      {
        "type": "blockchainLeaseFee",
        "amount": "0.00",
        "currency": "USD"
      }
    ],
    "timeline": [
      {
        "status": "active",
        "time": "2026-03-23T17:41:23.450386Z"
      },
      {
        "status": "created",
        "time": "2026-03-23T17:41:19.986668Z"
      }
    ],
    "createDate": "2026-03-23T17:41:19.979669Z",
    "updateDate": "2026-03-23T17:41:23.405690Z",
    "merchantWalletId": "12345",
    "currency": "USD"
  }
}

3. Enable customer payment

Once you receive the deposit address via paymentMethods.address, share it with the customer so they can send funds on the correct chain.
A continuous payment intent doesn’t define a fixed amount on create; you communicate any specific charge (for example an invoice total) from your own checkout or UI.
You can present the address two ways:
  1. as plain text the customer can cut and paste; or
  2. as a QR code the customer can scan via an app.
The customer then sends payment from their wallet (custodial or non-custodial).
When using transient payment intents, you can set a time frame in which the customer must send payment by adjusting the expiresOn setting.

4. Receive payment from Circle

Once Circle obtains payment onchain, Circle creates a Payment resource linked to the Payment Intent created earlier and updates the status of that Payment Intent. Your firm will then receive payment via the method specified.

Option 1: Webhook notifications

Payment intent webhook notification
{
  "clientId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291",
  "notificationType": "paymentIntents",
  "version": 1,
  "customAttributes": {
    "clientId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291"
  },
  "paymentIntent": {
    "type": "continuous",
    "id": "e7b49cb6-1f78-4a0f-8fd6-35fc74dca335",
    "amountPaid": {
      "amount": "5.00",
      "currency": "USD"
    },
    "amountRefunded": {
      "amount": "0.00",
      "currency": "USD"
    },
    "settlementCurrency": "USD",
    "paymentMethods": [
      {
        "type": "blockchain",
        "chain": "ETH",
        "address": "0xfd5a9f666d96022d13a73e3638fb7ec958696fbe"
      }
    ],
    "fees": [
      {
        "type": "blockchainLeaseFee",
        "amount": "0.00",
        "currency": "USD"
      },
      {
        "type": "totalPaymentFees",
        "amount": "0.00",
        "currency": "USD"
      }
    ],
    "timeline": [
      {
        "status": "active",
        "time": "2026-03-23T17:41:23.450386Z"
      },
      {
        "status": "created",
        "time": "2026-03-23T17:41:19.986668Z"
      }
    ],
    "createDate": "2026-03-23T17:41:19.979669Z",
    "updateDate": "2026-03-23T17:52:18.080633Z",
    "merchantWalletId": "12345",
    "currency": "USD"
  }
}
Payment webhook notification
{
  "clientId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291",
  "notificationType": "payments",
  "version": 1,
  "customAttributes": {
    "clientId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291"
  },
  "payment": {
    "id": "021ff661-e7d5-332f-bb9c-e43870608f26",
    "type": "payment",
    "status": "pending",
    "amount": {
      "amount": "5.00",
      "currency": "USD"
    },
    "createDate": "2026-03-23T17:49:54.197Z",
    "updateDate": "2026-03-23T17:49:54.259Z",
    "merchantId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291",
    "merchantWalletId": "12345",
    "paymentIntentId": "e7b49cb6-1f78-4a0f-8fd6-35fc74dca335",
    "fromAddresses": {
      "chain": "ETH",
      "addresses": ["0x6dbe810e3314546009bd6e1b29f9031211cda5d2"]
    },
    "depositAddress": {
      "chain": "ETH",
      "address": "0xfd5a9f666d96022d13a73e3638fb7ec958696fbe"
    },
    "transactionHash": "0xfbc0f1c8256af3453fd3be7a1491e3581e072022a29ffc78cf129a662182305e"
  }
}

Option 2: Retrieve payment intent and payment

Retrieve a payment intent:
curl --location --request GET 'https://api-sandbox.circle.com/v1/paymentIntents/{id}' \
--header 'X-Requested-Id: ${GUID}' \
--header 'Authorization: Bearer ${YOUR_API_KEY}'
Response
{
  "data": {
    "type": "continuous",
    "id": "e7b49cb6-1f78-4a0f-8fd6-35fc74dca335",
    "amountPaid": {
      "amount": "5.00",
      "currency": "USD"
    },
    "amountRefunded": {
      "amount": "0.00",
      "currency": "USD"
    },
    "settlementCurrency": "USD",
    "paymentMethods": [
      {
        "type": "blockchain",
        "chain": "ETH",
        "address": "0xfd5a9f666d96022d13a73e3638fb7ec958696fbe"
      }
    ],
    "fees": [
      {
        "type": "blockchainLeaseFee",
        "amount": "0.00",
        "currency": "USD"
      },
      {
        "type": "totalPaymentFees",
        "amount": "0.00",
        "currency": "USD"
      }
    ],
    "timeline": [
      {
        "status": "active",
        "time": "2026-03-23T17:41:23.450386Z"
      },
      {
        "status": "created",
        "time": "2026-03-23T17:41:19.986668Z"
      }
    ],
    "createDate": "2026-03-23T17:41:19.979669Z",
    "updateDate": "2026-03-23T17:52:18.080633Z",
    "merchantWalletId": "12345",
    "currency": "USD"
  }
}
Retrieve a payment:
curl --location --request GET 'https://api-sandbox.circle.com/v1/payments/{id}' \
--header 'X-Requested-Id: ${GUID}' \
--header 'Authorization: Bearer ${YOUR_API_KEY}'
Response
{
  "data": {
    "id": "021ff661-e7d5-332f-bb9c-e43870608f26",
    "type": "payment",
    "status": "paid",
    "amount": {
      "amount": "5.00",
      "currency": "USD"
    },
    "fees": {
      "amount": "0.00",
      "currency": "USD"
    },
    "createDate": "2026-03-23T17:49:54.197184Z",
    "updateDate": "2026-03-23T17:52:17.910610Z",
    "merchantId": "5b057f1e-743c-4aeb-beeb-ef7b2e16f291",
    "merchantWalletId": "12345",
    "paymentIntentId": "e7b49cb6-1f78-4a0f-8fd6-35fc74dca335",
    "settlementAmount": {
      "amount": "5.00",
      "currency": "USD"
    },
    "fromAddresses": {
      "chain": "ETH",
      "addresses": ["0x6dbe810e3314546009bd6e1b29f9031211cda5d2"]
    },
    "depositAddress": {
      "chain": "ETH",
      "address": "0xfd5a9f666d96022d13a73e3638fb7ec958696fbe"
    },
    "transactionHash": "0xfbc0f1c8256af3453fd3be7a1491e3581e072022a29ffc78cf129a662182305e"
  }
}
For blockchains that require a ‘memo’ or ‘address tag’ (XLM, HBAR, etc.), the optional addressTag field will be present in the depositAddress object.