{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"3ffb3647-605f-4c69-b383-5ed725f9bd9f","name":"PaywithAccount - Built on OnePipe","description":"OnePipe supports _direct-from-account_ payments. This enables money to be _pulled_ from customer bank accounts into your business account. Either as a one-time transaction, or on a recurring basis. We built [paywithaccount.com](https://paywithaccount.com) as a use case on OnePipe to drive this specific scenario.\n\n\\[ [explainer video](https://www.youtube.com/watch?v=-VND79PZuXQ) | [product website ](https://www.paywithtransfer.com/developers/) | [sandbox postman collection](https://paywithaccount.com/sandbox) \\]\n\n## Customers can link their bank accounts to your platform\n\n<img src=\"https://content.pstmn.io/5e41ce1b-52ee-43db-a297-10d3054b3451/bGluay1hY2NvdW50LnBuZw==\">\n\n## You can take payments from linked accounts\n\n<img src=\"https://content.pstmn.io/7499d453-783f-4817-9acc-8423e1e2f8fd/Y29sbGVjdC1mcm9tLWFjY291bnQucG5n\">\n\n1. Request a customer's consent to link their account to your service\n    \n2. Wait a bit for their consent and bank approval to be processed\n    \n3. You'd get a notification on your webhook once #2 has happened\n    \n4. Then, you can request payments off those accounts at any time\n    \n5. You can also call the [scheduler ](#f84d06cd-9c00-4006-bbd7-3ef449346b95) at any time to setup recurring payments\n    \n6. Listen for notifications informing you of successful or failed transactions\n    \n7. Fulfil the customer's service request based on #6\n    \n\n---\n\n#### Take a look at what's possible\n\n> Want to see an ideal embedded payments integration that combines virtual accounts with 1-click direct-from-account payments? Play with [this demo](http://demo.paywithaccount.com) and see what happens after you register. You can embed an experience just like that \n  \n\n---\n\n> **To get started:** [Sign up, ](https://app.paywithaccount.com/sign-up) and after compliance checks and approval, request API access. You can also be provided with a prepared postman collection that you can just import and use if you don't want to construct your collection yourself using the information provided. \n  \n\n# Getting started\n\nHere are the preliminary steps before you can use PaywithAccount via APIs\n\n1. Sign up on PaywithAccount \\[[guide](https://paywithaccount.com/guide/?q=How%20to%20request%20API%20access)\\]\n    \n2. Request API access \\[[guide](https://paywithaccount.com/guide/?q=How%20to%20request%20API%20access)\\]\n    \n3. Once approved, you will receive 2 emails:\n    \n    1. That contains the postman collection\n        \n    2. Another with a link to set up your password. After setting your password, log in and retrieve your credentials.\n        \n\n# **General Information**\n\nAll requests to the API are made through a single base URL:\n\n```\nhttps://api.onepipe.io\n\n ```\n\nThere are no separate URLs for sandbox and production. Instead, the environment is controlled by the **`mock_mode`** field in the request payload.\n\n### Mock mode\n\n- **`mock_mode = inspect`** **→** Sandbox Mode\n    \n    - Requests are processed in test mode.\n        \n    - You receive mock responses that simulate the expected behavior of the endpoint.\n        \n    - Recommended for development and early-stage integration testing.\n        \n- **`mock_mode = live`** **→** Production Mode\n    \n    - Requests are processed in live mode.\n        \n    - You receive real-time responses based on actual inputs and live transaction flows.\n        \n    - Use this mode only after successful sandbox testing.\n        \n\n## Access to Live Mode During Integration\n\nDuring the integration phase, you will be provided with limited access to the `mock_mode = live` setting.\n\n- This allows you to preview real-time responses and perform end-to-end testing of your workflows.\n    \n- Access is controlled and monitored to ensure stability and compliance.\n    \n- Full unrestricted access to production (`mockmode = live`) is granted only after your integration is fully tested and approved.\n    \n\n# Headers\n\nEvery API call must include specific headers for authentication, security, and proper request handling. Below is a breakdown of the required headers and their purposes:\n\n1. **Content-Type**\n    \n\n```\nContent-Type: application/json\n\n ```\n\n- Informs the server that the body of the request is in JSON format\n    \n- Required for all request\n    \n\n**2\\. Authorization**\n\n```\nAuthorization: Bearer {api_key}\n\n ```\n\n- This header contains the API key assign to you\n    \n- It authenticates the request and confirms that the call is made by an authorized client\n    \n- Format: `Bearer {{your_api_key}}`\n    \n\n**`3.`** **Signature**\n\n```\nSignature: {{MD5Hash(request_ref;client_secret)}}\n\n ```\n\n- Ensures integrity and security of the request.\n    \n- Generated using an MD5 hash function\n    \n- To compute the signature:\n    \n    - Concatenate the `request_ref` (a unique reference for every API call) and your `client_secret` separated by a semi colon `(;)`.\n        \n    - Apply the MD5 hashing function to the concatenated string.\n        \n- This hashed value is then sent as the `Signature` header.\n    \n- Purpose:\n    \n    - To verify that the request originates from a trusted source.\n        \n    - Serves as a second layer of security by “signing” the request.\n        \n\n**Example Header format**  \nYour complete header for evey single call will look like\n\n```\nContent-Type:application/json\nAuthorization:Bearer {{api_key}}\nSignature:{{MD5Hash(request_ref;client_secret)}}\n\n ```\n\n## Notes\n\n- **request_ref**: A unique identifier generated for every API call. No two requests should have the same reference.\n    \n- The server validates the `Signature` by regenerating the hash internally and comparing it with the one provided.\n    \n- If the values do not match, the request will be rejected.\n    \n\n# Request Payload Structure\n\nEvery API request uses a common payload structure. This ensures consistency across services and reduces integration effort. The payload is divided into standard objects, each serving a specific purpose.\n\n##### **Top Level Fields**\n\n| **Field** | **Type** | **Requirement** | **Description** |\n| --- | --- | --- | --- |\n| request_ref | String | Yes | Unique reference ID for this API call. Must be unique for every request. |\n| request_type | String | Yes | Defines the type of request. For mandate checks, use Get Accounts Max. |\n| auth | Object | Yes | Contains authentication information (provider, type, secure value). |\n| transaction | Object | Yes | Holds transaction-specific details like reference, amount, customer info. |\n\n##### Auth Object\n\n| **Field** | **Type** | **Requirement** | **Descriptional** |\n| --- | --- | --- | --- |\n| type | String/null | No | Authentication type other service. For mandate check,get_bank, may be null. |\n| secure | String/null | No | Encrypted authentication value. May be null if not applicable. |\n| auth_provider | String | Yes | Identifies the authentication provider. Use `PaywithAccount`. |\n\n#### **Type**\n\nThis defines the authentication type and varies depending on the service being called.\n\n- For get banks service → the value is `null`.\n    \n- For mandate creation → the value is `\"bank.account\"`, because a mandate is being placed on a specific account.\n    \n\n#### **Secure**\n\nIf type has a value, then secure must also have a value.\n\n- The value is encrypted using TripleDES with your secret key as the encryption key.\n    \n\n```\nTripleDES.encrypt(\"{account_number};{cbn_bankcode}\", secretKey)\n\n ```\n\n#### **The Auth Object**\n\nUsing the formula, the full object looks like this:\n\n```\n\"type\": \"bank.account\",\n\"secure\": TripleDES.encrypt(\"{account_number};{cbn_bankcode}\", secretKey),\n\"auth_provider\": \"paywithaccount\"\n\n ```\n\n#### Sample encryption in Java\n\n```\nMessageDigest md = MessageDigest.getInstance(\"md5\");\nbyte[] digestOfPassword = md.digest(key.getBytes(\"UTF-16LE\"));\nbyte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);\nfor (int j = 0, k = 16; j < 8;) {\n    keyBytes[k++] = keyBytes[j++];\n}\nSecretKey secretKey = new SecretKeySpec(keyBytes, 0, 24, \"DESede\");\nIvParameterSpec iv = new IvParameterSpec(new byte[8]);\nCipher cipher = Cipher.getInstance(\"DESede/CBC/PKCS5Padding\");\ncipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);\nbyte[] plainTextBytes = toBeEncrypted.getBytes(\"UTF-16LE\");\nbyte[] cipherText = cipher.doFinal(plainTextBytes);\nString output = new String(Base64.encodeBase64(cipherText));\nreturn output;\n\n ```\n\n#### Sample encryption in C-Sharp\n\n```\nstring encryptedText = \"\";\nMD5 md5 = new MD5CryptoServiceProvider();\nTripleDES des = new TripleDESCryptoServiceProvider();\ndes.KeySize = 128;\ndes.Mode = CipherMode.CBC;\ndes.Padding = PaddingMode.PKCS7;\nbyte[] md5Bytes = md5.ComputeHash(Encoding.Unicode.GetBytes(key));\nbyte[] ivBytes = new byte[8];\ndes.Key = md5Bytes;\ndes.IV = ivBytes;\nbyte[] clearBytes = Encoding.Unicode.GetBytes(TextToEncrypt);\nICryptoTransform ct = des.CreateEncryptor();\nusing (MemoryStream ms = new MemoryStream())\n{\n    using (CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write))\n    {\n        cs.Write(clearBytes, 0, clearBytes.Length);\n        cs.Close();\n    }\n    encryptedText = Convert.ToBase64String(ms.ToArray());\n}\nreturn encryptedText;\n\n ```\n\n#### Sample encryption in PHP\n\n```\nfunction EncryptV2($encryption_key,$data)\n{\n    $source = mb_convert_encoding($encryption_key, 'UTF-16LE', 'UTF-8');\n    $key = md5($source, true);\n    $key .= substr($key, 0, 8);\n     // a 128 bit (16 byte) key\n     // append the first 8 bytes onto the end\n    //Pad for PKCS7\n    $block = mcrypt_get_block_size('tripledes', 'cbc');\n    $len = strlen($data);\n    $padding = $block - ($len % $block);\n    $data .= str_repeat(chr($padding),$padding);\n    $iv =  \"\\0\\0\\0\\0\\0\\0\\0\\0\";\n    $encData = mcrypt_encrypt('tripledes', $key, $data, 'cbc',$iv);\n    echo base64_encode($encData);\n}\n\n ```\n\n#### Sample encryption in Node.js\n\n```\nconst crypto = require('crypto');\nfunction encrypt(sharedKey, plainText) {\n    const bufferedKey = Buffer.from(sharedKey, 'utf16le');\n    const key = crypto.createHash('md5').update(bufferedKey).digest();\n    const newKey = Buffer.concat([key, key.slice(0, 8)]);\n    const IV = Buffer.alloc(8, '\\0');\n    const cipher = crypto.createCipheriv('des-ede3-cbc', newKey, IV).setAutoPadding(true);\n    return cipher.update(plainText, 'utf8', 'base64') + cipher.final('base64');\n}\n\n ```\n\n#### Transaction Object\n\n| **Field** | **Type** | **Requirement** | **Description** |\n| --- | --- | --- | --- |\n| mock_mode | String | Yes | Defines the simulation mode for testing. Example: \"Inspect\" |\n| transaction_ref | String | Yes | Unique reference for this transaction. Must be unique for each request. |\n| transaction_description | String | Yes | Short description of the transaction purpose. Example: \"Check active mandates\" |\n| transaction_ref_parent | String/Null | No | Optional reference to a parent transaction (for nested or linked transactions). |\n| amount | Number | Yes | Amount involved in the transaction. Use 0 if the transaction does not involve payment. |\n| customer | Object | Yes | Contains customer-specific information (see below). |\n| meta | Object | No | Optional metadata related to the transaction (e.g., biller code, category). |\n| details | Object | No | Additional transaction-specific details; can be empty if not applicable. |\n\n**Customer Object**\n\nThe `customer` object stores information to uniquely identify and contact the customer. **Fields are optional depending on the service being called**. If not required, they can be left as empty strings (`\"\"`)\n\n| **Field** | **Type** | **Requirement** | **Description** |\n| --- | --- | --- | --- |\n| customer_ref | String | Yes | Unique customer identifier. Always advised to use the 13-digit phone number starting with 234. Example: 2348022222222 |\n| firstname | String | No | Customer first name. Can be left as \"\" if not required by the service |\n| surname | String | No | Customer last name. Can be left as \"\" if not required |\n| email | String | No | Customer email address. Can be left as \"\" if not required |\n| mobile_no | String | No | Customer mobile phone number. Can be left as \"\" if not required |\n\n#### Meta Object\n\nThe `meta` object is **optional** and can contain extra contextual information for the transaction depending on the service.\n\n| **Field** | **Type** | **Requirement** | **Description** |\n| --- | --- | --- | --- |\n| biller_code | String | No | Code identifying the biller or service provider. Example: \"000019\" |\n\n**Details Object**\n\n- The `details` object can contain additional information relevant to the transaction.\n    \n- It can be empty (`{}`) if no extra details are needed.\n    \n\n`Doc W.I.P.`","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"6358444","team":242895,"collectionId":"3ffb3647-605f-4c69-b383-5ed725f9bd9f","publishedId":"2sB34coNLt","public":true,"publicUrl":"https://docs.paywithaccount.com","privateUrl":"https://go.postman.co/documentation/6358444-3ffb3647-605f-4c69-b383-5ed725f9bd9f","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"008CB5"},"documentationLayout":"classic-double-column","customisation":{"metaTags":[{"name":"description","value":""},{"name":"title","value":"#163947"}],"appearance":{"default":"dark","themes":[{"name":"dark","logo":"https://content.pstmn.io/4000dec1-3bf3-4086-9ebb-4a657405797c/UGF5d2l0aEFjY291bnQtUC1saWdodC12Mi5wbmc=","colors":{"top-bar":"212121","right-sidebar":"303030","highlight":"008CB5"}},{"name":"light","logo":"https://content.pstmn.io/1ce649a3-99c0-4423-8cfc-f582ccfc40e8/UGF5d2l0aEFjY291bnQtUC1kYXJrLXYyLnBuZw==","colors":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"008CB5"}}]}},"version":"8.10.1","publishDate":"2025-07-06T08:12:28.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{"title":"#163947","description":""},"logos":{"logoLight":"https://content.pstmn.io/1ce649a3-99c0-4423-8cfc-f582ccfc40e8/UGF5d2l0aEFjY291bnQtUC1kYXJrLXYyLnBuZw==","logoDark":"https://content.pstmn.io/4000dec1-3bf3-4086-9ebb-4a657405797c/UGF5d2l0aEFjY291bnQtUC1saWdodC12Mi5wbmc="}},"statusCode":200},"environments":[],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/a27a425324c006dd1f53f07becf2d5c16478567dd1dde25001728b716c749aa8","favicon":"https://res.cloudinary.com/postman/image/upload/v1547191824/team/zjhn0lwn04wuxbe90rhq.ico"},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"}],"canonicalUrl":"https://docs.paywithaccount.com/view/metadata/2sB34coNLt"}