API Documentation

Complete guide to integrating TransVoucher's payment processing API

Version 1.0 Current: v1.0

Quick Start

Get up and running with TransVoucher in minutes

1

Get API Credentials

Sign up and obtain your API key and secret from the merchant dashboard

2

Install SDK

Add one of our available SDKs or use direct API calls with your preferred language

3

Process Payments

Start accepting card payments and receive crypto settlements

Basic Payment Integration

JavaScript
// Initialize TransVoucher
const transvoucher = new TransVoucher({
  apiKey: 'your-api-key',
  environment: 'sandbox' // or 'production'
});

// Create a payment
const payment = await transvoucher.payments.create({
  amount: 100.00,                    // Optional when is_price_dynamic is true
  currency: 'USD',
  title: 'Product Purchase',
  description: 'Product purchase',
  multiple_use: false,
  cancel_on_first_fail: false,       // Optional - If true, payment link fails permanently after first failed attempt. By default user can retry.
  is_price_dynamic: false,           // Optional - When true, allows customers to set their own amount (default: false)
  customer_details: {
    // read more about the possibilities here in the "Pre-Fill Userdata" section
    first_name: 'John',                // Optional
    last_name: 'Doe',                  // Optional
    id: 'cust_123',                    // Optional - Customer's unique identifier
    email: '[email protected]',     // Optional
    phone: '+1234567890',              // Optional
    date_of_birth: '1990-01-01',       // Optional - YYYY-MM-DD format
    country_of_residence: 'US',        // Optional - ISO country code
    state_of_residence: 'CA'           // Optional - Required if country is US
  },
  // Use metadata to identify customer/session - will be returned in webhooks and API responses
  metadata: {
    // example data:
    order_type: 'standard',
    product_id: 'PROD-456',
    user_id: 'user_789',
    session_id: 'sess_abc123'
  }
});

// Check payment status
if (transvoucher.payments.isCompleted(payment)) {
  console.log('Payment completed successfully');
}

// Redirect to payment page
window.location.href = payment.payment_url;
                

Authentication

API Key Authentication

TransVoucher uses API key and secret pairs to authenticate requests. Include both headers in every API request:

X-API-Key: your-api-key
X-API-Secret: your-api-secret

Security Note: Never expose your API keys or secrets in client-side code. Always make API calls from your server and store credentials securely.

Example Request

curl -X POST https://api.transvoucher.com/v1.0/payment/create \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key" \
  -H "X-API-Secret: your-api-secret" \
  -d '{
    "amount": 99.99,
    "currency": "USD",
    "customer_email": "[email protected]"
  }'

Webhook Signatures

Webhook events are signed with your endpoint secret to verify authenticity:

// Verify webhook signature
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  // Ensure we got the expected format
  if (!signature.startsWith('sha256=')) {
    throw new Error('Invalid signature format');
  }

  const signatureHex = signature.slice(7); // strip prefix

  // Important: payload must be the raw JSON string, not parsed+stringified
  const computedSignature = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');

  return crypto.timingSafeEqual(
    Buffer.from(signatureHex, 'hex'),
    Buffer.from(computedSignature, 'hex')
  );
}

API Endpoints

Payments

POST /v1.0/payment/create

Create a new payment session

Parameters

Parameter Type Required Description
amount number Yes Payment amount (minimum 0.01)
currency string No Currency code (USD, EUR, TRY) - default: USD
title string Yes Title of the payment link
redirect_url string No Redirect URL
success_url string No Success URL
cancel_url string No Cancel URL
customer_details object No Customer information object. Optionally supports: first_name, middle_name, last_name, email, phone, date_of_birth (YYYY-MM-DD), country_of_residence (alpha2 country short code), state_of_residence (required for US, alpha2 US state code), card_country_code (alpha2 US state code, only required for US), card_city (billing address city), card_state_code (alpha2 US state code, required and only allowed for US), card_post_code (billing address post/zip code), card_street, (billing address line 1)
metadata object No Use this to identify customer/session - will be returned in webhooks and API responses
theme string No UI theme customization (auto, light, dark) - (default: "auto")
lang string No Language code (en, es, fr, de, it, pt, ru, zh, ja, ko) - (default: "en")
default_payment_method string No Default payment method (card, apple-pay, google-pay)
payment_method_forced boolean No Force only the selected payment method (default: false)
cancel_on_first_fail boolean No When true, the payment link fails permanently after first failed attempt and user is redirected to cancel_url/redirect_url or shown an error page with fail_reason. No "Try Again" button is shown. By default user can retry (default: false)
is_price_dynamic boolean No When true, allows customers to set their own payment amount during checkout. The amount parameter becomes optional when this is enabled (default: false)

Response

{
  "success": true,
  "data": {
    "transaction_id": "014504dc-016d-43f7-3358-451cc70ea024",
    "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
    "payment_url": "https://transvoucher.com/pay/...",
    "expires_at": "2024-01-01T12:00:00Z",
    "amount": 99.99,
    "currency": "USD",
    "status": "pending"
  }
}
GET /v1.0/payment-link/status/{paymentLinkId}

Retrieve payment link status by its ID

Response

{
  "success": true,
  "data": {
    "id": "ae27e294-0447-480c-a769-cdbfeada2439",
    "transaction_id": "014504dc-016d-43f7-3358-451cc70ea024",
    "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
    "fiat_base_amount": 99.99,
    "fiat_total_amount": 99.99,
    "fiat_currency": "USD",
    "commodity": "USDT",
    "commodity_amount": 99.99,
    "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
    "status": "completed",
    "fail_reason": null,
    "created_at": "2024-01-01T10:00:00Z",
    "updated_at": "2024-01-01T10:05:00Z",
    "paid_at": "2024-01-01T10:05:00Z",
    "payment_details": {
      ///...
    },
    "payment_method": {
      "type": "card", // or "apple_pay", "google_pay" | optional
      "brand": "VISA", // card brand (VISA, MASTERCARD, AMEX, JCB, DISCOVER) | optional 
      "processor": "safecharge", // payment processor (safecharge, ap_safecharge, gp_safecharge, worldpay) | optional
      "card_id": "..." // card identifier - only for card payments | optional
    }
  }
}
GET /v1.0/payment/status/{transactionId}

Retrieve payment status by transaction ID

Response

{
  "success": true,
  "data": {
    "transaction_id": "014504dc-016d-43f7-3358-451cc70ea024",
    "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
    "amount": 99.99,
    "currency": "USD",
    "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
    "status": "completed",
    "fail_reason": null,
    "created_at": "2024-01-01T10:00:00Z",
    "updated_at": "2024-01-01T10:05:00Z",
    "paid_at": "2024-01-01T10:05:00Z",
    "payment_details": {
      //...
    },
    "payment_method": {
      "type": "card", // or "apple_pay", "google_pay" | optional
      "brand": "VISA", // card brand (VISA, MASTERCARD, AMEX, JCB, DISCOVER) | optional 
      "processor": "safecharge", // payment processor (safecharge, ap_safecharge, gp_safecharge, worldpay) | optional
      "card_id": "..." // card identifier - only for card payments | optional
    }
  }
}
GET /v1.0/payment/list

List all payments with pagination and filtering

Query Parameters

Parameter Type Description
limit integer Number of results (1-100, default: 10)
page_token string Token for pagination (from previous response)
status string Filter by status (pending, completed, failed, expired)
from_date date Filter payments from this date (YYYY-MM-DD)
to_date date Filter payments to this date (YYYY-MM-DD)

Response

{
  "success": true,
  "data": {
    "payments": [
      {
        "transaction_id": "014504dc-016d-43f7-3358-451cc70ea024",
        "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
        "amount": 99.99,
        "currency": "USD",
        "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
        "status": "completed",
        "customer_details": {...},
        "metadata": {...},
        "created_at": "2024-01-01T10:00:00Z",
        "updated_at": "2024-01-01T10:05:00Z",
        "paid_at": "2024-01-01T10:05:00Z"
      }
    ],
    "has_more": true,
    "next_page_token": "eyJsYXN0X2lkIjoxMjN9",
    "count": 10
  }
}

Currencies

GET /v1.0/currencies

Retrieve all available fiat currencies supported by the platform

Parameters

No parameters required

Response

{
  "success": true,
  "data": [
    {
      "short_code": "USD",
      "name": "US Dollar",
      "symbol": "$",
      "current_usd_value": "1.000000",
      "processed_via_currency_code": null
    },
    {
      "short_code": "EUR",
      "name": "Euro",
      "symbol": "€",
      "current_usd_value": "1.100000",
      "processed_via_currency_code": null
    },
    {
      "short_code": "GBP",
      "name": "British Pound",
      "symbol": "£",
      "current_usd_value": "1.270000",
      "processed_via_currency_code": null
    },
    {
      "short_code": "TRY",
      "name": "Turkish Lira",
      "symbol": "₺",
      "current_usd_value": "0.037000",
      "processed_via_currency_code": "EUR"
    }
  ]
}

Response Fields

Field Type Description
short_code string ISO 4217 currency code (e.g., USD, EUR, GBP)
name string Full name of the currency
symbol string Currency symbol (e.g., $, €, £)
current_usd_value string Current USD exchange rate value
processed_via_currency_code string|null If the currency is processed via another currency, this field contains that currency code. Otherwise null for direct processing.

Webhooks

Webhook Events

TransVoucher sends webhook events to notify your application of payment status changes to your configured webhook endpoint:

payment_intent.created

Sent when a payment intent is created

{
  "event": "payment_intent.created",
  "timestamp": "2024-01-01T10:00:00.000000Z",
  "data": {
    "payment_link_id": "ae27e294-0447-480c-a769-cdbfeada2439",
    "transaction": {
      "id": "014504dc-016d-43f7-3358-451cc70ea024",
      "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
      "fiat_base_amount": "10.000000",
      "fiat_total_amount": "10.000000",
      "fiat_currency": "USD",
      "commodity_amount": "10.000000",
      "commodity": "USDT",
      "network": "POL", // polygon
      "status": "pending",
      "created_at": "2024-01-01T10:00:00.000000Z",
      "updated_at": "2024-01-01T10:00:00.000000Z",
      "paid_at": null
    },
    "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
    "sales_channel": {
      "id": 1259046,
      "name": "Your Sales Channel Name",
      "type": "website"
    },
    "merchant": {
      "id": 39,
      "company_name": "Your Company Name"
    },
    "customer_details": {
      // all optional
      "email": "[email protected]",
      "phone": null,
      "first_name": "Carter",
      "middle_name": null,
      "last_name": "Smith",
      "date_of_birth": "1990-01-01",
      "country_of_residence": "US", // if present, will be a valid alpha-2 country short code
      "state_of_residence": "AR",   // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_country_code": null,    // if present, will be a valid alpha-2 country short code
      "card_state_code": null,      // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_city": null,
      "card_post_code": null,
      "card_street": null,
      "lang": "en"                  // the language for the payment page - possible values: en, es, fr, de, it, pt, ru, zh, ja, ko, tr
    },
    "metadata": {
      // your optional metadata
      "user": "r567890ß098765",
      "product": "2234567890",
      "type": "standard",
    },
    "payment_method": {
      "type": "card", // or "apple_pay", "google_pay" | optional
      "brand": "VISA", // card brand (VISA, MASTERCARD, AMEX, JCB, DISCOVER) | optional 
      "processor": "safecharge", // payment processor (safecharge, ap_safecharge, gp_safecharge, worldpay) | optional
      "card_id": "..." // card identifier - only for card payments | optional
    }
  }
}
payment_intent.attempting

Sent when a payment attempt was started by the customer

{
  "event": "payment_intent.attempting",
  "timestamp": "2024-01-01T10:00:00.000000Z",
  "data": {
    "payment_link_id": "ae27e294-0447-480c-a769-cdbfeada2439",
    "transaction": {
      "id": "014504dc-016d-43f7-3358-451cc70ea024",
      "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
      "fiat_base_amount": "10.000000",
      "fiat_total_amount": "10.000000",
      "fiat_currency": "USD",
      "commodity_amount": "10.000000",
      "commodity": "USDT",
      "network": "POL", // polygon
      "status": "attempting",
      "created_at": "2024-01-01T10:00:00.000000Z",
      "updated_at": "2024-01-01T10:00:00.000000Z",
      "paid_at": null
    },
    "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
    "sales_channel": {
      "id": 1234567,
      "name": "Your Sales Channel Name",
      "type": "website"
    },
    "merchant": {
      "id": 12345,
      "company_name": "Your Company Name"
    },
    "customer_details": {
      // all optional
      "email": "[email protected]",
      "phone": "+1234567890",
      "first_name": "Carter",
      "middle_name": null,
      "last_name": "Smith",
      "date_of_birth": "1990-01-01",
      "country_of_residence": "US", // if present, will be a valid alpha-2 country short code
      "state_of_residence": "AR",   // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_country_code": null,    // if present, will be a valid alpha-2 country short code
      "card_state_code": null,      // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_city": null,
      "card_post_code": null,
      "card_street": null
    },
    "metadata": {
      "payment_link_title": "Your Payment Link Title",
      "payment_link_description": null, // can be "Your Payment Link Description"
      // + your optional metadata
      // ...
    },
    "payment_method": {
      "type": "card", // or "apple_pay", "google_pay" | optional
      "brand": "VISA", // card brand (VISA, MASTERCARD, AMEX, JCB, DISCOVER) | optional 
      "processor": "safecharge", // payment processor (safecharge, ap_safecharge, gp_safecharge, worldpay) | optional
      "card_id": "..." // card identifier - only for card payments | optional
    }
  }
}
payment_intent.processing

Sent when a payment is being processed

{
  "event": "payment_intent.processing",
  "timestamp": "2024-01-01T10:00:00.000000Z",
  "data": {
    "payment_link_id": "ae27e294-0447-480c-a769-cdbfeada2439",
    "transaction": {
      "id": "014504dc-016d-43f7-3358-451cc70ea024",
      "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
      "fiat_base_amount": "10.000000",
      "fiat_total_amount": "10.000000",
      "fiat_currency": "USD",
      "commodity_amount": "10.000000",
      "commodity": "USDT",
      "network": "POL", // polygon
      "status": "processing",
      "created_at": "2024-01-01T10:00:00.000000Z",
      "updated_at": "2024-01-01T10:00:00.000000Z",
      "paid_at": null
    },
    "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
    "sales_channel": {
      "id": 1234567,
      "name": "Your Sales Channel Name",
      "type": "website"
    },
    "merchant": {
      "id": 12345,
      "company_name": "Your Company Name"
    },
    "customer_details": {
      // all optional
      "email": "[email protected]",
      "phone": "+1234567890",
      "first_name": "Carter",
      "middle_name": null,
      "last_name": "Smith",
      "date_of_birth": "1990-01-01",
      "country_of_residence": "US", // if present, will be a valid alpha-2 country short code
      "state_of_residence": "AR",   // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_country_code": null,    // if present, will be a valid alpha-2 country short code
      "card_state_code": null,      // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_city": null,
      "card_post_code": null,
      "card_street": null
    },
    "metadata": {
      "payment_link_title": "Your Payment Link Title",
      "payment_link_description": null, // can be "Your Payment Link Description"
      // + your optional metadata
      // ...
    },
    "payment_method": {
      "type": "card", // or "apple_pay", "google_pay" | optional
      "brand": "VISA", // card brand (VISA, MASTERCARD, AMEX, JCB, DISCOVER) | optional 
      "processor": "safecharge", // payment processor (safecharge, ap_safecharge, gp_safecharge, worldpay) | optional
      "card_id": "..." // card identifier - only for card payments | optional
    }
  }
}
payment_intent.succeeded

Sent when a payment intent is successfully completed

{
  "event": "payment_intent.succeeded",
  "timestamp": "2024-01-01T10:00:00.000000Z",
  "data": {
    "transaction": {
      "id": "014504dc-016d-43f7-3358-451cc70ea024",
      "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
      "fiat_base_amount": "10.000000",
      "fiat_total_amount": "10.000000",
      "fiat_currency": "USD",
      "commodity_amount": "10.000000",
      "commodity": "USDT",
      "network": "POL", // polygon
      "status": "completed",
      "created_at": "2024-01-01T10:00:00.000000Z",
      "updated_at": "2024-01-01T10:00:00.000000Z",
      "paid_at": "2024-01-01T10:00:00.000000Z",
    },
    "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
    "sales_channel": {
      "id": 1234567,
      "name": "Your Sales Channel Name",
      "type": "website"
    },
    "merchant": {
      "id": 12345,
      "company_name": "Your Company Name"
    },
    "customer_details": {
      // all optional
      "email": "[email protected]",
      "phone": "+1234567890",
      "first_name": "Carter",
      "middle_name": null,
      "last_name": "Smith",
      "date_of_birth": "1990-01-01",
      "country_of_residence": "US", // if present, will be a valid alpha-2 country short code
      "state_of_residence": "AR",   // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_country_code": null,    // if present, will be a valid alpha-2 country short code
      "card_state_code": null,      // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_city": null,
      "card_post_code": null,
      "card_street": null
    },
    "metadata": {
      "payment_link_title": "Your Payment Link Title",
      "payment_link_description": null, // can be "Your Payment Link Description"
      // + your optional metadata
      // ...
    },
    "payment_method": {
      "type": "card", // or "apple_pay", "google_pay" | optional
      "brand": "VISA", // card brand (VISA, MASTERCARD, AMEX, JCB, DISCOVER) | optional 
      "processor": "safecharge", // payment processor (safecharge, ap_safecharge, gp_safecharge, worldpay) | optional
      "card_id": "..." // card identifier - only for card payments | optional
    }
  }
}
payment_intent.failed

Sent when a payment intent fails or is declined

{
  "event": "payment_intent.failed",
  "timestamp": "2024-01-01T10:00:00.000000Z",
  "data": {
    "payment_link_id": "ae27e294-0447-480c-a769-cdbfeada2439",
    "transaction": {
      "id": "014504dc-016d-43f7-3358-451cc70ea024",
      "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
      "fiat_base_amount": "10.000000",
      "fiat_total_amount": "10.000000",
      "fiat_currency": "USD",
      "commodity_amount": "10.000000",
      "commodity": "USDT",
      "network": "POL", // polygon
      "status": "failed",
      "created_at": "2024-01-01T10:00:00.000000Z",
      "updated_at": "2024-01-01T10:00:00.000000Z",
      "paid_at": null
    },
    // clear text error reason
    "fail_reason": "Contact Bank",
    "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
    "sales_channel": {
      "id": 1234567,
      "name": "Your Sales Channel Name",
      "type": "website"
    },
    "merchant": {
      "id": 12345,
      "company_name": "Your Company Name"
    },
    "customer_details": {
      // all optional
      "email": "[email protected]",
      "phone": "+1234567890",
      "first_name": "Carter",
      "middle_name": null,
      "last_name": "Smith",
      "date_of_birth": "1990-01-01",
      "country_of_residence": "US", // if present, will be a valid alpha-2 country short code
      "state_of_residence": "AR",   // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_country_code": null,    // if present, will be a valid alpha-2 country short code
      "card_state_code": null,      // if present, will be a valid US state short code (alpha-2 uppercase)
      "card_city": null,
      "card_post_code": null,
      "card_street": null
    },
    "metadata": {
      "payment_link_title": "Your Payment Link Title",
      "payment_link_description": null, // can be "Your Payment Link Description"
      // + your optional metadata
      // ...
    },
    "payment_method": {
      "type": "card", // or "apple_pay", "google_pay" | optional
      "brand": "VISA", // card brand (VISA, MASTERCARD, AMEX, JCB, DISCOVER) | optional 
      "processor": "safecharge", // payment processor (safecharge, ap_safecharge, gp_safecharge, worldpay) | optional
      "card_id": "..." // card identifier - only for card payments | optional
    }
    "fail_reason": "Card CVV invalid" // for example | generally clear text reason for failure
   }
}
payment_intent.cancelled

Sent when a payment intent is cancelled

{
  "event": "payment_intent.cancelled",
  "timestamp": "2024-01-01T10:00:00.000000Z",
  "data": {
    "payment_link_id": "ae27e294-0447-480c-a769-cdbfeada2439",
    "transaction": {
      "id": "014504dc-016d-43f7-3358-451cc70ea024",
      "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
      "fiat_base_amount": "10.000000",
      "fiat_total_amount": "10.000000",
      "fiat_currency": "USD",
      "commodity_amount": "10.000000",
      "commodity": "USDT",
      "network": "POL", // polygon
      "status": "cancelled",
      "created_at": "2024-01-01T10:00:00.000000Z",
      "updated_at": "2024-01-01T10:00:00.000000Z",
      "paid_at": null
    },
    "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
    "sales_channel": {
      "id": 1234567,
      "name": "Your Sales Channel Name",
      "type": "website"
    },
    "merchant": {
      "id": 12345,
      "company_name": "Your Company Name"
    },
    "customer_details": {
      // all optional
      "email": "[email protected]",
      "phone": "+1234567890",
      "first_name": "Carter",
      "middle_name": null,
      "last_name": "Smith",
      "date_of_birth": "1990-01-01",
      "country_of_residence": "NL",
      "state_of_residence": null
    },
    "metadata": {
      "payment_link_title": "Your Payment Link Title",
      "payment_link_description": null, // can be "Your Payment Link Description"
      // + your optional metadata
      // ...
    },
    "payment_method": {
      "type": "card", // or "apple_pay", "google_pay" | optional
      "brand": "VISA", // card brand (VISA, MASTERCARD, AMEX, JCB, DISCOVER) | optional 
      "processor": "safecharge", // payment processor (safecharge, ap_safecharge, gp_safecharge, worldpay) | optional
      "card_id": "..." // card identifier - only for card payments | optional
    }
  }
}

Note: This is a representative example. The structure follows the same pattern as other webhooks.

payment_intent.expired

Sent when a payment intent expires

{
  "event": "payment_intent.expired",
  "timestamp": "2024-01-01T10:00:00.000000Z",
  "data": {
    "payment_link_id": "ae27e294-0447-480c-a769-cdbfeada2439",
    "transaction": {
      "id": "014504dc-016d-43f7-3358-451cc70ea024",
      "reference_id": "b6b5c588-4735-4480-9f88-6b993bad30cf",
      "fiat_base_amount": "10.000000",
      "fiat_total_amount": "10.000000",
      "fiat_currency": "USD",
      "commodity_amount": "10.000000",
      "commodity": "USDT",
      "network": "POL", // polygon
      "status": "expired",
      "created_at": "2024-01-01T10:00:00.000000Z",
      "updated_at": "2024-01-01T10:00:00.000000Z",
      "paid_at": null
    },
    "blockchain_tx_hash": "BLOCKCHAIN_TRANSACTION_HASH", // or null
    "sales_channel": {
      "id": 1234567,
      "name": "Your Sales Channel Name",
      "type": "website"
    },
    "merchant": {
      "id": 12345,
      "company_name": "Your Company Name"
    },
    "customer_details": {
      // all optional
      "email": "[email protected]",
      "phone": "+1234567890",
      "first_name": "Carter",
      "middle_name": null,
      "last_name": "Smith",
      "date_of_birth": "1990-01-01",
      "country_of_residence": "NL",
      "state_of_residence": null
    },
    "metadata": {
      "payment_link_title": "Your Payment Link Title",
      "payment_link_description": null, // can be "Your Payment Link Description"
      // + your optional metadata
      // ...
    },
    "payment_method": {
      "type": "card", // or "apple_pay", "google_pay" | optional
      "brand": "VISA", // card brand (VISA, MASTERCARD, AMEX, JCB, DISCOVER) | optional 
      "processor": "safecharge", // payment processor (safecharge, ap_safecharge, gp_safecharge, worldpay) | optional
      "card_id": "..." // card identifier - only for card payments | optional
    }
  }
}

Note: This is a representative example based on other webhook structures. The exact fields may vary.

Pre-Fill User Data

Customer Information Pre-filling

When providing customer details in your payment request, you can streamline the user experience in two ways:

Complete Pre-fill

If ALL customer information fields are provided (first_name, (optionally middle_name), last_name, email, phone, date_of_birth, country_of_residence, and state_of_residence for US), the customer information form will be skipped entirely. Users will proceed directly to the payment form.

Partial Pre-fill

If only some fields are provided, they will be pre-filled in the customer information form. Users will only need to complete the remaining fields before proceeding to payment.

Payment Methods

Default and Forced Payment Methods

You can control which payment methods are available to your customers by setting the default payment method or forcing a single payment method:

{
  "amount": 99.99,
  "currency": "USD",
  "title": "Product Purchase",
  //...
  "default_payment_method": "apple-pay",  // "card", "google-pay"
  "payment_method_forced": true,
  //...
}

Forced Payment Method

If payment_method_forced is set to true, only the selected default_payment_method will be available to customers.

Default Payment Method

If payment_method_forced is set to false (default), the selected default_payment_method will be pre-selected, but customers can choose other available payment methods.

Available Payment Methods

  • card - Credit/Debit card
  • apple-pay - Apple Pay
  • google-pay - Google Pay

SDK Integration

JavaScript SDK

Installation

npm install @transvoucher/sdk
or
yarn add @transvoucher/sdk

Usage

import TransVoucher from '@transvoucher/sdk';

const transvoucher = new TransVoucher({
  apiKey: process.env.TRANSVOUCHER_API_KEY,
  environment: 'production' // or 'sandbox'
});

// Create payment
const payment = await transvoucher.payments.create({
  amount: 99.99,                       // Required
  currency: 'USD',                     // Required
  title: 'Product Purchase',           // Required
  description: 'Product purchase',     // Optional
  multiple_use: false,                 // Optional
  cancel_on_first_fail: false,         // Optional - If true, payment link fails permanently after first failed attempt. By default user can retry.
  customer_details: {
    // read more about the possibilities here in the "Pre-Fill Userdata" section
    first_name: 'John',                // Optional
    last_name: 'Doe',                  // Optional
    email: '[email protected]',     // Optional
    phone: '+1234567890',              // Optional
    date_of_birth: '1990-01-01',       // Optional - YYYY-MM-DD format
    country_of_residence: 'US',        // Optional - ISO country code
    state_of_residence: 'CA'           // Optional - Required if country is US

    // unrelated to payment flow:
    id: 'cust_123',                    // Optional - Customer's unique identifier
  },
  // Use metadata to identify customer/session - will be returned in webhooks and API responses
  metadata: {
    // example data:
    order_type: 'standard',
    product_id: 'PROD-456',
    user_id: 'user_789',
    session_id: 'sess_abc123'
  }
});

// Helper methods for checking payment status
if (transvoucher.payments.isCompleted(payment)) {
  console.log('Payment completed');
} else if (transvoucher.payments.isPending(payment)) {
  console.log('Payment pending');
}

console.log('Payment URL:', payment.payment_url);
                    

PHP SDK

Installation

composer require transvoucher/php-sdk

Usage

<?php
require_once 'vendor/autoload.php';

use TransVoucher\TransVoucher;

$transvoucher = new TransVoucher([
    'api_key' => $_ENV['TRANSVOUCHER_API_KEY'],
    'environment' => 'production'
]);

$payment = $transvoucher->payments->create([
    'amount' => 99.99,
    'currency' => 'USD',
    'title' => 'Product Purchase',
    'description' => 'Product purchase',
    'multiple_use' => false,
    'cancel_on_first_fail' => false,       // Optional - If true, payment link fails permanently after first failed attempt. By default user can retry.
    'customer_details' => [
        // read more about the possibilities here in the "Pre-Fill Userdata" section
        'first_name' => 'John',                // Required if customer_details is provided
        'last_name' => 'Doe',                  // Required if customer_details is provided
        'id' => 'cust_123',                    // Optional - Customer's unique identifier
        'email' => '[email protected]',     // Optional
        'phone' => '+1234567890',              // Optional
        'date_of_birth' => '1990-01-01',       // Optional - YYYY-MM-DD format

        
        'country_of_residence' => 'US',        // Optional - if present, has to be a valid alpha-2 country short code
        'state_of_residence' => 'CA',          // Optional
        // rules for usage of "state_of_residence":
        // - if present, has to be a valid US state short code (alpha-2 uppercase)
        // - required if "country_of_residence" is "US" (we will ask for it if you don't prefill it)
        // - has to be dropped (not be in the payload) when "country_of_residence" is not "US"
        
        // if you want to prefill the card billing address:

        'card_country_code' => 'US',           // Optional - alpha-2 country short code card billing address
        'card_city' => 'California',           // Optional - prefill card billing address
        'card_state_code' => 'CA',             // Optional - prefill card information
        // rules for usage of "card_state_code":
        // - if present, has to be a valid US state short code (alpha-2 uppercase)
        // - required if "card_country_code" is "US" (we will ask for it if you don't prefill it)
        // - has to be dropped (not be in the payload) when "card_country_code" is not "US"

        'card_post_code' => '12345',           // Optional - prefill card information
        'card_street' => 'Street 123',         // Optional - prefill card information
    ],
    // Use metadata to identify customer/session - will be returned in webhooks and API responses
    'metadata' => [
        // example data:
        'order_type' => 'standard',
        'product_id' => 'PROD-456',
        'user_id' => 'user_789',
        'session_id' => 'sess_abc123'
    ]
]);

// Helper methods for checking payment status
if ($payment->isCompleted()) {
    echo 'Payment completed';
} else if ($payment->isPending()) {
    echo 'Payment pending';
}

header('Location: ' . $payment->payment_url);
?>

Testing

Sandbox Environment

Use our sandbox environment to test your integration without processing real payments:

Base URL: https://sandbox-api.transvoucher.com/v1.0

🧪 Sandbox Testing Rules

💳 Only card payments work reliably - Google Pay/ApplePay usually won't work

👤 Enter any valid format for customer profile data

📱 Use any phone number (must be valid, but we don't send real OTP/SMS - use "1234" or any other code)

💳 Always use test card: 4242 4242 4242 4242 with a future expiry date

🔑 CVV determines payment outcome:
CVV Result
400 ❌ General failure
401 💳 Declined by card issuer
402 📝 Incorrect card details
403 📊 Transaction limits exceeded
404 💰 Insufficient funds
405 🔒 Incorrect CVV
406 🗑️ Failed card validation (card deleted)
407 🆘 Failed card validation (contact support)
ANY OTHER ✅ SUCCESS (e.g., 123)

Production Checklist

  • Test all payment flows in sandbox environment
  • Implement webhook endpoints and verify signatures
  • Handle error scenarios and edge cases
  • Secure API keys and never expose them client-side
  • Complete KYB verification for your merchant account
  • Update all endpoints to use /v1.0/ prefix for future compatibility

Need Help?

Our developer support team is here to help you integrate successfully

Technical Support

Get help with integration issues and technical questions

Contact via Telegram →

Email Support

Send detailed questions and receive comprehensive responses

[email protected]

Help Center

Browse FAQs and common integration patterns

Visit Help Center →