Skip to main content
BVNK

Receive stablecoin payments

Beta

The Payments v.3 API endpoints are in beta and may change as we enhance the product. See Migrate crypto payments from v.1 for background on this project.

Using BVNK's Receive products, you can collect crypto payments from your customers, allowing them to top up accounts or purchase goods and services from you whilst BVNK manages the conversion and settlement to your accounts.

BVNK stablecoin payments are perfect, when:

  • You need to collect payments from your customers and you want stablecoins to be an option so that you can unlock additional markets and user segments.
  • As a Neobank or PSP serving businesses and individuals you want to allow your customers to send stablecoins to top up their account.

Every BVNK pay-in has two sides: your customer is the originator, the one paying, and you're the beneficiary, whose wallet is credited. BVNK supports various pay-in combinations to meet different business needs:

  • Crypto converted and received in fiat: Accept stablecoin payments from customers and receive fiat currency in your account.
  • Crypto converted and received in a different crypto: Accept one type of stablecoin and receive a different crypto currency in your account.
  • Crypto paid in the same currency: Accept stablecoin payments and receive the same stablecoin type in your account.

There are two methods to collect payments from your customers:

  • Payment Links / Checkout: For every payment, BVNK generates a live quote to be accepted by the customer and a unique blockchain address for the payment to be made to.

    Best for gaming, trading, or e-commerce platforms where the customer needs to send the exact amount of cryptocurrency or stablecoins to purchase an item, given the market rate at that point.

See the respective tabs for more details on the workflow.

info

Before you start Make sure you've followed the Getting Started guide, so that you have your account set up, API keys generated, and a wallet ID ready to be used.

For this method, you will use the BVNK-hosted payments page, as it is the fastest way to add crypto to your payment flows. A single POST /payment/v3/payins call returns both the deposit instructions and the hosted page URL.

Payments pass the following statuses throughout the workflow:

StatusImmutable?Description
PENDING_QUOTE_ACCEPTANCE (conditional)❌Only reached if you create the payin without a chosen currency and network. The customer has not yet picked one and accepted a priced quote on the hosted page.
PENDING_CUSTOMER_PAYMENT❌Initial status when the currency and network are known at creation. The payin is priced and waiting for the customer to send funds.
PENDING_VERIFICATION (conditional)❌The payment is fully priced with the rate locked, and is waiting on the end customer to confirm it. Only occurs if your account is configured for it.
PENDING_INFO (conditional)❌BVNK needs more information from you to release the payment. Only occurs if a Request for Information is triggered.
PROCESSING❌BVNK has detected the customer's payment on the blockchain and is processing it toward your wallet. The payment can still expire from here if the customer sent insufficient gas or confirmations don't complete within the expiry window.
HELD❌Held for compliance reasons. Reversible: a held payment returns to PROCESSING once cleared.
COMPLETED✅Full amount has been received and credited to your wallet in the beneficiary currency. May carry labels: ["OVER"] or labels: ["UNDER"], see below.
FAILED✅The payment was attempted from PROCESSING and did not succeed.
EXPIREDUsually ✅No funds arrived before the payment's expiry window. If a payment later arrives, the same payin can still move on to PROCESSING and COMPLETED, see below.

A payin that receives the wrong amount still reaches COMPLETED; the mismatch is captured in labels[] instead:

  • An overpaid payin carries labels: ["OVER"]. BVNK creates a linked payout for the difference and references it in relatedPayments[].
  • An underpaid payin carries labels: ["UNDER"], with no linked payout: the shortfall is simply not credited.
  • A payin that arrives after EXPIRED but still completes carries labels: ["LATE"], and statusHistory[] shows the full detour through EXPIRED and back to PROCESSING. This is why EXPIRED is only usually immutable.

For example, a payin asking for 223.05 EUR that receives more ETH than the rate required completes like this:

Response excerpt: overpaid payin
{
"status": "COMPLETED",
"originator": {
"required": { "currency": "ETH", "amount": "0.13275995" },
"actual": { "currency": "ETH", "amount": "0.14500000" }
},
"beneficiary": {
"required": { "currency": "EUR", "amount": "223.05" },
"actual": { "currency": "EUR", "amount": "223.05" }
},
"checkout": {
"required": { "currency": "EUR", "amount": "223.05" },
"actual": { "currency": "EUR", "amount": "243.61" }
},
"labels": ["OVER"],
"relatedPayments": [
{ "type": "payment:payout", "paymentId": "d4f81c66-3a29-4b7e-9c05-8e2f1a7b6d30" }
]
}

See Handle exception scenarios for how to handle each label, and Receive stablecoins via Payment Links for the full create and retrieve flow.


Ready to start? Once you have completed all prerequisites above, you can proceed with the integration:

Was this page helpful?