Cross-Border Payments Integration Guide

Embed VoPay's cross-border payment experience in your application, and connect the optional balance-check and transaction-review hooks that give you control over every payout.

Overview

VoPay Cross-Border Services is a global payment service providing fast, transparent payments between senders and recipients across multiple channels and payout methods. The service provides:

  • A technical interface for initiating transactions to approved receiving territories
  • Wholesale and retail foreign-exchange (FX) rates and fees
  • Transaction reporting and settlement statements to support reconciliation

Supported payment use cases:

  • P2P — Person to Person
  • B2P — Business to Person
  • B2B — Business to Business
  • P2B — Person to Business

The fastest way to offer cross-border payments is the embedded experience: a secure, brandable VoPay page that you load in an iframe. VoPay handles recipient collection, FX quoting, compliance data, and payment processing end to end — your integration can be as small as one API call.

How It Works

  1. Generate an embed URL. Your backend calls POST /gcm/generate-embed-url and loads the returned link in an iframe within your web application.
  2. The end user sends a cross-border transaction. Inside the iframe, the user picks a destination, delivery method, and amount, and provides recipient details. VoPay handles the entire flow — quoting, validation, and processing.
  3. Live balance check (optional). Before the user can proceed, VoPay calls a balance endpoint that you host to confirm the sender has sufficient funds — preventing last-step declines.
  4. Transaction review (optional). Once the user submits, VoPay notifies you via webhook and holds the transaction for review. You fetch the full details, then confirm or cancel; confirmed transactions are processed through the Mastercard network.

Steps 3 and 4 are independent — enable either, both, or neither depending on how much control you need over the flow of funds.

Environments & Authentication

EnvironmentBase URL
Sandboxhttps://earthnode-dev.vopay.com/api/v2
Productionhttps://earthnode.vopay.com/api/v2

Every API request is authenticated with three parameters:

ParameterTypeDescription
AccountIDStringThe unique identifier for your VoPay account.
KeyStringThe API key associated with the AccountID.
SignatureStringA SHA-1 hash generated from your API key, shared secret, and the current date. See the Authentication Guidelines.

Full endpoint specifications for everything referenced in this guide live in the API Reference, under the Global Cash Management section.

Step 1: Generate the Embedded Experience

This endpoint generates a secure, single-use URL that launches the VoPay cross-border payment experience inside your web application or platform.

POST /api/v2/gcm/generate-embed-urlAPI reference

Request Parameters

ParameterDescription
AccountIDRequiredYour VoPay account ID.
KeyRequiredYour API key.
SignatureRequiredRequest signature (see Authentication above).
ClientAccountIDOptionalThe client account (sender) the session is created for. Defaults to your primary client account.
ClientNameOptionalDisplay name shown in the experience. Defaults to your account name.
ClientReferenceNumberOptionalYour internal reference for the session, echoed back in reporting.
RecipientContactIDOptionalPre-selects a saved recipient so the user skips recipient entry.
DeliveryChannelIDOptionalPre-selects the destination corridor and payout method.
BuyAmountOptionalPre-fills the amount the recipient receives. Cannot be combined with SellAmount.
SellAmountOptionalPre-fills the amount the sender pays. Cannot be combined with BuyAmount.
LanguageOptionalUI language code (e.g. en, fr). Defaults to en.
DarkModeOptionalSet to true to render the experience in dark mode.
StylesheetUrlOptionalURL of a CSS file with custom rules, so the experience matches your branding.

Custom Styling

Point StylesheetUrl at a publicly accessible stylesheet to customize:

  • Buttons — background color, text color, border, hover effects, font
  • Progress bar — color, height
  • Text — font family, size, color

Example Request

curl -X POST 'https://earthnode.vopay.com/api/v2/gcm/generate-embed-url' \
  -H 'Content-Type: application/json' \
  -d '{
    "AccountID": "YOUR_ACCOUNT_ID",
    "Key": "YOUR_API_KEY",
    "Signature": "YOUR_GENERATED_SIGNATURE",
    "ClientReferenceNumber": "ORDER-10021",
    "StylesheetUrl": "https://your-website.com/vopay-styles.css"
  }'

Example Response

{
  "Success": true,
  "ErrorMessage": "",
  "Link": "https://earthnode.vopay.com/embed/1234567890?authToken=XYZ",
  "IframeKey": "a1b2c3d4e5"
}
FieldTypeDescription
LinkStringThe embeddable URL. Load it in an iframe or open it as a link.
IframeKeyStringIdentifies this embedded session in subsequent API calls (e.g. balance lookups).

On error, the endpoint returns an appropriate HTTP status code with a JSON body containing an error code and a descriptive message.

Integration Steps

  1. Generate the signature on your backend per the Authentication Guidelines.
  2. Send the request to /gcm/generate-embed-url with any optional parameters you need.
  3. Parse the response to obtain the Link.
  4. Embed the link in an iframe within your page. The user completes the entire transaction inside it.
📘

One session, one link

Generate a fresh embed URL per user session — treat the Link as short-lived and never cache or share it between users.

Controlling the Iframe from Your Page

Beyond CSS styling, the embedded experience exposes a postMessage API. This lets you hide the iframe's built-in menu (Home, Send, Recipients, Activity) and drive navigation from buttons in your own UI instead — so the embedded experience blends seamlessly into your application's navigation.

All messages, in both directions, share one shape:

{
  "type": "ACTION | INFO",
  "code": "INIT | CONFIG | CONFIG_PROCESSED | NAVIGATION",
  "payload": {}
}

The startup handshake

  1. The iframe finishes loading and posts INFO / INIT to your page.
  2. Your page replies with ACTION / CONFIG containing your configuration.
  3. The iframe applies it and acknowledges with INFO / CONFIG_PROCESSED.
📘

Avoid the menu flash

Keep the iframe hidden (e.g. visibility: hidden) until CONFIG_PROCESSED arrives — this prevents the menu from flashing briefly before your configuration is applied.

Messages you can send to the iframe

MessagePayloadEffect
ACTION / CONFIGhideMenu (Boolean), primaryColor (String, optional), timezone (String, optional)Hides the built-in menu, overrides the primary brand color, and sets the timezone used for displaying dates. The iframe acknowledges with CONFIG_PROCESSED.
ACTION / NAVIGATIONpath (String)Navigates the iframe to an internal page. Use this to wire your own buttons or tabs to the embedded experience.

Messages the iframe sends to your page

MessagePayloadMeaning
INFO / INITThe iframe has loaded and is ready to receive your CONFIG.
INFO / CONFIG_PROCESSEDYour configuration has been applied; safe to reveal the iframe.
ACTION / NAVIGATIONpath (String)The user navigated inside the iframe. Use this to keep your page's URL or active tab in sync.

Navigation paths

PathPage
homeLanding page
sendStart a cross-border transaction
recipientsSaved recipients
activityTransaction history
sender-profileSender information
fxEstimatorFX rate estimator

Example

<nav>
  <button id="btn-send">Send Money</button>
  <button id="btn-activity">Transaction History</button>
</nav>

<iframe id="vopay-embed" src="EMBED_LINK" allow="clipboard-write"
        style="width: 100%; height: 100%; border: none; visibility: hidden"></iframe>
const iframe = document.getElementById('vopay-embed');
const sendToIframe = (message) => iframe.contentWindow.postMessage(message, '*');

window.addEventListener('message', (event) => {
  if (!event.data) return;
  const { type, code, payload } = event.data;

  // 1. The iframe is ready — apply your configuration
  if (type === 'INFO' && code === 'INIT') {
    sendToIframe({
      type: 'ACTION',
      code: 'CONFIG',
      payload: {
        hideMenu: true,
        primaryColor: '#1257D0',
        timezone: 'America/Vancouver',
      },
    });
  }

  // 2. Configuration applied — reveal the iframe
  if (type === 'INFO' && code === 'CONFIG_PROCESSED') {
    iframe.style.visibility = 'visible';
  }

  // 3. Keep your UI in sync as the user moves around inside the iframe
  if (type === 'ACTION' && code === 'NAVIGATION') {
    console.log('User is now on:', payload.path);
  }
});

// Your own buttons drive the embedded experience
document.getElementById('btn-send').addEventListener('click', () =>
  sendToIframe({ type: 'ACTION', code: 'NAVIGATION', payload: { path: 'send' } }),
);
document.getElementById('btn-activity').addEventListener('click', () =>
  sendToIframe({ type: 'ACTION', code: 'NAVIGATION', payload: { path: 'activity' } }),
);
🚧

Verify the sender

In production, check event.origin against the origin of your embed link before acting on a message, and pass that origin as the second argument to postMessage instead of '*'.

Step 3: Live Balance Checks (Optional)

While not required, integrating live balance checks can significantly improve the success rate of cross-border transactions. By confirming sufficient funds before authorizing a transaction, you reduce declines and prevent the frustrating case where a transaction fails at the last step due to insufficient funds.

As a technology layer, VoPay does not participate in the flow of funds — we rely on an API that you provide for balance retrieval. During the embedded flow, VoPay calls your endpoint before allowing the end user to proceed.

What You Provide

1. A REST GET endpoint

A dedicated endpoint for fetching the sender's available balance, reachable from VoPay's servers:

GET https://api.yourcompany.com/card/{card_id}/balance

2. A JSON response with a named balance attribute

The response must be JSON, and you tell us which attribute represents the available balance:

{
  "card_id": "1234567890",
  "cardholder_name": "John Doe",
  "available_balance": 1500.00,
  "currency": "USD"
}

Here, available_balance is the attribute you would identify to VoPay.

3. An authentication method

Choose one of the supported methods and share the corresponding credentials:

MethodYou provide
API KeyA unique API key for authentication.
Bearer TokenA valid bearer token for authorization.
Basic AuthA username and password.

Ensure the credentials have sufficient permissions to access balance information. All credentials are stored encrypted following industry best practices.

📘

Configured in the Global Send Admin Dashboard

Balance checks are configured under Global Send Configuration → Transaction Processing — including your endpoint URL, when the balance is checked (on amount entry and/or at submission), and whether it must cover the send amount plus fees. See the companion Global Send Admin Dashboard guide.

Step 4: Transaction Review & Confirmation (Optional)

Once the end user has provided all the details for their cross-border transaction, there are two processing modes:

Immediate ProcessingWebhook Review & Confirmation
How it worksVoPay processes the transaction as soon as the user submits it.VoPay creates a pending transaction and notifies your endpoint. Nothing moves until you explicitly confirm.
Best forLow-risk transactions where speed matters most.Higher-value transactions, or when you need to run your own checks before funds are transferred.

The Review Flow

  1. Transaction created. When the user submits, VoPay creates a pending transaction and sends a webhook to your endpoint. The payload is a lightweight notification containing key fields, including the TransactionID.
  2. Fetch the full details. Pass the TransactionID from the webhook payload to GET /api/v2/gcm/withdraw/transaction (API reference) to retrieve the complete transaction record — sender, recipient, amounts, FX rate, and fees.
  3. Your checks. Your system performs whatever validation your business requires — live balance verification, AML screening, fraud prevention, or any custom rules.
  4. Your decision. Instruct VoPay to proceed or reject:

Both endpoints take the TransactionID from the webhook payload; cancel also accepts an optional CancellationReason. Confirmed transactions are processed through the Mastercard network.

📘

Configured in the Global Send Admin Dashboard

The processing mode is selected under Global Send Configuration → Transaction Processing: choose Automatic Submission for immediate processing or Manual Review to enable this review flow.

Transaction Status Updates via Webhooks

VoPay delivers real-time transaction status updates as POST requests with a JSON payload to a webhook endpoint you provide. Payload details are in the webhook documentation. Your webhook URL and real-time notification settings can be managed in the Global Send Admin Dashboard under Integration Settings.

Delivery & Retries

AttemptWhenTimeout
1Immediately on status change5 seconds
25 minutes after attempt 1 fails15 seconds
35 minutes after attempt 2 fails30 seconds

After three unsuccessful attempts, the notification is marked as deprecated and no further attempts are made.

🚧

Acknowledge every webhook

Your endpoint must return an HTTP 200 status code to confirm receipt — any other response counts as a failed attempt.

Retrieving Transaction & Contact Data

Use these endpoints to reconcile activity and build reporting on top of the embedded experience:

EndpointPurpose
GET /api/v2/gcm/withdraw/transactionsAPI referenceLists cross-border transactions on your account, filterable by date range and status.
GET /api/v2/gcm/withdraw/transactionAPI referenceReturns the full detail of a single cross-border transaction, including its current status, FX rate, and fees.
GET /api/v2/gcm/recipient-contactsAPI referenceRetrieves the recipients saved by your users — name, contact details, and IDs you can use to pre-populate future sessions via RecipientContactID.

Integration Process

1. Information Exchange

Provide the following to your VoPay integration contact:

  • Webhook endpoint URL for transaction status notifications
  • Whether you want webhook review & confirmation enabled (Step 4)
  • If using live balance checks: your REST GET endpoint URL
  • If using live balance checks: the JSON attribute name for the available balance
  • If using live balance checks: the authentication method and credentials (API key, bearer token, or username/password)

2. Testing & Validation

We conduct thorough testing in the sandbox environment to validate balance retrieval, webhook delivery, and transaction processing end to end.

3. Deployment

Once testing is successful, the complete integration — embedded experience, live balance checks, webhooks, and reporting — is deployed to production.

Support

Our support team is available to assist with any questions or issues during the integration process.


Did this page help you?