This guides walks you through the steps to set up a basic payments workflow using the Paxos Platform, including configuring a stablecoin pay-in workflow and setting up a refund workflow. Once completed, similar, more robust, workflows can be implemented in production. If you already have sandbox access, this guide should take less than one hour to complete.

Before You Begin

  • Paxos may need to enable some API functionality described in the payments guides. Contact Support with any access issues.
  • If you need a developer sandbox account, contact us before continuing.
  • The API endpoints require authentication with a Client ID and Secret.
  • Each Client ID has a specific set of allowed scopes to access API endpoints.
  • To represent the Buyer in this guide, send enough testnet tokens to pay network fees, along with one of the supported testnet stablecoins, to an off-platform wallet.

Set Up Stablecoin Pay-in Workflow

To accept a pay-in on the Paxos Platform, first use Create Deposit Address to add a new wallet address on the public blockchain. Then add the deposit address as a stablecoin payment option for Buyers, typically at checkout.
Using a wallet connector or displaying a QR code in the Buyer interface helps to ensure that Buyers send the correct amount and avoid errors.
Once a Buyer completes a purchase, the transaction shows up in the List Transfers monitoring and reconciliation polling request.

1. Add Seller Stablecoin Deposit Address

Use Create Deposit Address to add a wallet address to the Profile designated for the Seller. The request must include one of supported stablecoins networks. Set conversion_target_asset to USD to automatically convert stablecoin pay-ins to USD on the Paxos Platform.
Best PracticeWhenever possible, include your own unique identifier in the request using ref_id. Doing so helps to protect against submitting the same request twice, as the second request with the same ref_id will be rejected with 409 already exists. The ref_id can also be used in many query parameters.
The example uses SOLANA as the crypto_network. If needed, use either ETHEREUM or POLYGON_POS for crypto_network.
curl --location 'https://api.sandbox.paxos.com/v2/transfer/deposit-addresses' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {access_token}' \
--data '{
 
    "profile_id": "eb1dbb95-8e22-471b-9ded-40bbfe309037",
    "crypto_network": "SOLANA",
    "ref_id": "da_73bcbb08-db06-4308-b0c2-2a6398012f8b",
    "conversion_target_asset": "USD"
    {/* highlight-end */}
}'
Capture the address and compatible_crypto_networks values for distribution to potential Buyers. Also store the id to use when looking up pay-ins.
{
    "id": "2d3b2366-c432-4098-ba16-83ca418c6f00",
    "profile_id": "eb1dbb95-8e22-471b-9ded-40bbfe309037",
    "customer_id": "8cbc1177-d982-4750-a435-3c7f36245452",
    "crypto_network": "SOLANA",
    "identity_id": "00000000-0000-0000-0000-000000000000",
    "ref_id": "da_73bcbb08-db06-4308-b0c2-2a6398012f8b",
    "address": "7iR1TfsaZ3f1PmbsoRuPYDbV7iujxZmuHaZDDU1Uv4YX",
    "account_id": "00000000-0000-0000-0000-000000000000",
    "conversion_target_asset": "USD",
    "compatible_crypto_networks": [
        "SOLANA"
    ]
}
Since the designated Profile has not gone through the Identity onboarding process, the default identity_id and account_id values appear in the response.
Onboarding Questions? See the onboarding FAQ for details about user Identity and Account requirements. Contact Support to help determine the best onboarding approach.

2. Receive Stablecoin Payment

Off the Paxos Platform, share the deposit address with Buyers, typically on the checkout page, and start accepting stablecoin pay-ins. Once a Buyer completes a pay-in transaction, Paxos credits the designated Profile with either stablecoin or USD, based on the deposit address configuration.
For this guide, all received pay-ins are automatically converted to USD on the Paxos Platform because we used “conversion_target_asset”: “USD”` when creating the deposit address.

3. Add Pay-in Monitoring and Reconciliation Request

Using List Transfers, create a recurring request that looks for completed transactions in the Seller’s Profile. Retrieve the status for payments received in the deposit address using the profile_id, filtered by on the CRYPTO_DEPOSIT type and updated_at.gte parameters.
Best PracticeWe recommend to poll List Transfers globally at a set cadence (for example, at 1 second intervals), using slightly behind the last processed updated_at.gte as a synchronization checkpoint.
curl --location 'https://api.sandbox.paxos.com/v2/transfer/transfers?profile_ids=eb1dbb95-8e22-471b-9ded-40bbfe309037&updated_at.gte=2024-06-24T15%3A44%3A54.383141Z&type=CRYPTO_DEPOSIT' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {access_token}'
The response confirms that a total of 7.06 PYUSD (asset) was converted to USD (balance_asset) when the pay-in reached the Paxos Platform.
{
    "items": [
        {
            "id": "9d93693f-5157-49f4-ae44-4a7a8eae3d73",
            "customer_id": "8cbc1177-d982-4750-a435-3c7f36245452",
            "profile_id": "eb1dbb95-8e22-471b-9ded-40bbfe309037",
            "amount": "7.06",
            "total": "7.06",
            "fee": "0",
            "asset": "PYUSD",
            "balance_asset": "USD",
            {/* highlight-end */}
            "direction": "CREDIT",
            "type": "CRYPTO_DEPOSIT",
            "status": "COMPLETED",
            "created_at": "2024-06-24T15:44:48.724648Z",
            "updated_at": "2024-06-24T15:44:55.383141Z",
            "destination_address": "7iR1TfsaZ3f1PmbsoRuPYDbV7iujxZmuHaZDDU1Uv4YX",
            "crypto_network": "SOLANA",
            "crypto_tx_hash": "4ex3dQ1bkoxQyyWKsk5UfVwNzzi2HXBcDb2Xv1BzxKLhRKZaVmfAJyM2hWochXTqTRDMsrpcfvoaFTMZrBsaaJPx",
            "crypto_tx_index": "4",
            "auto_conversion": {}
        }
    ],
    "next_page_cursor": "CAISDAj3qOazBhCIidm2ARijg5MN"
}

4. Move USD to Bank Account

To manage on-platform cash balances, use the Fiat Transfers APIs to batch withdraw USD to any designated bank account as needed. Learn more in the fiat transfers guide.
If you need to create a fiat account Paxos may need to enable some API functionality. C> ontact Support for assistance.

Set Up a Refund Workflow

To process stablecoin refunds on the Paxos Platform, first fund your account with USD then use Create Crypto Withdrawal to initiate a stablecoin refund to the Buyer. Once a refund is complete, the transaction shows up in the List Transfers monitoring and reconciliation polling request.

1. Add USD to a Refund Account

Production implementations can use the Fiat Transfers APIs to send USD to a destination on the Paxos Platform, which is out of scope for this guide. The fiat transfers guide provides step-by-step instructions on setting up fiat movements.
If you need to create a fiat account Paxos may need to enable some API functionality. Contact Support for assistance.
For simplicity, this guide uses Create Sandbox Deposit to simulate funding the designated Seller Profile with USD. Include the Seller’s Profile ID (profile_id) as a path parameter, as well as the deposit asset and amount as query parameters.
curl --location 'https://api.sandbox.paxos.com/v2/sandbox/profiles/eb1dbb95-8e22-471b-9ded-40bbfe309037/deposit' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {access_token} \
--data '{
    "asset": "USD",
    "amount": "100"
}'
A successful response only includes the system-generated activity_id.
{
    "activity_id": "a457f3b2-8897-4118-bc9b-216541cfc5a7"
}

1.1 Sandbox Only: Check USD Deposit

To confirm the USD deposit, use List Profile Balances.
curl --location 'https://api.sandbox.paxos.com/v2/profiles/eb1dbb95-8e22-471b-9ded-40bbfe309037/balances?assets=USD' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {access_token}'
The Profile USD balance is now 107.06, reflecting both the previously received pay-in and the current USD deposit.
{
    "items": [
        {
            //highlight-start
            "asset": "USD",
            "available": "107.06",
            {/* highlight-end */}
            "trading": "0"
        }
    ]
}

2. Initiate a Stablecoin Refund

Use Create Crypto Withdrawal to send stablecoin to the Buyer’s designated wallet address. The request must include one of supported stablecoins networks.
Set balance_asset to USD to automatically convert fiat to stablecoin and issue a refund in a single request.
For this guide, the refund is issued to the Buyer’s original wallet address (destination_address) using the same /guides/stablecoin/network pair:
  • The asset is PYUSD, the balance_asset is USD, and the crypto_network is SOLANA.
The funding source is the Seller’s Profile (profile_id) used earlier.
Best PracticeWhenever possible, include your own unique identifier in the request using ref_id. Doing so helps to protect against submitting the same request twice, as the second request with the same ref_id will be rejected with 409 already exists. The ref_id can also be used in many query parameters.
curl --location 'https://api.sandbox.paxos.com/v2/transfer/crypto-withdrawals' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {access_token}' \
--data '{
    "profile_id": "eb1dbb95-8e22-471b-9ded-40bbfe309037",
    "asset": "PYUSD",
    "destination_address": "BtXdwoYSWPprQT88ZCLuQcXuTz4dFHB1AJFYqr5uXoAd",
    "crypto_network": "SOLANA",
    "ref_id": "cw_293a8f7c-bcb6-483f-919b-8661ae65f0e6",
    "balance_asset": "USD",
    "amount": "7.06"
}'
The initial response has a status of PENDING, since the on-chain transaction has not yet been confirmed. Create a refund monitoring request to check that the refund was successful.
{
    "id": "c327d8b7-0c1a-4125-b73f-318924373d37",
    "customer_id": "8cbc1177-d982-4750-a435-3c7f36245452",
    "profile_id": "eb1dbb95-8e22-471b-9ded-40bbfe309037",
    "ref_id": "cw_293a8f7c-bcb6-483f-919b-8661ae65f0e6",
    "amount": "7.06",
    "total": "7.06",
    "fee": "0",
    "asset": "PYUSD",
    "balance_asset": "USD",
    "direction": "DEBIT",
    "type": "CRYPTO_WITHDRAWAL",
    "status": "PENDING",
    "created_at": "2024-06-24T18:33:51.087868Z",
    "updated_at": "2024-06-24T18:33:51.087868Z",
    "destination_address": "BtXdwoYSWPprQT88ZCLuQcXuTz4dFHB1AJFYqr5uXoAd",
    "crypto_network": "SOLANA",
    "auto_conversion": {}
}

3. Add Refund Monitoring and Reconciliation Request

Using List Transfers, create a recurring request that looks for completed transactions in the Seller’s Profile. Retrieve the status for refunds sent by using the profile_id, filtering by on the CRYPTO_WITHDRAWAL type and updated_at.gte parameters.
Best PracticeWe recommend to poll List Transfers globally at a set cadence (for example, at 1 second intervals), using slightly behind the last processed updated_at.gte as a synchronization checkpoint.
curl --location 'https://api.sandbox.paxos.com/v2/transfer/transfers?profile_ids=eb1dbb95-8e22-471b-9ded-40bbfe309037&updated_at.gte=2024-06-24T15%3A44%3A54.383141Z&type=CRYPTO_WITHDRAWAL' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {access_token}'
The response confirms that a total of 7.06 PYUSD (asset) was sent to the Buyer’s wallet address.
{
    "items": [
        {
            "id": "c327d8b7-0c1a-4125-b73f-318924373d37",
            "customer_id": "8cbc1177-d982-4750-a435-3c7f36245452",
            "profile_id": "eb1dbb95-8e22-471b-9ded-40bbfe309037",
            "ref_id": "cw_293a8f7c-bcb6-483f-919b-8661ae65f0e6",
            //highlight-start
            "amount": "7.06",
            "total": "7.06",
            "fee": "0",
            "asset": "PYUSD",
            "balance_asset": "USD",
            "direction": "DEBIT",
            "type": "CRYPTO_WITHDRAWAL",
            "status": "COMPLETED",
            {/* highlight-end */}
            "created_at": "2024-06-24T18:33:51.105228Z",
            "updated_at": "2024-06-24T18:34:24.976618Z",
            "destination_address": "BtXdwoYSWPprQT88ZCLuQcXuTz4dFHB1AJFYqr5uXoAd",
            "crypto_network": "SOLANA",
            "crypto_tx_hash": "4xo8doZQ58W6WCrzmyjd3vyrv2SPMRjHiz4v6w8mEuCCWbAyiXjzbFADia7St6XF3jTNyQmrDmpSNH84TXdDujFU",
            "crypto_tx_index": "0",
            "auto_conversion": {}
        }
    ],
    "next_page_cursor": "CAISDAiw-OazBhCQhNjRAxi0jpMN"
}

3.1 Sandbox Only: Check USD Withdrawal

To confirm USD was used to fund the crypto withdrawal, use List Profile Balances.
curl --location 'https://api.sandbox.paxos.com/v2/profiles/eb1dbb95-8e22-471b-9ded-40bbfe309037/balances?assets=USD' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer {access_token}'
The Profile USD balance is now 100.00, where previously it was 7.06.
{
    "items": [
        {
            //highlight-start
            "asset": "USD",
            "available": "100.00",
            {/* highlight-end */}
            "trading": "0"
        }
    ]
}