{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"ec7e062e-ee83-4f44-9214-2a2f6222e4b4","name":"Paygate Plus - Documentation","description":"# Build on reliable banking infrastructure\n\nAt Fidelity, payment processing and classic banking, we remain committed to a collaborative effort to expand the opportunities that financial services represent and deepen financial inclusion.\n\nThe bouquet of APIs on Paygate Plus helps to further this objective.\n\n# Want to try it quickly?\n\nTo get started, sign up for Paygate Plus by visiting [https://paygateplus.ng](https://paygateplus.ng). Once your account has been approved, you will receive an invite email to set your password on the platform.\n\n1. Set up your password\n    \n2. Login with newly set password\n    \n3. Go to **My Settings**\n    \n4. GO to **API Settings**\n    \n5. Generate your **API key** and **secret**\n    \n6. Click **Save Changes** to save the newly generated API credentials\n    \n\n# General API information\n\nThe 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 **Postman**.\n\nThe base url currently sits at:\n\n```\nhttps://api.paygateplus.ng\n\n ```\n\n# Authentication headers\n\nAuthenticate your API calls by including your API key in the Authorization header of every request you make. You can manage your API keys from your dashboard.\n\n**Online Encryption Tool:**  \n[https://onepipe.io/tools/encryptor/Home/Encrypt](https://onepipe.io/tools/encryptor/Home/Encrypt)\n\n_**Sample Authorization Header:**_\n\n```\nAuthorization: Bearer {api_key}\n\n ```\n\nAlso, every request requires you to provide a unique `request-ref` per call. Then You'd need to add a custom header called `Signature` that's an MD5 hash of that `request-ref` and your `api-secret` separated by a semi-colon. `;`.\n\n_**Sample Signature Header:**_\n\n```\nSignature:MD5Hash(request_ref;client_secret)\n\n ```\n\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# What requests would look like\n\nFor all requests, you'd put a JSON object in the body of your API call. All payloads have the following high level construct:\n\n``` json\n    {\n      \"request_ref\":\"0000000001\",\n      \"request_type\":\"collect | disburse |etc\",\n      \"auth\": {\n        \"type\": \"bvn | bank.account\", \n        \"secure\": \"YKBOxtdD8kZHqG7JO0C9TZ\",\n        \"auth_provider\": \"Fidelity\"\n      },\n      \"transaction\": {\n        \"amount\": 10000,\n        \"transaction_ref\": \"000001\",\n        \"transaction_desc\": \"A random transaction\",\n        \"transaction_ref-parent\": \"000001\",\n        \"customer\":{\n            \"customer_ref\": \"000001\",\n            \"firstname\": \"Kola\",\n          \"surname\": \"Eboe\",\n            \"email\": \"kolaebue@gmail.com\",\n            \"mobile_no\": \"2348009871412\"\n        },\n        \"meta\":{\n            \"a_key\":\"a_meta_value_1\",\n            \"b_key\":\"a_meta_value_2\"\n        },\n        \"details\": {\n            \"key\": 'value'\n        }\n      }\n    }\n\n ```\n\n#### Request body elements\n\n| Field | Type | Requirement | Description |\n| --- | --- | --- | --- |\n| request_ref | string | compulsory | A unique reference for this API call |\n| request_type | string | compulsory | Set to `get_statement` |\n| auth.type | string | optional | Depends on what the provider requires to get a statement. Most times, will be `bank.account`. |\n| auth.secure | string | optional | If a type is set, then encrypt the value here. |\n| auth.auth_provider | string | compulsory | The Provider against which you want to open the account. e.g. `GTBank` |\n| auth.route_mode | string | optional | Set to `null` |\n| transaction.mock_mode | string | compulsory | Set to `inspect` (for test mode) or `live` (for live mode) |\n| transaction.transaction_ref | string | compulsory | A unique reference for the transaction |\n| transaction.transaction.desc | string | compulsory | A short description or narration |\n| transaction.transaction_ref_parent | string | optional | Can be set to `null`. But if you are repeating an prior transaction, you can set it to the `transaction_ref` of the former transaction to create a link for easy tracking. |\n| amount | int | compulsory | Set to `0` |\n| transaction.customer.customer_ref | string | compulsory | A unique reference to identify this customer |\n| transaction.customer.firstname | string | compulsory | The firstname of the customer |\n| transaction.customer.surname | string | compulsory | The surname of the customer |\n| transaction.customer.email | string | compulsory | The email of the customer |\n| transaction.customer.mobile_no | string | compulsory | The mobile number of the customer |\n| transaction.details.start_date | string | compulsory | The start date of the date range for which the statement is required. (yyyy-MM-dd) |\n| transaction.details.end_date | string | compulsory | The end date of the date range for which the statement is required. (yyyy-MM-dd) |\n\n# What responses would look like\n\nFor all responses, you'd get a JSON object in the body of the response you receive. All payloads have the following high level construct:\n\n``` json\n    {\n        \"status\": \"Processing | WaitingForOTP | ProcessingOTP | Successful | Failed | OfflineValidating | OfflineValidated | OfflineNotifying | OfflineNotified\",\n        \"message\": \"The transaction has been processed successully\",\n        \"data\": {\n            \"provider_responde_code\":\"00\",\n            \"provider\": \"Fidelity\",\n            \"errors\": [],\n            \"error\": null,\n            \"charge_token\": \"Kz5Dev7BenV9HmLNB\",\n            \"paymentoptions\": []\n        }\n    }\n\n ```\n\n- **status**: Indicates the state of the request, whether successful, failed or anything in between\n    \n- **message**: Provides a text description of the state of the request and at times a message for the customer\n    \n- **data**: Will contain much more details of the outcome of the request. The values within this could vary by request type or endpoint called but some standard elements would be in almost all calls\n    \n- **provider_response_code**: The actual response code received from the underlying provider, e.g. `00` for Quickteller\n    \n- **provider**: The provider that was used to process the request\n    \n- **errors**: In case of a failed transaction, this contains the lists of errors that occurred while processing the transaction\n    \n- **error**: This contain the most important error that hinders the successful completion of the transaction.  \n    We highly recommend that developers use the Errors field to determine the result of an API call. As an empty Errors node indicate a successful transaction.\n    \n\n**NOTE**: Some API calls may have response elements that are only applicable to those API calls. You will see examples in the provided postman collection and across the documentation.\n\n# Standard status codes\n\n- **Successful**: For all requests that were successfully processed\n    \n- **Failed**: If a request fails. Read the errors object(s)\n    \n- **WaitingForOTP**: If a request requires OTP validation for completion.\n    \n- **PendingValidation**: If a request requires other information to be supplied for completion.\n    \n- **Processing**: If a transaction request is still in a processing state and needs to be subsequently queried.\n    \n- **OptionsDelivered**: Applicable only for services that support some form of options processing.\n    \n- **InvalidID**: If an ID being looked up by service is not valid.\n    \n- **Fraud**: If a request is flagged as suspicious.\n    \n- **Duplicate**: If a similar request has been made earlier within a stipulated time frame of 5 minutes.\n    \n- **\\[Anything else\\]**: This would vary per endpoint called. Applicable values would be in the documentation for that endpoint.\n    \n\n# HTTP Status Codes\n\n- **200**: A successful request occurred, do note that the description field on the response can contain further steps to be carried on this transaction\n    \n- **400**: Data validation error occurred due to inconsistent data supplied by the client\n    \n- **401**: Invalid request authorization, which might be due to invalid API key or the client is not registered for the service being accessed.\n    \n- **500**: An internal server error at our End, this should be reported if it persists.\n    \n\n# Encryption of Secure element\n\nFor encryption of values for the `auth.secure` field, you'd use Triple DES Encryption algorithm with your application secret key as the encryption key\n\nE.g.\n\n```\nTripleDES.encrypt(\"{bvn}\",secretKey)\nTripleDES.encrypt(\"{bank_account;bank_code}\",secretKey)\nTripleDES.encrypt(\"{otp}\",secretKey)\n\n ```\n\n**NOTE For DCIR:**\n\nCVV is not required for Card-Present transactions, the cvv position should be left empty.\n\n```\nTripleDES.encrypt(\"{card.Pan;card.Cvv;card.Expdate;card.Pin}\",secretKey) => Card-Not-Present\nTripleDES.encrypt(\"{card.Pan;;card.Expdate;card.Pinblock}\",secretKey) => Card-Present\n\n ```\n\n**NOTE** Expiry date is YYMM\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  $method = \"des-ede3-cbc\";\n  $source = mb_convert_encoding($encryption_key, 'UTF-16LE', 'UTF-8');\n  $encryption_key = md5($source, true);\n  $encryption_key .= substr($encryption_key, 0, 16);\n  $iv =  \"\\0\\0\\0\\0\\0\\0\\0\\0\";\n  $encData = openssl_encrypt($data, $method, $encryption_key, $options = OPENSSL_RAW_DATA, $iv);\n  return 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# Switching providers for a service\n\nAll services subscribed to in your application are attached to providers that will end up fulfilling such service(s) on request. You can switch providers as you wish by managing the application from your dashboard and editing the service details. Also, for some endpoints, you can explicitly set the provider you would like to be used in the request payload. You would see examples in the documentation for the endpoints that support this.\n\n# Bank CBN Codes\n\nAnywhere bank codes are required in the API specification (bank_code), this refers to the CBN bank codes. Details of all bank codes can be found [here](https://sandbox.interswitchng.com/docbase/docs/autogate-file-transfer/appendix/bank-cbn-codes/).\n\nNow let's dive deeper into specific API calls.","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":false,"owner":"6358444","team":242895,"collectionId":"ec7e062e-ee83-4f44-9214-2a2f6222e4b4","publishedId":"UUy7ZPGS","public":true,"publicUrl":"https://docs.paygateplus.ng","privateUrl":"https://go.postman.co/documentation/6358444-ec7e062e-ee83-4f44-9214-2a2f6222e4b4","customColor":{"top-bar":"FFFFFF","right-sidebar":"0E247D","highlight":"78b943"},"documentationLayout":"classic-double-column","customisation":null,"version":"8.10.1","publishDate":"2021-10-07T14:06:28.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{},"logos":{}},"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.paygateplus.ng/view/metadata/UUy7ZPGS"}