# Integration

## Environment

### Testnet

`App`  [https://test.coindpay.xyz](https://test.coindpay.xyz/) （ <mark style="background-color:$danger;">Integration & Debugging</mark> ）

Core steps: register merchants, manage payments, bind settlement wallets, configure webhooks, and integrate the merchant order flow end-to-end > [test.coindpay.xyz/account/payouts](https://test.coindpay.xyz/account/payouts)

Subscription-type Payments Links require contacting our team（ [@CoindPay](https://x.com/CoindPay) or collaboration group ）to whitelist static IPs and configure the necessary sandbox permissions.

Other payment types and business scenarios remain publicly available and open by default.

You can check your current IP at [https://whatismyipaddress.com](https://whatismyipaddress.com/)  VPN may affect your outbound IP.

### Prod

`App`  [https://coindpay.xyz](https://coindpay.xyz/) （ <mark style="background-color:$danger;">Production Business & KYB Required</mark> ）

* **Payments** support **USDT/USDC** on **EVM** and **SVM** networks [/pages/WuOkyhKpbCvravr9fOhh#id-2.-payout-assets](https://docs.coindpay.xyz/landing/start/developers/pages/WuOkyhKpbCvravr9fOhh#id-2.-payout-assets "mention")\
  Please confirm that your **connected wallet** matches the correct network in your account settings.
* **On/Off-ramps** support **100+ assets** across **30+ networks** for large-volume **buy and sell crypto** transactions. When creating ramp orders, ensure that your selected asset type matches the corresponding wallet address.
* Wallet configuration is fully flexible — developers can specify either an **EVM** or **SVM** address as the payout primary wallet > [coindpay.xyz/account/payouts](https://coindpay.xyz/account/payouts)

## 1. Create Account

Before using CoindPay, you need to create an account. This account serves as a **unified identity** for both your developer role and merchant enterprise.

Visit the CoindPay website and choose one of the account creation methods:

* **Social Account**
  * Supported social login providers (e.g. Google, X, etc.)
* **Wallet**
  * **EVM wallet** (Ethereum-compatible chains)
  * **SVM wallet** (Solana)

> <mark style="background-color:purple;">Note: Even if you sign up using a social account, you will still be required to bind a payout wallet to complete</mark> <mark style="background-color:red;">**and enable payments.**</mark>

<figure><img src="/files/LDXHZgb8fYFb3WdmGNa7" alt=""><figcaption></figcaption></figure>

> 💡 Once your account is created, you will have a unified merchant identity to manage Payments Links, track orders, and manage team members.

<figure><img src="/files/e1bd6ZRN7gMjldVdydyX" alt=""><figcaption></figcaption></figure>

## 2. Create Payments

A Payments Link is a convenient way to collect payments. You can generate a link and share it with customers or embed it into your applications.

{% hint style="warning" %}
If merchant KYB compliance is not completed, users will be prompted to complete the KYB onboarding and compliance review. The prompt is triggered via **More → Account profile** or during **Pay → Payments create**, with an onboarding modal.
{% endhint %}

<figure><img src="/files/RUdN7F3BdyPvU6lmfYrn" alt=""><figcaption></figcaption></figure>

#### Option 1: Few Products（No-code）

If you have a small number of products:

1. Create a **Payments Link** and provide the necessary form information at once.
2. Share the link with your customers or embed it in your website/app.

> Designed for no-code integration, for creators or merchants avoiding custom development.

#### Option 2: Many Products（Dynamic）

If you have many products or need dynamic payment links:

1. Create a **Payments Link**&#x20;
2. Dynamically append parameters to generate **unlimited dynamic Payments Links**.
3. Share or embed these links into your applications or product flows.

{% hint style="info" %}

1. All Payments Links support dynamic parameter appending only for the parameters listed in the table below.&#x20;
2. All other settings, such as payment methods, subscription type, and additional options, must be selected and configured directly in the payments form.
   {% endhint %}

<figure><img src="/files/5TWk3CJOfYCJEazVS8xi" alt=""><figcaption></figcaption></figure>

## 3. Multiple integrations

### URL Parameters

You can extend the embedded checkout link by appending parameters to the URL.\
This is especially useful when you want to dynamically pass metadata such as product title, description, price, images or others.

<table><thead><tr><th width="257.951171875">Parameter</th><th>Type</th><th width="211.193603515625">Description</th><th>Example</th></tr></thead><tbody><tr><td><code>merchant_transaction_id</code></td><td><code>string*</code></td><td><strong>Required.</strong> Unique Id for the order transaction generated by the merchant. Can be generated with <code>randomUUID()</code> to ensure uniqueness. The <code>rampId</code> is returned in webhook order payloads. corresponds to <code>rampId</code></td><td><code>merchant_transaction_id=550e8400-e29b-41d4-a716-446655440000</code></td></tr><tr><td><code>currency</code></td><td><code>string?</code></td><td>Effective only if included in the payment link’s supported currency list; otherwise defaults to the first configured currency.</td><td><code>currency=EUR</code></td></tr><tr><td><code>price</code></td><td><code>string?</code></td><td>Payment amount in the supported fiat or crypto currency format.<br><mark style="background-color:purple;"><strong>Lmimits #</strong></mark><a data-mention href="/pages/r67FarAduWyVbyLS4OK5">/pages/r67FarAduWyVbyLS4OK5</a></td><td><code>price=29.99</code></td></tr><tr><td><code>signature</code></td><td><code>string?</code></td><td>HMAC-SHA256 hex signature generated with the merchant secret key; <strong>Required</strong> if a custom price is provided.</td><td><code>signature=b95df8938****9fgk56</code></td></tr><tr><td><code>title</code></td><td><code>string?</code></td><td>The product or payment title displayed on the checkout page.</td><td><code>title=Hello</code>  </td></tr><tr><td><code>desc</code></td><td><code>string?</code></td><td>A short description of the product or service.</td><td><code>desc=Text</code></td></tr><tr><td><code>images</code></td><td><code>array?</code></td><td>A list of image objects to display in the checkout interface.</td><td><code>images=[{"url":"https://cdn.example.com/item.jpg"}]</code></td></tr><tr><td><code>name</code></td><td><code>string?</code></td><td>Pre-filled consumer name (≤120 characters)</td><td><code>name=Elon Musk</code></td></tr><tr><td><code>email</code></td><td><code>string?</code></td><td>Pre-fill the customer's email in the checkout form.</td><td><code>email=user@example.com</code></td></tr><tr><td><code>payment_method</code></td><td><code>string?</code></td><td>optional. Fiat payments only. If not specified, all payment methods supported for the selected currency will be returned. If specified, the method will be automatically preselected at checkout.<br>Supported values include <code>card</code>, <code>google</code>, <code>apple</code>, <code>revolut_pay</code>, <code>volt_banktransfer_eur</code>, <code>EightBWorld_instapay</code>, <code>interac_gk</code>, <code>unlimint_pix_brl</code> and others. Refer to <a data-mention href="/pages/oFmASVVpiVcy11qnc28t">/pages/oFmASVVpiVcy11qnc28t</a> for the full and up-to-date list.</td><td><code>payment_method=apple</code></td></tr><tr><td><code>fix_payment_method</code></td><td><code>boolean?</code></td><td>Locks the selected <code>payment_method</code> and prevents changes during checkout. Recommended for channel-specific flows (e.g. iOS) to optimize conversion and payment success.</td><td><code>fix_payment_method=true</code></td></tr><tr><td><del><code>redirect_url</code></del><br><mark style="background-color:$danger;">Temporarily unavailable (risk control upgrade)</mark></td><td><code>string?</code></td><td>URL to which the user is redirected after passing the payments or ramps scenes;<br>We recommend using the <strong>default checkout exit flow</strong> rather than redirecting via <code>redirect_url</code>. redirect urls are subject to <strong>risk and compliance monitoring</strong>, and high-risk or non-compliant destinations may affect <strong>merchant account health</strong>.</td><td><code>redirect_url=https://coindpay.xyz/wallet</code></td></tr><tr><td><mark style="background-color:yellow;">more</mark></td><td></td><td>Please contact our Devs team for dynamic updates.</td><td></td></tr></tbody></table>

{% hint style="info" %}

#### **Checkout Tips**

*<mark style="background-color:red;">?</mark> The value is optional, <mark style="background-color:red;">\*</mark> the value is required.*\
Non-authentic product or consumer information, such as `title`, `email`, and `desc`, is not required to be provided.

1. **merchant\_transaction\_id**

* The `merchant_transaction_id` is **required**.
* Orders may transition through multiple statuses, but all remain tied to the same `merchant_transaction_id`
* Separate or recurring orders generate **distinct `merchant_transaction_id`** values.
* Use `randomUUID()`  or other encrypted Id libraries to generate a **unique Id** for each transaction to avoid duplicates.
* `merchant_transaction_id` serves as an alias for `rampId`. The `rampId` is returned in webhook order payloads.
* If not provided, it will **not cause an error**, but you may lose the ability to reliably **track the order** or **query its status** via this Id.

2. **email**

* Ensure the pre-submitted email matches the one used in subsequent order flows.
* The email should be a **user’s email address obtained in advance**.
* If the email is in a valid format, it will be **automatically pre-filled** in the checkout form.
* If unsure, request the user to **manually enter their email** to prevent mismatches.

3. **price**

* When the `price` routing parameter is enabled, configure the product’s **Amount Type** as **Fixed Amount**.
* The **Random Amount** option is intended for tipping or donation scenarios and is **not controlled** by the `price` parameter.
* When `price` is **not provided**, the payment Link will use the amount configured in the merchant dashboard.
* When `price` **is provided in the URL**, it is treated as **dynamic input** and **must be protected by a signature**.
* Any modification to the `price` value without a valid signature will result in the Payment Link being marked as **invalid**.

4. **signature**

* The `signature` parameter is conditionally required.
* f `price` is **present**, a valid `signature` **must** be generated and included.
* If `price` is **absent**, `signature` is optional.
* The signature cryptographically binds the request parameters to the merchant and prevents client-side tampering.

5. **currency**

* The `currency` routing parameter is optional.

* Please ensure the provided `currency` is supported in the payment link currency configuration,  passing an unconfigured currency will be ignored.

* [x] Multiple Fiat Currencies ( **USD-pegged Disabled** )

- The product link resolves to either the **first configured currency** or the **developer-provided `currency` parameter** (must match one of the enabled currencies).
- Client-side currency switching is **disabled**; only the resolved currency is used.

* [x] Multiple Fiat Currencies **( USD-pegged Enabled )**

- The product link resolves to either the **first configured currency** or the **developer-provided `currency` parameter** (must exist in the enabled list).
- End users may freely switch between all enabled currencies.
- Amounts remain **anchored to USD**, with conversions applied automatically using **real-time FX rates**.

6. **USD-pegged**

* **Default:** USD-pegged is **disabled**. the **amount remains uniform** and can be controlled via the `price` parameter.
* When **USD-pegged** is enabled:
  * All selected fiat currencies are automatically **pegged to USD**.
  * Settlement amounts are calculated **in real time** based on current FX rates.
    {% endhint %}

### Code for Checkout

```typescript
import { createHmac } from 'crypto'

export function createHmacSignature(secret: string, data: string): string {
  return createHmac('sha256', secret).update(data).digest('hex')
}
```

{% code lineNumbers="true" %}

```typescript
import { randomUUID } from 'crypto'

const checkoutLink = 'xxx'  // created via the CoindPay merchant /pay

const merchant_transaction_id = randomUUID() || 'others utils id'

export interface priceSignaturePayload {
  merchant_transaction_id: string
  price: string
}

export function canonicalizePriceSignaturePath(payload: priceSignaturePayload): string {
  return `merchant_transaction_id=${payload?.merchant_transaction_id}&price=${payload?.price}`
}

// secretKey: The merchant/developer’s API Secret from the dashboard integration webhooks.
const secretKey = YOUR_MERCHANT_API_SECRET

// Merchant payment link signature（If price is included in the URL）
export function signCheckoutPriceSignature(payload: priceSignaturePayload): string {
  const canonical = canonicalizePriceSignaturePath(payload)
  return createHmacSignature(secretKey, canonical)
}

// Render to your dynamic product link params
const paramsData = {
  merchant_transaction_id,  // 'xxx-123456',
  title: 'Your product title', // 
  desc: 'Your product desc',
  price: 19.99,
  signature: 'xxx', // signCheckoutPriceSignature('your price payload')
  email: 'your_customers@domain.com'
})

export function getEncodeCheckoutLink(
  link: string,
  queryData?: Record<string, any>
): string {
  const url = new URL(link)

  Object.entries(queryData || {}).forEach(([key, value]) => {
    if (value === undefined || value === null) return
    url.searchParams.set(
      key,
      typeof value === 'object' ? JSON.stringify(value) : String(value)
    )
  })

  return url.toString()
}


const url = getEncodeCheckoutLink(checkoutLink, paramsData)

// you can preview this url
console.log('url', url)
```

{% endcode %}

<figure><img src="/files/9SfBAJFyInaOSqLkwYsr" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/gBvgsse6rGiQzRt6wueo" alt=""><figcaption></figcaption></figure>

<https://coindpay.xyz/pay/link/vVKAsfomepqD0fstx9bdE?name=Jason&email=consumer@coindpay.xyz>\
\ <mark style="background-color:$danger;">Note: the actual checkout URL must include the</mark> <mark style="background-color:$danger;"></mark><mark style="background-color:$danger;">`merchant_transaction_id`</mark> <mark style="background-color:$danger;"></mark><mark style="background-color:$danger;">parameter.</mark>

<figure><img src="/files/fOu9sHaT9wNZLq9YUzJ1" alt=""><figcaption></figcaption></figure>

> Example: Quick payment methods limited to iOS channels

<https://coindpay.xyz/pay/link/vVKAsfomepqD0fstx9bdE?payment_method=apple&fix_payment_method=true><br>

<figure><img src="/files/wUyJbkJkgEkceK1O0CD8" alt=""><figcaption></figcaption></figure>

### ① Web

{% hint style="info" %}
E-commerce checkouts, SaaS dashboards, or any web-based payment page.
{% endhint %}

#### 1. Embed via iFrame

> Native HTML styles can be customized as needed.

You can freely customize the surrounding HTML, container styles, and transitions using TailwindCSS or your preferred styling approach.

```typescript
// React component + TailwindCSS

const yourCustomName = '', yourCustomStyle = {}

const onIframeLoad = ()=> {} // If some scenes for iframe loading success

<iframe
  src={url}
  allowFullScreen
  sandbox="allow-scripts allow-same-origin allow-popups allow-forms allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation"
  allow="camera; microphone; geolocation; fullscreen; accelerometer; autoplay; clipboard-write; clipboard-read; payment; gyroscope; encrypted-media; picture-in-picture"
  className={yourCustomName}
  style={yourCustomStyle}
  onLoad={onIframeLoad}
/>
```

#### **2. Redirect to Payment Page**

> Customize your content area (Button, image, etc.) style

```html
<a href={url} target="_blank">
  Pay with CoindPay
</a>
```

{% hint style="info" %}
**Highlights:**

* ✅ No SDK required
* ✅ Instant integration
* ✅ Dynamic data and ui adaptation
  {% endhint %}

### ② Mobile App

{% hint style="info" %}
iOS / Android / React Native / Flutter apps that need to embed or redirect to a payment flow.
{% endhint %}

#### WebView Embed

```typescript
// React Native example

<WebView source={{ uri: url }} />
```

### White-label Checkout

Personalized parameters such as `payment_method`, `fixed_payment_method` can be used to initialize the frontend checkout experience and directly launch the CoindPay checkout interface, making it well-suited for developer merchants seeking a more native and streamlined checkout experience.

<div data-with-frame="true"><figure><img src="/files/1DjBnc4HCtaZVWMSXrdU" alt=""><figcaption></figcaption></figure></div>

### Embedded mode

Whether to enable **Embedded** mode depends on the merchant developer’s integration approach.

**Suitable for iframe embedding**（Enabling embedded mode will hide basic payment link details, including merchant and product information, to provide a cleaner and more seamless embedded checkout experience）

<div align="left"><figure><img src="/files/cASm2eIwRyDRlFA6uhnZ" alt=""><figcaption></figcaption></figure></div>

<div data-with-frame="true"><figure><img src="/files/GS37eDyJOvhSXW4za3V9" alt=""><figcaption></figcaption></figure></div>

### Theme & Brand

Customize the checkout theme color, brand logo, and other branding elements.

<figure><img src="/files/aoh7zGFOQrO36tzLwKF7" alt=""><figcaption></figcaption></figure>

## 4. Account & Webhooks

{% hint style="info" %}
Manage your account-related settings, including wallet bindings, event callback URLs, notifications, and developer or merchant information.
{% endhint %}

Go to **More → Account/Payouts** or **Integration/Hooks** to view and manage your developer information, webhook endpoints, and related configurations.

### Wallet payouts

{% hint style="info" %}
When creating a payment link, merchants will be prompted to link a settlement wallet.&#x20;

This step is required for merchants using fiat pay-in and stablecoin or crypto pay-out flows.
{% endhint %}

<figure><img src="/files/TK3VnQgwtJW0F6LJH6HM" alt=""><figcaption></figcaption></figure>

### Webhooks callback

Once your **Webhooks** are configured under **Developer Settings → Webhooks URLs**, CoindPay will automatically send webhook notifications to your specified endpoint whenever a payment event occurs (e.g., `completed`, `failed`, or `pending`).

Your server should handle these events, verify the request signature using your `API Secret` and update your own order database accordingly.

<figure><img src="/files/jj72FISrhkzyZyof3KS4" alt=""><figcaption></figcaption></figure>

{% hint style="warning" %}
The following example code how to handle webhook order data in a `Next.js` API route.

⚠️  Merchants and developers should pay special attention to verifying the `x-signature` request header and securely managing the private `API Secret` found in your **Developer Hooks** settings.

⚠️  The `API Secret` is used to validate the callback signature. When a transaction status changes, CoindPay sends a webhook request containing the transaction data.\
If you’re using callbacks, make sure to enable signature verification to ensure authenticity.

⚠️  To verify the signature, generate an HMAC SHA-256 hash using your `API Secret` and the **entire raw callback body** as input. Because the signature is generated based on the full payload, the request body must be used **exactly as received**, without any modification or parsing before signature verification.

⚠️  To avoid compatibility issues caused by data serialization differences across programming languages, please pay attention to how `rawBody` is handled in environments such as Node.js, Go, and Java.

⚠️  Before using webhooks and managing the order flow, ensure that your API secret has been generated and that it is correctly applied to the signature headers.
{% endhint %}

#### Local Debugging Mode

{% hint style="info" %}
If you have not yet obtained **Testnet sandbox IP access**, we also provide a **local debugging mode**. This allows you to effectively validate your **Webhook API integration** and end-to-end **order flow**.
{% endhint %}

<figure><img src="/files/b5MV5ZGUiO46DccFg4II" alt=""><figcaption></figcaption></figure>

> #### Below is a webhook API example based on <mark style="background-color:red;">Node (Next.js)</mark>
>
> <mark style="background-color:$primary;">Some code references</mark>[#code-with-parameters](#code-with-parameters "mention")

```typescript
// The unique ID from your front-end with the customers
const merchant_transaction_id = 'xxx' // See => Example with Parameters

// https://api.yourdomain.com/webhooks/payments/landing
import type { NextApiRequest, NextApiResponse } from 'next'
import getRawBody from 'raw-body'

// Refer to the utils code in the “Code with Parameters” ⬆️
import { createSignature } from '@/lib/utils' 

export const config = {
  api: {
    bodyParser: false, // ✅ Disable Next.js automatic body parsing
  },
}

export default async function landing(req: NextApiRequest, res: NextApiResponse) {
  if (req.method !== 'POST') {
    return res.status(405).json({ ok: false, message: 'Method not allowed ˙◠˙' })
  }
  
  try {
    const secretKey = process.env.COINDPAY_API_SECRET_KEY as string
    
    if (!secretKey) {
      throw new Error('Missing CoindPay API SECRET KEY in env ˙◠˙')
    }

    const signatureHeader = req.headers['x-signature'] as string

    if (!signatureHeader) {
      return res.status(400).json({
        ok: false,
        message: 'Invalid signature ˙◠˙',
      })
    }
    
    // 1. Retrieve the raw request body
    const rawBody = (await getRawBody(req)).toString('utf8')
    console.log('📦 raw body:', rawBody)
    
    // 2. Verify signature (must use rawBody for verification)
    const expectedSig = createSignature(secretKey, rawBody)

    if (signatureHeader !== expectedSig) {
      console.error(`🚫 x-signature mismatch:`, { expectedSig, got: signatureHeader })
      return res.status(401).json({ ok: false, message: 'Invalid signature ˙◠˙' })
    }
    
    // 3. Parse JSON payload after successful verification
    const data = JSON.parse(rawBody)
    console.log('💎 Parsed data:', data)
  
    if (!data || !data?.id) {
      return res.status(502).json({ ok: false, message: 'Invalid payment order ˙◠˙' })
    }
    
    console.log(`✅ CoindPay payment ${data?.id}-${data?.rampStatus} callback data：`, data)
    
    // post your order data to your db, create or poll for updates
    // const payment = await prisma.payment.upsert({
    //  where: { rampId: data.id },
    //  update: {
    //    ...data,
    //  },
    //  create: {
    //    ...data,
    //  },
    // })
    ....
  } catch (error) {
    console.error(`🚫 CoindPay order data storage failed:`, error?.message)
  }
}
```

> #### Webhooks Data Example（Selected statuses）[Full Order Fields](/landing/start/developers/payments-order.md#full-order-fields)

{% tabs %}
{% tab title="new" %}

```json
{
    "id": "69ae9bd******0de524430c",
    "createdAt": "2026-03-09T10:07:18.900Z",
    "updatedAt": "2026-03-09T10:07:40.021Z",
    "rampId": "SS2654******96s121",
    "rampStatus": "new",
    "rampType": "pay",
    "payMethod": "mobile_pay",
    "name": "andrew tim",
    "email": "hello@hotmail.com",
    "timezone": "Australia/Adelaide",
    "chain": "BSC",
    "amount": 14.147862,
    "usd": 15,
    "fiatAmount": 15,
    "fiatCoin": "USD",
    "symbol": "USDT",
    "payeeId": "-m3NiJQWM***F8Ih8K6IE",
    "appid": "693a61c42******e914fe691"
}
```

{% endtab %}

{% tab title="pending" %}

```json
{  
    "id": "69ae9bd******0de524430c",
    "createdAt": "2026-03-09T10:07:18.900Z",
    "updatedAt": "2026-03-09T10:07:44.932Z",
    "rampId": "SS2654******96s121",
    "rampStatus": "pending",
    "rampType": "pay",
    "payMethod": "google",
    "name": "andrew tim",
    "email": "hello@hotmail.com",
    "timezone": "Australia/Adelaide",
    "chain": "BSC",
    "amount": 14.147862,
    "usd": 15,
    "fiatAmount": 15,
    "fiatCoin": "USD",
    "symbol": "USDT",
    "payeeId": "-m3NiJQWM***F8Ih8K6IE",
    "appid": "693a61c42******e914fe691"
}
```

{% endtab %}

{% tab title="paid" %}

```json
{
    "id": "69ae9bd78974110de524430c",
    "createdAt": "2026-03-09T10:07:18.900Z",
    "updatedAt": "2026-03-09T10:08:10.242Z",
    "rampId": "SS2654******96s121",
    "rampStatus": "paid",
    "rampType": "pay",
    "payMethod": "google",
    "name": "andrew tim",
    "email": "hello@hotmail.com",
    "timezone": "Australia/Adelaide",
    "chain": "BSC",
    "amount": 14.147862,
    "usd": 15,
    "fiatAmount": 15,
    "fiatCoin": "USD",
    "symbol": "USDT",
    "payeeId": "-m3NiJQWM***F8Ih8K6IE",
    "appid": "693a61c42******e914fe691"
}
```

{% endtab %}

{% tab title="order\_scheduled" %}

```json
{
    "id": "69ae9bd******0de524430c",
    "createdAt": "2026-03-09T10:07:18.900Z",
    "updatedAt": "2026-03-09T10:08:09.065Z",
    "rampId": "SS2654******96s121",
    "rampStatus": "order_scheduled",
    "rampType": "pay",
    "payMethod": "google",
    "name": "andrew tim",
    "email": "hello@hotmail.com",
    "timezone": "Australia/Adelaide",
    "chain": "BSC",
    "amount": 14.147862,
    "usd": 15,
    "fiatAmount": 15,
    "fiatCoin": "USD",
    "symbol": "USDT",
    "payeeId": "-m3NiJQWM***F8Ih8K6IE",
    "appid": "693a61c42******e914fe691"
}
```

{% endtab %}

{% tab title="completed" %}

```json
{
    "id": "69ae9bd******0de524430c",
    "createdAt": "2026-03-09T10:07:18.900Z",
    "updatedAt": "2026-03-09T10:08:54.815Z",
    "settledAt": "2026-03-09T10:08:54.751Z",
    "rampId": "SS2654******96s121",
    "rampStatus": "completed",
    "rampType": "pay",
    "payer": "0x301D477Ec915B46C5561158Df1b5757A6CE22133",
    "payMethod": "google",
    "name": "andrew tim",
    "email": "hello@hotmail.com",
    "timezone": "Australia/Adelaide",
    "chain": "BSC",
    "amount": 14.147862,
    "reserveAmount": 0.707393,
    "afterReserveAmount": 13.440469,
    "usd": 14.147862,
    "fiatAmount": 15,
    "fiatCoin": "USD",
    "symbol": "USDT",
    "signature": "0xbd3f0e2a255b43301b5b8dc02ff3a953be4939c682e98ba4ceeff553bc055590",
    "payeeId": "-m3NiJQWM***F8Ih8K6IE",
    "appid": "693a61c42******e914fe691"
}
```

{% endtab %}

{% tab title="fialed" %}

```json
{
    "id": "69ae9bd******0de524430c",
    "createdAt": "2026-03-09T10:07:18.900Z",
    "updatedAt": "2026-03-09T10:08:50.815Z",
    "rampId": "SS2654******96s121",
    "rampStatus": "failed",
    "rampType": "pay",
    "payMethod": "google",
    "name": "andrew tim",
    "email": "hello@hotmail.com",
    "timezone": "Australia/Adelaide",
    "chain": "BSC",
    "amount": 14.147862,
    "usd": 14.147862,
    "fiatAmount": 15,
    "fiatCoin": "USD",
    "symbol": "USDT",
    "payeeId": "-m3NiJQWM***F8Ih8K6IE",
    "appid": "693a61c42******e914fe691"
}
```

{% endtab %}
{% endtabs %}

### Order status

#### Payments/On-Ramps Status Reference

> Below is a list of possible `rampStatus` values returned&#x20;
>
> when rampType=`buy` paymentMethod=[Payment methods](/landing/start/customers/payment-methods.md)

<table><thead><tr><th width="175.92578125">Status</th><th>Description</th></tr></thead><tbody><tr><td><code>init</code></td><td>User opened the payment window but hasn’t entered the payment stage and the order has not yet entered the processing flow.</td></tr><tr><td><code>new</code></td><td>A new transaction has been created. <br>Starting from the <code>new</code> status, merchants with configured webhooks will receive event notifications.</td></tr><tr><td><code>pending</code></td><td>Waiting for 3DS verification from the user.</td></tr><tr><td><code>paid</code></td><td>The payer’s card has been authorized and the funds have been deposited into the processing channel.<br>Final settlement and any conversion are subject to the issuing bank’s compliance and eligibility checks. If the bank declines, no funds will be captured.</td></tr><tr><td><code>order_scheduled</code></td><td>Indicates that the order has entered the processing queue.<br>This status only reflects queue placement — and no funds are reserved.</td></tr><tr><td><code>order_retry</code></td><td>The order was declined or cancelled due to <strong>legal, compliance, or banking constraints</strong>. The consumer attempts the payment again through <strong>an alternative recommended banking provider</strong>.</td></tr><tr><td><code>expired</code></td><td><p>Order has been created, customer has not made payment for the order within the expiry time. (Expiry times may differ for each payment method).</p><p>Expired orders can become active again. If payment is received after expiry, the order will automatically continue through the normal processing stages.</p></td></tr><tr><td><code>cancelled</code></td><td>The transaction was canceled, usually due to timeout or user action.</td></tr><tr><td><code>refunded</code></td><td>Order has been refunded by our customer support in response to a request from the customer.</td></tr><tr><td><code>failed</code></td><td>The transaction was rejected or declined by the bank. </td></tr><tr><td><code>settling</code></td><td>Funds have been authorized and are in the settlement process. The payout transaction has not yet been finalized on-chain.</td></tr><tr><td><code>settle_failed</code></td><td>Settlement attempt failed due to a transient or recoverable error. The order is eligible for retry（caused by RPC, network, or temporary infrastructure issues, retry may be triggered）</td></tr><tr><td><code>completed</code></td><td>✅ The merchant’s account has received the funds, and a receipt/invoice is sent to the customer’s email.<br>This status also serves as the final indicator that the order has successfully completed.</td></tr></tbody></table>

#### Off-Ramp Status Reference

> Below is a list of possible `rampStatus` values returned&#x20;
>
> when rampType=`sell` paymentMethod=`card`

| Status      | Description                                                                                                                                                    |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `init`      | User opened the payment window but hasn’t entered the payment stage and the order has not yet entered the processing flow.                                     |
| `new`       | <p>A new transaction has been created. <br>Starting from the <code>new</code> status, merchants with configured webhooks will receive event notifications.</p> |
| `pending`   | The transaction is in progress; payout processing has started.                                                                                                 |
| `failed`    | The transaction failed; the crypto amount will be returned to the user.                                                                                        |
| `completed` | ✅ The payout has been successfully transferred to the user’s card.                                                                                             |

💡 **Tips:**

1. Keeping your secret key safe, don't forget add the `.env` file to `.gitignore`
2. The <mark style="background-color:red;">rampId</mark> is required, from your front-end `merchant_transaction_id`
3. An order is successful only when its status is `completed`&#x20;

### Testnet config

> #### <mark style="background-color:purple;">Testnet Provider A - card list</mark> <a href="#sandbox-payment-card-details" id="sandbox-payment-card-details"></a>

Payout Asset：**ETH** on the EVM **Sepolia**（Prod environment configurations remain unaffected.）

<figure><img src="/files/rT0VEesTquLmgSSx5LNE" alt=""><figcaption></figcaption></figure>

{% stepper %}
{% step %}
**Card #1**

* Card Number `4444 4444 4444 3333`
* Expiration Date `any future date`
* CVV `123`
* Cardholder Name `name + surname`
  {% endstep %}

{% step %}
**Card #2**

* Card Number `5555 4444 3333 1111`
* Expiration Date `any future date`
* CVV `123` for success, `555` for fail
* Cardholder Name `name + surname`
  {% endstep %}
  {% endstepper %}

{% hint style="info" %}
If you encounter risk control or KYC interactions that affect the payment flow in the <kbd>Testnet</kbd> sandbox environment, you can use our official verification email: **<contact@coindpay.xyz>**\
In the regular payment environment, please use your own developer or customer email.
{% endhint %}

> #### <mark style="background-color:green;">Order Fallback Testnet Provider B - card list</mark> <a href="#sandbox-payment-card-details" id="sandbox-payment-card-details"></a>

Payout Asset：**USDT** on the EVM **BSC Testnet**（Prod environment configurations remain unaffected.）No changes to the payment link payout configuration are required in the test environment.

<div data-with-frame="true"><figure><img src="/files/nWYYfVlV2FAmE4RWDbPX" alt=""><figcaption></figcaption></figure></div>

**Visa**

| Card PAN         | 3-D Secure result                                         | Transaction result            |
| ---------------- | --------------------------------------------------------- | ----------------------------- |
| 4000000000000085 | 3-D secure version 2, challenge flow, full authentication | Payment has CONFIRMED status  |
| 4580000000000059 | 3-D secure version 2, frictionless flow, attempt          | Payment has CONFIRMED status  |
| 4000000000000093 | 3-D secure version 2, frictionless flow, success          | Payment has CONFIRMED status  |
| 4000000000000051 | No 3-D Secure                                             | Payment has AUTHORIZED status |
| 4000000000000077 | No 3-D Secure                                             | Payment has CONFIRMED status  |
| 4444444444444455 | 3-D secure version 2, challenge flow, full authentication | Payment has DECLINED status   |
| 4444444444449777 | No 3-D Secure                                             | Payment has DECLINED status   |

**Mastercard**

| Card PAN         | 3-D Secure result                                         | Transaction result            |
| ---------------- | --------------------------------------------------------- | ----------------------------- |
| 5100000000000065 | 3-D secure version 2, challenge flow, full authentication | Payment has CONFIRMED status  |
| 2400000000000069 | 3-D secure version 2, frictionless flow, attempt          | Payment has CONFIRMED status  |
| 5100000000000073 | 3-D secure version 2, frictionless flow, success          | Payment has CONFIRMED status  |
| 5100000000000651 | No 3-D Secure                                             | Payment has AUTHORIZED status |
| 2400000000000077 | No 3-D Secure                                             | Payment has CONFIRMED status  |
| 5555555555559955 | 3-D secure version 2, challenge flow, full authentication | Payment has DECLINED status   |
| 5555555555554477 | No 3-D Secure                                             | Payment has DECLINED status   |

> #### <mark style="background-color:orange;">Order Fallback Testnet Provider C - card list</mark> <a href="#sandbox-payment-card-details" id="sandbox-payment-card-details"></a>

Payout Asset：from your payment link configuration.

**🆔 KYC Data**

A first time customer will be guided through a KYC process during their first order with us. We suggested you input words and names that exist as opposed to random strings, as there are still some basic validations in place.

You may also be asked to upload Id documents. This can be any image with some text, captured using your device. This will not be verified, however will need to be in high resolution.

<figure><img src="/files/6umDS4jyVM37UHvd9pmJ" alt=""><figcaption></figcaption></figure>

**Card #1**

| Field         | Value                                         |
| ------------- | --------------------------------------------- |
| Card Name     | Use the name that you provided as part of KYC |
| Card Number   | 4111 1111 1111 1111                           |
| Expiry        | Any expiry date in the future                 |
| Security Code | Any                                           |

### <mark style="background-color:red;">Demo video（Payments）</mark>

{% file src="/files/ckFjq4sRV5naX9Bba90N" %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.coindpay.xyz/landing/start/developers/integration.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
