Vantack API

To enable third-party platforms to integrate Vantack's capabilities, we've meticulously designed a comprehensive and flexible API structure. Our API facilitates easy integration, providing developers with the tools to incorporate blockchain payment solutions into their applications.

Core API Components

  • Secure Authentication: Utilizing API keys we ensure secure and authorized access to our services.
  • Blockchain Interaction: Developers can easily select networks, manage tokens, and authorize transactions, offering unparalleled flexibility across blockchains.
  • Dynamic Payment Processing: Our API supports the creation and management of various payment types, including one-time invoices, recurring subscriptions, and usage-based billing, with built-in support for handling overdue payments.

Introduction

The Vantack API is organized around REST. The API uses resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and relies on standard HTTP response codes, authentication, and verbs.

You can use the API in a development mode that doesn't affect your live data or interact with live networks. The API key you use to authenticate each request determines whether the request is treated as live or test.

The API doesn't support bulk updates β€” you operate on a single object per request. This keeps requests predictable and easier to reason about.

Authentication

Vantack has implemented a secure, API key–based authentication system for API access. Here’s an overview:

API Access

  • The API key must be included in the HTTP headers of each request to authenticate.
  • All API interactions require HTTPS to ensure the security of data in transit.

Security and Monitoring

  • The system enforces rate limiting based on API keys to prevent abuse.
  • API requests are logged for security and monitoring purposes.
  • Keys are stored securely, with encryption applied to sensitive information.

This authentication system is designed to ensure secure and controlled access to the Vantack API, giving users the ability to manage their API keys directly for increased security and flexibility.

All API requests must include the following headers for authentication:

  • Merchant-ID: The unique identifier assigned to each merchant.
  • API-Key: The API key generated through the merchant dashboard.
Merchant-ID: <your-merchant-id>
API-Key: <your-api-key>
    

Generating API keys

To generate and manage your API keys:

For Production

For Development

Note: API keys can be disabled but not re-enabled. To disable an API key, go to the Your API Keys page, locate the key you wish to disable, and click Disable. You cannot use the same API key on both development and production services.

Testing the API

Vantack provides a full test environment so you can develop and test your integration without affecting live data or spending real tokens.


⚠️ Important: You must use credentials from the test environment β€” not production. Log in to the test dashboard at https://app.vantack.com, generate an API key there, and copy the Merchant-ID from that test account. Production credentials will not work against the test API.


All API routes documented in this guide can be tested by using the test API base URL:

https://test-api.vantack.com/

Simply replace the production API host with the test host above for any route. For example, to create a purchase session in the test environment:

POST https://test-api.vantack.com/v1/purchase/session/start

Making a Test Payment

Follow these steps to test a complete payment flow using testnet tokens and the test API.

Step 1 β€” Create or Log Into Your Test Account

Go to https://app.vantack.com and either create a new account or sign in with an existing one. This is the account you will use to make test purchases.

Step 2 β€” Find Your Wallet Address

Once signed in, locate your default wallet address in your account. Copy this address β€” you will need it to request test tokens.

Step 3 β€” Fund Your Wallet with Test USDC

Before you can complete any test payment, your wallet must already have test tokens. Fund it ahead of time using the Circle faucet:

  1. Visit faucet.circle.com.
  2. Select Polygon PoS Amoy as the network.
  3. Paste your wallet address from Step 2.
  4. Request test USDC β€” the tokens will arrive in your wallet within a few seconds.

⚠️ Always fund your wallet before starting the checkout flow. Do not attempt to add tokens during the checkout process.

Step 4 β€” Test a Purchase End to End

With your wallet funded and your test API credentials ready, you can now test the full payment flow:

  1. Create a Purchase Session β€” call POST /v1/purchase/session/start against the test API using your test Merchant-ID and API-Key. See the Create A Purchase Session section for the full request body.
  2. Open the checkout URL β€” the API response includes a url field (e.g. https://test-buy.vantack.com/checkout/76db1abbe9). Open this URL in your browser.
  3. Complete the payment β€” sign in on the checkout page with the same account you funded in Step 3. Your test USDC will be available to complete the purchase.

This flow lets you test every part of the integration β€” from session creation to on-chain payment β€” using real API calls and testnet tokens, without spending real funds.

Getting started

Before you make your first API call, decide how you want to integrate Vantack into your product β€” as a full checkout experience, a simple commerce button, or a fully headless flow.

All of the endpoints in this section are designed to be easy to wire into your existing stack so you can start accepting on‑chain payments without rebuilding your application from scratch.

Commerce integration

The Commerce integration gives you a complete hosted checkout experience with minimal setup. The routes in this section are designed to work together in a clear sequence β€” each one building on the last so you can go from accepting your first payment to handling refunds and recurring billing in a single flow.


Create a Purchase Session

Start by calling Create a Purchase Session. The response returns a url field β€” this is your hosted checkout link. You can open it in a new tab, a modal, or embed it in an iframe. The customer completes payment entirely on the hosted page; you don't handle any wallet logic yourself.

Listen for Payment Webhooks

Once the customer pays, your webhook endpoint receives either a Payment event (success) or a Failed Payment event. Use these to fulfill orders, send receipts, update your database, or retry failed charges. The webhook payload includes everything you need β€” you don't need to poll any API.

Need to query payment history or look up a specific transaction? The Payments API has retrieval endpoints β€” since the webhook already delivers this data, these are optional but useful for backfills and audits.

Cancel an Agreement Recurring only

For recurring payments, a billing agreement is created on the customer's first payment. When a customer wants to stop being charged β€” either triggered by them or by you β€” call Cancel an Agreement with the agreement_id from the webhook payload. No further charges will be made.

Need to retrieve agreement details or list all active agreements? The Agreements API provides full agreement data β€” the webhook delivers the essentials, but this is handy for building a subscription management UI.

Issue a Refund via Transfer

To refund a customer, use Create Transfer Request. Pass the customer's registered email or wallet address in to_address, set the amount and token, and the funds are sent directly from your merchant wallet β€” no signatures required (within your configured allowance).

After the transfer executes, your webhook endpoint receives a Wallet Transfer event confirming the transaction hash and final status.

Create a Purchase Session

The Create endpoint allows you to create a new payment request and retrieve URLs for making and monitoring payments. If the request is associated with an agreement, the system first checks whether it can be automatically processed according to the agreement rules. If it cannot be processed automatically, a unique payment URL will be generated where the user can complete the payment manually.

In production, the minimum scheduling frequency for recurring payments is once per day. In the test environment, you can schedule as frequently as once per minute for development and testing.

There are two types of Purchase Session requests: one for single payments and the other for recurring payments.

Endpoint

POST https://api.vantack.com/v1/purchase/session/start

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Body Parameters

NameTypeDescription
name string Required
Shown to payer on payment screen.
details string Required
Shown to payer on payment screen.
amount number Required
Amount of currency.
currency string Optional
Defaults to USD. Can use another currency type.
recurring boolean Optional
Set to true if used for a subscription. Defaults to false.
interval string Required if recurring
Frequency unit for recurring charges.
Enum: DayWeekMonthYear
frequency string Optional
Number of intervals between each charge. For example, 2 with interval: Day means every 2 days.
Enum: EveryEvery OtherEvery ThirdEvery FourthEvery FifthEvery SixthEvery Seventh
Duration string Optional
Number of intervals the subscription will run before ending. 0 means no fixed end.
success_url string Optional
URL to redirect the payer upon successful payment.
cancel_url string Optional
URL to redirect the payer if they cancel the payment process.
expires_in_hours number Optional
Number of hours before the payment request expires. After expiration, no purchase or signature submission requests will be processed.
metadata object Optional
Arbitrary key-value pairs you provide. Returned in every webhook for both success and failure events. Use this to tie events to records in your system (e.g. set customerId to link all webhooks to a customer).

Request body example

{
  "name": "New Test",
  "details": "USDC Test",
  "currency": "USDC",
  "recurring": false,
  "amount": 0.03,
  "metadata": {
    "sku": "USDC Test"
  },
  "success_url": "www.google.com",
  "cancel_url": "www.google.com"
}
{
  "name": "New Test",
  "details": "USDC Test",
  "currency": "USDC",
  "recurring": true,
  "amount": 0.05,
  "metadata": {
    "customerId": "111"
  },
  "success_url": "www.google.com",
  "cancel_url": "www.google.com",
  "interval": "Month",
  "frequency": "Every",
  "Duration": "Until Cancelled",
  "expires_in_hours": 5
}

Response

{
  "data": {
    "amount": 0.05,
    "cancel_url": "www.google.com",
    "created": 1773454642,
    "currency": "USDC",
    "details": "USDC Test",
    "expires_at": 1773472642,
    "expires_in_hours": 5,
    "message": "Purchase session created successfully",
    "metadata": {
      "customerId": "111"
    },
    "name": "New Test",
    "purchase_session_id": "sess_e649ebf7-ce74-43bc-9e7f-7e9d17411354",
    "status": "session_created",
    "success_url": "www.google.com",
    "updated": 1773454642,
    "url": "https://buy.vantack.com/checkout/8b4d08bb87"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Payment

When a customer makes a successful payment, your server receives a webhook notification. Use this event to fulfill orders, provision access, or trigger any downstream logic.

Every webhook includes an X-Event-Id header that uniquely identifies the event. You can use this to safely deduplicate deliveries on your end.

Payload Fields

NameTypeDescription
type string
"payment" β€” type of action being executed.
merchant_id string
Unique identifier for the merchant.
origin_id string
Unique identifier for the payment's origin.
origin string
Source of the payment. Values: "purchase_sessions" or "subscriptions".
name string
Name of the purchase item.
currency string
Symbol for the currency used (e.g. "USDC", "USDT").
amount number
The amount the customer paid, excluding fees.
metadata object
Arbitrary key-value pairs attached to the payment (if any).
payment_date string
Date and time the payment was made.
status string
"completed".
payment_id string
The ID of the payment object. Use this to retrieve full transaction details.
transaction_details object
Information about the on-chain transaction.
user object
Information about the customer.
agreement_id string
ID of the purchase agreement.

Payload example

{
  "type": "payment",
  "merchant_id": "mrch_10d3ed3c-2471-4573-ac66-ec7e3b414e80",
  "origin_id": "161",
  "origin": "subscriptions",
  "name": "New Test",
  "currency": "USDC",
  "amount": 0.1,
  "metadata": null,
  "payment_date": "2025-08-18T08:37:59.229191Z",
  "status": "completed",
  "transaction_details": {
    "transaction_id": 343,
    "transaction_hash": "0x15c4308c3f55e7ef13d062e0784ec30181a400a2ac92bfac849443c486d33963",
    "chain_id": 84532
  },
  "user": {
    "first_name": "Test",
    "last_name": "Test",
    "email": "test@gmail.com",
    "subscriber_id": "1d5faea9-306c-488d-b2f9-b00b2e8cd414"
  },
  "payment_id": "paym_6f7a1c13-706c-4df3-a566-6a8ced58ccfc",
  "agreement_id": "agre_0a5578b2-b76b-4d8c-b568-4ec7442a21dc"
}

Failed Payment

When a payment attempt fails, your server receives a webhook. Multiple failed attempts for the same payment share the same payment_id but each carries a unique X-Event-Id header β€” use that to tell individual attempts apart.

Payload Fields

NameTypeDescription
type string
"failed_payment" β€” type of action being executed.
merchant_id string
Unique identifier for the merchant.
origin_id string
Unique identifier for the payment's origin.
origin string
Source of the payment. Values: "purchase_sessions" or "subscriptions".
name string
Name of the purchased item.
currency string
Symbol for the currency used (e.g. "USDC", "USDT").
amount number
The amount attempted, excluding fees.
metadata object
Arbitrary key-value pairs attached to the payment (if any).
payment_date string
Date and time of the failed attempt.
status string
"failed".
transaction_details object
Information about the transaction attempt.
user object
Information about the customer.
agreement_id string
ID of the purchase agreement.

Payload example

{
  "type": "failed_payment",
  "merchant_id": "mrch_92313b-1291-43c5-941d-9349d82fc33e",
  "origin_id": "8",
  "origin": "subscriptions",
  "name": "New Test",
  "currency": "USDC",
  "amount": 1,
  "metadata": {
    "customerId": "111"
  },
  "payment_date": "2025-05-28T17:20:03.766627-07:00",
  "status": "failed",
  "transaction_details": {
    "transaction_id": 29,
    "transaction_hash": "",
    "chain_id": 80002
  },
  "user": {
    "first_name": "Test",
    "last_name": "Test",
    "email": "test@gmail.com",
    "subscriber_id": "22b5ff13-e846-40cc-80fa-9e0261f8fd42"
  },
  "agreement_id": "agre_0a5578b2-b76b-4d8c-b568-4ec7442a21dc"
}

Cancel an Agreement

Request the cancellation of a billing agreement. Once cancelled, no further charges will be made against the agreement. The cancellation webhook will be sent to your configured endpoint.

Endpoint

POST https://api.vantack.com/v1/agreements/cancel/{agreement_id}

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
agreement_id string Required
The ID of the agreement to cancel.

Response

{
  "data": {
    "agreement_id": "agre_416d5931-6c09-4b95-a4dd-950d6e307a05",
    "cancellation_event_metadata": {
      "origin": "purchase_sessions",
      "name": "New Test",
      "amount": 0.1,
      "metadata": {
        "customerId": "111"
      },
      "agreement_id": "agre_416d5931-6c09-4b95-a4dd-950d6e307a05",
      "frequency": 1,
      "interval": 2,
      "duration": 0,
      "start_date": "2025-08-07T10:31:36.604923+02:00",
      "cancellation_date": "2025-08-07T10:32:35.972411+02:00",
      "active_until": "2025-09-07T10:31:36.602971Z"
    },
    "message": "Agreement cancelled successfully"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid agreement ID or request.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Create Transfer Request

Initiate a direct token transfer to a recipient. This endpoint transfers funds without requiring any signatures from the merchant β€” as long as the amount is within the allowance set on your Wallet Security page.

The recipient's email must be registered with the platform to prevent unauthorized or accidental transfers. Use the same email used when creating a purchase session.

If the transfer amount exceeds your configured allowance, the API will not process the transfer. You can increase the allowance under Settings β†’ Wallet Security β†’ Grant/Transfer Permission, or send the transfer directly from the Wallet page.

⚠️ chainId values for the TEST ENVIRONMENT: 80002 (Polygon), 84532 (Base), 11155111 (Ethereum).

⚠️ chainId values for the PRODUCTION ENVIRONMENT: 137 (Polygon), 8453 (Base), 1 (Ethereum).

Endpoint

POST https://api.vantack.com/v1/merchants/transfer/request

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Body Parameters

NameTypeDescription
to_address string Required
Recipient's registered email address or wallet address.
amount number Required
Amount of tokens to transfer.
chainId number Required
ID of the target blockchain. See description above for test and production values.
token string Required
Symbol of the token to transfer (e.g. "USDC", "USDT", "PYUSD").

Request body example

{
  "to_address": "example@email.com",
  "amount": 0.1,
  "chainId": 80002,
  "token": "USDC"
}

Response

{
  "data": {
    "fee": 0.115,
    "message": "Processing the transfer.",
    "status": "success"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Wallet Transfer Webhook

After a transfer is executed, the following payload is sent to your webhook endpoint.

If the webhook fails to deliver, it will retry up to 5 times with each retry occurring every 5–10 minutes.

Payload Fields

NameTypeDescription
type string
"transfer" β€” indicates this payload is for a wallet-to-wallet transfer.
merchant_id string
Unique identifier for the merchant initiating the transfer.
amount_in_usd string
Amount being transferred, denominated in USD.
hash string
Blockchain transaction hash β€” use this to verify and track the transfer on-chain.
transfer_id string
Unique identifier for this specific transfer within the platform.
wallet_id string
Unique identifier for the merchant wallet that initiated the transfer.
network string
Blockchain network the transfer occurred on (e.g. "Polygon", "Base", "Ethereum").
from_address string
Blockchain address of the sender wallet.
to_address string
Blockchain address of the receiver wallet.
status string
Status of the transfer. Values: "success", "pending", "failed".
status_confirmed_at string
Timestamp when the transfer status was confirmed. Format: ISO 8601 with timezone.

Payload example

{
  "type": "transfer",
  "merchant_id": "mrch_053daf5f-7de6-491e-8096-5c8a8612f334",
  "amount_in_usd": "0.985000",
  "hash": "0x0924b6a3cc49d2ba216452358271533bc8190826b6cae395747be86b91a6ea98",
  "transfer_id": "7",
  "wallet_id": "wa-tffvk-1nj19-1qqbt0j5ieophqg",
  "network": "PolygonAmoy",
  "from_address": "0xd0cbe3ab3a241f6c4d5f2c0e2bfe37ec03fe7f04",
  "to_address": "0x1C337aBF69aB1DC1F9388e97bBd4AAD57059D8Eb",
  "status": "success",
  "status_confirmed_at": "2025-08-15T11:43:19.641041+02:00"
}

Headless API

Best for advanced integrations that require full control over the payment flow, UI, and custom business logic.

The Headless API allows you to programmatically create and manage purchase sessions using the platform's APIs without relying on the hosted checkout UI. You can either use the returned checkout link with any supported integration method, or build a fully custom checkout experience β€” including wallet connections, message signing, and blockchain transaction handling.

⚠️ Important β€” this integration requires wallet infrastructure

The Headless API does not provide any UI or wallet infrastructure. By using this method you are responsible for:

  • Building and maintaining the checkout UI
  • Managing wallet connections (e.g., MetaMask, WalletConnect)
  • Handling EIP-712 signing flows
  • Safely storing and submitting user signatures

If you do not want to manage wallet infrastructure or signing logic, we recommend using the Hosted Checkout via the Commerce Integration section instead.

Prerequisites

Before using the Headless API, ensure you have:

  • An API key β€” see how to create an API key
  • Familiarity with HTTP requests and handling JSON responses
  • Capability to manage wallet connections and signature flows (e.g., MetaMask, WalletConnect)

Summary

With the headless integration flow, the platform allows you to:

  • Create a purchase session per customer
  • Retrieve a typed data message (EIP-712) for signing the purchase
  • Implement a custom UI for checkout including wallet connection and signing experience
  • Submit signed messages to Vantack to initiate on-chain payment
  • Handle webhook events to track payment completion

Flow: step-by-step

1. Create a Purchase Session

POST to the platform's API with product and buyer details β€” see how to create a purchase session. The response includes a unique purchase_session_id.

2. Request Message to Sign

Use the purchase_session_id along with customer data to obtain a typed data message describing the purchase. The response returns EIP-712 typed data ready for user signature.

3. Handle Wallet & Sign Message

Your frontend connects to the customer's wallet (e.g., MetaMask). Prompt the user to sign the provided EIP-712 typed data and store the resulting signature.

4. Submit Signature

POST the signature back to the platform using the Submit Signed Purchase Message endpoint. Vantack processes and broadcasts the transaction on-chain β€” no further action needed from your backend.

5. Listen for Webhook Events

Receive webhook notifications as described in the Webhooks section. Use these to unlock access, show success screens, or trigger retry flows for your users.

Accounts, API Keys & Webhooks

Accounts are the basic organizations that use Vantack services. They can be individuals, businesses, or non-profit organizations. They can have one or more users associated with them, and they can be connected to other accounts.

Creating an account through the API will connect that account with your account, enabling you to call the API as that account in the future. This allows a platform account the ability to onboard users, and configure products and payment agreements for their users.

Create an account

As a platform merchant, you can create accounts for your users (submerchants). If you've already collected information for your connected accounts, you can prefill that information here and we won't ask for it again during onboarding.

If you need to set up a wallet address for your users, send it in the default_deposit_address field. Leave it empty and the user will be guided to create their own wallet when they sign up.

Endpoint

POST https://api.vantack.com/v1/merchants/create

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Body Parameters

NameTypeDescription
default_deposit_address string Optional
Wallet address to assign to the submerchant account.
business_profile object Optional
Business details for the submerchant.
individual object Optional
Individual identity details for the submerchant.
settings object Optional
Branding and configuration settings.

Request body example

{
  "default_deposit_address": "0xc3Fe74dD43B3734B65A6B6b307EC50A9D4a8Dc3d",
  "business_profile": {
    "name": "My Company",
    "description": "A leading provider of innovative solutions",
    "email": "merchant@example.com",
    "company_name": "Acme Corporation",
    "industry": "blockchain_crypto",
    "user_role": "founder",
    "familiarity_with_crypto": true,
    "company_size": "11_50",
    "use_platform_for": ["subscriptions", "one_time_payments"]
  },
  "individual": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john@example.com"
  },
  "settings": {
    "branding": {
      "logo_image_url": "https://example.com/logo.png",
      "background_image_url": "https://example.com/background.jpg",
      "brand_color": "#1E88E5"
    }
  }
}

Response

{
  "data": {
    "merchant_id": "7d8f523f-6081-48a8-bc29-dbf8bd7635dd",
    "submerchant_id": "10a5841c-7d88-4798-9178-48a0e445961c",
    "email_verification_link": "https://app.vantack.com/verify/...",
    "created_at": "2025-06-14T10:08:07.887096+02:00",
    "object": "merchant",
    "business_profile": {
      "name": "My Company",
      "description": "A leading provider of innovative solutions",
      "email": "merchant@example.com",
      "company_name": "Acme Corporation",
      "industry": "blockchain_crypto",
      "user_role": "founder",
      "familiarity_with_crypto": true,
      "company_size": "11_50",
      "use_coinsub_for": ["subscriptions", "one_time_payments"]
    },
    "individual": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "john@example.com"
    },
    "settings": {
      "branding": {
        "logo_image_url": "https://example.com/logo.png",
        "background_image_url": "https://example.com/background.jpg",
        "brand_color": "#1E88E5"
      }
    },
    "default_deposit_address": "0xc3Fe74dD43B3734B65A6B6b307EC50A9D4a8Dc3d"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Resend Verification Email

Resends the verification email to a submerchant if it was not received. This endpoint has a 20-minute cooldown period between requests.

Endpoint

POST https://api.vantack.com/v1/merchants/{merchant_id}/resend-verification

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account.

Response

{
  "data": {
    "email": "merchant@example.com",
    "message": "Verification email resent successfully"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid merchant ID or cooldown period has not elapsed.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Update an account

Update a connected submerchant account. To update your own account use the Coinsub dashboard.

⚠️ Email field cannot be updated via this endpoint.

⚠️ The request will fail if the wallet address already exists in the system.

Endpoint

PATCH https://api.vantack.com/v1/merchants/{merchant_id}

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account to update.

Body Parameters

NameTypeDescription
business_profile object Optional
Updated business details.
individual object Optional
Updated individual identity details.
settings object Optional
Updated branding and configuration.

Request body example

{
  "business_profile": {
    "name": "Acme Corp",
    "description": "Crypto Payment Services",
    "default_deposit_address": "0x60a1A4149A99bEaCEf7138Be44Cdda907039975b"
  },
  "individual": {
    "first_name": "John",
    "last_name": "Doe"
  },
  "settings": {
    "branding": {
      "logo_image_url": "https://example.com/logo.png",
      "background_image_url": "",
      "brand_color": "#1E88E5"
    }
  }
}

Response

{
  "data": {
    "merchant_id": "mrch_00d47bc8-898f-4519-a1f9-edfeb84682bd",
    "updated_at": "2025-04-01T13:49:37.848171403+05:30",
    "object": "merchant",
    "business_profile": {
      "name": "Acme Corp",
      "description": "Crypto Payment Services",
      "default_deposit_address": "0x60a1A4149A99bEaCEf7138Be44Cdda907039975b"
    },
    "individual": {
      "first_name": "John",
      "last_name": "Doe"
    },
    "settings": {
      "branding": {
        "logo_image_url": "https://example.com/logo.png",
        "background_image_url": "",
        "brand_color": "#1E88E5"
      }
    }
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” wallet address already exists or invalid field.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Retrieve an account

Retrieves the full details of a connected submerchant account.

Endpoint

GET https://api.vantack.com/v1/merchants/{merchant_id}

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account to retrieve.

Response

{
  "data": {
    "merchant_id": "mrch_2848a3ba-4cf0-490e-b936-bee9a12ac6aa",
    "submerchant_id": "",
    "email_verification_link": "",
    "created_at": "2025-06-06T15:23:27.569208+02:00",
    "object": "account",
    "business_profile": {
      "name": "Acme Corporation",
      "description": "A leading provider of innovative solutions",
      "email": "merchant@example.com",
      "company_name": "Acme Corporation",
      "industry": "blockchain_crypto",
      "user_role": "founder",
      "familiarity_with_crypto": true,
      "company_size": "11_50",
      "use_coinsub_for": ["subscriptions", "one_time_payments"]
    },
    "individual": {
      "first_name": "John",
      "last_name": "Doe",
      "email": "john@example.com"
    },
    "settings": {
      "branding": {
        "logo_image_url": "https://example.com/logo.png",
        "background_image_url": "https://example.com/background.jpg",
        "brand_color": "#1E88E5"
      }
    },
    "default_deposit_address": "0xADc926EdaA9Ef107Bc41E83321D393763asd8aaa"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid merchant ID.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Delete an account

Deletes a connected submerchant account. Accounts with ongoing payment agreements cannot be deleted until all active agreements are cancelled first.

Endpoint

DELETE https://api.vantack.com/v1/merchants/{merchant_id}

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account to delete.

Response

{
  "data": {
    "merchant_id": "mrch_2848a3ba-4cf0-490e-b936-bee9a12ac6aa",
    "message": "Account deleted successfully"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” account has active agreements and cannot be deleted.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

List all connected accounts

Retrieves a list of all submerchant accounts connected to your platform account.

Endpoint

GET https://api.vantack.com/v1/merchants/list_accounts

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Response

{
  "data": [
    {
      "merchant_id": "mrch_2c155cd7-77e5-4e00-96b9-dbccedeab6a8",
      "submerchant_id": "",
      "email_verification_link": "",
      "created_at": "2025-06-06T14:53:22.796505+02:00",
      "object": "account",
      "business_profile": {
        "name": "Acme Corporation",
        "description": "A leading provider of innovative solutions",
        "email": "merchant@example.com",
        "company_name": "Acme Corporation",
        "industry": "blockchain_crypto",
        "user_role": "founder",
        "familiarity_with_crypto": true,
        "company_size": "11_50",
        "use_coinsub_for": ["subscriptions", "one_time_payments"]
      },
      "individual": {
        "first_name": "John",
        "last_name": "Doe",
        "email": "john@example.com"
      },
      "settings": {
        "branding": {
          "logo_image_url": "https://example.com/logo.png",
          "background_image_url": "https://example.com/background.jpg",
          "brand_color": "#1E88E5"
        }
      },
      "default_deposit_address": "0xADc926EdaA9Ef107Bc41E83321D393763e4B845b"
    }
  ],
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid request parameters.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Create API Key for connected account

Creates a new API key for a connected submerchant account. The returned key can be used to authenticate API requests on behalf of that account.

Endpoint

POST https://api.vantack.com/v1/merchants/{merchant_id}/apikeys

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account.

Response

{
  "data": {
    "api_key": "afa1eacd-2912-448d-9fe5-d6ee524846b6",
    "message": "API key created successfully"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid merchant ID.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Retrieve API Keys for connected account

Retrieves all API keys for a connected submerchant account, along with their current status.

Endpoint

GET https://api.vantack.com/v1/merchants/{merchant_id}/apikeys

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account.

Response

{
  "data": {
    "api_key": [
      {
        "api_key": "afa1eacd-2912-448d-9fe5-d6ee524846b6",
        "status": "Active"
      }
    ]
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid merchant ID.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Disable API Key for connected account

Disables an API key for a connected submerchant account. Disabled keys can no longer be used to authenticate requests.

Endpoint

DELETE https://api.vantack.com/v1/merchants/{merchant_id}/apikeys/{apiKey}/disable

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account.
apiKey string Required
The API key to disable.

Response

{
  "data": {
    "api_key": "afa1eacd-2912-448d-9fe5-d6ee524846b6",
    "message": "API key disabled successfully",
    "status": "Disabled"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid merchant ID or API key.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Create Webhook for connected account

Creates a webhook endpoint for a connected submerchant account. All payment and agreement events for that account will be sent to the provided URL.

Endpoint

POST https://api.vantack.com/v1/merchants/{merchant_id}/webhooks

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account.

Body Parameters

NameTypeDescription
url string Required
Fully qualified HTTPS URL to receive webhook events.

Request body example

{
  "url": "https://yourdomain.com/webhooks/coinsub"
}

Response

{
  "data": {
    "webhook_id": "afa1eacd-2912-448d-9fe5-d6ee524846b6",
    "message": "Webhook created",
    "status": "active"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid merchant ID or URL.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Disable Webhook for connected account

Disables a webhook for a connected submerchant account. No further events will be delivered to the webhook URL once disabled.

Endpoint

POST https://api.vantack.com/v1/merchants/{merchant_id}/webhooks/{webhookId}/disable

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account.
webhookId string Required
ID of the webhook to disable.

Response

{
  "data": {
    "webhook_id": "afa1eacd-2912-448d-9fe5-d6ee524846b6",
    "message": "Webhook disabled",
    "status": "disabled"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid merchant ID or webhook ID.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Retrieve Webhooks for connected account

Retrieves all webhooks registered for a connected submerchant account, including their current status.

Endpoint

GET https://api.vantack.com/v1/merchants/{merchant_id}/webhooks

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
merchant_id string Required
Merchant ID of the submerchant account.

Response

{
  "data": {
    "webhooks": [
      {
        "webhook_id": "afa1eacd-2912-448d-9fe5-d6ee524846b6",
        "url": "https://yourdomain.com/webhooks/coinsub",
        "date_created": "2025-07-07T15:39:35.638438-04:00",
        "status": "active",
        "merchant_id": "10a5841c-7d88-4798-9178-48a0e445961c"
      }
    ]
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid merchant ID.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Agreements

Payment agreements generate recurring payments through Vantack's payment network based on pre-defined agreements signed by the customer. The customer is required to agree to any changes to a payment agreement.

Retrieve an agreement

Retrieve an agreement for your account or a connected account.

Endpoint

GET https://api.vantack.com/v1/agreements/{agreement_id}/retrieve_agreement/

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Optional
Content-Type string Optional

Path Parameters

NameTypeDescription
agreement_id string Required
The ID of the agreement to retrieve.

Response

{
  "data": {
    "id": "agre_f6341089-a37a-439b-bd1f-20c3d5317679",
    "object": "agreement",
    "active": "true",
    "metadata": null,
    "account": "00000000-0000-0000-0000-000000000000",
    "last_payment_date": 1743107382,
    "next_payment_date": null,
    "status": "active",
    "created_at": "2025-03-27T20:29:42.057449+05:30",
    "payments": null
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid agreement ID.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Retrieve all agreements

List all agreements for your account or a connected account.

Endpoint

GET https://api.vantack.com/v1/agreements/list_agreements

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Response

{
  "data": {
    "object": "list",
    "url": "/v1/agreements/list_agreements",
    "has_more": false,
    "data": [
      {
        "id": "agre_62c4f415-3822-4fb4-9392-fcee1db79c34",
        "object": "agreement",
        "active": "true",
        "metadata": null,
        "account": "0eade899-17e1-475e-8979-b04d63eef00f",
        "last_payment_date": 1743108251,
        "next_payment_date": null,
        "status": "active",
        "created_at": "2025-03-27T20:44:10.509652+05:30",
        "payments": null
      },
      {
        "id": "agre_48961ba9-fe41-4453-b783-d365d57a3f2e",
        "object": "agreement",
        "active": "true",
        "metadata": {
          "invoiceNumber": 123456,
          "sku": "TEST"
        },
        "account": "0eade899-17e1-475e-8979-b04d63eef00f",
        "last_payment_date": 1743614967,
        "next_payment_date": null,
        "status": "active",
        "created_at": "2025-04-02T17:29:27.43186+05:30",
        "payments": null
      }
    ]
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid request parameters.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Payments

Payments represent transactions that merchants receive from their customers. Each payment record contains the amount, currency, transaction status, customer details, and what was purchased β€” whether a one-time payment or part of a recurring subscription.

Use the Payments API to view your complete payment history, look up specific transaction details, and monitor payment statuses across your account and connected accounts.

Retrieve a payment

Retrieve a payment by its payment_id. A payment belongs either to your account or a connected account.

If a payment has multiple consecutive charge attempts that fail due to insufficient user balance, the metadata object will include a failed_dates array listing the timestamps of each failed attempt.

Endpoint

GET https://api.vantack.com/v1/payments/{id}

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Accept string Optional
The content type the client is willing to accept. Example: application/json

Path Parameters

NameTypeDescription
id string Required
The payment_id of the payment to retrieve.

Response

{
  "data": [
    {
      "payment_id": "paym_6f7a1c13-706c-4df3-a566-6a8ced58ccfc",
      "origin": "subscriptions",
      "origin_id": "161",
      "amount": 0.0985,
      "fee": 2.00264,
      "status": "completed",
      "account_id": "1d5faea9-306c-488d-b2f9-b00b2e8cd414",
      "transaction_hash": "0x15c4308c3f55e7ef13d062e0784ec30181a400a2ac92bfac849443c486d33963",
      "transaction_date": "2025-08-18T08:37:59.222842Z",
      "network_id": 84532,
      "currency": "USDC",
      "token_name": "USDC",
      "network_name": "Base Sepolia",
      "block_explorer_url": "https://sepolia.basescan.org/tx/0x15c4308c3f55e7ef13d062e0784ec30181a400a2ac92bfac849443c486d33963",
      "agreement_id": "agre_115608f9-662c-4ae4-aa6f-3928f99df15b"
    }
  ],
  "status": 200
}
{
  "error": "Bad request β€” invalid or missing payment ID.",
  "status": 400
}

Retrieve all payments

List all payments for your account or a connected account. You can filter results by agreement, status, or both.

Endpoint

GET https://api.vantack.com/v1/payments/list

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Body Parameters

NameTypeDescription
agreement string Optional
Filter payments by agreement ID. Nullable.
status string Optional
Filter payments by status. Nullable.
Enum: confirmedpendingfailed

Response

{
  "data": {
    "object": "list",
    "has_more": false,
    "data": [
      {
        "payment_id": "paym_6f7a1c13-706c-4df3-a566-6a8ced58ccfc",
        "origin": "subscriptions",
        "origin_id": "161",
        "amount": 0.0985,
        "fee": 2.00264,
        "status": "completed",
        "account_id": "1d5faea9-306c-488d-b2f9-b00b2e8cd414",
        "transaction_hash": "0x15c4308c3f55e7ef13d062e0784ec30181a400a2ac92bfac849443c486d33963",
        "transaction_date": "2025-08-18T08:37:59.222842Z",
        "network_id": 84532,
        "currency": "USDC",
        "token_name": "USDC",
        "network_name": "Base Sepolia",
        "agreement_id": "agre_115608f9-662c-4ae4-aa6f-3928f99df15b"
      }
    ]
  },
  "status": 200
}
{
  "error": "Bad request β€” invalid filter parameters.",
  "status": 400
}

Subscription Products

A product is a digital offer created by a merchant that users can purchase in exchange for access to a service, benefit, or digital experience. While many products are traditional subscriptions, they can also represent one-time access or single-purchase offerings.

  • Merchant-Defined: Each product is owned and managed by a specific merchant, who determines its pricing, duration, and usage.
  • Flexible Pricing: Products are priced in USD but payment may be made using crypto, supporting both recurring subscriptions and one-time purchases.
  • Blockchain Integration: Payments are directed to a dedicated blockchain address, enabling secure on-chain transactions.
  • Lifecycle Status: Products can be active, inactive, or discontinued, giving merchants full control over their offerings.

Retrieve all Subscription Products

List all products for your merchant account.

Endpoint

GET https://api.vantack.com/v1/agreements/list_agreements

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Response

{
  "data": [
    {
      "subscription_product_id": 7247,
      "subscription_name": "Test",
      "product_type": "subscription"
    }
  ],
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid request parameters.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Retrieve Subscriptions For Subscriber

List all active subscriptions and one-time purchases for a specific subscriber.

Endpoint

GET https://api.vantack.com/v1/agreements/active_subscriptions_and_purchases/{subscriber_id}

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Path Parameters

NameTypeDescription
subscriber_id string Required
Unique identifier for the subscriber.

Response

{
  "status": "success",
  "data": {
    "subscriptions": [
      {
        "id": "sub_123e4567-e89b-12d3-a456-426614174000",
        "subscriber_id": "sub_98765432-e89b-12d3-a456-426614174000",
        "merchant_id": "mrch_7cdd80d6-76f4-47b8-8000-70ebac04c3db",
        "agreement_id": "agr_123e4567-e89b-12d3-a456-426614174000",
        "status": "active",
        "amount": 99.99,
        "currency": "USDC",
        "frequency": "Monthly",
        "interval": 1,
        "duration": 12,
        "next_billing_date": "2024-06-26T14:30:00Z",
        "created_at": "2024-05-26T14:30:00Z",
        "product_name": "Premium Subscription"
      }
    ],
    "purchases": [
      {
        "id": "pur_123e4567-e89b-12d3-a456-426614174000",
        "subscriber_id": "sub_98765432-e89b-12d3-a456-426614174000",
        "merchant_id": "mrch_7cdd80d6-76f4-47b8-8000-70ebac04c3db",
        "agreement_id": "agr_123e4567-e89b-12d3-a456-426614174000",
        "status": "completed",
        "amount": 49.99,
        "currency": "USDC",
        "created_at": "2024-05-25T10:15:00Z",
        "product_name": "One-time Purchase",
        "metadata": {
          "order_id": "ORD123456",
          "customer_email": "customer@example.com"
        }
      }
    ]
  }
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid subscriber ID.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Retrieve Subscriptions For Subscriber and Product Id

Check whether a specific subscriber has an active subscription to a given product.

Endpoint

POST https://api.vantack.com/v1/subscriptions/check_subscription_status_product

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Body Parameters

NameTypeDescription
subscriber_id string Required
Unique identifier for the subscriber.
subscription_product_id number Required
ID of the subscription product to check.

Request body example

{
  "subscriber_id": "e18c3f05-63aa-4481-ac43-d655f013efa0",
  "subscription_product_id": 7241
}

Response

{
  "data": {
    "active": false,
    "subscriber_id": "e18c3f05-63aa-4481-ac43-d655f013efa0",
    "subscription_product_id": 7241
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid subscriber ID or product ID.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Retrieve the Subscription Status of a Product with a Subscriber's Metadata

Check the subscription status of a subscriber based on metadata. Returns one of three states: active subscription, inactive subscription, or no matching subscription found.

Endpoint

POST https://api.vantack.com/v1/subscriptions/check_subscription_by_metadata

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Content-Type string Optional

Body Parameters

NameTypeDescription
subscription_product_id number Required
ID of the subscription product to check.
metadata object Required
Key-value metadata used to identify the subscriber.

Request body example

{
  "subscription_product_id": 7246,
  "metadata": {
    "customerId": "1212424128"
  }
}

Response

{
  "active": true,
  "subscriber_id": "123e4567-e89b-12d3-a456-426614174000",
  "metadata": {
    "customerId": "1212424128"
  },
  "subscription_product_id": 1
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid product ID or metadata.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Merchant Wallet Transfers

Vantack Merchant Wallets are secure, non-custodial wallets powered by DFNS's battle-tested wallet infrastructure. Designed with robust key management and WebAuthn-based authentication, these wallets ensure enterprise-grade security without exposing private keys or relying on vulnerable seed phrases.

With Merchant Wallets, Vantack merchants don't need to connect external wallets or manage third-party integrations. Everything is built-in β€” making on-chain payments, managing funds, and receiving crypto subscriptions frictionless and secure, straight from your dashboard.

Wallet Credentials

Merchant wallets on the platform support two types of credentials:

FIDO2 / Passkeys

FIDO2 credentials (commonly referred to as passkeys) offer a secure, passwordless authentication method based on public key cryptography. These credentials are typically linked to a user and stored in secure authenticators (e.g., Face ID, external security keys). Upon sign up, a default passkey will be added to your platform account.

Platform Key Credentials

Platform Key Credentials are asymmetric key pairs managed and operated by the platform. When you sign up, a Platform Key Credential is automatically created for you. This key allows for secure, programmatic signing operations and comes with a default transaction allowance of $100.

How These Key Types Work Together

Once your wallet balance exceeds $10, you'll be required to set up a Passkey (FIDO2 credential). Passkeys are tied to your personal device and identity β€” using technologies like Face ID or security keys β€” to provide passwordless, phishing-resistant authentication.

By combining both key types, the platform ensures seamless programmatic signing while strengthening account security through user-bound passkeys as your account value grows.

Wallet Transfers

Traditionally, sending crypto funds requires users to pay gas fees using the native token of the blockchain β€” for example, ETH on Ethereum or MATIC on Polygon. To remove this barrier, we've introduced gasless transfers β€” a seamless way to send funds without needing to hold or spend native tokens.

Gasless transfers can be executed in two ways:

1. Platform-Signed Transfers

The platform handles the transaction signature on behalf of the merchant. The merchant grants the platform permission to sign transfers up to a specified threshold (e.g. $100 per transfer). If a transfer exceeds this threshold, the platform requests a manual signature before proceeding. Ideal for minimizing operational friction while maintaining control over large transfers.

2. Merchant-Signed Transfers

The merchant handles the signing process directly, maintaining full control over every transaction. Each transfer must be individually approved and signed by the merchant's Passkey.

⚠️ Security Restriction

Gasless transfers are only permitted between wallets registered within the platform. This ensures traceability, accountability, and reduces the risk of fraud or phishing attempts.

Create Transfer Request

To initiate a new transfer you must provide the following parameters: to_address (the recipient's email address registered with the platform, or wallet address β€” use the same email used when creating a purchase session), amount (amount of tokens to transfer), chainId (ID of the target blockchain), and token (symbol of the token being transferred, e.g. USDC, USDT, PYUSD).

This endpoint transfers funds directly to the recipient without requiring any signatures from the merchant. If the amount exceeds the allowance set on the Wallet Security page, the API will not process the transfer.

⚠️ ⚠️ The recipient's email must be registered with our platform to prevent unauthorized or accidental transfers.

⚠️ ⚠️ chainId values for the TEST ENVIRONMENT are: 80002 for Polygon, 84532 for Base, 11155111 for Ethereum.

⚠️ ⚠️ chainId values for the PRODUCTION ENVIRONMENT are: 137 for Polygon, 8453 for Base, 1 for Ethereum.

Endpoint

POST https://api.vantack.com/v1/merchants/transfer/request

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Body Parameters

NameTypeDescription
to_address string Required
The recipient's registered email address or wallet address.
amount number Required
Amount of tokens to transfer.
chainId number Required
ID of the target blockchain.
token string Required
Symbol of the token being transferred (e.g. USDC, USDT, PYUSD).

Request body example

{
  "to_address": "0xEB86303B89AC120c7de660e8fB76D2cb79ed79CD",
  "amount": 0.1,
  "chainId": 80002,
  "token": "USDC"
}

Response

{
  "data": {
    "fee": 0.115,
    "message": "Processing the transfer.",
    "status": "success"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

When a Signature is Required

The Create Transfer endpoint processes funds directly without requiring a signature β€” as long as the transfer amount is within your configured allowance. If the amount exceeds the limit set on the Wallet Security page, the API will not process the transfer.

If your transfers regularly exceed the default $100 limit, you have two options:

Option 1 β€” Increase the allowance

Navigate to Settings β†’ Wallet Security β†’ Grant/Transfer Permission and update the allowance to the amount you require.

Option 2 β€” Send via the Wallet UI

Go to the Wallet page, locate the token you want to send, and click Send next to it. Enter the desired amount and the recipient's wallet address or email.

Fees & Earnings

The Fees & Earnings endpoints expose how the platform calculates, distributes, and records transaction fees across merchants, resellers, and the platform. Fees are structured in multiple layers:

  • Customer Percent β€” charged to buyers at the point of purchase.
  • Merchant Percent β€” deducted from the merchant's settlement amount.
  • Platform Percent β€” reserved for the platform (fixed, not configurable).

After settlement, fees are allocated across the merchant hierarchy and recorded as immutable earnings entries, including payment amounts, costs, merchant earnings, currency, payment type, and timestamps. These records support financial reporting, reconciliation, and aggregation over any time range.

Get Fee Structure

Get the effective fee structure for the merchant, including any inherited defaults used for pricing and earnings calculations.

Endpoint

GET https://api.vantack.com/v1/merchants/fee/structure

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Accept string Optional
The content type the client is willing to accept. Example: application/json

Response

{
  "data": {
    "merchant_id": "be560a6f-9160-4668-a9ee-a8c10aadb4a4",
    "customer_percent": 0,
    "merchant_percent": 0.044,
    "platform_percent": 0.02,
    "include_network_fee": true,
    "transaction_type": "default"
  },
  "status": 200
}
{
  "error": "Bad request β€” invalid or missing parameters.",
  "status": 400
}

Update Fee Structure

Update the merchant's fee structure for a specific transaction type (customer/merchant percent and network-fee inclusion). Platform percent is fixed by the system and cannot be changed.

Endpoint

PUT https://api.vantack.com/v1/merchants/fee/structure

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Accept string Optional
The content type the client is willing to accept. Example: application/json

Body Parameters

NameTypeDescription
customer_percent number Optional
Fee percentage charged to the customer.
merchant_percent number Optional
Fee percentage deducted from the merchant.
include_network_fee boolean Optional
Whether to include the blockchain network fee in the total.
transaction_type string Optional
The transaction type this fee structure applies to.

Request body example

{
  "customer_percent": 1,
  "merchant_percent": 1,
  "include_network_fee": true,
  "transaction_type": "default"
}

Response

{
  "status": 200,
  "data": {
    "message": "Fee structure updated successfully.",
    "data": {
      "merchant_id": "be560a6f-9160-4668-a9ee-a8c10aadb4a4",
      "customer_percent": 1,
      "merchant_percent": 0.01,
      "platform_percent": 0.015,
      "include_network_fee": true,
      "transaction_type": "default"
    }
  }
}
{
  "error": "Bad request β€” invalid fee structure values.",
  "status": 400
}

Get Earnings

Returns a paginated list of fee earnings for the authenticated merchant, grouped by payment. Each item is a summary view including payment amount, total fee cost, merchant earnings, currency, and timestamps.

Only MERCHANT earnings are returned for the merchant tied to the API key. This endpoint is intended for finance reporting, reconciliation, and aggregation over a specified time range.

⚠️ Date boundaries are accounting-safe: after is inclusive, before is exclusive.

⚠️ All numeric values are rounded to 3 decimal places server-side.

⚠️ Use either last_days or after/before β€” not both.

⚠️ To compute totals across a large range: request the first page, then continue while has_next = true, aggregating values across all pages.

Endpoint

GET https://api.vantack.com/v1/merchants/fee/earnings

Header Parameters

NameTypeDescription
API-Key string Required
Merchant-ID string Required
Accept string Optional
The content type the client is willing to accept. Example: application/json

Query Parameters

NameTypeDescription
after string Optional
RFC3339 timestamp. Inclusive lower bound. Use either last_days or after/before, not both.
before string Optional
RFC3339 timestamp. Exclusive upper bound. Use either last_days or after/before, not both.
sort string Required
Sort direction by created_at. Example: asc or desc.
page string Required
Page number for pagination.
per_page string Required
Number of results per page.
last_days number Optional
Integer (1–3650). Returns earnings from the last N days. Use either last_days or after/before, not both.

Response

{
  "data": {
    "earnings": [
      {
        "id": "earn_abc123",
        "payment_amount": 10.52,
        "payment_type": "purchase",
        "payment_total_cost": 0.484,
        "merchant_earnings": 0.252,
        "currency": "USDC",
        "created_at": "2026-01-30T12:08:27.171959Z"
      }
    ],
    "total_count": 2,
    "page": 1,
    "per_page": 50,
    "total_pages": 1,
    "has_next": false,
    "has_previous": false,
    "filters": {
      "last_days": 30,
      "sort": "desc"
    }
  },
  "status": 200
}
{
  "error": "Bad request β€” invalid query parameters.",
  "status": 400
}

Purchase Sessions

Purchase Sessions are the starting point for any payment flow on Vantack. A session holds all the details about a payment request β€” the amount, currency, product info, and configuration for one-time or recurring billing.

Once created, the session returns a hosted checkout URL that you can redirect the customer to, embed in an iframe, or open in a modal. For headless flows, you can use the session ID to request a typed data message and handle signing directly in your own UI.

Create A Purchase Session

The Create endpoint allows you to create a new payment request and retrieve URLs for making and monitoring payments. If the request is associated with an agreement, the system first checks whether it can be automatically processed according to the agreement rules. If it cannot be processed automatically, a unique payment URL will be generated where the user can complete the payment manually.

In production, the minimum scheduling frequency for recurring payments is once per day. In the test environment, you can schedule as frequently as once per minute for development and testing.

Endpoint

POST https://api.vantack.com/v1/purchase/session/start

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Body Parameters

NameTypeDescription
name string Required
Shown to payer on payment screen.
details string Required
Shown to payer on payment screen.
currency string Optional
Defaults to USD. Can use another currency type.
recurring boolean Optional
Set as true if used for subscription. Defaults to false.
amount number Required
Amount of currency.
metadata object Optional
Arbitrary key-value pairs you provide. Returned in every webhook for both success and failure events. Example: set customerId from your system to tie all webhook events to a single customer.
success_url string Optional
The url to redirect your payer upon successful payment.
cancel_url string Optional
The url to redirect the payer to if they cancel the payment process.
interval string Required if recurring
Required if recurring is set as true.
Enum: DayWeekMonthYear
frequency string Optional
Number of intervals between each recurring charge (e.g., "2" with interval: "Minute" β†’ every 2 minutes).
Enum: EveryEvery OtherEvery ThirdEvery FourthEvery FifthEvery SixthEvery Seventh
Duration string Optional
Number of intervals the subscription will run before ending. "0" means no fixed end.
expires_in_hours number Optional
Number of hours before the payment request expires. After expiration, no purchase requests or signature submission requests will be processed.

Request body example

{
  "name": "Invisilink",
  "details": "This is a very cool product!",
  "currency": "USDC",
  "recurring": true,
  "amount": 0.2,
  "metadata": {
    "customerId": "111"
  },
  "success_url": "https://www.google.com",
  "cancel_url": "https://www.google.com",
  "interval": "Minute",
  "frequency": "2",
  "Duration": "0",
  "expires_in_hours": 5
}

Response

{
  "data": {
    "purchase_session_id": "sess_497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "url": "https://buy.vantack.com/checkout/76db1abbe9",
    "name": "Example Merchant",
    "details": "Making a test payment",
    "currency": "USD",
    "amount": "5",
    "metadata": {
      "invoiceNumber": 12343,
      "customerId": "di2d-22edd2-232d2-22"
    },
    "created": 1647628799,
    "updated": 1647628799,
    "success_url": "string",
    "cancel_url": "string",
    "status": "session_created",
    "message": "Purchase session created successfully"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Retrieve Purchase Session Status

Returns the status of a specific purchase session.

Endpoint

GET https://api.vantack.com/v1/purchase/status/{purchase_session_id}

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Optional
Merchant-ID string Optional

Path Parameters

NameTypeDescription
purchase_session_id string Required
The ID of the purchase session to retrieve status for.

Request body example

Response

{
  "data": {
    "purchase_session_id": "sess_7c003b85-cbe9-4825-86e5-a38495b257ab",
    "purchase_session_status": "completed",
    "payment_ids": [
      "paym_8dc38141-b2a9-44b4-98ee-d134a84fe7ec"
    ],
    "expired": false
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Purchase session not found.",
  "status": 404
}

Delete Purchase Session

Delete a specific purchase request.

Endpoint

DELETE https://api.vantack.com/v1/purchase/delete/{purchase_session_id}

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Optional
Merchant-ID string Optional

Path Parameters

NameTypeDescription
purchase_session_id string Required
The ID of the purchase session to delete.

Response

Payment Link Deleted Successfully.

{
  "data": {
    "message": "Purchase session deleted successfully."
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request.",
  "status": 400
}

If a PAID payment request is requested to be deleted, the deletion will be denied.

{
  "error": "Conflict β€” cannot delete a paid purchase session.",
  "status": 409
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Expire Purchase Session

Force expires a specific purchase session.

Endpoint

POST https://api.vantack.com/v1/purchase/expire/{purchase_session_id}

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Optional
Merchant-ID string Optional

Path Parameters

NameTypeDescription
purchase_session_id string Required
The ID of the purchase session to expire.

Response

Purchase Session Expired Successfully.

{
  "data": {
    "expired_at": 1757336748,
    "expires_in_hours": 0,
    "message": "Purchase session expired successfully",
    "purchase_session_id": "sess_b0713280-0b7a-45d2-b85e-78c9531be1e3"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request.",
  "status": 400
}

If a PAID payment request is requested to be expired, the action will be denied.

{
  "error": "Conflict β€” cannot expire a paid purchase session.",
  "status": 409
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Purchase Messages

Purchase Messages enable a fully headless, signature-based payment flow. Instead of redirecting the customer to the hosted checkout UI, you request a typed data message (EIP-712) and present it to the user's wallet for signing β€” giving you complete control over the checkout experience.

Once the user signs the message, submit it back to Vantack for processing. If the user hasn't yet approved the smart contract to spend their token, the response will include a permit message in typed data format for the approval step.

Request Purchase Message to Sign

The Request Message endpoint allows users to create a new message that can be cryptographically signed by your users using signedTypeData methods. This allows you to configure a purchase session and sign that purchase session agreement, or pass that agreement along to your users for them to sign, bypassing the need to use our checkout user interface.

If we can't process the request automatically, we'll create a unique payment URL where the payment can be made.

Endpoint

POST https://api.vantack.com/v1/purchase/message/request

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Body Parameters

NameTypeDescription
purchase_session_id string Required
ID of the purchase session.
wallet_address string Required
Address of wallet from which payment will be made.
product_name string Optional
Name of the product that is being sold.
price integer Required
Price of the product.
metadata object Optional
Optional json data (e.g., invoice number, product ID).
token string Optional
Symbol of the token to be used for payment.
recurring boolean Optional
Set as true if used for subscription. Defaults to false.
duration string Required if recurring
Required if recurring is set as true. If user provides a number, it will represent the number of recurring payments.
frequency string Required if recurring
Required if recurring is set as true.
Enum: EveryEvery OtherEvery ThirdEvery FourthEvery FifthEvery SixthEvery Seventh
interval string Required if recurring
Required if recurring is set as true. Defaults to 0 if recurring is false.
Enum: DayWeekMonthYearMinuteHour
chainId number Optional
Chain ID of the blockchain network being used for payment.

Request body example

{
  "purchase_session_id": "sess_4f480a7a-7b47-4abe-bd8a-4df57c2fc90a",
  "wallet_address": "0x60a1A4149A99bEaCEf7138Be44Cdda907039975b",
  "product_name": "MyProduct",
  "price": 5,
  "metadata": {
    "invoiceNumber": 12343,
    "customerId": "di2d-22edd2-232d2-22"
  },
  "token": "USDC",
  "recurring": false,
  "duration": "Until Cancelled",
  "frequency": "",
  "interval": "",
  "chainId": 1
}

Response

{
  "data": {
    "message": "Typed data message created sucessfully.",
    "purchase_session_id": "sess_7cf1a788-fefc-417a-bc30-68efce3d225c",
    "status": "success",
    "typedDataMessage": {
      "domain": {
        "chainId": 80002,
        "name": "CoinSubAgent",
        "verifyingContract": "0xb8F7B1B12F026266BbDCBDD1d302AF588812DDA6",
        "version": "1"
      },
      "message": {
        "A": 5,
        "D": 1,
        "I": 6,
        "M": "Sangat Das",
        "P": "1",
        "S": "CG_PLUS",
        "T": "USDC",
        "nonce": "0",
        "to": "0x215e3953a1bcb368dF42a23eb62cd4A72bf66181"
      },
      "primaryType": "Subscribe",
      "types": {
        "Subscribe": [
          { "name": "M", "type": "string" },
          { "name": "S", "type": "string" },
          { "name": "I", "type": "uint256" },
          { "name": "T", "type": "string" },
          { "name": "to", "type": "address" },
          { "name": "A", "type": "uint256" },
          { "name": "P", "type": "string" },
          { "name": "D", "type": "uint256" },
          { "name": "nonce", "type": "uint256" }
        ]
      }
    }
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Submit Signed Purchase Message

The Submit Signed Purchase Message endpoint allows you to submit signed messages for processing. If the user has already approved our network smart contract to spend their token then we can immediately process the payment.

If they need to approve our smart contract we will notify you and provide relevant information to complete the approval process. If token approval does not exist, the response will be permit message typed data.

A short demo on how to sign a message using EIP-712 is available here: CodeSandbox EIP-712 Demo.

Endpoint

POST https://api.vantack.com/v1/purchase/message/sign

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Body Parameters

NameTypeDescription
purchase_session_id string Required
ID of the purchase session.
signed_typed_data object Required
The signed typed data object returned after the user signs the EIP-712 message.

Request body example

{
  "purchase_session_id": "sess_4f480a7a-7b47-4abe-bd8a-4df57c2fc90a",
  "signed_typed_data": {
    "signature": "0x696db2a6114ffd5f758ad03b21e60a8ab16c8ee2c6ed63cbace750dd54b74bc140d0635560eb4e5f8234c1d78aa0436fc92c93125564ed988c85b767745b091501",
    "signing_address": "0x215e3953a1bcb368dF42a23eb62cd4A72bf66181",
    "chainId": 80002
  }
}

Response

{
  "data": {
    "approval_info": {
      "address": "0x215e3953a1bcb368dF42a23eb62cd4A72bf66181",
      "domain": {
        "chainId": 80002,
        "name": "USDC",
        "verifyingContract": "0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582",
        "version": "2"
      },
      "message": {
        "deadline": "1743594189",
        "nonce": "0",
        "owner": "0x215e3953a1bcb368dF42a23eb62cd4A72bf66181",
        "spender": "0xb8F7B1B12F026266BbDCBDD1d302AF588812DDA6",
        "value": "115792089237316195423570985008687907853269984665640564039457584007913129639935"
      },
      "primaryType": "Permit",
      "types": {
        "Permit": [
          { "name": "owner", "type": "address" },
          { "name": "spender", "type": "address" },
          { "name": "value", "type": "uint256" },
          { "name": "nonce", "type": "uint256" },
          { "name": "deadline", "type": "uint256" }
        ]
      }
    },
    "message": "Signed message is valid, but token approval is required",
    "status": "need_approval"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Permit Messages

Permit messages enable gasless token approvals by allowing users to sign an off-chain message that authorizes Vantack's smart contract to spend their tokens. Instead of requiring an on-chain approval transaction β€” which costs gas β€” users can simply sign a structured message with their wallet. This reduces friction at checkout and makes the payment process faster and more cost-effective.

When you submit a signed purchase session, Vantack checks whether the user has already approved token spending. If so, the payment is processed immediately. If not, the response will include a permit message in typed data format. You can present this message to the user for signing. Once signed, submit it to Vantack to complete the approval and proceed with the transaction β€” all without requiring an additional on-chain approval step.

Submit Signed Permit Message

The Submit Signed Permit Message endpoint enables you to submit the signed permit message from your user that gives our smart contract the ability to spend their tokens. Once we confirm the validity of the signed permit message we will process the related purchase session transaction.

A short demo on how to sign a message using EIP-712 is available here: CodeSandbox EIP-712 Demo.

Endpoint

POST https://api.vantack.com/v1/purchase/permit/sign

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Body Parameters

NameTypeDescription
purchase_session_id string Required
ID of the purchase session associated with this permit.
signed_permit object Required
The signed permit object from the user's wallet.

Request body example

{
  "purchase_session_id": "sess_7cf1a788-fefc-417a-bc30-68efce3d225c",
  "signed_permit": {
    "signing_address": "0x215e3953a1bcb368dF42a23eb62cd4A72bf66181",
    "signature": "0xe9899673e6a1c8dca3b47ee1b139aac1b9158be19773971ac5785a907f8a96335afa7a0ff1ffa026393b642b7695d00e12f7aaba6e96444a170aa843ddf0eb8e00",
    "chainId": 80002
  }
}

Response

{
  "data": {
    "message": "Permit signed successfully. We are processing the payment.",
    "status": "success"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Webhooks

Webhooks allow real-time communication between systems. They are used to synchronize disparate systems by publishing automated messages with predefined payloads that can be interpreted by integrated systems β€” enabling instant updates and data sharing without continuous polling.

Our platform webhooks provide notifications when specific actions occur on your account, such as when a customer subscribes to a product, purchases a one-off product, makes a payment, or cancels a subscription. By setting up webhooks, you can automate processes and keep your systems in sync with our platform in real-time.

How to Use the Webhooks

1. Sign into the platform
2. Navigate to Merchant Settings

From the dashboard, select the Settings menu on the sidebar, then Merchant Settings.

3. Input Webhook URL

Input your webhook URL and other merchant details in the settings.

If you want to control webhook URL configuration for your connected merchant accounts, use the Create Webhook for connected account endpoint under Accounts & API Keys.

Webhook Triggers

The webhook is triggered during the following actions:

  • When a customer subscribes to a recurring product.
  • When a customer purchases a one-off product.
  • When a customer makes a payment.
  • When a customer cancels a subscription.
  • When payment processing fails (e.g. insufficient customer balance).
  • When you execute a wallet-to-wallet transfer from your account.
Webhook Event Uniqueness

Every webhook includes an X-Event-Id header that uniquely identifies a specific trigger/event. For failed payments, multiple charge attempts may be associated with the same payment_id β€” each attempt still gets its own unique X-Event-Id.

Webhook Payloads

We send five different event types: Recurrence Signup, Payment, Failed Payment, Subscription Cancellation, and Wallet Transfer.

Recurrence Signup

When a customer agrees to make recurring payments, the webhook sends the following data. Note that other than the first_payment_id, there is no information about the first payment made β€” payment information is sent as a separate payment event.

Payload Fields

NameTypeDescription
type string
"recurrence_signup" β€” type of action being executed.
merchant_id string
Unique identifier for the merchant.
origin_id string
Unique identifier for the recurrence signup's origin.
origin string
Source of the payment. Values: "purchase_sessions" or "subscriptions".
name string
Name of the recurring payments.
amount number
The amount received each time a recurring payment is made.
agreement_id string
The id of the agreement that can be used to retrieve agreement details.
frequency string
How often the customer is billed. Values: "Every", "Every Other", "Every Third", "Every Fourth", "Every Fifth", "Every Sixth", or "Every Seventh".
interval string
The time period for the billing cycle. Values: "Day", "Week", "Month", or "Year".
duration string
The number of billing cycles. Either a number (e.g. "1") or "Until Cancelled". Data type: string.
start_date string
Date the user agreed to the recurring payments.
next_process_date string
The next date the customer will be billed.
first_payment_id string
The payment_id of the first payment made for this billing agreement.
user object
Information about the customer.
metadata object
Miscellaneous information (if any) about the payment. Data type: object.

Payload example

{
  "type": "recurrence_signup",
  "merchant_id": "mrch_10d3ed3c-2471-4573-ac66-ec7e3b414e80",
  "origin_id": "161",
  "origin": "subscriptions",
  "name": "asdasd",
  "amount": 0.0985,
  "agreement_id": "agre_115608f9-662c-4ae4-aa6f-3928f99df15b",
  "frequency": "Every",
  "interval": "Day",
  "duration": "Until Cancelled",
  "start_date": "2025-08-18T08:37:59.858585Z",
  "next_process_date": "2025-08-19T08:38:00Z",
  "first_payment_id": "paym_6f7a1c13-706c-4df3-a566-6a8ced58ccfc",
  "user": {
    "first_name": "Test",
    "last_name": "Test",
    "email": "test@gmail.com",
    "subscriber_id": "1d5faea9-306c-488d-b2f9-b00b2e8cd414"
  },
  "metadata": {
    "some": "metadata"
  }
}

Payment

When a customer makes a successful payment, the webhook sends the following data.

Every webhook includes an X-Event-Id header that uniquely identifies the event. You can use this to safely deduplicate deliveries on your end.

Payload Fields

NameTypeDescription
type string
"payment" β€” type of action being executed.
merchant_id string
Unique identifier for the merchant.
origin_id string
Unique identifier for the payment's origin.
origin string
Source of the payment. Values: "purchase_sessions" or "subscriptions".
name string
Name of the purchase item.
currency string
Symbol for the currency used (e.g. "USDC", "USDT").
amount number
The amount the customer paid, excluding fees.
metadata object
Miscellaneous information (if any) about the payment. Data type: object.
payment_date string
Date and time the payment was made.
status string
"completed".
payment_id string
The id of the payment object. Can be used to retrieve full transaction details.
transaction_details object
Information about the on-chain transaction.
user object
Information about the customer.
agreement_id string
ID of the purchase agreement.

Payload example

{
  "type": "payment",
  "merchant_id": "mrch_10d3ed3c-2471-4573-ac66-ec7e3b414e80",
  "origin_id": "161",
  "origin": "subscriptions",
  "name": "asdasd",
  "currency": "USDC",
  "amount": 0.1,
  "metadata": null,
  "payment_date": "2025-08-18T08:37:59.229191Z",
  "status": "completed",
  "transaction_details": {
    "transaction_id": 343,
    "transaction_hash": "0x15c4308c3f55e7ef13d062e0784ec30181a400a2ac92bfac849443c486d33963",
    "chain_id": 84532
  },
  "user": {
    "first_name": "asd",
    "last_name": "asd",
    "email": "asd@gmail.com",
    "subscriber_id": "1d5faea9-306c-488d-b2f9-b00b2e8cd414"
  },
  "payment_id": "paym_6f7a1c13-706c-4df3-a566-6a8ced58ccfc",
  "agreement_id": "agre_0a5578b2-b76b-4d8c-b568-4ec7442a21dc"
}

Failed Payment

When a customer makes a payment attempt and it fails, the webhook sends the following data.

For failed payments, multiple charge attempts may be associated with the same payment_id. Each charge attempt will still include its own unique X-Event-Id value, which you can use to differentiate between individual attempts.

Payload Fields

NameTypeDescription
type string
"failed_payment" β€” type of action being executed.
merchant_id string
Unique identifier for the merchant.
origin_id string
Unique identifier for the payment's origin.
origin string
Source of the payment. Values: "purchase_sessions" or "subscriptions".
name string
Name of the purchased item.
currency string
Symbol for the currency used (e.g. "USDC", "USDT").
amount number
The amount the customer attempted to pay, excluding fees.
metadata object
Miscellaneous information (if any) about the payment. Data type: object.
payment_date string
Date and time of the failed payment attempt.
status string
"failed".
transaction_details object
Information about the on-chain transaction.
user object
Information about the customer.
agreement_id string
ID of the purchase agreement.

Payload example

{
  "type": "failed_payment",
  "merchant_id": "mrch_92313b-1291-43c5-941d-9349d82fc33e",
  "origin_id": "8",
  "origin": "subscriptions",
  "name": "Willy Wonka's Wonka Bar",
  "currency": "USDC",
  "amount": 1,
  "metadata": {
    "some": "metadata"
  },
  "payment_date": "2025-05-28T17:20:03.766627-07:00",
  "status": "failed",
  "transaction_details": {
    "transaction_id": 29,
    "transaction_hash": "0x20887c4a415fdf19486364c02c550107da5c79147891e2264f1ef281383599fd",
    "chain_id": 80002
  },
  "user": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john_doe@company.net",
    "subscriber_id": "22b5ff13-e846-40cc-80fa-9e0261f8fd42"
  },
  "agreement_id": "agre_0a5578b2-b76b-4d8c-b568-4ec7442a21dc"
}

Subscription Cancellation

When a subscriber cancels a subscription, the webhook sends the following data.

Payload Fields

NameTypeDescription
type string
"cancellation" β€” type of action being executed.
merchant_id string
Unique identifier for the merchant.
origin string
Source of the payment. Values: "purchase_sessions" or "subscriptions".
name string
Name of the purchase item.
amount number
The amount paid with each billing cycle.
metadata object
Miscellaneous information (if any) about the payment. Data type: object.
agreement_id string
Unique identifier for the original agreement created at sign-up.
frequency string
How often the customer is billed. Values: "Every", "Every Other", "Every Third", "Every Fourth", "Every Fifth", "Every Sixth", or "Every Seventh".
interval string
The time period for the billing cycle. Values: "Day", "Week", "Month", or "Year".
duration string
The number of billing cycles. Either a number or "Until Cancelled". Data type: string.
start_date string
Date the user agreed to the recurring payments.
cancellation_date string
Date the user cancelled the agreement for recurring payments.
active_until string
Date the last billing cycle will end.
user object
Information about the customer.

Payload example

{
  "type": "cancellation",
  "merchant_id": "mrch_92313b-1291-43c5-941d-9349d82fc33e",
  "origin": "purchase_sessions",
  "name": "Willy Wonka's Candy Subscription Package",
  "amount": 1,
  "metadata": {
    "some": "metadata"
  },
  "agreement_id": "agre_78e289d9-bbb0-4930-be9a-2edd6822e1ff",
  "frequency": "Every",
  "interval": "Minute",
  "duration": "Until Cancelled",
  "start_date": "2025-05-28T16:22:49.47113-07:00",
  "cancellation_date": "2025-05-28T16:49:16.502493-07:00",
  "active_until": "2025-05-28T16:49:25.398975Z",
  "user": {
    "first_name": "John",
    "last_name": "Doe",
    "email": "john_doe@company.net",
    "subscriber_id": "22b5ff13-e846-40cc-80fa-9e0261f8fd42"
  }
}

Wallet Transfer

When you execute a wallet-to-wallet transfer from your merchant wallet, the following payload is sent to the webhook.

Payload Fields

NameTypeDescription
type string
"transfer" β€” indicates this payload is for a wallet-to-wallet transfer.
merchant_id string
Unique identifier for the merchant initiating the transfer.
amount_in_usd string
Amount being transferred, denominated in USD. Data type: string.
hash string
Unique transaction hash on the blockchain, used to verify and track the transfer.
transfer_id string
Unique identifier for this specific transfer within the platform.
wallet_id string
Unique identifier for the wallet within the platform that initiated the transfer.
network string
Blockchain network on which the transfer occurs (e.g. "Polygon").
from_address string
Blockchain address of the sender wallet.
to_address string
Blockchain address of the receiver wallet.
status string
Status of the transfer. Values: "success", "pending", "failed".
status_confirmed_at string
Timestamp when the transfer status was confirmed. Format: ISO 8601 with timezone.

Payload example

{
  "type": "transfer",
  "merchant_id": "mrch_053daf5f-7de6-491e-8096-5c8a8612f334",
  "amount_in_usd": "0.985000",
  "hash": "0x0924b6a3cc49d2ba216452358271533bc8190826b6cae395747be86b91a6ea98",
  "transfer_id": "7",
  "wallet_id": "wa-tffvk-1nj19-1qqbt0j5ieophqg",
  "network": "PolygonAmoy",
  "from_address": "0xd0cbe3ab3a241f6c4d5f2c0e2bfe37ec03fe7f04",
  "to_address": "0x1C337aBF69aB1DC1F9388e97bBd4AAD57059D8Eb",
  "status": "success",
  "status_confirmed_at": "2025-08-15T11:43:19.641041+02:00"
}

Retry Mechanism

If the webhook fails to deliver the data, it will retry up to 5 times, with each retry occurring every 5–10 minutes.

Embedded Checkout Options

This guide provides detailed information about integrating Vantack payment processing into your application. Vantack offers four distinct integration methods designed to accommodate different technical requirements and use cases β€” from simple no-code solutions to advanced API integrations with full customization capabilities.

Option Integration Level Customization Hosted Checkout UI
1. Standard Checkout Link πŸ”Ή No Code βœ… Full control βœ…
2. Button Embed πŸ”Έ Low Code βœ… Button color βœ…
3. iFrame Embed πŸ”Έ Medium Code βœ… Full control βœ…
4. Headless API πŸ”Έ Developer βœ… Fully programmable ❌

Which Integration Option Should You Use?

Choosing the right integration depends on your technical resources, business model, and how much control you want over the checkout experience.

πŸ”Ή Standard Checkout Link β€” Best for Non-Technical Merchants

Who it's for: Individual creators, small merchants or service providers, teams with no dev resources.

Why use it: Zero development required. Shareable across any platform (email, social, website). Fastest way to start accepting stablecoin payments.

πŸ”Έ Button Embed β€” Best for Low-Code Teams

Who it's for: Marketing teams with light dev help, Shopify/WordPress/Webflow users, sites that need a call-to-action button with minimal backend setup.

Why use it: Simple HTML embed. Button styling via data-color. Redirects to secure hosted checkout.

πŸ”Έ Modal iFrame β€” Best for Custom Frontends

Who it's for: Sites with web developers, businesses that care about seamless branding, publishers, SaaS sites, or gated content platforms.

Why use it: Fully embedded experience. Controlled modal styling. Checkout stays within your UI context.

πŸ”Έ Headless API β€” Best for Crypto-Native Platforms

Who it's for: Web3 apps, dApps, DeFi platforms, teams already managing wallets or signing flows, platforms needing custom onboarding or wallet UX.

Why use it: Full control over the payment process. You manage wallet interaction and signing. Suitable for integrations with other on-chain or backend systems.

Create a Product

Before using any integration option, follow these steps to create a product and get its unique checkout link:

1. Visit the Merchant Dashboard

https://app.vantack.com/merchant/products/

2. Click "+ Add Product"

Fill in the product name, pricing, and other details. You can create one-time or recurring subscription products.

3. Get Your Product Link & ID

After creation, you'll be shown a unique product checkout link, like: https://buy.vantack.com/9d205d5012

This ID (9d205d5012) is your product identifier β€” used in embed code, API requests, and iframe integrations.

Button Embed

Best for: Websites and applications that want seamless payment buttons with minimal development effort.

This method allows you to embed customizable payment buttons directly into your website with just a single script tag.

Prerequisites
  • A product created via the merchant dashboard.
  • Basic HTML/JavaScript knowledge for customization.
Implementation

After creating your product, embed the following snippet:

<script
  class="crypto-button-script"
  data-id="9d205d5012"
  data-color="#0484fc"
  src="https://buy.vantack.com/djs/button.js"
></script>
Customization Options
  • Button Color: Modify the data-color attribute to match your brand.
  • Button Size: Additional sizing options available in the button library.
  • Custom CSS: Apply additional styling to integrate with your design system.
  • Product ID: Modify the data-id attribute to reuse for another product.

iFrame Embed

Best for: Providing a seamless checkout experience while keeping customers on your website.

This method embeds the checkout experience directly into your website using an iframe within a modal overlay, ensuring customers never leave your site during the payment process.

Prerequisites
  • A product created via the merchant dashboard.
  • Basic HTML/JavaScript knowledge for customization.
Implementation

Use your checkout link to generate the iframe code:

<iframe
  src="https://buy.vantack.com/9d205d5012"
  allow="clipboard-read *; publickey-credentials-create *; publickey-credentials-get *"
></iframe>
Security Considerations
  • The iframe includes necessary permissions for secure crypto payments.
  • All payment processing occurs within the Vantack secure environment.
  • No sensitive payment data is handled by your website.

Test Customer Demand for Crypto Payments

The Crypto Interest & Engagement Button allows you to measure customer interest in paying with cryptocurrency before launch. By integrating this button, you can collect customer interactions, emails, and waitlist sign-ups β€” all without processing any payments immediately.

How It Works

1. Customer clicks "Pay with Crypto"

The button records the interaction in our database.

2. Modal opens

A pop-up asks the customer if they want to receive updates via email.

3. Customer enters email

They are added to your "waitlist" for crypto payments.

4. You get data

Track interest, cart sizes, and popular products.

Step 1 β€” Get Your Merchant ID

  • Log in to your Vantack Dashboard.
  • Go to Settings β†’ API Keys.
  • Copy your Merchant ID.

Step 2 β€” Add the Script to Your Website

Place the following script anywhere in your HTML:

<script
  src="https://test.vantack.com/djs/crypto-interest-button.js"
  data-merchant-id="YOUR_MERCHANT_ID_HERE"
  data-button-text="Subscribe with Crypto ⚑"
  data-background-color="rgb(30,30,30)"
  data-button-color="rgb(0, 200, 200)"
  data-button-text-color="rgb(255, 255, 255)"
  data-logo-mode="dark"
  data-cart-size="100"
  data-merchant-industry="Fashion"
  data-product-metadata='{"product_name": "Skirt", "price": 99.99, "category": "clothing"}'
></script>

Step 3 β€” Customize Button (Optional)

The button can be fully customized using the data-* attributes. You can customize the look of your buttons to match your website's style.

Attribute Required Description Example
data-merchant-id Required Your unique Merchant ID from Vantack. "b8690aab-2202-4ed5-abf7-02f4661e0925"
data-button-text Optional Text displayed on the button. "Subscribe with Crypto ⚑"
data-background-color Optional Background color of the button block. Accepts HEX or RGB. "rgb(30,30,30)"
data-button-color Optional Button color. "rgb(0,200,200)"
data-button-text-color Optional Color of the text on the button. "rgb(255,255,255)"
data-logo-mode Optional Logo style (dark or white). "dark"
data-cart-size Optional The total cart value associated with this product. 99.99
data-merchant-industry Optional Your business category. "Fashion"
data-product-metadata Optional Product details in JSON format. '{"product_name": "Skirt", "price": 99.99}'

Step 4 β€” Collect Data & Analyze

Use the APIs below to collect data about user engagement and interest. This feature is currently restricted to the test environment.

Get Click Count

Gets the total interest button click count.

Endpoint

GET https://api.vantack.com/v1/engagement/analytics/clicks

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Response

{
  "data": {
    "total_clicks": 0
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Get Click Count With Interval

Gets the total interest button click count with interval (in days).

Endpoint

GET https://api.vantack.com/v1/engagement/analytics/clicks/{days}

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Path Parameters

NameTypeDescription
days integer Required
Number of days to include in the interval (e.g. 8).

Response

{
  "data": {
    "total_clicks": 1,
    "interval": "1 days",
    "from_utc": "2025-09-30T00:00:00Z",
    "to_utc": "2025-10-01T00:00:00Z"
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Get Click Count & Details

Gets the total interest button click count with details about collected emails, consent, and user location breakdown.

Endpoint

GET https://api.vantack.com/v1/engagement/analytics/detailed

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Response

{
  "data": {
    "total_clicks": 27,
    "email_count": 7,
    "consent_count": 7,
    "average_cart_size": 1436.2962962962963,
    "user_countries": {
      "Germany": 1
    },
    "user_continents": {
      "Europe": 1
    }
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Get All Emails

Get all emails collected from the interest button.

Endpoint

GET https://api.vantack.com/v1/engagement/analytics/emails

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Query Parameters

NameTypeDescription
page string Optional
Page number.
per_page string Optional
Results per page.

Response

{
  "data": {
    "emails": [
      "test@platform.io"
    ],
    "total_count": 1,
    "page": 1,
    "per_page": 5,
    "total_pages": 1,
    "has_next": false,
    "has_previous": false
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}

Get All Data

Get all user collected data (regionality, cart size, products metadata, etc.).

Endpoint

GET https://api.vantack.com/v1/engagement/analytics/data

Header Parameters

NameTypeDescription
Content-Type string Optional
API-Key string Required
Merchant-ID string Required

Query Parameters

NameTypeDescription
page string Optional
Page number.
per_page string Optional
Results per page.

Response

{
  "data": {
    "results": [],
    "total_count": 0,
    "page": 1,
    "per_page": 10,
    "total_pages": 0,
    "has_next": false,
    "has_previous": false
  },
  "status": 200
}
{
  "error": "Unauthorized β€” invalid or missing API key.",
  "status": 401
}
{
  "error": "Bad request β€” invalid or missing required fields.",
  "status": 400
}
{
  "error": "An unexpected error occurred. Please try again later.",
  "status": 500
}