Skip to main content
BVNK

Receive stablecoins via Payment Links

Beta

The Payments v.3 API endpoints are currently in beta and may change as the product evolves. For more information, see Migrate crypto payments from v.1.

Use this method to integrate crypto payments into your checkout flow and collect payments from customers. You can build a custom UI using the API response or redirect users to a pre-built Hosted Payments Page.

Example use case: This flow is ideal for platforms that collect payments from customers. For example, a trading platform can implement a deposit feature, enabling customers to top up their accounts for futures trading. Customers access the cashier, select cryptocurrency as the payment method, and enter the deposit amount. They are then redirected to the Hosted Payments Page to choose the cryptocurrency for the deposit. In this scenario, BVNK serves as the cryptocurrency payment provider.

Each payment on /payment/v3/payins involves two parties: the customer, referred to as the originator, and you, the beneficiary, whose wallet receives the funds. BVNK generates deposit instructions for the customer, monitors the blockchain for the incoming transaction, and then converts and settles the payment into your wallet in fiat, a different stablecoin, or the same stablecoin, according to your preference.

Collect payments​

To accept stablecoin payments from customers, follow these steps:

  1. Send a POST /payment/v3/payins request with a body similar to the example below. Specify your wallet in beneficiary.walletId, and include the customer's currency, compliance details, and network under originator.

    Request: POST /payment/v3/payins
    {
    "reference": "myUniqueRef333",
    "expiryDuration": "PT20M",
    "originator": {
    "currency": "ETH",
    "customerId": "d063635e-0f83-4e47-a1f3-fc9484df1509",
    "requesterIpAddress": "172.16.254.1",
    "entity": {
    "type": "COMPANY",
    "legalName": "BVNK LTD",
    "registrationNumber": "5493001KJTIIGC8Y1R12",
    "relationshipType": "SELF_OWNED",
    "address": {
    "country": "GB"
    }
    },
    "paymentInstrument": {
    "type": "CRYPTO_ADDRESS",
    "network": "ETHEREUM"
    }
    },
    "beneficiary": {
    "walletId": "a:24092328494070:G5i4XZ9:1"
    },
    "checkout": {
    "amount": "223.05",
    "currency": "EUR",
    "returnUrl": "https://my-shop.com/payment-complete?ref=xyz"
    }
    }

    originator.currency and originator.paymentInstrument.network specify the currency and network the customer will use for payment, as determined in this example. checkout.amount and checkout.currency represent the displayed payment value, which is 223.05 EUR here. BVNK calculates the required ETH amount based on this value, following the "fix one currency" rule applied throughout the v.3 payments platform.

    tip

    Instead of including entity with each payment, you can create a reusable contact and reference it using originator.contactId. For more information, see Manage contacts. Provide either entity or originator.contactId, but not both; requests containing both will be rejected.

    You can restrict available currencies for your customer using checkout.currencyOptions[]. This field is optional. If you omit both originator.currency and checkout.currencyOptions[], the customer can deposit funds in any supported currency, selecting their preference on the hosted page. For a complete list of supported currencies and networks, refer to the Supported Currencies API.

    The following example restricts the customer's options to ETH on Ethereum, or USDT on Ethereum or Tron:

    Request: restricting available currencies
    {
    "reference": "myUniqueRef340",
    "expiryDuration": "PT20M",
    "beneficiary": {
    "walletId": "a:24092328494070:G5i4XZ9:1"
    },
    "checkout": {
    "amount": "223.05",
    "currency": "EUR",
    "currencyOptions": [
    {
    "currency": "ETH",
    "network": ["ETHEREUM"]
    },
    {
    "currency": "USDT",
    "network": ["ETHEREUM", "TRON"]
    }
    ],
    "returnUrl": "https://my-shop.com/payment-complete?ref=xyz"
    }
    }

    Each entry includes a network[] array of chain names, such as "ETHEREUM" or "TRON".

    After submitting the request successfully, you receive the following response:

    Response
    Response: 201 Created
    {
    "id": "3A6FAFFA-F21D-416E-B17E-2529A9BC44A0",
    "reference": "myUniqueRef333",
    "type": "payment:payin",
    "direction": "IN",
    "status": "PENDING_CUSTOMER_PAYMENT",
    "method": "CRYPTO",
    "fees": {
    "customerFee": null,
    "processingFee": { "estimated": { "currency": "EUR", "amount": "1.12" }, "actual": null },
    "networkFee": null
    },
    "originator": {
    "required": { "currency": "ETH", "amount": "0.13275995" },
    "actual": null,
    "customerId": "d063635e-0f83-4e47-a1f3-fc9484df1509",
    "customerReference": null,
    "requesterIpAddress": "172.16.254.1",
    "entity": {
    "type": "COMPANY",
    "legalName": "BVNK LTD",
    "registrationNumber": "5493001KJTIIGC8Y1R12",
    "relationshipType": "SELF_OWNED",
    "address": { "country": "GB" }
    },
    "paymentInstrument": {
    "type": "CRYPTO_ADDRESS",
    "network": "ETHEREUM",
    "addresses": [],
    "tag": null
    }
    },
    "beneficiary": {
    "required": { "currency": "EUR", "amount": "223.05" },
    "actual": null,
    "walletId": "a:24092328494070:G5i4XZ9:1"
    },
    "conversion": {
    "type": "QUOTE",
    "baseRate": "1688.54",
    "allInRate": "1680.1",
    "spread": {
    "percentage": "0.005",
    "amount": "1.12",
    "currency": "EUR"
    },
    "validityDuration": "PT60M",
    "expiresAt": "2026-03-14T21:43:23Z"
    },
    "instructions": [
    {
    "type": "CRYPTO",
    "network": "ETHEREUM",
    "currency": "ETH",
    "amount": "0.13275995",
    "address": "0xb794f5ea0ba39494ce839613fffba74279579268",
    "tag": null,
    "uri": "ethereum:0xb794f5ea0ba39494ce839613fffba74279579268?value=1.3276e17"
    }
    ],
    "checkout": {
    "required": { "currency": "EUR", "amount": "223.05" },
    "actual": null,
    "displayRate": {
    "from": "ETH",
    "to": "EUR",
    "rate": "1680.1"
    },
    "redirectUrl": "https://pay.bvnk.com/payin/3A6FAFFA-F21D-416E-B17E-2529A9BC44A0",
    "returnUrl": "https://my-shop.com/payment-complete?ref=xyz"
    },
    "trackingDetails": [],
    "labels": [],
    "relatedPayments": [],
    "statusHistory": [
    { "status": "PENDING_CUSTOMER_PAYMENT", "timestamp": "2026-03-14T20:43:23Z" }
    ],
    "metadata": {},
    "expiryDuration": "PT20M",
    "expiresAt": "2026-03-14T21:03:23Z",
    "updatedAt": "2026-03-14T20:43:23Z",
    "createdAt": "2026-03-14T20:43:23Z"
    }

    In this response:

    • checkout.redirectUrl directs customers to the Hosted Payments Page to select their digital asset.
    • instructions[] contains deposit instructions, with one entry for each accepted currency and network combination. In this example, there is only one entry because both the currency and network were specified at creation. If you allow the customer to choose using checkout.currencyOptions[], the array will include one entry for each permitted currency and network combination.
    • labels[] and relatedPayments[] are empty in this example because the payment has not yet settled.
  2. Once the customer sends the required amounts, track the payment by:

  • Polling GET /payment/v3/payins/{id}, or

    Response
    Response: GET /payment/v3/payins/3A6FAFFA-F21D-416E-B17E-2529A9BC44A0
    {
    "id": "3A6FAFFA-F21D-416E-B17E-2529A9BC44A0",
    "reference": "myUniqueRef333",
    "type": "payment:payin",
    "direction": "IN",
    "status": "COMPLETED",
    "method": "CRYPTO",
    "fees": {
    "customerFee": null,
    "processingFee": { "estimated": { "currency": "EUR", "amount": "1.12" }, "actual": { "currency": "EUR", "amount": "1.12" } },
    "networkFee": null
    },
    "originator": {
    "required": { "currency": "ETH", "amount": "0.13275995" },
    "actual": { "currency": "ETH", "amount": "0.13275995" },
    "customerId": "d063635e-0f83-4e47-a1f3-fc9484df1509",
    "customerReference": null,
    "requesterIpAddress": "172.16.254.1",
    "entity": {
    "type": "COMPANY",
    "legalName": "BVNK LTD",
    "registrationNumber": "5493001KJTIIGC8Y1R12",
    "relationshipType": "SELF_OWNED",
    "address": { "country": "GB" }
    },
    "paymentInstrument": {
    "type": "CRYPTO_ADDRESS",
    "network": "ETHEREUM",
    "addresses": [
    "0x3f5ce5fbfe3e9af3971dd833d26ba9b5c936f0be"
    ],
    "tag": null
    }
    },
    "beneficiary": {
    "required": { "currency": "EUR", "amount": "223.05" },
    "actual": { "currency": "EUR", "amount": "223.05" },
    "walletId": "a:24092328494070:G5i4XZ9:1"
    },
    "conversion": {
    "type": "QUOTE",
    "baseRate": "1688.54",
    "allInRate": "1680.1",
    "spread": {
    "percentage": "0.005",
    "amount": "1.12",
    "currency": "EUR"
    },
    "validityDuration": "PT60M",
    "expiresAt": "2026-03-14T21:43:23Z"
    },
    "instructions": [
    {
    "type": "CRYPTO",
    "network": "ETHEREUM",
    "currency": "ETH",
    "amount": "0.13275995",
    "address": "0xb794f5ea0ba39494ce839613fffba74279579268",
    "tag": null,
    "uri": "ethereum:0xb794f5ea0ba39494ce839613fffba74279579268?value=1.3276e17"
    }
    ],
    "checkout": {
    "required": { "currency": "EUR", "amount": "223.05" },
    "actual": { "currency": "EUR", "amount": "223.05" },
    "displayRate": {
    "from": "ETH",
    "to": "EUR",
    "rate": "1680.1"
    },
    "redirectUrl": "https://pay.bvnk.com/payin/3A6FAFFA-F21D-416E-B17E-2529A9BC44A0",
    "returnUrl": "https://my-shop.com/payment-complete?ref=xyz"
    },
    "trackingDetails": [
    {
    "amount": "0.13275995",
    "currency": "ETH",
    "hash": "0x975ca9788bd6b82e45414e8a7734a39780ed4bf519d41c85eb58f2dd0501df33",
    "network": "ETHEREUM",
    "createdAt": "2026-03-14T20:49:23Z",
    "confirmedAt": "2026-03-14T20:50:23Z"
    }
    ],
    "labels": [],
    "relatedPayments": [],
    "statusHistory": [
    { "status": "PENDING_CUSTOMER_PAYMENT", "timestamp": "2026-03-14T20:43:23Z" },
    { "status": "PROCESSING", "timestamp": "2026-03-14T20:49:23Z" },
    { "status": "COMPLETED", "timestamp": "2026-03-14T20:50:23Z" }
    ],
    "metadata": {},
    "expiryDuration": "PT20M",
    "expiresAt": "2026-03-14T21:03:23Z",
    "updatedAt": "2026-03-14T20:50:23Z",
    "createdAt": "2026-03-14T20:43:23Z"
    }
  • Subscribing to the payin status-change webhook as an alternative to polling.

    If the payment amount is incorrect or arrives late, labels[] will be populated with OVER, UNDER, or LATE instead of a separate status. relatedPayments[] links an overpaid payin to the corresponding refund payout created by BVNK. For a complete reference of statuses and labels, see Receive stablecoin payments.


Provide additional party information​

You may also need to provide additional party information to comply with the Travel Rule. See the Provide additional party information guide for more details.


Handle errors​

If a customer sends funds in an incorrect currency or on the wrong network, BVNK may not process the payment. You should display a disclaimer instructing customers to use the correct currency and network, as incorrect payments may be declined or result in lost funds. The instructions[] array provides the exact currencies and networks BVNK will accept for each payment. Displaying this information directly is the most reliable way to prevent errors.

Was this page helpful?