VYPay API Documentation

Base URL: https://vypay.xyz/api/v1

Getting Started

The VYPay API now focuses on account visibility and wallet-to-wallet transfers. Responses are JSON encoded and all requests must be sent over HTTPS.

Authentication

The VYPay API supports two authentication methods:

Method 1: Bearer Token (Recommended)

Use an API token in the Authorization header. Tokens can have specific permissions and can be managed from the Token Management page.

Authorization: Bearer vypay_your_token_here

Benefits: Secure, revocable, permission-scoped, and doesn't expose your password.

Method 2: Email and Password

Include your VYPay credentials in the JSON request body. This method grants full access to all endpoints.

{
    "email": "you@example.com",
    "password": "your-password"
}

Note: You can mix credentials with endpoint parameters in the same payload.

Token Permissions

When using Bearer tokens, access is restricted based on granted permissions:

API Endpoints

Account

POST /account/balance.php

Return the authenticated user's balance and basic profile data.

Required Permission: account.read

curl -X POST "https://vypay.xyz/api/v1/account/balance.php" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json"
const response = await fetch('https://vypay.xyz/api/v1/account/balance.php', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  }
});
const data = await response.json();
console.log(data);
$ch = curl_init('https://vypay.xyz/api/v1/account/balance.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "balance": 150.50,
    "currency": "VYC",
    "formatted": "150.50 VYC"
}
POST /account/update.php

Update mutable account fields such as name or email.

Required Permission: account.update

Request Body:
{
    "name": "New Display Name"
}
curl -X POST "https://vypay.xyz/api/v1/account/update.php" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{"name": "New Display Name"}'
const response = await fetch('https://vypay.xyz/api/v1/account/update.php', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'New Display Name'
  })
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/account/update.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'name' => 'New Display Name'
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "success": true,
    "message": "Account updated successfully",
    "updated_fields": ["name"]
}
POST /transactions/transfer.php

Transfer funds between VYPay users. The call wraps balance updates in a single database transaction.

Required Permission: transactions.create

Request Body:
{
    "to_email": "friend@example.com",
    "amount": 42.5,
    "reason": "Dinner"
}
curl -X POST "https://vypay.xyz/api/v1/transactions/transfer.php" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "to_email": "friend@example.com",
    "amount": 42.5,
    "reason": "Dinner"
  }'
const response = await fetch('https://vypay.xyz/api/v1/transactions/transfer.php', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    to_email: 'friend@example.com',
    amount: 42.5,
    reason: 'Dinner'
  })
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/transactions/transfer.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'to_email' => 'friend@example.com',
    'amount' => 42.5,
    'reason' => 'Dinner'
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "success": true,
    "transaction_id": 1234,
    "amount": 42.5,
    "currency": "VYC",
    "sender": {
        "id": 8,
        "email": "you@example.com",
        "balance_after": 157.5
    },
    "recipient": {
        "id": 12,
        "email": "friend@example.com",
        "balance_after": 310.75
    },
    "reason": "Dinner",
    "created_at": "2025-10-31T14:52:30+00:00"
}
POST /transactions/history.php

Return paginated transaction history. You can filter by direction, date range, or counterparty.

Required Permission: transactions.read

Query Parameters (optional):
curl -X POST "https://vypay.xyz/api/v1/transactions/history.php?limit=25&direction=sent" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json"
const response = await fetch('https://vypay.xyz/api/v1/transactions/history.php?limit=25&direction=sent', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  }
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/transactions/history.php?limit=25&direction=sent');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "transactions": [
        {
            "transaction_id": 1234,
            "direction": "sent",
            "amount": 42.5,
            "currency": "VYC",
            "counterparty_email": "friend@example.com",
            "sender_email": "you@example.com",
            "receiver_email": "friend@example.com",
            "reason": "Dinner",
            "created_at": "2025-10-31 14:52:30"
        }
    ],
    "pagination": {
        "total": 87,
        "limit": 25,
        "offset": 0,
        "has_more": true
    },
    "filters": {
        "direction": "sent",
        "start_date": "2025-10-01",
        "end_date": "2025-10-31"
    }
}

Note: limit defaults to 20 and is capped at 100. You may also pass limit and offset in the query string.

Payments

POST /payments/create.php

Create a new payment request.

Required Permission: payments.create

Request Body:
{
    "amount": 99.99,
    "description": "Premium Subscription",
    "redirect_url": "https://vypay.xyz/success"
}
curl -X POST "https://vypay.xyz/api/v1/payments/create.php" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 99.99,
    "description": "Premium Subscription",
    "redirect_url": "https://vypay.xyz/success"
  }'
const response = await fetch('https://vypay.xyz/api/v1/payments/create.php', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: 99.99,
    description: 'Premium Subscription',
    redirect_url: 'https://vypay.xyz/success'
  })
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/payments/create.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'amount' => 99.99,
    'description' => 'Premium Subscription',
    'redirect_url' => 'https://vypay.xyz/success'
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "success": true,
    "payment_id": "pay_abc123",
    "amount": 99.99,
    "currency": "VYC",
    "status": "pending",
    "checkout_url": "https://vypay.xyz/pay/abc123",
    "created_at": "2025-12-30T10:30:00+00:00"
}
POST /payments/details.php?id=PAYMENT_ID

Get detailed information about a specific payment.

Required Permission: payments.read

curl -X POST "https://vypay.xyz/api/v1/payments/details.php?id=pay_abc123" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json"
const response = await fetch('https://vypay.xyz/api/v1/payments/details.php?id=pay_abc123', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  }
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/payments/details.php?id=pay_abc123');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "payment_id": "pay_abc123",
    "amount": 99.99,
    "currency": "VYC",
    "description": "Premium Subscription",
    "status": "completed",
    "transaction_id": "txn_xyz789",
    "created_at": "2025-12-30T10:30:00+00:00",
    "updated_at": "2025-12-30T10:35:00+00:00"
}
POST /payments/history.php

Get paginated payment history with optional filtering.

Required Permission: payments.read

Query Parameters:
curl -X POST "https://vypay.xyz/api/v1/payments/history.php?status=completed&limit=20" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json"
const response = await fetch('https://vypay.xyz/api/v1/payments/history.php?status=completed&limit=20', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  }
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/payments/history.php?status=completed&limit=20');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "payments": [
        {
            "payment_id": "pay_abc123",
            "amount": 99.99,
            "currency": "VYC",
            "description": "Premium Subscription",
            "status": "completed",
            "created_at": "2025-12-30T10:30:00+00:00"
        }
    ],
    "pagination": {
        "total": 45,
        "limit": 20,
        "offset": 0
    }
}
POST /payments/verify.php

Verify payment status and authenticity.

Required Permission: payments.verify

Request Body:
{
    "payment_id": "pay_abc123"
}
curl -X POST "https://vypay.xyz/api/v1/payments/verify.php" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{"payment_id": "pay_abc123"}'
const response = await fetch('https://vypay.xyz/api/v1/payments/verify.php', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    payment_id: 'pay_abc123'
  })
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/payments/verify.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'payment_id' => 'pay_abc123'
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "valid": true,
    "payment_id": "pay_abc123",
    "status": "completed",
    "amount": 99.99,
    "currency": "VYC"
}

Products

POST /products/create.php

Create a new product for sale.

Required Permission: products.create

Request Body:
{
    "name": "Premium Subscription",
    "description": "1-year premium access",
    "price": 99.99,
    "currency": "VYC"
}
curl -X POST "https://vypay.xyz/api/v1/products/create.php" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium Subscription",
    "description": "1-year premium access",
    "price": 99.99,
    "currency": "VYC"
  }'
const response = await fetch('https://vypay.xyz/api/v1/products/create.php', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Premium Subscription',
    description: '1-year premium access',
    price: 99.99,
    currency: 'VYC'
  })
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/products/create.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'name' => 'Premium Subscription',
    'description' => '1-year premium access',
    'price' => 99.99,
    'currency' => 'VYC'
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "success": true,
    "product_id": "prod_abc123",
    "name": "Premium Subscription",
    "description": "1-year premium access",
    "price": 99.99,
    "currency": "VYC",
    "is_active": true,
    "created_at": "2025-12-30T10:30:00+00:00"
}
POST /products/details.php?id=PRODUCT_ID

Get detailed information about a specific product.

Required Permission: products.read

curl -X POST "https://vypay.xyz/api/v1/products/details.php?id=prod_abc123" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json"
const response = await fetch('https://vypay.xyz/api/v1/products/details.php?id=prod_abc123', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  }
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/products/details.php?id=prod_abc123');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "product_id": "prod_abc123",
    "name": "Premium Subscription",
    "description": "1-year premium access",
    "price": 99.99,
    "currency": "VYC",
    "is_active": true,
    "created_at": "2025-12-30T10:30:00+00:00",
    "updated_at": "2025-12-30T10:30:00+00:00"
}
POST /products/update.php?id=PRODUCT_ID

Update an existing product's details.

Required Permission: products.update

Allowed Fields: name, description, price, currency, is_active

Request Body:
{
    "name": "Premium Subscription Plus",
    "price": 149.99,
    "is_active": true
}
curl -X POST "https://vypay.xyz/api/v1/products/update.php?id=prod_abc123" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Premium Subscription Plus",
    "price": 149.99,
    "is_active": true
  }'
const response = await fetch('https://vypay.xyz/api/v1/products/update.php?id=prod_abc123', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Premium Subscription Plus',
    price: 149.99,
    is_active: true
  })
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/products/update.php?id=prod_abc123');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
    'name' => 'Premium Subscription Plus',
    'price' => 149.99,
    'is_active' => true
]));
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "success": true,
    "message": "Product updated successfully",
    "product_id": "prod_abc123"
}
POST /products/delete.php?id=PRODUCT_ID

Delete (soft delete) a product. Sets is_active to false.

Required Permission: products.delete

curl -X POST "https://vypay.xyz/api/v1/products/delete.php?id=prod_abc123" \
  -H "Authorization: Bearer vypay_your_token_here" \
  -H "Content-Type: application/json"
const response = await fetch('https://vypay.xyz/api/v1/products/delete.php?id=prod_abc123', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer vypay_your_token_here',
    'Content-Type': 'application/json'
  }
});
const data = await response.json();
$ch = curl_init('https://vypay.xyz/api/v1/products/delete.php?id=prod_abc123');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer vypay_your_token_here',
    'Content-Type: application/json'
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
Response:
{
    "success": true,
    "message": "Product deleted successfully",
    "product_id": "prod_abc123"
}

Utilities

GET /health.php

Basic health check for uptime monitoring.

GET /info.php

API metadata and helpful links.

GET /currencies.php

List currently supported currencies.

Examples

Transfer Funds with Bearer Token (cURL)

curl -X POST "https://vypay.xyz/api/v1/transactions/transfer.php" \
    -H "Authorization: Bearer vypay_your_token_here" \
    -H "Content-Type: application/json" \
    -d '{
        "to_email": "friend@example.com",
        "amount": 25.00,
        "reason": "Lunch"
    }'

Transfer Funds with Email/Password (cURL)

curl -X POST "https://vypay.xyz/api/v1/transactions/transfer.php" \
    -H "Content-Type: application/json" \
    -d '{
        "email": "you@example.com",
        "password": "your-password",
        "to_email": "friend@example.com",
        "amount": 25.00,
        "reason": "Lunch"
    }'

Fetch Latest Transactions with Bearer Token (JavaScript)

const response = await fetch('https://vypay.xyz/api/v1/transactions/history.php?limit=10', {
    method: 'POST',
    headers: { 
        'Content-Type': 'application/json',
        'Authorization': 'Bearer vypay_your_token_here'
    }
});

const result = await response.json();
console.log('Recent transactions:', result.transactions);

Fetch Latest Transactions with Email/Password (JavaScript)

const response = await fetch('https://vypay.xyz/api/v1/transactions/history.php', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        email: 'you@example.com',
        password: 'your-password',
        limit: 10
    })
});

const result = await response.json();
console.log('Recent transactions:', result.transactions);

Error Handling

All errors follow a consistent JSON structure:

{
    "success": false,
    "error": "Insufficient balance"
}

Common Errors

Token-Specific Errors

// Invalid token
{
    "error": "Invalid token",
    "code": "invalid_token"
}

// Token expired
{
    "error": "Token has expired",
    "code": "token_expired"
}

// Token revoked
{
    "error": "Token has been revoked",
    "code": "token_revoked"
}

// Insufficient permissions
{
    "error": "Insufficient permissions",
    "required": "transactions.create"
}
Need Help? Reach us at support@vybolabs.com or visit the Token Management page to create and manage API tokens.
🔒 Best Practice: Use Bearer tokens for production applications. They're more secure, can be revoked without changing your password, and support granular permissions. Create tokens at Token Management.