docs.poolerapp.com
Preview meta tags from the docs.poolerapp.com website.
Thumbnail
Search Engine Appearance
Pooler's Suite. 🚀
Pooler is a modern and multi-purpose Banking as a Service infrastructure built to allow businesses to smoothly collect payment from their customers in multiple ways using a virtual account number. The easiest way to use the Pooler API is by clicking the **Run in Postman** button above. [Postm ](https://www.getpostman.com/) is a free tool that helps developers run and debug API requests. Every endpoint documented here is readily available by running our Postman collection. ## Support Pooler engineers are always available to answer your questions. The quickest way to get help is by posting your question on the [Slack channel](https://join.slack.com/t/woodcorehq/shared_invite/zt-1qcmtll1e-oPWNw3nDIlvNpOUgNI~GYQ) with the tag **@support**. It is guaranteed that you will receive a response within 5-20 minutes max! ## Endpoints The API is accessed by making HTTP requests to the pooler endpoint URL. Every (methods, parameters, etc.) is fixed to a version number, and every request must contain one. We have provided a single base URL for both **Test** and **Live** environment. You can switch from the test environment to the live environment on your dashboard whenever needed, provided you have completed all compliance requirements. **The stable HTTP endpoint for the latest version is**: | **Base URL** | **Environment** | | --- | --- | | `https://api.poolerapp.com/api/v1` | Live/Test Environment | It's **important** to note that any transactions conducted in the live environment are considered live transactions, meaning they have actual financial implications. Take caution when performing actions in the live environment to ensure accuracy and validity. # Onboarding Upon registration, an email One-Time-Password (OTP) will be sent to the email address you provided during registration. Enter the OTP to sign into your Pooler account. Once you are signed in, subsequent access to your account will only require your email and password, without any additional OTP entry. ## **Live vs Test environment** Your first interaction on Pooler is the Pooler test environment. This is the default mode created for practicing and testing out Pooler’s features. In this environment, you can create test virtual accounts, process transfers, and explore other Pooler services to get acquainted with the system and more essentially upload your Know Your Customer (KYC) information for review. In addition, test API Keys are provided specifically for integrating with test environments. These environments define the limits to what actions you can take within your account and how your transactions are handled on Pooler. For instance, in the test mode, you can not conduct real transactions that have actual financial implication. Once your KYC details are approved, your account will promoted to the Live environment. Here, a new set of API keys (a secret key and a public key) will be generated for you. These keys enable you to conduct live transactions and interact with Pooler's APIs for a real transactions that have actual financial implication. ## **Demo bank** We have provided a [Demo Bank](https://demobank.poolerapp.com/) simulator to enable you to fund your account during test integrations. The demo bank serves as an external bank to enable you to practice how collection or inflow payment works. 🚫 **IMPORTANT**: The minimum deposit amount for collection is N200. This is set to cover the associated collection charge. Therefore, any collection made with an amount lower than the deposit amount will fail as it falls below the minimum threshold. It is important to ensure that the deposit amount meets or exceeds the minimum required amount to avoid transaction failures. # Security This section will guide you through accessing your Pooler account, and the available security operations. Here you will learn how authentication, and user verification, work on Pooler. ## **Authorization: API Keys** When you sign up, Pooler creates API keys for you to use when making and verifying requests. You can find these keys on your dashboard. There are two types of API keys on Pooler: - **API Key**: This key is for authenticating your API calls using the OAuth 2.0 authentication algorithm. You are required to include a secret key in the Authorization header of each API request. In this format:`Authorization: pk_test_****` - **Public Key:** The public key is specifically designed to integrate the Pooler Inline Javascript to access [Pooler Checkout.](https://docs.poolerapp.com/#f6ac8366-7c0f-4112-878b-ca860b05408c) It is important to note that these public keys can not be used to create accounts or transactions via APIs. They are only for integrating with the frontend. **To get your API keys:** 1. On your Dashboard, navigate to UTILITY & SETTINGS > Developers. 2. Alternatively, click on the Profile icon > Profile & Account on your Dashboard. The Developers section is located at the bottom of the page. If your account has 2FA enabled, you will need to enter the Time-based One-Time Password (TOTP) displayed from your authenticator app to view the key. 🚧 **WARNING**: Ensure to safeguard your API keys and avoid any disclosure or exposing it in any way. ## Two-Factor Guide You have the option to enable two-factor authentication on your account as a additional layer of security. This system requires you to sign in and verify your identity using a third-party authenticator app such as [Google Authenticator](https://googleauthenticator.net/), [Microsoft Authenticator](https://support.microsoft.com/en-us/account-billing/download-and-install-the-microsoft-authenticator-app-351498fc-850a-45da-b7b6-27e523b8702a), or any other authenticator application of your choice. It is important to have either of these apps installed on your mobile device. With 2FA enabled, subsequent sign in to your Pooler account, will require the use of an OTP from an authenticator app. This layer of security extends to any attempt to view your secret keys, which will also require the use of an OTP from the authenticator app. To enable 2FA authentication, first sign in with your email OTP. Next, on your dashboard, navigate to your Profile icon > Profile & account. At the bottom of the page, you'll find the option to "Enable two-factor authentication.” For more information, see the [Multi-Factor Guide](https://docs.poolerapp.com/#multi-factor-guide) for more information. #### **Setting up the Authenticator App using the Scan feature** You can setup your Authenticator app by scanning the QR displayed on the Pooler sign-in page. Follow the steps below to set up your app: 1. Ensure you have your [Google](https://googleauthenticator.net/), [Microsoft](https://support.microsoft.com/en-us/account-billing/download-and-install-the-microsoft-authenticator-app-351498fc-850a-45da-b7b6-27e523b8702a), [Authy](https://authy.com/) or any other authenticator app installed on your mobile device. 2. Click on the + icon and select the “Scan a QR code” option 3. Scan the QR code on your [Pooler 2-step verification sign-in page](https://app.poolerapp.com/verify_otp?action=complete2fa), using your mobile device. On completion, a 6-digits code will be displayed on your authenticator app. Enter the code in the required fields on your Pooler verifiation page. **Note:** The code expires after 30seconds. #### Setting up Authenticator App using Secret Key Alternatively to the "QR code scan" feature for setting up authenticator app, you can setup your [Google](https://googleauthenticator.net/), [Microsoft](https://support.microsoft.com/en-us/account-billing/download-and-install-the-microsoft-authenticator-app-351498fc-850a-45da-b7b6-27e523b8702a), [Authy](https://authy.com/), or any other authenticator app to generate One-Time Passwords (OTPs) using a set of unique 16-character alphanumeric secret key. The Secret Key is available on the UI of your [Pooler 2-step verification page](https://app.poolerapp.com/verify_otp?action=complete2fa). To initiate this setup, you can manually copy and input the provided secret key into your authenticator app. This will enable your app to generate the required OTPs for your sign-in process. The steps below will guide you through this process: 1. Ensure you have your Google, Microsoft, or Authy authenticator app installed on your device. 2. Next, on your Pooler 2-step verification sign-in page, we have provided a set of 16-character alphanumeric secret keys below the QR code. 3\. Copy the Secret Key and navigate to your authenticator app. 4\. Click on the **+** icon on your authenticator app and select the “Setup key” option. 5\. In the Account field, enter the email address linked to your Pooler account. 6\. Enter the Secret Key in the key field. You have the option to configure **time-based** OTP, which means, your secret key will change in sync with time. In this mode, a unique 6-digit code regenerates every 30 seconds. Alternatively, you can opt for **counter-based** OTP, which is not time-dependent. In this mode, the 6-digit code remains valid until refreshed by using the refresh icon. Upon successfully adding the Account and Secret Key, your authenticator app will promptly display the generated OTP. Copy this OTP and enter it into your Pooler verification page. ## **IP Whitelisting** IP whitelisting is a security measure that permits only to a specified list of IP addresses to make requests on your account. This ensures that only authorized users or devices with approved IP addresses can use your secret key for authorization. On Pooler, the IP whitelisting feature is available to further enhance the security of your account, preventing unauthorized access to your data. **How does it work?** When you make an API request, your secret key (available on your dashboard) authorizes this request. IP whitelisting adds extra security by allowing only the IP addresses you havr provided to make requests with your merchant secret key. When you whitelist an IP address, for every API request made using your secret key, we will verify the IP address of the user. If the IP address matches the whitelisted address, the request will be approved. However, if the request comes from an IP address not on the list, we block it. **Note** that this feature is optional and only designed to enable you to further secure your data and transactions on Pooler. We have provided other [security](https://docs.poolerapp.com/#security) measures to safeguard your account. **How to whitelist an IP address** - On your Pooler account dashboard, simply navigate to the profile icon at the top right of your screen and select **"Profile & account”.** - In the **Developer section,** add the IP address you wish to whitelist. You can add as many addresses as you need for added security. **Note:** 1. Whitelisting only blocks requests made using your secret key, which is API request. This means it does not affect access to your Pooler dashboard. 2. Once an IP address is whitelisted, it cannot be duplicated; you can only whitelist an IP address once. 3. There is no limit to the number of IP addresses you can whitelist on your Pooler account. You can add as many addresses as desired. # Webhook In addition to email notification of transactions, webhook is a fast and cost-effective way to manage system-to-system communications. Below are the supported events that trigger a webhook on Pooler. **Available webhook action type and event.** | **Action Type** | **Event** | | --- | --- | | Account Created | `event.create.account` | | Incoming Transaction — \[Collected\] | `event.collection` | | Outgoing Transaction — \[Transfer- successful\] | `event.transfer.success` | | Outgoing Transaction — \[Transfer- reversed\] | `event.transfer.reversed` | | Outgoing Transaction — \[Transfer- failed\] | `event.transfer.failed` | **NOTE:** The creation of an expiry account, also known as a disposable account, during the checkout process does **NOT** trigger a webhook event. These disposable accounts have a short-term lifespan, designed to expire upon reaching their predetermined time limit. Thereby, webhook events are not sent when these accouts are created. However this applies only to accounts created during the checkout process. **Provide Webhook URL** To get webhook events and actions notifications, you are required to provide a webhook URL which these notifications will be sent. Follow the steps below to setup a webhook on your Pooler account: 1. Log in to your Pooler account and click to the profile icon at the top right of the dashboard. 2. Select **Profile & Account** and navigate to **Webhook URL** field on the **Developers section.** 3\. Enter your webhook URL and click on the **Submit** button. 🚫 **IMPORTANT:** _We recommend that you use webhook to provide value to your customers._ you should acknowledge the event before executing the long-running tasks. Long-running tasks will lead to a request timeout and an automatic error response from your server without a `200 OK` response. **Verify the Message & Prevent Replay Attacks** A webhook URL is an endpoint on the client's API. This endpoint is publicly available and because of this, it can be called from any application. As a webhooks receiver, you want to verify that requests hitting your endpoint are coming from the right source. ### Transfer Webhook In addition to the [Transfer Status Query](https://docs.poolerapp.com/#31a2ab13-6e0b-45a0-909f-198bb7aa74da) endpoint, we **highly recommend** that you verify the status to every transfer processed using the webhook notifications sent to your webhook URL. These notifications include details of the transfer status and its corresponding value, which will provide you with adequate information on the status of your transfer. On Pooler, there are three key transfer statuses that are returned for each transfer transaction: 1. Completed 2. Reversed 3. Failed For a comprehensive understanding of these statuses and their associated values, the section below contains sample webhooks for each transfer status and detailed description to ensure you have a good understanding of each transfer webhook. #### **Successful transfer** For each successfully processed transfer, the table below contains actions and their response. | Status | Value | Description | | | --- | --- | --- | --- | | `completed` | `true` | The transfer has been successfully processed. | | | `failed` | `false` | The transaction is successfully processed | | | `is_reversed` | `false` | The transfer was not reversed, because it was completed. | | Here is an example of a successful transfer webhook notification: ``` json { "event": "event.transfer.success", "data": { "id": 23, "merchant_id": 41, "amount": "225.00", "reference": "PLRTRF_14006021696337464189", "completed": true, "in_transit": false, "failed": false, "from_mercahnt_number": "5586037126", "from_merchant_name": "Losales", "target_number": "2011117825", "target_name": "OYEBANJI OLAYEMI", "target_bank_code": "000004", "createdAt": "2023-10-03T12:51:04.000Z", "updatedAt": "2023-10-03T12:51:07.266Z", "version": 1, "gateway": { "id": 87, "merchant_id": 41, "payout_id": 23, "fee_amount": "25", "account_no": "5586037126", "account_type": null, "is_reversed": false, "transaction_type": "transfer", "reference": "PLRTRF_14006021696337464189", "session_id": "3511414131100014111696337464414", "amount": "250.00", "currency": "NGN", "narration": "Losales/tar/OYEBANJI OLAYEMI", "pending": false, "completed": true, "is_virtual_account": 0, "sender_details": { "bvn": "22222222222", "name": "Losales", "email": "[email protected]", "bank_code": "090380", "bank_name": "Kredi Money Microfinance Bank", "mobile_number": "2348907652341", "account_number": "5586037126" }, "reciever_details": { "bvn": null, "name": "OYEBANJI OLAYEMI", "bank_code": "000004", "account_number": "2011117825" }, "settled_amount": "225.00", "reversal_reference": null, "settlement_account_id": 41, "created_at": "2023-10-03T12:51:04.000Z", "modified_at": "2023-10-03T12:51:07.264Z" } } } ``` #### **Reversed Transfer** Webhook notifications are also sent for transfers that have been reversed due to failure to complete or process. The table below contains the status and value returned for a reversed transfer. | Status | Value | Description | | --- | --- | --- | | `completed` | `false` | The transfer was not successful, either failed or has been reversed. Check `is_reversed` and `failed` status to confirm. | | `failed` | `true` | The transfer was unsuccessful and could not be processed. Check `is_reversed` status if transfer was been reversed. | | `is_reversed` | `true` | The transfer was not successful, and the funds has been reversed to the sender's account. | Here is a sample of reversed transfer webhook notification: ``` json { "event": "event.transfer.reversed", "data": { "id": 28, "merchant_id": 41, "amount": "500.00", "reference": "PLRTRF_16085041696566206081", "completed": false, "in_transit": false, "failed": true, "from_mercahnt_number": "5586037126", "from_merchant_name": "Losales", "target_number": "1234567890", "target_name": "WOODCORE POOLER SETTLEMENT CLIENT", "target_bank_code": "999998", "is_payout": false, "createdAt": "2023-10-06T04:23:26.000Z", "updatedAt": "2023-10-06T04:23:27.743Z", "version": 1, "gateway": { "id": 95, "merchant_id": 41, "payout_id": 28, "fee_amount": "25", "account_no": "5586037126", "account_type": null, "is_reversed": true, "transaction_type": "transfer", "reference": "PLRTRF_16085041696566206081", "session_id": "8141011242711401131696566206337", "amount": "525.00", "currency": "NGN", "narration": "Losales/tar/WOODCORE POOLER SETTLEMENT CLIENT", "pending": false, "completed": false, "is_virtual_account": 0, "sender_details": { "bvn": "22222222222", "name": "Losales", "email": "[email protected]", "bank_code": "090380", "bank_name": "Kredi Money Microfinance Bank", "mobile_number": "2348907652341", "account_number": "5586037126" }, "reciever_details": { "bvn": null, "name": "WOODCORE POOLER SETTLEMENT CLIENT", "bank_code": "999998", "account_number": "1234567890" }, "settled_amount": "500.00", "reversal_reference": "9A4D429D5E71", "settlement_account_id": 41, "is_payout": false, "created_at": "2023-10-06T04:23:26.000Z", "modified_at": "2023-10-06T04:23:27.74 ``` #### **Failed Transfer** In the event of a transfer request failure, webhook notifications are sent to your webhook URL. | Status | Value | Description | | --- | --- | --- | | `completed` | `false` | The transfer was not successful, either failed or has been reversed. Check `is_reversed` and `failed` status to confirm. | | `failed` | `true` | The transfer was unsuccessful and could not be processed. Check `is_reversed` status if transfer was reversed. | | `is_reversed` | `false` | Funds reversal did not take place. | Here is a sample of failed transfer webhook notification: ``` json { "event": "event.transfer.failed", "data": { "id": 209, "merchant_id": 12, "amount": "300.00", "reference": "PLRT_1715673", "completed": false, "in_transit": false, "failed": true, "from_mercahnt_number": "3122052555", "from_merchant_name": "IEP analytics", "target_number": "1011000200", "target_name": "POOLER MINI UPDATED", "target_bank_code": "090325", "createdAt": "2023-10-06T02:39:09.000Z", "updatedAt": "2023-10-06T02:40:47.599Z", "version": 1, "gateway": { "id": 481, "merchant_id": 12, "payout_id": 209, "fee_amount": "50", "account_no": "3122052555", "account_type": null, "is_reversed": false, "transaction_type": "transfer", "reference": "PLRT_1715673", "session_id": "157441351108144131696559949154", "amount": "350.00", "currency": "NGN", "narration": "PAYOUT FROM/IEP TO POOLER MINI UPDATED", "pending": false, "completed": false, "is_virtual_account": 0, "sender_details": { "bvn": "22222222222", "name": "IEP analytics", "email": "[email protected]", "bank_code": "090380", "bank_name": "Kredi Money Microfinance Bank", "mobile_number": "08207608950899", "account_number": "3122052555" }, "reciever_details": { "bvn": null, "name": "POOLER MINI UPDATED", "bank_code": "090325", "account_number": "1011000200" }, "settled_amount": "300.00", "reversal_reference": null, "settlement_account_id": 12, "created_at": "2023-10-06T02:39:09.000Z", "modified_at": "2023-10-06T02:40:47.589Z" } } } ``` ### Intra-transfer Webhook Similar to transfers, webhook events are sent when a transfer is made from one wallet to another wallet under the same merchant. This process is known as "[Intra-transfer](https://docs.poolerapp.com/#ca872ede-3b9f-40c3-8a3d-f42b1f9f8655)" When an intra-transfer is performed, a webhook event is sent to your webhook URL, containing details of the transfer. **Note**: You cannot perform fund transfers from a wallet to an external bank or a wallet created by another merchant on Pooler. See the [Pooler Wallet](https://docs.poolerapp.com/#0446c510-e38e-49b3-8d4b-65cf37216144) section for more information. Here is a sample of an intra-transfer webhook: ``` json { "event": "event.intra.transfer", "data": { "id": 215, "completed": true, "merchant_id": 209, "reference": "GGHTKLJHG", "amount": 5000, "session_id": "GGHTKLJHG", "bank_name": "KREDI MONEY MFB", "target_account_number": "5564559659", "target_account_name": "Anita Achu/Cashier two", "narration": "Hey Buying", "createdAt": "2024-01-24T13:48:12.024Z", "updatedAt": "2024-01-24T13:48:12.024Z", "gateway": { "id": 215, "merchant_id": 209, "fee_amount": 0, "account_no": "5512966493", "is_reversed": false, "transaction_type": "intra-transfer", "reference": "GGHTKLJHG", "session_id": "GGHTKLJHG", "amount": 5000, "currency": "NGN", "narration": "Hey Buying", "completed": true, "wallet_account": true, "sender_details": { "name": "Anita Achu/Cashier two", "account_number": "5564559659", "bvn": "22222222222", "bank_code": "KREDI MONEY MFB" }, "reciever_details": { "name": "Anita Achu/Cashier One", "account_number": "5512966493", "bvn": "22222222222", "bank_code": "KREDI MONEY MFB" }, "settled_amount": 5000, "settlement_account_id": 132, "modified_at": "2024-01-24T13:48:12.475Z", "updatedAt": "2024-01-24T13:48:12.475Z" } } } ``` ### **Signature Validation** Events sent from Pooler come with the `x-swim-token`. The value of this header is a `HMAC SHA256`signature of the event payload signed using your secret key. Verifying the header signature should be done before processing the event: **JavaScript Sample** ``` javascript const signature = crypto // api_key derived for Pooler Dashboard .createHmac("sha256", api_key) .update(JSON.stringify(req.body)) .digest("hex"); if (signature == req.headers["x-swim-token"]) { // Body is signed and valid. Goodluck } ``` **Java Sample** ``` java package hmacexample; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import org.json.JSONException; import org.json.JSONObject; public class HMacExample { public static void main(String[] args) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, JSONException { //first you verify that this request came from pooler String key = "YOUR_API_KEY"; //replace with your pooler x-key String rawJson = "{}"; JSONObject body = new JSONObject(rawJson); String result = ""; String HMAC_SHA256 = "HmacSHA256"; String xpoolerSignature = ""; //put in the request's header value for x-swim-token byte [] byteKey = key.getBytes("UTF-8"); SecretKeySpec keySpec = new SecretKeySpec(byteKey, HMAC_SHA256); Mac sha256_HMAC = Mac.getInstance(HMAC_SHA256); sha256_HMAC.init(keySpec); byte [] mac_data = sha256_HMAC. doFinal(body.toString().getBytes("UTF-8")); result = DatatypeConverter.printHexBinary(mac_data); if(result.toLowerCase().equals(xpoolerSignature)) { // you can trust the event, it came from pooler // respond with the http 200 response immediately before attempting to process the response }else{ // this isn't from Pooler, ignore it } } } ``` **C# Sample** ``` csharp using System; using System.Security.Cryptography; using System.Text; using Newtonsoft.Json.Linq; namespace HMacExample { class Program { static void Main(string[] args) { String key = "YOUR_API_KEY"; //replace with your pooler secret_key String jsonInput = "{}"; //the json input String inputString = Convert.ToString(new JValue(jsonInput)); String result = ""; byte[] secretkeyBytes = Encoding.UTF8.GetBytes(key); byte[] inputBytes = Encoding.UTF8.GetBytes(inputString); using (var hmac = new HMACSHA256(secretkeyBytes)) { byte[] hashValue = hmac.ComputeHash(inputBytes); result = BitConverter.ToString(hashValue).Replace("-", string.Empty);; } Console.WriteLine(result); String signature = ""; //put in the request's header value for x-swim-token if(result.ToLower().Equals(signature)) { // you can trust the event, it came from pooler // respond with the http 200 response immediately before attempting to process the response } else { // this isn't from pooler, ignore it } } } } ``` ``` python import hmac import hashlib pooler_signature = request.headers.get("x-swim-token") key = secret_key.encode("utf-8") mes = json.dumps(payload, separators=(',', ':')).encode("utf-8") encoded_payload = hmac.new(key, mes, hashlib.sha256).hexdigest() if encoded_payload == pooler_signature: return True else: return False ``` ### **Webhook Retry Mechanism** Where a webhook event is not processed and fails to send data to your webhook URL, Pooler provides a webhook retry mechanism that automatically retries failed events after a 10 minutes interval. **How does it work?** When a transaction request or account creation is processed, a webhook event is sent to the provided webhook URL. If acknowledged, a `200` status code response is returned. However, where the webhook event fails to process, i.e., does not return a `200` status code for the initial webhook event, the webhook retry mechanism will retry the webhook **every 10 minutes for a limited number of 20 times**. If the webhook is successful at any point during the retry, the webhook retry stops. This will enable you to prevent potential failovers and ensure that all events are accurately logged. If you encounter any issues or have questions about the webhook re feature, kindly contact our [support team](https://join.slack.com/t/woodcorehq/shared_invite/zt-1qcmtll1e-oPWNw3nDIlvNpOUgNI~GYQ) for assistance. # Collection Collection refers to fund transfer from an external bank account to the Pooler virtual accounts. For example a fund transfer from customer's **Access Bank** to **Anita Bakery Services** (pooler virtual account). Through collections your pooler accounts both virtual and merchant account are funded. The funds received from collection are automatically settled on the merchant account. ### Demo Bank Please use the Pooler [Demo Bank](https://demobank.poolerapp.com) simulator to process collections when integrating. 🚫 IMPORTANT: The minimum deposit amount for collection is N200. This is set to cover the associated collection charge. Therefore, any collection made with an amount lower than the deposit amount will fail as it falls below the minimum threshold. It is important to ensure that the deposit amount meets or exceeds the minimum required amount to avoid transaction failures. ### **Mismatch or Incorrect Collection Amount** When sending money to an account generated during checkout or to a disposable account that has an amount set on it, the expectation is that the customer sends the exact amount for that checkout or disposable account. In the event where an incorrect amount is sent to the checkout or disposable account, you will get a webhook event with appropriate information that informs you that the customer sent the wrong amount. **Webhook** Webhook events are sent for every collection received on your merchant account. This event contain details of the collection received to enable you verify payment. However, getting an `event.collection` event is not a sufficient indication that collection was successfully settled into your account. Ensure you verify that the `completed` parameter on the webhook payload is set to `true` before proceeding to provide value. The `event.collection` webhook also has includes an `amount_mismatch_data` field. This field contains information incases where an incorrect amount is received. If the amount sent to your account does not match the expected sum or there is a discrepancy in the amount, an `amount_mismatch` field will be set to `true`. The table below shows `amount_mismatch_data` field: | **Key** | **Value** | **Description** | | --- | --- | --- | | **`amount_mismatch`** | `boolean[true]` | An incorrect amount was received. | | `amount_sent` | `string[amount]` | The value of the incorrect amount sent into the account | | `amount_on_account` | `string[amount]` | The value of the expected amount. | | `over` | `boolean` | If `true` it means the amount was above and if `false` means the amount was below the expected amount. | Here is a sample of an **incorrect collection** **amount** webhook. ``` json { "event": "event.collection", "data": { "version": 0, "id": 494, "completed": true, "merchant_id": 1, "account_id": 5, "reference": "PLR_1412786", "amount": "220.00", "session_id": "090529231117194540297591535889", "bank_name": "KREDI MICROFINANCE BANK", "target_account_number": "1234567890", "target_account_name": "WOODCORE/OPEOLUWA KOLAPO", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 220 to KREDI MONEY MFB 1234567890", "payment_link_id": null, "payment_link_info_id": null, "updatedAt": "2023-11-17T19:46:53.523Z", "createdAt": "2023-11-17T19:46:53.523Z", "gateway": { "is_payout": false, "id": 805, "merchant_id": 1, "collection_id": 494, "fee_amount": "100.00", "account_no": "1234567890", "is_reversed": false, "transaction_type": "collection", "reference": "PLR_1412786", "session_id": "090529231117194540297591535889", "amount": "220.00", "currency": "NGN", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 220 to KREDI MONEY MFB 5581340391", "completed": true, "pending": false, "is_virtual_account": true, "sender_details": { "name": "ACCESS BANK", "account_number": "0987654321", "bvn": "null", "bank_code": "000014", "bank_name": null }, "reciever_details": { "name": "WOODCORE/OPEOLUWA KOLAPO", "account_number": "5512345678", "bank_code": "90898" }, "settled_amount": "120.00", "settlement_account_id": 1, "payment_link_id": null, "payment_link_info_id": null, "remark": "Wrong Amount Sent. Amount Set On Disposable Account Is 1000.00, While The Amount Deposited Is 220.00", "amount_mismatch": true, "modified_at": "2023-11-17T19:46:53.531Z", "created_at": "2023-11-17T19:46:53.531Z", "amount_mismatch_data": { "amount_sent": "220.00", "amount_on_account": "1000.00", "over": false } }, "payment_link_data": null, "checkout_payer_info": null } } ``` From the webhook above, whenever the `amount_mismatch` field is set to `true` this indicates that your customer has sent an amount that does not match the expected collection amount. You have the option to initiate a refund using our [Transfer endpoints](https://docs.poolerapp.com/#b46e9b72-e6b6-4c07-a423-82080b5d9260), ensuring a swift resolution by refunding the amount back to the customer. When a correct amount is received, you'll receive the following webhook response. See sample of a **correct collection** amount webhook below: ``` json { "event": "event.collection", "data": { "version": 0, "id": 495, "completed": true, "merchant_id": 1, "account_id": 5, "reference": "PLR_1800946", "amount": "1000.00", "session_id": "090529231117195923625421209723", "bank_name": "KREDI MICROFINANCE BANK", "target_account_number": "1234567890", "target_account_name": "WOODCORE/OPEOLUWA KOLAPO", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 1000 to KREDI MONEY MFB 1234567890", "payment_link_id": null, "payment_link_info_id": null, "updatedAt": "2023-11-17T20:00:33.491Z", "createdAt": "2023-11-17T20:00:33.491Z", "gateway": { "is_payout": false, "id": 806, "merchant_id": 1, "collection_id": 495, "fee_amount": "100.00", "account_no": "1234567890", "is_reversed": false, "transaction_type": "collection", "reference": "PLR_1800946", "session_id": "090529231117195923625421209723", "amount": "1000.00", "currency": "NGN", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 1000 to KREDI MONEY MFB 5581340391", "completed": true, "pending": false, "is_virtual_account": true, "sender_details": { "name": "ACCESS BANK", "account_number": "0987654321", "bvn": "null", "bank_code": "000014", "bank_name": null }, "reciever_details": { "name": "WOODCORE/OPEOLUWA KOLAPO", "account_number": "1234567890", "bank_code": "90898" }, "settled_amount": "900.00", "settlement_account_id": 1, "payment_link_id": null, "payment_link_info_id": null, "remark": null, "amount_mismatch": false, "modified_at": "2023-11-17T20:00:33.495Z", "created_at": "2023-11-17T20:00:33.495Z" }, "payment_link_data": null, "checkout_payer_info": null } } ``` ### **Initial Inward Credit Webhook** When payment is made into your account, we promptly initiate the settlement process on our end. This triggers a pending collection event which is sent to your webhook URL, known as **initial inward credit event**, which indicates that the collection has been acknowledged on our end and is being processed to be settled in your Pooler account. ``` json { "event": "event.collection.pending", "data": { "merchant_id": 1, "fee_amount": "100.00", "account_no": "5582012744", "is_reversed": false, "transaction_type": "collection", "session_id": "090529231118130406138931096794", "amount": "300.00", "settled_amount": "200.00", "currency": "NGN", "sender_details": { "account_no": "5876543210", "account_name": "ACCESS BANK", "bank_name": "000014" }, "reciever_details": { "account_no": "5512345678", "account_name": "WOODCORE/OPEOLUWA KOLAPO", "bank_name": "KREDI MFB" }, "settlement_account_id": 1, "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 300 to KREDI MONEY MFB 5582012744", "completed": false, "pending": true, "payment_link_data": null, "checkout_payer_info": null } } ``` 🚫 **IMPORTANT:** The `event.collection.pending` webhook does not mean that the money has been settled into your account. It serves as a notification for collection awaiting settlement. We **strongly advise** that you wait for the for `event.collection` webhook before proceeding with any further actions. The `event.collection.pending` webhook has an `amount_mismatch_data` field. This field contains information to enable you to verify if the amount sent by the customer is the right amount. Where the amount sent by your customer does not match the expected amount, the `amount_mismatch` field will be set to `true`, and there will be an `amount_mismatch_data` object in the payload; this indicates that the incorrect amount, either exceeding or below the expected amount, was received**.** Once a collection has been received and settled into your account, an `event.collection` will be sent to your webhook URL. **ONLY** use this webhook event to verify that payment has been received and settled into your account before you proceed to provide value to your customers. _The initial inward credit feature is available on demand. If you wish to receive initial inward credit webhook events, reach out to our developers via_ [Slack](https://woodcorehq.slack.com/ssb/redirect) _for a swift response to your request._ # Pagination _For the most part, if the API action is plural, you can page it via a query string parameter. The default number of items to be returned is 10._ | Query String Parameter | Required | Description | | --- | --- | --- | | page | optional | Page number of the result set (default: 0) | | perPage | optional | Limit the number of results per page. (default: 10) | # API Response Code These response codes provide detailed description of issues you may encounter while using the Pooler API service. This includes issues such as incorrect parameters, invalid API keys, and actions that disrupt the regular function of the system such as invalid or already existing fields and so on. The response listed below covers Pooler V1: | **Response code** | **Description** | | --- | --- | | 200 `SUCCESS` | The request was acccpted and processed. | | 202 `ACCEPTED` | The request has been accepted and is being processed. | | 400 `BAD_REQUEST` | The required parameter is invalid or already exists on the system. | | 401 `UNAUTHORIZED` | The caller is not authorized to make use of the service. Verify your API key. | | 422 `UNPROCESSABLE ENTITY` | Invalid request data. This can include incorrect keys or JSON body. Review the request data and ensure that it meets the expected format, field, and validation rules. | | 404 `NOT FOUND` | The page was not found. This may be returned if the URL or endpoint does not exist | | 500 `INTERNAL SERVER ERROR` | There was an error while processing your request on the server. |
Bing
Pooler's Suite. 🚀
Pooler is a modern and multi-purpose Banking as a Service infrastructure built to allow businesses to smoothly collect payment from their customers in multiple ways using a virtual account number. The easiest way to use the Pooler API is by clicking the **Run in Postman** button above. [Postm ](https://www.getpostman.com/) is a free tool that helps developers run and debug API requests. Every endpoint documented here is readily available by running our Postman collection. ## Support Pooler engineers are always available to answer your questions. The quickest way to get help is by posting your question on the [Slack channel](https://join.slack.com/t/woodcorehq/shared_invite/zt-1qcmtll1e-oPWNw3nDIlvNpOUgNI~GYQ) with the tag **@support**. It is guaranteed that you will receive a response within 5-20 minutes max! ## Endpoints The API is accessed by making HTTP requests to the pooler endpoint URL. Every (methods, parameters, etc.) is fixed to a version number, and every request must contain one. We have provided a single base URL for both **Test** and **Live** environment. You can switch from the test environment to the live environment on your dashboard whenever needed, provided you have completed all compliance requirements. **The stable HTTP endpoint for the latest version is**: | **Base URL** | **Environment** | | --- | --- | | `https://api.poolerapp.com/api/v1` | Live/Test Environment | It's **important** to note that any transactions conducted in the live environment are considered live transactions, meaning they have actual financial implications. Take caution when performing actions in the live environment to ensure accuracy and validity. # Onboarding Upon registration, an email One-Time-Password (OTP) will be sent to the email address you provided during registration. Enter the OTP to sign into your Pooler account. Once you are signed in, subsequent access to your account will only require your email and password, without any additional OTP entry. ## **Live vs Test environment** Your first interaction on Pooler is the Pooler test environment. This is the default mode created for practicing and testing out Pooler’s features. In this environment, you can create test virtual accounts, process transfers, and explore other Pooler services to get acquainted with the system and more essentially upload your Know Your Customer (KYC) information for review. In addition, test API Keys are provided specifically for integrating with test environments. These environments define the limits to what actions you can take within your account and how your transactions are handled on Pooler. For instance, in the test mode, you can not conduct real transactions that have actual financial implication. Once your KYC details are approved, your account will promoted to the Live environment. Here, a new set of API keys (a secret key and a public key) will be generated for you. These keys enable you to conduct live transactions and interact with Pooler's APIs for a real transactions that have actual financial implication. ## **Demo bank** We have provided a [Demo Bank](https://demobank.poolerapp.com/) simulator to enable you to fund your account during test integrations. The demo bank serves as an external bank to enable you to practice how collection or inflow payment works. 🚫 **IMPORTANT**: The minimum deposit amount for collection is N200. This is set to cover the associated collection charge. Therefore, any collection made with an amount lower than the deposit amount will fail as it falls below the minimum threshold. It is important to ensure that the deposit amount meets or exceeds the minimum required amount to avoid transaction failures. # Security This section will guide you through accessing your Pooler account, and the available security operations. Here you will learn how authentication, and user verification, work on Pooler. ## **Authorization: API Keys** When you sign up, Pooler creates API keys for you to use when making and verifying requests. You can find these keys on your dashboard. There are two types of API keys on Pooler: - **API Key**: This key is for authenticating your API calls using the OAuth 2.0 authentication algorithm. You are required to include a secret key in the Authorization header of each API request. In this format:`Authorization: pk_test_****` - **Public Key:** The public key is specifically designed to integrate the Pooler Inline Javascript to access [Pooler Checkout.](https://docs.poolerapp.com/#f6ac8366-7c0f-4112-878b-ca860b05408c) It is important to note that these public keys can not be used to create accounts or transactions via APIs. They are only for integrating with the frontend. **To get your API keys:** 1. On your Dashboard, navigate to UTILITY & SETTINGS > Developers. 2. Alternatively, click on the Profile icon > Profile & Account on your Dashboard. The Developers section is located at the bottom of the page. If your account has 2FA enabled, you will need to enter the Time-based One-Time Password (TOTP) displayed from your authenticator app to view the key. 🚧 **WARNING**: Ensure to safeguard your API keys and avoid any disclosure or exposing it in any way. ## Two-Factor Guide You have the option to enable two-factor authentication on your account as a additional layer of security. This system requires you to sign in and verify your identity using a third-party authenticator app such as [Google Authenticator](https://googleauthenticator.net/), [Microsoft Authenticator](https://support.microsoft.com/en-us/account-billing/download-and-install-the-microsoft-authenticator-app-351498fc-850a-45da-b7b6-27e523b8702a), or any other authenticator application of your choice. It is important to have either of these apps installed on your mobile device. With 2FA enabled, subsequent sign in to your Pooler account, will require the use of an OTP from an authenticator app. This layer of security extends to any attempt to view your secret keys, which will also require the use of an OTP from the authenticator app. To enable 2FA authentication, first sign in with your email OTP. Next, on your dashboard, navigate to your Profile icon > Profile & account. At the bottom of the page, you'll find the option to "Enable two-factor authentication.” For more information, see the [Multi-Factor Guide](https://docs.poolerapp.com/#multi-factor-guide) for more information. #### **Setting up the Authenticator App using the Scan feature** You can setup your Authenticator app by scanning the QR displayed on the Pooler sign-in page. Follow the steps below to set up your app: 1. Ensure you have your [Google](https://googleauthenticator.net/), [Microsoft](https://support.microsoft.com/en-us/account-billing/download-and-install-the-microsoft-authenticator-app-351498fc-850a-45da-b7b6-27e523b8702a), [Authy](https://authy.com/) or any other authenticator app installed on your mobile device. 2. Click on the + icon and select the “Scan a QR code” option 3. Scan the QR code on your [Pooler 2-step verification sign-in page](https://app.poolerapp.com/verify_otp?action=complete2fa), using your mobile device. On completion, a 6-digits code will be displayed on your authenticator app. Enter the code in the required fields on your Pooler verifiation page. **Note:** The code expires after 30seconds. #### Setting up Authenticator App using Secret Key Alternatively to the "QR code scan" feature for setting up authenticator app, you can setup your [Google](https://googleauthenticator.net/), [Microsoft](https://support.microsoft.com/en-us/account-billing/download-and-install-the-microsoft-authenticator-app-351498fc-850a-45da-b7b6-27e523b8702a), [Authy](https://authy.com/), or any other authenticator app to generate One-Time Passwords (OTPs) using a set of unique 16-character alphanumeric secret key. The Secret Key is available on the UI of your [Pooler 2-step verification page](https://app.poolerapp.com/verify_otp?action=complete2fa). To initiate this setup, you can manually copy and input the provided secret key into your authenticator app. This will enable your app to generate the required OTPs for your sign-in process. The steps below will guide you through this process: 1. Ensure you have your Google, Microsoft, or Authy authenticator app installed on your device. 2. Next, on your Pooler 2-step verification sign-in page, we have provided a set of 16-character alphanumeric secret keys below the QR code. 3\. Copy the Secret Key and navigate to your authenticator app. 4\. Click on the **+** icon on your authenticator app and select the “Setup key” option. 5\. In the Account field, enter the email address linked to your Pooler account. 6\. Enter the Secret Key in the key field. You have the option to configure **time-based** OTP, which means, your secret key will change in sync with time. In this mode, a unique 6-digit code regenerates every 30 seconds. Alternatively, you can opt for **counter-based** OTP, which is not time-dependent. In this mode, the 6-digit code remains valid until refreshed by using the refresh icon. Upon successfully adding the Account and Secret Key, your authenticator app will promptly display the generated OTP. Copy this OTP and enter it into your Pooler verification page. ## **IP Whitelisting** IP whitelisting is a security measure that permits only to a specified list of IP addresses to make requests on your account. This ensures that only authorized users or devices with approved IP addresses can use your secret key for authorization. On Pooler, the IP whitelisting feature is available to further enhance the security of your account, preventing unauthorized access to your data. **How does it work?** When you make an API request, your secret key (available on your dashboard) authorizes this request. IP whitelisting adds extra security by allowing only the IP addresses you havr provided to make requests with your merchant secret key. When you whitelist an IP address, for every API request made using your secret key, we will verify the IP address of the user. If the IP address matches the whitelisted address, the request will be approved. However, if the request comes from an IP address not on the list, we block it. **Note** that this feature is optional and only designed to enable you to further secure your data and transactions on Pooler. We have provided other [security](https://docs.poolerapp.com/#security) measures to safeguard your account. **How to whitelist an IP address** - On your Pooler account dashboard, simply navigate to the profile icon at the top right of your screen and select **"Profile & account”.** - In the **Developer section,** add the IP address you wish to whitelist. You can add as many addresses as you need for added security. **Note:** 1. Whitelisting only blocks requests made using your secret key, which is API request. This means it does not affect access to your Pooler dashboard. 2. Once an IP address is whitelisted, it cannot be duplicated; you can only whitelist an IP address once. 3. There is no limit to the number of IP addresses you can whitelist on your Pooler account. You can add as many addresses as desired. # Webhook In addition to email notification of transactions, webhook is a fast and cost-effective way to manage system-to-system communications. Below are the supported events that trigger a webhook on Pooler. **Available webhook action type and event.** | **Action Type** | **Event** | | --- | --- | | Account Created | `event.create.account` | | Incoming Transaction — \[Collected\] | `event.collection` | | Outgoing Transaction — \[Transfer- successful\] | `event.transfer.success` | | Outgoing Transaction — \[Transfer- reversed\] | `event.transfer.reversed` | | Outgoing Transaction — \[Transfer- failed\] | `event.transfer.failed` | **NOTE:** The creation of an expiry account, also known as a disposable account, during the checkout process does **NOT** trigger a webhook event. These disposable accounts have a short-term lifespan, designed to expire upon reaching their predetermined time limit. Thereby, webhook events are not sent when these accouts are created. However this applies only to accounts created during the checkout process. **Provide Webhook URL** To get webhook events and actions notifications, you are required to provide a webhook URL which these notifications will be sent. Follow the steps below to setup a webhook on your Pooler account: 1. Log in to your Pooler account and click to the profile icon at the top right of the dashboard. 2. Select **Profile & Account** and navigate to **Webhook URL** field on the **Developers section.** 3\. Enter your webhook URL and click on the **Submit** button. 🚫 **IMPORTANT:** _We recommend that you use webhook to provide value to your customers._ you should acknowledge the event before executing the long-running tasks. Long-running tasks will lead to a request timeout and an automatic error response from your server without a `200 OK` response. **Verify the Message & Prevent Replay Attacks** A webhook URL is an endpoint on the client's API. This endpoint is publicly available and because of this, it can be called from any application. As a webhooks receiver, you want to verify that requests hitting your endpoint are coming from the right source. ### Transfer Webhook In addition to the [Transfer Status Query](https://docs.poolerapp.com/#31a2ab13-6e0b-45a0-909f-198bb7aa74da) endpoint, we **highly recommend** that you verify the status to every transfer processed using the webhook notifications sent to your webhook URL. These notifications include details of the transfer status and its corresponding value, which will provide you with adequate information on the status of your transfer. On Pooler, there are three key transfer statuses that are returned for each transfer transaction: 1. Completed 2. Reversed 3. Failed For a comprehensive understanding of these statuses and their associated values, the section below contains sample webhooks for each transfer status and detailed description to ensure you have a good understanding of each transfer webhook. #### **Successful transfer** For each successfully processed transfer, the table below contains actions and their response. | Status | Value | Description | | | --- | --- | --- | --- | | `completed` | `true` | The transfer has been successfully processed. | | | `failed` | `false` | The transaction is successfully processed | | | `is_reversed` | `false` | The transfer was not reversed, because it was completed. | | Here is an example of a successful transfer webhook notification: ``` json { "event": "event.transfer.success", "data": { "id": 23, "merchant_id": 41, "amount": "225.00", "reference": "PLRTRF_14006021696337464189", "completed": true, "in_transit": false, "failed": false, "from_mercahnt_number": "5586037126", "from_merchant_name": "Losales", "target_number": "2011117825", "target_name": "OYEBANJI OLAYEMI", "target_bank_code": "000004", "createdAt": "2023-10-03T12:51:04.000Z", "updatedAt": "2023-10-03T12:51:07.266Z", "version": 1, "gateway": { "id": 87, "merchant_id": 41, "payout_id": 23, "fee_amount": "25", "account_no": "5586037126", "account_type": null, "is_reversed": false, "transaction_type": "transfer", "reference": "PLRTRF_14006021696337464189", "session_id": "3511414131100014111696337464414", "amount": "250.00", "currency": "NGN", "narration": "Losales/tar/OYEBANJI OLAYEMI", "pending": false, "completed": true, "is_virtual_account": 0, "sender_details": { "bvn": "22222222222", "name": "Losales", "email": "[email protected]", "bank_code": "090380", "bank_name": "Kredi Money Microfinance Bank", "mobile_number": "2348907652341", "account_number": "5586037126" }, "reciever_details": { "bvn": null, "name": "OYEBANJI OLAYEMI", "bank_code": "000004", "account_number": "2011117825" }, "settled_amount": "225.00", "reversal_reference": null, "settlement_account_id": 41, "created_at": "2023-10-03T12:51:04.000Z", "modified_at": "2023-10-03T12:51:07.264Z" } } } ``` #### **Reversed Transfer** Webhook notifications are also sent for transfers that have been reversed due to failure to complete or process. The table below contains the status and value returned for a reversed transfer. | Status | Value | Description | | --- | --- | --- | | `completed` | `false` | The transfer was not successful, either failed or has been reversed. Check `is_reversed` and `failed` status to confirm. | | `failed` | `true` | The transfer was unsuccessful and could not be processed. Check `is_reversed` status if transfer was been reversed. | | `is_reversed` | `true` | The transfer was not successful, and the funds has been reversed to the sender's account. | Here is a sample of reversed transfer webhook notification: ``` json { "event": "event.transfer.reversed", "data": { "id": 28, "merchant_id": 41, "amount": "500.00", "reference": "PLRTRF_16085041696566206081", "completed": false, "in_transit": false, "failed": true, "from_mercahnt_number": "5586037126", "from_merchant_name": "Losales", "target_number": "1234567890", "target_name": "WOODCORE POOLER SETTLEMENT CLIENT", "target_bank_code": "999998", "is_payout": false, "createdAt": "2023-10-06T04:23:26.000Z", "updatedAt": "2023-10-06T04:23:27.743Z", "version": 1, "gateway": { "id": 95, "merchant_id": 41, "payout_id": 28, "fee_amount": "25", "account_no": "5586037126", "account_type": null, "is_reversed": true, "transaction_type": "transfer", "reference": "PLRTRF_16085041696566206081", "session_id": "8141011242711401131696566206337", "amount": "525.00", "currency": "NGN", "narration": "Losales/tar/WOODCORE POOLER SETTLEMENT CLIENT", "pending": false, "completed": false, "is_virtual_account": 0, "sender_details": { "bvn": "22222222222", "name": "Losales", "email": "[email protected]", "bank_code": "090380", "bank_name": "Kredi Money Microfinance Bank", "mobile_number": "2348907652341", "account_number": "5586037126" }, "reciever_details": { "bvn": null, "name": "WOODCORE POOLER SETTLEMENT CLIENT", "bank_code": "999998", "account_number": "1234567890" }, "settled_amount": "500.00", "reversal_reference": "9A4D429D5E71", "settlement_account_id": 41, "is_payout": false, "created_at": "2023-10-06T04:23:26.000Z", "modified_at": "2023-10-06T04:23:27.74 ``` #### **Failed Transfer** In the event of a transfer request failure, webhook notifications are sent to your webhook URL. | Status | Value | Description | | --- | --- | --- | | `completed` | `false` | The transfer was not successful, either failed or has been reversed. Check `is_reversed` and `failed` status to confirm. | | `failed` | `true` | The transfer was unsuccessful and could not be processed. Check `is_reversed` status if transfer was reversed. | | `is_reversed` | `false` | Funds reversal did not take place. | Here is a sample of failed transfer webhook notification: ``` json { "event": "event.transfer.failed", "data": { "id": 209, "merchant_id": 12, "amount": "300.00", "reference": "PLRT_1715673", "completed": false, "in_transit": false, "failed": true, "from_mercahnt_number": "3122052555", "from_merchant_name": "IEP analytics", "target_number": "1011000200", "target_name": "POOLER MINI UPDATED", "target_bank_code": "090325", "createdAt": "2023-10-06T02:39:09.000Z", "updatedAt": "2023-10-06T02:40:47.599Z", "version": 1, "gateway": { "id": 481, "merchant_id": 12, "payout_id": 209, "fee_amount": "50", "account_no": "3122052555", "account_type": null, "is_reversed": false, "transaction_type": "transfer", "reference": "PLRT_1715673", "session_id": "157441351108144131696559949154", "amount": "350.00", "currency": "NGN", "narration": "PAYOUT FROM/IEP TO POOLER MINI UPDATED", "pending": false, "completed": false, "is_virtual_account": 0, "sender_details": { "bvn": "22222222222", "name": "IEP analytics", "email": "[email protected]", "bank_code": "090380", "bank_name": "Kredi Money Microfinance Bank", "mobile_number": "08207608950899", "account_number": "3122052555" }, "reciever_details": { "bvn": null, "name": "POOLER MINI UPDATED", "bank_code": "090325", "account_number": "1011000200" }, "settled_amount": "300.00", "reversal_reference": null, "settlement_account_id": 12, "created_at": "2023-10-06T02:39:09.000Z", "modified_at": "2023-10-06T02:40:47.589Z" } } } ``` ### Intra-transfer Webhook Similar to transfers, webhook events are sent when a transfer is made from one wallet to another wallet under the same merchant. This process is known as "[Intra-transfer](https://docs.poolerapp.com/#ca872ede-3b9f-40c3-8a3d-f42b1f9f8655)" When an intra-transfer is performed, a webhook event is sent to your webhook URL, containing details of the transfer. **Note**: You cannot perform fund transfers from a wallet to an external bank or a wallet created by another merchant on Pooler. See the [Pooler Wallet](https://docs.poolerapp.com/#0446c510-e38e-49b3-8d4b-65cf37216144) section for more information. Here is a sample of an intra-transfer webhook: ``` json { "event": "event.intra.transfer", "data": { "id": 215, "completed": true, "merchant_id": 209, "reference": "GGHTKLJHG", "amount": 5000, "session_id": "GGHTKLJHG", "bank_name": "KREDI MONEY MFB", "target_account_number": "5564559659", "target_account_name": "Anita Achu/Cashier two", "narration": "Hey Buying", "createdAt": "2024-01-24T13:48:12.024Z", "updatedAt": "2024-01-24T13:48:12.024Z", "gateway": { "id": 215, "merchant_id": 209, "fee_amount": 0, "account_no": "5512966493", "is_reversed": false, "transaction_type": "intra-transfer", "reference": "GGHTKLJHG", "session_id": "GGHTKLJHG", "amount": 5000, "currency": "NGN", "narration": "Hey Buying", "completed": true, "wallet_account": true, "sender_details": { "name": "Anita Achu/Cashier two", "account_number": "5564559659", "bvn": "22222222222", "bank_code": "KREDI MONEY MFB" }, "reciever_details": { "name": "Anita Achu/Cashier One", "account_number": "5512966493", "bvn": "22222222222", "bank_code": "KREDI MONEY MFB" }, "settled_amount": 5000, "settlement_account_id": 132, "modified_at": "2024-01-24T13:48:12.475Z", "updatedAt": "2024-01-24T13:48:12.475Z" } } } ``` ### **Signature Validation** Events sent from Pooler come with the `x-swim-token`. The value of this header is a `HMAC SHA256`signature of the event payload signed using your secret key. Verifying the header signature should be done before processing the event: **JavaScript Sample** ``` javascript const signature = crypto // api_key derived for Pooler Dashboard .createHmac("sha256", api_key) .update(JSON.stringify(req.body)) .digest("hex"); if (signature == req.headers["x-swim-token"]) { // Body is signed and valid. Goodluck } ``` **Java Sample** ``` java package hmacexample; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import org.json.JSONException; import org.json.JSONObject; public class HMacExample { public static void main(String[] args) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, JSONException { //first you verify that this request came from pooler String key = "YOUR_API_KEY"; //replace with your pooler x-key String rawJson = "{}"; JSONObject body = new JSONObject(rawJson); String result = ""; String HMAC_SHA256 = "HmacSHA256"; String xpoolerSignature = ""; //put in the request's header value for x-swim-token byte [] byteKey = key.getBytes("UTF-8"); SecretKeySpec keySpec = new SecretKeySpec(byteKey, HMAC_SHA256); Mac sha256_HMAC = Mac.getInstance(HMAC_SHA256); sha256_HMAC.init(keySpec); byte [] mac_data = sha256_HMAC. doFinal(body.toString().getBytes("UTF-8")); result = DatatypeConverter.printHexBinary(mac_data); if(result.toLowerCase().equals(xpoolerSignature)) { // you can trust the event, it came from pooler // respond with the http 200 response immediately before attempting to process the response }else{ // this isn't from Pooler, ignore it } } } ``` **C# Sample** ``` csharp using System; using System.Security.Cryptography; using System.Text; using Newtonsoft.Json.Linq; namespace HMacExample { class Program { static void Main(string[] args) { String key = "YOUR_API_KEY"; //replace with your pooler secret_key String jsonInput = "{}"; //the json input String inputString = Convert.ToString(new JValue(jsonInput)); String result = ""; byte[] secretkeyBytes = Encoding.UTF8.GetBytes(key); byte[] inputBytes = Encoding.UTF8.GetBytes(inputString); using (var hmac = new HMACSHA256(secretkeyBytes)) { byte[] hashValue = hmac.ComputeHash(inputBytes); result = BitConverter.ToString(hashValue).Replace("-", string.Empty);; } Console.WriteLine(result); String signature = ""; //put in the request's header value for x-swim-token if(result.ToLower().Equals(signature)) { // you can trust the event, it came from pooler // respond with the http 200 response immediately before attempting to process the response } else { // this isn't from pooler, ignore it } } } } ``` ``` python import hmac import hashlib pooler_signature = request.headers.get("x-swim-token") key = secret_key.encode("utf-8") mes = json.dumps(payload, separators=(',', ':')).encode("utf-8") encoded_payload = hmac.new(key, mes, hashlib.sha256).hexdigest() if encoded_payload == pooler_signature: return True else: return False ``` ### **Webhook Retry Mechanism** Where a webhook event is not processed and fails to send data to your webhook URL, Pooler provides a webhook retry mechanism that automatically retries failed events after a 10 minutes interval. **How does it work?** When a transaction request or account creation is processed, a webhook event is sent to the provided webhook URL. If acknowledged, a `200` status code response is returned. However, where the webhook event fails to process, i.e., does not return a `200` status code for the initial webhook event, the webhook retry mechanism will retry the webhook **every 10 minutes for a limited number of 20 times**. If the webhook is successful at any point during the retry, the webhook retry stops. This will enable you to prevent potential failovers and ensure that all events are accurately logged. If you encounter any issues or have questions about the webhook re feature, kindly contact our [support team](https://join.slack.com/t/woodcorehq/shared_invite/zt-1qcmtll1e-oPWNw3nDIlvNpOUgNI~GYQ) for assistance. # Collection Collection refers to fund transfer from an external bank account to the Pooler virtual accounts. For example a fund transfer from customer's **Access Bank** to **Anita Bakery Services** (pooler virtual account). Through collections your pooler accounts both virtual and merchant account are funded. The funds received from collection are automatically settled on the merchant account. ### Demo Bank Please use the Pooler [Demo Bank](https://demobank.poolerapp.com) simulator to process collections when integrating. 🚫 IMPORTANT: The minimum deposit amount for collection is N200. This is set to cover the associated collection charge. Therefore, any collection made with an amount lower than the deposit amount will fail as it falls below the minimum threshold. It is important to ensure that the deposit amount meets or exceeds the minimum required amount to avoid transaction failures. ### **Mismatch or Incorrect Collection Amount** When sending money to an account generated during checkout or to a disposable account that has an amount set on it, the expectation is that the customer sends the exact amount for that checkout or disposable account. In the event where an incorrect amount is sent to the checkout or disposable account, you will get a webhook event with appropriate information that informs you that the customer sent the wrong amount. **Webhook** Webhook events are sent for every collection received on your merchant account. This event contain details of the collection received to enable you verify payment. However, getting an `event.collection` event is not a sufficient indication that collection was successfully settled into your account. Ensure you verify that the `completed` parameter on the webhook payload is set to `true` before proceeding to provide value. The `event.collection` webhook also has includes an `amount_mismatch_data` field. This field contains information incases where an incorrect amount is received. If the amount sent to your account does not match the expected sum or there is a discrepancy in the amount, an `amount_mismatch` field will be set to `true`. The table below shows `amount_mismatch_data` field: | **Key** | **Value** | **Description** | | --- | --- | --- | | **`amount_mismatch`** | `boolean[true]` | An incorrect amount was received. | | `amount_sent` | `string[amount]` | The value of the incorrect amount sent into the account | | `amount_on_account` | `string[amount]` | The value of the expected amount. | | `over` | `boolean` | If `true` it means the amount was above and if `false` means the amount was below the expected amount. | Here is a sample of an **incorrect collection** **amount** webhook. ``` json { "event": "event.collection", "data": { "version": 0, "id": 494, "completed": true, "merchant_id": 1, "account_id": 5, "reference": "PLR_1412786", "amount": "220.00", "session_id": "090529231117194540297591535889", "bank_name": "KREDI MICROFINANCE BANK", "target_account_number": "1234567890", "target_account_name": "WOODCORE/OPEOLUWA KOLAPO", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 220 to KREDI MONEY MFB 1234567890", "payment_link_id": null, "payment_link_info_id": null, "updatedAt": "2023-11-17T19:46:53.523Z", "createdAt": "2023-11-17T19:46:53.523Z", "gateway": { "is_payout": false, "id": 805, "merchant_id": 1, "collection_id": 494, "fee_amount": "100.00", "account_no": "1234567890", "is_reversed": false, "transaction_type": "collection", "reference": "PLR_1412786", "session_id": "090529231117194540297591535889", "amount": "220.00", "currency": "NGN", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 220 to KREDI MONEY MFB 5581340391", "completed": true, "pending": false, "is_virtual_account": true, "sender_details": { "name": "ACCESS BANK", "account_number": "0987654321", "bvn": "null", "bank_code": "000014", "bank_name": null }, "reciever_details": { "name": "WOODCORE/OPEOLUWA KOLAPO", "account_number": "5512345678", "bank_code": "90898" }, "settled_amount": "120.00", "settlement_account_id": 1, "payment_link_id": null, "payment_link_info_id": null, "remark": "Wrong Amount Sent. Amount Set On Disposable Account Is 1000.00, While The Amount Deposited Is 220.00", "amount_mismatch": true, "modified_at": "2023-11-17T19:46:53.531Z", "created_at": "2023-11-17T19:46:53.531Z", "amount_mismatch_data": { "amount_sent": "220.00", "amount_on_account": "1000.00", "over": false } }, "payment_link_data": null, "checkout_payer_info": null } } ``` From the webhook above, whenever the `amount_mismatch` field is set to `true` this indicates that your customer has sent an amount that does not match the expected collection amount. You have the option to initiate a refund using our [Transfer endpoints](https://docs.poolerapp.com/#b46e9b72-e6b6-4c07-a423-82080b5d9260), ensuring a swift resolution by refunding the amount back to the customer. When a correct amount is received, you'll receive the following webhook response. See sample of a **correct collection** amount webhook below: ``` json { "event": "event.collection", "data": { "version": 0, "id": 495, "completed": true, "merchant_id": 1, "account_id": 5, "reference": "PLR_1800946", "amount": "1000.00", "session_id": "090529231117195923625421209723", "bank_name": "KREDI MICROFINANCE BANK", "target_account_number": "1234567890", "target_account_name": "WOODCORE/OPEOLUWA KOLAPO", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 1000 to KREDI MONEY MFB 1234567890", "payment_link_id": null, "payment_link_info_id": null, "updatedAt": "2023-11-17T20:00:33.491Z", "createdAt": "2023-11-17T20:00:33.491Z", "gateway": { "is_payout": false, "id": 806, "merchant_id": 1, "collection_id": 495, "fee_amount": "100.00", "account_no": "1234567890", "is_reversed": false, "transaction_type": "collection", "reference": "PLR_1800946", "session_id": "090529231117195923625421209723", "amount": "1000.00", "currency": "NGN", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 1000 to KREDI MONEY MFB 5581340391", "completed": true, "pending": false, "is_virtual_account": true, "sender_details": { "name": "ACCESS BANK", "account_number": "0987654321", "bvn": "null", "bank_code": "000014", "bank_name": null }, "reciever_details": { "name": "WOODCORE/OPEOLUWA KOLAPO", "account_number": "1234567890", "bank_code": "90898" }, "settled_amount": "900.00", "settlement_account_id": 1, "payment_link_id": null, "payment_link_info_id": null, "remark": null, "amount_mismatch": false, "modified_at": "2023-11-17T20:00:33.495Z", "created_at": "2023-11-17T20:00:33.495Z" }, "payment_link_data": null, "checkout_payer_info": null } } ``` ### **Initial Inward Credit Webhook** When payment is made into your account, we promptly initiate the settlement process on our end. This triggers a pending collection event which is sent to your webhook URL, known as **initial inward credit event**, which indicates that the collection has been acknowledged on our end and is being processed to be settled in your Pooler account. ``` json { "event": "event.collection.pending", "data": { "merchant_id": 1, "fee_amount": "100.00", "account_no": "5582012744", "is_reversed": false, "transaction_type": "collection", "session_id": "090529231118130406138931096794", "amount": "300.00", "settled_amount": "200.00", "currency": "NGN", "sender_details": { "account_no": "5876543210", "account_name": "ACCESS BANK", "bank_name": "000014" }, "reciever_details": { "account_no": "5512345678", "account_name": "WOODCORE/OPEOLUWA KOLAPO", "bank_name": "KREDI MFB" }, "settlement_account_id": 1, "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 300 to KREDI MONEY MFB 5582012744", "completed": false, "pending": true, "payment_link_data": null, "checkout_payer_info": null } } ``` 🚫 **IMPORTANT:** The `event.collection.pending` webhook does not mean that the money has been settled into your account. It serves as a notification for collection awaiting settlement. We **strongly advise** that you wait for the for `event.collection` webhook before proceeding with any further actions. The `event.collection.pending` webhook has an `amount_mismatch_data` field. This field contains information to enable you to verify if the amount sent by the customer is the right amount. Where the amount sent by your customer does not match the expected amount, the `amount_mismatch` field will be set to `true`, and there will be an `amount_mismatch_data` object in the payload; this indicates that the incorrect amount, either exceeding or below the expected amount, was received**.** Once a collection has been received and settled into your account, an `event.collection` will be sent to your webhook URL. **ONLY** use this webhook event to verify that payment has been received and settled into your account before you proceed to provide value to your customers. _The initial inward credit feature is available on demand. If you wish to receive initial inward credit webhook events, reach out to our developers via_ [Slack](https://woodcorehq.slack.com/ssb/redirect) _for a swift response to your request._ # Pagination _For the most part, if the API action is plural, you can page it via a query string parameter. The default number of items to be returned is 10._ | Query String Parameter | Required | Description | | --- | --- | --- | | page | optional | Page number of the result set (default: 0) | | perPage | optional | Limit the number of results per page. (default: 10) | # API Response Code These response codes provide detailed description of issues you may encounter while using the Pooler API service. This includes issues such as incorrect parameters, invalid API keys, and actions that disrupt the regular function of the system such as invalid or already existing fields and so on. The response listed below covers Pooler V1: | **Response code** | **Description** | | --- | --- | | 200 `SUCCESS` | The request was acccpted and processed. | | 202 `ACCEPTED` | The request has been accepted and is being processed. | | 400 `BAD_REQUEST` | The required parameter is invalid or already exists on the system. | | 401 `UNAUTHORIZED` | The caller is not authorized to make use of the service. Verify your API key. | | 422 `UNPROCESSABLE ENTITY` | Invalid request data. This can include incorrect keys or JSON body. Review the request data and ensure that it meets the expected format, field, and validation rules. | | 404 `NOT FOUND` | The page was not found. This may be returned if the URL or endpoint does not exist | | 500 `INTERNAL SERVER ERROR` | There was an error while processing your request on the server. |
DuckDuckGo
Pooler's Suite. 🚀
Pooler is a modern and multi-purpose Banking as a Service infrastructure built to allow businesses to smoothly collect payment from their customers in multiple ways using a virtual account number. The easiest way to use the Pooler API is by clicking the **Run in Postman** button above. [Postm ](https://www.getpostman.com/) is a free tool that helps developers run and debug API requests. Every endpoint documented here is readily available by running our Postman collection. ## Support Pooler engineers are always available to answer your questions. The quickest way to get help is by posting your question on the [Slack channel](https://join.slack.com/t/woodcorehq/shared_invite/zt-1qcmtll1e-oPWNw3nDIlvNpOUgNI~GYQ) with the tag **@support**. It is guaranteed that you will receive a response within 5-20 minutes max! ## Endpoints The API is accessed by making HTTP requests to the pooler endpoint URL. Every (methods, parameters, etc.) is fixed to a version number, and every request must contain one. We have provided a single base URL for both **Test** and **Live** environment. You can switch from the test environment to the live environment on your dashboard whenever needed, provided you have completed all compliance requirements. **The stable HTTP endpoint for the latest version is**: | **Base URL** | **Environment** | | --- | --- | | `https://api.poolerapp.com/api/v1` | Live/Test Environment | It's **important** to note that any transactions conducted in the live environment are considered live transactions, meaning they have actual financial implications. Take caution when performing actions in the live environment to ensure accuracy and validity. # Onboarding Upon registration, an email One-Time-Password (OTP) will be sent to the email address you provided during registration. Enter the OTP to sign into your Pooler account. Once you are signed in, subsequent access to your account will only require your email and password, without any additional OTP entry. ## **Live vs Test environment** Your first interaction on Pooler is the Pooler test environment. This is the default mode created for practicing and testing out Pooler’s features. In this environment, you can create test virtual accounts, process transfers, and explore other Pooler services to get acquainted with the system and more essentially upload your Know Your Customer (KYC) information for review. In addition, test API Keys are provided specifically for integrating with test environments. These environments define the limits to what actions you can take within your account and how your transactions are handled on Pooler. For instance, in the test mode, you can not conduct real transactions that have actual financial implication. Once your KYC details are approved, your account will promoted to the Live environment. Here, a new set of API keys (a secret key and a public key) will be generated for you. These keys enable you to conduct live transactions and interact with Pooler's APIs for a real transactions that have actual financial implication. ## **Demo bank** We have provided a [Demo Bank](https://demobank.poolerapp.com/) simulator to enable you to fund your account during test integrations. The demo bank serves as an external bank to enable you to practice how collection or inflow payment works. 🚫 **IMPORTANT**: The minimum deposit amount for collection is N200. This is set to cover the associated collection charge. Therefore, any collection made with an amount lower than the deposit amount will fail as it falls below the minimum threshold. It is important to ensure that the deposit amount meets or exceeds the minimum required amount to avoid transaction failures. # Security This section will guide you through accessing your Pooler account, and the available security operations. Here you will learn how authentication, and user verification, work on Pooler. ## **Authorization: API Keys** When you sign up, Pooler creates API keys for you to use when making and verifying requests. You can find these keys on your dashboard. There are two types of API keys on Pooler: - **API Key**: This key is for authenticating your API calls using the OAuth 2.0 authentication algorithm. You are required to include a secret key in the Authorization header of each API request. In this format:`Authorization: pk_test_****` - **Public Key:** The public key is specifically designed to integrate the Pooler Inline Javascript to access [Pooler Checkout.](https://docs.poolerapp.com/#f6ac8366-7c0f-4112-878b-ca860b05408c) It is important to note that these public keys can not be used to create accounts or transactions via APIs. They are only for integrating with the frontend. **To get your API keys:** 1. On your Dashboard, navigate to UTILITY & SETTINGS > Developers. 2. Alternatively, click on the Profile icon > Profile & Account on your Dashboard. The Developers section is located at the bottom of the page. If your account has 2FA enabled, you will need to enter the Time-based One-Time Password (TOTP) displayed from your authenticator app to view the key. 🚧 **WARNING**: Ensure to safeguard your API keys and avoid any disclosure or exposing it in any way. ## Two-Factor Guide You have the option to enable two-factor authentication on your account as a additional layer of security. This system requires you to sign in and verify your identity using a third-party authenticator app such as [Google Authenticator](https://googleauthenticator.net/), [Microsoft Authenticator](https://support.microsoft.com/en-us/account-billing/download-and-install-the-microsoft-authenticator-app-351498fc-850a-45da-b7b6-27e523b8702a), or any other authenticator application of your choice. It is important to have either of these apps installed on your mobile device. With 2FA enabled, subsequent sign in to your Pooler account, will require the use of an OTP from an authenticator app. This layer of security extends to any attempt to view your secret keys, which will also require the use of an OTP from the authenticator app. To enable 2FA authentication, first sign in with your email OTP. Next, on your dashboard, navigate to your Profile icon > Profile & account. At the bottom of the page, you'll find the option to "Enable two-factor authentication.” For more information, see the [Multi-Factor Guide](https://docs.poolerapp.com/#multi-factor-guide) for more information. #### **Setting up the Authenticator App using the Scan feature** You can setup your Authenticator app by scanning the QR displayed on the Pooler sign-in page. Follow the steps below to set up your app: 1. Ensure you have your [Google](https://googleauthenticator.net/), [Microsoft](https://support.microsoft.com/en-us/account-billing/download-and-install-the-microsoft-authenticator-app-351498fc-850a-45da-b7b6-27e523b8702a), [Authy](https://authy.com/) or any other authenticator app installed on your mobile device. 2. Click on the + icon and select the “Scan a QR code” option 3. Scan the QR code on your [Pooler 2-step verification sign-in page](https://app.poolerapp.com/verify_otp?action=complete2fa), using your mobile device. On completion, a 6-digits code will be displayed on your authenticator app. Enter the code in the required fields on your Pooler verifiation page. **Note:** The code expires after 30seconds. #### Setting up Authenticator App using Secret Key Alternatively to the "QR code scan" feature for setting up authenticator app, you can setup your [Google](https://googleauthenticator.net/), [Microsoft](https://support.microsoft.com/en-us/account-billing/download-and-install-the-microsoft-authenticator-app-351498fc-850a-45da-b7b6-27e523b8702a), [Authy](https://authy.com/), or any other authenticator app to generate One-Time Passwords (OTPs) using a set of unique 16-character alphanumeric secret key. The Secret Key is available on the UI of your [Pooler 2-step verification page](https://app.poolerapp.com/verify_otp?action=complete2fa). To initiate this setup, you can manually copy and input the provided secret key into your authenticator app. This will enable your app to generate the required OTPs for your sign-in process. The steps below will guide you through this process: 1. Ensure you have your Google, Microsoft, or Authy authenticator app installed on your device. 2. Next, on your Pooler 2-step verification sign-in page, we have provided a set of 16-character alphanumeric secret keys below the QR code. 3\. Copy the Secret Key and navigate to your authenticator app. 4\. Click on the **+** icon on your authenticator app and select the “Setup key” option. 5\. In the Account field, enter the email address linked to your Pooler account. 6\. Enter the Secret Key in the key field. You have the option to configure **time-based** OTP, which means, your secret key will change in sync with time. In this mode, a unique 6-digit code regenerates every 30 seconds. Alternatively, you can opt for **counter-based** OTP, which is not time-dependent. In this mode, the 6-digit code remains valid until refreshed by using the refresh icon. Upon successfully adding the Account and Secret Key, your authenticator app will promptly display the generated OTP. Copy this OTP and enter it into your Pooler verification page. ## **IP Whitelisting** IP whitelisting is a security measure that permits only to a specified list of IP addresses to make requests on your account. This ensures that only authorized users or devices with approved IP addresses can use your secret key for authorization. On Pooler, the IP whitelisting feature is available to further enhance the security of your account, preventing unauthorized access to your data. **How does it work?** When you make an API request, your secret key (available on your dashboard) authorizes this request. IP whitelisting adds extra security by allowing only the IP addresses you havr provided to make requests with your merchant secret key. When you whitelist an IP address, for every API request made using your secret key, we will verify the IP address of the user. If the IP address matches the whitelisted address, the request will be approved. However, if the request comes from an IP address not on the list, we block it. **Note** that this feature is optional and only designed to enable you to further secure your data and transactions on Pooler. We have provided other [security](https://docs.poolerapp.com/#security) measures to safeguard your account. **How to whitelist an IP address** - On your Pooler account dashboard, simply navigate to the profile icon at the top right of your screen and select **"Profile & account”.** - In the **Developer section,** add the IP address you wish to whitelist. You can add as many addresses as you need for added security. **Note:** 1. Whitelisting only blocks requests made using your secret key, which is API request. This means it does not affect access to your Pooler dashboard. 2. Once an IP address is whitelisted, it cannot be duplicated; you can only whitelist an IP address once. 3. There is no limit to the number of IP addresses you can whitelist on your Pooler account. You can add as many addresses as desired. # Webhook In addition to email notification of transactions, webhook is a fast and cost-effective way to manage system-to-system communications. Below are the supported events that trigger a webhook on Pooler. **Available webhook action type and event.** | **Action Type** | **Event** | | --- | --- | | Account Created | `event.create.account` | | Incoming Transaction — \[Collected\] | `event.collection` | | Outgoing Transaction — \[Transfer- successful\] | `event.transfer.success` | | Outgoing Transaction — \[Transfer- reversed\] | `event.transfer.reversed` | | Outgoing Transaction — \[Transfer- failed\] | `event.transfer.failed` | **NOTE:** The creation of an expiry account, also known as a disposable account, during the checkout process does **NOT** trigger a webhook event. These disposable accounts have a short-term lifespan, designed to expire upon reaching their predetermined time limit. Thereby, webhook events are not sent when these accouts are created. However this applies only to accounts created during the checkout process. **Provide Webhook URL** To get webhook events and actions notifications, you are required to provide a webhook URL which these notifications will be sent. Follow the steps below to setup a webhook on your Pooler account: 1. Log in to your Pooler account and click to the profile icon at the top right of the dashboard. 2. Select **Profile & Account** and navigate to **Webhook URL** field on the **Developers section.** 3\. Enter your webhook URL and click on the **Submit** button. 🚫 **IMPORTANT:** _We recommend that you use webhook to provide value to your customers._ you should acknowledge the event before executing the long-running tasks. Long-running tasks will lead to a request timeout and an automatic error response from your server without a `200 OK` response. **Verify the Message & Prevent Replay Attacks** A webhook URL is an endpoint on the client's API. This endpoint is publicly available and because of this, it can be called from any application. As a webhooks receiver, you want to verify that requests hitting your endpoint are coming from the right source. ### Transfer Webhook In addition to the [Transfer Status Query](https://docs.poolerapp.com/#31a2ab13-6e0b-45a0-909f-198bb7aa74da) endpoint, we **highly recommend** that you verify the status to every transfer processed using the webhook notifications sent to your webhook URL. These notifications include details of the transfer status and its corresponding value, which will provide you with adequate information on the status of your transfer. On Pooler, there are three key transfer statuses that are returned for each transfer transaction: 1. Completed 2. Reversed 3. Failed For a comprehensive understanding of these statuses and their associated values, the section below contains sample webhooks for each transfer status and detailed description to ensure you have a good understanding of each transfer webhook. #### **Successful transfer** For each successfully processed transfer, the table below contains actions and their response. | Status | Value | Description | | | --- | --- | --- | --- | | `completed` | `true` | The transfer has been successfully processed. | | | `failed` | `false` | The transaction is successfully processed | | | `is_reversed` | `false` | The transfer was not reversed, because it was completed. | | Here is an example of a successful transfer webhook notification: ``` json { "event": "event.transfer.success", "data": { "id": 23, "merchant_id": 41, "amount": "225.00", "reference": "PLRTRF_14006021696337464189", "completed": true, "in_transit": false, "failed": false, "from_mercahnt_number": "5586037126", "from_merchant_name": "Losales", "target_number": "2011117825", "target_name": "OYEBANJI OLAYEMI", "target_bank_code": "000004", "createdAt": "2023-10-03T12:51:04.000Z", "updatedAt": "2023-10-03T12:51:07.266Z", "version": 1, "gateway": { "id": 87, "merchant_id": 41, "payout_id": 23, "fee_amount": "25", "account_no": "5586037126", "account_type": null, "is_reversed": false, "transaction_type": "transfer", "reference": "PLRTRF_14006021696337464189", "session_id": "3511414131100014111696337464414", "amount": "250.00", "currency": "NGN", "narration": "Losales/tar/OYEBANJI OLAYEMI", "pending": false, "completed": true, "is_virtual_account": 0, "sender_details": { "bvn": "22222222222", "name": "Losales", "email": "[email protected]", "bank_code": "090380", "bank_name": "Kredi Money Microfinance Bank", "mobile_number": "2348907652341", "account_number": "5586037126" }, "reciever_details": { "bvn": null, "name": "OYEBANJI OLAYEMI", "bank_code": "000004", "account_number": "2011117825" }, "settled_amount": "225.00", "reversal_reference": null, "settlement_account_id": 41, "created_at": "2023-10-03T12:51:04.000Z", "modified_at": "2023-10-03T12:51:07.264Z" } } } ``` #### **Reversed Transfer** Webhook notifications are also sent for transfers that have been reversed due to failure to complete or process. The table below contains the status and value returned for a reversed transfer. | Status | Value | Description | | --- | --- | --- | | `completed` | `false` | The transfer was not successful, either failed or has been reversed. Check `is_reversed` and `failed` status to confirm. | | `failed` | `true` | The transfer was unsuccessful and could not be processed. Check `is_reversed` status if transfer was been reversed. | | `is_reversed` | `true` | The transfer was not successful, and the funds has been reversed to the sender's account. | Here is a sample of reversed transfer webhook notification: ``` json { "event": "event.transfer.reversed", "data": { "id": 28, "merchant_id": 41, "amount": "500.00", "reference": "PLRTRF_16085041696566206081", "completed": false, "in_transit": false, "failed": true, "from_mercahnt_number": "5586037126", "from_merchant_name": "Losales", "target_number": "1234567890", "target_name": "WOODCORE POOLER SETTLEMENT CLIENT", "target_bank_code": "999998", "is_payout": false, "createdAt": "2023-10-06T04:23:26.000Z", "updatedAt": "2023-10-06T04:23:27.743Z", "version": 1, "gateway": { "id": 95, "merchant_id": 41, "payout_id": 28, "fee_amount": "25", "account_no": "5586037126", "account_type": null, "is_reversed": true, "transaction_type": "transfer", "reference": "PLRTRF_16085041696566206081", "session_id": "8141011242711401131696566206337", "amount": "525.00", "currency": "NGN", "narration": "Losales/tar/WOODCORE POOLER SETTLEMENT CLIENT", "pending": false, "completed": false, "is_virtual_account": 0, "sender_details": { "bvn": "22222222222", "name": "Losales", "email": "[email protected]", "bank_code": "090380", "bank_name": "Kredi Money Microfinance Bank", "mobile_number": "2348907652341", "account_number": "5586037126" }, "reciever_details": { "bvn": null, "name": "WOODCORE POOLER SETTLEMENT CLIENT", "bank_code": "999998", "account_number": "1234567890" }, "settled_amount": "500.00", "reversal_reference": "9A4D429D5E71", "settlement_account_id": 41, "is_payout": false, "created_at": "2023-10-06T04:23:26.000Z", "modified_at": "2023-10-06T04:23:27.74 ``` #### **Failed Transfer** In the event of a transfer request failure, webhook notifications are sent to your webhook URL. | Status | Value | Description | | --- | --- | --- | | `completed` | `false` | The transfer was not successful, either failed or has been reversed. Check `is_reversed` and `failed` status to confirm. | | `failed` | `true` | The transfer was unsuccessful and could not be processed. Check `is_reversed` status if transfer was reversed. | | `is_reversed` | `false` | Funds reversal did not take place. | Here is a sample of failed transfer webhook notification: ``` json { "event": "event.transfer.failed", "data": { "id": 209, "merchant_id": 12, "amount": "300.00", "reference": "PLRT_1715673", "completed": false, "in_transit": false, "failed": true, "from_mercahnt_number": "3122052555", "from_merchant_name": "IEP analytics", "target_number": "1011000200", "target_name": "POOLER MINI UPDATED", "target_bank_code": "090325", "createdAt": "2023-10-06T02:39:09.000Z", "updatedAt": "2023-10-06T02:40:47.599Z", "version": 1, "gateway": { "id": 481, "merchant_id": 12, "payout_id": 209, "fee_amount": "50", "account_no": "3122052555", "account_type": null, "is_reversed": false, "transaction_type": "transfer", "reference": "PLRT_1715673", "session_id": "157441351108144131696559949154", "amount": "350.00", "currency": "NGN", "narration": "PAYOUT FROM/IEP TO POOLER MINI UPDATED", "pending": false, "completed": false, "is_virtual_account": 0, "sender_details": { "bvn": "22222222222", "name": "IEP analytics", "email": "[email protected]", "bank_code": "090380", "bank_name": "Kredi Money Microfinance Bank", "mobile_number": "08207608950899", "account_number": "3122052555" }, "reciever_details": { "bvn": null, "name": "POOLER MINI UPDATED", "bank_code": "090325", "account_number": "1011000200" }, "settled_amount": "300.00", "reversal_reference": null, "settlement_account_id": 12, "created_at": "2023-10-06T02:39:09.000Z", "modified_at": "2023-10-06T02:40:47.589Z" } } } ``` ### Intra-transfer Webhook Similar to transfers, webhook events are sent when a transfer is made from one wallet to another wallet under the same merchant. This process is known as "[Intra-transfer](https://docs.poolerapp.com/#ca872ede-3b9f-40c3-8a3d-f42b1f9f8655)" When an intra-transfer is performed, a webhook event is sent to your webhook URL, containing details of the transfer. **Note**: You cannot perform fund transfers from a wallet to an external bank or a wallet created by another merchant on Pooler. See the [Pooler Wallet](https://docs.poolerapp.com/#0446c510-e38e-49b3-8d4b-65cf37216144) section for more information. Here is a sample of an intra-transfer webhook: ``` json { "event": "event.intra.transfer", "data": { "id": 215, "completed": true, "merchant_id": 209, "reference": "GGHTKLJHG", "amount": 5000, "session_id": "GGHTKLJHG", "bank_name": "KREDI MONEY MFB", "target_account_number": "5564559659", "target_account_name": "Anita Achu/Cashier two", "narration": "Hey Buying", "createdAt": "2024-01-24T13:48:12.024Z", "updatedAt": "2024-01-24T13:48:12.024Z", "gateway": { "id": 215, "merchant_id": 209, "fee_amount": 0, "account_no": "5512966493", "is_reversed": false, "transaction_type": "intra-transfer", "reference": "GGHTKLJHG", "session_id": "GGHTKLJHG", "amount": 5000, "currency": "NGN", "narration": "Hey Buying", "completed": true, "wallet_account": true, "sender_details": { "name": "Anita Achu/Cashier two", "account_number": "5564559659", "bvn": "22222222222", "bank_code": "KREDI MONEY MFB" }, "reciever_details": { "name": "Anita Achu/Cashier One", "account_number": "5512966493", "bvn": "22222222222", "bank_code": "KREDI MONEY MFB" }, "settled_amount": 5000, "settlement_account_id": 132, "modified_at": "2024-01-24T13:48:12.475Z", "updatedAt": "2024-01-24T13:48:12.475Z" } } } ``` ### **Signature Validation** Events sent from Pooler come with the `x-swim-token`. The value of this header is a `HMAC SHA256`signature of the event payload signed using your secret key. Verifying the header signature should be done before processing the event: **JavaScript Sample** ``` javascript const signature = crypto // api_key derived for Pooler Dashboard .createHmac("sha256", api_key) .update(JSON.stringify(req.body)) .digest("hex"); if (signature == req.headers["x-swim-token"]) { // Body is signed and valid. Goodluck } ``` **Java Sample** ``` java package hmacexample; import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import org.json.JSONException; import org.json.JSONObject; public class HMacExample { public static void main(String[] args) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, JSONException { //first you verify that this request came from pooler String key = "YOUR_API_KEY"; //replace with your pooler x-key String rawJson = "{}"; JSONObject body = new JSONObject(rawJson); String result = ""; String HMAC_SHA256 = "HmacSHA256"; String xpoolerSignature = ""; //put in the request's header value for x-swim-token byte [] byteKey = key.getBytes("UTF-8"); SecretKeySpec keySpec = new SecretKeySpec(byteKey, HMAC_SHA256); Mac sha256_HMAC = Mac.getInstance(HMAC_SHA256); sha256_HMAC.init(keySpec); byte [] mac_data = sha256_HMAC. doFinal(body.toString().getBytes("UTF-8")); result = DatatypeConverter.printHexBinary(mac_data); if(result.toLowerCase().equals(xpoolerSignature)) { // you can trust the event, it came from pooler // respond with the http 200 response immediately before attempting to process the response }else{ // this isn't from Pooler, ignore it } } } ``` **C# Sample** ``` csharp using System; using System.Security.Cryptography; using System.Text; using Newtonsoft.Json.Linq; namespace HMacExample { class Program { static void Main(string[] args) { String key = "YOUR_API_KEY"; //replace with your pooler secret_key String jsonInput = "{}"; //the json input String inputString = Convert.ToString(new JValue(jsonInput)); String result = ""; byte[] secretkeyBytes = Encoding.UTF8.GetBytes(key); byte[] inputBytes = Encoding.UTF8.GetBytes(inputString); using (var hmac = new HMACSHA256(secretkeyBytes)) { byte[] hashValue = hmac.ComputeHash(inputBytes); result = BitConverter.ToString(hashValue).Replace("-", string.Empty);; } Console.WriteLine(result); String signature = ""; //put in the request's header value for x-swim-token if(result.ToLower().Equals(signature)) { // you can trust the event, it came from pooler // respond with the http 200 response immediately before attempting to process the response } else { // this isn't from pooler, ignore it } } } } ``` ``` python import hmac import hashlib pooler_signature = request.headers.get("x-swim-token") key = secret_key.encode("utf-8") mes = json.dumps(payload, separators=(',', ':')).encode("utf-8") encoded_payload = hmac.new(key, mes, hashlib.sha256).hexdigest() if encoded_payload == pooler_signature: return True else: return False ``` ### **Webhook Retry Mechanism** Where a webhook event is not processed and fails to send data to your webhook URL, Pooler provides a webhook retry mechanism that automatically retries failed events after a 10 minutes interval. **How does it work?** When a transaction request or account creation is processed, a webhook event is sent to the provided webhook URL. If acknowledged, a `200` status code response is returned. However, where the webhook event fails to process, i.e., does not return a `200` status code for the initial webhook event, the webhook retry mechanism will retry the webhook **every 10 minutes for a limited number of 20 times**. If the webhook is successful at any point during the retry, the webhook retry stops. This will enable you to prevent potential failovers and ensure that all events are accurately logged. If you encounter any issues or have questions about the webhook re feature, kindly contact our [support team](https://join.slack.com/t/woodcorehq/shared_invite/zt-1qcmtll1e-oPWNw3nDIlvNpOUgNI~GYQ) for assistance. # Collection Collection refers to fund transfer from an external bank account to the Pooler virtual accounts. For example a fund transfer from customer's **Access Bank** to **Anita Bakery Services** (pooler virtual account). Through collections your pooler accounts both virtual and merchant account are funded. The funds received from collection are automatically settled on the merchant account. ### Demo Bank Please use the Pooler [Demo Bank](https://demobank.poolerapp.com) simulator to process collections when integrating. 🚫 IMPORTANT: The minimum deposit amount for collection is N200. This is set to cover the associated collection charge. Therefore, any collection made with an amount lower than the deposit amount will fail as it falls below the minimum threshold. It is important to ensure that the deposit amount meets or exceeds the minimum required amount to avoid transaction failures. ### **Mismatch or Incorrect Collection Amount** When sending money to an account generated during checkout or to a disposable account that has an amount set on it, the expectation is that the customer sends the exact amount for that checkout or disposable account. In the event where an incorrect amount is sent to the checkout or disposable account, you will get a webhook event with appropriate information that informs you that the customer sent the wrong amount. **Webhook** Webhook events are sent for every collection received on your merchant account. This event contain details of the collection received to enable you verify payment. However, getting an `event.collection` event is not a sufficient indication that collection was successfully settled into your account. Ensure you verify that the `completed` parameter on the webhook payload is set to `true` before proceeding to provide value. The `event.collection` webhook also has includes an `amount_mismatch_data` field. This field contains information incases where an incorrect amount is received. If the amount sent to your account does not match the expected sum or there is a discrepancy in the amount, an `amount_mismatch` field will be set to `true`. The table below shows `amount_mismatch_data` field: | **Key** | **Value** | **Description** | | --- | --- | --- | | **`amount_mismatch`** | `boolean[true]` | An incorrect amount was received. | | `amount_sent` | `string[amount]` | The value of the incorrect amount sent into the account | | `amount_on_account` | `string[amount]` | The value of the expected amount. | | `over` | `boolean` | If `true` it means the amount was above and if `false` means the amount was below the expected amount. | Here is a sample of an **incorrect collection** **amount** webhook. ``` json { "event": "event.collection", "data": { "version": 0, "id": 494, "completed": true, "merchant_id": 1, "account_id": 5, "reference": "PLR_1412786", "amount": "220.00", "session_id": "090529231117194540297591535889", "bank_name": "KREDI MICROFINANCE BANK", "target_account_number": "1234567890", "target_account_name": "WOODCORE/OPEOLUWA KOLAPO", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 220 to KREDI MONEY MFB 1234567890", "payment_link_id": null, "payment_link_info_id": null, "updatedAt": "2023-11-17T19:46:53.523Z", "createdAt": "2023-11-17T19:46:53.523Z", "gateway": { "is_payout": false, "id": 805, "merchant_id": 1, "collection_id": 494, "fee_amount": "100.00", "account_no": "1234567890", "is_reversed": false, "transaction_type": "collection", "reference": "PLR_1412786", "session_id": "090529231117194540297591535889", "amount": "220.00", "currency": "NGN", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 220 to KREDI MONEY MFB 5581340391", "completed": true, "pending": false, "is_virtual_account": true, "sender_details": { "name": "ACCESS BANK", "account_number": "0987654321", "bvn": "null", "bank_code": "000014", "bank_name": null }, "reciever_details": { "name": "WOODCORE/OPEOLUWA KOLAPO", "account_number": "5512345678", "bank_code": "90898" }, "settled_amount": "120.00", "settlement_account_id": 1, "payment_link_id": null, "payment_link_info_id": null, "remark": "Wrong Amount Sent. Amount Set On Disposable Account Is 1000.00, While The Amount Deposited Is 220.00", "amount_mismatch": true, "modified_at": "2023-11-17T19:46:53.531Z", "created_at": "2023-11-17T19:46:53.531Z", "amount_mismatch_data": { "amount_sent": "220.00", "amount_on_account": "1000.00", "over": false } }, "payment_link_data": null, "checkout_payer_info": null } } ``` From the webhook above, whenever the `amount_mismatch` field is set to `true` this indicates that your customer has sent an amount that does not match the expected collection amount. You have the option to initiate a refund using our [Transfer endpoints](https://docs.poolerapp.com/#b46e9b72-e6b6-4c07-a423-82080b5d9260), ensuring a swift resolution by refunding the amount back to the customer. When a correct amount is received, you'll receive the following webhook response. See sample of a **correct collection** amount webhook below: ``` json { "event": "event.collection", "data": { "version": 0, "id": 495, "completed": true, "merchant_id": 1, "account_id": 5, "reference": "PLR_1800946", "amount": "1000.00", "session_id": "090529231117195923625421209723", "bank_name": "KREDI MICROFINANCE BANK", "target_account_number": "1234567890", "target_account_name": "WOODCORE/OPEOLUWA KOLAPO", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 1000 to KREDI MONEY MFB 1234567890", "payment_link_id": null, "payment_link_info_id": null, "updatedAt": "2023-11-17T20:00:33.491Z", "createdAt": "2023-11-17T20:00:33.491Z", "gateway": { "is_payout": false, "id": 806, "merchant_id": 1, "collection_id": 495, "fee_amount": "100.00", "account_no": "1234567890", "is_reversed": false, "transaction_type": "collection", "reference": "PLR_1800946", "session_id": "090529231117195923625421209723", "amount": "1000.00", "currency": "NGN", "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 1000 to KREDI MONEY MFB 5581340391", "completed": true, "pending": false, "is_virtual_account": true, "sender_details": { "name": "ACCESS BANK", "account_number": "0987654321", "bvn": "null", "bank_code": "000014", "bank_name": null }, "reciever_details": { "name": "WOODCORE/OPEOLUWA KOLAPO", "account_number": "1234567890", "bank_code": "90898" }, "settled_amount": "900.00", "settlement_account_id": 1, "payment_link_id": null, "payment_link_info_id": null, "remark": null, "amount_mismatch": false, "modified_at": "2023-11-17T20:00:33.495Z", "created_at": "2023-11-17T20:00:33.495Z" }, "payment_link_data": null, "checkout_payer_info": null } } ``` ### **Initial Inward Credit Webhook** When payment is made into your account, we promptly initiate the settlement process on our end. This triggers a pending collection event which is sent to your webhook URL, known as **initial inward credit event**, which indicates that the collection has been acknowledged on our end and is being processed to be settled in your Pooler account. ``` json { "event": "event.collection.pending", "data": { "merchant_id": 1, "fee_amount": "100.00", "account_no": "5582012744", "is_reversed": false, "transaction_type": "collection", "session_id": "090529231118130406138931096794", "amount": "300.00", "settled_amount": "200.00", "currency": "NGN", "sender_details": { "account_no": "5876543210", "account_name": "ACCESS BANK", "bank_name": "000014" }, "reciever_details": { "account_no": "5512345678", "account_name": "WOODCORE/OPEOLUWA KOLAPO", "bank_name": "KREDI MFB" }, "settlement_account_id": 1, "narration": "CR|FRM KOLAPO OPEOLUWA to WOODCOREOPEOLUWA KOLAPOSent 300 to KREDI MONEY MFB 5582012744", "completed": false, "pending": true, "payment_link_data": null, "checkout_payer_info": null } } ``` 🚫 **IMPORTANT:** The `event.collection.pending` webhook does not mean that the money has been settled into your account. It serves as a notification for collection awaiting settlement. We **strongly advise** that you wait for the for `event.collection` webhook before proceeding with any further actions. The `event.collection.pending` webhook has an `amount_mismatch_data` field. This field contains information to enable you to verify if the amount sent by the customer is the right amount. Where the amount sent by your customer does not match the expected amount, the `amount_mismatch` field will be set to `true`, and there will be an `amount_mismatch_data` object in the payload; this indicates that the incorrect amount, either exceeding or below the expected amount, was received**.** Once a collection has been received and settled into your account, an `event.collection` will be sent to your webhook URL. **ONLY** use this webhook event to verify that payment has been received and settled into your account before you proceed to provide value to your customers. _The initial inward credit feature is available on demand. If you wish to receive initial inward credit webhook events, reach out to our developers via_ [Slack](https://woodcorehq.slack.com/ssb/redirect) _for a swift response to your request._ # Pagination _For the most part, if the API action is plural, you can page it via a query string parameter. The default number of items to be returned is 10._ | Query String Parameter | Required | Description | | --- | --- | --- | | page | optional | Page number of the result set (default: 0) | | perPage | optional | Limit the number of results per page. (default: 10) | # API Response Code These response codes provide detailed description of issues you may encounter while using the Pooler API service. This includes issues such as incorrect parameters, invalid API keys, and actions that disrupt the regular function of the system such as invalid or already existing fields and so on. The response listed below covers Pooler V1: | **Response code** | **Description** | | --- | --- | | 200 `SUCCESS` | The request was acccpted and processed. | | 202 `ACCEPTED` | The request has been accepted and is being processed. | | 400 `BAD_REQUEST` | The required parameter is invalid or already exists on the system. | | 401 `UNAUTHORIZED` | The caller is not authorized to make use of the service. Verify your API key. | | 422 `UNPROCESSABLE ENTITY` | Invalid request data. This can include incorrect keys or JSON body. Review the request data and ensure that it meets the expected format, field, and validation rules. | | 404 `NOT FOUND` | The page was not found. This may be returned if the URL or endpoint does not exist | | 500 `INTERNAL SERVER ERROR` | There was an error while processing your request on the server. |
General Meta Tags
26- titlePooler's Suite. 🚀
- charsetutf-8
- X-UA-CompatibleIE=edge
- viewportwidth=device-width,initial-scale=1
- top-barfff
Open Graph Meta Tags
5- og:titlePooler's Suite. 🚀
- og:descriptionPooler is a modern and multi-purpose Banking as a Service infrastructure built to allow businesses to smoothly collect payment from their customers in multiple ways using a virtual account number. The easiest way to use the Pooler API is by clicking the **Run in Postman** button above. [Postm ](https://www.getpostman.com/) is a free tool that helps developers run and debug API requests. Every endpoint documented here is readily available by running our Postman collection. ## Support Pooler engineers are always available to answer your questions. The quickest way to get help is by posting your question on the [Slack channel](https://join.slack.com/t/woodcorehq/shared_invite/zt-1qcmtll1e-oPWNw3nDIlvNpOUgNI~GYQ) with the tag **@support**. It is guaranteed that you will receive a response within 5-20 minutes max! ## Endpoints The API is accessed by making HTTP requests to the pooler endpoint URL. Every (methods, parameters, etc.) is fixed to a version number, and every request must ...
- og:site_namePooler's Suite. 🚀
- og:urlhttps://docs.poolerapp.com
- og:imagehttps://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/a68f81c9334b087f7fbcc5fae57e2fc36047febf7e020549735f4aed85e97b39
Twitter Meta Tags
7- twitter:titlePooler's Suite. 🚀
- twitter:descriptionPooler is a modern and multi-purpose Banking as a Service infrastructure built to allow businesses to smoothly collect payment from their customers in multiple ways using a virtual account number. The easiest way to use the Pooler API is by clicking the **Run in Postman** button above. [Postm ](https://www.getpostman.com/) is a free tool that helps developers run and debug API requests. Every endpoint documented here is readily available by running our Postman collection. ## Support Pooler engineers are always available to answer your questions. The quickest way to get help is by posting your question on the [Slack channel](https://join.slack.com/t/woodcorehq/shared_invite/zt-1qcmtll1e-oPWNw3nDIlvNpOUgNI~GYQ) with the tag **@support**. It is guaranteed that you will receive a response within 5-20 minutes max! ## Endpoints The API is accessed by making HTTP requests to the pooler endpoint URL. Every (methods, parameters, etc.) is fixed to a version number, and every request must ...
- twitter:cardsummary
- twitter:domainhttps://docs.poolerapp.com
- twitter:imagehttps://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/a68f81c9334b087f7fbcc5fae57e2fc36047febf7e020549735f4aed85e97b39
Link Tags
8- canonicalhttps://docs.poolerapp.com/
- preconnecthttps://docs.poolerapp.com/
- preconnecthttps://documenter-assets.pstmn.io
- prefetchhttps://docs.poolerapp.com/view/metadata/2s93CRJWt8
- prefetchhttps://docs.poolerapp.com/api/collections/19873942/2s93CRJWt8?environment=19873942-11b788c2-1531-49f6-b5f0-ae337b2df87a&segregateAuth=true&versionTag=latest