> ## Documentation Index
> Fetch the complete documentation index at: https://docs.paxos.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Stablecoin Pay-ins Quickstart

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

This guide walks you through the steps to set up a basic payments workflow using the Paxos Platform, including [configuring a stablecoin pay-in workflow](/guides/payments/quickstart#payment-workflow) and [setting up a refund workflow](/guides/payments/quickstart#refunds).
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](https://support.paxos.com) with any access issues.
* If you need a developer sandbox account, [contact us](https://support.paxos.com/hc/en-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.

<Accordion title="Example: Sandbox Credentials" id="generate-keys">
  [Log in](https://dashboard.sandbox.paxos.com) to your sandbox account and go to [**Settings** > **API Management**](https://dashboard.sandbox.paxos.com/admin/api).
  Either select an existing **Client ID** or create a new one.

  <Tip>
    **Best Practice**

    Always store the **Client ID** and **Client Secret** in a safe place.
    The secret must be reset if forgotten.
  </Tip>

  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](https://oauth.sandbox.paxos.com/oauth2/token):

  ```shell theme={null}
  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"`).

  ```json theme={null}
  {
   "access_token": "access_token",
   "expires_in": 3599,
   "scope": "funding:read_profile funding:write_profile transfer:read_transfer transfer:write_crypto_withdrawal transfer:write_deposit_address",
   "token_type": "bearer"
  }
  ```
</Accordion>

* To follow along with this guide, [create a new Profile](/api-reference/endpoints/profiles/create-profile) to represent the Seller.
  However, any existing Profile can be used when setting up simple [pay-in](/guides/payments/quickstart#payment-workflow) and [refund](/guides/payments/quickstart#refunds) workflows.
  Learn more about [user onboarding requirements](/guides/payments/faq#seller-onboarding).

<Accordion title="Example: Seller Profile" id="create-profile">
  Use [Create Profile](/api-reference/endpoints/profiles/create-profile) to represent the seller.

  ```shell theme={null}
  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.

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

  Use [List Profiles](/api-reference/endpoints/profiles/list-profiles) to retrieve the Profile ID when needed.
</Accordion>

* To represent the Buyer in this guide, send enough testnet tokens to pay network fees, along with one of the [supported testnet stablecoins](/guides/payments/faq#supported-assets), to an off-platform wallet.

<Accordion title="Example: Buyer's Wallet" id="buyer-wallet">
  We [airdropped Solana Devnet](https://faucet.solana.com/) to a self-custody wallet.
  We also used the [Paxos Testnet Faucet](https://faucet.paxos.com/) to transfer some [PYUSD on Solana Devnet](/guides/stablecoin/pyusd) to the Buyer's wallet.
  The same Buyer wallet is used to simulate a purchase as well as a refund.
</Accordion>

## Set Up Stablecoin Pay-in Workflow

To accept a pay-in on the Paxos Platform, first use [Create Deposit Address](/api-reference/endpoints/deposit-addresses/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.

<Tip>
  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.
</Tip>

Once a Buyer completes a purchase, the transaction shows up in the [List Transfers](/api-reference/endpoints/transfers/list-transfers) monitoring and reconciliation polling request.

### 1. Add Seller Stablecoin Deposit Address

Use [Create Deposit Address](/api-reference/endpoints/deposit-addresses/create-deposit-address) to add a wallet address to the Profile designated for the Seller.
The request must include one of [supported stablecoins](/guides/payments/faq#supported-assets) networks.
Set `conversion_target_asset` to `USD` to automatically convert stablecoin pay-ins to USD on the Paxos Platform.

<Tip>
  **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.
</Tip>

The example uses `SOLANA` as the `crypto_network`.
If needed, use either `ETHEREUM` or `POLYGON_POS` for `crypto_network`.

```shell theme={null}
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](/guides/payments/quickstart/#pay-in-monitor-reconcile).

```json highlight={8,12} theme={null}
{
    "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](/guides/payments/faq#seller-onboarding) for details about user Identity and Account requirements.
> Contact [Support](https://support.paxos.com/hc/en-us) to help determine the best onboarding approach.

### 2. Receive Stablecoin Payment

Off the Paxos Platform, share the [deposit address](/guides/payments/quickstart#pay-in-add-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.

<Accordion title="Example: Buyer's Wallet" id="buyer-wallet">
  We [airdropped Solana Devnet](https://faucet.solana.com/) to a self-custody wallet.
  We also used the [Paxos Testnet Faucet](https://faucet.paxos.com/) to transfer some [PYUSD on Solana Devnet](/guides/stablecoin/pyusd) to the Buyer's wallet.
  The same Buyer wallet is used to simulate a purchase as well as a refund.
</Accordion>

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](/guides/payments/quickstart#pay-in-add-deposit-address).

### 3. Add Pay-in Monitoring and Reconciliation Request

Using [List Transfers](/api-reference/endpoints/transfers/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](/guides/payments/quickstart#pay-in-add-deposit-address) using the `profile_id`, filtered by on the `CRYPTO_DEPOSIT` type and `updated_at.gte` parameters.

<Tip>
  Best Practice

  We recommend to poll [List Transfers](/api-reference/endpoints/transfers/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.
</Tip>

```shell theme={null}
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.

```json theme={null}
{
    "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](/api-reference/endpoints/fiat-transfers) APIs to batch withdraw USD to any designated bank account as needed.
Learn more in the [fiat transfers guide](/guides/developer/fiat-transfers).

> If you need to [create a fiat account](/api-reference/endpoints/fiat-transfers/create-fiat-account) Paxos may need to enable some API functionality.
> Contact [Support](https://support.paxos.com/hc/en-us) for assistance.

## Set Up a Refund Workflow

To process stablecoin refunds on the Paxos Platform, first [fund your account with USD](/guides/payments/quickstart#refund-fund-account) then use  [Create Crypto Withdrawal](/api-reference/endpoints/crypto-withdrawals/create-crypto-withdrawal) to initiate a stablecoin refund to the Buyer.
Once a refund is complete, the transaction shows up in the [List Transfers](/api-reference/endpoints/transfers/list-transfers) monitoring and reconciliation polling request.

### 1. Add USD to a Refund Account

Production implementations can use the [Fiat Transfers](/api-reference/endpoints/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](/guides/developer/fiat-transfers) provides step-by-step instructions on setting up fiat movements.

> If you need to [create a fiat account](/api-reference/endpoints/fiat-transfers/create-fiat-account) Paxos may need to enable some API functionality.
> Contact [Support](https://support.paxos.com/hc/en-us) for assistance.

For simplicity, this guide uses [Create Sandbox Deposit](/api-reference/endpoints/sandbox-deposits/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.

```shell theme={null}
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`.

```json theme={null}
{
    "activity_id": "a457f3b2-8897-4118-bc9b-216541cfc5a7"
}
```

### 1.1 Sandbox Only: Check USD Deposit

To confirm the USD deposit, use [List Profile Balances](/api-reference/endpoints/profiles/list-profile-balances).

```shell theme={null}
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.

```json theme={null}
{
    "items": [
        {
            "asset": "USD",
            "available": "107.06",
            "trading": "0"
        }
    ]
}
```

### 2. Initiate a Stablecoin Refund

Use [Create Crypto Withdrawal](/api-reference/endpoints/crypto-withdrawals/create-crypto-withdrawal) to send stablecoin to the Buyer's designated wallet address.
The request must include one of [supported stablecoins](/guides/payments/faq#supported-assets) networks.

<Tip>
  Set `balance_asset` to `USD` to automatically convert fiat to stablecoin and issue a refund in a single request.
</Tip>

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.

<Tip>
  **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.
</Tip>

```shell theme={null}
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](/guides/payments/quickstart#refund-monitor-reconcile) to check that the refund was successful.

```json theme={null}
{
    "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](/api-reference/endpoints/transfers/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.

<Tip>
  Best Practice

  We recommend to poll [List Transfers](/api-reference/endpoints/transfers/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.
</Tip>

```shell theme={null}
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.

```json theme={null}
{
    "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](/api-reference/endpoints/profiles/list-profile-balances).

```shell theme={null}
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`.

```json theme={null}
{
    "items": [
        {
            "asset": "USD",
            "available": "100.00",
            "trading": "0"
        }
    ]
}
```
