Skip to main content

Quickstart

Accept stablecoin pay-ins with real-time settlement. Issue on-chain refunds.

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. Reach out to your Paxos Representative or the Help Desk 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.
    Example: Sandbox Credentials

    Log in to your sandbox account and go to Settings > API Management. Either select an existing Client ID or create a new one.

    Best Practice

    Always store the Client ID and Client Secret in a safe place. The secret must be reset if forgotten.

    To complete the steps in this guide, ensure the following scopes are enabled for the client (scopes may be updated at any time):

    funding:read_profile \
    funding:write_profile \
    transfer:read_transfer \
    transfer:write_crypto_withdrawal \
    transfer:write_deposit_address

    Include the client (client_id) and secret (client_secret) in the authentication request to https://oauth.sandbox.paxos.com/oauth2/token:

    curl --location "https://oauth.sandbox.paxos.com/oauth2/token" \
    --form grant_type=client_credentials \
    --form client_id={client_id} \
    --form client_secret={client_secret} \
    --form scope="funding:read_profile funding:write_profile transfer:read_transfer transfer:write_crypto_withdrawal transfer:write_deposit_address"

    Confirm the response includes the requisite scopes and save the {access_token} to use in the request authorization header (-H "Authorization: Bearer {access_token}").

    {
    "access_token": "{access_token}",
    "expires_in": 3599, // Seconds (59 Minutes and 59 Seconds)
    "scope": "funding:read_profile funding:write_profile transfer:read_transfer transfer:write_crypto_withdrawal transfer:write_deposit_address",
    "token_type": "bearer"
    }
  • To follow along with this guide, create a new Profile to represent the Seller. However, any existing Profile can be used when setting up simple pay-in and refund workflows. Learn more about user onboarding requirements.
    Example: Seller Profile

    Use Create Profile to represent the seller.

    curl --location 'https://api.sandbox.paxos.com/v2/profiles' \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    --header 'Authorization: Bearer {access_token}' \
    --data '{
    "nickname": "Seller A",
    "description": "Stablecoin Pay-in and Refunds."
    }'

    Save the id (profile_id) from the response, it will be used throughout this guide.

    {
    "id": "eb1dbb95-8e22-471b-9ded-40bbfe309037",
    "nickname": "Seller A",
    "type": "NORMAL"
    }

    Use List Profiles to retrieve the Profile ID when needed.

  • 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.
    Example: Buyer's Wallet

    We airdropped Solana Devnet to a self-custody wallet. We also used the Paxos Testnet Faucet to send some PYUSD on Solana Devnet to the Buyer's wallet. The same Buyer wallet is used to simulate a purchase as well as a refund.

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.

Best Practice

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 Practice

Whenever 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"
}'

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 the payments team or reach out to your Paxos Representative 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.

Example: Buyer's Wallet

We airdropped Solana Devnet to a self-custody wallet. We also used the Paxos Testnet Faucet to send some PYUSD on Solana Devnet to the Buyer's wallet. The same Buyer wallet is used to simulate a purchase as well as a refund.

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 Practice

We 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",
"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.

Before You Begin

If you need to create a fiat account Paxos may need to enable some API functionality. Contact us or reach out to your Paxos Representative 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.

Before You Begin

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": [
{
"asset": "USD",
"available": "107.06",
"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.

tip

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 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 Practice

Whenever 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 Practice

We 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",
"amount": "7.06",
"total": "7.06",
"fee": "0",
"asset": "PYUSD",
"balance_asset": "USD",
"direction": "DEBIT",
"type": "CRYPTO_WITHDRAWAL",
"status": "COMPLETED",
"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": [
{
"asset": "USD",
"available": "100.00",
"trading": "0"
}
]
}