{"info":{"_postman_id":"fb883344-2f15-471f-a5ee-81c38db6cca3","name":"UBA Virtual Account API - Documentation","description":"<html><head></head><body><h2 id=\"general-api-information\"><strong>General API information</strong></h2>\n<h4 id=\"complete-api-collection-for-uba-virtual-account-service-with-rsaaes-encryption\"><strong>Complete API collection for UBA Virtual Account Service with RSA/AES encryption</strong></h4>\n<p>The APIs are fairly RESTFUL and organized around the main services you would be interacting with. You can simply import this collection from the top right of the page into your <strong>Postman</strong>.</p>\n<p>The base url currently sits at:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>https://ubavirtualaccounts.ubagroup.com\n\n</code></pre><h1 id=\"authentication-headers\"><strong>Authentication headers</strong></h1>\n<h5 id=\"required-headers-for-all-requests\">Required Headers for All Requests</h5>\n<h4 id=\"1-authorization-header\">1. <strong>Authorization Header</strong></h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Authorization: Bearer {sha256_hash_of_merchant_public_key}\n\n</code></pre><p>It consists of:</p>\n<ul>\n<li><p><strong>Prefix:</strong> \"Bearer \" (with trailing space)</p>\n</li>\n<li><p><strong>Value:</strong> SHA256 hash of your MERCHANT_PUBLIC_KEY</p>\n</li>\n</ul>\n<p><strong>Example:</strong></p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Authorization: Bearer a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456\n\n</code></pre><hr>\n<h4 id=\"2-signature-header\">2. <strong>Signature Header</strong></h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Signature: {rsa_signed_payload_hash}\n\n</code></pre><p>It involves</p>\n<ol>\n<li><p>Converting your JSON payload to a string</p>\n</li>\n<li><p>Generating a SHA256 hash of the payload string</p>\n</li>\n<li><p>Signing the hash with your MERCHANT_PRIVATE_KEY using RSA</p>\n</li>\n</ol>\n<hr>\n<h4 id=\"3-securetoken-header\">3. <strong>SecureToken Header</strong></h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>SecureToken: {rsa_encrypted_aes_key}\n\n</code></pre><p>It involves</p>\n<ol>\n<li><p>An AES symmetric key (generated by you, 32 bytes recommended)</p>\n</li>\n<li><p>Encrypted using RSA with the VAS_PUBLIC_KEY</p>\n</li>\n<li><p>This encrypted key is used by the server to decrypt your payload</p>\n</li>\n</ol>\n<hr>\n<h4 id=\"4-content-type-header\">4. <strong>Content-Type Header</strong></h4>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>Content-Type: application/json\n\n</code></pre><p><strong>Description:</strong> Indicates that the request body is in JSON format.</p>\n<p><strong>Required For:</strong> All requests</p>\n<h1 id=\"payload-encryption-decryption\">Payload Encryption &amp; Decryption</h1>\n<p>All request and response payloads exchanged with the Virtual Account API are <strong>AES encrypted</strong> to ensure secure data transmission.</p>\n<h3 id=\"request-encryption\">Request Encryption</h3>\n<p>Before sending a request to the API, the <strong>JSON payload must be encrypted using AES</strong> with a randomly generated <strong>AES symmetric key</strong>.</p>\n<p>Steps:</p>\n<ol>\n<li><p>Convert the request body into a JSON string (<code>json_payload_string</code>).</p>\n</li>\n<li><p>Generate an <strong>AES symmetric key</strong>.</p>\n</li>\n<li><p>Encrypt the JSON payload string using <strong>AES encryption</strong> with this symmetric key.</p>\n</li>\n<li><p>Set the AES-encrypted payload as the value of the data field in the request body.</p>\n</li>\n</ol>\n<p>Example request body:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{  \"data\": \"{{aes_encrypted(json_payload_string)}}\"}\n\n</code></pre><p>Request Payload example:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>curl --location 'https://virtualaccountstest.ubagroup.com/api/v1/virtual/accounts' \\\n--header 'Authorization: Bearer sha256hash(merchantPublicKey)' \\\n--header 'Signature: rsa_signed(sha256hash(json_payload_string))' \\\n--header 'SecureToken: rsa_encrypted(aes_symmetric_key)' \\\n--header 'Content-Type: application/json' \\\n--data '{\n    \"data\": \"{{aes_encrypted(json_payload_string)}}\"\n}'\n\n</code></pre><hr>\n<h3 id=\"response-decryption\">Response Decryption</h3>\n<p>The API response payload follows the <strong>same encryption format</strong> as the request.</p>\n<p>Example response body:</p>\n<pre class=\"click-to-expand-wrapper is-snippet-wrapper\"><code>{  \"data\": \"{{aes_encrypted(json_payload_string)}}\"}\n\n</code></pre><p>To decrypt the response:</p>\n<ol>\n<li><p>Retrieve the <code>data</code> value from the response body.</p>\n</li>\n<li><p>Use the <strong>same AES symmetric key</strong> sent in the request to decrypt the payload.</p>\n</li>\n<li><p>The result will be the <strong>original JSON response payload</strong>.</p>\n</li>\n</ol>\n<hr>\n<h1 id=\"http-status-codes\">HTTP Status Codes</h1>\n<div class=\"click-to-expand-wrapper is-table-wrapper\"><table>\n<thead>\n<tr>\n<th>Code</th>\n<th>Meaning</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>201</td>\n<td>Created: Successful request.</td>\n</tr>\n<tr>\n<td>400</td>\n<td>Bad Request: Invalid request parameters or missing required parameters.</td>\n</tr>\n<tr>\n<td>401</td>\n<td>Unauthorized access due to invalid or missing credentials.</td>\n</tr>\n<tr>\n<td>403</td>\n<td>Forbidden access due to insufficient permissions.</td>\n</tr>\n<tr>\n<td>404</td>\n<td>Not Found: The requested resource was not found.</td>\n</tr>\n<tr>\n<td>5xx</td>\n<td>Server Error: An error occurred on the server</td>\n</tr>\n</tbody>\n</table>\n</div></body></html>","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","toc":[{"content":"Authentication headers","slug":"authentication-headers"},{"content":"Payload Encryption & Decryption","slug":"payload-encryption-decryption"},{"content":"HTTP Status Codes","slug":"http-status-codes"}],"owner":"42332797","collectionId":"fb883344-2f15-471f-a5ee-81c38db6cca3","publishedId":"2sBXVo98K9","public":true,"customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"d42e11"},"publishDate":"2026-03-06T09:45:53.000Z"},"item":[{"name":"1. Virtual Account Management","item":[{"name":"1.0 Open Virtual Account (Static)","id":"18b4fd7b-ea8d-4b23-b719-b3a93b3bd4ae","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"bvn\": \"1111111111\",\n  \"firstName\": \"John\",\n  \"lastName\": \"Doe\",\n  \"middleName\": \"Joe\",\n  \"accountName\": \"John Doe Joe\",\n  \"email\": \"john@doe.com\",\n  \"phone\": \"2347011111111\",\n  \"productType\": \"XYZ\",\n  \"customerReference\": \"2347011111111\",\n  \"merchant\": {\n    \"code\": \"MER01\"\n  },\n  \"meta\": {\n    \"product_code\": \"PRO21\"\n  }\n}","options":{"raw":{"language":"json"}}},"url":"https://virtualaccountstest.ubagroup.com/api/v1/virtual/accounts","description":"<p>Creates a static virtual account that can be used multiple times</p>\n","urlObject":{"path":["api","v1","virtual","accounts"],"host":["https://virtualaccountstest.ubagroup.com"],"query":[],"variable":[]}},"response":[],"_postman_id":"18b4fd7b-ea8d-4b23-b719-b3a93b3bd4ae"},{"name":"1.0 Open Virtual Account (Dynamic)","id":"892ac2dd-53e5-46c5-acd8-c86944bd601f","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"bvn\": \"1111111111\",\n  \"firstName\": \"Jane\",\n  \"lastName\": \"Smith\",\n  \"middleName\": \"Mary\",\n  \"accountName\": \"Jane Mary Smith\",\n  \"email\": \"jane@smith.com\",\n  \"phone\": \"2347022222222\",\n  \"productType\": \"ABC\",\n  \"customerReference\": \"2347022222222\",\n  \"expireAt\": \"2024-12-31T23:59:59.999+0100\",\n  \"singleDepositLimit\": \"5000\",\n  \"merchant\": {\n    \"code\": \"MER01\"\n  },\n  \"meta\": {\n    \"product_code\": \"PRO22\"\n  }\n}","options":{"raw":{"language":"json"}}},"url":"https://virtualaccountstest.ubagroup.com/api/v1/virtual/accounts","description":"<p>Creates a dynamic virtual account that expires after single deposit or at specified time</p>\n","urlObject":{"path":["api","v1","virtual","accounts"],"host":["https://virtualaccountstest.ubagroup.com"],"query":[],"variable":[]}},"response":[],"_postman_id":"892ac2dd-53e5-46c5-acd8-c86944bd601f"},{"name":"1.1 Update Virtual Account","id":"05d2594d-573d-4836-b2fe-f9479d05e8bd","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"PUT","header":[],"body":{"mode":"raw","raw":"{\n  \"firstName\": \"John\",\n  \"lastName\": \"Doe\",\n  \"middleName\": \"Joseph\",\n  \"accountName\": \"John Joseph Doe\",\n  \"status\": \"ACTIVE\",\n  \"productType\": \"XYZ_UPDATED\",\n  \"meta\": {\n    \"product_code\": \"PRO23\"\n  }\n}","options":{"raw":{"language":"json"}}},"url":"https://virtualaccountstest.ubagroup.com/api/v1/virtual/accounts/:accountNumber","description":"<p>Updates an existing virtual account. Status can be ACTIVE or INACTIVE</p>\n","urlObject":{"path":["api","v1","virtual","accounts",":accountNumber"],"host":["https://virtualaccountstest.ubagroup.com"],"query":[],"variable":[{"id":"3a8082d0-8f81-45ea-929a-11e2f36b47ee","description":{"content":"<p>Virtual account number (vNUBAN)</p>\n","type":"text/plain"},"type":"any","value":"6200000044","key":"accountNumber"}]}},"response":[],"_postman_id":"05d2594d-573d-4836-b2fe-f9479d05e8bd"},{"name":"1.2 Get All Merchant Virtual Accounts","id":"21e237f2-4d99-4380-bdf7-e5474a995b8d","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://virtualaccountstest.ubagroup.com/api/v1/virtual/accounts","description":"<p>Retrieves all virtual accounts for the merchant (both static and dynamic)</p>\n","urlObject":{"path":["api","v1","virtual","accounts"],"host":["https://virtualaccountstest.ubagroup.com"],"query":[],"variable":[]}},"response":[],"_postman_id":"21e237f2-4d99-4380-bdf7-e5474a995b8d"},{"name":"1.3 Get A Virtual Account","id":"36eab464-5d8e-40cc-884b-e1c33693aa22","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"GET","header":[],"url":"https://virtualaccountstest.ubagroup.com/api/v1/virtual/accounts/:accountNumber","description":"<p>Retrieves details of a specific virtual account</p>\n","urlObject":{"path":["api","v1","virtual","accounts",":accountNumber"],"host":["https://virtualaccountstest.ubagroup.com"],"query":[],"variable":[{"id":"06a71e86-d2bd-41d5-9ff5-174ee3c1f955","description":{"content":"<p>Virtual account number (vNUBAN)</p>\n","type":"text/plain"},"type":"any","value":"6200000044","key":"accountNumber"}]}},"response":[],"_postman_id":"36eab464-5d8e-40cc-884b-e1c33693aa22"}],"id":"06360e73-4614-4cca-87c8-506084095cc2","description":"<p>Endpoints for creating, updating, and retrieving virtual accounts</p>\n","_postman_id":"06360e73-4614-4cca-87c8-506084095cc2"},{"name":"2. Transaction Queries","item":[{"name":"3.0 Query Virtual Account Inflow","id":"fed33476-7c24-44e2-9814-986085f293b1","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"vNUBAN\": \"6200000044\",\n  \"startDate\": \"2024-11-01\",\n  \"endDate\": \"2024-11-30\"\n}","options":{"raw":{"language":"json"}}},"url":"https://virtualaccountstest.ubagroup.com/api/v1/virtual/notifications/query","description":"<p>Query all inflow transactions for a virtual account within a date range. Date format: yyyy-MM-dd</p>\n","urlObject":{"path":["api","v1","virtual","notifications","query"],"host":["https://virtualaccountstest.ubagroup.com"],"query":[],"variable":[]}},"response":[],"_postman_id":"fed33476-7c24-44e2-9814-986085f293b1"}],"id":"21a71dc9-fe70-4d15-b4b8-4732987808fc","description":"<p>Endpoints for querying transaction history and inflows</p>\n","_postman_id":"21a71dc9-fe70-4d15-b4b8-4732987808fc"},{"name":"3. Funds Transfer","item":[{"name":"4.0 Transfer Funds","id":"588e864b-e945-448c-9e78-412f7d5e7182","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"transactionRef\": \"TXN1778061856\",\n  \"sourceAccount\": \"2214238553\",\n  \"destinationAccount\": \"0222209887\",\n  \"transferAmount\": \"1000.00\",\n  \"narration\": \"Test transfer from Postman\",\n  \"destinationAccountName\": \"Adewale Hassan\",\n  \"destinationBankCode\": \"060\"\n}","options":{"raw":{"language":"json"}}},"url":"https://virtualaccountstest.ubagroup.com/api/v1/transactions/transfer-funds","description":"<p>Initiates an intra-bank funds transfer. Transaction reference must be unique.</p>\n","urlObject":{"path":["api","v1","transactions","transfer-funds"],"host":["https://virtualaccountstest.ubagroup.com"],"query":[],"variable":[]}},"response":[],"_postman_id":"588e864b-e945-448c-9e78-412f7d5e7182"},{"name":"4.1 Query Funds Transfer","id":"10844a9d-5b70-4922-98d5-029202d4f182","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"transactionRef\": \"TXN1234567890\",\n  \"stan\": \"796219703029\"\n}","options":{"raw":{"language":"json"}}},"url":"https://virtualaccountstest.ubagroup.com/api/v1/transactions/transfer-funds/query","description":"<p>Query the status of a funds transfer transaction using transaction reference and/or STAN</p>\n","urlObject":{"path":["api","v1","transactions","transfer-funds","query"],"host":["https://virtualaccountstest.ubagroup.com"],"query":[],"variable":[]}},"response":[],"_postman_id":"10844a9d-5b70-4922-98d5-029202d4f182"}],"id":"90c48e81-cb7e-4cb4-addd-2291528bee97","description":"<p>Endpoints for initiating and querying funds transfers</p>\n","_postman_id":"90c48e81-cb7e-4cb4-addd-2291528bee97"},{"name":"4. Webhook Example","item":[{"name":"Transaction Notification (Incoming Webhook)","id":"67a3ab34-f883-4f9e-a58a-caf7feebb646","protocolProfileBehavior":{"disableBodyPruning":true},"request":{"method":"POST","header":[{"key":"SecureToken","value":"{{rsa_encrypted_aes_key}}","description":"<p>RSA encrypted AES key using merchant public key</p>\n"},{"key":"Content-Type","value":"application/json"}],"body":{"mode":"raw","raw":"{\n  \"data\": \"{{aes_encrypted_payload}}\"\n}","options":{"raw":{"language":"json"}}},"url":"https://your-webhook-url.com/webhook","description":"<p>This is an example of the incoming webhook call from UBA when a virtual account receives payment. You need to:</p>\n<ol>\n<li>Configure your webhook URL in Settings → API Settings</li>\n<li>Decrypt SecureToken with your MERCHANT_PRIVATE_KEY to get AES key</li>\n<li>Decrypt the data payload with the AES key</li>\n</ol>\n<p>Decrypted payload will contain transaction details like sessionID, amount, beneficiaryAccountNumber, etc.</p>\n","urlObject":{"protocol":"https","path":["webhook"],"host":["your-webhook-url","com"],"query":[],"variable":[]}},"response":[{"id":"d95deac6-f0d4-4dd9-9245-e4f2b7fa0cf3","name":"Decrypted Webhook Payload Example","originalRequest":{"method":"POST","header":[],"body":{"mode":"raw","raw":"{\n  \"sessionID\": \"241103033404675000698906894002\",\n  \"nameEnquiryRef\": \"241103033404675000698906894002\",\n  \"destinationInstitutionCode\": \"000004\",\n  \"channelCode\": \"1\",\n  \"beneficiaryAccountName\": \"Autos - John Doe\",\n  \"beneficiaryAccountNumber\": \"6200000044\",\n  \"beneficiaryBankVerificationNumber\": \"11111111111\",\n  \"originatorAccountName\": \"Adewale Hassan\",\n  \"originatorAccountNumber\": \"3333002345\",\n  \"originatorBankVerificationNumber\": \"10330004415\",\n  \"originatorKYCLevel\": \"3\",\n  \"transactionLocation\": \"6.4300747,3.4110715\",\n  \"narration\": \"Test transfer\",\n  \"paymentReference\": \"7962197030298791\",\n  \"customerReference\": \"2348045933232\",\n  \"status\": \"Successful\",\n  \"amount\": \"1000.00\",\n  \"collectionAccountNumber\": \"00018263487\",\n  \"createdOn\": \"2024-11-03 03:34:18\",\n  \"updatedOn\": \"2024-11-03 03:34:18\"\n}","options":{"raw":{"language":"json"}}},"url":"https://your-webhook-url.com/webhook"},"_postman_previewlanguage":"json","header":[],"cookie":[],"responseTime":null,"body":"{\n  \"sessionID\": \"241103033404675000698906894002\",\n  \"nameEnquiryRef\": \"241103033404675000698906894002\",\n  \"destinationInstitutionCode\": \"000004\",\n  \"channelCode\": \"1\",\n  \"beneficiaryAccountName\": \"Autos - John Doe\",\n  \"beneficiaryAccountNumber\": \"6200000044\",\n  \"beneficiaryBankVerificationNumber\": \"11111111111\",\n  \"originatorAccountName\": \"Adewale Hassan\",\n  \"originatorAccountNumber\": \"3333002345\",\n  \"originatorBankVerificationNumber\": \"10330004415\",\n  \"originatorKYCLevel\": \"3\",\n  \"transactionLocation\": \"6.4300747,3.4110715\",\n  \"narration\": \"Test transfer\",\n  \"paymentReference\": \"7962197030298791\",\n  \"customerReference\": \"2348045933232\",\n  \"status\": \"Successful\",\n  \"amount\": \"1000.00\",\n  \"collectionAccountNumber\": \"00018263487\",\n  \"createdOn\": \"2024-11-03 03:34:18\",\n  \"updatedOn\": \"2024-11-03 03:34:18\"\n}"}],"_postman_id":"67a3ab34-f883-4f9e-a58a-caf7feebb646"}],"id":"bf7d6e96-3214-415d-9359-15fe58ccf845","description":"<p>Example of incoming webhook notifications from UBA</p>\n","_postman_id":"bf7d6e96-3214-415d-9359-15fe58ccf845"}],"event":[{"listen":"prerequest","script":{"type":"text/javascript","requests":{},"exec":["// Get environment variables","const merchantPublicKey = pm.environment.get('merchant_public_key');","const merchantPrivateKey = pm.environment.get('merchant_private_key');","const vasPublicKey = pm.environment.get('vas_public_key');","const aesKey = pm.environment.get('aes_symmetric_key');","","if (!merchantPublicKey || !merchantPrivateKey || !vasPublicKey || !aesKey) {","    console.error('Missing required environment variables. Please set: merchant_public_key, merchant_private_key, vas_public_key, aes_symmetric_key');","}","","// SHA256 Hash function","function sha256Hash(str) {","    return CryptoJS.SHA256(str).toString();","}","","// RSA Sign function","function rsaSign(data, privateKey) {","    const sign = new JSEncrypt();","    sign.setPrivateKey(privateKey);","    const signature = sign.sign(data, CryptoJS.SHA256, 'sha256');","    return signature;","}","","// RSA Encrypt function","function rsaEncrypt(data, publicKey) {","    const encrypt = new JSEncrypt();","    encrypt.setPublicKey(publicKey);","    return encrypt.encrypt(data);","}","","// AES Encrypt function","function aesEncrypt(plainText, key) {","    const keyHex = CryptoJS.enc.Utf8.parse(key);","    const encrypted = CryptoJS.AES.encrypt(plainText, keyHex, {","        mode: CryptoJS.mode.ECB,","        padding: CryptoJS.pad.Pkcs7","    });","    return encrypted.toString();","}","","// Set Authorization header","const authHash = sha256Hash(merchantPublicKey);","pm.request.headers.upsert({","    key: 'Authorization',","    value: 'Bearer ' + authHash","});","","// Get request body if exists","let jsonPayload = '';","if (pm.request.body && pm.request.body.mode === 'raw') {","    try {","        const bodyObj = JSON.parse(pm.request.body.raw);","        // Check if body already has 'data' field (already encrypted)","        if (bodyObj.data && bodyObj.data.includes('U2FsdGVk')) {","            // Already encrypted, skip","            jsonPayload = '';","        } else {","            jsonPayload = pm.request.body.raw;","        }","    } catch (e) {","        jsonPayload = pm.request.body.raw;","    }","}","","// Set Signature header if payload exists","if (jsonPayload && jsonPayload.trim() !== '' && !jsonPayload.includes('\"data\"')) {","    const payloadHash = sha256Hash(jsonPayload);","    const signature = rsaSign(payloadHash, merchantPrivateKey);","    pm.request.headers.upsert({","        key: 'Signature',","        value: signature","    });","    ","    // Encrypt the payload","    const encryptedData = aesEncrypt(jsonPayload, aesKey);","    pm.request.body.update({","        mode: 'raw',","        raw: JSON.stringify({ data: encryptedData }),","        options: {","            raw: {","                language: 'json'","            }","        }","    });","}","","// Set SecureToken header","const encryptedAesKey = rsaEncrypt(aesKey, vasPublicKey);","pm.request.headers.upsert({","    key: 'SecureToken',","    value: encryptedAesKey","});","","// Set Content-Type","pm.request.headers.upsert({","    key: 'Content-Type',","    value: 'application/json'","});"],"id":"c7caf875-d733-4edb-bee9-6ebdbb4883ba"}},{"listen":"test","script":{"type":"text/javascript","packages":{},"requests":{},"exec":[""],"id":"5501988e-67af-45fb-ade2-3d29b93a5bb3"}}],"variable":[{"key":"base_url","value":"https://virtualaccountstest.ubagroup.com"}]}