# Check Merchant Balance Source: https://docs.hub2.io/api-reference/balance/check-merchant-balance get /balance Returns a summary of a merchant accounts balances (collection, transfer and transfer irt accounts) . # Create a kyb Source: https://docs.hub2.io/api-reference/compliance/create-a-kyb post /compliance/kyb # Create a kyb transaction Source: https://docs.hub2.io/api-reference/compliance/create-a-kyb-transaction post /compliance/transaction # Delete a kyb Source: https://docs.hub2.io/api-reference/compliance/delete-a-kyb delete /compliance/kyb/{name} # Delete a kyb transaction Source: https://docs.hub2.io/api-reference/compliance/delete-a-kyb-transaction delete /compliance/transaction/{reference} # Fetch a kyb list Source: https://docs.hub2.io/api-reference/compliance/fetch-a-kyb-list get /compliance/kyb # Fetch a kyb transactions list Source: https://docs.hub2.io/api-reference/compliance/fetch-a-kyb-transactions-list get /compliance/transaction # Get kyc information Source: https://docs.hub2.io/api-reference/compliance/get-kyc-information get /compliance/kyc # Retrieve a kyb by name Source: https://docs.hub2.io/api-reference/compliance/retrieve-a-kyb-by-name get /compliance/kyb/{name} # Retrieve a kyb transaction by reference Source: https://docs.hub2.io/api-reference/compliance/retrieve-a-kyb-transaction-by-reference get /compliance/transaction/{reference} # Update a kyb Source: https://docs.hub2.io/api-reference/compliance/update-a-kyb put /compliance/kyb/{name} # Get countries Source: https://docs.hub2.io/api-reference/data/get-countries get /data/countries Returns the list of countries where Hub2 is available # Get providers Source: https://docs.hub2.io/api-reference/data/get-providers get /data/providers Returns the list of providers available with Hub2 # Create IRT transfer Source: https://docs.hub2.io/api-reference/irt/create-irt-transfer post /irt/transfer Make an IRT transfer # Retrieve a IRT transfers collection Source: https://docs.hub2.io/api-reference/irt/retrieve-a-irt-transfers-collection get /irt/transfer Return a list of IRT transfers, eventually filtered by criteria. # Execute payment Source: https://docs.hub2.io/api-reference/payment-on-terminal/execute-payment post /terminal/payments # Retrieve a payment Source: https://docs.hub2.io/api-reference/payment-on-terminal/retrieve-a-payment get /terminal/payments/{id} # Attempt a payment on a PaymentIntent object Source: https://docs.hub2.io/api-reference/payments/attempt-a-payment-on-a-paymentintent-object post /payment-intents/{id}/payments This is the endpoint to use whenever you want to attempt a payment on a payment intent. It will create a payment object associated with the intent which will contains all the informations about the payment. Whenever a payment fails or don't have the appropriate amount to match the intent, other payments can be created on the same intent. # Authenticate the current payment Source: https://docs.hub2.io/api-reference/payments/authenticate-the-current-payment post /payment-intents/{id}/authentication Some circuit have authentication restrictions which requires an extra step. This endpoint is here to allow you to make that extra steps. It happens after a payment has been requested and when that payment moved to the "action_required" state. # Create a PaymentIntent object Source: https://docs.hub2.io/api-reference/payments/create-a-paymentintent-object post /payment-intents This endpoint is the first entry point of the PAY-IN circuit. First of all, you must create a payment intent which describes your intention to collect an amount of money in a currency. Later on, you will perform payments associated with this payment intent. Please do save the fields returned by this endpoint, especially the field 'id' and 'token'. That will help you identity the payment intent in our platform whenever you want to retrieve it. # Retrieve a PaymentIntent collection Source: https://docs.hub2.io/api-reference/payments/retrieve-a-paymentintent-collection get /payment-intents This endpoints is here to provide you an efficient way of retrieving multiple payment intents at the same time. Everything is provided in the request's headers to perform a proper pagination on the results. # Retrieve a PaymentIntent object Source: https://docs.hub2.io/api-reference/payments/retrieve-a-paymentintent-object get /payment-intents/{id} This endpoint allows you to fetch an existing payment intent from our database. You must either provide the "id" or the "token" for us to find that payment intent. Retrieving using the "token" is the fastest way and uses a more permissive rate limit (10 requests per 5 seconds). # Retrieve a PaymentIntent status Source: https://docs.hub2.io/api-reference/payments/retrieve-a-paymentintent-status get /payment-intents/{id}/status This endpoint allows you to fetch the status of an existing payment intent from our database. You must either provide the "id" or the "token" for us to find that payment intent. Retrieving using the "token" is the fastest way and uses a more permissive rate limit (10 requests per 5 seconds). # Retrieve a Payments collection Source: https://docs.hub2.io/api-reference/payments/retrieve-a-payments-collection get /payments Return a list of Payments, eventually filtered by criteria. # Retrieve configured URLs Source: https://docs.hub2.io/api-reference/payments/retrieve-configured-urls get /payment-intents/url/{token} This endpoint fetch the merchant's preference and return the redirection URL saved in there. This is mostly used for the Hub2 modal feature. You must provide the payment intent token for that. # Retrieve fees Source: https://docs.hub2.io/api-reference/payments/retrieve-fees get /payment-intents/{id}/payment-fees This endpoint allows you to retrieve the fees associated with a payment intent. Fees are applied per payment and this endpoints will group all the fees in an array. # Retrieve the status payment object Source: https://docs.hub2.io/api-reference/payments/retrieve-the-status-payment-object get /payments/{id}/status # Synchronously attempt a payment on a payment intent Source: https://docs.hub2.io/api-reference/payments/synchronously-attempt-a-payment-on-a-payment-intent post /payment-intents/{id}/payments/sync This is the same endpoint but the payment is handled synchronously, it means it will wait for the provider response before returning the status of the payment intent. This endpoint is not the favored way to integrate our api and is not available for all merchants and for all providers. # Create a delegated payment Source: https://docs.hub2.io/api-reference/processing-only/make-a-delegated-payment post /delegated/payments This endpoint allows you to make a payment using your own provider credentials. # Create a delegated Transfer Source: https://docs.hub2.io/api-reference/processing-only/make-a-delegated-transfer post /delegated/transfers This endpoint allows you to make a transfer (PAY-OUT) using your own provider credentials. # Create a delegated IRT transfer Source: https://docs.hub2.io/api-reference/processing-only/make-a-delegated-transfer-irt post /delegated/transfers/irt Make an IRT transfer using your own provider credentials. # Create a delegated synchronous payment Source: https://docs.hub2.io/api-reference/processing-only/make-a-synchronous-delegated-payment post /delegated/payments/sync This endpoint allows you to make a synchronous payment using your own provider credentials. # Create a Provisioning Source: https://docs.hub2.io/api-reference/provisioning/create-a-provisioning post /provisionings Move funds from merchant's collection account to transfer account # Retrieve a Provisioning from given id Source: https://docs.hub2.io/api-reference/provisioning/retrieve-a-provisioning-from-given-id get /provisionings/{id} # Retrieve a Provisionings collection Source: https://docs.hub2.io/api-reference/provisioning/retrieve-a-provisionings-collection get /provisionings # Retrieve a Receipt Source: https://docs.hub2.io/api-reference/receipt/retrieve-a-receipt get /receipts/{id} Retrieve a sucessful or failed transfer or payment receipt # Retrieve a Receipt as an HTML representation Source: https://docs.hub2.io/api-reference/receipt/retrieve-a-receipt-as-an-html-representation get /receipts/html/{id} Retrieve a sucessful or failed transfer or payment receipt as HTML # Create a new recipient Source: https://docs.hub2.io/api-reference/recipients/create-recipient post /recipient # Delete a recipient by id Source: https://docs.hub2.io/api-reference/recipients/delete-recipient delete /recipient/{id} # Get a recipient by id Source: https://docs.hub2.io/api-reference/recipients/find-recipient get /recipient/{id} # Retrieve a list of recipients according to filters Source: https://docs.hub2.io/api-reference/recipients/list-recipients get /recipient # Create a refund Source: https://docs.hub2.io/api-reference/refunds/create-refund POST https://api.hub2.io/refunds This endpoint allows you to create a refund for a successful transfer. Creates a refund for a previously successful transfer. The refund will be processed asynchronously and you will receive webhook notifications about status changes. ## Request The transfer ID to refund (e.g., `tr_000000000000000000011`) Zendesk ticket ID associated with the refund (e.g., `zd_123456`) ## Response The unique refund ID The current status of the refund. Possible values: `created`, `pending`, `pending_manual`, `successful`, `failed` The original transfer ID that is being refunded The refund amount (same as original transfer) The currency of the refund (e.g., `XOF`, `USD`) The reason for the refund The payment method used for the refund. Possible values: `mobile_money`, `bank_transfer` Whether fallback methods are allowed for this refund Whether a fallback method was used for this refund Additional metadata associated with the refund The Zendesk ticket ID associated with the refund The date and time when the refund was created The date and time when the refund was last updated ```bash Example Request theme={null} curl --location --request POST 'https://api.hub2.io/refunds' \ --header 'ApiKey: [REDACTED]' \ --header 'MerchantId: [REDACTED]' \ --header 'Environment: sandbox' \ --header 'Content-Type: application/json' \ --data-raw '{ "id": "tr_000000000000000000011", "zendeskTicketId": "zd_123456" }' ``` ```typescript Typescript theme={null} import fetch from 'node-fetch'; async function createRefund() { const response = await fetch('https://api.hub2.io/refunds', { method: 'POST', headers: { 'ApiKey': '[REDACTED]', 'MerchantId': '[REDACTED]', 'Environment': 'sandbox', 'Content-Type': 'application/json' }, body: JSON.stringify({ "id": "tr_000000000000000000011", "zendeskTicketId": "zd_123456" }) }); if (response.ok) { const result = await response.json(); console.log(result); } else { console.log(`HTTP Status: ${response.status}`); } } createRefund(); ``` ```python Python theme={null} import json import requests headers = { 'ApiKey': '[REDACTED]', 'MerchantId': '[REDACTED]', 'Environment': 'sandbox', 'Content-Type': 'application/json', } data = { "id": "tr_000000000000000000011", "zendeskTicketId": "zd_123456" } response = requests.post( 'https://api.hub2.io/refunds', headers=headers, data=json.dumps(data) ) if response.status_code == 200: print(response.json()) else: print(f'HTTP Status: {response.status_code}') ``` ```json Response theme={null} { "id": 123, "status": "created", "transactionId": "tr_000000000000000000011", "amount": 2000, "currency": "XOF", "reason": "Customer requested refund", "paymentMethod": "mobile_money", "fallbackAllowed": true, "fallbackUsed": false, "metadata": {}, "zendeskTicketId": "zd_123456", "createdAt": "2023-01-01T12:00:00.000Z", "updatedAt": "2023-01-01T12:00:00.000Z" } ``` # Retrieve a refund Source: https://docs.hub2.io/api-reference/refunds/retrieve-a-refund GET https://api.hub2.io/refunds/{id} This endpoint allows you to retrieve the details of a specific refund. Retrieves the details of a refund using its unique ID. ## Path Parameters The unique refund ID ## Response The unique refund ID The current status of the refund. Possible values: `created`, `pending`, `pending_manual`, `successful`, `failed` The original transfer ID that is being refunded The refund amount (same as original transfer) The currency of the refund (e.g., `XOF`, `USD`) The reason for the refund The payment method used for the refund. Possible values: `mobile_money`, `bank_transfer` Whether fallback methods are allowed for this refund Whether a fallback method was used for this refund Additional metadata associated with the refund The Zendesk ticket ID associated with the refund The date and time when the refund was created The date and time when the refund was last updated ```bash Example Request theme={null} curl --location --request GET 'https://api.hub2.io/refunds/123' \ --header 'ApiKey: [REDACTED]' \ --header 'MerchantId: [REDACTED]' \ --header 'Environment: sandbox' \ --header 'Content-Type: application/json' ``` ```typescript Typescript theme={null} import fetch from 'node-fetch'; async function getRefund() { const response = await fetch('https://api.hub2.io/refunds/123', { method: 'GET', headers: { 'ApiKey': '[REDACTED]', 'MerchantId': '[REDACTED]', 'Environment': 'sandbox', 'Content-Type': 'application/json' } }); if (response.ok) { const refund = await response.json(); console.log(refund); } else { console.log(`HTTP Status: ${response.status}`); } } getRefund(); ``` ```python Python theme={null} import requests headers = { 'ApiKey': '[REDACTED]', 'MerchantId': '[REDACTED]', 'Environment': 'sandbox', 'Content-Type': 'application/json', } response = requests.get( 'https://api.hub2.io/refunds/123', headers=headers ) if response.status_code == 200: print(response.json()) else: print(f'HTTP Status: {response.status_code}') ``` ```json Response theme={null} { "id": 123, "status": "successful", "transactionId": "tr_000000000000000000011", "amount": 2000, "currency": "XOF", "reason": "Customer requested refund", "paymentMethod": "mobile_money", "fallbackAllowed": true, "fallbackUsed": false, "metadata": {}, "zendeskTicketId": "zd_123456", "createdAt": "2023-01-01T12:00:00.000Z", "updatedAt": "2023-01-01T12:30:00.000Z" } ``` # Retrieve refunds collection Source: https://docs.hub2.io/api-reference/refunds/retrieve-refunds-collection GET https://api.hub2.io/refunds This endpoint allows you to retrieve a list of refunds with filtering and pagination options. Retrieves a paginated list of refunds. You can filter the results using various query parameters. ## Query Parameters Filter by refund ID Filter refunds created after this date (ISO 8601 format, e.g., `2023-01-01T00:00:00.000Z`) Filter refunds created before this date (ISO 8601 format, e.g., `2023-01-01T12:00:00.000Z`) Filter by refund status. Possible values: `created`, `pending`, `pending_manual`, `successful`, `failed` Filter by transfer reference (original transfer reference) Page number for pagination Number of results per page (max 100) ## Response Array of refund objects The unique refund ID The current status of the refund The original transfer ID that is being refunded The refund amount The currency of the refund The reason for the refund The payment method used for the refund Whether fallback methods are allowed Whether a fallback method was used Additional metadata associated with the refund The Zendesk ticket ID associated with the refund The date and time when the refund was created The date and time when the refund was last updated Pagination information Current page number Number of results per page Total number of refunds Total number of pages ```bash Example Request theme={null} curl --location --request GET 'https://api.hub2.io/refunds?fromDate=2023-01-01T00:00:00.000&toDate=2023-01-01T12:00:00.000&page=1&perPage=100' \ --header 'ApiKey: [REDACTED]' \ --header 'MerchantId: [REDACTED]' \ --header 'Environment: sandbox' \ --header 'Content-Type: application/json' ``` ```typescript Typescript theme={null} import fetch from 'node-fetch'; async function getRefunds() { const response = await fetch('https://api.hub2.io/refunds?fromDate=2023-01-01T00:00:00.000&toDate=2023-01-01T12:00:00.000&page=1&perPage=100', { method: 'GET', headers: { 'ApiKey': '[REDACTED]', 'MerchantId': '[REDACTED]', 'Environment': 'sandbox', 'Content-Type': 'application/json' } }); if (response.ok) { const refunds = await response.json(); console.log(refunds); } else { console.log(`HTTP Status: ${response.status}`); } } getRefunds(); ``` ```python Python theme={null} import requests headers = { 'ApiKey': '[REDACTED]', 'MerchantId': '[REDACTED]', 'Environment': 'sandbox', 'Content-Type': 'application/json', } response = requests.get( 'https://api.hub2.io/refunds?fromDate=2023-01-01T00:00:00.000&toDate=2023-01-01T12:00:00.000&page=1&perPage=100', headers=headers ) if response.status_code == 200: print(response.json()) else: print(f'HTTP Status: {response.status_code}') ``` ```json Response theme={null} { "data": [ { "id": 123, "status": "successful", "transactionId": "tr_000000000000000000011", "amount": 2000, "currency": "XOF", "reason": "Customer requested refund", "paymentMethod": "mobile_money", "fallbackAllowed": true, "fallbackUsed": false, "metadata": {}, "zendeskTicketId": "zd_123456", "createdAt": "2023-01-01T12:00:00.000Z", "updatedAt": "2023-01-01T12:30:00.000Z" }, { "id": 124, "status": "pending", "transactionId": "tr_000000000000000000012", "amount": 1500, "currency": "XOF", "reason": "Merchant initiated refund", "paymentMethod": "mobile_money", "fallbackAllowed": true, "fallbackUsed": false, "metadata": {}, "zendeskTicketId": "zd_789012", "createdAt": "2023-01-01T11:30:00.000Z", "updatedAt": "2023-01-01T11:30:00.000Z" } ], "pagination": { "page": 1, "perPage": 100, "total": 2, "totalPages": 1 } } ``` # Get a list of sms sent Source: https://docs.hub2.io/api-reference/sms/get-a-list-of-sms-sent get /sms/list Retrieve a list of sms sent between two date. # Retrieve number of sms sent Source: https://docs.hub2.io/api-reference/sms/retrieve-number-of-sms-sent get /sms/count Retrieve number of sms sent between two date # Send Sms Source: https://docs.hub2.io/api-reference/sms/send-sms post /sms Send Sms to different destinations. # Create Transfer Source: https://docs.hub2.io/api-reference/transfers/create-transfer post /transfers This endpoint allows you to make a transfer (PAY-OUT) # Retrieve a Transfer Source: https://docs.hub2.io/api-reference/transfers/retrieve-a-transfer get /transfers/{id} This endpoint allows you to fetch an existing transfer from our database by providing its 'id' # Retrieve a Transfer collection Source: https://docs.hub2.io/api-reference/transfers/retrieve-a-transfer-collection get /transfers Return a list of Transfers, eventually filtered by criteria. # Retrieve a transfer's balance Source: https://docs.hub2.io/api-reference/transfers/retrieve-a-transfers-balance get /transfers/{id}/balance Fetch balance before and after transfer # Retrieve a transfer's status Source: https://docs.hub2.io/api-reference/transfers/retrieve-a-transfers-status get /transfers/{id}/status Retrieve the status for a transfer # Create a webhook Source: https://docs.hub2.io/api-reference/webhooks/create-a-webhook post /webhooks # Get a webhook Source: https://docs.hub2.io/api-reference/webhooks/get-a-webhook get /webhooks/{id} # Get all webhooks Source: https://docs.hub2.io/api-reference/webhooks/get-all-webhooks get /webhooks # Remove a webhook Source: https://docs.hub2.io/api-reference/webhooks/remove-a-webhook delete /webhooks/{id} # Update a webhook Source: https://docs.hub2.io/api-reference/webhooks/update-a-webhook patch /webhooks/{id} # Error management Source: https://docs.hub2.io/documentation/en/error_management ## Error format The error format in HUB2 API is being standardized. Below are the fields in the standardized response along with an example: | Field name | Description | | :----------- | :--------------------------------------------------------------- | | `status` | The HTTP status | | `code` | A business error code internal to HUB2 API (see full list below) | | `message` | A readable description of the error code | | `request_id` | Unique request identifier | Currently, it is necessary to set the header 'x-use-standardized-error' === true to obtain this standardized format. Starting from October the 1st of 2024, this error format will be the only one returned by the HUB2 API. Therefore, merchants needs to update their integration before this deadline. ## Sample : Error 404 ```json theme={null} { "status": 404, "code": "Not Found", "message": "Country not found", "request_id": "req_RRg_xtA55q32PLIWYVLFL" } ``` **Note**: the field `request_id` is a unique request identifier that will allow HUB2 Support team to respond more quickly in case of help requests. ## Error codes ### HTTP status codes HTTP status codes do not indicate application errors. Standard HTTP status codes that can be returned by the HUB2 API : | Status Code | Status Text | Description | | :------------------------- | :-------------------- | :-------------------------------------------------------------------------------------------------------------------------------------- | | `200` | `OK` | The HTTP request was completed as expected. | | `400` | `Bad Request` | The request was unacceptable, often due to a missing required parameter. | | `401` | `Unauthorized` | No valid API key provided. | | `402` | `Request Failed` | The parameters were valid but the request failed. | | `403` | `Forbidden` | The API key doesn’t have permissions to perform the request. | | `404` | `Not Found` | The requested resource doesn’t exist. | | `409` | `Conflict` | The client's request is in direct conflict with another action that is already in progress or has been completed | | `429` | `Too Many Requests` | Excessive requests have been made to the API in a short amount of time. The request wasn't accepted to preserve overall API performance | | `500`, `502`, `503`, `504` | Server-related errors | Something went wrong on HUB2’s end. | ### Application error codes Application error codes that may be returned by the HUB2 API : | Code | Reason | | :-------------------------- | :------------------------------------------------------------------------------------------------------------------ | | `account-already-exists` | An account 'accountType' in mode (live or sandbox) already exists for the merchant merchantId | | `cancellation-already-done` | The transaction id has already been canceled. | | `insufficient-funds` | The account does not have enough funds to transfer amount currency. | | `invalid-currency` | Invalid currency (currency). | | `locked-account` | The account is locked. | | `transaction-not-found` | The transaction transactionId for the account accountId is not found. | | `currency-not-found` | Currency not found (currency). | | `withdrawal-unavailable` | Withdrawals are unavailable on the account accountId. The account may be blocked or does not have sufficient funds. | | `missing-funds-reservation` | Insufficient reserved funds. | | `merchant-not-found` | The merchant is not found. | | `unsupported-command` | Unsupported command. | | `no_auth_required` | The transaction id does not require authentication. | | `transaction_canceled` | The transaction (payment) has been canceled. No payment can be processed. | | `transaction_missing` | The transaction (transfer or payment) is not found. | | `transaction_in_progress` | The transaction (transfer or payment) is already in progress. | | `transaction_done` | The transaction (transfer or payment) has already been completed. | # Glossary Source: https://docs.hub2.io/documentation/en/glossary Definition of useful terms used in HUB2's payment platform ## Collection Account Account used for payments. ## Transfer Account Account used for transfers. ## IRT Transfer Account Account used for IRT. ## IRT (International Remittance Transfers) The cross-border transfer of funds from one person to another. ## Payment A payment (or PAY-IN) is a financial transaction in which money is moved from the user's account to the merchant's collection account. ## Transaction polling A method of periodically retrieving the status of a transaction by regularly querying an API for updates. [Polling vs. Webhooks](https://blog.bytebytego.com/i/141963246/polling-vs-webhooks) ## Balance Difference between total debit transactions (transfers/pay-outs, withdrawals, fees) and total credit transactions (payments collected/pay-ins, deposits). The difference cannot be negative. Consequently, the balance is a credit balance. ## Transfer A transfer (or PAY-OUT) is a financial transaction in which money is moved from the merchant's transfer account to the user's account. ## Webhook Sending notifications to the merchant when specific events occur. [Polling vs. Webhooks](https://blog.bytebytego.com/i/141963246/polling-vs-webhooks) ## IPN Instant Payment Notification. Webhooks sent by providers to HUB2. ## KYB Know Your Business - A declaration in which an aggregator merchant provides informations about a merchant he aggregates. This prior declaration is necessary to use the [bank collection feature](/integration/en/other_products/bank_collection) ## KYB transaction Declaration made by a merchant-aggregator when making a bank transfer to HUB2 to refill its account. This information enables HUB2's teams to check the conformity of the transaction and validate it. ## KYC Know Your Customer - A process for verifying the identity of a company's customers. ## Submerchant An account linked to a PSP or Fintech Merchant account that is granted a unique ID to process transactions. This structure ensures compliance with regulatory requirements. # Rate limits Source: https://docs.hub2.io/documentation/en/limits Those are the limits applied on our API. This documentation was last updated on **23-11-21**. ## Introduction As the HUB2 API is their main project, a solid quality of service is required. In order to keep an appropriate latency and a reliable service, rate limits must be enforced on the most cost-heavy endpoints. This limit is applied per IP address, so it is relative to each of the API users and the usage of one won't impact the usage of the other. That is why we enforce those limits. ## API limits Here is a table of rate limits. The global limit is for all other endpoints. | `GET` | `/transfers` | 1 req / 30 sec | 2 req / min | | | :----- | :------------------------------------- | :-------------- | :------------ | :----------- | | `POST` | `/transfers` | 75 req / 10 sec | 400 req / min | | | `GET` | `/transfers/:id` | 1 req / 5 sec | 12 req / min | *\*per :id* | | `GET` | `/transfers/:id/balance` | 1 req / 10 sec | 6 req / min | | | `GET` | `/transfers/:id/status` | 5 req / 5 sec | 60 req / min | *\*per :id* | | `GET` | `/payments` | 1 req / 30 sec | 2 req / min | | | `GET` | `/payments_intents` | 1 req / 30 sec | 2 req / min | | | `POST` | `/payments_intents` | 75 req / 10 sec | 400 req / min | | | `GET` | `/payments_intents/:id` | 1 req / 5 sec | 12 req / min | *\*per :id* | | `POST` | `/payments_intents/:id/authentication` | 30 req / 5 sec | 360 req / min | | | `POST` | `/payments_intents/:id/payments` | 75 req / 10 sec | 400 req / min | | | `POST` | `/payments_intents/:id/payments/sync` | 75 req / 10 sec | 400 req / min | | | `GET` | `/payments_intents/:id/payment-fees` | 75 req / 10 sec | 450 req / min | | | `GET` | `/payments/:id/status` | 5 req / 5 sec | 60 req / min | *\*per :id* | | `GET` | `/payments_intents/:id/status` | 5 req / 5 sec | 60 req / min | *\*per :id* | | `POST` | `/terminal/payments` | 5 req / 10 sec | 30 req / min | | | `GET` | `/terminal/payments/:id` | 5 req / 10 sec | 30 req / min | | | `GET` | `/balance` | 75 req / 10 sec | 450 req / min | | | `*` | `*` | 50 req / 5 sec | 600 req / min | Global limit | **Actual limit** is how the code handles it in termes of requests / seconds.
**Rationalized limit** ease understanding and helps compare the different values on a same scale.
**This limit applies both to mode `sandbox` and mode `live`.
Remember to stop sandbox traffic if the transaction stream is getting heavy.**
## How to handle limits Whenever a request is received by the API beyond the limit of the endpoint, an error `Too Many Requests` with HTTP status `429` will be returned. Please checkout [MDN documentation](https://developer.mozilla.org/en/docs/Web/HTTP/Status/429) about this. The request failed and was not handled by the API because of the rate limit. Headers are provided in the HTTP response for proper handling : | Header name | Description | | :---------------------- | :--------------------------------------------------------------------------------------------------------- | | `Retry-After` | In case the limit is reached,
this header tells how long to wait before a new request will be allowed | | `X-RateLimit-Limit` | The current limit on the endpoint | | `X-RateLimit-Remaining` | Number of remaining requests before reaching the limit | | `X-RateLimit-Reset` | Time before a spot is free in the queue for a new request | ### Reactive solution (easier) One way to handle rate limits from a client-side perspective is to retry requests if they fail for a 429 reason: ```javascript hub2-api.js theme={null} const MAXIMUM_TRY_COUNT = 3; const URL = 'https://api.hub2.io/balance; const CONFIGURATION = { method: "GET", headers: { ApiKey: MY_API_KEY, MerchantId: MY_MERCHANT_ID, }, }; (function requestRetry(numberOfTries) { fetch(URL, CONFIGURATION) .then(() => { // code here }) .catch((error) => { if (error?.response?.status === 429) { if (numberOfTries > MAXIMUM_TRY_COUNT) { throw error; } // Adding 1 second of grace delay const retryAfter: number = parseInt(response.headers['retry-after'], 10) + 1; await new Promise((resolve) => setTimeout(resolve, retryAfter)); return requestRetry(numberOfTries + 1); } }) })(0); ``` ```typescript hub2.service.ts theme={null} // Using framework NestJS import { HttpService } from "@nestjs/axios"; import { Injectable } from "@nestjs/common"; import { lastValueFrom } from "rxjs"; @Injectable() export class HUB2Service { public static MAXIMUM_TRY_COUNT: number = 3; constructor( private readonly http: HttpService, ) {} async requestRetry(numberOfTries: number = 0): Promise { const url = 'https://api.hub2.io/balance; const config = { headers: { ApiKey: MY_API_KEY, MerchantId: MY_MERCHANT_ID, }, }; try { const response = await lastValueFrom(this.http.post(url, {}, config)); } catch (error) { if (error?.response?.status === 429) { if (numberOfTries > HUB2Service.MAXIMUM_TRY_COUNT) { throw error; } // Adding 1 second of grace delay const retryAfter: number = parseInt(response.headers['retry-after'], 10) + 1; await new Promise((resolve) => setTimeout(resolve, retryAfter)); return this.requestRetry(numberOfTries + 1); } } } } ``` ### Proactive solution (harder) The proactive solution is a bit trickier, it consist of keeping a pool of requests ready to be started with the exact size of the destination endpoint rate limit. Whenever the pool is empty, the next request waits in line for a token to free up. Check out [that interesting article](https://www.useanvil.com/blog/engineering/throttling-and-consuming-apis-with-429-rate-limits/) on how to implement rate limit from the client-side perspective, especially approaches 4 and 4.1. ## Conclusion In a perfect world, no limit would be set on the API endpoints. However in the real world, it helps preventing abuse and keep a reliable service for everyone. The team work on a daily basis to improve the stability and the performance of the API and this page will be updated as soon as upgrades allow to loosen the limits. # Policies Source: https://docs.hub2.io/documentation/en/policies There are constraints to comply when making a transaction, depending on the country and the provider : * `amount` must be set between the minimum and maximum amount values (inclusively) listed in the below table (MIN & MAX columns) * `amount` must be a multiple of the value listed in the below table (MULTIPLE column) ## PAY-IN ### Mobile Money | GATEWAY | COUNTRY | PROVIDER | CURRENCY | MIN | MAX | | :------ | :------ | :------- | :------- | :-- | :-------- | | Fedapay | BJ | Moov | XOF | 100 | 3 000 000 | | Fedapay | BJ | MTN | XOF | 100 | 3 000 000 | | Fedapay | TG | Moov | XOF | - | - | | Fedapay | TG | Togocell | XOF | - | - | | Intouch | BF | Mobicash | XOF | - | - | | Intouch | BF | Orange | XOF | - | - | | Intouch | CI | Moov | XOF | - | - | | Intouch | CI | MTN | XOF | - | - | | Intouch | CI | Orange | XOF | - | - | | Intouch | CM | MTN | XAF | 500 | 500 000 | | Intouch | CM | Orange | XAF | 500 | 500 000 | | Intouch | GA | Airtel | XAF | - | - | | Intouch | GA | Mobicash | XAF | - | - | | Intouch | GN | MTN | GNF | - | - | | Intouch | GN | Orange | GNF | - | - | | Intouch | ML | Mobicash | XOF | - | - | | Intouch | ML | Orange | XOF | - | - | | Intouch | SN | Emoney | XOF | - | - | | Intouch | SN | Free | XOF | - | - | | Intouch | SN | Orange | XOF | - | - | * For BF, CM, SN and ML, a rounding fee (paid by customer) is applied to reach a modulo 5 amount * For GN, a rounding fee (paid by customer) is applied to reach a modulo 1000 amount ## PAY-OUT | PROVIDER | COUNTRY | MIN | MAX | MULTIPLE | | :------- | :------ | :----- | :-------- | :------- | | Orange | BF | 100 | 1 000 000 | 5 | | Mobicash | BF | 500 | 1 000 000 | 5 | | Orange | CI | 200 | 1 500 000 | 5 | | MTN | CI | 100 | 2 000 000 | 5 | | Moov | CI | 500 | 2 000 000 | 5 | | Orange | CM | 500 | 500 000 | 5 | | MTN | CM | 500 | 500 000 | 5 | | Airtel | GA | 100 | 1 000 000 | 5 | | Mobicash | GA | 100 | 1 000 000 | 5 | | Orange | GN | 10 000 | 1 500 000 | 1 000 | | MTN | GN | 10 000 | 1 500 000 | 1 000 | | Orange | ML | 500 | 1 500 000 | 5 | | Mobicash | ML | 500 | 1 500 000 | 5 | | Orange | SN | 100 | 1 500 000 | 5 | | Free | SN | 100 | 1 500 000 | 5 | | EMoney | SN | 100 | 1 500 000 | 5 | # API keys Source: https://docs.hub2.io/integration/en/getting_started/api_keys ## Introduction API keys are used as the main authentication mechanism for the HUB2 API, therefore it's really important to understand what they are and how to use them. API Key management is accessible on the [HUB2 Dashboard](https://dashboard.hub2.io), in the "Developer" section, as illustrated below: The following screenshot shows the list of existing keys: ## Keys management ### Creating a key The API key is only visible when it is created and **can no longer be consulted after this stage**, for security reasons. Click on the "**Create a key**" button to access the following window: * (Optional) Enter a **name** and a **description** for the new key. * The parameter **`environment`** (*sandbox* or *live*) is required. The new key will be restricted to this environment. [Read more about environments.](#environment) In this section, it's possible to restrict which originating IP addresses can use the newly created API key. Permissions of the new API key can be set here. Permissions set on an API key allows the segregation of responsibilities and advanced configuration. This section allows a merchant to use different API keys, whether its software has several components, each with a different role, or not. On the summary page, review the settings for the new API key, and then, click *Validate*. The API key is only displayed once. Save it now in a secure vault. It will not be accessible later. ### Editing a key On each API key row, in the "Actions" column, an *Edit* button is available to change the settings of a key. This edition process is the same as the creation process, except that you will not be able to view the key. **Every setting can be edited**. Changes to permissions and IP address restrictions are taken into account as soon as they are modified. Special attention is required before committing changes. ### Deleting a key In the "Actions" column, a *Delete* button is available to delete a key. Deleting a key is irreversible. HTTP traffic using the deleted key will be stopped immediately after deletion. ## Using the keys In the [API reference](/api-reference), the endpoints requiring authentication by merchant ID and API key are listed. For these endpoints, HTTP headers must be configured in the HTTP request to identify and authenticate the emitter. ## API key configuration ### Environment * `sandbox`: This is a closed environment for integration testing. No traffic or real world transactions will be created if the API key used is set to the `sandbox` environment. Provider behaviour is simulated by HUB2. Also, the transfer and collection accounts used for `sandbox` transactions will be the `sandbox` accounts. * `live` : *NB: Requires GO LIVE and an integration review by HUB2 before traffic can be sent in a `live` (real world) environment*. This is the real world environment, a key in this environment allows real traffic to be processed and providers will be contacted if the transaction endpoints are called. [More on transfer and collection accounts.](/integration/en/getting_started/api_operation#accounts) ### IP address restriction IP address restriction is an optional feature available to merchants to further secure exchanges between the merchant platform and HUB2. When an IP address restriction has been set on an API key, HUB2 checks that the IP address originating the HTTP request is authorized to use the API key it contains. ### Permissions Configurable permissions per API key allows merchants to create multiple keys with different permissions, so that each key has a different responsibility. The full list of permissions and their description is as follows: | Permission | Description | | | :------------------------------- | :-------------------------------------------------------------------------------------------------------------------------- | - | | `Api.transfer_create` | Allows the creation of transfers | | | `Api.transfer_read` | Allows the reading of transfers | | | `Api.payment_intent_create` | Allows the creation of payment intents | | | `Api.payment_intent_read` | Allows the reading of payment intents | | | `Api.payment_intent_auth_create` | Allows the authentication of a payment | | | `Api.payment_fees_read` | Allows the reading of payment fees | | | `Api.payment_create` | Allows the creation of a payment in a payment intent | | | `Api.provisioning_read` | Allows the reading of provisioning requests | | | `Api.provisioning_create` | Allows the creation of a provisioning request | | | `Api.merchant_balance_read` | Allows the reading of transfer and collection accounts balance | | | `Api.terminal_payment_create` | Allows the creation of payments to be made via payment terminal | | | `Api.terminal_payment_read` | Allows the reading of payments made via payment terminal | | | `Api.kyb_read` | Allows the reading of [kyb](/documentation/en/glossary#kyb) / [kyb-transaction](/documentation/en/glossary#kyb-transaction) | | | `Api.kyb_update` | Allows the update of kyb | | | `Api.kyb_delete` | Allows the deletion of kyb / kyb-transaction | | | `Api.kyb_create` | Allows the creation of kyb / kyb-transaction | | ## Good practices ### Security A good security practice is to **renew API keys on a regular basis**. If a key has been inadvertently disclosed to a third party, or stolen by a malicious third party, deleting the keys concerned and recreating new ones can limit the impact on a merchant's business. **Disclaimer**: The merchant is responsible for the manner in which the API Key has been securely stored on its platform. HUB2 cannot be held responsible for the processing of illegitimate traffic associated with a Merchant API Key that has been stolen or disclosed. # API Operation Source: https://docs.hub2.io/integration/en/getting_started/api_operation ## HUB2 APIs The **Pay-in** & **Pay-out** APIs developed by HUB2 are different in the way they operate. ### Pay-out API The [Pay-out API](/integration/en/transfers) is used to transfer funds to a third party: the transaction is a debit. The funds are automatically sent to the recipient without any interaction on their part. The [transfer account](/documentation/en/glossary#transfer-account) must be funded before transfers can be made using the HUB2 API. Before proceeding with the transfer, HUB2 checks whether the merchant has the necessary funds and reserves them until the provider confirms the actual transfer of the funds to the recipient. ### Pay-in API The [Pay-in API](/integration/en/payments) is used to collect funds from a third party (end customer): the transaction is of the credit type. Customer interaction is required here, since the customer must, depending on the case : * confirm the transaction with their provider when they receive a PUSH message or execute a USSD code * first generate an authentication code with the provider, to be provided at the time of payment. Once the transaction has been authenticated, the amount of the transaction is credited to the merchant's [collection account](/documentation/en/glossary#collection-account). ## Accounts As mentioned above, pay-ins (payments) and pay-outs (transfers) use distinct accounts to operate. All successful pay-ins are credited to the collection account and all successful pay-outs are deducted from the transfer account. **Important :** Since transactions may exist in a `live` or `sandbox` environment, collection and transfer accounts also exist in both environments. As a consequence, a transaction that is created in a `sandbox` environment will only affect the `sandbox` account and thus, the `sandbox` balance. Same for the `live` environment. When a new merchant is created on the HUB2 platform, and since HUB2 simulates the provider's behavior in the `sandbox` environment, the `sandbox` transfer account is **credited with 100,000 XOF** to help the integration process. ## Asynchronicity All transactions created on the HUB2 API, with the exception of transactions created on the [synchronous circuit](#synchronous-circuit), are processed asynchronously. Once accepted, the parameters of a transaction request are recorded in a stack of transactions to be processed and are then handled by the other components of the HUB2 infrastructure. This mode of operation has a number of advantages, not least of which is the ability to respond very quickly to the sender of the HTTP request, thereby reducing the time spent waiting on the merchant platform side, and thus reducing its load. ## Circuits ### Asynchronous circuit All transactions initiated in this circuit are processed asynchronously by the HUB2 API. This is the default mode of operation for providers, who do not respond directly to transaction requests but place them in a queue for processing. Transactions are then updated once they have been processed. The time taken for a provider to process a transaction may vary from one provider to another. Updating the status of a transaction to a final state at HUB2 therefore depends on the transaction status update at the provider. Once a transaction has been assigned a final status, it can be updated at HUB2 in one of two ways: * either by an [Instant Payment Notification](/documentation/en/glossary#ipn) sent by the provider * or by [regularly querying the status of the transaction](/documentation/en/glossary#transaction-polling) by HUB2 at the provider ### Synchronous circuit The [asynchronous](#asynchronicity) operating mode of HUB2 is not available with the synchronous circuit. The sender of the HTTP request (the merchant) must wait for a response from HUB2, which will depend on both the provider contacted and the responsiveness of the end customer. This circuit is only available for pay-ins (payments). Some providers offer the option, either by default or as an additional circuit, of operating synchronously. In this mode of operation, the transaction request is processed immediately when it is called, without being placed in a stack of transactions to be processed later. The final status of a transaction is obtained directly when the provider responds, although there may be a non-negligible delay between HUB2 sending the request and the provider responding. The providers for which the synchronous circuit is available are : * Wave (all countries) This circuit can only be activated on request to HUB2 Support. Please contact HUB2 Support for more information. # Introduction Source: https://docs.hub2.io/integration/en/getting_started/introduction A guide to help getting started with HUB2 API integration *Go to the full documentation of REST API endpoints, parameters and responses returned - **[API Reference](/api-reference)*** HUB2 [Transfer (Pay-out) API](/integration/en/transfers) & [Payment (Pay-in) API](/integration/en/payments) solutions offer a standardized and secure integration for online financial transactions. These solutions support various payment methods, such as : * Mobile money * Bank transfers * Debit or credit cards To begin integrating the HUB2 API, it is crucial to follow the steps and concepts detailed in this Getting Started Guide, which lay the foundation for the rest of the integration process. [A glossary](/documentation/en/glossary) is also available to help understand the terms used in this documentation. # Security Source: https://docs.hub2.io/integration/en/getting_started/security_considerations # Security considerations Security remains the top priority when it comes to online financial transactions. ## Integration To ensure that exchanges between the merchant and HUB2 remain confidential, and that only the merchant is at the origin of the transactions (and therefore of the amount and other properties of these transactions), **the integration of the API must only take place on the server side**. Sensitive data, such as API keys, **must never be disclosed**, whether on a website or in a mobile application. This approach strengthens security by avoiding direct exposure of API keys and sensitive information on the client side. By performing transactions on the server side, the risk of malicious attacks, such as client-side data manipulation, is considerably reduced. ## CORS To protect against potential client-side integrations, the HUB2 API is set up so that it can never be loaded from the end-client's browser. In other words, the HTTP headers for *cross origin resource sharing* ([CORS](https://developer.mozilla.org/fr/docs/Web/HTTP/CORS)) have been correctly set. # Signature To enhance the security and integrity of API interactions, an optional payload signature mechanism is available. This feature enables merchants to cryptographically sign the JSON request body sent to the API. By verifying this signature, it can be ensured that the data has not been tampered with in transit and originates from a trusted source. This added layer of security is particularly valuable for sensitive financial transactions. Check out the [integration page](/integration/en/other_products/payload_signature) to understand how to use out. # Platform security mechanisms To protect the HUB2 platform, several security components are implemented at different levels of the infrastructure. At the perimeter, a *Web Application Firewall* (WAF) analyzes every single HTTP request before forwarding it to the backend. Its primary role is to detect and block malicious HTTP requests before they can reach the application layer. For **rejected requests**, clients will face the following behavior: Here, an SQL injection (SQLi attack) is simulated on the HUB2 API.
The web application firewall immediately rejects the request and returns a response with the status `HTTP 403 Forbidden`.
**Note:** The WAF will *always* return a `text/html` response Body.
**Please keep this in mind when integrating the HUB2 API.**
### Troubleshooting `HTTP 403 Forbidden` common errors If a legitimate request faces an `HTTP 403 Forbidden`, please first follow the below guidelines to ensure your integration complies with our security standards. If your request is still rejected after applying the below guidelines, feel free to file a ticket with the HUB2 Support team. #### 1. `GET` HTTP request with Body content * `GET` requests must **NOT** include any Body content. All non-compliant requests will be rejected by the HUB2 security gateway. * The `Content-Length` header is not mandatory for a `GET` request. However, if included, it must be set to `0` and the body must remain completely empty. For example: Notice the `Content-Type` & `Content-Length` headers sent, along with the **Body content** for a `GET` request. Such requests will be rejected. ```http theme={null} GET /webhooks/ HTTP/1.1 Host: api.hub2.io Accept: application/json User-Agent: Example Merchant backend/1.0 Content-Type: application/json <------------ Here Content-Length: 184 <----------------------- Here {"url":"https://my.webhook.target","events":["payment.created","payment_intent.created"],"description":"This is a webhook trigger upon payment & payment_intent creation","metadata":{}} ^----------- Here ``` See the ***Good practice*** below to fix this. Apply the following recommendations to avoid triggering the security gateway: 1. Remove the Body content entirely. 2. Remove the `Content-Type` & `Content-Length` headers (`Content-Length` is generally computed automatically by your HTTP client library, so there is usually nothing extra to configure). ```http theme={null} GET /webhooks/ HTTP/1.1 Host: api.hub2.io Accept: application/json User-Agent: Example Merchant backend/1.0 ``` #### 2. Non-stringified JSON body All HTTP `POST` requests using `application/json` must be **stringified** as a **single line of text**. Multi-line JSON payloads will be rejected by the HUB2 security gateway. Formatting the JSON string with carriage returns (CR/LF) or spaces (except inside the values themselves) can trigger filtering rules. For example: Notice the **multi-line JSON object** in the Body content below: ```http theme={null} POST /webhooks/ HTTP/1.1 Host: api.hub2.io Accept: application/json User-Agent: Example Merchant backend/1.0 Content-Type: application/json Content-Length: 214 v----------- Here { "url": "https://my.webhook.target", "events": [ "payment.created", "payment_intent.created" ], "description": "This is a webhook trigger upon payment & payment_intent creation", "metadata": {} } ``` See the ***Good practice*** below to fix this. To avoid triggering the security gateway, transform the multi-line Body content into a **single line of text**, as follows: ```http theme={null} POST /webhooks/ HTTP/1.1 Host: api.hub2.io Accept: application/json User-Agent: Example Merchant backend/1.0 Content-Type: application/json Content-Length: 184 {"url":"https://my.webhook.target","events":["payment.created","payment_intent.created"],"description":"This is a webhook trigger upon payment & payment_intent creation","metadata":{}} ``` #### 3. Body content differs from the `Content-Type` header The HUB2 API currently only accepts JSON payloads. If an HTTP request is sent with valid JSON content, but the `Content-Type` header is set to a different value (e.g., `text/plain`, `text/xml`, or `application/x-www-form-urlencoded`), the security gateway will parse it incorrectly and block the request. For example: Notice the incorrect `Content-Type` header given the JSON payload: ```http theme={null} POST /webhooks/ HTTP/1.1 Host: api.hub2.io Accept: application/json User-Agent: Example Merchant backend/1.0 Content-Type: application/x-www-form-urlencoded <------------ Here Content-Length: 184 {"url":"https://my.webhook.target","events":["payment.created","payment_intent.created"],"description":"This is a webhook trigger upon payment & payment_intent creation","metadata":{}} ``` See the ***Good practice*** below to fix this. Always set the `Content-Type` header **to match the Body content** format: ```http theme={null} POST /webhooks/ HTTP/1.1 Host: api.hub2.io Accept: application/json User-Agent: Example Merchant backend/1.0 Content-Type: application/json <------------ Here Content-Length: 184 {"url":"https://my.webhook.target","events":["payment.created","payment_intent.created"],"description":"This is a webhook trigger upon payment & payment_intent creation","metadata":{}} ``` # Understand errors Source: https://docs.hub2.io/integration/en/getting_started/understand_errors To better understand what could cause a failure, it is necessary to distinguish between errors reported at HTTP protocol level via HTTP status codes and the ones reported at application level (HUB2 API). ## HTTP error status codes A HTTP status code in "error" (`HTTP 4XX` or `HTTP 5XX`) indicates a communication issue or request processing issue between an HTTP client and an HTTP server. These codes, included in the server response, indicate the status of the HTTP request. These codes are standardised and must be followed by the server-side application in order to be correctly interpreted by the HTTP client. ## Application errors On the other hand, there are "application errors" which occur once the HTTP request has been accepted for asynchronous processing (after it has returned an `HTTP 2XX` status code). These errors are specific to the logic of the HUB2 platform and are communicated via specific error codes defined within the HUB2 application. See also : * [Failure causes on Transfers](/integration/en/transfers/transfers_failure_causes) (Pay-outs) * [Failure causes on Payments](/integration/en/payments/payments_failure_causes) (Pay-ins) ## Fix an error It is important to distinguish between the two types of errors. Understand that HTTP status codes in error indicates an issue *during communication (or with the request) between the client and the server*, whereas application errors reflect issues encountered during the asynchronous processing of a transaction, *outside the context of an HTTP request*, and only at HUB2 level. The reasons for failure listed on the [Application errors pages](#application-errors) are only for errors encountered during asynchronous processing of any HTTP request. For more details about which HTTP status code can be returned by the HUB2 API for each endpoint, please refer to the [HUB2 API Reference Documentation](/api-reference). # Balances Source: https://docs.hub2.io/integration/en/other_products/balances The accounts balances are available at any time using the HUB2 API. Please check the endpoint in the [API reference](/api-reference/balance/check-merchant-balance). # Request Here is a sample of a request to that endpoint : ```bash Curl theme={null} curl --location --request GET 'https://api.hub2.io/balance?currency=XOF&date=2023-10-01T00:00:00.000Z' \ --header 'ApiKey: [REDACTED]' \ --header 'MerchantId: [REDACTED]' \ --header 'Environment: sandbox' \ ``` ```typescript Typescript theme={null} import fetch from 'node-fetch'; async function getBalance() { const response = await fetch('https://api.hub2.io/balance?currency=XOF&date=2023-10-01T00:00:00.000Z', { method: 'GET', headers: { 'ApiKey': '[REDACTED]', 'MerchantId': '[REDACTED]', 'Environment': 'sandbox' } }); if (response.ok) { const result = await response.json(); console.log(result); } else { console.log(`HTTP Status: ${response.status}`); } } getBalance(); ``` ```python Python theme={null} import requests url = 'https://api.hub2.io/balance?currency=XOF&date=2023-10-01T00:00:00.000Z' headers = { 'ApiKey': '[REDACTED]', 'MerchantId': '[REDACTED]', 'Environment': 'sandbox', } response = requests.get(url, headers=headers) if response.status_code == 200: print(response.json()) else: print(f'HTTP Status: {response.status_code}') ``` Please note the following parameters : * Parameter `currency` : identify the currency to fetch, here the value is `XOF` * Parameter `date` : identify the date for which the balance will be fetched, here the value is `2023-10-01T00:00:00.000Z`, default value is now if the field is missing # Response Here is a sample of the response in JSON format : ```json theme={null} { "collectionAccount": [ { "amount": 100, "availableBalance": 100, "currency": "XOF", "date": "2023-10-01T00:00:00.000Z" } ], "transferAccount": [ { "availableBalance": 100, "reservedBalance": 100, "currency": "XOF", "date": "2023-10-01T00:00:00.000Z", "amount": 100 } ] } ``` # Bank collection Source: https://docs.hub2.io/integration/en/other_products/bank_collection ## Introduction This feature is dedicated to merchant aggregators and allows collection via bank transfers. ## Life cycle Here's a schema of the process.