How to get started

Start building your integration

Expand your global reach with Belmoney’s international payout infrastructure. Find all the information you need to start using Belmoney products.

RAAS Integration

Integration to use RaaS

Incoming Part
Authentication Method

In order to connect to our Web API application, you must have an APIKey and APISecret values >to construct the header for all your request in the following form:

Requires APIKey and APISecret.
Header format: Authorization: APIAuth checksum

Creating the checksum

The checksum is a combination of APIKey, APISecret and a timestamp value of the current instance you are sending the request, separated by semicolons ‘:’ and the result will be in a Base64 SHA1 HMAC string.


Creating the hash

The hash is a combination of the timestamp mentioned above in the following format YYYYMMDD_HHmmss, in UTC within 1 hour of the actual request, encrypted with the APISecret value, using the SHA1 HMAC 512 bit encoding and the result will be in a Base64 as well. For more details about the Authentication Hash process, please read the Detail and find refer to this file: File download.

Process Summary Timestamp:

  1. Create a timestamp in the format YYYYMMDD_HHmmss.
  2. Hash: Sign the timestamp using HMAC-SHA1 and APISecret ass a key.
  3. Token APIAuth: Concatene APIKey, Timestamp, and Hash.
  4. Request header: AddAuthorization: APIAuth with the constructed value.

Here is some code to perform this entire process. If you want to do it in your favourite programming language, just use the same patterns.

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // Sample API key and secret for demonstration
        String apiKey = "1d/beqphsf2ulqghm8mcga==";
        String apiSecret = "NRz6GwT0Ci1S5lQKaJmiu+f8oCa5RrnlEPv4v0cETY2JxlOj2+ndifD1+4MXQxgYdZS1//dfgw6k2DB4v2HHtw==";

        // Generate and print the authentication token
        String authToken = generateApiAuthToken(apiKey, apiSecret);
        System.out.println("Generated API Authentication Token: " + authToken);
    }

    public static String generateApiAuthToken(String apiKey, String apiSecret) {
        try {
            System.out.println("Starting authentication");
            // Get the current date-time in the format YYYYMMDD_HHMMSS
            String date = getCurrentDateTime();
            // Generate the HMAC-SHA512 signature
            String sig = generateHmacSha512(date, apiSecret);
            // Convert the signature to binary
            byte[] sigBinary = hexStringToByteArray(sig);
            // Encode to Base64
            String sigBase64 = Base64.getEncoder().encodeToString(sigBinary);
            // Create the authInfo
            String authInfo = Base64.getEncoder()
                    .encodeToString((apiKey + ":" + date + ":" + sigBase64).getBytes(StandardCharsets.UTF_8));
            return authInfo;
        } catch (Exception e) {
            System.err.println("Error generating API authentication token: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static String getCurrentDateTime() {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss").withZone(ZoneOffset.UTC);
            return formatter.format(Instant.now());
        } catch (Exception e) {
            System.err.println("Error getting current date and time: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static String generateHmacSha512(String data, String key) {
        try {
            Mac mac = Mac.getInstance("HmacSHA512");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA512");
            mac.init(secretKeySpec);
            byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (Exception e) {
            System.err.println("Error generating HMAC-SHA512 signature: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static String bytesToHex(byte[] bytes) {
        try {
            StringBuilder hexString = new StringBuilder();
            for (byte b : bytes) {
                hexString.append(String.format("%02x", b));
            }
            return hexString.toString();
        } catch (Exception e) {
            System.err.println("Error converting bytes to hex: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static byte[] hexStringToByteArray(String hex) {
        try {
            int length = hex.length();
            byte[] bytes = new byte[length / 2];
            for (int i = 0; i < length; i += 2) {
                bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16));
            }
            return bytes;
        } catch (Exception e) {
            System.err.println("Error converting hex to byte array: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }
}

 

The PayerNetworkList API retrieves detailed information about the payment network of a specific payer. This includes:

  • Branches (locations where transactions can be processed)

  • Accepted payment types (cash pick-up, bank deposit, wallet top-up)

  • Accepted currencies (which currencies the payer supports)

  • Physical location points (specific addresses where transactions can be completed)

Request Details
Endpoint: POST /api/Incoming/PayerNetworkList
Method: POST
Purpose: Fetches details about the payment network for a specific payer (PayerID).

Headers

  • Authorization: APIAuth (API authentication token required)

  • Accept: application/json (ensures the API responds in JSON)

  • Content-Type: application/json (request body is JSON format)

Request Body
Must include the PayerID (the unique ID of the payer whose network you want to query).


{
"PayerID": 858
}

If the request is successful (200 OK), the API returns a list of branches and payment options for the payer.

{
  "Results": [
    {
      "PayerBranchID": 23979,
      "PayerBranchName": "Company",
      "Address1": "Company - # Limit - 80.000 per day",
      "Address2": null,
      "CityName": "CASABLANCA",
      "StateCode": "null",
      "CountryCode": "MA",
      "PhoneNumber": null,
      "PayAllCities": true,
      "HasLocations": true,
      "PaymentTypes": [1, 2, 6],
      "Currencies": ["MAD"]
    }
  ]
}

Explanation of Fields

  1. Payer Branch Information

  • PayerBranchID: Unique ID of the payer branch used to map which country you want to send the transaction to.

  • PayerBranchName: Branch name (e.g., “Belmoney”)

  • Address1: Branch address, sometimes with extra info (e.g., daily limit)

  • Address2: Additional address details (if available)

  • CityName: City where the branch is located (e.g., “Belgium”)

  • StateCode: State or province code (if applicable)

  • CountryCode: ISO country code (e.g., “MA” for Morocco)

  • PhoneNumber: Branch phone number (if available)

  • PayAllCities: Indicates whether payments are accepted from all cities

  • HasLocations: Indicates whether the branch has physical locations

  1. Accepted Payment Methods

  • PaymentTypes: List of accepted payment types (IDs)

  • Currencies: List of currencies accepted by the branch

Accepted Payment Types
1: Account Deposit (Bank Transfer)
2: Office Pick-Up (Cash Collection)
3: Bank Pick-Up
4: Home Delivery
5: Card Top-Up
6: Wallet Top-Up
7: Pix (Brazilian Instant Payment System)

The  PreRegister endpoint used to pre-register a transfer before its finalization. This allows validating sender, beneficiary, and payment details before officially registering the transaction.

Request Details
Endpoint: POST /api/Incoming/PreRegister
Method: POST
Purpose: Create a pre-registration of the transaction, generating a unique TransferID.

The request body must be in JSON format and include details about:

  • The transfer (TransferID, Reference, Reason)
  • The sender (Name, Adress, DOB, ID’s, ETC)
  • The beneficiary (Name, Adress, Contact,ETC.)
  • Transaction details (Amount, Rate, Fees, Currency, Payment Details)


Example Request 

{
  "TransferID": null,
  "Reference": "47",
  "TransferPIN": "",
  "TransConfirmation": null,
  "TransferReasonID": 17,
  "Sender": {
    "AgencyReference": 3851, 
    "FirstName": "Test",
    "MiddleName": null,
    "LastName": "Testing",
    "SecondLastName": null,
    "Address1": "NA NA",
    "CountryCode": "IT",
    "StateName": "Italy",
    "CityCode": "",
    "CityName": "NA",
    "ZipCode": "NA",
    "DOB": "1989-08-03",
    "PhoneNumber": "+393397962812",
    "CellPhoneNumber": null,
    "PrimaryPhoneNumber": null,
    "PhoneNumberCountryCode": null,
    "Email": "123@yahoo.com",
    "Sex": "M",
    "BirthCityName": "",
    "BirthCountryCode": "Milan",
    "CitizenshipCountryCode": "IT",
    "ProfessionID": 68,
    "PEPTypeID": 2,
    "SenderTypeID": 1,
    "Documents": [],
    "IDs": [
      {
        "IDIssuedDate": "2020-12-31T00:00:00.000Z",
        "IDExpirationDate": "2030-01-01T00:00:00.000Z",
        "IssuedCountryCode": "IT",
        "Authority": null,
        "IDCopy": true,
        "IDType": "2",
        "IDNo": "afdg32165ag"
      }
    ]
  },
  "Beneficiary": {
    "AgencyReference": 45688,
    "FirstName": "Belmoney",
    "MiddleName": null,
    "LastName": "Testing",
    "SecondLastName": null,
    "Address1": "Nigeria",
    "CountryCode": "NG",
    "CityCode": null,
    "CityName": "Nigeria",
    "ZipCode": null,
    "PhoneNumber": "+2348110357777",
    "CellPhoneNumber": "",
    "PrimaryPhoneNumber": "",
    "Email": "benef@benef.com",
    "RelationshipToSenderID": 10,
    "IDs": []
  },
  "AmountAndFees": {
    "PaymentAmount": 44375,
    "OriginalAmount": 25,
    "Rate": "1775.00",
    "RateID": 1,
    "PayerCurrencyCode": "EUR",
    "PaymentCurrencyCode": "NGN",
    "PercentFee": 0,
    "FlatFee": 1.99,
    "OtherFee": 0,
    "Tax": 0,
    "FeesTax": 0,
    "Discount": 0,
    "BirthCountryCode": "NGN"
  },
  "Payment": {
    "PayerBranchReference": "24076",
    "PaymentTypeID": "1",
    "LocationCode": null,
    "BankAccount": {
      "Code": 872,
      "Name": "9 Payment Service Bank",
      "BranchCode": "any branch",
      "BranchName": "any branch",
      "AccountType": 1,
      "AccountNo": "3116835661313"
    }
  },
  "Notes": [],
  "CreationDate": ""
}
Explanation of Fields

Transfer Details

(✅ Yes) – Required

(❌ No) – No Required

  • TransferID (❌ No) – Unique transaction ID (set to null when creating a new transfer).

  • Reference (✅ Yes) – Your reference for the transfer.

  • TransferPIN (❌ No) – Can be a number generated by your standards; if omitted, the system generates one automatically.

  • TransConfirmation (❌ No) – Transaction confirmation status.

  • TransferReasonID (✅ Yes) – Reason for the transfer (e.g.,1=Personal Remittance).


Sender Details
  • FirstName (✅ Yes) – Sender’s first name.

  • LastName (✅ Yes) – Sender’s last name.

  • Address1 (✅ Yes) – Sender’s full address.

  • CountryCode (✅ Yes) – Sender’s country code (ISO 3166).

  • CityName (✅ Yes) – Sender’s city.

  • ZipCode (✅ Yes) – Postal code of the sender.

  • DOB (✅ Yes) – Date of birth in ISO 8601 format.

  • IDs (✅ Yes) – List of identification documents for the sender.


Beneficiary Details
  • FirstName (✅ Yes) – Beneficiary’s first name.

  • LastName (✅ Yes) – Beneficiary’s last name.

  • CountryCode (✅ Yes) – Beneficiary’s country code (ISO 3166).

  • CityName (✅ Yes) – Beneficiary’s city.

  • RelationshipToSenderID (✅ Yes) – Relationship between sender and beneficiary.


Amount & Fees
  • PaymentAmount (✅ Yes) – Total transfer amount.

  • OriginalAmount (✅ Yes) – Amount before conversion.

  • Rate (✅ Yes) – Exchange rate applied.

  • PayerCurrencyCode (✅ Yes) – Currency of the sender.

  • PaymentCurrencyCode (✅ Yes) – Currency of the receiver.

Introduction to the Payment Gateway

Belmoney operates its own PCI Level 1 certified payment gateway, providing a robust and secure infrastructure that connects your business with multiple payment processors. Our gateway goes beyond simple transaction processing — it acts as a powerful payment orchestration layer, intelligently routing transactions across multiple providers to maximize approval rates and minimize declines. With built-in smart retry logic and dynamic routing, our platform actively increases payment acceptance rates while reducing fraud, false positives, and problematic transactions through advanced security layers.

Integration with the Payment Gateway

After capturing the payment instructions, you must complete the following steps:

  1. Pre-register the transaction with the payment instructions via our gateway API.
  2. Capture the client payment through card processor (debit/credit card, Google Pay, Apple Pay, Account to Account)
  3. Confirm the transaction by submitting the payment confirmation information back to our gateway.

The Agent confirms the transfer and passes the payment confirmation information on at the Confirm.

Request Details
Endpoint: POST /api/Incoming/Confirm
Method: POST
Purpose: It validates and finalizes the payment so that the remittance process can proceed to the next stage. 

{
"Reference": "NML118",
"TransferPayment": {
"PaymentTypeID": "3",
"PaymentConfirmationCode": "34f72032-594f-44d2-955e-99f0f61067d8",
"PaymentProcessorCode": "PayCross",
"PaymentProcessorFullResponse": "[{\"time\": \"11:40:09\", \"data\": {\"history\": [{\"transactionStatus\": \"SUCCESS\", \"reasonCode\": \"S100\", \"reasonMessage\": \"Authorised\", \"timeStamp\": \"2025-07-01T11:40:07.993+01:00\"}], \"locale\": \"en_GB\", \"processing\": {\"model\": \"MANAGE\", \"authResponse\": {\"statusCode\": \"00\", \"acquirerName\": \"AIB Merchant Services\", \"message\": \"Approved \\u2013 Account Verification Approval\", \"authCode\": \"EVEJ6D\", \"gatewayReference\": \"8acda4a697ab4aca0197c59292773c16\", \"gatewayCode\": \"000.000.000\", \"gatewayMessage\": \"Transaction succeeded\", \"avsAddressCheck\": \"FULL_MATCH\", \"avsPostcodeCheck\": \"FULL_MATCH\", \"cv2Check\": \"MATCHED\", \"status\": \"AUTHORISED\"}, \"route\": \"PAYON\"}, \"customFields\": {}, \"paymentMethod\": {\"registered\": true, \"card\": {\"cardToken\": \"MT_rAzy5GfxSJqy4tMTL_WpIQ\", \"cardFingerprint\": \"Q1MtNmYyODllMGMtMzczNy00OWRlLTg4OWUtNzgyZTBiMzk2ODli\", \"new\": true, \"cardType\": \"MC_DEBIT\", \"cardUsageType\": \"DEBIT\", \"cardScheme\": \"MASTERCARD\", \"cardCategory\": \"COMMERCIAL\", \"maskedPan\": \"516760******4893\", \"expiryDate\": \"0928\", \"issuer\": \"REVOLUT LTD\", \"issuerCountry\": \"IRL\", \"cardHolderName\": \"Nawaf ali\", \"cardNickname\": \"Nawaf ali\"}, \"billingAddress\": {\"line1\": \"7 Tandys Crescent\", \"line2\": \"\", \"line3\": \"\", \"line4\": \"\", \"city\": \"Lucan\", \"region\": \"\", \"postcode\": \"K78 P9F7\", \"country\": \"Ireland\", \"countryCode\": \"IRL\"}, \"paymentClass\": \"CARD\", \"reuse\": {\"storage\": \"NEW\", \"agreement\": \"ADHOC\", \"receivedSchemeReference\": \"BPDE51QE60701\"}}, \"customer\": {\"merchantRef\": \"14162\", \"id\": \"13894496\", \"displayName\": \"NAWAF ALI\", \"billingAddress\": {\"line1\": \"7 Tandys Crescent\", \"line2\": \"\", \"city\": \"Lucan\", \"region\": \"\", \"postcode\": \"K78 P9F7\", \"country\": \"Ireland\", \"countryCode\": \"IRL\"}, \"email\": \"hnawaf@hotmail.com\", \"telephone\": \"+353862118116\", \"defaultCurrency\": \"EUR\", \"ip\": \"83.111.92.116\", \"registered\": true}, \"transaction\": {\"transactionId\": \"11695488667\", \"merchantRef\": \"2579289\", \"merchantDescription\": \"Altras International\", \"status\": \"SUCCESS\", \"stage\": \"COMPLETE\", \"type\": \"PAYMENT\", \"amount\": 6.49, \"consumerSpend\": 6.49, \"currency\": \"EUR\", \"transactionTime\": \"2025-07-01T11:40:06.311+01:00\", \"receivedTime\": \"2025-07-01T11:40:06.311+01:00\", \"channel\": \"WEB\", \"customerInitiated\": true}, \"sessionId\": \"SMToVGmVmaMZIwJ_H_aUCXcMt\", \"strongCustomerAuthentication\": {\"challengeRequested\": \"NO_CHALLENGE_REQUESTED\", \"merchantRisk\": {\"deliveryTimeframe\": \"ELECTRONIC\", \"shippingTo\": \"DIGITAL\"}, \"accountInfo\": {\"accountOpened\": {\"date\": \"2016-11-07\"}, \"accountLastChanged\": {\"date\": \"2025-07-01\"}, \"passwordLastChanged\": {\"date\": \"2025-07-01\"}, \"activity\": {\"purchasesInLastSixMonths\": 17, \"transactionAttemptsInLastYear\": 25}, \"suspiciousActivity\": false}, \"authenticationInfo\": {\"method\": \"MERCHANT_CREDENTIAL\", \"time\": \"2020-09-14T22:42:28\"}}, \"installationId\": \"8000134\"}}]"
 }
}

adsa

The AddSenderDocumentsAPI is used to upload sender documents in a remittance transfer system. This ensures compliance and verification during the transaction process. 

Request Details
Endpoint: POST /api/Incoming/AddSenderDocuments
Method: POST
Purpose: Uploads sender documents in base64 format for a remittance transaction

{
{
  "TransferID": "1027275000000068", 
  "Documents": [
    {
      "TypeID": 2, 
      "DocumentData": "iVBORw0KGgoAAAANSUhEUgAAAUMAAAFwCAIAAACtv45TAAAA..."
    }
  ]
}

Explanation of Fields

  • TransferID 
    The unique identifier for the remittance transaction.

  • Documents
    A list of documents being uploaded.

  • TypeID 
    The document type ID (see list below).

  • DocumentData 
    The document file in base64 format.

Available TypeID Values (Document Types)
Each document must have a TypeID, which determines the type of file being uploaded:

  • 1 – General

  • 2 – Identification (e.g., passport, ID card)

  • 3 – Proof of Address (e.g., utility bill, bank statement)

  • 4 – Compliance (e.g., compliance-related documents)

  • 5 – KYC Form (Know Your Customer form)

The AddSenderSelfieVideoAPI is used to upload sender documents in a remittance transfer system. This ensures compliance and verification during the transaction process. 

Request Details
Endpoint: POST /api/Incoming/AddSenderSelfieVideo
Method: POST
Purpose: Uploads sender video selfie in base64 format for a remittance transaction

{
  "TransferID": "1027275000000068",
  "VideoData": "iVBORw0KGgoAAAANSUhEUgAAAUMAAAFwCAIAAACtv45TAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAACCOSURBVHhe7Z0tlyo704b5B49EIkduiUSORI5EIpHzE5BI1quQSCQSiTlrIUcikUhkv0kq3Z2PygfMMHum9n2tWedsQndSqeTupEN3atAAAH4/"
}

Explanation of Fields

  • TransferID 
    The unique identifier for the remittance transaction.

  • VideoData
    A video being uploaded.

The Statuses API is used to check the status of the order for a remittance transfer system.

Request Details
Endpoint: POST /api/Incoming/Statuses
Method: POST
Purpose: Check the status of the order for a remittance transaction. The request body must be in JSON format and include details about: The remittance transfer (Reference) The request is in x www form urlencoded to view transaction statuses via your transaction reference.

Outgoing Part

The NewList  API is used to retrieve a list of outgoing transactions that have not been processed yet. This endpoint track release transactions after compliance relesead and identify which ones need further action.

Request Details
Endpoint: GET /api//Outgoing/NewList
Method: GET
Purpose: Retrieves a list of outgoing remittance transactions that are still pending and not yet processed.

Example response:

{
    "References": [
        "368",
        "369",
        "370"
    ],
    "Errors": null,
    "HasErrors": false
}

Explanation of Fields

  • References
    A list of transaction reference numbers that are still pending.

  • Errors
    If any errors occur, this field will contain error messages. If no errors, it returns null.

  • HasErrors
    Indicates whether an error occurred during the request (true = yes, false = no).

The NewList{rerence} API is used to check more information from a specific transaction not processed yet.

Request Details
Endpoint: GET /api//Outgoing/New/368
Method: GET
Purpose: Retrieves more information from a specific transaction not processed yet.

Example response:

{
    "Transfer": {
        "TransferID": null,
        "Reference": "371",
        "TransferPIN": "991919141",
        "TransConfirmation": null,
        "TransferReasonID": null,
        "Sender": {
            "AgencyReference": "1027277000000265",
            "FirstName": "Vitin",
            "MiddleName": null,
            "LastName": "Lucas",
            "SecondLastName": null,
            "Address1": "Madrid",
            "CountryCode": "ES",
            "StateCode": null,
            "StateName": "Madrid",
            "CityCode": null,
            "CityName": "",
            "ZipCode": "1818094113",
            "DOB": "1996-03-28T00:00:00",
            "PhoneNumber": "971-123451234",
            "CellPhoneNumber": "971-123451234",
            "PrimaryPhoneNumber": "971-123451234",
            "PhoneNumberCountryCode": null,
            "Email": "V23itl1lucas@bel.money",
            "Sex": "M",
            "BirthCityName": "Brazil",
            "BirthCountryCode": "BR",
            "CitizenshipCountryCode": null,
            "ProfessionID": null,
            "PEPTypeID": 2,
            "SenderTypeID": null,
            "IDs": [
                {
                    "IDIssuedDate": "2025-03-07T00:00:00",
                    "IDExpirationDate": "2027-06-05T00:00:00",
                    "IssuedCountryCode": "BR",
                    "Authority": "Ajman",
                    "IDCopy": false,
                    "IDType": 5,
                    "IDNo": "FU018804"
                }
            ],
            "Documents": null
        },
        "Beneficiary": {
            "AgencyReference": "1027277000000578",
            "FirstName": "RAJESH",
            "MiddleName": null,
            "LastName": "PANDIT",
            "SecondLastName": null,
            "Address1": "sdf23456",
            "CountryCode": "BJ",
            "StateCode": null,
            "CityCode": 280,
            "CityName": "ABOMEY",
            "ZipCode": null,
            "PhoneNumber": "229-1234567890",
            "CellPhoneNumber": "229-1234567890",
            "PrimaryPhoneNumber": "229-1234567890",
            "Email": null,
            "RelationshipToSenderID": null,
            "IDs": [
                {
                    "IDCopy": false,
                    "IDType": 0,
                    "IDNo": null
                }
            ]
        },
        "AmountAndFees": {
            "PaymentAmount": 10.05,
            "OriginalAmount": 10,
            "Rate": 1.05,
            "RateID": 1,
            "PayerCurrencyCode": "EUR",
            "PaymentCurrencyCode": "USD",
            "PercentFee": null,
            "FlatFee": null,
            "OtherFee": null,
            "Tax": null,
            "FeesTax": null,
            "Discount": null,
            "TokenId": null
        },
        "Payment": {
            "PayerBranchReference": "27200",
            "PaymentTypeID": 2,
            "LocationCode": null,
            "BankAccount": null
        },
        "TransferPayment": null,
        "Notes": null,
        "CreationDate": "0001-01-01T00:00:00"
    },
    "Errors": null,
    "HasErrors": false
}


Explanation of Fields

  • References
    A list of transaction reference numbers that are still pending.

  • Errors
    If any errors occur, this field will contain error messages. If no errors, it returns null.

  • HasErrors
    Indicates whether an error occurred during the request (true = yes, false = no).

The UpdateRate API is used to update the exchange rate of a specific outgoing remittance transaction.

Request Details
Endpoint: https://apps.belmoneylabs.org/WebAPI-UAT/RemittanceTransfers/api/Outgoing/UpdateRate
Method: POST
Purpose: Updates the exchange rate (Rate) for a given transaction.

Example response:

{
  "Rate": 11500,
  "Note": "Test API - UpdateRate",
  "Reference": "368"
}'

Explanation of Fields

  • References
    A list of transaction reference numbers that are still pending.

  • Errors
    If any errors occur, this field will contain error messages. If no errors, it returns null.

  • HasErrors

    Indicates whether an error occurred during the request (true = yes, false = no).

The Processing API is used to update the status of an outgoing transaction to “in process”. This means the transaction has started but has not yet been completed or paid.

Request Details
Endpoint: https://apps.belmoneylabs.org/WebAPI-UAT/RemittanceTransfers/api/Outgoing/Processing
Method: POST
Purpose: Updates the exchange rate (Rate) for a given transaction.

Example response:

{
  "ConfirmationReference": 371,
  "Note": "Test Processing",
  "Reference": "371"
}'

How the Request Works

  1. The request is sent with a transaction reference to update its status.
  2. The API processes the request and marks the transaction as “in process”.
  3. A response is returned, confirming whether the update was successful.

The Paid API is used to mark a transaction as paid. This is typically done when the recipient has received the funds successfully.

Request Details
Endpoint: https://apps.belmoneylabs.org/WebAPI-UAT/RemittanceTransfers/api/Outgoing/Paid
Method: POST
Purpose: Marks a transaction as paid based on a provided reference.

Example response:

{
  "ConfirmationReference": 371,
  "Note": "Paid",
  "Reference": "371"
}'

How the Request Works

  1. The request is sent with a transaction reference to update its status.
  2. The API processes the update and marks the transaction as completed
  3. A response is returned, confirming whether the update was successful.

The Cancel is used to mark a transaction as canceled and this is needed when the transaction is canceled by the payer to notify Belmoney that the transaction was cancelled.

Request Details
Endpoint: https://apps.belmoneylabs.org/WebAPI-UAT/RemittanceTransfers/api/Outgoing/Cancel
Method: POST
Purpose: Marks a transaction as canceled based on a provided reference.

Example response:

{
  "ConfirmationReference": 371,
  "Note": "Cancel",
  "Reference": "371"
}'

How the Request Works

  1. The request is sent with a transaction reference to update its status.
  2. The API processes the update and marks the transaction as completed
  3. A response is returned, onfirming whether the cancellation was successful.

Payment Agregator Integration

Integration to use Payment Aggregator HUB

Incoming Part
Authentication Method

In order to connect to our Web API application, you must have an APIKey and APISecret values >to construct the header for all your request in the following form:

Requires APIKey and APISecret.
Header format: Authorization: APIAuth checksum

Creating the checksum

The checksum is a combination of APIKey, APISecret and a timestamp value of the current instance you are sending the request, separated by semicolons ‘:’ and the result will be in a Base64 SHA1 HMAC string.


Creating the hash

The hash is a combination of the timestamp mentioned above in the following format YYYYMMDD_HHmmss, in UTC within 1 hour of the actual request, encrypted with the APISecret value, using the SHA1 HMAC 512 bit encoding and the result will be in a Base64 as well. For more details about the Authentication Hash process, please read the Detail and find refer to this file: File download.

Process Summary Timestamp:

  1. Create a timestamp in the format YYYYMMDD_HHmmss.
  2. Hash: Sign the timestamp using HMAC-SHA1 and APISecret ass a key.
  3. Token APIAuth: Concatene APIKey, Timestamp, and Hash.
  4. Request header: AddAuthorization: APIAuth with the constructed value.

Here is some code to perform this entire process. If you want to do it in your favourite programming language, just use the same patterns.

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        // Sample API key and secret for demonstration
        String apiKey = "1d/beqphsf2ulqghm8mcga==";
        String apiSecret = "NRz6GwT0Ci1S5lQKaJmiu+f8oCa5RrnlEPv4v0cETY2JxlOj2+ndifD1+4MXQxgYdZS1//dfgw6k2DB4v2HHtw==";

        // Generate and print the authentication token
        String authToken = generateApiAuthToken(apiKey, apiSecret);
        System.out.println("Generated API Authentication Token: " + authToken);
    }

    public static String generateApiAuthToken(String apiKey, String apiSecret) {
        try {
            System.out.println("Starting authentication");
            // Get the current date-time in the format YYYYMMDD_HHMMSS
            String date = getCurrentDateTime();
            // Generate the HMAC-SHA512 signature
            String sig = generateHmacSha512(date, apiSecret);
            // Convert the signature to binary
            byte[] sigBinary = hexStringToByteArray(sig);
            // Encode to Base64
            String sigBase64 = Base64.getEncoder().encodeToString(sigBinary);
            // Create the authInfo
            String authInfo = Base64.getEncoder()
                    .encodeToString((apiKey + ":" + date + ":" + sigBase64).getBytes(StandardCharsets.UTF_8));
            return authInfo;
        } catch (Exception e) {
            System.err.println("Error generating API authentication token: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static String getCurrentDateTime() {
        try {
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss").withZone(ZoneOffset.UTC);
            return formatter.format(Instant.now());
        } catch (Exception e) {
            System.err.println("Error getting current date and time: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static String generateHmacSha512(String data, String key) {
        try {
            Mac mac = Mac.getInstance("HmacSHA512");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA512");
            mac.init(secretKeySpec);
            byte[] hash = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
            return bytesToHex(hash);
        } catch (Exception e) {
            System.err.println("Error generating HMAC-SHA512 signature: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static String bytesToHex(byte[] bytes) {
        try {
            StringBuilder hexString = new StringBuilder();
            for (byte b : bytes) {
                hexString.append(String.format("%02x", b));
            }
            return hexString.toString();
        } catch (Exception e) {
            System.err.println("Error converting bytes to hex: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }

    private static byte[] hexStringToByteArray(String hex) {
        try {
            int length = hex.length();
            byte[] bytes = new byte[length / 2];
            for (int i = 0; i < length; i += 2) {
                bytes[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16));
            }
            return bytes;
        } catch (Exception e) {
            System.err.println("Error converting hex to byte array: " + e.getMessage());
            e.printStackTrace();
            return null;
        }
    }
}

 

The PayerNetworkList API retrieves detailed information about the payment network of a specific payer. This includes:

  • Branches (locations where transactions can be processed)

  • Accepted payment types (cash pick-up, bank deposit, wallet top-up)

  • Accepted currencies (which currencies the payer supports)

  • Physical location points (specific addresses where transactions can be completed)

Request Details
Endpoint: POST /api/Incoming/PayerNetworkList
Method: POST
Purpose: Fetches details about the payment network for a specific payer (PayerID).

Headers

  • Authorization: APIAuth (API authentication token required)

  • Accept: application/json (ensures the API responds in JSON)

  • Content-Type: application/json (request body is JSON format)

Request Body
Must include the PayerID (the unique ID of the payer whose network you want to query).


{
"PayerID": 858
}

If the request is successful (200 OK), the API returns a list of branches and payment options for the payer.

{
  "Results": [
    {
      "PayerBranchID": 23979,
      "PayerBranchName": "Company",
      "Address1": "Company - # Limit - 80.000 per day",
      "Address2": null,
      "CityName": "CASABLANCA",
      "StateCode": "null",
      "CountryCode": "MA",
      "PhoneNumber": null,
      "PayAllCities": true,
      "HasLocations": true,
      "PaymentTypes": [1, 2, 6],
      "Currencies": ["MAD"]
    }
  ]
}

Explanation of Fields

  1. Payer Branch Information

  • PayerBranchID: Unique ID of the payer branch used to map which country you want to send the transaction to.

  • PayerBranchName: Branch name (e.g., “Belmoney”)

  • Address1: Branch address, sometimes with extra info (e.g., daily limit)

  • Address2: Additional address details (if available)

  • CityName: City where the branch is located (e.g., “Belgium”)

  • StateCode: State or province code (if applicable)

  • CountryCode: ISO country code (e.g., “MA” for Morocco)

  • PhoneNumber: Branch phone number (if available)

  • PayAllCities: Indicates whether payments are accepted from all cities

  • HasLocations: Indicates whether the branch has physical locations

  1. Accepted Payment Methods

  • PaymentTypes: List of accepted payment types (IDs)

  • Currencies: List of currencies accepted by the branch

Accepted Payment Types
1: Account Deposit (Bank Transfer)
2: Office Pick-Up (Cash Collection)
3: Bank Pick-Up
4: Home Delivery
5: Card Top-Up
6: Wallet Top-Up
7: Pix (Brazilian Instant Payment System)

The API RatesAndFeesList  call fetches rates, fees, and payers available in a specific corridor (transaction path, such as country or currency). The request format in cURL is as follows:

Request Details
Endpoint: POST /api/Incoming/RatesAndFeesList
Method: POST
Purpose: Return a list of rates, fees, and other details that will apply to transactions between the partner and beneficiary in different countries or regions. This request can be used to configure the user interface with the correct options for the end client.

Example Response

{
{
  "Results": [
    {
      "CountryCode": "AD",
      "CountryName": "Andorra",
      "PayerID": 827,
      "PayerName": "Belmoney Payer Account Deposit",
      "PayerBranchID": 255587,
      "PayerBranchName": "All",
      "CurrencyCode": "EUR",
      "CurrencyTypeName": "Euro",
      "PaymentTypeID": 1,
      "PaymentTypeName": "Account Deposit",
      "FromAmount": 15,
      "ToAmount": 100,
      "PercentageFee": 0,
      "FlatFee": 5,
      "RateTypeID": 1,
      "RateTypeDescription": "Standard",
      "Rate": 1,
      "FromCurrencyCode": "EUR"
    }
  ]
}
Explanation of Fields
  • CountryCode: “AD”
    • Transaction corridor’s country code. In this example, “AD” represents Andorra.
  • CountryName: “Andorra”
    • Name of the country associated with the code above.
  • PayerID: 827
    • ID of the payer processing the transaction. Each payer can have different conditions for rates and fees.
  • PayerName: “Belmoney Payer Account Deposit”
    • Payer’s name, in this case, a Belmoney account deposit.
  • PayerBranchID: 255587
    • Payer branch ID, This field identifies the country sending the transaction. Each PayerBranchID and PayerBranchReference differs depending on the country.
  • PayerBranchName: “All”
    • Branch name, indicating it’s valid for all branches.
  • CurrencyCode: “EUR”
    • Currency code (in this example, “EUR” for Euro).
  • CurrencyTypeName: “Euro”
    • Full name of the currency.
  • PaymentTypeID: 1
    • ID of the payment type, here representing “Account Deposit.”
  • PaymentTypeName: “Account Deposit”
    • Name of the payment type, indicating an account deposit.
  • FromAmount: 15
    • Minimum amount to make a transaction in this corridor, which is 15 EUR in this example.
  • ToAmount: 100
    • Maximum allowable transaction amount, in this case, 100 EUR.
  • PercentageFee: 0
    • Percentage fee applied to the transaction. In this case, there is no percentage fee.
  • FlatFee: 5
    • Flat fee applied to the transaction, which is 5 EUR in this case.
  • RateTypeID: 1
    • Rate type ID, here representing “Standard.”
  • RateTypeDescription: “Standard”
    • Description of the rate type, confirming it is the standard rate applied.
  • Rate: 1
    • Exchange rate applied to the transaction. In this example, 1 EUR to 1 EUR.
  • FromCurrencyCode: “EUR”
    • Currency code for the transaction’s originating currency, here “EUR” (Euro).

The  Create this endpoint is to to create a new remittance transfer order, involving both the sender and the beneficiary, along with transaction details such as amount and fees.

Request Details
Endpoint: POST /api/Incoming/Create
Method: POST
Purpose: Create a transaction, generating a unique TransferID.

The request body must be in JSON format and include details about:

  • The transfer (TransferID, Reference, Reason)
  • The sender (Name, Adress, DOB, ID’s, ETC)
  • The beneficiary (Name, Adress, Contact,ETC.)
  • Transaction details (Amount, Rate, Fees, Currency, Payment Details)


Example Request 

{
  "TransferID": null,
  "Reference": "47",
  "TransferPIN": "",
  "TransConfirmation": null,
  "TransferReasonID": 17,
  "Sender": {
    "AgencyReference": 3851, 
    "FirstName": "Test",
    "MiddleName": null,
    "LastName": "Testing",
    "SecondLastName": null,
    "Address1": "NA NA",
    "CountryCode": "IT",
    "StateName": "Italy",
    "CityCode": "",
    "CityName": "NA",
    "ZipCode": "NA",
    "DOB": "1989-08-03",
    "PhoneNumber": "+393397962812",
    "CellPhoneNumber": null,
    "PrimaryPhoneNumber": null,
    "PhoneNumberCountryCode": null,
    "Email": "123@yahoo.com",
    "Sex": "M",
    "BirthCityName": "",
    "BirthCountryCode": "Milan",
    "CitizenshipCountryCode": "IT",
    "ProfessionID": 68,
    "PEPTypeID": 2,
    "SenderTypeID": 1,
    "Documents": [],
    "IDs": [
      {
        "IDIssuedDate": "2020-12-31T00:00:00.000Z",
        "IDExpirationDate": "2030-01-01T00:00:00.000Z",
        "IssuedCountryCode": "IT",
        "Authority": null,
        "IDCopy": true,
        "IDType": "2",
        "IDNo": "afdg32165ag"
      }
    ]
  },
  "Beneficiary": {
    "AgencyReference": 45688,
    "FirstName": "Belmoney",
    "MiddleName": null,
    "LastName": "Testing",
    "SecondLastName": null,
    "Address1": "Nigeria",
    "CountryCode": "NG",
    "CityCode": null,
    "CityName": "Nigeria",
    "ZipCode": null,
    "PhoneNumber": "+2348110357777",
    "CellPhoneNumber": "",
    "PrimaryPhoneNumber": "",
    "Email": "benef@benef.com",
    "RelationshipToSenderID": 10,
    "IDs": []
  },
  "AmountAndFees": {
    "PaymentAmount": 44375,
    "OriginalAmount": 25,
    "Rate": "1775.00",
    "RateID": 1,
    "PayerCurrencyCode": "EUR",
    "PaymentCurrencyCode": "NGN",
    "PercentFee": 0,
    "FlatFee": 1.99,
    "OtherFee": 0,
    "Tax": 0,
    "FeesTax": 0,
    "Discount": 0,
    "BirthCountryCode": "NGN"
  },
  "Payment": {
    "PayerBranchReference": "24076",
    "PaymentTypeID": "1",
    "LocationCode": null,
    "BankAccount": {
      "Code": 872,
      "Name": "9 Payment Service Bank",
      "BranchCode": "any branch",
      "BranchName": "any branch",
      "AccountType": 1,
      "AccountNo": "3116835661313"
    }
  },
  "Notes": [],
  "CreationDate": ""
}
Explanation of Fields

Transfer Details

(✅ Yes) – Required

(❌ No) – No Required

  • TransferID (❌ No) – Unique transaction ID (set to null when creating a new transfer).

  • Reference (✅ Yes) – Your reference for the transfer.

  • TransferPIN (❌ No) – Can be a number generated by your standards; if omitted, the system generates one automatically.

  • TransConfirmation (❌ No) – Transaction confirmation status.

  • TransferReasonID (✅ Yes) – Reason for the transfer (e.g.,1=Personal Remittance).


Sender Details
  • FirstName (✅ Yes) – Sender’s first name.

  • LastName (✅ Yes) – Sender’s last name.

  • Address1 (✅ Yes) – Sender’s full address.

  • CountryCode (✅ Yes) – Sender’s country code (ISO 3166).

  • CityName (✅ Yes) – Sender’s city.

  • ZipCode (✅ Yes) – Postal code of the sender.

  • DOB (✅ Yes) – Date of birth in ISO 8601 format.

  • IDs (✅ Yes) – List of identification documents for the sender.


Beneficiary Details
  • FirstName (✅ Yes) – Beneficiary’s first name.

  • LastName (✅ Yes) – Beneficiary’s last name.

  • CountryCode (✅ Yes) – Beneficiary’s country code (ISO 3166).

  • CityName (✅ Yes) – Beneficiary’s city.

  • RelationshipToSenderID (✅ Yes) – Relationship between sender and beneficiary.


Amount & Fees
  • PaymentAmount (✅ Yes) – Total transfer amount.

  • OriginalAmount (✅ Yes) – Amount before conversion.

  • Rate (✅ Yes) – Exchange rate applied.

  • PayerCurrencyCode (✅ Yes) – Currency of the sender.

  • PaymentCurrencyCode (✅ Yes) – Currency of the receiver.

The AddSenderDocumentsAPI is used to upload sender documents in a remittance transfer system. This ensures compliance and verification during the transaction process. 

Request Details
Endpoint: POST /api/Incoming/AddSenderDocuments
Method: POST
Purpose: Uploads sender documents in base64 format for a remittance transaction

{
{
  "TransferID": "1027275000000068", 
  "Documents": [
    {
      "TypeID": 2, 
      "DocumentData": "iVBORw0KGgoAAAANSUhEUgAAAUMAAAFwCAIAAACtv45TAAAA..."
    }
  ]
}

Explanation of Fields

  • TransferID 
    The unique identifier for the remittance transaction.

  • Documents
    A list of documents being uploaded.

  • TypeID 
    The document type ID (see list below).

  • DocumentData 
    The document file in base64 format.

Available TypeID Values (Document Types)
Each document must have a TypeID, which determines the type of file being uploaded:

  • 1 – General

  • 2 – Identification (e.g., passport, ID card)

  • 3 – Proof of Address (e.g., utility bill, bank statement)

  • 4 – Compliance (e.g., compliance-related documents)

  • 5 – KYC Form (Know Your Customer form)

The Statuses API is used to check the status of the order for a remittance transfer system.

Request Details
Endpoint: POST /api/Incoming/Statuses
Method: POST
Purpose: Check the status of the order for a remittance transaction. The request body must be in JSON format and include details about: The remittance transfer (Reference) The request is in x www form urlencoded to view transaction statuses via your transaction reference.