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

# Create Your First Payment

This guide walks you through creating your first payment using Carbn's payment infrastructure. Before initiating payments, ensure your users have completed onboarding and have active status.

## Prerequisites

Before you can create payments, you need:

* **Active Users**: Users must have `active` status after successful KYC verification
* **Registered Accounts**: Users need registered bank accounts or wallets
* **API Authentication**: Valid API key with payment permissions

<Info>
  Users with `under_review`, `rejected`, or `incomplete` status cannot initiate payments.
</Info>

***

## Steps to make your first payment:

<Steps>
  <Step title="Register Destination Account">
    Before initiating transfers, users need registered destination account (bank accounts or wallets).

    <AccordionGroup>
      <Accordion title="Register Bank Account" icon="landmark" defaultOpen>
        <CodeGroup>
          ```bash cURL theme={null}
          curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/accounts/register' \
          --header 'Content-Type: application/json' \
          --header 'x-api-key: <api-key>' \
          --data-raw '{
            "user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            "account_type": "bank_account",
            "account_details": {
              "account_number": "1234567890",
              "routing_number": "021000021",
              "bank_name": "Example Bank",
              "account_holder_name": "John Doe"
            },
            "currency": "USD"
          }'
          ```

          ```javascript JavaScript theme={null}
          const response = await fetch('https://api.carbnconnect.com/payment/api/v1/accounts/register', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'x-api-key': '<api-key>'
            },
            body: JSON.stringify({
              user_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              account_type: "bank_account",
              account_details: {
                account_number: "1234567890",
                routing_number: "021000021",
                bank_name: "Example Bank",
                account_holder_name: "John Doe"
              },
              currency: "USD"
            })
          });
          ```

          ```python Python theme={null}
          import requests

          headers = {
              'Content-Type': 'application/json',
              'x-api-key': '<api-key>'
          }

          data = {
              "user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              "account_type": "bank_account",
              "account_details": {
                  "account_number": "1234567890",
                  "routing_number": "021000021",
                  "bank_name": "Example Bank",
                  "account_holder_name": "John Doe"
              },
              "currency": "USD"
          }

          response = requests.post(
              'https://api.carbnconnect.com/payment/api/v1/accounts/register',
              headers=headers,
              json=data
          )
          ```
        </CodeGroup>
      </Accordion>

      <Accordion title="Register Wallet" icon="wallet">
        <CodeGroup>
          ```bash cURL theme={null}
          curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/wallets/register' \
          --header 'Content-Type: application/json' \
          --header 'x-api-key: <api-key>' \
          --data-raw '{
            "user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            "crypto": "USDC",
              wallet_address: "3BsSG...",
              blockchain: "solana",
            "source_currency": "USD"
          }'
          ```

          ```javascript JavaScript theme={null}
          const response = await fetch('https://api.carbnconnect.com/payment/api/v1/wallets/register', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'x-api-key': '<api-key>'
            },
            body: JSON.stringify({
              user_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              crypto: "USDC",
              wallet_address: "3BsSG...",
              blockchain: "solana",
              source_currency: "USD"
            })
          });
          ```

          ```python Python theme={null}
          import requests

          headers = {
              'Content-Type': 'application/json',
              'x-api-key': '<api-key>'
          }

          data = {
              "user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              "crypto": "USDC",
              "wallet_address": "3BsSG...",
              "blockchain": "solana",
              "source_currency": "USD"
          }

          response = requests.post(
              'https://api.carbnconnect.com/payment/api/v1/wallets/register',
              headers=headers,
              json=data
          )
          ```
        </CodeGroup>
      </Accordion>
    </AccordionGroup>
  </Step>

  <Step title="Initiate Onramp Transfer">
    Now that you have registered a destination wallet, you can initiate an onramp transfer (fiat to stablecoins). Carbn Connect supports multiple methods for onramp transfers:

    <AccordionGroup>
      <Accordion title="Open Banking Transfer" icon="arrow-left-right" defaultOpen>
        Open Banking provides better visibility and user experience. The deposit links guide users through the payment flow without leaving your application, giving you full control over the user journey.

        <Info>
          **Regional Availability**: Open Banking is currently available for onramp transfers in **US**, **EU**, and **UK**.
        </Info>

        <CodeGroup>
          ```bash cURL theme={null}
          curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/transfers/onramp' \
          --header 'Content-Type: application/json' \
          --header 'x-api-key: <api-key>' \
          --data-raw '{
            "user_id": "0abad22b-53d3-4473-b1ee-283f4b32e3ad",
            "wallet_id": "34e9819d-2f1c-40a5-9404-a1be8fe34227",
            "open_banking": {
              "amount": 3,
              "redirect_url": "https://www.yourapp.com/payment-success",
              "is_mobile_app": false,
              "country_codes": ["SWE"]
            }
          }'
          ```

          ```javascript JavaScript theme={null}
          const response = await fetch('https://api.carbnconnect.com/payment/api/v1/transfers/onramp', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'x-api-key': '<api-key>'
            },
            body: JSON.stringify({
              user_id: "0abad22b-53d3-4473-b1ee-283f4b32e3ad",
              wallet_id: "34e9819d-2f1c-40a5-9404-a1be8fe34227",
              open_banking: {
                amount: 3,
                redirect_url: "https://www.yourapp.com/payment-success",
                is_mobile_app: false,
                country_codes: ["SWE"]  // Optional: filter banks by country codes
              }
            })
          });
          ```

          ```python Python theme={null}
          import requests

          headers = {
              'Content-Type': 'application/json',
              'x-api-key': '<api-key>'
          }

          data = {
              "user_id": "0abad22b-53d3-4473-b1ee-283f4b32e3ad",
              "wallet_id": "34e9819d-2f1c-40a5-9404-a1be8fe34227",
              "open_banking": {
                  "amount": 3,
                  "redirect_url": "https://www.yourapp.com/payment-success",
                  "is_mobile_app": False,
                  "country_codes": ["SWE"]  # Optional: filter banks by country codes
              }
          }

          response = requests.post(
              'https://api.carbnconnect.com/payment/api/v1/transfers/onramp',
              headers=headers,
              json=data
          )
          ```
        </CodeGroup>

        <Note>
          **Country Codes Filtering**: The `country_codes` parameter is optional. When not provided, all supported bank countries for the user are available. When provided as an array of ISO 3166-1 alpha-3 country codes (e.g., `["SWE", "NOR"]`), only banks from the specified countries will be shown in the payment flow.
        </Note>

        <CodeGroup>
          ```json Response theme={null}
          {
            "transaction_id": "d5c48677-b85d-4de5-a685-196d0e6596f7",
            "source_currency": "eur",
            "open_banking": {
              "deposit_link": "https://secure.plaid.com/hl/lpps56nr6p98sn9r89341n78s8834q672q",
              "payment_id": "payment-id-production-2308307c-0d61-46d3-9225-50d48f607e36",
              "link_token": "link-production-cf01ae1c-43fa-4e34-896a-23f3389d127d"
            },
            "v_bank": null
          }
          ```
        </CodeGroup>

        <Note>
          **Open Banking Benefits:**

          * **Better Visibility**: Full payment tracking and monitoring throughout the process
          * **Enhanced UX**: Users never leave your application during payment flow
          * **Real-time Updates**: Immediate payment confirmation and status updates
          * **Amount Control**: Exact amount validation and processing
          * **Seamless Integration**: Embed payment flow directly in your app
          * **Lower Fees**: Reduced processing costs compared to traditional methods
        </Note>
      </Accordion>

      <Accordion title="Virtual Account Transfer" icon="wallet-cards">
        Virtual Account method serves as a fallback option or for payment methods not supported by Open Banking. It generates unique bank account details that users can transfer money to from any bank. However, it provides limited visibility - you can only monitor once funds are deposited, with no tracking of when users initiate payments or control over transfer amounts.

        <CodeGroup>
          ```bash cURL theme={null}
          curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/transfers/onramp' \
          --header 'Content-Type: application/json' \
          --header 'x-api-key: <api-key>' \
          --data-raw '{
            "user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
            "wallet_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
          }'
          ```

          ```javascript JavaScript theme={null}
          const response = await fetch('https://api.carbnconnect.com/payment/api/v1/transfers/onramp', {
            method: 'POST',
            headers: {
              'Content-Type': 'application/json',
              'x-api-key': '<api-key>'
            },
            body: JSON.stringify({
              user_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              wallet_id: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
            })
          });

          const data = await response.json();
          console.log('Virtual Account Details:', data.v_bank);
          ```

          ```python Python theme={null}
          import requests

          headers = {
              'Content-Type': 'application/json',
              'x-api-key': '<api-key>'
          }

          data = {
              "user_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
              "wallet_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
          }

          response = requests.post(
              'https://api.carbnconnect.com/payment/api/v1/transfers/onramp',
              headers=headers,
              json=data
          )

          result = response.json()
          print('Virtual Account Details:', result['v_bank'])
          ```
        </CodeGroup>

        <CodeGroup>
          ```json Response theme={null}
          {
            "transaction_id": null,
            "source_currency": "eur",
            "open_banking": null,
            "v_bank": {
              "bic": "MODRIE22XXX",
              "iban": "IE44MODR99035511728566",
              "bank_name": "Modulr Finance, Ireland Branch",
              "payment_rail": "sepa"
            }
          }
          ```
        </CodeGroup>

        <Warning>
          **Virtual Account Limitations:**

          * **Limited Visibility**: No tracking until funds arrive - you only know when money lands
          * **No Amount Control**: Users can send any amount, not necessarily what was requested
          * **Payment Uncertainty**: No way to know if/when users actually make the transfer
          * **Delayed Monitoring**: Can only monitor after funds are deposited, not during transfer
        </Warning>

        <Info>
          **When to Use Virtual Accounts:**

          * As a fallback when Open Banking is not available
          * For payment methods not supported by Open Banking
          * When users prefer traditional bank transfers
          * For regions outside US/EU/UK where Open Banking isn't available
        </Info>
      </Accordion>

      <Accordion title="QR Payin (PHP)" icon="qr-code">
        QR Payin is available exclusively for PHP (Philippine Peso) transactions. This method generates a QR code that users can scan with their mobile banking app to complete the payment. The QR code has an expiration time and must be used before it expires.

        <Info>
          **Regional Availability**: QR Payin is currently available only for **PHP** currency transactions.

          **Minimum Amount**: The minimum transfer amount for QR Payin is **400 PHP**.
        </Info>

        <CodeGroup>
          ```bash cURL theme={null}
          curl --location --request POST 'https://api.carbnconnect.com/payment/api/v1/transfers/onramp' \
          --header 'Content-Type: application/json' \
          --header 'x-api-key: <api-key>' \
          --data-raw '{
            "user_id": "b8aacdf0-876b-43c1-bbe1-2f2465bbed86",
            "wallet_id": "9a7dc4df-c6a6-4de9-871f-83361b821c29",
            "qr_payin": {
              "amount": 400
            }
          }'
          ```
        </CodeGroup>

        <CodeGroup>
          ```json Response theme={null}
          {
            "transaction_id": "76e12d55-1a25-457e-9e97-0495162de555",
            "source_currency": "PHP",
            "qr_payin": {
              "qr_code": "00020101021228600011ph.ppmi.p2m0111DCPHPHM1XXX03192147235668383093866050301152044814530360854034005802PH5904test6015MAHAGUN MORPHEU62380011ph.ppmi.p2m0519198581120859644569663048038",
              "expiry_time": "2026-02-10T07:13:58.621Z"
            }
          }
          ```
        </CodeGroup>

        <Note>
          **QR Payin Benefits:**

          * **Convenient**: Users can pay by scanning QR code with their mobile banking app
          * **Fast Processing**: Payments are processed quickly once scanned
          * **Mobile-Friendly**: Ideal for mobile-first payment flows
          * **Secure**: Uses standard QR payment protocols
        </Note>

        <Warning>
          **Important**: The QR code has an expiration time. Users must complete the payment before the `expiry_time`. After expiration, a new QR code must be generated.
        </Warning>
      </Accordion>
    </AccordionGroup>
  </Step>
</Steps>

***

## What's Next?

<CardGroup cols={2}>
  <Card title="Monitor Transfer Status" icon="chart-line" href="/documentation/developer-platform/monitoring/transfer-status" arrow="true">
    Track transfer states and understand the complete payment lifecycle
  </Card>

  <Card title="Configure Webhook" icon="webhook" href="/documentation/getting-started/configure-webhook" arrow="true">
    Set up real-time notifications for payment status updates
  </Card>
</CardGroup>

<CardGroup cols={1}>
  <Card title="Supported Payment Methods" icon="route" href="/documentation/network/supported-payment-methods" arrow="true">
    Explore supported payment methods, currencies, and assets
  </Card>
</CardGroup>

## Getting Help

<Columns cols={1}>
  <Card title="Contact Support" icon="headset" href="mailto:support@carbn.xyz" arrow="true">
    When contacting support, please include:
    <Check>**Transaction ID** of the payment</Check>
    <Check>**Wallet ID** If transfer ID not available</Check>
    <Check>**Transfer type** (FX, on-ramp, off-ramp)</Check>
    <Check>**Error messages** or **status codes** </Check>
    <Check>**Timestamp** when the error occurred</Check>
  </Card>
</Columns>
