# Payvessel Checkout
Source: https://docs.payvessel.com/accept-payment/checkout
Hosted checkout for cards and bank transfer: integrate with the payvessel-checkout npm package or Merchant Checkout API
**Accept payments with minimal integration** using Payvessel's hosted checkout. Customers can pay with **card** or **bank transfer** in a single modal. Ideal for e-commerce, donations, and subscriptions.
## Overview
Payvessel Checkout provides a secure, conversion-optimized payment interface. You can integrate it in two ways:
1. **npm package (Recommended):** A lightweight frontend SDK that handles the modal UI and payment channels.
2. **Merchant Checkout API:** A server-side integration for custom redirects or backend-driven flows.
Use your **public API key** (`api_key`) in frontend code. Keep secret keys server-side only.
### Recommended Integration Pattern
For production systems, use this flow:
1. Create order/session state on your backend first.
2. Launch checkout from your frontend using `payvessel-checkout`.
3. On completion callbacks, verify transaction status on your backend.
4. Fulfill value (goods/services/wallet credit) **only after successful server-side verification**.
***
## Integrating with `payvessel-checkout`
The `payvessel-checkout` package is the fastest way to add payment capabilities to your web application.
### Installation
Install the package via npm or Yarn:
```bash theme={null}
npm install payvessel-checkout
# or
yarn add payvessel-checkout
```
### Usage Examples
Include the SDK via CDN or bundle it with your app.
```html theme={null}
```
```jsx theme={null}
import { Checkout } from 'payvessel-checkout';
function PaymentButton() {
const handlePayment = async () => {
const init = Checkout({
api_key: 'YOUR_PUBLIC_API_KEY',
});
await init.initializeCheckout({
customer_email: 'user@example.com',
customer_phone_number: '08012345678',
customer_name: 'Jane Smith',
amount: '1000',
currency: 'NGN',
metadata: { order_id: 'ORD-1001' },
channels: ['BANK_TRANSFER', 'CARD'],
onSuccessfulOrder: (data) => {
alert('Payment received!');
console.log(data);
},
onClose: () => console.log('User closed the modal'),
});
};
return (
);
}
```
Ensure you use the `"use client"` directive for the payment component.
```tsx theme={null}
"use client";
import { Checkout } from 'payvessel-checkout';
export default function CheckoutComponent() {
const startPayment = async () => {
const init = Checkout({
api_key: process.env.NEXT_PUBLIC_PAYVESSEL_KEY!,
});
await init.initializeCheckout({
customer_email: 'customer@email.com',
customer_phone_number: '08012345678',
customer_name: 'Customer Name',
amount: '2500',
currency: 'NGN',
metadata: { order_id: 'ORD-2500' },
channels: ['BANK_TRANSFER', 'CARD'],
onSuccessfulOrder: (response) => {
// Handle success
},
});
};
return (
);
}
```
### Essential Parameters
| Parameter | Type | Required | Description |
| ----------------------- | ------ | -------- | --------------------------------------------------------- |
| `api_key` | string | Yes | Your Public API Key from the dashboard. |
| `customer_email` | string | Yes | The customer's email address. |
| `customer_phone_number` | string | Yes | The customer's phone number. |
| `customer_name` | string | Yes | The customer's full name. |
| `amount` | string | Yes | Amount to charge in naira (e.g., "100" for β¦100.00). |
| `currency` | string | Yes | Currency code, default is `NGN`. |
| `metadata` | object | Yes | Attach order context (for example, order id and cart id). |
| `channels` | array | No | Payment methods: `["BANK_TRANSFER", "CARD"]`. |
| `reference` | string | No | Your unique transaction reference. |
### Callback Behavior
| Callback | When It Fires | Recommended Action |
| ------------------- | ------------------------------------------------------------------------ | --------------------------------------------------- |
| `onSuccess` | Initialization succeeds (checkout session created) | Log and track for observability. |
| `onSuccessfulOrder` | Customer completes payment and transaction is confirmed in checkout flow | Call your backend to verify and then fulfill value. |
| `onError` | Checkout initialization/payment flow encounters an error | Show user-friendly error and allow retry. |
| `onClose` | User closes the modal | Preserve cart/session and allow resume. |
***
## Server-Side Verification
After a successful payment, always verify the transaction on your server before providing value to the customer.
1. Listen for webhooks from Payvessel.
2. Or use the **Verify Transaction** API to check the status manually.
For technical details, see:
* [Verify Payment](/api-reference/transactions/verify-payment)
* [Webhook Basics](/api-basics/webhooks)
Never mark an order as paid based only on frontend callbacks.
***
## Mobile and Platform SDKs
If you are not integrating with a web frontend, use the SDK that matches your platform.
### React Native SDK (`react-native-payvessel`)
Use this SDK for React Native apps with in-app modal checkout.
```bash theme={null}
npm install react-native-payvessel react-native-webview
# iOS only
cd ios && pod install
```
```tsx theme={null}
import React, { useState } from "react";
import { View, Button } from "react-native";
import PayvesselCheckout from "react-native-payvessel";
export default function App() {
const [visible, setVisible] = useState(false);
return (
);
}
```
Reference: [react-native-payvessel on npm](https://www.npmjs.com/package/react-native-payvessel)
### iOS SDK (`Payvessel`)
Install with CocoaPods:
```ruby theme={null}
pod 'Payvessel', '~> 1.0'
```
Or Swift Package Manager:
```swift theme={null}
dependencies: [
.package(url: "https://github.com/Nex-Panther-Technologies-Ltd/payvessel-ios-sdk.git", from: "1.0.0")
]
```
```swift theme={null}
import Payvessel
Payvessel.shared.configure(with: PayvesselConfig(
apiKey: "your_api_key",
secretKey: "your_secret_key",
environment: .sandbox
))
```
Reference: [Payvessel on CocoaPods](https://cocoapods.org/pods/Payvessel)
### Android SDK (`payvessel-android-sdk`)
Add JitPack and dependency:
```kotlin theme={null}
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven("https://jitpack.io")
}
}
```
```kotlin theme={null}
dependencies {
implementation("com.github.Nex-Panther-Technologies-Ltd:payvessel-android-sdk:1.0.0")
}
```
```kotlin theme={null}
Payvessel.configure(
PayvesselConfig(
apiKey = "your_api_key",
secretKey = "your_secret_key",
environment = PayvesselEnvironment.SANDBOX
)
)
```
Reference: [Android SDK on JitPack](https://jitpack.io/#Nex-Panther-Technologies-Ltd/payvessel-android-sdk/1.0.0)
### WooCommerce Plugin
For WordPress stores, install the official WooCommerce plugin and add your Payvessel keys in WooCommerce payment settings.
Reference: [Payvessel Payment Gateway for WooCommerce](https://wordpress.org/plugins/payvessel-payment-gateway-for-woocommerce/)
***
## Next Steps
Request/response schemas for server-side integration.
How to confirm payments accurately.
# Customer Reserved Account
Source: https://docs.payvessel.com/accept-payment/customer-reserved-account
Create virtual bank accounts for customers: STATIC (permanent) or DYNAMIC (one-time) reserve accounts
**Reserve virtual bank accounts** so customers can pay by transferring to a unique account number. Use **STATIC** accounts for recurring funding (e.g. wallet top-up, rent) or **DYNAMIC** accounts for one-time payments.
Permanent account. **9PSB: KYC optional** (30k daily limit, can upgrade). **Palmpay: KYC required**. Safe to store and reuse.
Temporary, one-time use. No KYC required. Create when needed; do not store.
***
## STATIC vs DYNAMIC
| | **STATIC** | **DYNAMIC** |
| --------------- | ------------------------------------------------------- | ----------------------------------------- |
| **Lifespan** | Permanent | Temporary, single use |
| **Use case** | Recurring payments, wallet funding, saved beneficiaries | One-time payment (e.g. checkout) |
| **BVN/NIN** | 9PSB: Optional; Palmpay: Required | Not required |
| **Storage** | Can store in your DB; customer can save as beneficiary | Do **not** store; create when you need it |
| **After use** | Stays valid | Becomes invalid immediately after use |
| **Daily limit** | 9PSB: 30k (without BVN/NIN); upgrade to lift limit | N/A |
**DYNAMIC accounts:** If a customer sends money to an expired or already-used DYNAMIC account, they will receive a **refund**. Always create a new DYNAMIC account per transaction when using one-time flows.
***
## How it works
1. You call the **Reserve an Account** API with customer details and `account_type`: `STATIC` or `DYNAMIC`.
2. Payvessel returns one or more **virtual account numbers** (per partner bank).
3. You share the account number, account name, and bank name with the customer.
4. When the customer transfers to that account, Payvessel, the partner bank, and you (the merchant) get notified.
5. You use the account reference / tracking reference for reconciliation and records.
### Supported banks
Both STATIC and DYNAMIC accounts can be created with these partner banks:
| Bank | Code |
| --------------------- | -------- |
| PalmPay | `999991` |
| 9Payment Service Bank | `120001` |
**KYC Requirements:**
* **9PSB Static**: KYC optional (no BVN/NIN needed to create; 30k daily limit applies)
* **Palmpay Static**: KYC required (BVN or NIN must be provided)
* **9PSB Dynamic**: No KYC required
* **Palmpay Dynamic**: No KYC required
You can request accounts for one or both banks by passing their codes in the `bankcode` array.
***
## When to use which
* **Single-service payments** (e.g. electricity, ISP): Reserve an account per customer so they pay by transfer; you get notifications and can confirm payment.
* **Wallets / top-up** (e.g. super agents, investment apps, logistics): Use **STATIC** accounts so each customer has a permanent account number to fund their wallet.
* **One-time checkout**: Use **DYNAMIC**: create an account when the user chooses βPay with bank transferβ, show the details, and do not reuse that account.
## Upgrading 9PSB Static Accounts
When a customer's 9PSB static account receives funds exceeding the 30k daily limit, they must upgrade the account by providing their BVN and NIN. You can implement this upgrade flow in two ways:
1. **Merchant-initiated**: Merchant upgrades the account on their dashboard
2. **Customer-initiated**: Customer upgrades via your platform using the [Update Virtual Account](/api-reference/virtual-accounts/update-virtual-account) API endpoint
Once upgraded, the customer's account will have no daily limit restrictions.
***
## API reference (code, payload, response)
For the **Create Virtual Account** and **Get Virtual Account** endpoints: including request/response bodies, headers, and code samples: use the **API reference** tab:
***
## Next steps
OpenAPI reference for create virtual account
Fetch account details by business ID and account number
Configure webhooks for payment notifications
Authentication and base URLs
# Authentication
Source: https://docs.payvessel.com/api-basics/authentication
Learn how to authenticate your API requests with Payvessel
**Secure your API requests with Payvessel's authentication system.**
All API requests to Payvessel must be authenticated using your API credentials. This ensures that only authorized applications can access your account and process payments.
Your unique identifier for API access
Your secret token for request authentication
***
## Authentication Headers
Include these headers in every API request:
```json theme={null}
{
"api-key": "YOUR_API_KEY",
"api-secret": "YOUR_SECRET",
"Content-Type": "application/json"
}
```
**Keep your credentials secure!** Never expose your API secret in client-side code or public repositories.
## Environment Details
### π§ͺ Sandbox Environment
The sandbox environment is dedicated to test and development phases.
```bash Base URL theme={null}
https://sandbox.payvessel.com
```
```bash API Key theme={null}
YOUR_API_KEY
```
```bash API Secret theme={null}
YOUR_SECRET
```
### π Production Environment
The production environment is dedicated to live applications with real connections to institutions.
```bash Base URL theme={null}
https://api.payvessel.com
```
```bash API Key theme={null}
Your production API key (starts with PVKEY-)
```
```bash API Secret theme={null}
Your production API secret (starts with PVSECRET-)
```
## Key Rotation
Regular key rotation is essential for maintaining security:
Create a new API key in your Payvessel dashboard
Deploy your application with the new key
Verify all functionality works with the new key
Disable the old key once the new one is confirmed working
## Troubleshooting Authentication
**Common causes:**
* Invalid or expired API key
* Missing Authorization header
* Key used in wrong environment
**Solutions:**
* Verify key format and environment
* Check header spelling and format
* Regenerate key if necessary
**Common causes:**
* Insufficient permissions for the operation
* Account not verified for live transactions
* API key doesn't have required scopes
**Solutions:**
* Check account verification status
* Verify API key permissions
* Contact support for scope issues
# Environments
Source: https://docs.payvessel.com/api-basics/environments
Understanding Payvessel's sandbox and production environments
**Safely develop and test your integration before going live with Payvessel's dedicated environments.**
Payvessel provides separate environments to ensure you can build, test, and deploy your payment integration with confidence.
Safe testing environment with simulated transactions
Live environment for real payments and transactions
***
## Sandbox Environment
The sandbox environment provides a complete replica of the production API without processing real money or affecting live systems.
### π― Purpose and Benefits
Build and iterate on your integration safely
Validate all payment flows and error scenarios
Understand API behavior without financial risk
### π Sandbox Features
* Test credit card numbers for various scenarios
* Simulated bank account information
* Mock mobile money accounts
* Cryptocurrency test networks
* Full webhook functionality
* Simulated event triggers
* Webhook validation tools
* Real-time event monitoring
* Transaction history and analytics
* Account management features
* API key management
* Webhook configuration
### π Sandbox Endpoints
The sandbox environment is dedicated to test and development phases.
```bash theme={null}
# Sandbox Base URL
https://sandbox.payvessel.com
```
Example sandbox request:
```bash theme={null}
curl https://sandbox.payvessel.com/api/v1/payments \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{
"amount": 1000,
"currency": "USD",
"payment_method": "card"
}'
```
## Production Environment
The production environment processes real payments and handles live customer transactions.
### π Going Live Requirements
Fully implement and test your integration in sandbox
Complete KYC and business verification process
Pass security assessment and compliance checks
Receive approval from Payvessel team
### π Production Endpoints
The production environment is dedicated to live applications with real connections to institutions.
```bash theme={null}
# Production Base URL
https://api.payvessel.com
```
Example production request:
```bash theme={null}
curl https://api.payvessel.com/api/v1/payments \
-H "api-key: PVKEY-[your-production-key]" \
-H "api-secret: PVSECRET-[your-production-secret]" \
-H "Content-Type: application/json" \
-d '{
"amount": 1000,
"currency": "USD",
"payment_method": "card"
}'
```
### π Production Security
Production environment includes enhanced security measures:
* **Real-time fraud monitoring**
* **Advanced threat detection**
* **Compliance scanning**
* **Audit logging**
* **Encrypted data storage**
## Best Practices
* Test all payment flows thoroughly
* Validate error handling scenarios
* Test webhook endpoints
* Verify currency and amount handling
* Use separate API keys for each environment
* Implement proper error handling
* Monitor transaction success rates
* Set up alerting for failures
# PayVessel API Products
Source: https://docs.payvessel.com/api-products
Explore PayVessel APIs for USD virtual cards, Nigerian virtual accounts, BVN and NIN verification, credit score checks, payments, transfers, and wallets.
PayVessel provides REST APIs for payments, banking, identity, and card issuing in Nigeria. Use this page to find the right product API for your integration.
## Virtual card API
Issue **USD virtual Visa and Mastercard** cards for your customers. Fund cards from your business wallet, manage freeze and terminate lifecycle, and receive webhooks for spend and funding events.
Getting started, limits, and security
API reference with request samples
Load USD from your business wallet
## Virtual account API
Create **STATIC** or **DYNAMIC** Nigerian virtual bank accounts so customers can pay you by bank transfer. Reserve accounts per customer and reconcile incoming credits with webhooks.
Guide: STATIC vs DYNAMIC accounts
API reference
Retrieve account details by ID
Checkout and collection flows
## BVN verification API
Verify **Bank Verification Number (BVN)** details against customer-submitted identity data. Choose basic field-match verification or enhanced profile retrieval for deeper KYC.
Match scores and onboarding checks
Full BVN profile fields
API reference
API reference
## NIN verification API
Verify **National Identification Number (NIN)** records for Nigerian customers. Use basic verification for match results or enhanced verification when you need richer identity attributes.
Field-match workflows
Extended NIN profile data
API reference
API reference
## Credit score API and risk checks
Run **credit score queries**, blacklist screening, and loan-feature lookups to support underwriting, limits, and compliance decisions.
Score-based risk signals
Request and response schemas
Screen customers against deny lists
Full verification stack
## Payments, transfers, and wallets
Checkout and card payments
Payouts and disbursements
Managed balances
All endpoints
## Get started
1. Create a PayVessel business account and obtain **API key** and **secret** from the [Dashboard](https://app.payvessel.com).
2. Read [Authentication](/api-basics/authentication) and [Environments](/api-basics/environments) (production and sandbox).
3. Follow the [Quickstart](/quickstart) or jump to the product guide above.
# Create Order
Source: https://docs.payvessel.com/api-reference/biller-reseller/create-order
api-reference/vaas-services-openapi.json POST /vaas/api/v1/biller-reseller/orders
Create a biller reseller order and charge the merchant wallet
# Get Biller Items
Source: https://docs.payvessel.com/api-reference/biller-reseller/get-biller-items
api-reference/vaas-services-openapi.json GET /vaas/api/v1/biller-reseller/billers/{biller_id}/items
Get available items/packages for a specific biller and category
# Get Billers
Source: https://docs.payvessel.com/api-reference/biller-reseller/get-billers
api-reference/vaas-services-openapi.json GET /vaas/api/v1/biller-reseller/billers
Get available billers for a given category
# Get Order
Source: https://docs.payvessel.com/api-reference/biller-reseller/get-order
api-reference/vaas-services-openapi.json GET /vaas/api/v1/biller-reseller/orders/{order_id}
Get a biller reseller order by ID
# Validate Recharge Account
Source: https://docs.payvessel.com/api-reference/biller-reseller/validate-account
api-reference/vaas-services-openapi.json POST /vaas/api/v1/biller-reseller/validate-account
Validate a customer recharge account before placing an order
# Verify Order
Source: https://docs.payvessel.com/api-reference/biller-reseller/verify-order
api-reference/vaas-services-openapi.json GET /vaas/api/v1/biller-reseller/orders/verify/{reference}
Verify the status of a biller reseller order by its merchant reference
# Create eSIM Order
Source: https://docs.payvessel.com/api-reference/esim/create-order
api-reference/vaas-services-openapi.json POST /vaas/api/v1/esim/orders
Create an eSIM order and charge the merchant wallet
# Get eSIM Order
Source: https://docs.payvessel.com/api-reference/esim/get-order
api-reference/vaas-services-openapi.json GET /vaas/api/v1/esim/orders/{order_id}
Get an eSIM order by ID and refresh provider status
# List Packages
Source: https://docs.payvessel.com/api-reference/esim/list-packages
api-reference/vaas-services-openapi.json GET /vaas/api/v1/esim/packages
List available eSIM packages with optional filters
# List Regions
Source: https://docs.payvessel.com/api-reference/esim/list-regions
api-reference/vaas-services-openapi.json GET /vaas/api/v1/esim/regions
List all supported eSIM regions
# List Airports
Source: https://docs.payvessel.com/api-reference/flight/airports
api-reference/vaas-services-openapi.json GET /vaas/api/v1/flight/airports
Retrieve the supported airport catalogue for the flight API
# Create Flight Order
Source: https://docs.payvessel.com/api-reference/flight/create-order
api-reference/vaas-services-openapi.json POST /vaas/api/v1/flight/orders
Charge the wallet and create a flight booking order
# Create Flight Quote
Source: https://docs.payvessel.com/api-reference/flight/create-quote
api-reference/vaas-services-openapi.json POST /vaas/api/v1/flight/quotes
Validate a selected flight option and create a bookable quote
# Get Flight Order
Source: https://docs.payvessel.com/api-reference/flight/get-order
api-reference/vaas-services-openapi.json GET /vaas/api/v1/flight/orders/{order_id}
Retrieve a single flight order by ID
# List Flight Orders
Source: https://docs.payvessel.com/api-reference/flight/list-orders
api-reference/vaas-services-openapi.json GET /vaas/api/v1/flight/orders
Retrieve all flight orders for the authenticated business
# Search Flights
Source: https://docs.payvessel.com/api-reference/flight/search
api-reference/vaas-services-openapi.json POST /vaas/api/v1/flight/search
Retrieve available flight options and preview pricing
# Get Country
Source: https://docs.payvessel.com/api-reference/gift-cards/get-country
api-reference/vaas-services-openapi.json GET /vaas/api/v1/gift-cards/countries/{country_id}
Retrieve a single country by its numeric ID
# Get Order
Source: https://docs.payvessel.com/api-reference/gift-cards/get-order
api-reference/vaas-services-openapi.json GET /vaas/api/v1/gift-cards/orders/{order_id}
Retrieve a gift card order by ID
# List Countries
Source: https://docs.payvessel.com/api-reference/gift-cards/list-countries
api-reference/vaas-services-openapi.json GET /vaas/api/v1/gift-cards/countries
List all countries with gift card products available
# List Operators
Source: https://docs.payvessel.com/api-reference/gift-cards/list-operators
api-reference/vaas-services-openapi.json GET /vaas/api/v1/gift-cards/countries/{country_code}/operators
Fetch all gift card operators available in a specific country
# List Products
Source: https://docs.payvessel.com/api-reference/gift-cards/list-products
api-reference/vaas-services-openapi.json GET /vaas/api/v1/gift-cards/operators/{operator_id}/products
Fetch all available products for a gift card operator
# Purchase Gift Card
Source: https://docs.payvessel.com/api-reference/gift-cards/purchase
api-reference/vaas-services-openapi.json POST /vaas/api/v1/gift-cards/orders
Purchase a gift card and charge the business wallet
# Verify Order
Source: https://docs.payvessel.com/api-reference/gift-cards/verify-order
api-reference/vaas-services-openapi.json GET /vaas/api/v1/gift-cards/orders/verify/{reference}
Verify the status of a gift card order by its merchant reference
# API Reference
Source: https://docs.payvessel.com/api-reference/introduction
PayVessel REST API reference for virtual card API, virtual account API, BVN and NIN verification API, credit score API, payments, transfers, and wallets.
**Code samples, request/response payloads, and endpoint reference.** Use this tab for HTTP methods, headers, body schemas, and example code. For concepts, integration flows, and when-to-use guidance, see the **Guides** tab.
PayVessel's REST API provides programmatic access to accept payments, send money, verify identities, manage wallets, issue **USD virtual cards**, and more. Our API is organized around REST principles with predictable resource-oriented URLs, accepts form-encoded request bodies, returns JSON-encoded responses, and uses standard HTTP response codes and authentication.
**Base URL**: `https://api.payvessel.com`
**Sandbox URL**: `https://sandbox.payvessel.com`
**Live**: 100 requests per minute
**Sandbox**: 1000 requests per minute
## Authentication
All API requests must be authenticated with your **API key** and **secret key**. Your API keys carry many privileges, so be sure to keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, and so forth.
```bash cURL theme={null}
curl https://api.payvessel.com/transaction/initialize \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY" \
-H "Content-Type: application/json"
```
```javascript Node.js theme={null}
const payvessel = require('payvessel')(YOUR_SECRET_KEY);
```
```php PHP theme={null}
```
```python Python theme={null}
import payvessel
payvessel.api_key = "YOUR_SECRET_KEY"
```
**Keep your API keys secure!** Your secret API key can perform any API request to PayVessel without restriction. Store your secret key securely and never expose it in client-side code.
## API Categories
Our API is organized into logical groups of functionality, matching the navigation:
Initialize, confirm, and verify payments, and retrieve transaction lists.
**Key Endpoints:**
* `POST /transaction/initialize` - Initialize a payment
* `POST /transaction/confirm` - Confirm transaction
* `GET /transaction/verify/{reference}` - Verify transaction status
* `GET /transaction/list` - List transactions
Send money to bank accounts and mobile money users with instant transfers.
**Key Endpoints:**
* `POST /transfer/recipient` - Create transfer recipient
* `POST /transfer/initiate` - Initialize transfer
Create and manage digital wallets, check balances, and generate statements.
**Key Endpoints:**
* `POST /wallets/create` - Create new wallet
* `GET /pms/api/external/request/wallet/balance/` - Check wallet balance
* `GET /wallets/{wallet_id}/statement` - Generate statement
Create and manage reserved virtual accounts for automated collections.
**Key Endpoints:**
* `POST /reserved-account/create` - Create virtual account
* `GET /reserved-account/{account_number}` - Get account details
## Request & Response Format
### Authentication
All API requests require `api-key`, `api-secret`, and `Content-Type: application/json`. See [Authentication](/api-basics/authentication) for details.
### Response Structure
All API responses follow a consistent structure:
```json theme={null}
{
"status": true,false,
"message": "Descriptive message",
"data": {
// Response data here
}
}
```
### HTTP Status Codes
| Code | Description |
| ----- | --------------------------------------------------------------------- |
| `200` | **OK** - The request was successful |
| `201` | **Created** - The resource was successfully created |
| `400` | **Bad Request** - The request was invalid or malformed |
| `401` | **Unauthorized** - Authentication credentials were missing or invalid |
| `403` | **Forbidden** - The request is understood, but not authorized |
| `404` | **Not Found** - The requested resource could not be found |
| `429` | **Too Many Requests** - Rate limit exceeded |
| `500` | **Internal Server Error** - An error occurred on PayVessel's servers |
## Idempotency
The PayVessel API supports [idempotency](https://en.wikipedia.org/wiki/Idempotence) for safely retrying requests without accidentally performing the same operation twice. When creating or modifying objects, provide an additional `Idempotency-Key: ` header to the request.
**Best Practice**: Use a UUID or other random string as your idempotency key. PayVessel will return the same response for repeated requests with the same key for 24 hours.
## Webhooks
PayVessel uses webhooks to notify your application when events occur in your account. Learn more about webhook integration in our [webhook documentation](/api-basics/webhooks).
Common webhook events:
* `transaction.success` - Payment completed successfully
* `transaction.failed` - Payment failed or was declined
* `transfer.success` - Transfer completed successfully
* `verification.completed` - Identity verification completed
## Testing
Use our sandbox environment to test your integration without real money. The sandbox mirrors the production API but with test data.
**Sandbox Base URL**: `https://sandbox.payvessel.com`
Check out our [testing guide](/api-basics/testing) for test card numbers, bank accounts, and complete testing scenarios.
***
**Ready to start building?** Explore the endpoint documentation below or jump to our [quickstart guide](/quickstart) for step-by-step integration instructions.
# Initialize Payment
Source: https://docs.payvessel.com/api-reference/transactions/initialize-payment
POST /pms/transactions/initialize/
Initialize a new payment transaction to collect money from customers
Initialize a new payment transaction to collect money from customers via cards, bank transfers, or mobile wallets.
This endpoint creates a payment session and returns a checkout URL where customers can complete their payment securely.
This is the primary canonical initialization endpoint for both the transaction and checkout flows. It maps to `POST /pms/transactions/initialize/`, and `api-reference/checkout/initialize-transaction` is an equivalent alias.
## Endpoint
**POST** `/pms/transactions/initialize/`
## Request Body
Customer's email address for transaction receipt and notifications
Transaction amount in naira (NGN) or the smallest currency unit
For β¦500.00, send `"500"` (500 naira)
Three-letter ISO currency code
**Supported currencies:** `NGN`, `USD`
Unique transaction reference. If not provided, PayVessel will generate one automatically
Must be unique across all your transactions
URL to redirect customers after payment completion
Payment methods to allow for this transaction
**Available channels:** `BANK_TRANSFER`
If not specified, all available channels will be enabled
Customer information object
Customer's email address (alternative to root-level email)
Customer's first name
Customer's last name
Customer's phone number in international format
## Example Request
```bash cURL theme={null}
curl -X POST https://sandbox.payvessel.com/pms/transactions/initialize/ \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{
"customer_email": "test@example.com",
"customer_name": "Test Customer",
"customer_phone_number": "08012345678",
"amount": "50",
"currency": "NGN",
"channels": [
"BANK_TRANSFER"
]
}'
```
```javascript Node.js theme={null}
const payvessel = require('payvessel')(process.env.PAYVESSEL_SECRET_KEY);
const transaction = await payvessel.transaction.initialize({
email: 'customer@example.com',
amount: '50',
currency: 'NGN',
reference: 'TXN_2024_001',
callback_url: 'https://yourapp.com/payment/callback',
channels: ['BANK_TRANSFER'],
customer: {
first_name: 'John',
last_name: 'Doe',
phone: '+2348012345678'
}
});
```
```php PHP theme={null}
transaction->initialize([
'email' => 'customer@example.com',
'amount' => '50',
'currency' => 'NGN',
'reference' => 'TXN_2024_001',
'callback_url' => 'https://yourapp.com/payment/callback',
'channels' => ['BANK_TRANSFER'],
'customer' => [
'first_name' => 'John',
'last_name' => 'Doe',
'phone' => '+2348012345678'
]
]);
?>
```
```python Python theme={null}
import payvessel
payvessel.api_key = os.environ['PAYVESSEL_SECRET_KEY']
transaction = payvessel.Transaction.initialize(
email='customer@example.com',
amount='50',
currency='NGN',
reference='TXN_2024_001',
callback_url='https://yourapp.com/payment/callback',
channels=['BANK_TRANSFER'],
customer={
'first_name': 'John',
'last_name': 'Doe',
'phone': '+2348012345678'
}
)
```
## Response
Request status indicator - `"success"` or `"error"`
Human-readable message describing the result
Transaction data object
Secure checkout URL where customers complete payment
Access code for the transaction session
Unique transaction reference
Transaction amount in the smallest currency unit
Transaction currency code
Current transaction status - `"pending"`
ISO 8601 timestamp when transaction was created
## Example Response
```json 200 Success theme={null}
{
"status": true,
"message": "Checkout transaction successfully initialized",
"data": {
"id": "52b9bb2d-01d1-46ac-9800-14d34cb5f882",
"transaction_ref": "B0C866BD914C487895ACB8C45B939017",
"amount": "5000.00",
"status": "PENDING",
"access_code": "TEST-ACS-7AF7VH-2QIHE83N-TCTL28-BSDH",
"checkout_url": "https://checkout.payvessel.com/TEST-ACS-7AF7VH-2QIHE83N-TCTL28-BSDH",
"created_datetime": "2026-04-01T15:46:56.171229"
}
}
```
```json 400 Bad Request theme={null}
{
"success": false,
"message": "amount must be at least 50",
"details": [
{
"code": "invalid",
"detail": "amount must be at least 50",
"attr": "amount"
},
{
"code": "required",
"detail": "This field is required.",
"attr": "channels"
},
{
"code": "blank",
"detail": "This field may not be blank.",
"attr": "customer_email"
}
]
}
```
```json 401 Unauthorized theme={null}
{
"status": "error",
"message": "Unauthorized. Please check your API key"
}
```
After initializing a payment:
Confirm transaction status after payment
Receive real-time payment notifications
## Webhook Events
This endpoint triggers the following webhook events:
* `transaction.pending` - Transaction created and pending payment
* `transaction.success` - Payment completed successfully
* `transaction.failed` - Payment failed or was declined
**Best Practice**: Always verify transaction status using the verification endpoint, even after receiving webhook notifications, to ensure data integrity.
# Verify Payment
Source: https://docs.payvessel.com/api-reference/transactions/verify-payment
api-reference/openapi.json GET /pms/transactions/{reference}/confirm/
Verify the status of a payment transaction by reference
Verify the status and details of a payment transaction using its unique reference. Call this endpoint after payment completion to confirm the transaction status.
**Always verify payments!** Never rely solely on frontend callbacks or webhook notifications. Always verify transaction status on your backend for security.
## Endpoint
**GET** `/pms/transactions/{reference}/confirm/`
## Path Parameters
The unique transaction reference returned when the payment was initialized
## Example Request
```bash cURL theme={null}
curl -X GET https://api.payvessel.com/pms/transactions/TXN_2024_001/confirm/ \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET" \
-H "Content-Type: application/json"
```
```javascript Node.js theme={null}
const payvessel = require('payvessel')(process.env.PAYVESSEL_SECRET_KEY);
const transaction = await payvessel.transaction.confirm('TXN_2024_001');
```
```php PHP theme={null}
transaction->confirm('TXN_2024_001');
?>
```
```python Python theme={null}
import payvessel
payvessel.api_key = os.environ['PAYVESSEL_SECRET_KEY']
transaction = payvessel.Transaction.confirm('TXN_2024_001')
```
## Response
Request status indicator - `"success"` or `"error"`
Human-readable message describing the result
Transaction verification data
Internal transaction ID
Unique transaction reference
Transaction amount in smallest currency unit
Transaction currency code
Transaction status
**Possible values:**
* `success` - Payment completed successfully
* `failed` - Payment failed or was declined
* `pending` - Payment is still processing
* `abandoned` - Payment was started but not completed
* `cancelled` - Payment was cancelled
Response message from the payment gateway
ISO 8601 timestamp when payment was completed (null if not paid)
ISO 8601 timestamp when transaction was created
Payment method used - `card`, `bank`, `ussd`, `qr`, `mobile_money`, `bank_transfer`
Transaction fees charged in smallest currency unit
Customer information
Customer ID in PayVessel system
Customer's email address
Customer's first name
Customer's last name
Customer's phone number
Payment authorization details (for card payments)
Authorization code for future charges
First 6 digits of the card number
Last 4 digits of the card number
Card expiry month
Card expiry year
Authorization channel used
Type of card - `visa`, `mastercard`, `american express`, etc.
Issuing bank name
Country code of the issuing bank
Card brand
Whether the authorization can be reused for future payments
Custom metadata attached to the transaction
Transaction processing log and history
## Example Response
```json 200 Success - Successful Payment theme={null}
{
"status": "success",
"message": "Transaction verification successful",
"data": {
"id": 123456789,
"reference": "TXN_2024_001",
"amount": 50000,
"currency": "NGN",
"status": "success",
"gateway_response": "Successful",
"paid_at": "2024-01-15T14:35:22Z",
"created_at": "2024-01-15T14:30:00Z",
"channel": "card",
"fees": 750,
"customer": {
"id": 12345,
"email": "customer@example.com",
"first_name": "John",
"last_name": "Doe",
"phone": "+2348012345678"
},
"authorization": {
"authorization_code": "AUTH_xyz789abc",
"bin": "408408",
"last4": "4081",
"exp_month": "12",
"exp_year": "2027",
"channel": "card",
"card_type": "visa",
"bank": "TEST BANK",
"country_code": "NG",
"brand": "visa",
"reusable": true
},
"metadata": {
"custom_fields": [
{
"display_name": "Order ID",
"variable_name": "order_id",
"value": "ORD_001"
}
]
},
"log": {
"start_time": 1705329000,
"time_spent": 322,
"attempts": 1,
"errors": 0,
"success": true,
"mobile": false,
"input": [],
"history": [
{
"type": "action",
"message": "Attempted to pay with card",
"time": 15
},
{
"type": "success",
"message": "Successfully paid with card",
"time": 322
}
]
}
}
}
```
```json 200 Success - Failed Payment theme={null}
{
"status": "success",
"message": "Transaction verification successful",
"data": {
"id": 123456790,
"reference": "TXN_2024_002",
"amount": 50000,
"currency": "NGN",
"status": "failed",
"gateway_response": "Insufficient Funds",
"paid_at": null,
"created_at": "2024-01-15T15:00:00Z",
"channel": "card",
"fees": 0,
"customer": {
"id": 12346,
"email": "customer2@example.com",
"first_name": "Jane",
"last_name": "Smith",
"phone": "+2348012345679"
},
"authorization": null,
"metadata": {},
"log": {
"start_time": 1705330800,
"time_spent": 45,
"attempts": 1,
"errors": 1,
"success": false,
"mobile": false,
"input": [],
"history": [
{
"type": "action",
"message": "Attempted to pay with card",
"time": 10
},
{
"type": "error",
"message": "Payment failed: Insufficient Funds",
"time": 45
}
]
}
}
}
```
```json 404 Not Found theme={null}
{
"status": "error",
"message": "Transaction not found"
}
```
```json 401 Unauthorized theme={null}
{
"status": "error",
"message": "Unauthorized. Please check your API key"
}
```
## Transaction Status Guide
Understanding transaction statuses is crucial for proper payment handling:
**Payment Completed Successfully**
The payment has been processed and funds have been collected. You can proceed with order fulfillment.
* `paid_at` timestamp will be populated
* `authorization` object will contain card details (for card payments)
* Funds will be settled to your account based on your settlement schedule
**Payment Failed**
The payment attempt was unsuccessful. Common reasons include:
* Insufficient funds
* Invalid card details
* Bank decline
* Network timeout
* `paid_at` will be null
* `authorization` will be null
* Check `gateway_response` for specific failure reason
**Payment Processing**
The payment is still being processed. This is common with:
* Bank transfers
* USSD payments
* Some mobile money transactions
* Keep checking status periodically
* You'll receive a webhook when status changes
**Payment Started but Not Completed**
Customer initiated payment but didn't complete it:
* Closed browser before entering details
* Session timeout
* Customer changed mind
* No funds were collected
* Payment can potentially still be completed if session is still valid
**Payment Cancelled**
Payment was explicitly cancelled by customer or system:
* Customer clicked cancel
* Multiple failed attempts triggered cancellation
* System timeout
* Payment cannot be completed
* Customer needs to initiate a new payment
## Best Practices
**Verify every transaction** on your backend before order fulfillment, even after webhook notifications
**Implement logic** for all possible transaction statuses in your application
**Save authorization codes** for successful card payments to enable future recurring charges
**Use transaction logs** to debug payment issues and improve user experience
## Common Integration Patterns
```javascript theme={null}
// After customer returns from payment
app.get('/payment/callback', async (req, res) => {
const reference = req.query.reference;
try {
const verification = await payvessel.transaction.verify(reference);
if (verification.data.status === 'success') {
// Payment successful - fulfill order
await fulfillOrder(verification.data);
res.redirect('/order/success');
} else {
// Payment failed - show error
res.redirect('/order/failed');
}
} catch (error) {
// Handle verification error
res.redirect('/order/error');
}
});
```
```javascript theme={null}
// Verify subscription payment
const verifySubscriptionPayment = async (reference) => {
const verification = await payvessel.transaction.verify(reference);
if (verification.data.status === 'success') {
// Save authorization for future charges
await saveCustomerAuthorization({
customer_id: verification.data.customer.id,
authorization_code: verification.data.authorization.authorization_code,
card_type: verification.data.authorization.card_type,
last4: verification.data.authorization.last4
});
// Activate subscription
await activateSubscription(verification.data.customer.id);
}
return verification.data.status;
};
```
```javascript theme={null}
// Webhook endpoint for real-time updates
app.post('/webhook/payvessel', async (req, res) => {
const event = req.body;
if (event.event === 'transaction.success') {
// Always verify the transaction
const verification = await payvessel.transaction.verify(event.data.reference);
if (verification.data.status === 'success') {
await processSuccessfulPayment(verification.data);
}
}
res.status(200).send('OK');
});
```
## Related Endpoints
Create a new payment transaction
Retrieve transaction history
Process refunds for successful transactions
Charge a saved authorization for recurring payments
# Bulk Transfer
Source: https://docs.payvessel.com/api-reference/transfers/bulk-transfer
POST /pms/api/external/request/wallet/bulk-transfer/
Initiate multiple wallet transfers in a single batch
Use this endpoint to **send multiple payouts from your business wallet in one request**. Each transfer in the batch debits your wallet and credits a different beneficiary account.
Bulk transfers are powerful: always validate input (bank codes, account numbers, amounts) before sending a batch, and use unique references for each row.
### Sandbox
```bash theme={null}
curl -X POST "https://sandbox.payvessel.com/pms/api/external/request/wallet/bulk-transfer/" \
-H "api-key: YOUR_SANDBOX_API_KEY" \
-H "api-secret: YOUR_SANDBOX_API_SECRET" \
-H "Content-Type: application/json" \
-d '{"batch_reference":"PAYROLL_2026_03","transfers":[{"amount":"15000.00","account_number":"0123456789","bank_code":"999991","account_name":"John Doe","narration":"Salary March","reference":"PAYROLL_001"}]}'
```
## Endpoint
**POST** `/pms/api/external/request/wallet/bulk-transfer/`
## Request Body
Unique reference for this bulk batch (for reconciliation)
Must be unique across all your bulk transfers
List of individual transfers in the batch
Amount to send for this transfer in the smallest currency unit (e.g. `"15000.00"`)
Destination bank account number
Destination bank code (see bank list endpoint for available codes)
Optional account name for your own records
Description that may appear on the beneficiary's statement
Unique reference for this specific transfer in the batch
Must be unique across all transfers in this batch
### Example request
```json theme={null}
{
"batch_reference": "PAYROLL_2026_03",
"transfers": [
{
"amount": "15000.00",
"account_number": "0123456789",
"bank_code": "999991",
"account_name": "John Doe",
"narration": "March salary",
"reference": "PAYROLL_2026_03_EMP001"
},
{
"amount": "20000.00",
"account_number": "0987654321",
"bank_code": "120001",
"account_name": "Jane Smith",
"narration": "March salary",
"reference": "PAYROLL_2026_03_EMP002"
}
]
}
```
### Example cURL
```bash theme={null}
curl -X POST "https://api.payvessel.com/pms/api/external/request/wallet/bulk-transfer/" \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"batch_reference": "PAYROLL_2026_03",
"transfers": [
{
"amount": "15000.00",
"account_number": "0123456789",
"bank_code": "999991",
"account_name": "John Doe",
"narration": "March salary",
"reference": "PAYROLL_2026_03_EMP001"
},
{
"amount": "20000.00",
"account_number": "0987654321",
"bank_code": "120001",
"account_name": "Jane Smith",
"narration": "March salary",
"reference": "PAYROLL_2026_03_EMP002"
}
]
}'
```
## Response
On success you receive highβlevel information about the batch:
```json theme={null}
{
"status": true,
"message": "Bulk transfer initiated",
"data": {
"batch_reference": "PAYROLL_2026_03",
"total_count": 2,
"successful_count": 2,
"failed_count": 0,
"total_amount": "35000.00"
}
}
```
For detailed perβtransfer status, use the **transfer status** and **wallet transactions** endpoints.
# Get Bank List
Source: https://docs.payvessel.com/api-reference/transfers/get-bank-list
GET /pms/api/external/request/wallet/banks/
Retrieve list of supported banks for fund transfers
Retrieve list of supported banks for fund transfers.
## Endpoint
GET `/pms/api/external/request/wallet/banks/`
## Response
### 200
**Media type:** `application/json`
```json theme={null}
{
"status": true,
"message": "string",
"data": [
{
"bank_code": "string",
"bank_name": "string",
"bank_short_name": "string",
"bank_logo_url": "string",
"is_active": true
}
]
}
```
## Response Fields
Request status indicator
Response message
List of supported banks
Unique bank code used for transfers
Full bank name
Short bank display name
URL to bank logo image
Whether the bank is currently active for transfers
# Initiate Transfer
Source: https://docs.payvessel.com/api-reference/transfers/initiate-transfer
POST /pms/api/external/request/wallet/transfer/
Send money from your managed wallet to a bank account
Use this endpoint to **initiate a single payout from your business wallet to a beneficiaryβs bank account**. The transfer debits your wallet and credits the destination account.
**Transfers are irreversible once completed.** Always validate account details and confirm available balance before initiating a transfer.
## Endpoint
**POST** `/pms/api/external/request/wallet/transfer/`
## Request Body
Amount to transfer in the smallest currency unit (e.g. `"15000.00"` for β¦15,000.00)
Destination bank account number
Destination bank code (see bank list endpoint for available codes)
Optional account name for your own records
Description that may appear on the beneficiary's statement
Unique transfer reference for idempotency and reconciliation
Must be unique across all your transfers
One-time password when required by your security settings
### Example request
```json theme={null}
{
"amount": "15000.00",
"account_number": "0123456789",
"bank_code": "999991",
"account_name": "John Doe",
"narration": "Vendor payout - March",
"reference": "PAYOUT_2026_0001",
"otp": "123456"
}
```
### Example cURL
```bash theme={null}
curl -X POST "https://api.payvessel.com/pms/api/external/request/wallet/transfer/" \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"amount": "15000.00",
"account_number": "0123456789",
"bank_code": "999991",
"account_name": "John Doe",
"narration": "Vendor payout - March",
"reference": "PAYOUT_2026_0001",
"otp": "123456"
}'
```
## Response
On success you receive a JSON response with highβlevel status and details about the initiated transfer:
```json theme={null}
{
"status": true,
"message": "Transfer initiated successfully",
"data": {
"reference": "PAYOUT_2026_0001",
"session_id": "SESSION_123456789",
"amount": "15000.00",
"status": "pending",
"destination_account_number": "0123456789",
"destination_bank_code": "999991",
"destination_account_name": "John Doe"
}
}
```
The initial status will typically be `pending` while the receiving bank processes the transfer.
## Related endpoints
Use these endpoints together with **Initiate Transfer** to build a complete payout flow:
* **Get wallet balance**: check available funds before sending money.
* **Get bank list**: fetch supported banks and their bank codes.
* **Validate account**: confirm account number + bank code matches the expected account name.
* **Transfer status**: confirm whether a transfer is `pending`, `success`, or `failed` using `reference` and `session_id`.
* **Wallet transactions**: retrieve past transfers for reconciliation and reporting.
For highβlevel guidance and examples of when to use single vs bulk transfers, see the **Single Transfers** and **Bulk Transfers** guides under **Send Money & Payouts**.
# Transfer Status
Source: https://docs.payvessel.com/api-reference/transfers/transfer-status
POST /pms/api/external/request/wallet/transfer-status/
Check the status of a previously initiated transfer
Use this endpoint to **check the final status of a transfer** you created with either **Initiate Transfer** or **Bulk Transfer**.
## Endpoint
**POST** `/pms/api/external/request/wallet/transfer-status/`
## Request Body
Transfer reference you passed when initiating the transfer
Session ID returned in the initial transfer response
### Example request
```json theme={null}
{
"reference": "PAYOUT_2026_0001",
"session_id": "SESSION_123456789"
}
```
### Example cURL
```bash theme={null}
curl -X POST "https://api.payvessel.com/pms/api/external/request/wallet/transfer-status/" \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"reference": "PAYOUT_2026_0001",
"session_id": "SESSION_123456789"
}'
```
## Response
```json theme={null}
{
"status": true,
"message": "Transfer status retrieved",
"data": {
"reference": "PAYOUT_2026_0001",
"session_id": "SESSION_123456789",
"amount": "15000.00",
"status": "success",
"destination_account_number": "0123456789",
"destination_bank_code": "999991",
"destination_account_name": "John Doe",
"completed_at": "2026-03-11T13:04:35.988Z"
}
}
```
The `status` field in `data` tells you whether the transfer is `pending`, `success`, or `failed`.
Use this endpoint together with **Initiate Transfer**, **Bulk Transfer**, and wallet transaction history for full payout reconciliation.
# Validate Account
Source: https://docs.payvessel.com/api-reference/transfers/validate-account
POST /pms/api/external/request/wallet/validate-account/
Resolve an account number to an account name before initiating transfer
Resolve an account number to an account name before initiating transfer.
## Endpoint
**POST** `/pms/api/external/request/wallet/validate-account/`
## Request Body
**Media type:** `application/json`
```json theme={null}
{
"account_number": "4044823317",
"bank_code": "8980"
}
```
Bank account number to validate
Bank code for the destination bank
## Response
### 200
**Media type:** `application/json`
```json theme={null}
{
"status": true,
"message": "string",
"data": {
"account_name": "string",
"account_number": "string",
"bank_code": "string",
"bank_name": "string"
}
}
```
## Response Fields
Request status indicator
Response message
Validated account details
Resolved account holder name
Account number that was validated
Bank code used for validation
Resolved bank name
# Verify BVN (Basic)
Source: https://docs.payvessel.com/api-reference/verification/basic-bvn-verification
POST /api/v1/merchant/bvn/basic
BVN verification API: match customer identity fields against Bank Verification Number records (basic endpoint).
# Verify NIN (Basic)
Source: https://docs.payvessel.com/api-reference/verification/basic-nin-verification
POST /api/v1/merchant/nin/basic
NIN verification API: match customer identity fields against National Identification Number records (basic endpoint).
# Blacklist Query
Source: https://docs.payvessel.com/api-reference/verification/blacklist-query
POST /api/v1/merchant/risk/blacklist/query
Query blacklist data using phone number, BVN, and NIN identifiers.
# Credit Score Query
Source: https://docs.payvessel.com/api-reference/verification/credit-score-query
POST /api/v1/merchant/risk/credit-score/query
Credit score API: query Nigerian customer credit score and risk signals for lending and underwriting.
# Verify Driver's License
Source: https://docs.payvessel.com/api-reference/verification/drivers-license-verification
POST /api/v1/merchant/documents/drivers-license
Verify a driver's license and retrieve the identity details attached to the license number.
# Verify BVN (Enhanced)
Source: https://docs.payvessel.com/api-reference/verification/enhanced-bvn-verification
POST /api/v1/merchant/bvn/enhanced
BVN verification API (enhanced): retrieve full BVN-linked identity profile for Nigerian KYC.
# Verify NIN (Enhanced)
Source: https://docs.payvessel.com/api-reference/verification/enhanced-nin-verification
POST /api/v1/merchant/nin/enhanced
NIN verification API (enhanced): retrieve full NIN-linked identity profile for Nigerian KYC.
# Verify International Passport
Source: https://docs.payvessel.com/api-reference/verification/international-passport-verification
POST /api/v1/merchant/documents/international-passport
Verify an international passport and retrieve the identity details attached to the passport number.
# Loan Feature Query
Source: https://docs.payvessel.com/api-reference/verification/loan-feature-query
POST /api/v1/merchant/risk/loan-feature/query
Query loan-feature information using access type, value, authorization, type, and encryption settings.
# BVN and Account
Source: https://docs.payvessel.com/api-reference/verification/merchant-bank-account
POST /api/v1/merchant/bank/verify-account
Verify a bank account against a BVN, bank code, and account number.
# Compare Faces
Source: https://docs.payvessel.com/api-reference/verification/merchant-face
POST /api/v1/merchant/face/compare
Compare two face images and return a similarity score.
# Verify Voter's Card
Source: https://docs.payvessel.com/api-reference/verification/voters-card-verification
POST /api/v1/merchant/documents/voters-card
Verify a voter's card and retrieve the identity details attached to the voter ID.
# Create Virtual Account
Source: https://docs.payvessel.com/api-reference/virtual-accounts/create-virtual-account
api-reference/openapi.json POST /pms/api/external/request/customerReservedAccount/
Virtual account API: create a STATIC or DYNAMIC Nigerian reserved bank account for customer collections.
Create a reserved virtual bank account (STATIC or DYNAMIC). Authentication is covered in [Authentication](/api-basics/authentication).
**Supported Banks:**
* **PalmPay** (`999991`): Requires BVN/NIN for both STATIC and DYNAMIC accounts
* **9Payment Service Bank** (`120001`): For STATIC accounts, KYC is optional (30k daily limit); for DYNAMIC accounts, no KYC required
**Note on 9PSB Static Accounts:** When you create a 9PSB STATIC account without BVN/NIN, the account will have a 30,000 NGN daily receive limit. If your customer needs to receive more, they must upgrade the account by providing their BVN/NIN using the [Update Virtual Account](/api-reference/virtual-accounts/update-virtual-account) endpoint.
**Example request body (STATIC with 9PSB - KYC Optional):**
For a 9PSB STATIC account without KYC (30k daily limit):
```json theme={null}
{
"email": "johndoe@gmail.com",
"name": "JOHN DOE",
"phoneNumber": "09012345672",
"bankcode": ["120001"],
"account_type": "STATIC",
"businessid": "061C074E2F91F944B93993B4"
}
```
For a 9PSB or Palmpay STATIC account with KYC:
```json theme={null}
{
"email": "johndoe@gmail.com",
"name": "JOHN DOE",
"phoneNumber": "09012345672",
"bankcode": ["999991", "120001"],
"account_type": "STATIC",
"businessid": "061C074E2F91F944B93993B4",
"bvn": "22345678901",
"nin": "12345678901"
}
```
**Example request body (DYNAMIC):**
Both 9PSB and Palmpay support DYNAMIC accounts without KYC:
```json theme={null}
{
"email": "customer@example.com",
"name": "JANE DOE",
"phoneNumber": "08012345678",
"bankcode": ["999991"],
"account_type": "DYNAMIC",
"businessid": "061C074E2F91F944B93993B4"
}
```
or
```json theme={null}
{
"email": "customer@example.com",
"name": "JANE DOE",
"phoneNumber": "08012345678",
"bankcode": ["120001"],
"account_type": "DYNAMIC",
"businessid": "061C074E2F91F944B93993B4"
}
```
**Example response for PalmPay (DYNAMIC):**
```json theme={null}
{
"status": true,
"service": "CREATE_VIRTUAL_ACCOUNT",
"business": "061C074E2F91F944B93993B4",
"banks": {
"bankCode": "999991",
"bankName": "PalmPay",
"accountNumber": "8880314352",
"accountName": "Demo User",
"account_type": "DYNAMIC",
"expire_date": "2026-05-15T11:49:36.117753+01:00",
"trackingReference": "XOINFKVRO90311273BD8DZZ8"
}
}
```
**Example response for 9Payment Service Bank (DYNAMIC):**
```json theme={null}
{
"status": true,
"service": "CREATE_VIRTUAL_ACCOUNT",
"business": "061C074E2F91F944B93993B4",
"banks": {
"bankCode": "120001",
"bankName": "9Payment Service Bank",
"accountNumber": "5030200545",
"accountName": "Demo User",
"account_type": "DYNAMIC",
"expire_date": "2026-05-15T11:49:36.117753+01:00",
"trackingReference": "YOINFKVRO90311273BD8DZZ9"
}
}
```
**cURL:**
```bash theme={null}
curl -X POST "https://api.payvessel.com/pms/api/external/request/customerReservedAccount/" \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{"email":"johndoe@gmail.com","name":"JOHN DOE","phoneNumber":"09012345672","bankcode":["120001"],"account_type":"STATIC","businessid":"YOUR_BUSINESS_ID"}'
```
For concepts and when to use STATIC vs DYNAMIC, see the [Customer Reserved Account](/accept-payment/customer-reserved-account) guide.
## Upgrading 9PSB Static Accounts
When a customer's 9PSB static account (created without BVN/NIN) reaches its 30k daily limit, they must provide their BVN and NIN to remove the restriction. Use the [Update Virtual Account](/api-reference/virtual-accounts/update-virtual-account) endpoint to upgrade the account.
# Get Virtual Account
Source: https://docs.payvessel.com/api-reference/virtual-accounts/get-virtual-account
api-reference/openapi.json GET /pms/api/external/request/virtual-account/{businessid}/{account}/
Fetch details of a specific virtual account using its business ID and account number.
# Update Virtual Account
Source: https://docs.payvessel.com/api-reference/virtual-accounts/update-virtual-account
api-reference/openapi.json PUT /pms/api/external/request/customerReservedAccount/{account_number}/
Upgrade a 9PSB static virtual account by providing BVN and NIN to remove the 30k daily limit.
Upgrade a 9PSB static virtual account by providing the customer's BVN and NIN. This removes the 30,000 NGN daily receive limit.
**When to use this endpoint:**
When a customer's 9PSB static account (created without initial KYC) is about to or has exceeded the 30k daily receive limit, they must upgrade by providing their BVN and NIN. You can implement this upgrade flow on your platform using this endpoint, or merchants can upgrade directly on the PayVessel dashboard.
**Request body:**
Submit the customer's BVN (Bank Verification Number) and NIN (National Identification Number) as strings.
**Example request body:**
```json theme={null}
{
"bvn": "22345678901",
"nin": "12345678901"
}
```
| Field | Type | Description |
| ----- | ------ | -------------------------------------------------- |
| `bvn` | string | Customer's 11-digit Bank Verification Number |
| `nin` | string | Customer's 11-digit National Identification Number |
**Example response:**
```json theme={null}
{
"status": true,
"service": "string",
"bvn": "string",
"business": "string",
"errors": []
}
```
**cURL:**
```bash theme={null}
curl -X PUT "https://api.payvessel.com/pms/api/external/request/customerReservedAccount/{account_number}/" \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET" \
-H "Content-Type: application/json" \
-d '{"bvn":"22345678901","nin":"12345678901"}'
```
**Parameters:**
* **account\_number** (path, required): The virtual account number to upgrade
* **api-key** (header, required): Your API key
* **api-secret** (header, required): Your business API secret
For concepts on static vs dynamic accounts, see the [Customer Reserved Account](/accept-payment/customer-reserved-account) guide.
# Create a Card
Source: https://docs.payvessel.com/api-reference/virtual-cards/create-customer-card
api-reference/openapi.json POST /pms/api/external/request/virtual-cards/
Virtual card API: create a USD Visa or Mastercard virtual card for a customer with KYC and optional prefund (asynchronous).
This resource allows you to create a card for a customer. This operation is asynchronous, meaning we notify you via a webhook event on the final status.
## Contactless cards
Use the optional boolean field `is_contactless` on the create payload:
| Value | Description |
| ------- | ------------------------------------------------- |
| `false` | Standard virtual card (default) |
| `true` | Contactless-enabled card for tap-to-pay use cases |
Contactless cards may have a different issuance fee.
# Freeze a Card
Source: https://docs.payvessel.com/api-reference/virtual-cards/freeze-card
api-reference/openapi.json POST /pms/api/external/request/virtual-cards/{card_id}/freeze/
Temporarily block card spend
# Fund a Card
Source: https://docs.payvessel.com/api-reference/virtual-cards/fund-card
api-reference/openapi.json POST /pms/api/external/request/virtual-cards/{card_id}/fund/
Load USD from your business wallet onto a virtual card
# Get a Card
Source: https://docs.payvessel.com/api-reference/virtual-cards/get-card
api-reference/openapi.json GET /pms/api/external/request/virtual-cards/{card_id}/
Retrieve one issued virtual card by ID
# Get all Cards
Source: https://docs.payvessel.com/api-reference/virtual-cards/list-cards
api-reference/openapi.json GET /pms/api/external/request/virtual-cards/
List customer virtual cards for your business
# Get Card Transactions
Source: https://docs.payvessel.com/api-reference/virtual-cards/list-transactions
api-reference/openapi.json GET /pms/api/external/request/virtual-cards/{card_id}/transactions/
Transaction history for a virtual card
# Simulate Card Transaction
Source: https://docs.payvessel.com/api-reference/virtual-cards/mock-transaction
api-reference/openapi.json POST /pms/api/external/request/virtual-cards/{card_id}/mock-transaction/
Sandbox-only simulated spend or credit on a virtual card
Sandbox only. Triggers a simulated card spend or credit; balance and transaction history update when PayVessel processes the event.
# Terminate Card
Source: https://docs.payvessel.com/api-reference/virtual-cards/terminate-card
api-reference/openapi.json POST /pms/api/external/request/virtual-cards/{card_id}/terminate/
Permanently close a virtual card
# Unfreeze a Card
Source: https://docs.payvessel.com/api-reference/virtual-cards/unfreeze-card
api-reference/openapi.json POST /pms/api/external/request/virtual-cards/{card_id}/unfreeze/
Restore spend on a frozen card
# Withdraw from a Card
Source: https://docs.payvessel.com/api-reference/virtual-cards/withdraw-card
api-reference/openapi.json POST /pms/api/external/request/virtual-cards/{card_id}/withdraw/
Move USD from a virtual card back to your business wallet
# Get Wallets
Source: https://docs.payvessel.com/api-reference/wallets/get-wallets
GET /pms/api/external/request/wallet/get-or-create/
List or retrieve managed wallets for your business
**Get an existing wallet or create one automatically** for the authenticated business. No request body is required.
## Endpoint
**GET** `/pms/api/external/request/wallet/get-or-create/`
## Response
Request status.
Description of the result.
Unique wallet ID.
Business identifier.
Wallet name.
Wallet account number.
Wallet account name.
Settlement bank name.
Settlement bank code.
Wallet currency.
Wallet status.
Wallet creation timestamp.
Available balance.
Ledger balance.
## Example Request
```bash theme={null}
curl -X GET "https://api.payvessel.com/pms/api/external/request/wallet/get-or-create/" \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET"
```
## Example Response
```json theme={null}
{
"status": true,
"message": "string",
"data": {
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"business_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"wallet_name": "string",
"account_number": "string",
"account_name": "string",
"bank_name": "string",
"bank_code": "string",
"currency": "string",
"status": "string",
"created_datetime": "2026-05-07T12:06:43.830Z",
"balance": {
"available_balance": "806856696425.66",
"ledger_balance": ""
}
}
}
```
# Wallet Balance
Source: https://docs.payvessel.com/api-reference/wallets/wallet-balance
GET /pms/api/external/request/wallet/balance/
Retrieve the current balance for a managed wallet
**Retrieve the current balance** for a managed wallet. Always verify the available balance before initiating transfers to avoid transaction failures.
## Endpoint
**GET** `/pms/api/external/request/wallet/balance/`
## Response
Request status - `"success"` or `"error"`.
Description of the result.
Funds available for immediate transfer.
Book balance including pending debits/credits.
The wallet currency (e.g., `NGN`).
## Example Request
```bash theme={null}
curl -X GET https://api.payvessel.com/pms/api/external/request/wallet/balance/ \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET"
```
## Example Response
```json theme={null}
{
"status": true,
"message": "string",
"data": {
"available_balance": "1.78",
"ledger_balance": "-9390113420548.59",
"currency": "NGN"
}
}
```
# Webhook Overview
Source: https://docs.payvessel.com/api-reference/webhook/overview
Understand how Payvessel webhooks deliver real-time payment notifications and how to integrate them safely.
Payvessel uses webhooks to deliver real-time notifications when events occur on your account, such as successful payments, wallet funding, or virtual account credits. This allows you to trigger business workflows instantly without polling the API.
Configure webhook endpoints in the Payvessel Dashboard and verify each notification before updating customer balances or order status.
## Delivery Workflow
A transaction, transfer, verification, or account update happens inside Payvessel.
Payvessel signs the JSON payload with your secret key and sends it to your registered endpoint.
Your server verifies the signature, checks the sender IP, prevents duplicates, and runs business logic.
Return an HTTP 200 response to stop retries. Payvessel retries failed deliveries with exponential backoff.
## Security Essentials
Compute an HMAC SHA-512 hash with your secret (`PVSECRET-`) and compare with the `HTTP_PAYVESSEL_HTTP_SIGNATURE` header.
Accept requests only from Payvessel IPs 3.255.23.38 and 162.246.254.36.
Make webhook handlers idempotent and store processed references.
## Webhook Payload Anatomy
Payvessel webhook payloads are JSON objects that include high-level order information and nested objects for the specific resource that changed. A typical transaction notification looks like this:
```json theme={null}
{
"event": "transaction.success",
"order": {
"amount": "50000",
"settlement_amount": "48500",
"fee": "1500",
"currency": "NGN",
"description": "Order #INV-2094",
"status": "completed"
},
"transaction": {
"reference": "TXN_2024_001",
"channel": "bank_transfer",
"status": "success",
"customer_email": "customer@example.com",
"paid_at": "2024-02-14T10:36:42Z"
},
"metadata": {
"customer_id": "CUST_2983",
"order_id": "INV-2094"
}
}
```
Use the `event` field to route requests to dedicated handlers. See the [Supported Events](/api-reference/webhook/supported-events) catalog for the complete list.
## Delivery Guarantees & Retries
* **At-least-once delivery:** Implement idempotency to safely handle duplicates.
* **Retry schedule:** Payvessel retries failed deliveries for up to 24 hours with exponential backoff.
* **Timeouts:** Respond within 10 seconds; otherwise, the attempt is considered failed and retried.
## Testing Webhooks Locally
```bash theme={null}
ngrok http 3000
```
Configure the generated HTTPS URL as your webhook endpoint in the Payvessel Dashboard.
```bash theme={null}
lt --port 3000 --subdomain payvessel-webhooks
```
Use the Dashboard webhook tester or send stored JSON payloads with curl:
```bash theme={null}
curl -X POST https://your-app.ngrok.io/payvessel-webhook \
-H "Content-Type: application/json" \
-H "HTTP_PAYVESSEL_HTTP_SIGNATURE: " \
-d @payload.json
```
## Operational Best Practices
* Log every incoming request body and headers for traceability.
* Send alerts when webhook deliveries fail repeatedly.
* Wrap handlers in background jobs if business logic takes longer than a few seconds.
* Version your webhook handlers together with the API contract.
# Verifying Webhooks
Source: https://docs.payvessel.com/api-reference/webhook/verifying-webhooks
Secure your Payvessel webhook endpoints by validating signatures, IP addresses, and duplicate deliveries.
Every Payvessel webhook is signed with your secret key and sent from a known IP address. Always verify both signals, and prevent duplicate processing, before performing irreversible business actions.
## Signature Verification
1. Read the raw request body exactly as received.
2. Compute an HMAC using SHA-512 with your secret (`PVSECRET-`) as the key.
3. Compare the result with the `HTTP_PAYVESSEL_HTTP_SIGNATURE` header using a constant-time comparison.
Parsing JSON before calculating the signature can change whitespace and break verification. Always hash the raw payload first.
## IP Allowlist
Accept webhook requests only from the following Payvessel IP addresses:
* `3.255.23.38`
* `162.246.254.36`
When hosting behind a proxy or load balancer, read the left-most entry from the `X-Forwarded-For` header; otherwise, fall back to the connection's remote address.
## Duplicate Prevention
* Store processed `transaction.reference` (or `trackingReference`) values in persistent storage.
* Wrap webhook logic in idempotent database transactions.
* Return `200 OK` only after your state changes succeed; otherwise Payvessel will retry.
## End-to-End Examples
The following implementations verify signature, validate IP addresses, guard against duplicates, and respond with appropriate status codes.
```javascript Node.js (Express) theme={null}
import crypto from 'crypto';
import express from 'express';
const app = express();
const SECRET = process.env.PAYVESSEL_SECRET || 'PVSECRET-';
const TRUSTED_IPS = ['3.255.23.38', '162.246.254.36'];
app.post('/webhooks/payvessel', express.raw({ type: 'application/json' }), async (req, res) => {
const signature = req.header('HTTP_PAYVESSEL_HTTP_SIGNATURE');
const payload = req.body; // Buffer
const hash = crypto.createHmac('sha512', SECRET).update(payload).digest('hex');
// Determine caller IP (supports proxies)
const ip =
req.headers['x-forwarded-for']?.toString().split(',')[0].trim() ??
req.socket.remoteAddress;
if (signature !== hash || !TRUSTED_IPS.includes(ip)) {
return res.status(400).json({ message: 'Invalid signature or IP' });
}
const data = JSON.parse(payload.toString());
const reference = data.transaction.reference;
if (await hasProcessed(reference)) {
return res.status(200).json({ message: 'Already processed' });
}
await markProcessed(reference);
await handleBusinessLogic(data);
return res.status(200).json({ message: 'success' });
});
```
```python Python (Django) theme={null}
import hashlib
import hmac
import json
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_POST
SECRET = b"PVSECRET-"
TRUSTED_IPS = {"3.255.23.38", "162.246.254.36"}
@csrf_exempt
@require_POST
def payvessel_webhook(request):
payload = request.body
signature = request.META.get("HTTP_PAYVESSEL_HTTP_SIGNATURE")
ip_address = request.META.get("HTTP_X_FORWARDED_FOR", request.META.get("REMOTE_ADDR", ""))
ip = ip_address.split(",")[0].strip() if ip_address else ""
digest = hmac.new(SECRET, payload, hashlib.sha512).hexdigest()
if signature != digest or ip not in TRUSTED_IPS:
return JsonResponse({"message": "Invalid signature or IP"}, status=400)
data = json.loads(payload)
reference = data["transaction"]["reference"]
if PaymentEvent.objects.filter(reference=reference).exists():
return JsonResponse({"message": "Already processed"})
PaymentEvent.objects.create(reference=reference, payload=data)
process_payment(data)
return JsonResponse({"message": "success"})
```
```php PHP (Laravel) theme={null}
getContent();
$signature = $request->header('HTTP_PAYVESSEL_HTTP_SIGNATURE');
$hash = hash_hmac('sha512', $payload, $secret);
$ip = $request->headers->get('x-forwarded-for', $request->ip());
$ip = Str::of($ip)->explode(',')->first();
if ($signature !== $hash || !in_array(trim($ip), $trustedIps, true)) {
return Response::json(['message' => 'Invalid signature or IP'], 400);
}
$data = json_decode($payload, true, 512, JSON_THROW_ON_ERROR);
$reference = $data['transaction']['reference'];
if (PaymentEvent::where('reference', $reference)->exists()) {
return ['message' => 'Already processed'];
}
PaymentEvent::create([
'reference' => $reference,
'payload' => $data,
]);
dispatch(new ProcessPayvesselWebhook($data));
return ['message' => 'success'];
});
```
```ruby Ruby on Rails theme={null}
class PayvesselWebhooksController < ApplicationController
skip_before_action :verify_authenticity_token
SECRET = ENV.fetch('PAYVESSEL_SECRET', 'PVSECRET-')
TRUSTED_IPS = ['3.255.23.38', '162.246.254.36']
def receive
raw_body = request.raw_post
signature = request.headers['HTTP_PAYVESSEL_HTTP_SIGNATURE']
hash = OpenSSL::HMAC.hexdigest('SHA512', SECRET, raw_body)
ip = request.headers['X-Forwarded-For']&.split(',')&.first&.strip || request.remote_ip
unless signature == hash && TRUSTED_IPS.include?(ip)
return render json: { message: 'Invalid signature or IP' }, status: :bad_request
end
payload = JSON.parse(raw_body)
reference = payload.dig('transaction', 'reference')
return render json: { message: 'Already processed' } if WebhookEvent.exists?(reference: reference)
WebhookEvent.create!(reference: reference, payload: payload)
HandlePayvesselWebhookJob.perform_later(payload)
render json: { message: 'success' }
end
end
```
```java Java (Spring Boot) theme={null}
@RestController
@RequestMapping("/webhooks")
public class PayvesselWebhookController {
private static final String SECRET = "PVSECRET-";
private static final Set TRUSTED_IPS = Set.of("3.255.23.38", "162.246.254.36");
@PostMapping("/payvessel")
public ResponseEntity
## Failure Handling
* Respond with `4xx` for security violations (invalid signature, unknown IP).
* Respond with `5xx` when internal processing fails so Payvessel retries automatically.
* Implement alerting for repeated failures and monitor retry logs.
# Create Order
Source: https://docs.payvessel.com/biller-reseller/create-order
Create a biller reseller order to purchase airtime, data, or betting top-ups
Create a biller reseller order. PayVessel debits your business wallet and submits the request for fulfillment.
## Usage
```bash theme={null}
curl -X POST https://api.payvessel.com/vaas/api/v1/biller-reseller/orders \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"reference": "bet-order-001",
"biller_id": "BET9JA_BILLER_ID",
"item_id": "BET9JA_ITEM_ID",
"recharge_account": "12345678",
"amount": 1000
}'
```
## Request body
| Field | Type | Required | Description |
| ------------------ | ------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `biller_id` | string | Yes | The biller to purchase from. Alphanumeric, hyphens, and underscores only (max 64 characters). |
| `item_id` | string | Yes | The specific item/package to purchase. Alphanumeric, hyphens, and underscores only (max 64 characters). |
| `recharge_account` | string | Yes | Customer's phone number or account ID (max 15 characters) |
| `amount` | integer | Yes | Amount to charge in naira (must be greater than 0) |
| `reference` | string | Yes | Your unique merchant order reference (max 32 characters) |
| `webhook_url` | string | No | Webhook URL for order status notifications (max 512 characters) |
The order amount is debited from your business wallet immediately. Make sure you have sufficient balance before creating an order.
## Response
The response returns an order object. Key fields:
| Field | Type | Description |
| ----------------------- | ---------------- | -------------------------------------------------------------------------- |
| `id` | string (uuid) | PayVessel order ID |
| `business_id` | string | Your business ID |
| `merchant_reference` | string | Your merchant reference |
| `order_reference` | string | PayVessel's internal order reference |
| `category` | string | `airtime`, `data`, or `betting` |
| `biller_id` | string | The biller used |
| `item_id` | string | The item purchased |
| `recharge_account` | string | The customer's account |
| `amount` | number | Amount charged in naira |
| `status` | string | Order status: `pending`, `processing`, `success`, `failed`, or `cancelled` |
| `error_message` | string or null | Error details if the order failed |
| `wallet_transaction_id` | string or null | Associated wallet transaction |
| `created_datetime` | datetime | When the order was created |
| `updated_datetime` | datetime | Last status update |
| `completed_datetime` | datetime or null | When the order reached a terminal state |
## Next step
Use [Verify Order](/biller-reseller/verify-order) or [Get Order](/biller-reseller/get-order) to check whether the order has been fulfilled.
Full request/response details and Try it
# Get Biller Items
Source: https://docs.payvessel.com/biller-reseller/get-biller-items
Retrieve available items and packages for a specific biller
Fetch the available items (packages or denominations) for a specific biller. These are the purchasable options your users can select from.
## Usage
Pass the `biller_id` as a path parameter.
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/biller-reseller/billers/{biller_id}/items \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Response fields
Each item includes:
| Field | Type | Description |
| ----------------- | --------------- | ------------------------------------------------------- |
| `biller_id` | string | The parent biller's ID |
| `item_id` | string | Unique item identifier (used when creating an order) |
| `item_name` | string | Display name of the item |
| `amount` | integer or null | Fixed price (null if variable) |
| `min_amount` | integer or null | Minimum amount for variable-price items |
| `max_amount` | integer or null | Maximum amount for variable-price items |
| `is_fixed_amount` | boolean or null | `true` if the item has a fixed price |
| `ext_info` | object or null | Extra details (validity period, data size, description) |
### ext\_info object
| Field | Type | Description |
| ------------------ | --------------- | ---------------------------------------- |
| `validity_date` | integer or null | Validity in days |
| `item_size` | string or null | Data size (e.g. "1GB", "5GB") |
| `item_description` | object or null | Additional description from the provider |
## Next step
Use the `item_id` when [creating an order](/biller-reseller/create-order).
Full request/response details and Try it
# Get Billers
Source: https://docs.payvessel.com/biller-reseller/get-billers
Retrieve available billers for a given category (airtime, data, or betting)
Fetch the list of available billers (providers) for a specific category. Use this to display provider options to your users before they select a package.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/biller-reseller/billers \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Response fields
Each biller in the response includes:
| Field | Type | Description |
| ------------- | --------------- | ----------------------------------------- |
| `biller_id` | string | Unique identifier for the biller |
| `biller_name` | string | Display name (e.g. "Bet9ja", "SportyBet") |
| `biller_icon` | string | URL to the biller's logo |
| `min_amount` | integer or null | Minimum order amount (if applicable) |
| `max_amount` | integer or null | Maximum order amount (if applicable) |
| `status` | integer or null | Biller availability status |
## Next step
After selecting a biller, call [Get Biller Items](/biller-reseller/get-biller-items) to retrieve the available packages.
Full request/response details and Try it
# Get Order
Source: https://docs.payvessel.com/biller-reseller/get-order
Retrieve a biller reseller order by ID to check its status
Retrieve a biller reseller order by its PayVessel order ID. Use this to poll for the final order status after creation.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/biller-reseller/orders/{order_id} \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Response fields
| Field | Type | Description |
| ----------------------- | ---------------- | ------------------------------------------------------------ |
| `id` | string (uuid) | PayVessel order ID |
| `business_id` | string | Your business ID |
| `merchant_reference` | string | Your merchant reference |
| `order_reference` | string | PayVessel's internal order reference |
| `category` | string | `airtime`, `data`, or `betting` |
| `biller_id` | string | The biller used |
| `item_id` | string | The item purchased |
| `recharge_account` | string | The customer's account |
| `amount` | number | Amount charged in naira |
| `status` | string | `pending`, `processing`, `success`, `failed`, or `cancelled` |
| `error_message` | string or null | Error details if the order failed |
| `wallet_transaction_id` | string or null | Associated wallet transaction |
| `created_datetime` | datetime | When the order was created |
| `updated_datetime` | datetime | Last status update |
| `completed_datetime` | datetime or null | When the order reached a terminal state |
Full request/response details and Try it
# Biller Reseller API
Source: https://docs.payvessel.com/biller-reseller/overview
Resell airtime, data bundles, and betting top-ups through a single integration with the PayVessel biller reseller API.
The PayVessel **biller reseller API** lets you resell **airtime**, **data bundles**, and **betting top-ups** to your end users. Orders are charged against your business wallet, and fulfillment is handled by PayVessel.
## Supported categories
| Category | Description |
| --------- | ------------------------------------------------ |
| `airtime` | Prepaid mobile airtime credit |
| `data` | Mobile data bundles |
| `betting` | Betting account funding (e.g. Bet9ja, SportyBet) |
## Integration flow
1. **List billers** to show available providers (e.g. Bet9ja, SportyBet).
2. **List biller items** to get the specific packages or denominations for that biller.
3. **Validate the recharge account** to confirm the customer's account exists before placing an order.
4. **Create an order** to purchase the item; PayVessel debits your wallet and fulfils the request.
5. **Receive a webhook** when the order status changes (e.g. success, failed).
6. **Verify order** or **get order** to check the status or retrieve order details.
```mermaid theme={null}
sequenceDiagram
participant You
participant PayVessel
You->>PayVessel: GET /billers
PayVessel-->>You: List of billers
You->>PayVessel: GET /billers/{biller_id}/items
PayVessel-->>You: Available items/packages
You->>PayVessel: POST /validate-account
PayVessel-->>You: Account validated
You->>PayVessel: POST /orders
PayVessel-->>You: Order created (status: processing)
PayVessel--)You: Webhook (order status update)
```
## Order statuses
| Status | Description |
| ------------ | --------------------------------------- |
| `pending` | Order received, not yet being processed |
| `processing` | Order is being fulfilled |
| `success` | Fulfilled successfully |
| `failed` | Order could not be fulfilled |
| `cancelled` | Order was cancelled |
## Base path
All biller reseller endpoints are under:
```
/vaas/api/v1/biller-reseller
```
## Sandbox testing
In sandbox mode, only the following recharge accounts are accepted during [account validation](/biller-reseller/validate-account):
| Recharge Account | Account Name |
| ---------------- | --------------- |
| `1234567890` | John Doe |
| `0987654321` | Jane Smith |
| `1111111111` | Test User One |
| `2222222222` | Test User Two |
| `3333333333` | Test User Three |
Use any of these accounts when testing the validate-account and create-order endpoints.
Your sandbox wallet has a fixed balance of **NGN 10,000**. Orders are validated against this amount but debits are not tracked, so the balance never decreases.
## Authentication
All requests require `api-key` and `api-secret` headers. See [Authentication](/api-basics/authentication) for details.
# Validate Recharge Account
Source: https://docs.payvessel.com/biller-reseller/validate-account
Validate a customer's recharge account before placing a biller reseller order
Validate a customer's recharge account before placing an order. This confirms that the account exists with the provider and prevents failed orders.
## Usage
```bash theme={null}
curl -X POST https://api.payvessel.com/vaas/api/v1/biller-reseller/validate-account \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"recharge_account": "12345678",
"biller_id": "BET9JA_BILLER_ID"
}'
```
## Request body
| Field | Type | Required | Description |
| ------------------ | ------ | -------- | ------------------------------------------------------------------------------------------------ |
| `recharge_account` | string | Yes | The customer's account (phone number or betting ID). Max 15 characters. |
| `biller_id` | string | Yes | The biller to validate against. Alphanumeric, hyphens, and underscores only (max 64 characters). |
| `item_id` | string | No | Optional item ID for context. Alphanumeric, hyphens, and underscores only (max 64 characters). |
## Response
The response `data` object contains:
| Field | Type | Description |
| -------- | -------------- | -------------------------------------------------- |
| `biller` | string or null | The resolved biller/account name from the provider |
## Sandbox testing
In sandbox mode, only the following recharge accounts are valid:
| Recharge Account | Account Name |
| ---------------- | --------------- |
| `1234567890` | John Doe |
| `0987654321` | Jane Smith |
| `1111111111` | Test User One |
| `2222222222` | Test User Two |
| `3333333333` | Test User Three |
Any other account number will return a validation error.
Full request/response details and Try it
# Verify Order
Source: https://docs.payvessel.com/biller-reseller/verify-order
Verify the status of a biller reseller order by its merchant reference
Verify the status of a biller reseller order using your merchant reference. If the order is not yet final, PayVessel checks for the latest status before responding.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/biller-reseller/orders/verify/{reference} \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Path parameters
| Parameter | Type | Required | Description |
| ----------- | ------ | -------- | ------------------------------------ |
| `reference` | string | Yes | Your unique merchant order reference |
## Response fields
| Field | Type | Description |
| ----------------------- | ---------------- | ------------------------------------------------------------ |
| `id` | string (uuid) | PayVessel order ID |
| `business_id` | string | Your business ID |
| `merchant_reference` | string | Your merchant reference |
| `order_reference` | string | PayVessel's internal order reference |
| `category` | string | `airtime`, `data`, or `betting` |
| `biller_id` | string | The biller used |
| `item_id` | string | The item purchased |
| `recharge_account` | string | The customer's account |
| `amount` | number | Amount charged in naira |
| `status` | string | `pending`, `processing`, `success`, `failed`, or `cancelled` |
| `error_message` | string or null | Error details if the order failed |
| `wallet_transaction_id` | string or null | Associated wallet transaction |
| `created_datetime` | datetime | When the order was created |
| `updated_datetime` | datetime | Last status update |
| `completed_datetime` | datetime or null | When the order reached a terminal state |
Full request/response details and Try it
# Create eSIM Order
Source: https://docs.payvessel.com/esim/create-order
Purchase an eSIM data package and provision a profile
Create an eSIM order. PayVessel debits your business wallet, provisions the eSIM with the selected package, and returns the order details.
## Usage
```bash theme={null}
curl -X POST https://api.payvessel.com/vaas/api/v1/esim/orders \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"reference": "esim-order-001",
"package_code": "US_5GB_30D",
"quantity": 1
}'
```
## Request body
| Field | Type | Required | Default | Description |
| -------------- | ------- | -------- | ------- | ------------------------------------------------------------------- |
| `reference` | string | Yes | | Your unique merchant order reference (max 64 characters) |
| `package_code` | string | Yes | | The package to purchase (from [List Packages](/esim/list-packages)) |
| `quantity` | integer | No | `1` | Number of eSIMs to provision (must be greater than 0) |
The order amount is debited from your business wallet immediately. Make sure you have sufficient balance before creating an order.
## Response
The response returns an order object. Key fields:
| Field | Type | Description |
| -------------- | ------------- | ------------------------------------------------- |
| `id` | string (uuid) | PayVessel order ID |
| `reference` | string | Your merchant reference |
| `package_code` | string | The package purchased |
| `package_name` | string | Human-readable package name |
| `location` | string | Target region |
| `quantity` | integer | Number of eSIMs |
| `amount_usd` | number | Amount in USD |
| `amount_naira` | number | Amount in NGN |
| `status` | string | `pending`, `processing`, `completed`, or `failed` |
| `profiles` | array | eSIM profile details (populated when `completed`) |
## Next step
Poll [Get Order](/esim/get-order) until the status is `completed` to retrieve the eSIM profile with QR code and activation details.
Full request/response details and Try it
# Get eSIM Order
Source: https://docs.payvessel.com/esim/get-order
Retrieve an eSIM order by ID, including profile and activation details
Retrieve an eSIM order by its PayVessel order ID. When the order is `completed`, the response includes full eSIM profile details your user needs to activate their data plan.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/esim/orders/{order_id} \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Response fields
| Field | Type | Description |
| ------------------------- | ---------------- | ------------------------------------------------- |
| `id` | string (uuid) | PayVessel order ID |
| `reference` | string | Your merchant reference |
| `provider_order_no` | string or null | Provider's order number |
| `provider_transaction_id` | string or null | Provider's transaction ID |
| `package_code` | string | The package purchased |
| `package_slug` | string or null | Package slug |
| `package_name` | string | Human-readable package name |
| `location` | string | Target region |
| `currency_code` | string | Price currency |
| `quantity` | integer | Number of eSIMs |
| `amount_usd` | number | Amount in USD |
| `amount_naira` | number | Amount in NGN |
| `status` | string | `pending`, `processing`, `completed`, or `failed` |
| `error_message` | string or null | Error details if the order failed |
| `profiles` | array | eSIM profiles (see below) |
| `created_datetime` | datetime | When the order was created |
| `updated_datetime` | datetime | Last status update |
| `completed_datetime` | datetime or null | When provisioning completed |
### Profile object
Each profile in the `profiles` array contains the eSIM activation details:
| Field | Type | Description |
| ---------------- | --------------- | ---------------------------------------- |
| `iccid` | string or null | SIM card identifier |
| `qr_code_url` | string or null | QR code image URL for eSIM installation |
| `short_url` | string or null | Short activation URL |
| `ac` | string or null | Activation code (SM-DP+ address) |
| `msisdn` | string or null | Assigned phone number (if applicable) |
| `imsi` | string or null | International mobile subscriber identity |
| `esim_status` | string or null | Current eSIM status |
| `activate_time` | string or null | When the eSIM was activated |
| `expired_time` | string or null | When the eSIM expires |
| `total_volume` | integer or null | Total data allowance (bytes) |
| `total_duration` | integer or null | Total validity period |
| `duration_unit` | string or null | Unit for duration |
| `order_usage` | integer or null | Data used so far (bytes) |
| `pin` | string or null | SIM PIN |
| `puk` | string or null | SIM PUK |
| `apn` | string or null | APN setting |
| `packages` | array | Allocated packages on this profile |
### Allocated package object
| Field | Type | Description |
| --------------- | --------------- | ------------------------------ |
| `package_code` | string | Package identifier |
| `package_name` | string or null | Package name |
| `slug` | string or null | Package slug |
| `duration` | integer or null | Validity period |
| `volume` | integer or null | Data allowance (bytes) |
| `location_code` | string or null | Target location |
| `create_time` | string or null | When the package was allocated |
Full request/response details and Try it
# List Packages
Source: https://docs.payvessel.com/esim/list-packages
Browse available eSIM data packages with optional filters
List available eSIM data packages. Use query filters to narrow results by location, package type, or specific codes.
## Usage
```bash theme={null}
curl "https://api.payvessel.com/vaas/api/v1/esim/packages?location_code=US&package_type=BASE" \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Query parameters
| Parameter | Type | Required | Default | Description |
| --------------- | ------ | -------- | ------- | ------------------------------------------------------- |
| `location_code` | string | No | | Filter by region/country code (e.g. `US`, `GB`) |
| `package_type` | string | No | `BASE` | Package type filter |
| `package_code` | string | No | | Filter by exact package code |
| `slug` | string | No | | Filter by package slug |
| `iccid` | string | No | | Filter by ICCID (for top-up packages on existing eSIMs) |
## Response fields
Each package includes:
| Field | Type | Description |
| ------------------- | -------------- | ------------------------------------------------------- |
| `package_code` | string | Unique package identifier (used when creating an order) |
| `slug` | string or null | URL-friendly package identifier |
| `name` | string | Display name |
| `currency_code` | string | Price currency |
| `price_usd` | number | Wholesale price in USD |
| `retail_price_usd` | number or null | Suggested retail price in USD |
| `volume_bytes` | integer | Data allowance in bytes |
| `duration` | integer | Validity period |
| `duration_unit` | string | Unit for duration (e.g. "DAY") |
| `location` | string | Target location/region |
| `description` | string or null | Package description |
| `speed` | string or null | Network speed (e.g. "4G/LTE") |
| `location_networks` | array | Supported networks per location |
### location\_networks object
| Field | Type | Description |
| --------------- | -------------- | --------------------------- |
| `location_name` | string | Country or area name |
| `location_logo` | string or null | Logo URL |
| `operators` | array | Network operators available |
Each operator has:
| Field | Type | Description |
| --------------- | -------------- | ------------------------ |
| `operator_name` | string | Carrier name |
| `network_type` | string or null | Network type (e.g. "4G") |
## Next step
Use the `package_code` when [creating an order](/esim/create-order).
Full request/response details and Try it
# List Regions
Source: https://docs.payvessel.com/esim/list-regions
List all supported eSIM regions and countries
Retrieve all supported regions from the eSIM provider. Regions can be countries or broader areas (e.g. "Europe", "Asia") and may contain nested sub-locations.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/esim/regions \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Response fields
Each region includes:
| Field | Type | Description |
| --------------- | --------------- | ---------------------------------------------- |
| `code` | string | Region/country code (e.g. `US`, `EU`) |
| `name` | string | Display name (e.g. "United States", "Europe") |
| `region_type` | integer or null | Type identifier for the region |
| `sub_locations` | array | Nested sub-regions (same structure, recursive) |
Use the `code` value as the `location_code` filter when [listing packages](/esim/list-packages).
Full request/response details and Try it
# eSIM API
Source: https://docs.payvessel.com/esim/overview
Issue and manage eSIM data packages for global travel through the PayVessel eSIM API.
The PayVessel **eSIM API** lets you sell **eSIM data packages** to your users for international travel. Browse available regions and packages, create orders, and deliver eSIM profiles with QR codes for instant activation.
## Integration flow
1. **List regions** to discover supported countries and areas.
2. **List packages** with optional filters (location, type) to find data plans.
3. **Create an order** for a package; PayVessel debits your wallet and provisions the eSIM.
4. **Get order** to retrieve the eSIM profile details (QR code, ICCID, activation instructions).
```mermaid theme={null}
sequenceDiagram
participant You
participant PayVessel
participant Provider
You->>PayVessel: GET /regions
PayVessel-->>You: Supported regions
You->>PayVessel: GET /packages?location_code=US
PayVessel-->>You: Available packages
You->>PayVessel: POST /orders
PayVessel->>Provider: Provision eSIM
Provider-->>PayVessel: eSIM profile
PayVessel-->>You: Order created (status: processing)
You->>PayVessel: GET /orders/{order_id}
PayVessel-->>You: eSIM profile with QR code
```
## Order statuses
| Status | Description |
| ------------ | --------------------------------------------- |
| `pending` | Order received, not yet submitted to provider |
| `processing` | Submitted to provider, awaiting provisioning |
| `completed` | eSIM provisioned; profile details available |
| `failed` | Provider could not provision the eSIM |
## Base path
All eSIM endpoints are under:
```
/vaas/api/v1/esim
```
## Authentication
All requests require `api-key` and `api-secret` headers. See [Authentication](/api-basics/authentication) for details.
# List Airports
Source: https://docs.payvessel.com/flight/airports
Retrieve the supported airport catalogue for flight search
Retrieve the airport catalogue used by the flight API. Each airport object includes the airport code, display name, city, and country.
Airport data is cached by PayVessel and refreshed periodically. The current refresh window is **7 days**.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/flight/airports \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_API_SECRET"
```
## Response fields
| Field | Type | Description |
| --------------------- | ------- | -------------------------------- |
| `status` | boolean | `true` when the request succeeds |
| `message` | string | Human-readable response message |
| `data` | array | Airport objects |
| `data[].airport_code` | string | IATA airport code |
| `data[].airport_name` | string | Airport display name |
| `data[].city_country` | string | Combined city and country label |
| `data[].city` | string | City |
| `data[].country` | string | Country |
## Example response
```json theme={null}
{
"status": true,
"message": "Airports retrieved successfully",
"data": [
{
"airport_code": "LOS",
"airport_name": "Murtala Muhammed International Airport (LOS)",
"city_country": "Lagos, Nigeria",
"city": "Lagos",
"country": "Nigeria"
},
{
"airport_code": "JFK",
"airport_name": "John F. Kennedy International Airport (JFK)",
"city_country": "New York, United States",
"city": "New York",
"country": "United States"
}
]
}
```
Full request and response schema
# Create Order
Source: https://docs.payvessel.com/flight/create-order
Charge your wallet and create a flight booking order
Create a flight order from a valid `quote_id`. PayVessel charges your business wallet using the quoted total amount and then submits the booking for processing.
The `reference` you send is your merchant reference. It must be unique **within your business**. PayVessel also generates its own internal `order_reference`, which is returned in the response.
## Passenger type options
| Value | Meaning |
| -------- | ---------------- |
| `Adult` | Adult passenger |
| `Child` | Child passenger |
| `Infant` | Infant passenger |
## Usage
```bash theme={null}
curl -X POST https://api.payvessel.com/vaas/api/v1/flight/orders \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"quote_id": "f7724ed8-8899-4f19-8757-fcbce8a8d852",
"reference": "flight-order-001",
"passenger_details": [
{
"passenger_type": "Adult",
"first_name": "Amina",
"middle_name": "T.",
"last_name": "Ibrahim",
"date_of_birth": "1988-03-22",
"phone_number": "+2348031234567",
"address": "12 Admiralty Way, Lekki",
"passport_number": "A12345678",
"passport_expiry_date": "2030-03-22",
"passport_issuing_authority": "Nigeria Immigration Service",
"passport_issue_country_code": "NG",
"email": "amina.ibrahim@example.com",
"gender": "Female",
"title": "Mrs",
"city": "Lagos",
"country": "Nigeria",
"country_code": "NG",
"postal_code": "101001"
}
],
"webhook_url": "https://merchant.example.com/webhooks/flight"
}'
```
## Request body
| Field | Type | Required | Description |
| ------------------- | ------------- | -------- | --------------------------------------------------------- |
| `quote_id` | string (uuid) | Yes | Quote ID returned by [Create Quote](/flight/create-quote) |
| `reference` | string | Yes | Your merchant reference. Maximum length is `64` |
| `passenger_details` | array | Yes | Passenger payload for the booking |
| `webhook_url` | string | No | Merchant webhook URL for order status notifications |
### Passenger object
| Field | Type | Required | Description |
| ----------------------------- | ------ | -------- | --------------------------------------------------------- |
| `passenger_type` | string | Yes | `Adult`, `Child`, or `Infant` |
| `first_name` | string | Yes | Passenger first name |
| `middle_name` | string | No | Passenger middle name |
| `last_name` | string | Yes | Passenger last name |
| `date_of_birth` | date | No | Date in `YYYY-MM-DD` format. Often required for ticketing |
| `phone_number` | string | No | Passenger contact number |
| `address` | string | No | Passenger address |
| `passport_number` | string | No | Recommended for international bookings |
| `passport_expiry_date` | date | No | Recommended for international bookings |
| `passport_issuing_authority` | string | No | Passport issuing authority |
| `passport_issue_country_code` | string | No | ISO country code for passport issue country |
| `email` | string | No | Passenger email |
| `gender` | string | No | Passenger gender |
| `title` | string | No | Passenger title |
| `city` | string | No | Passenger city |
| `country` | string | No | Passenger country |
| `country_code` | string | No | ISO country code |
| `postal_code` | string | No | Postal code |
Wallet charging happens during order creation. Make sure your business wallet has sufficient balance before calling this endpoint.
## Example response
```json theme={null}
{
"status": true,
"message": "Flight order is being processed",
"data": {
"id": "df564c2d-4e6a-470a-b4e6-c46c298a01de",
"business_id": "9ca6db0d-45bf-459b-b95f-c06e7d5d0c12",
"merchant_reference": "flight-order-001",
"order_reference": "A1B2C3D4E5F6G7H8",
"quote_id": "f7724ed8-8899-4f19-8757-fcbce8a8d852",
"currency_code": "NGN",
"pricing": {
"currency_code": "NGN",
"base_price": 487500.0,
"service_charge": 24375.0,
"total_amount": 511875.0,
"wallet_reward_on_success": 2437.5,
"price_status": "final"
},
"status": "processing",
"error_message": null,
"passengers": [
{
"passenger_type": "Adult",
"first_name": "Amina",
"middle_name": "T.",
"last_name": "Ibrahim",
"title": "Mrs",
"gender": "Female"
}
],
"created_datetime": "2026-08-01T14:05:00Z",
"updated_datetime": "2026-08-01T14:05:00Z",
"completed_datetime": null
}
}
```
## Next steps
Use [List Orders](/flight/list-orders) or [Get Order](/flight/get-order) to track the latest status of the booking.
Full request and response schema
# Create Quote
Source: https://docs.payvessel.com/flight/create-quote
Validate a selected flight option and receive a bookable quote
Create a quote from a `selection_token` returned by [Search Flights](/flight/search-flights). A quote confirms the selected option and returns a `quote_id` that you will use when creating an order.
Quotes are time-bound. The current quote validity window is **30 minutes**.
## Usage
```bash theme={null}
curl -X POST https://api.payvessel.com/vaas/api/v1/flight/quotes \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"selection_token": "H4sIAJjPj2gC_5WQwU7DMBBE_2Vyk7t8bS1jQk2lM9m1K1JICJt2mN2o0m7b5HkQ3n3M2fWm6v8Q3m6aB7m6U1B8PpK9s7s1wQf2W4B1zQm5V6g3Y7..."
}'
```
## Request body
| Field | Type | Required | Description |
| ----------------- | ------ | -------- | -------------------------------------------- |
| `selection_token` | string | Yes | Opaque token returned by the search response |
## Response
Quote responses return **final pricing**, so `pricing.price_status` is `final`.
| Field | Type | Description |
| --------------- | ------------- | --------------------------------- |
| `id` | string (uuid) | Quote ID to use in order creation |
| `status` | string | Quote lifecycle status |
| `currency_code` | string | Display currency |
| `pricing` | object | Final pricing breakdown |
| `expires_at` | datetime | Quote expiry timestamp |
| `journeys` | array | Confirmed itinerary snapshot |
## Example response
```json theme={null}
{
"status": true,
"message": "Flight quote created successfully",
"data": {
"id": "f7724ed8-8899-4f19-8757-fcbce8a8d852",
"business_id": "9ca6db0d-45bf-459b-b95f-c06e7d5d0c12",
"status": "active",
"currency_code": "NGN",
"pricing": {
"currency_code": "NGN",
"base_price": 487500.0,
"service_charge": 24375.0,
"total_amount": 511875.0,
"wallet_reward_on_success": 2437.5,
"price_status": "final"
},
"airline_code": "EK",
"airline_name": "Emirates",
"airline_logo_url": "https://cdn.example.com/airlines/ek.png",
"marketing_carrier": "EK",
"journeys": [],
"fare_rules": [
"Changes may attract airline fees."
],
"penalty_rules": [
"Ticket is non-refundable after departure."
],
"is_refundable": false,
"expires_at": "2026-08-01T14:30:00Z",
"created_datetime": "2026-08-01T14:00:00Z",
"updated_datetime": "2026-08-01T14:00:00Z"
}
}
```
Full request and response schema
# Get Order
Source: https://docs.payvessel.com/flight/get-order
Retrieve a single flight order by ID
Retrieve a single flight order by its PayVessel `order_id`.
Store the `id` returned when the order is created if you need to fetch that order later.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/flight/orders/df564c2d-4e6a-470a-b4e6-c46c298a01de \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_API_SECRET"
```
## Path parameters
| Parameter | Type | Description |
| ---------- | ------------- | ------------------ |
| `order_id` | string (uuid) | PayVessel order ID |
## Example response
```json theme={null}
{
"status": true,
"message": "Flight order retrieved successfully",
"data": {
"id": "df564c2d-4e6a-470a-b4e6-c46c298a01de",
"business_id": "9ca6db0d-45bf-459b-b95f-c06e7d5d0c12",
"merchant_reference": "flight-order-001",
"order_reference": "A1B2C3D4E5F6G7H8",
"quote_id": "f7724ed8-8899-4f19-8757-fcbce8a8d852",
"currency_code": "NGN",
"pricing": {
"currency_code": "NGN",
"base_price": 487500.0,
"service_charge": 24375.0,
"total_amount": 511875.0,
"wallet_reward_on_success": 2437.5,
"price_status": "final"
},
"status": "completed",
"error_message": null,
"passengers": [
{
"passenger_type": "Adult",
"first_name": "Amina",
"middle_name": "T.",
"last_name": "Ibrahim",
"title": "Mrs",
"gender": "Female"
}
],
"created_datetime": "2026-08-01T14:05:00Z",
"updated_datetime": "2026-08-01T14:12:00Z",
"completed_datetime": "2026-08-01T14:12:00Z"
}
}
```
Full request and response schema
# List Orders
Source: https://docs.payvessel.com/flight/list-orders
Retrieve all flight orders for the authenticated business
Retrieve all flight orders belonging to the authenticated business. Orders are returned from **newest to oldest**.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/flight/orders \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_API_SECRET"
```
## Response
The `data` field contains an array of order objects. Each order includes the merchant reference, PayVessel order reference, pricing snapshot, status, and passenger summary.
## Example response
```json theme={null}
{
"status": true,
"message": "Flight orders retrieved successfully",
"data": [
{
"id": "df564c2d-4e6a-470a-b4e6-c46c298a01de",
"business_id": "9ca6db0d-45bf-459b-b95f-c06e7d5d0c12",
"merchant_reference": "flight-order-001",
"order_reference": "A1B2C3D4E5F6G7H8",
"quote_id": "f7724ed8-8899-4f19-8757-fcbce8a8d852",
"currency_code": "NGN",
"pricing": {
"currency_code": "NGN",
"base_price": 487500.0,
"service_charge": 24375.0,
"total_amount": 511875.0,
"wallet_reward_on_success": 2437.5,
"price_status": "final"
},
"status": "completed",
"error_message": null,
"passengers": [
{
"passenger_type": "Adult",
"first_name": "Amina",
"middle_name": "T.",
"last_name": "Ibrahim",
"title": "Mrs",
"gender": "Female"
}
],
"created_datetime": "2026-08-01T14:05:00Z",
"updated_datetime": "2026-08-01T14:12:00Z",
"completed_datetime": "2026-08-01T14:12:00Z"
}
]
}
```
Full request and response schema
# Flight API
Source: https://docs.payvessel.com/flight/overview
Search airports, retrieve flight options, create quotes, and place flight orders through the PayVessel flight API.
The PayVessel **flight API** lets you search airports, retrieve available flight options, create a bookable quote, and place flight orders through a single VaaS integration.
Search responses return **preview pricing**. Before creating an order, create a quote to confirm the final payable amount and receive a time-bound `quote_id`.
## Integration flow
1. **List airports** to retrieve supported airport codes.
2. **Search flights** to retrieve available options and an opaque `selection_token`.
3. **Create quote** to validate the selected option and receive a `quote_id`.
4. **Create order** to charge your wallet and submit the booking.
5. **List orders** or **get order** to track the latest booking status.
```mermaid theme={null}
sequenceDiagram
participant You
participant PayVessel
You->>PayVessel: GET /flight/airports
PayVessel-->>You: Airport catalogue
You->>PayVessel: POST /flight/search
PayVessel-->>You: Flight options + selection_token
You->>PayVessel: POST /flight/quotes
PayVessel-->>You: Bookable quote + quote_id
You->>PayVessel: POST /flight/orders
PayVessel-->>You: Flight order created
You->>PayVessel: GET /flight/orders or /flight/orders/{order_id}
PayVessel-->>You: Latest order status
```
## Base path
All flight endpoints are under:
```text theme={null}
/vaas/api/v1/flight
```
## Authentication
All requests require `api-key` and `api-secret` headers. See [Authentication](/api-basics/authentication) for details.
## Search types
| `search_type` | Description |
| ------------------ | -------------------------------------------- |
| `oneway` | One itinerary only |
| `return` | Exactly two itineraries, outbound and return |
| `multidestination` | Two or more itineraries |
## Cabin classes
| `cabin_class` | Description |
| ----------------- | ---------------- |
| `economy` | Standard economy |
| `premium_economy` | Premium economy |
| `business` | Business class |
| `first` | First class |
## Quote statuses
| Status | Description |
| ----------- | ------------------------------------------------- |
| `active` | Quote is valid and can be used to create an order |
| `consumed` | Quote has already been used to create an order |
| `expired` | Quote validity window has elapsed |
| `cancelled` | Quote is no longer usable |
## Order statuses
| Status | Description |
| ------------ | ------------------------------------------------------------ |
| `pending` | Order has been created and is awaiting downstream processing |
| `processing` | Booking is in progress |
| `completed` | Booking completed successfully |
| `failed` | Booking could not be completed |
| `cancelled` | Order was cancelled |
## Pricing fields
| Field | Meaning |
| -------------------------- | --------------------------------------------------------------- |
| `base_price` | Merchant-facing fare before service charge |
| `service_charge` | Additional service fee charged on the booking |
| `total_amount` | Total amount payable by the merchant |
| `wallet_reward_on_success` | Amount scheduled to be credited back after a successful booking |
| `price_status` | `preview` during search, `final` after quote creation |
Retrieve supported airport codes
Retrieve flight options and preview pricing
Confirm a selected option and receive a quote ID
Charge the wallet and place a booking
Retrieve all orders for your business
Retrieve one order by ID
# Search Flights
Source: https://docs.payvessel.com/flight/search-flights
Retrieve available flight options and preview pricing
Search for available flights by itinerary and passenger counts. The response returns an array of options, each with an opaque `selection_token` that you must pass unchanged to [Create Quote](/flight/create-quote).
## Request rules
| `search_type` | Itinerary rule |
| ------------------ | ---------------------- |
| `oneway` | Exactly 1 itinerary |
| `return` | Exactly 2 itineraries |
| `multidestination` | At least 2 itineraries |
## Cabin class options
| Value | Meaning |
| ----------------- | --------------- |
| `economy` | Economy |
| `premium_economy` | Premium economy |
| `business` | Business |
| `first` | First |
## Usage
```bash theme={null}
curl -X POST https://api.payvessel.com/vaas/api/v1/flight/search \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{
"search_type": "oneway",
"cabin_class": "economy",
"adults": 1,
"children": 0,
"infants": 0,
"itineraries": [
{
"departure_airport_code": "JFK",
"arrival_airport_code": "DXB",
"departure_date": "2026-08-20"
}
]
}'
```
## Request body
| Field | Type | Required | Description |
| ------------- | ------- | -------- | ------------------------------------------------------------------------------ |
| `search_type` | string | No | `oneway` by default. Also supports `return` and `multidestination` |
| `cabin_class` | string | No | `economy` by default. Also supports `premium_economy`, `business`, and `first` |
| `adults` | integer | Yes | Number of adult passengers. Minimum `1` |
| `children` | integer | No | Number of child passengers. Default `0` |
| `infants` | integer | No | Number of infant passengers. Default `0` |
| `itineraries` | array | Yes | Travel legs for the search |
### Itinerary object
| Field | Type | Required | Description |
| ------------------------ | ------ | -------- | --------------------------- |
| `departure_airport_code` | string | Yes | 3-letter IATA code |
| `arrival_airport_code` | string | Yes | 3-letter IATA code |
| `departure_date` | date | Yes | Date in `YYYY-MM-DD` format |
## Response
Search returns **preview pricing**, so `pricing.price_status` is `preview`.
| Field | Type | Description |
| ---------------------------------- | ------ | ------------------------------------------ |
| `selection_token` | string | Opaque token for the selected option |
| `pricing.currency_code` | string | Display currency |
| `pricing.base_price` | number | Merchant-facing base fare |
| `pricing.service_charge` | number | Service fee |
| `pricing.total_amount` | number | Total payable amount |
| `pricing.wallet_reward_on_success` | number | Reward amount to be credited after success |
| `pricing.price_status` | string | `preview` |
| `journeys` | array | High-level flight journeys and segments |
## Example response
```json theme={null}
{
"status": true,
"message": "Flights retrieved successfully",
"data": [
{
"selection_token": "H4sIAJjPj2gC_5WQwU7DMBBE_2Vyk7t8bS1jQk2lM9m1K1JICJt2mN2o0m7b5HkQ3n3M2fWm6v8Q3m6aB7m6U1B8PpK9s7s1wQf2W4B1zQm5V6g3Y7...",
"pricing": {
"currency_code": "NGN",
"base_price": 487500.0,
"service_charge": 24375.0,
"total_amount": 511875.0,
"wallet_reward_on_success": 2437.5,
"price_status": "preview"
},
"airline_code": "EK",
"airline_name": "Emirates",
"airline_logo_url": "https://cdn.example.com/airlines/ek.png",
"marketing_carrier": "EK",
"journeys": [
{
"name": "Journey 1",
"airline_code": "EK",
"airline_name": "Emirates",
"departure_airport_code": "JFK",
"departure_airport_name": "John F. Kennedy International Airport",
"departure_datetime": "2026-08-20T11:00:00Z",
"arrival_airport_code": "DXB",
"arrival_airport_name": "Dubai International Airport",
"arrival_datetime": "2026-08-21T07:35:00Z",
"stop_count": 0,
"stop_time": null,
"trip_duration": "12h 35m",
"airline_logo_url": "https://cdn.example.com/airlines/ek.png",
"segments": [
{
"sequence": 1,
"airline_code": "EK",
"airline_name": "Emirates",
"flight_number": "EK204",
"departure_airport_code": "JFK",
"departure_airport_name": "John F. Kennedy International Airport",
"arrival_airport_code": "DXB",
"arrival_airport_name": "Dubai International Airport",
"departure_datetime": "2026-08-20T11:00:00Z",
"arrival_datetime": "2026-08-21T07:35:00Z",
"duration": "12h 35m",
"booking_class": "Y",
"cabin_class": "Economy",
"cabin_class_name": "Economy",
"aircraft": "Boeing 777-300ER",
"layover": null,
"layover_duration": null,
"baggage_count": 1,
"baggage_weight": 23,
"baggage_weight_unit": "KG"
}
]
}
],
"fare_rules": [
"Changes may attract airline fees."
],
"penalty_rules": [
"Ticket is non-refundable after departure."
],
"is_refundable": false
}
]
}
```
Full request and response schema
# Get Country
Source: https://docs.payvessel.com/gift-cards/get-country
Retrieve a single gift card country by its numeric ID
Retrieve details for a single country by its numeric ID.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/gift-cards/countries/{country_id} \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Path parameters
| Parameter | Type | Required | Description |
| ------------ | ------- | -------- | -------------------------------------------------------------------------- |
| `country_id` | integer | Yes | The numeric country ID (from [List Countries](/gift-cards/list-countries)) |
## Response fields
| Field | Type | Description |
| --------------- | --------------- | ----------------------- |
| `id` | integer | Numeric country ID |
| `name` | string | Country name |
| `code` | string | ISO 3166-1 alpha-2 code |
| `currency_code` | string | Local currency code |
| `fee` | integer or null | Processing fee |
| `image` | string or null | Country flag/image URL |
Full request/response details and Try it
# Get Order
Source: https://docs.payvessel.com/gift-cards/get-order
Retrieve a gift card order by ID to check status and get the redemption code
Retrieve a gift card order by its PayVessel order ID. Use this to poll for the final status and retrieve the redemption code.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/gift-cards/orders/{order_id} \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Response fields
| Field | Type | Description |
| ----------------------- | ---------------- | ---------------------------------------------------- |
| `id` | string (uuid) | PayVessel order ID |
| `business_id` | string | Your business ID |
| `merchant_reference` | string | Your merchant reference |
| `order_reference` | string | PayVessel's internal order reference |
| `operator_id` | string | Operator ID |
| `product_id` | string | Product ID |
| `product_name` | string | Gift card name |
| `country` | string | Country |
| `amount_naira` | number | Amount in NGN |
| `amount_usd` | number | Amount in USD |
| `redeem_code` | string or null | Gift card redemption code |
| `serial_number` | string or null | Gift card serial number |
| `status` | string | `pending`, `processing`, `completed`, or `cancelled` |
| `error_message` | string or null | Error details if the order failed |
| `wallet_transaction_id` | string or null | Associated wallet transaction |
| `created_datetime` | datetime | When the order was created |
| `updated_datetime` | datetime | Last status update |
| `completed_datetime` | datetime or null | When the order was fulfilled |
Full request/response details and Try it
# List Countries
Source: https://docs.payvessel.com/gift-cards/list-countries
List all countries that have gift card products available
Retrieve all countries that have gift card products available. Use this as the first step to let your users browse gift cards by region.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/gift-cards/countries \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Response fields
Each country includes:
| Field | Type | Description |
| --------------- | --------------- | ----------------------------------- |
| `id` | integer | Numeric country ID |
| `name` | string | Country name (e.g. "United States") |
| `code` | string | ISO 3166-1 alpha-2 code (e.g. `US`) |
| `currency_code` | string | Local currency code |
| `fee` | integer or null | Processing fee (if applicable) |
| `image` | string or null | Country flag/image URL |
## Next step
Use the `code` value to [list operators](/gift-cards/list-operators) available in that country.
Full request/response details and Try it
# List Operators
Source: https://docs.payvessel.com/gift-cards/list-operators
Fetch all gift card operators available in a specific country
Fetch all gift card operators (brands) available in a specific country. Use the ISO 3166-1 alpha-2 country code from [List Countries](/gift-cards/list-countries).
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/gift-cards/countries/US/operators \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Path parameters
| Parameter | Type | Required | Description |
| -------------- | ------ | -------- | ----------------------------------------------- |
| `country_code` | string | Yes | ISO 3166-1 alpha-2 code (e.g. `US`, `GB`, `NG`) |
## Response fields
Each operator includes:
| Field | Type | Description |
| --------------- | -------------- | ------------------------------------------------------ |
| `id` | string | Operator ID (used to fetch products and create orders) |
| `name` | string | Brand name (e.g. "Amazon", "iTunes", "Steam") |
| `brand_id` | string or null | Brand identifier |
| `operator_type` | object or null | Operator type with `id` and `name` fields |
| `currency` | string or null | Operator currency |
| `image` | string or null | Brand logo URL |
## Next step
Use the operator `id` as the `operator_id` to [list products](/gift-cards/list-products).
Full request/response details and Try it
# List Products
Source: https://docs.payvessel.com/gift-cards/list-products
Fetch all available products for a gift card operator
Fetch all available products (denominations/values) for a given gift card operator. This returns the specific card values your users can purchase, along with USD and NGN pricing.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/gift-cards/operators/{operator_id}/products \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Path parameters
| Parameter | Type | Required | Description |
| ------------- | ------ | -------- | ----------------------------------------------------------------- |
| `operator_id` | string | Yes | The operator ID from [List Operators](/gift-cards/list-operators) |
## Response fields
The `data` object is a map of product IDs to product objects:
| Field | Type | Description |
| ------------- | -------------- | -------------------------------------------------------- |
| `id` | string | Product ID (used as `product_id` when creating an order) |
| `name` | string | Display name (e.g. "\$25 Amazon Gift Card") |
| `price_type` | string or null | Pricing type (e.g. "FIXED", "RANGE") |
| `usd` | number or null | Price in USD |
| `ngn` | number or null | Price in NGN |
| `operator_id` | string or null | Parent operator ID |
| `country` | string or null | Country code |
| `image` | string or null | Card image URL |
## Next step
Use the product `id` as the `product_id` when [purchasing a gift card](/gift-cards/purchase).
Full request/response details and Try it
# Gift Card API
Source: https://docs.payvessel.com/gift-cards/overview
Purchase and deliver digital gift cards from global brands through the PayVessel gift card API.
The PayVessel **gift card API** lets you sell **digital gift cards** from global brands to your users. Browse available operators by country, check products and pricing, and purchase cards instantly.
## Integration flow
1. **List countries** to discover which countries have gift card products.
2. **List operators** for a country to see available gift card brands.
3. **List products** for an operator to see available values and pricing.
4. **Purchase a gift card** by creating an order; PayVessel debits your wallet.
5. **Receive a webhook** when the order status changes (e.g. completed, cancelled).
6. **Verify order** or **get order** to retrieve the gift card details (redeem code, serial number).
```mermaid theme={null}
sequenceDiagram
participant You
participant PayVessel
You->>PayVessel: GET /countries
PayVessel-->>You: Available countries
You->>PayVessel: GET /countries/{country_code}/operators
PayVessel-->>You: Gift card operators
You->>PayVessel: GET /operators/{operator_id}/products
PayVessel-->>You: Products and pricing
You->>PayVessel: POST /orders
PayVessel-->>You: Order created
PayVessel--)You: Webhook (order status update)
```
## Order statuses
| Status | Description |
| ------------ | ------------------------------------------ |
| `pending` | Order received, not yet being processed |
| `processing` | Order is being fulfilled |
| `completed` | Gift card purchased; redeem code available |
| `cancelled` | Order was cancelled |
## Base path
All gift card endpoints are under:
```
/vaas/api/v1/gift-cards
```
## Authentication
All requests require `api-key` and `api-secret` headers. See [Authentication](/api-basics/authentication) for details.
# Purchase Gift Card
Source: https://docs.payvessel.com/gift-cards/purchase
Purchase a gift card and receive a redemption code
Purchase a gift card. PayVessel debits your business wallet and returns the gift card redemption details.
## Usage
```bash theme={null}
curl -X POST https://api.payvessel.com/vaas/api/v1/gift-cards/orders \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"reference": "gift-order-001",
"operator_id": "AMAZON_US",
"product_id": "AMAZON_25_USD"
}'
```
## Request body
| Field | Type | Required | Description |
| ------------- | ------ | -------- | ----------------------------------------------------------------- |
| `reference` | string | Yes | Your unique merchant order reference (max 64 characters) |
| `operator_id` | string | Yes | The operator ID from [List Operators](/gift-cards/list-operators) |
| `product_id` | string | Yes | The product ID from [List Products](/gift-cards/list-products) |
| `webhook_url` | string | No | Webhook URL for order status notifications (max 512 characters) |
The order amount is debited from your business wallet immediately. Make sure you have sufficient balance before creating an order.
## Response
The response returns an order object. Key fields:
| Field | Type | Description |
| ----------------------- | ---------------- | ------------------------------------------------------ |
| `id` | string (uuid) | PayVessel order ID |
| `merchant_reference` | string | Your merchant reference |
| `order_reference` | string | PayVessel's internal order reference |
| `operator_id` | string | Operator ID |
| `product_id` | string | Product ID |
| `product_name` | string | Gift card name |
| `country` | string | Country |
| `amount_usd` | number | Amount in USD |
| `amount_naira` | number | Amount in NGN |
| `redeem_code` | string or null | Gift card redemption code (available when `completed`) |
| `serial_number` | string or null | Gift card serial number |
| `status` | string | `pending`, `processing`, `completed`, or `cancelled` |
| `error_message` | string or null | Error details if the order failed |
| `wallet_transaction_id` | string or null | Associated wallet transaction |
| `created_datetime` | datetime | When the order was created |
| `updated_datetime` | datetime | Last status update |
| `completed_datetime` | datetime or null | When the order was fulfilled |
## Next step
If the status is not yet `completed`, use [Verify Order](/gift-cards/verify-order) or [Get Order](/gift-cards/get-order) to check the status and retrieve the redemption code.
Full request/response details and Try it
# Verify Order
Source: https://docs.payvessel.com/gift-cards/verify-order
Verify the status of a gift card order by its merchant reference
Verify the status of a gift card order using your merchant reference. If the order is not yet final, PayVessel checks the provider for the latest status before responding.
## Usage
```bash theme={null}
curl https://api.payvessel.com/vaas/api/v1/gift-cards/orders/verify/{reference} \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY"
```
## Path parameters
| Parameter | Type | Required | Description |
| ----------- | ------ | -------- | ------------------------------------ |
| `reference` | string | Yes | Your unique merchant order reference |
## Response fields
| Field | Type | Description |
| ----------------------- | ---------------- | ---------------------------------------------------- |
| `id` | string (uuid) | PayVessel order ID |
| `business_id` | string | Your business ID |
| `merchant_reference` | string | Your merchant reference |
| `order_reference` | string | PayVessel's internal order reference |
| `operator_id` | string | Operator ID |
| `product_id` | string | Product ID |
| `product_name` | string | Gift card name |
| `country` | string | Country |
| `amount_naira` | number | Amount in NGN |
| `amount_usd` | number | Amount in USD |
| `redeem_code` | string or null | Gift card redemption code |
| `serial_number` | string or null | Gift card serial number |
| `status` | string | `pending`, `processing`, `completed`, or `cancelled` |
| `error_message` | string or null | Error details if the order failed |
| `wallet_transaction_id` | string or null | Associated wallet transaction |
| `created_datetime` | datetime | When the order was created |
| `updated_datetime` | datetime | Last status update |
| `completed_datetime` | datetime or null | When the order was fulfilled |
Full request/response details and Try it
# BVN Verification API (Basic)
Source: https://docs.payvessel.com/identity-verification/basic-bvn-verification
PayVessel basic BVN verification API to match customer identity fields against Bank Verification Number records in Nigeria.
**BVN verification API (basic)** is best when you already collected customer profile data and want to check how closely it matches the BVN record.
## Best For
* Fast onboarding checks
* Match-score driven workflows
* Tiered KYC where you do not yet need full BVN profile details
## What You Submit
You provide the BVN together with identity fields such as first name, middle name, last name, gender, birthday, and phone number.
## What You Get Back
The response tells you how well the submitted profile matches the BVN record:
* `name_match_rlt`
* `names_match_percentage`
* `birthday_match_rlt`
* `gender_match_rlt`
* `phone_number_match_rlt`
## How To Use It
Use this guide when you need a simple pass / review / fail decision:
* Auto-approve when all core fields match
* Route to manual review when the match percentage is borderline
* Reject or request correction when the identity fields clearly differ
## Typical Flow
1. Collect BVN and customer profile details.
2. Call Basic BVN Verification.
3. Evaluate the match fields and score.
4. Escalate to Enhanced BVN, document checks, or face comparison when needed.
If you need actual profile data from the BVN source instead of match results, use [Enhanced BVN Verification](/identity-verification/enhanced-bvn-verification).
# NIN Verification API (Basic)
Source: https://docs.payvessel.com/identity-verification/basic-nin-verification
PayVessel basic NIN verification API to match customer identity fields against National Identification Number records.
Basic NIN verification is similar to basic BVN verification: it checks whether submitted identity fields align with the NIN record.
## Best For
* National-ID based KYC
* Match-result workflows
* Entry-level onboarding checks
## What You Submit
You provide the NIN together with first name, last name, middle name, gender, birthday, and phone number.
## What You Get Back
The endpoint returns match-result fields that help you assess whether the provided identity profile aligns with the NIN record.
## How To Use It
* Use the result for automated acceptance thresholds
* Trigger manual review on partial matches
* Ask the customer to correct inputs when mismatches are obvious
## Escalation Path
If the customer passes this step but you still need more evidence, continue to:
* [Enhanced NIN Verification](/identity-verification/enhanced-nin-verification)
* Document verification
* Face comparison
# Blacklist Query
Source: https://docs.payvessel.com/identity-verification/blacklist-query
Use blacklist queries to screen customers before high-risk actions
Blacklist queries help you determine whether a customer appears in a screened list before you allow higher-risk actions.
## Best For
* Pre-onboarding screening
* Transfer or withdrawal controls
* Escalated review before limit upgrades
## What You Submit
You can query with identifiers such as:
* Phone number
* BVN
* NIN
## What You Get Back
The response returns fields such as:
* `result`
* `hit_time`
* `request_id`
## How To Use It
* Block immediately on confirmed blacklist hits
* Step up verification for borderline or ambiguous cases
* Store the `request_id` for investigation and support workflows
# Credit Score API
Source: https://docs.payvessel.com/identity-verification/credit-score-query
PayVessel credit score API for Nigerian customer risk grading, underwriting, limits, and lending decisions.
The PayVessel **credit score API** provides a score-oriented risk signal that can support underwriting, limits, pricing, or access decisions.
## Best For
* Lending decisions
* Tiered product access
* Risk-based pricing or approval logic
## What You Submit
You provide:
* Mobile number
* ID number
* Optional extended metadata
## What You Get Back
The response can include:
* `credit_score`
* `version`
* `request_id`
## How To Use It
* Define score bands that map to approval or review outcomes
* Combine the score with identity verification and blacklist results
* Keep score use consistent with your compliance and product policy
# Driver's License Verification
Source: https://docs.payvessel.com/identity-verification/drivers-license-verification
Use driver's license verification when a license is part of your accepted identity set
Driverβs license verification is useful when you accept a Nigerian driverβs license as a supporting or primary document for onboarding.
## Best For
* Document-based KYC
* Multi-document onboarding journeys
* Secondary verification after BVN or NIN
## What You Submit
You submit the license number.
## What You Get Back
The response can include:
* Names
* Gender
* Birth date
* Photo
* License number
* Issue date
* Expiry date
## How To Use It
* Confirm the document exists and is tied to the expected customer
* Check the issue and expiry dates before approval
* Compare the returned photo and names to other identity records
Document verification is strongest when combined with a primary identity anchor such as BVN or NIN.
# BVN Verification API (Enhanced)
Source: https://docs.payvessel.com/identity-verification/enhanced-bvn-verification
PayVessel enhanced BVN verification API returns full BVN profile data for Nigerian KYC and onboarding workflows.
Enhanced BVN verification is the stronger BVN workflow when you need a richer profile tied to the customerβs BVN.
## Best For
* Full onboarding checks
* Compliance-heavy account creation
* Internal identity enrichment before approval or limit upgrades
## What You Submit
You only submit the BVN.
## What You Get Back
The response can include identity attributes such as:
* Names
* Gender
* Birthday
* Photo
* Linked phone numbers
* Name on card
## How To Use It
Use enhanced BVN when the outcome depends on profile retrieval, not just field matching. A common pattern is:
1. Run Enhanced BVN Verification.
2. Compare the returned profile to your customer-submitted data.
3. Add document or face checks for higher-risk users.
4. Store only the fields you actually need for audit and decisioning.
## When To Prefer This Over Basic BVN
Choose Enhanced BVN when:
* You need profile values back
* You want a stored photo or secondary phone number
* You are building a stronger first-time identity check
For lightweight match validation against fields the customer already entered, [Basic BVN Verification](/identity-verification/basic-bvn-verification) is usually enough.
# NIN Verification API (Enhanced)
Source: https://docs.payvessel.com/identity-verification/enhanced-nin-verification
PayVessel enhanced NIN verification API returns extended NIN profile data for Nigerian identity verification.
Enhanced NIN verification gives you a richer NIN-linked identity profile from a single NIN input.
## Best For
* Higher-trust customer onboarding
* Identity enrichment
* Compliance review and deeper KYC checks
## What You Submit
You submit the customerβs NIN.
## What You Get Back
The response can include:
* First name, middle name, and surname
* Gender
* Birth date
* Photo
* Telephone number
## How To Use It
Use enhanced NIN when you need to retrieve identity data first and compare it to your own records second.
Typical pattern:
1. Retrieve the NIN profile.
2. Compare returned values to the customer profile in your system.
3. Add document or bank-account verification where required.
4. Log the verification outcome for audit and support.
# International Passport Verification
Source: https://docs.payvessel.com/identity-verification/international-passport-verification
Use passport verification when you need passport-backed identity evidence
International passport verification is appropriate when a passport is part of your required document set or when you need nationality-linked document evidence.
## Best For
* Premium onboarding
* Cross-border or travel-linked use cases
* Secondary document validation
## What You Submit
You submit the passport number.
## What You Get Back
The response can include:
* Names
* Gender
* Birth date
* Photo
* Passport number
* Issue date
* Expiry date
* Nationality
## How To Use It
* Check expiry before approval
* Compare returned identity fields to the customer profile
* Use nationality and passport metadata to support downstream risk or compliance rules
# Loan Feature Query
Source: https://docs.payvessel.com/identity-verification/loan-feature-query
Use loan-feature queries when your workflow needs downstream loan-related signals
Loan-feature queries are useful when your product needs loan-linked data or eligibility signals based on the submitted access context.
## Best For
* Loan onboarding
* Offer personalization
* Downstream lending or product-access logic
## What You Submit
You provide:
* `access_type`
* `value`
* `authorization`
* `type`
* `encrypt`
## What You Get Back
The response returns a data object that you can interpret according to your product logic and the provider response you expect.
## How To Use It
* Call this after core identity verification is complete
* Use the response to decide whether to show, hide, or tailor loan features
* Log the request context so support and risk teams can audit decisions later
# Verify Bank Account
Source: https://docs.payvessel.com/identity-verification/merchant-bank-account
Use bank account verification before linking a customer bank account to payouts or settlements
Bank account verification confirms whether a bank account aligns with the submitted BVN and returns the resolved account-name details.
## Best For
* Linking payout accounts
* Reducing transfer failures
* Detecting name mismatches before funds movement
## What You Submit
You provide:
* BVN
* Bank code
* Bank account number
## What You Get Back
The response includes:
* `verify_result`
* `bank_account_name`
* `name_match_percentage`
## How To Use It
* Auto-approve strong account-name matches
* Pause for review when the match percentage is low
* Use this before enabling withdrawals, settlements, or recipient creation
# Compare Faces
Source: https://docs.payvessel.com/identity-verification/merchant-face
When to use face comparison and how to work with similarity scores
Face comparison helps you determine whether two submitted images likely belong to the same person.
## Best For
* Identity confirmation after BVN, NIN, or document retrieval
* Fraud reduction
* Manual-review support
## What You Submit
You submit:
* `source_image`
* `target_image`
These can represent a live selfie, stored customer image, or document-linked image depending on your flow.
## What You Get Back
The endpoint returns a `similarity` score.
## How To Use It
* Define an internal threshold for accept / review / reject
* Use higher thresholds for higher-risk actions
* Combine with liveness when you need stronger anti-spoof protection
Face similarity should support a broader identity decision, not replace core identity-number or document verification by itself.
# Identity Verification API
Source: https://docs.payvessel.com/identity-verification/overview
PayVessel identity verification API for BVN verification, NIN verification, credit score API, blacklist checks, and KYC in Nigeria.
Use the PayVessel **identity verification API** to confirm who a customer is, validate linked financial details, and apply risk checks before you allow higher-trust actions.
## Recommended Flow
1. Start with a strong identity anchor such as **BVN** or **NIN**.
2. Add **document verification** when you need richer profile evidence.
3. Run **face comparison** when you need image-based matching.
4. Confirm the customerβs **bank account** before payout or settlement flows.
5. Use **risk queries** to screen for blacklist hits, assess credit posture, or retrieve loan-related signals.
## Choose The Right Check
Compare a BVN against submitted identity fields and review match results.
Retrieve a fuller BVN profile for stronger onboarding and compliance checks.
Check NIN data against customer-submitted profile details.
Retrieve richer NIN profile details when you need a deeper identity view.
Verify driver's license, voter's card, and international passport records.
Compare two face images and review the returned similarity score.
Confirm a bank account against a BVN and returned account-name match score.
Screen blacklist status, credit score, and loan-related signals.
Reserved test values for simulating verified, not-found, and error responses.
Every identity endpoint is **simulated in the sandbox** β no request reaches a real bureau. See [Sandbox Testing](/identity-verification/sandbox-testing) for the reserved values that select each response.
Use the **API Reference** tab for exact headers, payloads, and live request examples. Use the pages in this section to decide **when** to call each endpoint and **how** to combine them.
# Identity Verification Sandbox Testing
Source: https://docs.payvessel.com/identity-verification/sandbox-testing
Reserved test values for simulating successful, failed, and error identity verification responses in the PayVessel sandbox.
Every identity verification endpoint is **simulated in the sandbox**. No request reaches a real bureau, nothing is billed to a live provider, and no real person's data is ever returned.
Reserved test values let you choose which response you get, so you can build and test your error handling before going live.
These values only work on `https://sandbox.payvessel.com`. In production the same endpoints query real records.
## How It Works
Every reserved value ends in `9999` followed by a two-digit outcome code. **Any value that does not end that way returns a successful verification**, so you can keep using realistic-looking test data for the happy path.
Returns a populated, successful response. `success` is `true`.
The record does not exist. Returns HTTP `200` with `success: false` and `data: null`.
The lookup succeeds but the answer is negative: a name mismatch, a blacklist hit, a poor credit score, an expired document, or a failed liveness check. `success` is `true` β the check ran, the outcome was unfavourable.
The upstream bureau failed. Returns HTTP `502`.
The upstream bureau did not respond in time. Returns HTTP `502`.
Returns HTTP `400`.
Returns HTTP `429`.
## Reserved Values
| Field | Verified | Not found | Adverse | Provider error | Timeout | Invalid | Rate limited |
| ------------------------------ | ------------------------- | ----------------- | ----------------- | ----------------- | ----------------- | ----------------- | ----------------- |
| `bvn`, `bvn_no`, `id_number` | `22222999900` | `22222999901` | `22222999902` | `22222999903` | `22222999904` | `22222999905` | `22222999906` |
| `nin` | `11111999900` | `11111999901` | `11111999902` | `11111999903` | `11111999904` | `11111999905` | `11111999906` |
| `bank_account` | `0000999900` | `0000999901` | β | `0000999903` | `0000999904` | `0000999905` | `0000999906` |
| `license_number` | `SBX999900` | `SBX999901` | `SBX999902` | `SBX999903` | `SBX999904` | `SBX999905` | `SBX999906` |
| `voters_id` | `SBX000999900` | `SBX000999901` | `SBX000999902` | `SBX000999903` | `SBX000999904` | `SBX000999905` | `SBX000999906` |
| `passport_number` | `A0999900` | `A0999901` | `A0999902` | `A0999903` | `A0999904` | `A0999905` | `A0999906` |
| `phone_number` | `234800000999900` | `234800000999901` | `234800000999902` | `234800000999903` | `234800000999904` | `234800000999905` | `234800000999906` |
| `biz_id`, `value` | any value ending `999900` | `β¦999901` | `β¦999902` | `β¦999903` | `β¦999904` | `β¦999905` | `β¦999906` |
| `source_image`, `target_image` | `sandbox:00` | `sandbox:01` | `sandbox:02` | `sandbox:03` | `sandbox:04` | `sandbox:05` | `sandbox:06` |
Hyphens and spaces are ignored, so `SBX-9999-02` and `SBX999902` behave identically.
## The Sandbox Identity
Reserved values return this person:
| Field | Value |
| ------------- | ------------- |
| First name | `John` |
| Middle name | `Ade` |
| Last name | `Doe` |
| Gender | `MALE` |
| Date of birth | `1990-01-01` |
| Phone number | `08000000000` |
Any **non-reserved** identifier returns a different but consistent person β the same input always gives the same result, so you can rely on it in automated tests.
## Choosing An Outcome When A Request Has Several Identifiers
The first reserved value wins, in this order:
| Endpoint | Order checked |
| --------------------- | ----------------------------------------- |
| Basic BVN | `bvn`, then `phone_number` |
| Bank account | `bank_account`, then `bank_code` |
| Blacklist query | `bvn_no`, then `nin`, then `phone_number` |
| Loan feature | `value`, then `authorization` |
| Liveness (initialize) | `biz_id`, then `user_id` |
| Face comparison | `source_image`, then `target_image` |
## Examples
```bash Verified theme={null}
curl --request POST \
--url https://sandbox.payvessel.com/kyc/api/v1/merchant/bvn/basic \
--header 'Content-Type: application/json' \
--header 'api-key: YOUR_API_KEY' \
--header 'api-secret: YOUR_API_SECRET' \
--data '{
"bvn": "22222999900",
"first_name": "John",
"last_name": "Doe",
"birthday": "1990-01-01"
}'
```
```bash Not found theme={null}
curl --request POST \
--url https://sandbox.payvessel.com/kyc/api/v1/merchant/bvn/basic \
--header 'Content-Type: application/json' \
--header 'api-key: YOUR_API_KEY' \
--header 'api-secret: YOUR_API_SECRET' \
--data '{
"bvn": "22222999901",
"first_name": "John",
"last_name": "Doe",
"birthday": "1990-01-01"
}'
```
```bash Provider error theme={null}
curl --request POST \
--url https://sandbox.payvessel.com/kyc/api/v1/merchant/bvn/basic \
--header 'Content-Type: application/json' \
--header 'api-key: YOUR_API_KEY' \
--header 'api-secret: YOUR_API_SECRET' \
--data '{
"bvn": "22222999903",
"first_name": "John",
"last_name": "Doe",
"birthday": "1990-01-01"
}'
```
## Endpoint Notes
These endpoints compare the identity fields **you submit** against the record. To see `MATCH`, submit the sandbox identity above alongside the reserved value. Submitting any other name returns `NO_MATCH`, which is a useful test case in its own right.
A successful bank account lookup always reports a confirmed name match, so there is no adverse variant to simulate. `0000999902` behaves the same as the not-found value.
Images are base64, so the numeric suffix rule would match real data by accident. Pass the literal string `sandbox:00` (or another code) as the image instead. `sandbox:01` returns a `400` for a missing face, matching production behaviour. Any real base64 image returns a successful comparison.
The `transaction_id` returned by the initialize call carries the outcome you selected with `biz_id`. Pass it straight to the query endpoint and you get the matching result.
A wallet balance failure happens before verification starts, so there is no reserved value for it. To test that path, drain your sandbox wallet balance.
# Voter's Card Verification
Source: https://docs.payvessel.com/identity-verification/voters-card-verification
Use voter's card verification when voter-registration data is part of your review flow
Voterβs card verification helps you validate a voter ID and retrieve identity details connected to that record.
## Best For
* Supporting identity checks
* Supplementary evidence during manual review
* Workflows that need polling-unit or location-linked voter details
## What You Submit
You submit the voter ID.
## What You Get Back
The response can include:
* Names
* Gender
* Birth date
* Photo
* Voter ID
* Polling unit
* State
* LGA
## How To Use It
Use this as a supporting evidence layer alongside stronger identity anchors such as BVN or NIN. It is especially useful when you want to cross-check location-linked identity details.
# PayVessel API Documentation
Source: https://docs.payvessel.com/index
Official PayVessel API docs for virtual card API, virtual account API, BVN and NIN verification API, credit score API, payments, transfers, and wallets. Build fintech products in Nigeria.
PayVessel helps developers integrate **payments**, **virtual accounts**, **USD virtual cards**, and **identity verification** (BVN, NIN, credit score) through a single REST API platform.
Virtual card API, virtual account API, BVN/NIN verification, credit score, and more
## Quick Start Guides
Securely collect payments from cards, bank accounts, and mobile wallets.
Make instant transfers to bank accounts and mobile money users.
Virtual card API: issue, fund, and manage Visa/Mastercard USD cards.
Virtual account API: STATIC and DYNAMIC Nigerian bank accounts for collections.
BVN verification API, NIN verification API, credit score, and risk checks.
Explore our SDKs, plugins, and no-code tools to integrate payments without direct API coding.
## Explore Our Code Demos
We've built simple, real-world projects to show you how to use the Payvessel API. Explore all demos or start with these popular examples:
**APIs Used:** Accept Payments, Verify Transactions\
**Tech:** Vue.js
**APIs Used:** Accept Payments, Verify Transactions\
**Tech:** Android (Kotlin)
**APIs Used:** Create Customer, Manage Subscriptions\
**Tech:** React
**APIs Used:** Payment Requests, Terminal Events\
**Tech:** Node.js
# Quickstart
Source: https://docs.payvessel.com/quickstart
Get started with the PayVessel API: authentication, sandbox, virtual card API, virtual account API, and identity verification in minutes.
**Chart your integration course before setting sail with Payvessel.**
To integrate Payvessel into your application, follow this step-by-step navigation guide.
Get up and running in minutes with our streamlined onboarding
Test safely in our sandbox environment with no real money
***
## ποΈ Step 1: Create Your Developer Account
**Sign up for a free merchant account** to access your payvessel dashboard.
In the Payvessel sandbox, you'll be able to:
* π³ Process payments using test card data and mock accounts
* π¦ Simulate bank transfers and mobile money transactions
* π Test webhooks and error scenarios
* β Validate customer identification processes
Learn more about testing in our sandbox environment in our [development guide](/development).
## βοΈ Step 2: Configure Your Integration
**Choose your integration vessel** based on your technical stack and business needs:
Use our pre-built checkout (cards + bank transfer) or the payvessel-checkout npm package
Leverage our libraries for popular frameworks and platforms
Build custom payment flows using our flexible endpoints
π **New to APIs?**
Read our [beginner-friendly guide](/essentials/markdown) to understand how APIs work and how to implement them in your application.
Once you select your integration method, test thoroughly using sandbox credentials and our provided test data. We've compiled common integration patterns and best practices to help you avoid early obstacles.
* Use our comprehensive test card numbers
* Validate all error scenarios
* Test webhook endpoints thoroughly
* Verify mobile money simulations
* Single payment flows
* Subscription billing
* Multi-party transactions
* Mobile-first implementations
## π Step 3: Launch Your Live Account
After successful testing, **upgrade to a production account** to access real transaction processing capabilities and actual fund movements.
## π Step 4: Complete Business Verification
To begin live transactions, you'll need to **complete our verification process**, which includes submitting business documentation and bank account details for settlement.
Upload your business registration and tax documents
Provide settlement account information for fund transfers
Submit identity verification for business owners
Our team will review and approve your application within 24-48 hours
## π Step β: Go Live! π
**Once verified and approved, you're ready to navigate live waters!** Start accepting real payments in multiple currencies through your Payvessel dashboard.
Discover advanced features and settings unavailable in test mode
Use our go-live checklist to ensure everything is shipshape
Migrate webhooks, redirect URLs, and security settings
Track transactions and optimize your payment flows
**Pre-Launch Checklist:**
* [ ] All sandbox tests passing
* [ ] Webhook endpoints configured
* [ ] Error handling implemented
* [ ] Security best practices followed
* [ ] Production credentials updated
***
## π Need Guidance?
Our developer documentation includes detailed tutorials, API references, and troubleshooting guides to ensure smooth sailing throughout your integration journey.
Comprehensive API references and guides
Get help from our integration experts
Sandbox environment and test utilities
Ready-to-use integration snippets
**Ready to begin your payment journey?**
Start building with Payvessel today
Dive deep into our comprehensive API
# Support
Source: https://docs.payvessel.com/support
Get help with your Payvessel integration
Need help? We're here for you. Reach out through any of the channels below.
## Contact Us
For integration help, API questions, and general inquiries.
**[support@payvessel.com](mailto:support@payvessel.com)**
For KYC, AML, regulatory, and compliance-related matters.
**[compliance@payvessel.com](mailto:compliance@payvessel.com)**
## Developer Community
Join our Slack channel to connect with the Payvessel engineering team and other developers. Get real-time help, share feedback, and stay updated on API changes.
Follow along with the developer community and get faster responses on technical questions.
## Self-Service Resources
Full endpoint documentation with request/response examples.
Get up and running with your first integration.
Test your integration safely before going live.
# Bulk transfers
Source: https://docs.payvessel.com/transfer-payout/bulk-transfers
**Send multiple payouts from your managed wallet in a single request.** Bulk transfers are perfect for payroll, vendor settlements, refunds, and other multiβrecipient disbursements.
## How bulk transfers work
1. **Prepare your batch**\
Build an array of transfer instructions (amount, destination account number, bank code, narration, unique reference for each row).
2. **Validate accounts (optional, recommended)**\
Optionally run accountβnumber + bankβcode pairs through the **validateβaccount** endpoint before including them in the batch.
3. **Call the bulk transfer endpoint**\
Use the **Bulk Transfer** operation under **Transfers** to submit the entire batch in one API call from your business wallet.
4. **Track batch result**\
The response returns:
* a `batch_reference`
* counts for `successful_count`, `failed_count`, and `total_count`
* the `total_amount` processed
5. **Reconcile individual transfers**\
Use the **transferβstatus** and **walletβtransactions** endpoints to drill into each transfer in the batch and reconcile them with your internal records.
***
## Best practices
* **Batch sizing:** start with batches of 50β100 transfers per call to balance speed and observability.
* **Idempotent references:** ensure each row in a batch has a unique reference so you can safely retry if there is a network error.
* **Monitoring:** log and alert on high `failed_count` for a batch and surface reasons back to your operations dashboard.
***
For detailed request/response payloads and code examples, use the **Transfers** API reference for the bulkβtransfer and transferβstatus endpoints, plus the **Wallets** API for balance and transactions.
# Get Bank List
Source: https://docs.payvessel.com/transfer-payout/get-bank-list
Fetch all supported banks and their codes before initiating a transfer
Retrieve the full list of supported banks. Use this to populate a bank picker in your UI and get the correct `bank_code` for transfers and account validation.
## How it works
1. **Call the endpoint** with your `api-key` and `api-secret`: no request body needed.
2. **Display the list** to your user for bank selection.
3. **Use the `bank_code`** when calling Validate Account or Initiate Transfer.
Only show banks where `is_active` is `true` in your UI.
Full request/response details
# Single transfers
Source: https://docs.payvessel.com/transfer-payout/single-transfers
**Send money from your managed wallet to a single bank account** using the wallet transfer APIs. Single transfers are ideal for withdrawals, refunds, and oneβoff payouts.
## How it works
1. **Get or create your wallet**\
Use the wallet API to get the business wallet for your integration. This gives you the wallet ID, account number, and current balances.
2. **Check available balance**\
Call the walletβbalance endpoint to ensure you have enough **available\_balance** to cover the transfer amount and any fees.
3. **Validate the destination account (optional but recommended)**\
Use the **validateβaccount** endpoint (name enquiry) to confirm the destination bank account number and name before sending funds.
4. **Initiate the transfer**\
Call the **Initiate Transfer** API under **Transfers** with:
* amount
* destination account number
* bank code
* narration / description
* a unique reference
* OTP or any required extra fields (depending on your risk settings)
5. **Check transfer status**\
After you receive the initial response, use the **transferβstatus** endpoint (or webhooks, if enabled) to confirm whether the transfer is `pending`, `success`, or `failed`.
6. **Reconcile wallet transactions**\
Use the **walletβtransactions** endpoint to fetch a history of debits and credits for the wallet and reconcile payouts with your internal records.
***
## Key considerations
* **Idempotency**: always send a unique reference per transfer so you can safely retry without doubling payouts.
* **Limits and fees**: design your UI to reflect any daily limits or perβtransfer caps enforced by your business rules.
* **User experience**: clearly communicate `pending` vs `success` to endβusers and surface clear error messages when a transfer fails.
***
For API payloads, headers, and response examples, see the **[Initiate Transfer](/api-reference/transfers/initiate-transfer)** reference and the wallet API references under **Wallets**.
# Transfer Status
Source: https://docs.payvessel.com/transfer-payout/transfer-status
Check the status of a previously initiated transfer
Check the final status of a transfer you created with [Single Transfers](/transfer-payout/single-transfers) or [Bulk Transfers](/transfer-payout/bulk-transfers). Use this to confirm whether a payout completed successfully.
## Usage
```bash theme={null}
curl -X POST https://api.payvessel.com/pms/api/external/request/wallet/transfer-status/ \
-H "api-key: YOUR_API_KEY" \
-H "api-secret: YOUR_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"reference": "PAYOUT_2026_0001",
"session_id": "SESSION_123456789"
}'
```
## Request body
| Field | Type | Required | Description |
| ------------ | ------ | -------- | ------------------------------------------------------------ |
| `reference` | string | No | The unique reference you passed when initiating the transfer |
| `session_id` | string | No | The session ID returned in the initial transfer response |
## Response fields
| Field | Type | Description |
| ---------------------------- | -------- | --------------------------------- |
| `reference` | string | Your transfer reference |
| `session_id` | string | Transfer session ID |
| `amount` | string | Transfer amount |
| `status` | string | `pending`, `success`, or `failed` |
| `destination_account_number` | string | Recipient account number |
| `destination_bank_code` | string | Recipient bank code |
| `destination_account_name` | string | Recipient account name |
| `completed_at` | datetime | When the transfer completed |
Full request/response details and Try it
# Validate Account
Source: https://docs.payvessel.com/transfer-payout/validate-account
Resolve a bank account number to a name before sending money
Confirm an account number belongs to the expected person before initiating a transfer. This prevents misdirected payments.
## How it works
1. **Send** the `account_number` and `bank_code` in the request body.
2. **Receive** the resolved `account_name`, `account_number`, `bank_code`, and `bank_name`.
3. **Show the account name** to your user for confirmation before proceeding with the transfer.
Always validate the account before calling Initiate Transfer. Transfers are irreversible once completed.
Full request/response details
# Banks and OFIs
Source: https://docs.payvessel.com/use-cases/banks-and-ofis
Modern payment infrastructure for traditional financial institutions
#
**Modernize your payment infrastructure while maintaining regulatory compliance and institutional-grade security.**
Traditional banks and financial institutions need payment solutions that bridge legacy systems with modern digital experiences.
Built for institutional scale and compliance requirements
Meet all banking regulations and security standards
***
## Why Banks Choose Payvessel
### π¦ Institutional-Grade Infrastructure
Purpose-built for financial institutions:
* 99.99% uptime SLA with enterprise support
* SOC 2 Type II and ISO 27001 certified
* PCI DSS Level 1 compliance
* Dedicated infrastructure and private cloud options
### π Legacy System Integration
Seamlessly connect with existing banking infrastructure:
* Core banking system integrations
* SWIFT network connectivity
* Real-time gross settlement (RTGS) support
* ACH and wire transfer capabilities
### π Comprehensive Compliance
Stay compliant across all jurisdictions:
* AML/KYC automated screening
* Sanctions list monitoring
* Regulatory reporting and audit trails
* GDPR and data privacy compliance
## Key Solutions for Banks
Modern payment experiences for online and mobile banking
International transfers with competitive FX rates
Real-time payment processing for immediate settlements
Complete payment acceptance solutions for business clients
White-label wallet solutions for retail and corporate clients
API-first approach for open banking initiatives
## Use Cases
* Customer-to-customer transfers
* Bill payment services
* Mobile banking applications
* ATM and card processing
* Loan disbursements and collections
* Bulk payment processing
* Payroll and supplier payments
* Treasury management solutions
* Trade finance facilitation
* Multi-currency account management
* Cross-border payment facilitation
* Nostro/Vostro account management
* SWIFT message processing
* Regulatory compliance reporting
* Risk management and monitoring
## Implementation Approach
Comprehensive analysis of current payment infrastructure and requirements
Detailed technical roadmap with minimal disruption to existing services
Controlled rollout with select customers and use cases
Gradual migration with 24/7 support and monitoring
Ongoing performance tuning and feature enhancement
## Compliance & Security
* PCI DSS Level 1 certification
* ISO 27001 information security
* SOC 2 Type II compliance
* Multi-factor authentication
* Basel III capital requirements
* PSD2 and open banking standards
* FATCA and CRS reporting
* Local banking regulations
**Enterprise Implementation:** Bank integrations require dedicated implementation support. Our enterprise team provides white-glove service throughout the entire process.
## Success Story
**Challenge:** A regional bank needed to modernize their payment infrastructure to compete with digital-first competitors while maintaining regulatory compliance.
**Solution:** Payvessel provided a phased integration approach, starting with mobile banking payments and expanding to full digital banking capabilities.
**Results:**
* 300% increase in digital transaction volume
* 50% reduction in payment processing costs
* 99.9% uptime across all payment channels
* Full regulatory compliance maintained throughout transition
**Ready to modernize your payment infrastructure?**
Schedule a consultation with our banking specialists
Review our technical documentation
# E-Commerce
Source: https://docs.payvessel.com/use-cases/e-commerce
Complete payment solutions for online retail and digital commerce
**Boost conversions and reduce cart abandonment with optimized payment experiences designed for online retail.**
E-commerce businesses need payment solutions that convert browsers into buyers while providing secure, fast checkout experiences.
Optimized checkout flows that increase sales
Multiple payment options to capture every customer
***
## Why E-Commerce Businesses Choose Payvessel
### π Conversion Optimization
Maximize your sales with features designed to convert:
* One-click checkout for returning customers
* Guest checkout options (no account required)
* Mobile-optimized payment flows
* Express payment buttons (Apple Pay, Google Pay)
* Smart payment method recommendations
### π³ Comprehensive Payment Methods
Accept payments the way your customers prefer:
* **Credit & Debit Cards:** Visa, Mastercard, American Express, Discover
* **Digital Wallets:** Apple Pay, Google Pay, PayPal, Amazon Pay
* **Buy Now, Pay Later:** Klarna, Afterpay, Affirm integration
* **Bank Transfers:** ACH, SEPA, local bank transfer methods
* **Alternative Payments:** Cryptocurrency, gift cards, loyalty points
### π Global Expansion
Sell worldwide with localized payment experiences:
* 35+ currencies with real-time conversion
* Local payment methods for international markets
* Multi-language checkout interfaces
* Regional tax calculation and compliance
* Cross-border seller protection
## E-Commerce Solutions
Complete checkout solutions for product-based businesses
Native mobile app payment integration
Recurring billing for subscription boxes and services
Multi-vendor payment splitting and marketplace solutions
Instant payment processing for digital products
Automated payment flows for dropshipping businesses
## Key Features for Online Stores
* **Address Autocomplete:** Reduce form friction with smart address suggestions
* **Payment Method Detection:** Automatically suggest preferred payment methods
* **Error Prevention:** Real-time validation to prevent payment failures
* **Mobile Optimization:** Touch-friendly interfaces for mobile shoppers
* **A/B Testing:** Test different checkout flows to optimize conversions
* **Machine Learning:** AI-powered fraud detection and prevention
* **Risk Scoring:** Real-time transaction risk assessment
* **3D Secure:** Additional authentication for high-risk transactions
* **Velocity Checking:** Monitor for suspicious transaction patterns
* **Chargeback Protection:** Comprehensive dispute management tools
* **Conversion Tracking:** Monitor checkout performance and drop-off points
* **Payment Method Analysis:** Understand customer payment preferences
* **Revenue Reporting:** Detailed transaction and settlement reports
* **Customer Insights:** Payment behavior and lifetime value analysis
* **Performance Metrics:** Real-time dashboards and automated alerts
## Platform Integrations
Seamlessly integrate with your existing e-commerce platform:
Native Shopify app with one-click installation
WordPress plugin for WooCommerce stores
Full-featured Magento extension
Integrated BigCommerce payment solution
**Custom Integrations:** Our APIs support custom e-commerce platforms and headless commerce architectures.
## Success Stories
**Challenge:** A growing fashion brand experienced 30% cart abandonment due to limited payment options and slow checkout.
**Solution:** Implemented Payvessel's express checkout with multiple payment methods and mobile optimization.
**Results:**
* 45% reduction in cart abandonment
* 25% increase in mobile conversions
* 60% faster checkout completion
* 15% growth in average order value
**Challenge:** An international marketplace needed to support sellers and buyers across multiple countries with local payment preferences.
**Solution:** Multi-currency support with local payment methods and automated seller transfers.
**Results:**
* Expanded to 15 new markets
* 200% increase in international transactions
* 90% reduction in payment-related support tickets
* Same-day seller transfers in major markets
## Getting Started with E-Commerce
Select from our e-commerce platform plugins or custom API integration
Set up your preferred payment methods and checkout flow
Use our sandbox environment to test all payment scenarios
Go live and use our analytics to continuously improve conversions
## Pricing for E-Commerce
* No monthly fees or setup costs
* Competitive per-transaction rates
* Volume discounts for high-volume merchants
* No hidden fees or long-term contracts
* Dynamic routing for lowest processing costs
* Currency optimization for international sales
* Subscription billing with failed payment recovery
* Detailed cost analysis and reporting
**Ready to boost your e-commerce sales?**
Start integrating in minutes with our e-commerce guide
Find your e-commerce platform integration
# Fintechs
Source: https://docs.payvessel.com/use-cases/fintechs
Payment solutions tailored for financial technology companies
**Empower your fintech platform with seamless payment infrastructure designed for innovation.**
Modern fintech companies need flexible, scalable payment solutions that can adapt to rapidly evolving business models and customer demands.
Launch payment features in days, not months
Handle millions of transactions with enterprise-grade reliability
***
## Why Fintechs Choose Payvessel
### π§ Developer-First Approach
Our APIs are designed with developers in mind, offering:
* Comprehensive documentation and code examples
* SDKs for popular programming languages
* Sandbox environment for thorough testing
* Real-time webhook notifications
### π° Flexible Business Models
Support diverse fintech use cases:
* **Digital Wallets** - Enable peer-to-peer transfers and mobile payments
* **Investment Platforms** - Handle deposits, withdrawals, and dividend payments
* **Lending Services** - Process loan disbursements and repayments
* **Neo-Banks** - Full suite of banking payment capabilities
### π Global Reach
Expand your fintech services globally with:
* Multi-currency transaction processing
* Local payment methods in 35+ countries
* Compliance with international financial regulations
* Real-time currency conversion
## Key Features for Fintechs
Real-time fund transfers and instant account settlements
PCI DSS compliance and advanced fraud protection
Detailed transaction insights and business intelligence
RESTful APIs with comprehensive documentation
Cards, bank transfers, mobile money, and digital wallets
Process payments in multiple currencies worldwide
## Success Stories
**Challenge:** A leading digital wallet needed to process millions of micro-transactions daily while maintaining low fees.
**Solution:** Payvessel's optimized infrastructure reduced transaction costs by 40% while handling 10x traffic growth.
**Result:** 2M+ active users and 99.9% uptime across multiple markets.
**Challenge:** An investment platform required instant deposits and automated dividend distributions.
**Solution:** Real-time payment processing with automated transfer capabilities.
**Result:** Reduced settlement times from 3 days to instant, improving user satisfaction by 60%.
## Getting Started
Create your free developer account and access our sandbox environment
Use our SDKs and APIs to build your payment flows
Thoroughly test all scenarios in our comprehensive sandbox
Deploy to production with full compliance and security
**Need custom solutions?** Our team works closely with fintech partners to build tailored payment infrastructure that scales with your business.
**Ready to revolutionize your fintech payments?**
Get started with our developer-friendly APIs
Discuss enterprise fintech solutions
# Remittance
Source: https://docs.payvessel.com/use-cases/remittance
Secure and affordable cross-border money transfer solutions
**Enable fast, affordable, and secure cross-border money transfers for individuals and businesses worldwide.**
The remittance industry requires solutions that prioritize speed, affordability, and compliance while serving diverse global communities.
Real-time money transfers to 35+ countries
Competitive rates with transparent pricing
***
## Why Remittance Companies Choose Payvessel
### π Global Network
Connect families and businesses across borders:
* Extensive network of banking partnerships worldwide
* Direct connections to major money transfer operators
* Mobile money integration in emerging markets
* Cash pickup locations in key corridors
### πΈ Competitive Economics
Offer better value to your customers:
* Wholesale foreign exchange rates
* Transparent fee structures
* Real-time rate displays
* Dynamic routing for best pricing
### π Regulatory Compliance
Stay compliant across all jurisdictions:
* Automated AML/KYC compliance
* Real-time sanctions screening
* Regulatory reporting for all transactions
* OFAC and international sanctions compliance
## Remittance Solutions
Personal money transfers for individuals and families
Corporate cross-border payments and supplier settlements
App-based transfers with mobile wallet integration
Cash-to-cash transfers through retail agent locations
Direct bank account transfers with correspondent banking
Instant transfers between debit cards globally
## Key Features
* **Real-time Transfers:** Instant money transfers in supported corridors
* **Same-day Settlement:** Next-best-thing to instant for traditional banking
* **99.9% Uptime:** Enterprise-grade infrastructure reliability
* **Transaction Tracking:** Real-time status updates for senders and recipients
* **Delivery Confirmations:** Automated notifications when funds are received
* **Transparent Fees:** Clear, upfront pricing with no hidden costs
* **Dynamic FX Rates:** Real-time exchange rates with competitive margins
* **Volume Discounts:** Better rates for high-volume senders
* **Promotional Rates:** Marketing tools for customer acquisition
* **Cost Comparison:** Help customers see savings vs. competitors
* **KYC Verification:** Digital identity verification with document scanning
* **AML Monitoring:** Continuous transaction monitoring and reporting
* **Sanctions Screening:** Real-time checks against global watch lists
* **Data Protection:** GDPR and regional privacy law compliance
* **Audit Trails:** Complete transaction history for regulatory purposes
## Popular Remittance Corridors
### πΊπΈ From United States
* **Mexico:** Instant bank deposits and cash pickup locations
* **Philippines:** Mobile wallet and bank transfer options
* **India:** Real-time bank transfers and UPI integration
* **Nigeria:** Mobile money and bank account deposits
* **Guatemala:** Cash pickup network and bank transfers
### π¬π§ From United Kingdom
* **Nigeria:** Mobile money and banking partnerships
* **Ghana:** Mobile money and cash pickup options
* **Poland:** Instant bank transfers and cash pickup
* **Romania:** Real-time banking and mobile solutions
* **Pakistan:** Bank transfers and mobile wallet integration
### π Other Major Corridors
* **UAE to India/Pakistan:** Banking and mobile solutions
* **Saudi Arabia to Philippines:** OFW-focused transfer solutions
* **Kuwait to India:** Instant banking and digital wallet options
* **Germany to Turkey:** Bank-to-bank and mobile transfers
## Implementation Options
Build custom remittance applications using our comprehensive APIs
Launch quickly with our pre-built, customizable remittance platform
Connect with existing money transfer operators and expand your network
Establish cash pickup locations through our retail partner network
## Compliance Features
* Digital ID verification
* Document authentication
* Biometric verification
* Risk assessment scoring
* Automated CTR/SAR filing
* OFAC sanctions screening
* Transaction monitoring alerts
* Audit trail maintenance
## Success Stories
**Challenge:** A fintech startup wanted to launch a mobile remittance service targeting the US-Mexico corridor with competitive rates and instant transfers.
**Solution:** Leveraged Payvessel's API-first approach with real-time FX rates and instant settlement capabilities.
**Results:**
* Launched in 3 months vs. 18-month industry average
* 40% lower fees than traditional competitors
* 95% of transfers completed within 10 minutes
* 50,000+ registered users in first year
**Challenge:** An established remittance company needed to modernize their platform to compete with digital-first competitors.
**Solution:** Integrated Payvessel's modern API while maintaining existing agent network and compliance systems.
**Results:**
* 60% reduction in transaction processing time
* 30% increase in customer satisfaction scores
* 25% growth in transaction volume
* Maintained 100% regulatory compliance
## Getting Started
We help navigate money transmitter licensing requirements
Access our global network of banking and agent partners
**Regulatory Requirements:** Remittance businesses must obtain proper licensing in their operating jurisdictions. Our compliance team can help guide you through the requirements.
**Ready to revolutionize cross-border payments?**
Begin with our remittance API documentation
Discuss regulatory requirements with our experts
# Telecommunications
Source: https://docs.payvessel.com/use-cases/telecommunications
Payment solutions for telecom operators and mobile service providers
**Streamline billing, top-ups, and digital service payments for telecom operators and mobile service providers.**
Telecommunications companies need payment solutions that handle high-volume transactions, recurring billing, and diverse customer payment preferences.
Optimized for mobile users and on-the-go payments
Process millions of transactions with enterprise reliability
***
## Why Telecom Companies Choose Payvessel
### πΆ Mobile-Optimized Infrastructure
Built for the mobile-first telecom industry:
* USSD integration for feature phone users
* Mobile money and carrier billing support
* SMS payment confirmations and receipts
* Progressive web apps for cross-platform compatibility
### π° Recurring Billing Excellence
Manage subscription lifecycles efficiently:
* Automated recurring billing and renewals
* Failed payment retry logic and dunning management
* Flexible billing cycles and proration
* Subscription upgrade/downgrade handling
### π Global Reach
Serve customers across multiple markets:
* Multi-currency billing and payments
* Local payment method integration
* Regional compliance and tax handling
* Cross-border revenue settlement
## Telecom Payment Solutions
Monthly billing and automated payment collection
Instant airtime and data bundle purchases
OTT platforms, streaming, and value-added services
Mobile wallet services and financial products
Device connectivity and M2M service billing
B2B telecom services and bulk billing
## Key Features for Telecom
* **Automated Billing Cycles:** Daily, weekly, monthly, and custom cycles
* **Proration Handling:** Automatic calculations for mid-cycle changes
* **Failed Payment Recovery:** Intelligent retry logic with dunning campaigns
* **Subscription Analytics:** Customer lifetime value and churn analysis
* **Billing Notifications:** SMS and email alerts for upcoming charges
* **Carrier Billing:** Direct carrier billing for digital services
* **USSD Integration:** \*123# style payments for feature phones
* **Mobile Money:** MTN Mobile Money, M-Pesa, Orange Money support
* **SMS Payments:** Text-to-pay for simple transactions
* **App-based Payments:** In-app purchase flows for mobile applications
* **Dynamic Pricing:** Real-time pricing adjustments based on demand
* **Promotional Campaigns:** Discount codes and promotional pricing
* **Usage-based Billing:** Pay-per-use and tiered pricing models
* **Revenue Sharing:** Automated partner and affiliate commission payments
* **Analytics Dashboard:** Real-time revenue and payment performance insights
## Use Cases by Service Type
### π± Mobile Network Operators (MNOs)
Seamless SIM activation with payment collection and KYC verification
Real-time airtime top-ups, data bundles, and service activations
Automated monthly billing with flexible payment options
Premium SMS, ringtones, mobile insurance, and digital content
### π Internet Service Providers (ISPs)
* **Broadband Billing:** Monthly internet service billing and upgrades
* **Installation Fees:** One-time setup and equipment charges
* **Overage Charges:** Usage-based billing for data overages
* **Service Bundles:** TV, internet, and phone package billing
### πΊ OTT and Digital Services
* **Streaming Subscriptions:** Video and music streaming service billing
* **Gaming Services:** In-game purchases and subscription management
* **Cloud Services:** Storage and software-as-a-service billing
* **Educational Content:** E-learning platform and course payments
## Regional Payment Methods
* M-Pesa (Kenya, Tanzania)
* MTN Mobile Money (Multi-country)
* Orange Money (West Africa)
* Airtel Money (East Africa)
* Alipay and WeChat Pay (China)
* GrabPay (Southeast Asia)
* UPI (India)
* GCash (Philippines)
## Integration Options
Full API integration for custom billing systems and customer portals
\*123# style payments for feature phones and unbanked customers
Text-based payment flows with automatic confirmation and receipts
Customer self-service portals for bill payments and account management
## Success Stories
**Challenge:** A West African mobile operator needed to increase prepaid top-up rates and reduce customer churn due to payment friction.
**Solution:** Integrated multiple mobile money providers with USSD fallback for feature phone users.
**Results:**
* 75% increase in successful top-up attempts
* 40% reduction in customer churn
* 300% increase in mobile money transaction volume
* Support for 15+ local payment methods
**Challenge:** A streaming service wanted to expand across emerging markets but struggled with local payment acceptance and failed subscriptions.
**Solution:** Implemented carrier billing and mobile money with intelligent payment retry logic.
**Results:**
* Expanded to 8 new markets in 6 months
* 85% reduction in failed subscription payments
* 200% increase in subscriber base
* 60% improvement in customer lifetime value
## Compliance and Security
* PCI DSS compliance for card transactions
* Telecom-grade encryption standards
* Fraud detection for high-volume transactions
* SIM card security integration
* Telecom billing regulations compliance
* Customer data protection (GDPR, etc.)
* Financial services regulations
* Local tax and levy collection
**Telecom Expertise:** Our team understands telecom billing cycles, customer acquisition costs, and the unique challenges of serving diverse customer bases across different markets.
**Ready to optimize your telecom payments?**
Start with our telecom-focused API documentation
Speak with our telecommunications specialists
# Travel and Hospitality
Source: https://docs.payvessel.com/use-cases/travel-and-hospitality
Seamless payment solutions for the travel and hospitality industry
**Deliver frictionless payment experiences that keep travelers moving and guests satisfied.**
The travel industry demands payment solutions that work across borders, currencies, and cultures while providing exceptional user experiences.
Accept payments from travelers worldwide
Process payments in 35+ currencies with real-time conversion
***
## Why Travel Companies Choose Payvessel
### π Worldwide Payment Acceptance
Cater to international travelers with:
* Local payment methods in key travel markets
* Dynamic currency conversion at checkout
* Mobile-optimized payment flows
* Offline payment capabilities for remote locations
### β‘ Fast Settlement
Keep cash flow healthy with:
* Same-day settlements available
* Automated split payments for bookings
* Real-time transaction monitoring
* Flexible payout schedules
### π Secure Transactions
Protect customer data and build trust:
* PCI DSS compliance for card data security
* 3D Secure authentication
* Advanced fraud detection
* Chargeback protection and management
## Industry Solutions
Streamlined booking and check-in payment processes
Ticket purchases, ancillary services, and loyalty programs
Vehicle bookings, deposits, and damage fee processing
Cabin bookings, onboard purchases, and excursion payments
Activity bookings, group payments, and commission handling
Property bookings, security deposits, and host payouts
## Key Features
* Credit and debit cards (Visa, Mastercard, Amex)
* Digital wallets (Apple Pay, Google Pay, PayPal)
* Bank transfers and local payment methods
* Buy now, pay later options
* Cryptocurrency payments (Bitcoin, Ethereum)
* Responsive checkout flows
* One-click payments for repeat customers
* QR code payments for contactless transactions
* Mobile wallet integration
* Progressive web app support
* Multi-currency pricing and display
* Real-time exchange rate conversion
* Local tax calculation and compliance
* Regional payment method preferences
* Localized checkout experiences
## Use Cases by Business Type
### π¨ Hotels and Accommodations
Secure online bookings with instant confirmation and automated receipts
Express check-in with pre-authorized payments and upselling opportunities
In-room dining, spa services, and activity bookings through mobile apps
Split payment options for group reservations and event bookings
### βοΈ Airlines and Transportation
* **Ticket Sales:** Multi-currency booking with dynamic pricing
* **Ancillary Revenue:** Seat upgrades, baggage fees, and meal selections
* **Loyalty Programs:** Point redemption and co-branded credit card integration
* **Corporate Travel:** B2B payment terms and automated expense reporting
### π― Travel Agencies and OTAs
* **Multi-Supplier Payments:** Automated commission splits to hotels, airlines, and activities
* **Automated Transfers:** Process instant refunds and vendor settlements with the Transfers API.
* **Customer Flexibility:** Payment plans and installment options for expensive trips
* **Refund Management:** Automated refund processing for cancellations
* **White-Label Solutions:** Branded payment experiences for partner agencies
## Success Stories
**Challenge:** A boutique hotel chain needed to reduce no-shows and streamline the check-in process while accepting international payments.
**Solution:** Implemented Payvessel's pre-authorization system with mobile check-in capabilities.
**Results:**
* 40% reduction in no-shows with guaranteed reservations
* 60% faster check-in process
* 25% increase in ancillary service bookings
* Support for guests from 50+ countries
**Challenge:** An adventure tourism company struggled with international payment acceptance and group booking management.
**Solution:** Multi-currency checkout with split payment capabilities for group leaders.
**Results:**
* 80% increase in international bookings
* Simplified group payment collection
* 95% reduction in payment-related customer service inquiries
## Getting Started
Explore our hotel and accommodation payment features
Discover airline and transportation payment capabilities
**Industry Expertise:** Our travel and hospitality specialists understand the unique challenges of seasonal businesses, international customers, and complex booking scenarios.
**Ready to enhance your guest payment experience?**
Begin with our travel-focused quick start guide
Speak with our travel industry experts
# Virtual Account API
Source: https://docs.payvessel.com/virtual-accounts/create-virtual-account
PayVessel virtual account API to create STATIC or DYNAMIC Nigerian virtual bank accounts for customer bank transfer collections.
The PayVessel **virtual account API** creates a unique virtual bank account for each customer so they can pay you by direct bank transfer without a checkout redirect.
**Supported banks for virtual accounts:**
| Bank | Code |
| --------------------- | -------- |
| PalmPay | `999991` |
| 9Payment Service Bank | `120001` |
| Rubies MFB | `090175` |
## How it works
1. **Send a request** with the customer's name, email, and any required identity fields.
2. **Receive a virtual account**: bank name, account number, and account name.
3. **Share the details** with your customer so they can pay via bank transfer.
4. **Receive a webhook** when funds land on the account.
## Use cases
* Dedicated accounts for individual customers
* Collections for invoices or subscriptions
* E-commerce order payments without a redirect
Full request/response details
# Get Virtual Account
Source: https://docs.payvessel.com/virtual-accounts/get-virtual-account
Retrieve Nigerian virtual account details by ID using the PayVessel virtual account API.
Fetch the details of a previously created virtual account by its identifier.
## How it works
1. **Provide the virtual account ID** in the request.
2. **Receive the account details**: account number, bank name, account name, and status.
## When to use
* Display account details to a returning customer
* Confirm an account is still active before sharing it
* Reconcile virtual accounts in your dashboard
Full request/response details
# Create a Card
Source: https://docs.payvessel.com/virtual-cards/create-customer-card
Create a USD virtual card for a customer (asynchronous)
This resource allows you to create a card for a customer. PayVessel debits your business USD wallet, completes customer KYC, and returns a card you can fund and manage through the API.
This operation is **asynchronous**, meaning we notify you via a **webhook event** on the final status (for example when the card becomes `ACTIVE`). You can also poll [Get a Card](/virtual-cards/get-card) until `card_number` is available.
**Supported card networks:**
| Network | `brand` value |
| ---------- | ------------- |
| Visa | `VISA` |
| Mastercard | `MASTERCARD` |
Currency must be `USD`. Minimum prefund is **\$1.00**.
Set `is_contactless` to `true` to issue a contactless-enabled card (tap-to-pay). Defaults to `false` for a standard virtual card. Contactless cards may have a different issuance fee.
## How it works
1. **Send a request** with full customer KYC and card details (`brand`, `currency`). Optionally include `prefund_amount` to fund the card on creation.
2. **PayVessel debits** your business USD wallet (issuance + prefund fees apply).
3. **Receive a card** in `PENDING` status with a PayVessel `card_id`.
4. **Wait for the final status** via your webhook handler, or poll [Get a Card](/virtual-cards/get-card) until `status` is `ACTIVE`.
## Required request fields
| Field | Required | Notes |
| --------------------------------------- | -------- | -------------------------------------------------------------------------------- |
| `first_name`, `last_name` | Yes | Customer legal name |
| `email`, `phone` | Yes | Nigerian phone format |
| `bvn`, `nin` | Yes | 11 digits each |
| `dob` | Yes | `YYYY-MM-DD` |
| `image` | Yes | Base64 identity document (JPEG or PNG) |
| `state`, `lga`, `street`, `postal_code` | Yes | Nigerian address |
| `brand`, `currency` | Yes | USD only |
| `is_contactless` | No | `false` (default) for standard virtual card; `true` for contactless-enabled card |
| `prefund_amount` | No | Optional; minimum **\$1 USD** when provided |
| `card_name` | Optional | Label on card (max 255 characters) |
## Use cases
* Issue virtual cards for marketplace sellers or wallet users
* Prefund cards for subscription or travel spend
* Onboard customers with full KYC in one API call
## Example request
```json theme={null}
{
"first_name": "Jane",
"last_name": "Doe",
"email": "jane.doe@example.com",
"phone": "08031234567",
"bvn": "22345678901",
"nin": "12345678901",
"dob": "1990-05-15",
"image": "data:image/jpeg;base64,YOUR_BASE64_IDENTITY_IMAGE",
"state": "Lagos",
"lga": "Ikeja",
"street": "12 Admiralty Way, Lekki Phase 1",
"postal_code": "101233",
"brand": "VISA",
"currency": "USD",
"is_contactless": false,
"prefund_amount": "10.00",
"card_name": "Jane Doe"
}
```
### Contactless card
Set `is_contactless` to `true` to issue a contactless-enabled card:
```json theme={null}
{
"first_name": "Jane",
"last_name": "Doe",
"email": "jane.doe@example.com",
"phone": "08031234567",
"bvn": "22345678901",
"nin": "12345678901",
"dob": "1990-05-15",
"image": "data:image/jpeg;base64,YOUR_BASE64_IDENTITY_IMAGE",
"state": "Lagos",
"lga": "Ikeja",
"street": "12 Admiralty Way, Lekki Phase 1",
"postal_code": "101233",
"brand": "VISA",
"currency": "USD",
"is_contactless": true,
"prefund_amount": "10.00",
"card_name": "Jane Doe"
}
```
Run this endpoint in the browser (interactive playground)
# Freeze a Card
Source: https://docs.payvessel.com/virtual-cards/freeze-card
Temporarily block card spend
Temporarily block new authorizations on an **ACTIVE** card. Funding and other operations may still be restricted while frozen.
## How it works
1. **Call freeze** with the target `card_id`.
2. **PayVessel blocks spend**: new merchant charges are declined.
3. **Unfreeze** when the customer should spend again.
## When to use
* Suspected fraud or lost device
* Customer-requested pause
* Compliance hold before investigation
Full request/response details and Try it
# Fund a Card
Source: https://docs.payvessel.com/virtual-cards/fund-card
Load USD from your business wallet onto a virtual card
Move USD from your PayVessel **business USD wallet** onto a customerβs virtual card. Funding fees apply; PayVessel holds the spendable card balance.
Minimum fund amount is **\$1.00 USD** per request.
## How it works
1. **Confirm wallet balance** can cover amount + funding fee.
2. **POST the fund amount** (minimum `1.00` USD) with the target `card_id`.
3. **Card balance updates** on the card object; use [Get a Card](/virtual-cards/get-card) to read the current balance.
## When to use
* Top up a card after the initial prefund
* Replenish spend limits for recurring customers
* Move float from your business wallet to card programs
Full request/response details and Try it
# Get a Card
Source: https://docs.payvessel.com/virtual-cards/get-card
Retrieve one issued virtual card by ID
Fetch the current state of a single virtual card: status, balance, customer linkage, and **full card credentials** when the card is ready.
## How it works
1. **Provide the PayVessel `card_id`** returned from create (or list).
2. **Receive the card object**: PayVessel syncs status and balance when needed.
3. **Poll after create** until `status` is `ACTIVE`: then `card_number`, `cvv`, and `expiry` are included in the response.
## Response fields (ACTIVE / FROZEN)
| Field | Description |
| ------------- | -------------------------------- |
| `card_number` | Full PAN (spaces every 4 digits) |
| `cvv` | Card verification value |
| `expiry` | Expiration (`MM/YY`) |
While `status` is `PENDING`, card credentials are omitted: poll until `ACTIVE`.
## Sample response (ACTIVE)
```json theme={null}
{
"status": true,
"message": "Virtual card retrieved successfully",
"data": {
"id": "7f219a25-d968-4894-9a8b-ba83fa0bf6ec",
"business_id": "8f926b04-e63a-4449-b346-ea922b69e20e",
"kind": "customer",
"customer_id": "5e6bda15-1090-4cfe-bc1d-861990947bbc",
"customer_name": "MUSA GANIYU",
"business_name": null,
"card_name": "Ganiyu Musa",
"status": "ACTIVE",
"currency": "USD",
"brand": "MASTERCARD",
"balance": "3.00",
"expiry": "08/31",
"card_number": "5573 5078 9962 7848",
"cvv": "123",
"created_datetime": "2026-05-24T00:38:02.543669",
"updated_datetime": "2026-05-24T03:20:19.331923"
}
}
```
Treat `card_number` and `cvv` as highly sensitive. Do not log them or store them in plaintext.
## When to use
* Poll activation after [Create a Card](/virtual-cards/create-customer-card)
* Show the virtual card to your end user in your app
* Confirm freeze/terminate status before the next action
Full request/response details and Try it
# Get all Cards
Source: https://docs.payvessel.com/virtual-cards/list-cards
List customer virtual cards for your business
List every **customer** and **business** virtual card issued under your business. Filter by lifecycle status when you only need active or pending cards.
List responses include `masked_pan` only. For full `card_number` and `cvv`, call [Get a Card](/virtual-cards/get-card) on a single `card_id`.
## How it works
1. **Call the list endpoint** with your API credentials (no body).
2. **Optionally filter** with `status` (`PENDING`, `ACTIVE`, `FROZEN`, `TERMINATED`, `FAILED`).
3. **Receive an array** of card objects with `id`, `kind`, `status`, `masked_pan`, and `balance`.
## When to use
* Populate a cards dashboard for your merchants
* Find a `card_id` before fund, withdraw, or freeze
* Reconcile how many cards are active vs terminated
## Sample response
```json theme={null}
{
"status": true,
"message": "Virtual cards retrieved successfully",
"data": [
{
"id": "7f219a25-d968-4894-9a8b-ba83fa0bf6ec",
"business_id": "8f926b04-e63a-4449-b346-ea922b69e20e",
"kind": "customer",
"customer_id": "5e6bda15-1090-4cfe-bc1d-861990947bbc",
"customer_name": "MUSA GANIYU",
"business_name": null,
"card_name": "Ganiyu Musa",
"masked_pan": "557350******7848",
"status": "ACTIVE",
"currency": "USD",
"brand": "MASTERCARD",
"balance": "3.00",
"expiry": "08/31",
"created_datetime": "2026-05-24T00:38:02.543669",
"updated_datetime": "2026-05-24T03:20:19.331923"
},
{
"id": "a0e7ed8b-bbb7-48d2-81e1-d76d98965006",
"business_id": "8f926b04-e63a-4449-b346-ea922b69e20e",
"kind": "customer",
"customer_id": "5e6bda15-1090-4cfe-bc1d-861990947bbc",
"customer_name": "MUSA GANIYU",
"business_name": null,
"card_name": "Ganiyu Musa",
"masked_pan": "227449******4392",
"status": "TERMINATED",
"currency": "USD",
"brand": "VISA",
"balance": "0.00",
"expiry": "08/31",
"created_datetime": "2026-05-22T21:35:08.115964",
"updated_datetime": "2026-05-22T21:35:50.942942"
},
{
"id": "aae598cc-99d9-4730-80f5-4044d49bba75",
"business_id": "8f926b04-e63a-4449-b346-ea922b69e20e",
"kind": "business",
"customer_id": null,
"customer_name": null,
"business_name": "Nex Panther Technologies",
"card_name": "MARKETING CARD",
"masked_pan": "222980******7461",
"status": "TERMINATED",
"currency": "USD",
"brand": "MASTERCARD",
"balance": "0.00",
"expiry": "08/31",
"created_datetime": "2026-05-22T20:29:31.615688",
"updated_datetime": "2026-05-24T02:05:56.229932"
}
]
}
```
The live response may include more cards in `data`; each object uses the same shape.
Full request/response details and Try it
# Get Card Transactions
Source: https://docs.payvessel.com/virtual-cards/list-transactions
Transaction history for a virtual card
View spend, funding, withdrawal, and fee activity for a single card. History is recorded from PayVessel webhooks and API operations.
## How it works
1. **Provide the `card_id`** for the card you want history for.
2. **Optionally set `size`** (default 50, maximum 100).
3. **Receive transactions** with amount, entry (debit/credit), status, merchant, and timestamps.
## When to use
* Show card activity in your customer portal
* Reconcile spends against card transaction history
* Support disputes using the transaction `id` (same value as `ref_id`)
Full request/response details and Try it
# Simulate Card Transaction
Source: https://docs.payvessel.com/virtual-cards/mock-transaction
Sandbox-only test spend and credits on virtual cards
Use this endpoint to **test card spend and transaction history** without real merchant charges. PayVessel records the simulation via webhook and updates the card balance.
**Sandbox only.** Not exposed in production. Your integration should only call this when using sandbox API keys and `https://sandbox.payvessel.com`.
## How it works
1. **Create and activate** a card ([Create a Card](/virtual-cards/create-customer-card), then poll [Get a Card](/virtual-cards/get-card) until `ACTIVE`).
2. **POST a simulation** with `amount` and `type` (`DEBIT` or `CREDIT`).
3. **PayVessel processes the event**: the transaction is recorded and the card balance is refreshed.
4. **Verify** with [Get Card Transactions](/virtual-cards/list-transactions).
## Request fields
| Field | Required | Description |
| -------- | -------- | --------------------------------------------------- |
| `amount` | Yes | USD amount (e.g. `"1.50"`) |
| `type` | No | `DEBIT` (default) = spend; `CREDIT` = refund/credit |
## When to use
* End-to-end testing of spend notifications in your app
* QA of transaction lists and balances in sandbox
* Demo environments without real card networks
## Limitations
* Card must be **ACTIVE** (not pending activation)
* Balance shown in the response may change again after the webhook syncs
* Production requests return a validation error
Run this endpoint in the browser (sandbox)
# Virtual Card API
Source: https://docs.payvessel.com/virtual-cards/overview
PayVessel virtual card API to issue USD Visa and Mastercard cards, fund from your wallet, withdraw, freeze, and receive webhooks for card transactions.
PayVessel **virtual card API** lets you issue **USD virtual cards** (Visa and Mastercard) so your customers can pay online at international merchants. You integrate through the **PayVessel API** using your business **API key** and **secret**; PayVessel handles card enrollment, card lifecycle, and wallet debits for funding.
## Virtual cards
PayVessel issues virtual **Mastercard** and **Visa** cards in **USD** that work on all platforms.
| | |
| ------------------------- | --------------------------------------------------------------- |
| **Validity** | 3 years |
| **Limit per transaction** | \$10,000 |
| **Card balance limit** | \$100,000 |
| **Repeated declines** | Card is terminated after **8** declines within **24 hours** |
| **Unfunded cards** | Card is terminated if not funded within **3 weeks** of creation |
## Where can cards be used?
PayVessel virtual **USD** cards are accepted at merchant sites that accept USD cards: commonly US merchants such as Meta (Facebook), PayPal, Google, Snap Inc., Canva, and many more.
Some merchants may decline the card. Restrictions are identified by **MCC** (Merchant Category Code). The following MCCs are **not supported**:
| MCC | Description |
| ---- | ---------------------------------------------------- |
| 4829 | Money Transfers |
| 5962 | Travel Related Arrangement Services |
| 5966 | Outbound Telemarketing Merchants |
| 6051 | Non-Financial Institutions / Cryptocurrency |
| 6211 | Security Brokers / Dealers |
| 7273 | Dating and Escort Services |
| 7297 | Massage Parlors |
| 7800 | Government-owned Lotteries |
| 7801 | Government-licensed Online Casinos (Online Gambling) |
| 7802 | Government-licensed Horse/Dog Racing |
| 7995 | Betting and Online Gambling |
### Restricted countries
Cards cannot be used in countries subject to geographic sanctions, including:
Algeria, Afghanistan, Belarus, Burundi, Central African Republic, Comoros, Congo (Democratic Republic of the), Congo (Republic of the), Cuba, Gambia, Iran, Iraq, Korea (North), Kyrgyzstan, Lebanon, Liberia, Libya, Maldives, Myanmar, Nicaragua, Palestine, Russian Federation, Serbia, Somalia, South Sudan, Sudan, Suriname, Svalbard and Jan Mayen, Syrian Arab Republic, Tajikistan, Togo, Tokelau, Turkmenistan, Ukraine, Uzbekistan, Venezuela, Wallis and Futuna, Yemen, and Zimbabwe.
If you encounter acceptance issues, contact [support@payvessel.com](mailto:support@payvessel.com).
Issue with KYC and prefund
List cards and status
Load USD from business wallet
***
## What you can do
| Capability | Description |
| ------------------------ | ----------------------------------------------------------------------------------------------- |
| **Create customer card** | Enroll or upgrade customer KYC, issue a USD virtual card, prefund from your business USD wallet |
| **List / get card** | Track `PENDING` β `ACTIVE`, masked PAN, card balance |
| **Fund card** | Debit business USD wallet; credit the card balance |
| **Withdraw** | Move USD from card back to business wallet (minimum \$3) |
| **Freeze / unfreeze** | Temporarily block or restore card spend |
| **Terminate** | Close card; remaining balance returns to business wallet (minus fees) |
| **Transactions** | Card spend, funding, and withdrawal history |
| **Simulate transaction** | Sandbox-only test spend/credit simulation |
***
## Customer KYC
The PayVessel API requires **full Nigerian KYC on every create request**.
| Field | Required | Notes |
| --------------------------------------- | -------- | ------------------------------------------- |
| `first_name`, `last_name` | Yes | Customer legal name |
| `email`, `phone` | Yes | Nigerian phone format |
| `bvn`, `nin` | Yes | 11 digits |
| `dob` | Yes | `YYYY-MM-DD` |
| `image` | Yes | Base64 identity image |
| `state`, `lga`, `street`, `postal_code` | Yes | Address |
| `brand`, `currency` | Yes | USD only |
| `prefund_amount` | No | Optional; minimum **\$1 USD** when provided |
***
## Money movement
**Fund** and **create-time prefund** debit your PayVessel **business USD wallet** (managed wallet). **Withdraw** and **terminate** credit it back (withdrawal fee may apply).
PayVessel holds and syncs the spendable `balance` on the card object after fund, withdraw, and card activity. Do not assume your local ledger matches the API balance without calling **Get card**.
Merchant charges (AUTHORIZATION, SETTLEMENT, etc.) reduce **card balance**. PayVessel will charge applicable fees to your business USD wallet.
***
## Card statuses
| Status | Meaning |
| ------------ | ---------------------------------------------------- |
| `PENDING` | PayVessel is provisioning the card; no PAN yet |
| `ACTIVE` | Card can be funded and used |
| `FROZEN` | Spend blocked; fund/withdraw may still be restricted |
| `TERMINATED` | Closed; balance settled to wallet |
| `FAILED` | Card creation failed |
***
## Fees
Funding fee tiers:
* Below tier threshold: flat fee in USD
* At or above tier: percentage of fund amount
***
## Error handling
| HTTP | Typical cause |
| ----- | -------------------------------------------------------------- |
| `401` | Missing or invalid `api-key` / `api-secret` |
| `400` | Validation (KYC, minimum amounts, insufficient wallet balance) |
| `404` | Unknown `card_id` for your business |
| `429` | API rate limit |
Responses use `{ "status": true|false, "message": "...", "data": ... }`. Validation errors may include a `errors` object.
***
## Security best practices
Never persist `card_number`, `cvv`, or `expiry` in your database, cache, session storage, or mobile secure storage. Store only the PayVessel `card_id` and non-sensitive metadata (status, `masked_pan` from list).
When your customer must view or use the card, call [Get a Card](/virtual-cards/get-card) from your **backend** at that moment. Return credentials to your client over HTTPS only for the active session: do not keep them after the user leaves the screen.
Never call the PayVessel API from a mobile app or browser with `api-key` / `api-secret`. All create, fund, and credential retrieval flows must run on your server.
Do not write PAN, CVV, or expiry to application logs, crash reports, analytics, webhooks you forward, or support tickets. Redact these fields in any debug output.
***
## Guides and API reference
Conceptual guides (how it works, use cases) live under **Guides β Issuing**. Technical schemas, **Try it**, and cURL samples live under **API reference β Issuing**.
Events and transaction types
Guide
API reference
API reference
# Terminate Card
Source: https://docs.payvessel.com/virtual-cards/terminate-card
Permanently close a virtual card
Permanently close a virtual card. Remaining balance is returned to your business USD wallet where applicable. **This cannot be undone.**
## How it works
1. **Call terminate** with the `card_id`.
2. **PayVessel closes the card**: status becomes `TERMINATED`.
3. **Remaining balance** settles to your business wallet (fees may apply).
## When to use
* Customer offboarding
* End of a card program for one user
* Recover all float after withdraw is impractical
Full request/response details and Try it
# Unfreeze a Card
Source: https://docs.payvessel.com/virtual-cards/unfreeze-card
Restore spend on a frozen card
Restore spending on a **FROZEN** card so the customer can authorize merchants again.
## How it works
1. **Call unfreeze** with the `card_id`.
2. **PayVessel restores spend**: status returns to `ACTIVE` when successful.
## When to use
* Customer confirms card is safe to use again
* End of a temporary compliance hold
* After resolving a false-positive fraud alert
Full request/response details and Try it
# Virtual Card Webhooks
Source: https://docs.payvessel.com/virtual-cards/webhooks
Virtual card API webhooks for card creation, transactions, funding, withdrawal, termination, and issuing events.
PayVessel sends webhooks when virtual cards are created, used at merchants, funded, withdrawn, or terminated. Configure your webhook URL in the PayVessel Dashboard and verify every payload before updating balances or order status in your system.
See [Verifying Webhooks](/api-reference/webhook/verifying-webhooks) for signature checks, trusted IPs, and idempotent handling.
These are example webhook responses for virtual card issuing.
```json theme={null}
{
"event": "issuing.transaction",
"card_id": "7b231d95-9006-4e53-a08c-dbe3b4d3ab4d",
"reference": "dd7412f3-aa14-4a77-94b5-a26f3cfb-56c",
"amount": 80,
"currency": "USD",
"mode": "DEBIT",
"status": "SUCCESS",
"type": "AUTHORIZATION",
"description": "Approved or completed successfully",
"fee": 0,
"settled": false,
"merchant": {
"city": "Lagos",
"country": "NG",
"name": "DLO*GOOGLE TikTok Liv"
},
"created_at": "2023-12-11T21:22:32.312347102Z",
"updated_at": "2023-12-11T21:22:32.312350944Z"
}
```
```json theme={null}
{
"event": "issuing.created.successful",
"reference": "your-create-reference",
"card": {
"id": "fe796aef-5dca-47d5-a542-16d403b464d1",
"name": "JOHN DOE",
"masked_pan": "536898******1914",
"type": "VIRTUAL",
"brand": "VISA",
"currency": "USD",
"status": "ACTIVE",
"balance": 0,
"auto_approve": true
}
}
```
```json theme={null}
{
"event": "issuing.created.failed",
"reference": "your-create-reference"
}
```
```json theme={null}
{
"event": "issuing.terminated",
"card_id": "700865ae-af75-4b6b-b09d-1ecb16753dee",
"amount": 120,
"reason": "Insufficient Funds",
"reference": "61a85f53-6e67-434d-9b6d-fa1d4c7c2f68"
}
```
```json theme={null}
{
"event": "issuing.charge",
"card_id": "32244f-3ac0-431d-9fb0-43f72505",
"amount": 30,
"transaction_date": "2024-12-17T09:26:42.243416144Z"
}
```
```json theme={null}
{
"event": "issuing.activation",
"card_id": "fb2f92a8-cac2-4bae-91ee-f0e7c91c409c",
"activation_code": "866026"
}
```
Match cards using `reference` from create (lifecycle events) or `card_id` in the payload (transaction and termination events). Store PayVessel `card_id` from the API for your own lookups.
***
## Transaction types
These are the possible transaction types on `issuing.transaction`:
* **AUTHORIZATION**: When a card is successfully used at a merchant site.
* **SETTLEMENT**: When a card is successfully used and settlement is completed at a merchant site.
* **FUNDING**: When the card is funded via [Fund a Card](/virtual-cards/fund-card) or create-time prefund.
* **WITHDRAWAL**: When funds are withdrawn from the card via [Withdraw from Card](/virtual-cards/withdraw-card).
* **TERMINATION**: When a card is terminated (also available from the PayVessel Dashboard).
* **DECLINE**: When an attempt to use the card at a merchant site is rejected (for example insufficient balance).
* **REVERSAL**: When a merchant charges a card but immediately returns that amount to the card.
* **REFUND**: When a reversal does not complete as expected and funds erroneously debited are returned.
* **CROSS-BORDER**: Cross-border use at merchants outside the US or when authorization currency is not USD.
`mode` can only be **`CREDIT`** or **`DEBIT`**.
***
## Card transaction events (`card.transaction`)
PayVessel also sends `card.transaction` to the webhook URL on your business. Use `event_type` to decide what to do.
| `event_type` | When it fires | Suggested action |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| `settlement` | Spend settled on the card | Append to history; refresh card balance |
| `decline` | Spend declined (for example insufficient card balance) | Show the decline to your customer |
| `termination` | Card terminated | Mark the card terminated |
| `contactless_fee` | Miden billed a contactless payment fee that the **card could not pay** (usually insufficient balance). PayVessel debits your USD wallet instead. | Debit your customer for `amount`. `charged_from` is `merchant_wallet`. |
| `cross_border_fee` | Same recovery path for a cross-border / FX fee Miden could not take from the card | Debit your customer for `amount` |
### Contactless and cross-border fee recovery
Miden sometimes cannot collect contactless or cross-border fees from the card (the card is below the amount, or would drop under the \$1 retain). They still bill PayVessel. PayVessel then:
1. Debits the **issuing merchant USD wallet** for the same fee amount
2. Sends you a `card.transaction` webhook so you can recover it from your customer
Treat `reference` as idempotent β the same event is not charged twice.
```json theme={null}
{
"event": "card.transaction",
"card_id": "7b231d95-9006-4e53-a08c-dbe3b4d3ab4d",
"reference": "MIDEN_ISSUER_FEE_evt-contactless-1",
"event_type": "contactless_fee",
"status": "successful",
"amount": "0.50",
"currency": "USD",
"balance_after": "1.20",
"merchant_name": "Merchant",
"description": "Contactless payment fee charged to merchant wallet β card had insufficient balance",
"fee_type": "contactless_payment",
"charged_from": "merchant_wallet",
"reason": "insufficient_card_balance",
"created_at": "2026-08-20T08:15:00.000000+00:00",
"message": "Success",
"code": "00"
}
```
Cross-border recovery uses `event_type` `cross_border_fee` and `fee_type` `cross_border`. If your USD wallet cannot cover the fee, `status` is `failed`. Fund the wallet and expect a retry of the same `reference`, or recover the amount from your customer.
***
## What to do on each event
| Event | Suggested action |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `issuing.created.successful` | Mark card active; show masked PAN; poll [Get a Card](/virtual-cards/get-card) if you need full credentials. |
| `issuing.created.failed` | Mark card `FAILED`; surface error to customer or retry create. |
| `issuing.transaction` / `issuing.charge` | Append to transaction history; refresh balance via [Get a Card](/virtual-cards/get-card) or [Get Card Transactions](/virtual-cards/list-transactions). |
| `issuing.terminated` | Mark card `TERMINATED`; expect wallet credit for remaining balance where applicable. |
Query normalized transaction history from the API
# Withdraw from a Card
Source: https://docs.payvessel.com/virtual-cards/withdraw-card
Move USD from a virtual card back to your business wallet
Return USD from a customerβs virtual card to your PayVessel **business USD wallet**. A minimum of **\$3.00** applies per withdrawal; withdrawal fees may apply.
## How it works
1. **Check card balance** via [Get a Card](/virtual-cards/get-card).
2. **POST the withdrawal amount** (minimum `3.00` USD).
3. **PayVessel debits the card** and credits your business wallet; balance syncs on the card object.
## When to use
* Recall unused float from a card program
* Partially move funds back before terminate
* Rebalance between card balance and business wallet
Full request/response details and Try it
# Get Wallets
Source: https://docs.payvessel.com/wallets/get-wallets
Guide: listing and retrieving wallets
Use the wallets listing endpoints when you have **multiple managed wallets** and need to:
* Show all wallets and balances in an internal dashboard.
* Find a specific wallet by ID or business identifier.
* Reconcile transfers across several wallets.
Typical usage:
1. List all wallets for your business.
2. Filter in your application by currency, label, or purpose.
3. Drill down into a specific wallet using its ID in the balance or statement endpoints.
For the technical details and code samples, use **API reference β Wallets β Get Wallets**.
# Wallets Overview
Source: https://docs.payvessel.com/wallets/overview
Managed external wallets for holding and moving funds
Use managed wallets to **hold balances for your business**, fund transfers, and reconcile payouts. A simple flow is:
1. Get your available wallets.
2. Check wallet balance before sending payouts.
3. Use transfer endpoints to move funds.
4. Reconcile wallet activity in your reporting flow.
How to read available and ledger balances
Working with multiple wallets
***
## Key concepts
* **Business wallet**: primary wallet linked to your merchant account, used for most payouts.
* **Available balance**: funds you can spend immediately.
* **Ledger balance**: available balance plus pending transactions.
* **Transactions**: credits (funding, incoming payments) and debits (transfers, fees).
For request/response payloads and code samples, use the **API reference β Wallets** section. For payout flows that use wallets, see **Send Money & Payouts β Transfers**.
# Wallet Balance
Source: https://docs.payvessel.com/wallets/wallet-balance
Guide: understanding wallet balances
Use the wallet balance endpoint to see **how much money is available** in a managed wallet before triggering payouts.
Key fields youβll see in responses:
* **available\_balance**: funds you can spend immediately.
* **ledger\_balance**: available balance plus pending debits/credits.
* **currency**: currency of the wallet (e.g. `NGN`).
Typical flow:
1. Call the wallet-balance endpoint with your `api-key` and `api-secret` headers.
2. Compare `available_balance` to the amount you plan to move.
3. Block or allow the transfer based on your own rules and limits.
For the exact endpoint path, headers, and JSON schema, see **API reference β Wallets β Wallet Balance**.