Creating a payment

To create a payment, you will need to use the Create payment endpoint.

{
    "merchantId": "86955f40-8f4e-464c-be2b-583635bf1c62",
    "type": "IN",
    "amount": 10,
    "currency": "USD",
    "expiryMinutes": 30,
    "reference": "test_reference_in_Qa4wy9",
    "returnUrl": "https://your-url-here.com/status",
    "payInDetails": {
        "currency": "USDT"
    },
    "customerId": "ba388054-4512-441e-a9c4-cbe9b0fe0332",
    "complianceDetails": {
        "requesterIpAddress": "77.71.188.87",
        "partyDetails": [
            {
                "type": "ORIGINATOR",
                "entityType": "INDIVIDUAL",
                "firstName": "John",
                "lastName": "Doe",
                "dateOfBirth": "1984-06-30",
                "relationshipType": "THIRD_PARTY",
                "countryCode": "DE"
            }
        ]
    }
}

Let's go through the details you'll need to supply in the create payment request

ParameterTypeRequiredDescription
merchantIdstringYesYour Merchant ID. You can find it on the Merchant Details page in your account.

See this guide for creating one
referencestringYesA reference you and your customer will see relating to the payment. This can be anything you like.
amountlongYesThe amount required to complete the payment.
currencystringYesThe currency code that you want to display the price to the end-user in.
returnUrlstringNoA URL that will be used to redirect the user if they click "back to merchant" in the payment flow.
typestringYesDictates whether you are creating a Pay IN or a Pay OUT - in this case, we are using IN to create a Pay IN.
expiryMinutesintegerNoThe amount of time you are giving the end-user to pay in. If no expiry minutes specified in your request, BVNK will default it to 20 minutes.
payInDetails.currencystringNoUse this to skip the cryptocurrency selection screen if you already know which currency your end-user is paying in. Don't send this variable if you want to give your customer the choice.
payInDetails.protocolstringNoProtocol is strictly required when supplying payInDetails.currency. The list of supported protocols per currency is available here.

Optional: Including Metadata

You can include custom metadata in your payout request. This metadata will be associated with the payout and will be included in webhook events related to this payout. To add metadata, include a top-level JSON object with the key "metadata". The value of this key should be another JSON object containing your desired key-value pairs.

Example request including metadata


{
    "merchantId": "86955f40-8f4e-464c-be2b-583635bf1c62",
    "type": "IN",
    "amount": 10,
    "currency": "USD",
    "expiryMinutes": 30,
    "reference": "test_reference_in_Qa4wy9",
    "returnUrl": "https://your-url-here.com/status",
    "payInDetails": {
        "currency": "USDT"
    },
    "customerId": "ba388054-4512-441e-a9c4-cbe9b0fe0332",
    "complianceDetails": {
        "requesterIpAddress": "77.71.188.87",
        "partyDetails": [
            {
                "type": "ORIGINATOR",
                "entityType": "INDIVIDUAL",
                "firstName": "John",
                "lastName": "Doe",
                "dateOfBirth": "1984-06-30",
                "relationshipType": "THIRD_PARTY",
                "countryCode": "DE"
            }
        ]
    },
    "metadata": {
        "orderId": "PO-2025-001",
        "internalUserId": "user-456",
        "reason": "Customer withdrawal"
    }
}

Metadata Rules:

When you add extra information (metadata) to your request, please keep the following in mind:

Maximum Number of Entries: You can include up to 10 separate pieces of metadata (key-value pairs).

Key Requirements:

Cannot be empty: Each metadata key must have at least one character.
Maximum Length: Each metadata key can be up to 40 characters long.
Allowed Characters: Metadata keys can only contain:
Uppercase letters (A-Z)
Lowercase letters (a-z)
Numbers (0-9)
Underscores (_)
Hyphens (-)
Value Requirements:

Cannot be empty: Each metadata value must be provided.
Maximum Length: Each metadata value can be up to 255 characters long.
Disallowed Characters: Metadata values cannot contain the characters < or >.


After submitting this successfully, you'll receive the following response (and optional metadata if included)

{
    "uuid": "3332388b-43cd-45a1-ad1b-7df5e5f4dc6e",
    "merchantDisplayName": "Euro Company",
    "merchantId": "86955f40-8f4e-464c-be2b-583635bf1c62",
    "dateCreated": 1728647621633,
    "expiryDate": 1728649421633,
    "quoteExpiryDate": 1728649422000,
    "acceptanceExpiryDate": 1728647652000,
    "quoteStatus": "ACCEPTED",
    "reference": "test_reference_in_Qa4wy9",
    "type": "IN",
    "subType": "merchantPayIn",
    "status": "PENDING",
    "displayCurrency": {
        "currency": "USD",
        "amount": 10,
        "actual": 0
    },
    "walletCurrency": {
        "currency": "EUR",
        "amount": 9.15,
        "actual": 0
    },
    "paidCurrency": {
        "currency": "USDT",
        "amount": 10.008422,
        "actual": 0
    },
    "feeCurrency": {
        "currency": "EUR",
        "amount": 0.09,
        "actual": 0
    },
    "networkFeeCurrency": null,
    "displayRate": {
        "base": "USDT",
        "counter": "USD",
        "rate": 0.999158508704
    },
    "exchangeRate": {
        "base": "USDT",
        "counter": "EUR",
        "rate": 0.91423
    },
    "address": {
        "address": "0x7b686317f8ed2c2bc3bbd060464f1939359a00e3",
        "tag": null,
        "protocol": "ERC20",
        "uri": "ethereum:0xdac17f958d2ee523a2206206994597c13d831ec7/transfer?address=0x7b686317f8ed2c2bc3bbd060464f1939359a00e3&uint256=10008422",
        "alternatives": [
            {
                "address": "0xab12ec2f0e47c45ac8ff0c3914fb426d5ef9541a",
                "tag": null,
                "protocol": "BEP20",
                "uri": "0xab12ec2f0e47c45ac8ff0c3914fb426d5ef9541a",
                "alternatives": []
            },
            {
                "address": "0x3f2b71f5cbca1e4cda0948208f67706a1a519c8e",
                "tag": null,
                "protocol": "POLYGON",
                "uri": "0x3f2b71f5cbca1e4cda0948208f67706a1a519c8e",
                "alternatives": []
            },
            {
                "address": "TYbVJodUGrkWJSWSVnHjXHU6g8RC7AvPE6",
                "tag": null,
                "protocol": "TRC20",
                "uri": "TYbVJodUGrkWJSWSVnHjXHU6g8RC7AvPE6",
                "alternatives": []
            }
        ]
    },
    "returnUrl": "https://your-url-here.com/status",
    "redirectUrl": "https://pay.sandbox.bvnk.com/payin?uuid=3332388b-43cd-45a1-ad1b-7df5e5f4dc6e",
    "transactions": [],
    "refund": null,
    "refunds": [],
    "currencyOptions": [],
    "flow": "DEFAULT",
    "twoStep": false,
  	"metadata": {
      "deviceType": "desktop",
      "sessionId": "abcdef123456",
      "userSegment": "premium",
      "campaignId": "promo-spring-2025"
    },
  "customerId": "ba388054-4512-441e-a9c4-cbe9b0fe0332"
}

Take note at this step of the redirectURL variable as we will be using this in the next step to redirect the end-user to the payment page.