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
- Generate an embed URL. Your backend calls
POST /gcm/generate-embed-urland loads the returned link in an iframe within your web application. - 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.
- 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.
- 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
| Environment | Base URL |
|---|---|
| Sandbox | https://earthnode-dev.vopay.com/api/v2 |
| Production | https://earthnode.vopay.com/api/v2 |
Every API request is authenticated with three parameters:
| Parameter | Type | Description |
|---|---|---|
AccountID | String | The unique identifier for your VoPay account. |
Key | String | The API key associated with the AccountID. |
Signature | String | A 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-url — API reference
Request Parameters
| Parameter | Description | |
|---|---|---|
AccountID | Required | Your VoPay account ID. |
Key | Required | Your API key. |
Signature | Required | Request signature (see Authentication above). |
ClientAccountID | Optional | The client account (sender) the session is created for. Defaults to your primary client account. |
ClientName | Optional | Display name shown in the experience. Defaults to your account name. |
ClientReferenceNumber | Optional | Your internal reference for the session, echoed back in reporting. |
RecipientContactID | Optional | Pre-selects a saved recipient so the user skips recipient entry. |
DeliveryChannelID | Optional | Pre-selects the destination corridor and payout method. |
BuyAmount | Optional | Pre-fills the amount the recipient receives. Cannot be combined with SellAmount. |
SellAmount | Optional | Pre-fills the amount the sender pays. Cannot be combined with BuyAmount. |
Language | Optional | UI language code (e.g. en, fr). Defaults to en. |
DarkMode | Optional | Set to true to render the experience in dark mode. |
StylesheetUrl | Optional | URL 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"
}| Field | Type | Description |
|---|---|---|
Link | String | The embeddable URL. Load it in an iframe or open it as a link. |
IframeKey | String | Identifies 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
- Generate the signature on your backend per the Authentication Guidelines.
- Send the request to
/gcm/generate-embed-urlwith any optional parameters you need. - Parse the response to obtain the
Link. - Embed the link in an iframe within your page. The user completes the entire transaction inside it.
One session, one linkGenerate a fresh embed URL per user session — treat the
Linkas 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
- The iframe finishes loading and posts
INFO / INITto your page. - Your page replies with
ACTION / CONFIGcontaining your configuration. - The iframe applies it and acknowledges with
INFO / CONFIG_PROCESSED.
Avoid the menu flashKeep the iframe hidden (e.g.
visibility: hidden) untilCONFIG_PROCESSEDarrives — this prevents the menu from flashing briefly before your configuration is applied.
Messages you can send to the iframe
| Message | Payload | Effect |
|---|---|---|
ACTION / CONFIG | hideMenu (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 / NAVIGATION | path (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
| Message | Payload | Meaning |
|---|---|---|
INFO / INIT | — | The iframe has loaded and is ready to receive your CONFIG. |
INFO / CONFIG_PROCESSED | — | Your configuration has been applied; safe to reveal the iframe. |
ACTION / NAVIGATION | path (String) | The user navigated inside the iframe. Use this to keep your page's URL or active tab in sync. |
Navigation paths
| Path | Page |
|---|---|
home | Landing page |
send | Start a cross-border transaction |
recipients | Saved recipients |
activity | Transaction history |
sender-profile | Sender information |
fxEstimator | FX 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 senderIn production, check
event.originagainst the origin of your embed link before acting on a message, and pass that origin as the second argument topostMessageinstead 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:
| Method | You provide |
|---|---|
| API Key | A unique API key for authentication. |
| Bearer Token | A valid bearer token for authorization. |
| Basic Auth | A 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 DashboardBalance 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 Processing | Webhook Review & Confirmation | |
|---|---|---|
| How it works | VoPay 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 for | Low-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
- 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. - Fetch the full details. Pass the
TransactionIDfrom the webhook payload toGET /api/v2/gcm/withdraw/transaction(API reference) to retrieve the complete transaction record — sender, recipient, amounts, FX rate, and fees. - Your checks. Your system performs whatever validation your business requires — live balance verification, AML screening, fraud prevention, or any custom rules.
- Your decision. Instruct VoPay to proceed or reject:
POST /api/v2/gcm/withdraw/confirm— API referencePOST /api/v2/gcm/withdraw/cancel— API reference
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 DashboardThe 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
| Attempt | When | Timeout |
|---|---|---|
| 1 | Immediately on status change | 5 seconds |
| 2 | 5 minutes after attempt 1 fails | 15 seconds |
| 3 | 5 minutes after attempt 2 fails | 30 seconds |
After three unsuccessful attempts, the notification is marked as deprecated and no further attempts are made.
Acknowledge every webhookYour endpoint must return an HTTP
200status 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:
| Endpoint | Purpose |
|---|---|
GET /api/v2/gcm/withdraw/transactions — API reference | Lists cross-border transactions on your account, filterable by date range and status. |
GET /api/v2/gcm/withdraw/transaction — API reference | Returns the full detail of a single cross-border transaction, including its current status, FX rate, and fees. |
GET /api/v2/gcm/recipient-contacts — API reference | Retrieves 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.
Updated about 6 hours ago