Send Cross Border Payments
This use case explains how to send international bank payments from your FV account using supported cross-border rails.
In this use case, we will perform a cross-border SEPA payment, but other payment types can be explored in the same way.
🔄 Flow Overview
Create Beneficiary → Add Payment Instrument → Upload File → Initiate Payment → Track Transaction
📊 Data Flow (IDs Across Steps)
BeneficiaryID → PaymentInstrumentID → FileId → TransactionID
✅ Prerequisites
- A valid
SessionToken - Include the following header in all requests:
X-AUTH-TOKEN: {{session_token}}
- (Optional but required for some payments) Upload a supporting document using the Files API to obtain a
FileId
Create Beneficiary
async function getFieldsForSEPA() {
try {
const response = await axios.post(
`${baseUrl}/beneficiary/create`,
[
{ "field": "Beneficiary_Type", "value": "individual" },
{ "field": "Beneficiary_Email", "value": "john.doe@example.com" },
{ "field": "Beneficiary_Address", "value": "123 Main Street" },
{ "field": "Beneficiary_City", "value": "New York" },
{ "field": "Beneficiary_Postal_Code", "value": "10001" },
{ "field": "Beneficiary_Country", "value": "US" },
…Response:
{
"ResponseData": {
"BeneficiaryId": "4650983997967871956",
"message": "Please allow 10 minutes for the beneficiary to turn Active. Once the beneficiary status is Active, You can create payment instruments."
}
}
Get Fields for Transfer Type (Cross Border SEPA)
async function getRequiredInstrumentFields() {
try {
const response = await axios.post(
`${baseUrl}/payment-instrument/get-required-fields`,
{
paymentType: "BUS_USD_Account.payment_cross_border_sepa"
},
{
headers: {
Authorization: `Bearer ${sessionToken}`,
"Content-Type": "application/json"
…Response
{
"ResponseCode": 200,
"ResponseMessage": "Success",
"ResponseData": {
"Fields": [
{
"Name": "BeneficiaryId",
"Required": true,
"Type": "Text"
},
{
…Note: List of countries will have lot more values we have shortended it for documentation purpose in the example above
Add Payment Instrument (Cross Border SEPA)
async function createSEPAPaymentInstrument() {
try {
const response = await axios.post(
`${baseUrl}/payment-instrument/create`,
[
{
"field": "Payment_Type",
"value": "Cross_Border_Payments.SEPA"
},
{
"field": "BeneficiaryId",
…Response:
{
ResponseCode: 200,
ResponseMessage: 'Success',
ResponseData: { PaymentInstrumentID: '-6477410681264623860' }
}
Upload Supporting Document
Use this endpoint to upload supporting documents (e.g., invoices) that can be attached to payments or other workflows.
const axios = require('axios');
const fs = require('fs');
const baseUrl = "https://sandbox.merchant.fvbank.us/v2";
const sessionToken = "your_session_token_here";
// 🔁 Update file path accordingly
const filePath = "/Users/rishav/Documents/Sample/Form_6_English.pdf";
async function uploadFile() {
try {
const response = await axios.post(
`${baseUrl}/files/upload?customField=Payment_Invoice&fileName=Ducket.pdf`,
fs.createReadStream(filePath),
…📌 Note
Refer to the Files Upload endpoint in the API Reference section to better understand:
- Supported file types
- Required query parameters (
customField,fileName) - How uploaded files are used across flows (e.g., attaching documents to payments)
{
"ResponseCode": 200,
"ResponseMessage": "Success",
"ResponseData": {
"ID": "-4004934485838221358"
}
}
Initiate Payment
💳 Create Cross Border Payment (Node.js)
Use this endpoint to initiate a bank payment (e.g., ACH/Wire) using a previously created payment instrument.
const axios = require('axios');
const baseUrl = "https://sandbox.merchant.fvbank.us/v2";
const sessionToken = "your_session_token_here";
async function createCrossBorderPayment() {
try {
const response = await axios.post(
`${baseUrl}/cross-border/send-payment`,
{
"BeneficiaryPaymentInstrumentID": "-6391842288344584436", // SEPA payment instrument ID
"Purpose": "Loan_Payments",
"Currency": "EUR",
…📌 Note
- use /cross-border/preview endpoint to get the expected FX rate for the transaction before making the transaction
SupportingDocumentis the File ID received after uploading a file via the Files Upload endpoint- Ensure all required compliance fields (e.g., Purpose, Description) are provided correctly
Below is the list of all the payment types we have available for cross border payments
| Rail | Payment_Type | Currency |
|---|---|---|
| SEPA | BUS_USD_Account.payment_cross_border_sepa | EUR |
| EUR Wire | BUS_USD_Account.payment_cross_border_eur_wire_payments | EUR |
| Faster Payments | BUS_USD_Account.payment_cross_border_faster_payments | GBP |
| GBP Wire | BUS_USD_Account.payment_cross_border_gbp_wire_payments | GBP |
| CAD Domestic | BUS_USD_Account.payment_cross_border_cad_domestic_payments | CAD |
| CAD Wire | BUS_USD_Account.payment_cross_border_cad_wire_payments | CAD |
| HKD Domestic | BUS_USD_Account.payment_cross_border_hkd_domestic_payments | HKD |
| HKD Wire | BUS_USD_Account.payment_cross_border_hkd_wire_payments | HKD |
| JPY Domestic | BUS_USD_Account.payment_cross_border_jpy_domestic_payments | JPY |
| JPY Wire | BUS_USD_Account.payment_cross_border_jpy_wire_payments | JPY |
| CLABE | BUS_USD_Account.payment_cross_border_clabe | MXN |
| MXN Wire | BUS_USD_Account.payment_cross_border_mxn_wire_payments | MXN |
| SGD Domestic | BUS_USD_Account.payment_cross_border_sgd_domestic_payments | SGD |
| SGD Wire | BUS_USD_Account.payment_cross_border_sgd_wire_payments | SGD |
| ZAR Domestic | BUS_USD_Account.payment_cross_border_zar_domestic_payments | ZAR |
| ZAR Wire | BUS_USD_Account.payment_cross_border_zar_wire_payments | ZAR |
| BRL Domestic | BUS_USD_Account.payment_cross_border_brl_domestic_payments | BRL |
| AED Domestic | BUS_USD_Account.payment_cross_border_aed_domestic_payments | AED |
| AED Wire | BUS_USD_Account.payment_cross_border_aed_wire_payments | AED |
Response:
{
"ResponseCode": 200,
"ResponseMessage": "Success",
"ResponseData": {
"TransactionNumber": "FV000007938"
}
}
Track Transaction Status
Use this endpoint to fetch detailed information about a specific transaction using the TransactionNumber.
const axios = require('axios');
const baseUrl = "https://sandbox.merchant.fvbank.us/v2";
const sessionToken = "your_session_token_here";
// 🔁 Replace with your actual Transaction Number
const transactionNumber = "FV000462103";
async function getTransactionDetails() {
try {
const response = await axios.get(
`${baseUrl}/transactions/details/${transactionNumber}`,
{
headers: {
…📌 Note
-
TransactionNumberis obtained from:-
Payment creation response
-
Transaction listing APIs
-
Webhook payloads
-
-
Use this endpoint to:
-
Track transaction status
-
View complete transaction details
-
Reconcile payments in your system
-
⚠️ Common Errors
- Missing or invalid
SessionToken - Incorrect
BeneficiaryIDorPaymentInstrumentID - Missing
SupportingDocumentwhen required - Invalid bank details (routing/account number)
- Expired session without refresh handling
📌 Summary
BeneficiaryID → PaymentInstrumentID → FileId → TransactionID
This flow can be reused for all cross border payment types by adjusting the Payment_Type and required banking details.