Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Our latest Deposits API is focused on simplicity, usability and personalization and it is used to allow your customers to deposit with their local payment methods of preference.
We work as a bridge between you and your customer's local payment methods such as banks, e-wallets, credit cards among others.
With only one integration, you have access to the most popular payment methods in the emerging markets.
In order to make that possible, we have developed our API v3 of Deposits allowing you to create payments directly from your own cashier or from one of ours in case you want us to take care of the fields needed for each country and payment method.
Our API v3 of deposits is meant to be used on the way that fits best to your needs and technical requirements.
With only one API, you can opt for different integrations:
OneShot Experience: You collect, validate and send all the details required for the payment, and you display the payment's metadata directly on your website or redirect the customers to the payment page.
Hosted Checkout Experience: We take the user to a checkout page to complete missing payment details manually. This flow is triggered as Oneshot experience fallback flow.
V3 PCI: You collect and send to us the Credit Card details for processing. The payment is approved/rejected instantaneously. A PCI certificate is required for this integration.
Start testing all the API features with our Postman collection here.
The OneShot Experience is an integration where you send all the details required for the deposit and the customer itself and we will return you the metadata of the payment for you to build the payment page on your own website or a URL to redirect the customer to the payment page!
We call it OneShot because the customer only has to generate the payment on your cashier and pay.
Once the payment is generated, we will send a field specifying whether the payment experience can be done OneShot: native on your cashier with the metadata we give you or with Redirect.
This integration offers a more personalized user experience, as the user won't leave your site but for pay (if at all).
In order to make the payment creation process as smoother as possible and to avoid errors, in case you don't send a field that is required for the payment method/country, we will take care of it by asking the missing information to the customer on our Hosted Checkout instead of declining the payment😉 .
With this integration, it is a good idea to ask the customer to fill in their details only once and store them in your database so you don't have to ask them for those details each time and instead, you send us the information directly from your database. In case they need to modify something, they should do it from their profile and not from your cashier.
The Hosted Checkout Experience is an integrating solution where you only need to send basic details about the deposit itself, and we will generate a link you will use to redirect your customers to our Hosted Checkout where we will prompt them for any missing details like the payment method, the document, email and full name.
Once integrated, adding new payment methods and countries with this integration requires no further development on your end since we will take care of the user experience!
With this integration, you only need to send the amount and the country of the deposit and we will handle the rest. The customers will be able to choose the payment method on our Checkout, input their data and pay.
The Hosted Checkout Experience, allows you to personalize our Checkout by sending details like the payment_type
to group our payment methods on different sections of your page, the bonus_amount
or a strikethrough_amount
to show a promo on our Hosted Checkout, the description
to show them what they are paying for or even your own logo
so the customer can see it on our Hosted Checkout. All of that, with only one integration described here.
The API V3 PCI for Credit Cards Processing allows you to build your own Credit Card checkout form to collect and send to us the customer's credit card details, allowing for a Seamless experience without redirecting the customer to an external checkout.
Follow this steps to start processing payments with the Zimopagos Deposits API:
1 - Sign Up: Create your merchant account in our Merchant Panel.
2 - Get Credentials: After your account has been activated, you will have access to your Staging (STG) Merchant Panel where you will need to
Whitelist your IPs
Retrieve your API Keys
Than can be done by going to Settings -> API Access.
3 - Integrate the APIs: Follow the instructions over this documentation to integrate our Deposits APIs.
In order to move your account from STG to PRODUCTION, there are a few tests you need to check you are able to do:
4 - Go Live: Once you have completed the tests required in step 3, Request Go Live on the Home of the STG Merchant Panel to generate your account in our Production environment.
We will review your tests, if everything is fine you will receive an email to activate your account on our production environment. In case there is something missing, we will let you know!
5 - Process payments: Get the production credentials, whitelist your IPs on the production environment and start processing your payments with Zimopagos!
Don't get stuck! In case you have any technical doubts not covered on this documentation, reach out to [email protected] for assistance.
In order for you to start testing our Deposits APIs right away, we have prepared a Postman Collection you can use to test and validate your integration along with the functionalities we offe
Make sure you replace the login
and secretKey
values with your own API Key and API Signature deposit credentials
Check the list of Payment Methods available on each American country
Learn how to integrate all of our Deposits endpoints
Welcome to Zimopagos APIs documentation page.
Here you will find all you need to know to integrate our products to start sending and receiving payments from your customers.
Our main Payment Processing APIs are listed below. Within each one of them you may find resourceful endpoints to consume and build a seamless integration.
For world-class UX and integration, we strongly suggest the use of our Deposits API OneShot Experience flow! 🚀
Learn how to integrate all of our Cashouts endpoints
Learn about our Payment Methods
You can retrieve the payment methods your account has enabled by using the
On the Merchant Panel you can check what Payment Methods your account has enabled by going to the "Payment Methods" section on the left menu. The Payment Method availability is real time updated on the panel.
Notice that not every payment method is available in Staging. Check on each country's table the available ones.
Some methods may not be available within an iframe due to our processor's security requirements. Check on each country's table the available ones. In those cases, we will ask the customer to open the payment page on a new window.
The checkouts may differ between STG and PROD in the cases we use different providers.
Some payment methods allows you to display the payment information directly on your website, without having to redirect the customer to an external website. Those methods are so called "ONE_SHOT" and are part of our . When creating a payment of this kind, we will return you all the fields you need to display to your customer on a and a URL to redirect the customer in case the payment requires so.
In case the flow is "REDIRECT", we will generate a link so that you can redirect the customer to the page where they will insert any missing details and see the payment instructions.
The ONE_SHOT
and REDIRECT
flows depends upon provider's availability. In order for us to provide you with the most efficient service, we may switch between service providers who doesn't support ONE_SHOT
flows, hence your cashier should be able to adapt to both scenarios.
Cashouts API v3 Introduction
Find below the description of a cashout flow using the D24 cashouts integration:
1 - Upon your customer's request, you submit a cashout request through the Cashout-Request API or through the Merchants panel (Transactions -> Withdrawals -> Request Cashout).
2 - Initial validations are performed by the API, such as:
Merchant account balance enough to cover the cashout
Merchant account Transaction/Daily/Monthly limits permit the cashout
Destination Bank Account details are correct.
Customer's details are correct. Eg. Document ID
3 - If the previous step is correct, the cashout is created and remains on PENDING status, otherwise, it's DECLINED. If Pending, it will be then sent to the bank for processing, when that happens, the status is set to DELIVERED.
4 - Once the transaction comes back from the bank, it can be either COMPLETED or REJECTED (by the bank).
There are some cases in which the bank could Confirm the Cashout and then Reject it because the destinatary's bank account was, for any reason, unable to receive the funds. This is a corner case but should be considered when integrating.
In order for you to start testing our Cashouts APIs right away, we have prepared a Postman Collection you can use to test and validate your integration along with the functionalities we offer
We provide you with test credentials to our test environment, but make sure sure you replace the vars apiKey
, apiPassphrase
and apiSignature
in the Pre-req. Scripts" section of all the requests with your own
Learn about how the notifications for refunds works
Every time a refund changes its status, we will send you an asynchronous notification to the notification_url
you sent in the refund request or the one you have configured under the section "Settings -> API Access" of our Merchant Panel containing the ID of the refund.
Once received the notification, you should check its new status with the and update it on your end accordingly.
Every time a refund changes its status, we will send you a notification so you can back.
In case that for some reason your server was unable to receive the notification and you returned an HTTP code different than 200, we will retry the notification up to 5 more times or until you respond with HTTP 200, whatever comes first.
The time between each of the 5 notifications attempts will be exponential: 5, 25, 125 and 625 minutes accordingly.
When the notifications fails to be sent, it will be shown like this in our Merchant Panel:
If you see the errors from the screenshot above, it means the refund was successfully completed and the money reached the customer's account/card but suddenly we couldn't notify you. Keep reading to know how to resend the notifications.
In case your system was unable to receive the notification in any of the 5 attempts, you can always check its status with the
If you need to trigger the check status by receiving our notification, once the issue preventing you from receiving our notifications was fixed, you can go to the Merchant Panel, locate the refund and click on the three dots button under the "Status History" section and then "Resend notification" to force a new notification to be sent.
It can take up to 1 minute for the notification to be resent in PROD and 3 on STG.
Flow
Description
ONE_SHOT
In the ONE_SHOT
flow, you will receive all the details needed to build a payment page on your own website. For example, the Boleto's number, barcode, expiration, amount, payment link, etc.
REDIRECT
In the REDIRECT
flow, we will respond you with a link you should use to redirect your customers so they can pay.
Field
Format
Description
refund_id
Number
ID of the refund. Use this ID to check the status of the refund.
{
"refund_id": 168284
}
Learn about how the notifications for deposits works
Every time a deposit changes its status, we will send you an asynchronous notification to the notification_url
you sent in the request or the one you have configured under the section "Settings -> API Access -> Confirm URL" containing the ID of the deposit.
Once received the notification, you should check its new status with the Deposit Status Endpoint and update it on your end accordingly.
In the STG environment, in order to test the full flow you can manually set a deposit to COMPLETED / CANCELLED status by login into the STG Merchant Panel and going to Transactions -> Deposits. Those options will change the status of the deposit, therefore sending the respective notification to your notification_url after a few minutes.
Field
Format
Description
deposit_id
Number
ID of the deposit. Use this ID to
{
"deposit_id": 3000000001
}
Every time a deposit changes its status, we will send you a notification so you can check its status back.
In case that for some reason your server was unable to handle our notification and you returned an HTTP code different than 2XX, we will retry the notification up to 5 more times or until you respond with HTTP 2XX, whatever comes first.
In case of errors while handling the notification, make sure you will answer with an HTTP code distinct than 2XX, that way we will retry the notification.
The time between each of the 5 notifications attempts will be exponential: 5, 25, 125 and 625 minutes accordingly.
When a notification failed to be sent, it will be shown like this in our Merchant Panel:
If you see the errors from the screenshot above, it means the payment was successfully completed and the money was credited to your account but suddenly we couldn't notify you. Keep reading to know how to resend the notifications.
In case your system was unable to handle the notification in any of the 5 attempts, you can always check its status with the Deposit Status Endpoint.
If you need to trigger the check status by receiving our notification, once the issue preventing you from receiving our notifications was fixed, you can go to the Merchant Panel, locate the deposit (Transactions -> Deposits) and click on the three dots button under the "Status History" section and then "Resend notification" to force a new notification to be sent.
It can take up to 1 minute for the notification to be resent.
Learn how to correctly calculate the Signature Control String to authenticate with the V3 Cashout endpoints
All calls to our Cashouts APIs must contain a Payload-Signature
field on the header used to ensure request integrity and to authenticate yourself since you will use your own API Signature (secret key) to generate and encrypt a hash.
It has to be created using HMAC-SHA-256 (RFC 2104) encoding and the payload is made of the entire JSON Payload sent in the body of the requests and notifications.
Use your API Signature to create the HASH
The Payload-Signature
field on the header of the requests will contain the hash generated from hashing the entire JSON Payload:
Payload-Signature: HMAC256(jsonPayload)
Example:
Payload-Signature: 223a9dd4784726f1536c926da7dc69155a57612c5c3c1e1b429c367a5eee67cf
The Payload-Signature
value is case sensitive and must be sent in lower case.
In case the jsonPayload
value is empty, use an empty string instead.
The jsonPayload
should be converted to UTF-8 before hashing it to prevent Invalid Signature
error when sending characters with different encodings.
Check the examples below on how to calculate the Payload-Signature
.
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.net.util.Base64;
String json_payload = "{ \"login\": \"cashout_API_Key\", \"pass\": \"cashout_API_Passphrase\", \"external_id\": \"123456789\", \"document_id\": \"1234567899\", \"document_type\": \"\", \"cashout_type\": \"BANK\", \"beneficiary_name\": \"Test User\", \"beneficiary_lastname\": \"Test User\", \"country\": \"MX\", \"amount\": 2000, \"currency\": \"MXN\", \"email\": \"[email protected]\", \"notification_url\": \"http:\\/\\/zimo-pagos.com\\/notification\", \"bank_code\": \"072\",\"bank_branch\": \"\", \"bank_account\": \"1234567890\", \"account_type\": \"C\", \"address\": \"\"}";
String secretKey = "cashout_secret_key";
Mac hasher = Mac.getInstance("HmacSHA256");
hasher.init(new SecretKeySpec(secretKey.getBytes(), "HmacSHA256"));
String payload_signature = Base64.encodeBase64String(hasher.doFinal(json_payload.getBytes())).toLowerCase();
<?php
$json_payload = '{
"login": "cashout_API_Key",
"pass": "cashout_API_Passphrase",
"external_id": "123456789",
"document_id": "1234567899",
"document_type": "",
"cashout_type": "BANK",
"beneficiary_name": "Test User",
"beneficiary_lastname": "Test User",
"country": "MX",
"amount": 2000,
"currency": "MXN",
"email": "[email protected]",
"notification_url": "http://www.zimo-pagos.com/notification",
"bank_code": "072",
"bank_branch": "",
"bank_account": "1234567890",
"account_type": "C",
"address": ""
}';
$secretKey = "cashout_secret_key";
$payload_signature = strtolower(hash_hmac('sha256', pack('A*', $json_payload), pack('A*', $secretKey)));
?>
using System;
using System.Text;
using System.Security.Cryptography;
string jsonPayload = "{ \"login\": \"cashout_API_Key\", \"pass\": \"cashout_API_Passphrase\", \"external_id\": \"123456789\", \"document_id\": \"1234567899\", \"document_type\": \"\", \"cashout_type\": \"BANK\", \"beneficiary_name\": \"Test User\", \"beneficiary_lastname\": \"Test User\", \"country\": \"MX\", \"amount\": 2000, \"currency\": \"MXN\", \"email\": \"[email protected]\", \"notification_url\": \"http:\\/\\/www.zimo-pagos.com\\/notification\", \"bank_code\": \"072\",\"bank_branch\": \"\", \"bank_account\": \"1234567890\", \"account_type\": \"C\", \"address\": \"\"}";
string secretKey = "cashout_secret_key";
byte[] keyByte = new ASCIIEncoding().GetBytes(secretKey);
byte[] jsonPayloadBytes = new ASCIIEncoding().GetBytes(jsonPayload);
byte[] hashmessage = new HMACSHA256(keyByte).ComputeHash(jsonPayloadBytes);
string payloadSignature = BitConverter.ToString(hashmessage).Replace("-", "").ToLower();
Learn how to calculate and send the Signature header value to verify requests integrity
All the calls to our Deposits APIs will contain an Authorization
field on the header used to ensure request integrity and to authenticate yourself since you will use your own secret key (API Signature) to generate and encrypt a hash.
It has to be created using HMAC-SHA-256 (RFC 2104) encoding and the payload must include the following details:
Use your API Signature to generate the Authorization value
The Authorization
field on the header of the requests will contain the string "ZIMOPAGOS " plus the hash generated, in the following format:
Authorization: "ZIMO" + HMAC256(X-Date + X-Login + JSONPayload)
Example:
Authorization: ZIMO 223a9dd4784726f1536c926da7dc69155a57612c5c3c1e1b429c367a5eee67cf
The X-Login
is your login API Key, it can be retrieved from the Merchant Panel by going to Settings -> API Access -> Deposit credentials -> API Key.
The X-Date
is the date in ISO8601 Datetime with Timezone. Format expected: ISO8601 Datetime with Timezone: yyyy-MM-dd'T'HH:mm:ssZ
. E.g.: 2020-06-21T12:33:20Z
.
The Authorization
value is case sensitive and must include all the above mentioned values.
The JSONPayload
is the exact same JSON you sent in the body of the request.
In case the JSONPayload
value is empty (for example in the status or payment methods endpoints), use an empty string ("") instead.
The JSONPayload
should be converted to UTF-8 before hashing it to prevent Invalid Signature error when sending characters with different encodings.
Check the examples in the different languages on how to properly calculate the Signature.
You can also check the code of our SDKs in Java and PHP to see how it is calculated.
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
public static final String AUTHORIZATION_SCHEME = "ZIMO ";
private static final String HMAC_SHA256 = "HmacSHA256";
public static String buildDepositKeySignature(String apiSignature, String xDate, String depositKey, String JSONPayload)
throws NoSuchAlgorithmException, InvalidKeyException, IOException {
byte[] hmacSha256 = null;
Mac mac = Mac.getInstance(HMAC_SHA256);
SecretKeySpec secretKeySpec = new SecretKeySpec(apiSignature.getBytes(StandardCharsets.UTF_8), HMAC_SHA256);
mac.init(secretKeySpec);
hmacSha256 = mac.doFinal(buildByteArray(xDate, apiKey, JSONPayload));
return AUTHORIZATION_SCHEME + toHexString(hmacSha256);
}
private static byte[] buildByteArray(String xDate, String apiKey, String JSONPayload) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
bos.write(xDate.getBytes(StandardCharsets.UTF_8));
bos.write(apiKey.getBytes(StandardCharsets.UTF_8));
if (JSONPayload != null) {
bos.write(JSONPayload.getBytes(StandardCharsets.UTF_8));
}
return bos.toByteArray();
}
private static String toHexString(byte[] bytes) {
Formatter formatter = new Formatter();
for (byte b : bytes) {
formatter.format("%02x", b);
}
return formatter.toString();
}
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;
namespace Application
{
class Directa24Example
{
public readonly static string AUTHORIZATION_SCHEME = "ZIMO";
private readonly static string HMAC_SHA256 = "HmacSHA256";
public static String buildDepositKeySignature(String apiSignature, String xDate, String depositKey, String jsonPayload)
{
byte[] hmacSha256 = null;
var apiSignatureEncod = Encoding.UTF8.GetBytes(apiSignature);
var hash = new HMACSHA256(apiSignatureEncod);
hmacSha256 = hash.ComputeHash(buildByteArray(xDate, depositKey, jsonPayload));
return AUTHORIZATION_SCHEME + toHexString(hmacSha256).ToLower();
}
private static byte[] buildByteArray(String xDate, String apiKey, String jsonPayload)
{
try
{
MemoryStream stream = new MemoryStream();
var xDateEncod = Encoding.UTF8.GetBytes(xDate);
var apiKeyEncod = Encoding.UTF8.GetBytes(apiKey);
stream.Write(xDateEncod, 0, xDateEncod.Length);
stream.Write(apiKeyEncod, 0, apiKeyEncod.Length);
if (!string.IsNullOrWhiteSpace(jsonPayload))
{
var jsonPayloadEncod = Encoding.UTF8.GetBytes(jsonPayload);
stream.Write(jsonPayloadEncod, 0, jsonPayloadEncod.Length);
}
return stream.ToArray();
}
catch (Exception ex)
{
throw ex;
}
}
private static string toHexString(byte[] bytes)
{
return BitConverter.ToString(bytes).Replace("-", string.Empty);
}
}
}
<?php
class ZimoExample {
const AUTHORIZATION_SCHEME = "ZIMO";
const HMAC_SHA256 = 'sha256';
public static function build_deposit_key_signature($api_signature, $x_date, $deposits_api_key, $json_payload) {
// Concatenate the content of the header X-Date, your deposits API Key (X-Login) and
// the whole JSON payload of the body of the request
$string = $x_date . $deposits_api_key . $json_payload;
// Generate the HASH by using yur own deposits API Signature and
// concatenate "D24 " in front of the hash
return self::AUTHORIZATION_SCHEME . hash_hmac(self::HMAC_SHA256, $string, $api_signature);
}
}
Technical and Security Aspects of our V3 Cashout endpoints
All API requests must be made over HTTPS. Calls made over plain HTTP will fail.
API requests without Payload-Signature will also fail.
You will be able to hit our APIs only from the IPs you have previously whitelisted on the Merchant Panel.
All the integration must be performed on our STG environment, where you can perform your tests freely without risks of any kind.
When you sign up, we will generate you an account on our STG environment where you will be able to:
See the transactions created
Approve and cancel transactions
Retrieve your API Keys
Whitelist your IPs, and more
Each environment has its own domain. The path of the endpoints do not change.
Environment
Domain
Staging
https://api-stg.zimo-pagos.com/
Production
Provided once you complete the testing
In order to authenticate, our Cashouts APIs uses API Keys in all of the requests to authenticate. Your API Keys can be retrieved from the Merchant Panel by going to Settings -> API Access -> Cashouts Credentials.
These are the three credentials you will need:
Your user: API Key
Your password: API Passphrase
Your secret key to generate the signatures: API Signature
Authentication to the API is performed via HTTP Basic Auth. You must provide your API Keys in all requests as the basic auth username and password.
Your user and password keys must be sent in all the API calls using the API Key
and API Passphrase
fields on the body of the request.
Your API Keys, along with your IP Addresses are your way to authenticate yourself, therefore, do not share your credentials in publicly accessible areas such as GitHub, client-side code and so forth.
All requests sent through Cashouts v3 API must have the following headers.
Header
Format
Mandatory
Description
Payload-Signature
String
Yes
HMAC256 of the whole JSON Payload using your API Signature
Content-Type
String
Yes
application/json
User-Agent
String
Yes
Server client user agent
For security purposes, you need to whitelist the IPs from where you will call our API.
In order to whitelist your IPs and make the process as smoother as possible, you should go to Settings -> API Access and add the list of IPs you will possibly use under the Cashouts IP Address section.
Reach out to [email protected] if you need to whitelist our servers IPs on your firewall.
We recommend you follow this list of technical and security practices to maximize the security of the information end-to-end.
Always ensure to verify the Signatures control string sent in the notifications to validate its veracity.
We convert all the data we receive to UTF-8. Make sure you are also converting it into UTF-8 to make sure both parties have the same details.
Go to the next page to learn how to generate the Payload-Signature control string to verify the requests' you send and receive integrity.
Learn how to use the Cashout Cancellation Endpoint to cancel cashouts when needed
DELETE
https://api-stg.Zimo-pagos.com/v3/cashout/cancel
This API allows you to cancel a cashout request. Only for cashouts in PENDING state.
The Cancel Cashout Request endpoint is only to cancel a cashout while it is still in PENDING state (it hasn't been sent for processing).
To do that, you will need to provide both the cashout ID on our end and the external ID you sent while creating the cashout.
The Payload-Signature of the Cashout Status Endpoint is calculated by hashing the JSON payload of the request using HMAC256 and your secret key (API Signature) to encrypt it.
for further instructions.
Response fields
Content-Type*
string
application/json
Payload-Signature*
string
Control Signature
login*
string
Your Zimo-Pagos CASHOUTS API login key
pass*
string
Your Zimo-Pagos CASHOUTS API pass key
cashout_id*
number
The ID of the cashout to cancel. It is the one generated by Zimo-Pagos when the cashout was created
external_id*
string
The external ID of the cashout to cancel. It is the one you sent when generating the cashout
// HEADERS
Content-Type: application/json
Payload-Signature: 2e5023770760ea0a02230bff1a6dab934fe3b47a5e3d43854b58676600ee3868
// BODY
{
"login": "cashout_login",
"pass": "cashout_pass",
"cashout_id": 11954,
"external_id": "cashoutID2134"
}
login
String. Length 32 max
Your Zimo-Pagos CASHOUTS API Key, it can be found on the Merchant Panel: Settings -> API Access. Notice there are specific Cashout credentials
pass
String. Length 32 max
Your Zimo-Pagos CASHOUTS API Passphrase, it can be found on the Merchant Panel: Settings -> API Access. Notice there are specific Cashout credentials
cashout_id
Number
Identifier of the cashout in the Zimo-Pagos end. Returned by the Create Cashout Endpoint
external_id
String
The external ID of the cashout to cancel. It is the one you sent when generating the cashout
// Cashout cancelled successfully
{
"cashout_status": 2,
"cashout_status_description": "Canceled"
}
// Cashout not found
{
"code": 509,
"message": "Cashout not found with this ID"
}
// The cashout can't be cancelled because its status is not Pending
{
"code": 510,
"message": "Invalid status transition"
}
Field
Format
Type
Description
cashout_status
Number
Success
If shown, it is the new status code of the cashout.
cashout_status_description
String
Success
If shown, it described the new status of the cashout.
code
Number
Error
Error code
message
String
Error
Error description
Learn about how the notifications of the Cashout API v3 work
A notification will be sent every time the status of a cashout changes.
For security reasons we don't send the status of the cashout on the notification itself. Once you have received the notification, you will need to use the Cashout Status Endpoint to retrieve its new status.
The notifications will be sent to the notification_url
specified in the request or to the default Withdrawals URL you have configured on the Merchant Panel by POST protocol in x-www-form-urlencoded format and will have the following fields:
Field
Format
Description
date
Date. Format: YYYY-MM-DD HH:MM:SS (GMT)
Date the cashout changed its status
bank_reference_id
String (max. 50 chars)
Reference ID of the bank if any
comments
String (max. 200 chars)
Comments of the cashout if any
external_id
String (max. 100 chars)
ID of the cashout you sent while creating the request
control
String
Control signature of the notification
cashout_id
Number
ID of the cashout on our end
status_reason
String
Reason of the status if any
In the STG environment you can force a notification to be sent to your notification_url
from the STG Merchant Panel by going to the Transactions -> Withdrawals
page, opening the cashout transaction and clicking on one of the options that will appear when clicking in the three dots button on the top right of the screen. Those options will change the status of the cashout therefore sending the respective notification after a few minutes.
date=2020-03-12%2020%3A26%3A11
&bank_reference_id=
&comments=
&external_id=cashoutV35381
&control=A4CFF64E78C4BD01F8BFCA4AFF04632EC4A33CC61BD6BBD156BA1289897892EB
&cashout_id=60067
&status_reason=
The control string for the notifications is made up of some random characters at the beginning and the end of the request and the external_id
received in the middle.
Check the examples below on how to calculate the control string for the notifications:
public static void main(String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
String external_id = "cashoutID1234";
String message = "Be4" + external_id + "Bo7";
String apiSignature = "your_deposits_api_signature";
Mac hasher = Mac.getInstance("HmacSHA256");
hasher.init(new SecretKeySpec(apiSignature.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
byte[] result = hasher.doFinal(message.getBytes(StandardCharsets.UTF_8));
System.out.println(StringUtils.upperCase(DatatypeConverter.printHexBinary(result)));
}
$external_id = 'cashoutID1234';
$message = 'Be4' . $external_id . 'Bo7';
$api_signature = 'cashout_api_signature';
$hash = strtoupper(hash_hmac('sha256', pack('A*', $message), pack('A*', $api_signature)));
string external_id = "cashoutID1234";
string message = "Be4" + external_id + "Bo7";
string apiSignature = "your_cashouts_api_signature";
byte[] keyByte = new System.Text.Encoding.UTF8.GetBytes(apiSignature);
byte[] messageBytes = new System.Text.Encoding.UTF8.GetBytes(message);
byte[] hashmessage = new HMACSHA256(keyByte).ComputeHash(messageBytes);
string control = BitConverter.ToString(hashmessage).Replace("-", "").ToUpper();
Every time a cashout changes its status, we will send you a notification so you can check its status back.
In case that for some reason your server was unable to receive the notification and you returned an HTTP code different than 2XX, we will retry the notification up to 5 more times or until you respond with HTTP 2XX, whatever comes first.
In case of errors while handling the notification, make sure you will answer with an HTTP code distinct than 2XX, that way we will retry the notification.
The time between the 5 notifications attempts will be of 5 minutes each.
When the notification failed to be sent, it will be shown like this in our Merchant Panel:
If you see the errors from the screenshot above, it means the cashout was successfully completed but suddenly we couldn't notify you. Keep reading to know how to resend the notifications.
In case your system was unable to receive the notification in any of the 5 attempts, you can always check its status with the Cashout Status Endpoint.
If you need to trigger the check status by receiving our notification, once the issue preventing you from receiving our notifications was fixed, you can go to the Merchant Panel, locate the cashout (Transactions -> Withdrawals) and click on the three dots button under the "Status History" section and then "Resend notification" to force a new notification to be sent.
It can take up to 2 minute for the notification to be resent.
{
"cashout_status": 2,
"cashout_status_description": "Canceled"
}
{
"code": 510,
"message": "Invalid status transition"
}
Learn how to use the Endpoint to retrieve the status of a cashout
POST
https://api-stg.zimo-pagos.com/v3/cashout/status
This API allows you to retrieve the status of a cashout
Content-Type*
string
application/json
Payload-Signature*
string
Control Signature
login*
String
Your Zimo-pagos CASHOUTS API login key
pass*
string
Your Zimo-pagos CASHOUTS API pass key
cashout_id*
number
The ID of the cashout to check status of. It is the one generated by Zimo-pagos when the cashout was created
external_id*
string
The ID of the cashout to check status of. It is the one you sent when the cashout was created
{
"cashout_status": 1,
"cashout_status_description": "Completed"
}
{
"cashout_status": 3,
"cashout_status_description": "Rejected",
"rejection_code": 0,
"rejection_reason": "Test"
}
{
"code": 401,
"message": "Invalid credentials."
}
{
"code": 509,
"message": "Cashout not found with this ID"
}
// HEADERS
Content-Type: application/json
Payload-Signature: 2e5023770760ea0a02230bff1a6dab934fe3b47a5e3d43854b58676600ee3868
// BODY
{
"login": "cashout_login",
"pass": "cashout_pass",
"cashout_id": 11954
}
login
String. Length 32 max
Your Zimo-pagos CASHOUTS API Key, it can be found on the Merchant Panel: Settings -> API Access. Notice there are specific Cashout credential
pass
String. Length 32 max
Your Zimo-pagos CASHOUTS API Passphrase, it can be found on the Merchant Panel: Settings -> API Access. Notice there are specific Cashout credentials
cashout_id
Number
Identifier of the cashout on Zimo-pagos' end. It is the one returned by the
external_id
String
Identifier of the cashout on the Merchant end. It is the one you sent while . You can opt to send this field or cashout_id
You can choose to send the external_id or the cashout_id
The Payload-Signature of the Cashout Status Endpoint is calculated by hashing the whole JSON payload of the request using HMAC256 and your secret key (API Signature) to encrypt it.
Click here for further instructions.
// Cashout successfully processed
{
"cashout_status": 1,
"cashout_status_description": "Completed"
}
// Cashout successfully processed through Pix including the E2E ID (Brazil)
{
"cashout_status": 1,
"cashout_status_description": "Completed",
"provider_external_reference": "E352104102024022919987ScFRY3aab3",
"bank": {
"code": "260",
"name": "Nubank",
"branch": "2003",
"account": "1892873892",
"beneficiary_name": "John Smith"
}
}
// Cashout Rejected by the bank
{
"cashout_status": 3,
"cashout_status_description": "Rejected",
"rejection_code": 808,
"rejection_reason": "ERROR_OTHER"
}
cashout_status
Number
Status code of the cashout.
cashout_status_description
String
Description of the status
provider_external_reference
String
ID of the transaction on the bank side. For Pix, it's the E2E ID (End-to-end)
bank[]
object
Object containing information about the bank of the beneficiary
bank[].code
String
Code of the bank of the beneficiary
bank[].name
String
Name of the bank of the beneficiary
bank[].branch
String
Branch of the beneficiary's bank account
bank[].account
String
Account number of the beneficiary's bank account
bank[].beneficiary_name
String
Name of the owner of the account
rejection_code
Number
Rejection code if sent by the bank.
rejection_reason
String
Reason of the rejection if sent by the bank
When processing Pix Withdrawals, we return as part of the Status endpoint further information about the bank account of the beneficiary.
This includes the provider_external_reference
, also known as the E2E ID. It is a unique ID assigned to the transactions that can be used to track the transfer across the Brazilian banking system, useful to optimize the support experience as it allows the users to uniquely track their money as it reaches their bank account.
{
"cashout_status": 1,
"cashout_status_description": "Completed",
"provider_external_reference": "E352104102024022919987ScFRY3aab3",
"bank": {
"code": "260",
"name": "Nubank",
"branch": "2003",
"account": "1892873892",
"beneficiary_name": "John Smith"
}
}
We also include details about the bank account that received the money, useful when using Pix Keys.
Click here to see each Cashout Status meaning.
Check all the possible status codes in the following page:
Learn how to use the endpoint to update the status of a cashout
PUT
https://api-stg.zimo-pagos.com/v3/cashout/status
This API allows you to change the status of a cashout
Content-Type*
string
application/json
Payload-Signature*
string
Control Signature
login*
String
Your Zimo-Pagos CASHOUTS API login key
pass*
string
Your Zimo-Pagos CASHOUTS API pass key
cashout_id*
number
The ID of the cashout to asign status to. It is the one generated by Zimo-Pagos when the cashout was created
status*
string
The status to be assigned to the cashout
{
"cashout_status": 1,
"cashout_status_description": "Completed"
}
{
"cashout_status": 3,
"cashout_status_description": "Rejected",
"rejection_code": 0,
"rejection_reason": "Test"
}
{
"code": 401,
"message": "Invalid credentials."
}
{
"code": 509,
"message": "Cashout not found with this ID"
}
This API is used to update a cashout from PENDING to ON_HOLD or from ON_HOLD to PENDING.
A cashout in ON_HOLD won't be processed until you set it back to PENDING. This is useful in cases where you need to perform some form of KYC over the beneficiary before proceeding with the request.
You can create a cashout in ON_HOLD by specifying the flag on_hold: true
on the cashout creation request.
If a cashout is ON_HOLD and you would like to definitely cancel it, please see the Cashout Cancellation Endpoint
Cashouts in ON_HOLD retain the amounts from your balance, so be careful to not accumulate cashouts in this status for long time.
// HEADERS
Content-Type: application/json
Payload-Signature: 2e5023770760ea0a02230bff1a6dab934fe3b47a5e3d43854b58676600ee3868
// BODY
{
"login": "cashout_login",
"pass": "cashout_pass",
"cashout id": "97875"
"status": "ON_HOLD"
}
login
String. Length 32 max
Your D24 CASHOUTS API Key, it can be found on the Merchant Panel: Settings -> API Access. Notice there are specific Cashout credentials
pass
String. Length 32 max
Your D24 CASHOUTS API Passphrase, it can be found on the Merchant Panel: Settings -> API Access. Notice there are specific Cashout credentials
cashout_id
Number
Identifier of the cashout on D24 end. It is the one returned by the
status
String
Status to be assigned to the cashout. Valid values: PENDING
, ON_HOLD
The Payload-Signature of the Cashout Update Status Endpoint is calculated by hashing the whole JSON payload of the request using HMAC256 and your secret key (API Signature) to encrypt it.
Click here for further instructions.
{
"code": 510,
"message": "Invalid status transition"
}
code
Number
Error code
message
String
Description of the error
Click here to see each Cashout Status meaning.
There are cases in which the bank confirms us that a payout was successful and after a few days, it gets rejected by the beneficiary's bank therefore the status on our platform will change to REJECTED as well. Those are very corner cases but should be considered.
Check all the possible status codes in the following page:
Retrieve the status of a previously created refund
GET
https://api-stg.zimo-pagos.com/v3/refunds/{refund_id}
This endpoint allows you to retrieve the status of a refund request.
You can trigger the check of the status of a refund at any moment you consider pertinent. However, every time a refund changes its status, we will send you a containing the ID of the refund so that you can check its status back to retrieve the new refund's status.
In order to check the status of the refunds, you need to:
Send the request with GET method.
Use the headers described .
Specify a valid refund_id
in the URL of the request as PATH PARAMETERS.
Send the Authorization header, as .
Regarding the Authorization value, since the body of the requests will be empty, you should use an empty ("") string or nothing as the jsonPayload
field.
In order to make the experience more personalized, we may add more fields to this response's object in the future. Please develop your integration to be able to ignore new fields considering that it will continue working fine no matter if we add new fields.
In order to generate an invoice as proof of refund, you need to:
Send the request with GET method.
Use the headers described .
Specify a valid refund_id
in the URL of the request as PATH PARAMETERS.
Send the query parameter voucher
as true.
Send the Authorization header, as .
Requesting a Refund and including the field voucher
as a query parameter with value true
will generate a voucher in base64, this voucher will need to be decoded to create the .pdf
to see each Refund Status meaning.
Check all the possible status in the following page:
refund_id*
Integer
Zimo-pagos refund_id. It is obtained when creating the refund
voucher
Boolean
true
/ false
value, The request with True value will return the refund invoice in base64 to be decoded to create a .pdf.
X-Date*
String
ISO8601 Datetime with Timezone: yyyy-MM-dd'T'HH:mm:ssZ
X-Login*
String
Merchant X-Login API Key
Authorization*
String
Authentication signature hash
curl --location --request GET 'https://api-stg.zimo-pagos.com/v3/refunds/1682844' \
--header 'X-Login: {{X-Login}}' \
--header 'X-Date: {{X-Date}}' \
--header 'Authorization: {{Authorization}}' \
--header 'Content-Type: application/json' \
--data-raw ''
import java.io.*;
import okhttp3.*;
public class main {
public static void main(String []args) throws IOException{
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
Request request = new Request.Builder()
.url("https://api-stg.zimo-pagos.com/v3/refunds/1682844")
.method("GET", null)
.addHeader("X-Login", "{{X-Login}}")
.addHeader("X-Date", "{{X-Date}}")
.addHeader("Authorization", "{{Authorization}}")
.addHeader("Content-Type", "application/json")
.build();
Response response = client.newCall(request).execute();
System.out.println(response.body().string());
}
}
using System;
using RestSharp;
namespace HelloWorldApplication {
class HelloWorld {
static void Main(string[] args) {
var client = new RestClient("https://api-stg.zimo-pagos.com/v3/refunds/1682844");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader("X-Login", "{{X-Login}}");
request.AddHeader("X-Date", "{{X-Date}}");
request.AddHeader("Authorization", "{{Authorization}}");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);
}
}
}
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api-stg.zimo-pagos.com/v3/refunds/1682844",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"X-Login: {{X-Login}}",
"X-Date: {{X-Date}}",
"Authorization: {{Authorization}}",
"Content-Type: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
{
"deposit_id": 300533569,
"merchant_invoice_id": "84044",
"status": "COMPLETED",
"amount": 100.00
}
{
"deposit_id": 300502126,
"merchant_invoice_id": "84121",
"status": "PENDING"
}
Field name
Format
Description
deposit_id
Integer
ID of the deposit refunded
merchant_invoice_id
String
Merchant invoice id of the deposit refunded
status
Enum
Status of the refund. Click here for the full list of refund codes.
amount
Number
Amount of the refund
voucher
String
Proof of refund in base64 coding for generation of .pdf
file.
Included in response only if voucher
is sent as true
in query params.
{
"deposit_id": 300533646,
"merchant_invoice_id": "newIUnit45328731",
"status": "PENDING"
}
{
"code": 208,
"description": "Resource not found",
"type": "RESOURCE_NOT_FOUND"
}
Learn about the technical and security aspects of our Deposits APIs
All API requests must be made over HTTPS. Calls made over plain HTTP will fail.
API requests without Authentication will also fail.
You will be able to hit our APIs only from the IPs you have previously whitelisted on the Merchant Panel.
All the integration must be performed on our TEST environment, where you can perform your tests freely without risks of any kind.
When you sign up with us, we will generate you an account on our STG environment where you will be able to:
See the transactions created
Approve and cancel transactions
Retrieve your API Keys
Whitelist your IPs, and more
Each environment has its own domain. The path of the endpoints doesn't change.
Testing
https://api-stg.zimo-pagos.com/
Production
Provided once you complete the testing
Our Deposits APIs uses API Keys in all of the requests to authenticate. Your API Keys can be retrieved from the Merchant Panel by going to Settings -> API Access.
There are basically two set of credentials:
One API Key and one API Signature for POST operations.
One API Key key for read-only endpoints.
Authentication to the API is performed via HTTP Basic Auth. You must provide your API Key in all the requests as the basic auth username value. You do not need to provide a password.
Your API Key must be sent in all the API calls using the X-Login field on the header of the request.
Your API Keys, along with your IP Addresses are your way to authenticate yourself, therefore, do not share your secret API keys in publicly accessible areas such as GitHub, client-side code and so forth.
All the requests sent through the API of Deposits v3 must have the following headers.
Authorization
String
Yes
"ZIMO"
plus a hash HMAC256 to verify request integrity
X-Login
String
Yes
Merchant API Key
X-Date
String
Yes
ISO8601 Datetime: yyyy-MM-dd'T'HH:mm:ssZ
. E.g.: 2020-06-21T12:33:20Z
Content-Type
String
Yes
application/json
X-Idempotency-Key
String
No
Unique value generated by the client which the server uses to recognize subsequent retries of the same request
All the requests you send must contain the Authorization
header with an HMAC256 control string signature using your own API Signature. This is used to verify the request integrity as we will calculate the same Signature and compare it with the one you send. In case of mismatch we will decline the request.
In the case of the notifications given by our APIs, those will also contain an Authorization
value which you should calculate and compare to make sure the content was not altered by a Man in the Middle attack.
Check the following page for instructions on how to calculate the Control Signature.
All the requests you send must contain the header X-Login
with your own API Key value used to authenticate yourself. Check API Keys.
All the requests you send must contain the header X-Date
with the time in which the request was created. The format is in ISO8601 Datetime: yyyy-MM-dd'T'HH:mm:ssZ
. E.g.: 2020-06-21T12:33:20Z
.
Make sure you use UTC as the timezone specified and not your client's local timezone.
If the date you send differs in more than 5 seconds with the time in our servers, we will block the request for security reasons.
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class ClientUtils {
private static final String DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ss'Z'";
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern(DATE_PATTERN);
public static String now() {
return LocalDateTime.now(ZoneOffset.UTC).format(DATE_TIME_FORMATTER);
}
}
<?php
namespace ZimoPagos\util;
class Helpers
{
private static $DATE_TIME_FORMATTER = "Y-m-d\TH:i:s\Z";
public static function getCurrentDate()
{
date_default_timezone_set('UTC');
return date(self::$DATE_TIME_FORMATTER);
}
}
print(Helpers::getCurrentDate());
Check our SDK in JAVA and PHP for the full code of how to generate the X-Date and the full request.
Our API supports idempotency for safely retrying requests without accidentally performing the same operation twice. This is useful when an API call is disrupted in transit and you do not receive a response. For example, if a request to the Deposit Creation Endpoint does not respond due to a network connection error, you can retry the request with the same idempotency key to guarantee that no more than one deposit is created.
In order to perform an idempotent request you need to send the X-Idempotency-Key: <key>
header with a random and unique string.
Idempotency works by saving the resulting status code and body of the first request made for any given idempotency key, regardless of whether it succeeded or failed. Subsequent requests with the same key return the same result, including 500
errors.
An idempotency key is a unique value generated by the client which the server uses to recognize subsequent retries of the same request. How you create unique keys is up to you, but we suggest using V4 UUIDs, or another random string with enough entropy to avoid collisions.
All POST
requests accept idempotency keys. Sending idempotency keys in GET
and DELETE
requests has no effect and should be avoided as these requests are idempotent by definition.
All of our Deposits APIs are designed to receive and respond the information in JSON format.
This header won't change across the requests, and shall always be: application/json
For security purposes, you need to whitelist the IPs from where you will call our API.
In order to whitelist your IPs and make the process as smoother as possible, you should go to Settings -> API Access and add the list of IPs you will possibly use under the Deposit IP Address section.
Reach out to [email protected] if you need to whitelist our servers IPs on your firewall.
We recommend you follow this list of technical and security practices to maximize the security of the information end-to-end.
Always ensure to verify the Signatures control string sent in the notifications to validate its veracity.
We convert all the data we receive to UTF-8. Make sure you are also converting it into UTF-8 to make sure both parties have the same details.
Always validate that a deposit is not released more than once based on the deposit_id
(The notifications can be sent multiple times).
Go to the next page to learn how to generate the requests signatures control string to verify the requests' you send and receive integrity.
Learn how to use the Cashout Bank Codes Endpoint to retrieve the list of bank codes accepted for cashouts in each country
GET
https://api-stg.zimo-pagos.com/v3/banks?country={ISO_CODE}
This API allows you to retrieve the list of banks available in each country
country*
string
Country ISO code
Authorization*
string
Authorization Header. Format: "Bearer your_read_only_key"
[
{
"code": 1,
"name": "BANCO DO BRASIL S.A."
},
{
"code": 3,
"name": "BANCO DA AMAZONIA S.A."
},
{
"code": 4,
"name": "BANCO DO NORDESTE DO BRASIL S.A."
},
{
"code": 21,
"name": "BANESTES S.A. BANCO DO ESTADO DO ESPIRITO SANTO"
},
{
"code": 33,
"name": "BANCO SANTANDER BRASIL S.A."
},
{
"code": 37,
"name": "BANCO DO ESTADO DO PARA S.A. - BANPARA"
},
{
"code": 41,
"name": "BANCO DO ESTADO DO RIO GRANDE DO SUL S.A. - BANRISUL"
},
{
"code": 47,
"name": "BANCO DO ESTADO DE SERGIPE S.A. - BANESE"
},
{
"code": 70,
"name": "BANCO DE BRASILIA S.A. - BRB"
},
{
"code": 77,
"name": "BANCO INTER"
},
{
"code": 104,
"name": "CAIXA ECONOMICA FEDERAL - CEF"
},
{
"code": 212,
"name": "BANCO ORIGINAL"
},
{
"code": 218,
"name": "BANCO BONSUCESSO S.A."
},
{
"code": 237,
"name": "BANCO BRADESCO S.A."
},
{
"code": 246,
"name": "BANCO ABC BRASIL S.A."
},
{
"code": 290,
"name": "PagSeguro Internet S.A"
},
{
"code": 336,
"name": "BANCO C6 S.A"
},
{
"code": 341,
"name": "ITAU UNIBANCO S.A."
},
{
"code": 389,
"name": "BANCO MERCANTIL DO BRASIL S.A."
},
{
"code": 399,
"name": "HSBC BANK BRASIL S.A. - BANCO MULTIPLO"
},
{
"code": 422,
"name": "BANCO SAFRA S.A."
},
{
"code": 477,
"name": "CITIBANK N.A."
},
{
"code": 637,
"name": "BANCO SOFISA"
},
{
"code": 707,
"name": "BANCO DAYCOVAL S.A."
},
{
"code": 745,
"name": "BANCO CITIBANK"
},
{
"code": 746,
"name": "BANCO MODAL S.A."
},
{
"code": 748,
"name": "BANCO COOPERATIVO SICREDI S.A."
},
{
"code": 756,
"name": "BANCO COOPERATIVO DO BRASIL S/A - BANCOOB"
}
]
{
"code": 100,
"description": "Invalid credentials",
"type": "INVALID_CREDENTIALS"
}
This endpoint is used to retrieve and display to your customer the list of banks available on their country. In case we add or remove a bank, this endpoint will reflect those updates real-time and therefore it is a good idea to constantly check this endpoint for the list of banks.
Once the user selected their bank by its name, you need to send its code to us in the bank_code field of the requests.
The endpoint is read only and so it uses a read only key. It can be used from the front-end without major security concerns.
// URL
GET: https://api-stg.zimo-pagos.com/v3/banks?country=AR
// HEADERS
Authorization: Bearer EKiFOWiHnI
Type
Field
Format
Description
Query Param
country
String (length: 2)
Header
Authorization
String
Bearer Token Authentication. It is a concatenation of the word "Bearer" and your Read Only API Key.
[
{
"code": 1,
"name": "BANCO DO BRASIL S.A."
},
{
"code": 3,
"name": "BANCO DA AMAZONIA S.A."
},
{
"code": 4,
"name": "BANCO DO NORDESTE DO BRASIL S.A."
},
{
"code": 21,
"name": "BANESTES S.A. BANCO DO ESTADO DO ESPIRITO SANTO"
},
{
"code": 33,
"name": "BANCO SANTANDER BRASIL S.A."
},
{
"code": 37,
"name": "BANCO DO ESTADO DO PARA S.A. - BANPARA"
},
{
"code": 41,
"name": "BANCO DO ESTADO DO RIO GRANDE DO SUL S.A. - BANRISUL"
},
{
"code": 47,
"name": "BANCO DO ESTADO DE SERGIPE S.A. - BANESE"
},
{
"code": 70,
"name": "BANCO DE BRASILIA S.A. - BRB"
},
{
"code": 75,
"name": "BANCO ABN AMRO S.A"
},
{
"code": 77,
"name": "BANCO INTER"
},
{
"code": 85,
"name": "Cooperativa Central de Crédito Urbano-CECRED"
},
{
"code": 93,
"name": "POLOCRED SCMEPP"
},
{
"code": 104,
"name": "CAIXA ECONOMICA FEDERAL - CEF"
},
{
"code": 121,
"name": "BANCO AGIPLAN S.A."
},
{
"code": 136,
"name": "Confederação Nacional das Cooperativas Centrais Unicred"
},
{
"code": 212,
"name": "BANCO ORIGINAL"
},
{
"code": 218,
"name": "BANCO BONSUCESSO S.A."
},
{
"code": 237,
"name": "BANCO BRADESCO S.A."
},
{
"code": 260,
"name": "NU PAGAMENTOS"
},
{
"code": 290,
"name": "PagSeguro Internet S.A"
},
{
"code": 318,
"name": "BANCO BMG S.A"
},
{
"code": 336,
"name": "BANCO C6 S.A"
},
{
"code": 341,
"name": "ITAU UNIBANCO S.A."
},
{
"code": 389,
"name": "BANCO MERCANTIL DO BRASIL S.A."
},
{
"code": 399,
"name": "HSBC BANK BRASIL S.A. - BANCO MULTIPLO"
},
{
"code": 422,
"name": "BANCO SAFRA S.A."
},
{
"code": 477,
"name": "CITIBANK N.A."
},
{
"code": 637,
"name": "BANCO SOFISA"
},
{
"code": 655,
"name": "Banco Votorantim S.A."
},
{
"code": 707,
"name": "BANCO DAYCOVAL S.A."
},
{
"code": 712,
"name": "BANCO OURINVEST S.A"
},
{
"code": 735,
"name": "BANCO NEON"
},
{
"code": 745,
"name": "BANCO CITIBANK"
},
{
"code": 746,
"name": "BANCO MODAL S.A."
},
{
"code": 748,
"name": "BANCO COOPERATIVO SICREDI S.A."
},
{
"code": 756,
"name": "BANCO COOPERATIVO DO BRASIL S/A - BANCOOB"
}
]
Field
Format
Description
code
Number
Bank code. It is the value you must send in the field bank_code
of the cashouts and deposits requests
name
String
Name of the bank
Check the requirements and validations made over the cashouts on Argentina
Field
Format
Description
login
String
Cashouts login
pass
String
Cashouts pass
external_id
String (max length: 100)
Transaction's ID on your end
document_id
See
Beneficiary's document ID
country
AR
See
currency
ARS/USD
See
amount
Number with up to 2 decimals
Cashout amount
bank_code
bank code
Code specifying the beneficiary's bank
bank_account
bank account
Beneficiary's bank account
bank_branch
institute number
Beneficiary's institute number
email
email address
Beneficiary's email address
beneficiary_name
String (max length: 100)
Beneficiary's name
beneficiary_lastname
String (max length: 100)
Beneficiary's last name
Use the Regex below to validate the bank accounts on your end.
Bank name
Bank Description
Format
All
CBU -
Numeric, Length 22
Since the first three digits of the CBU are the bank code, it is not mandatory to send the bank_code field.
public class Validations {
static Integer CBU_LENGTH = 22;
public static Boolean verifyCBU(String cbu) {
return cbuLengthValidation(cbu) && bankCodeValidation(cbu) && accountValidation(cbu);
}
public static Boolean cbuLengthValidation(String cbu) {
return cbu.length() == 22 && ValidationsUtils.validateOnlyNumbers(cbu);
}
public static Boolean bankCodeValidation(String cbu) {
if (cbu.length() == CBU_LENGTH && ValidationsUtils.validateOnlyNumbers(cbu)) {
String shortCbu = StringUtils.left(cbu, 8);
String bankCode = shortCbu.substring(0, 3);
String branchCode = shortCbu.substring(4, 7);
int firstCheckDigit = charToInt(shortCbu.toCharArray()[3]);
int secondCheckDigit = charToInt(shortCbu.toCharArray()[7]);
int sum = charToInt(bankCode.charAt(0)) * 7 + charToInt(bankCode.charAt(1)) * 1 + charToInt(bankCode.charAt(2)) * 3 + firstCheckDigit * 9 + charToInt(branchCode.charAt(0)) * 7 + charToInt(branchCode.charAt(1)) * 1 + charToInt(branchCode.charAt(2)) * 3;
int diference = (10 - sum % 10) % 10;
return diference == secondCheckDigit;
} else {
return false;
}
}
public static Boolean accountValidation(String cbu) {
String account = cbu.substring(8, 22);
int sum = 0;
int j = 0;
int[] weighter = new int[]{3, 9, 7, 1};
char[] arrayAccount = account.toCharArray();
int checkDigit = charToInt(account.toCharArray()[13]);
for(int i = 0; i < 13; ++i) {
sum += charToInt(arrayAccount[i]) * weighter[j % 4];
++j;
}
int diference = (10 - sum % 10) % 10;
return diference == checkDigit;
}
private static int charToInt(char ch) {
return Integer.parseInt(String.valueOf(ch));
}
}
Click here to check document types and validations.
{
"login": "xxxxxxxx",
"pass": "xxxxxxxx",
"external_id": "30000000001",
"country": "AR",
"currency": "ARS",
"amount": 100,
"document_id": "5676586998",
"bank_account": "",
"bank_code": "10000",
"bank_branch": "",
"email": "[email protected]",
"beneficiary_name": "John",
"beneficiary_lastname": "Smith",
"notification_url": "https://webhook.site/url",
"type": "json"
}
A.B.N Amro Bank
005
Banco de Galicia Y Buenos Aires
007
Lloyds Tsb Bank
010
Banco de La Nación Argentina
011
Banco de La Provincia de Buenos Aires
014
Industrial and Commercial Bank of China (ICBC)
015
Citibank
016
BBVA Banco Frances
017
The Bank Of Tokyo - Mitsubishi
018
Banco de La Provincia de Cordoba
020
Superville Bank
027
Banco de La Ciudad de Buenos Aires
029
Banco Patagonia Sudameris
034
Banco Hipotecario
044
Banco de San Juan
045
Banco Do Brasil
046
Banco Del Tucuman
060
Banco Municipal de Rosario
065
Santander Río
072
Banco Regional de Cuyo
079
Banco Del Chubut
083
Banco de Santa Cruz
086
Banco de La Pampa
093
Banco de Corrientes
094
Banco Provincia Del Neuquen
097
Banco Empresario de Tucuman Coop.
137
Banco B. I. Creditanstalt
147
HSBC Bank Argentina
150
J P Morgan Chase Bank Sucursal Buenos Aires
165
Banco Credicoop Coop.
191
Banco de Valores
198
Banco Roela
247
Banco Mariva
254
Banco Itau Buen Ayre
259
Bank Of America
262
Banca Nazionale Del Lavoro
265
Bnp Paribas
266
Banco Provincia de Tierra Del Fuego
268
Banco de La República Oriental Del Uruguay
269
Banco Saenz
277
Banco Meridian
281
Banco Macro Bansud
285
Banco Mercurio
293
Ing Bank
294
American Express Bank Ltd.
295
Banco Banex
297
Banco Comafi
299
Banco de Inversión Y Comercio Exterior
300
Banco Piano
301
Banco Finansur
303
Banco Julio
305
Banco Privado de Inversiones
306
Nuevo Banco de La Rioja
309
Banco Del Sol
310
Nuevo Banco Del Chaco
311
M. B. A. Banco de Inversiones
312
Banco de Formosa
315
Banco CMF
319
Banco de Santiago Del Estero
321
Nuevo Banco Industrial de Azul
322
Deutsche Bank
325
Nuevo Banco de Santa Fe
330
Banco Cetelem Argentina
331
Banco de Servicios Financieros
332
Banco Cofidis
335
Banco Bradesco Argentina
336
Banco de Servicios Y Transacciones
338
Rci Ba
339
Bacs Banco de Crédito Y Securitización
340
Nuevo Banco de Entre Rios
386
Nuevo Banco Suquia
387
Nuevo Banco Bisel
388
Banco Columbia
389
Learn how to generate cashouts request by using our Cashout API v3 directly from your website
POST
https://api-stg.zimo-pagos.com/v3/cashout
This endpoint allows you to generate cashout requests
Content-Type*
string
application/json
Payload-Signature*
string
Control signature
login*
string
Your Zimo-pagos CASHOUTS API login key
pass*
string
Your Zimo-pagos CASHOUTS API pass key
external_id*
string
Unique cashout ID on the merchant end
country*
string
Country of the cashout
amount*
number
Amount of the cashout
currency
string
Currency in which the amount was specified
document_id*
string
Document ID of the beneficiary
document_type
string
Document type of the ID specified
beneficiary_id
string
beneficiary id (for anonymous)
beneficiary_name*
string
Beneficiary's name
beneficiary_lastname
string
Beneficiary's last name
string
Beneficiary's email address
phone
string
Beneficiary's phone number
bank_code
number
Beneficiary's bank code
bank_account
string
Beneficiary's bank account
bank_branch
string
Beneficiary's branch of their bank account
account_type
string
Beneficiary's account type
address
string
Beneficiary's address
city
string
Beneficiary's city
postal_code
string
Beneficiary's postal code
beneficiary_birthdate
string
Beneficiary's birthdate
notification_url*
string
URL where the notifications will be sent
comments
string
Commentaries about the cashout
on_hold
boolean
Used to mark a cashout as on hold and not process it until manually changed to pending by you
{
"cashout_id": "8405147"
}
{
"code": 303,
"message": "Invalid bank code"
}
{
"code": 300,
"message": "bank_account: must not be null; Invalid Bank account"
}
{
"code": 504,
"message": "User unauthorized due to cadastral situation",
"reason": "Underage user detected",
"reason_code": 105
}
login
string (max length: 32)
Your Zimo-pagos CASHOUTS API Key, found on the Merchant Panel by going to: Settings -> API Access. Notice there are specific Cashout credentials
pass
string (max length: 32)
Your Zimo-pagos CASHOUTS API Passphrase, found on the Merchant Panel by going to: Settings -> API Access. Notice there are specific Cashout credentials
external_id
string (max length: 100)
Unique cashout ID on the merchant end
country
string (length: 2)
Country code for the cashout in ISO 3166-1 alpha-2 code format
amount
Big Decimal (up to 2 decimals)
Cashout amount on the currency specified
Valid number
currency
string (length: 3)
Currency code of the amount in ISO 4217 format
document_id
string (max length: 40)
Beneficiary’s personal identification number
document_type
string (maxLength: 15)
Beneficiary’s personal identification number type
beneficiary_name
string (max length: 100)
Beneficiary's name
String of up to 100 characters
beneficiary_lastname
string (max length: 100)
Beneficiary's last name
String of up to 100 characters
string (maxLength: 100)
Beneficiary's valid email address
phone
string (maxLength: 20)
Beneficiary's phone number
bank_code
Integer (max length: 6)
Beneficiary's bank code
bank_account
string (max length: 30)
Beneficiary's bank account number
bank_branch
string (max length: 15)
Beneficiary's bank branch number
account_type
string (max length: 1)
Type of account
address
string (max length: 255)
Beneficiary's address
String of up to 200 characters
city
string (max length: 100)
Beneficiary's city
String of up to 100 characters
postal_code
string (max length: 20)
Beneficiary's postal code
beneficiary_birthdate
string (pattern: 'YYYYMMDD')
Beneficiary's birthdate
notification_url
string (max length: 300)
To be provided if the notification URL is different from the notification URL defined on the Merchant Panel
Valid URL over HTTPS
comments
string (max length: 200)
A commentary for this cashout
String of up to 200 characters
on_hold
boolean
If the merchant wants to hold the cashout and set it to process later through the merchants panel. Default: false
[true, false]
code
Number
Error code. See the
message
String
Description of the error
reason
String
Reason description for KYC check failure. See the . *Only shown in case of code 504
reason_code
Number
Reason code for KYC check failure. See the . *Only shown in case of code 504
{
"code": 300,
"message": "bankAccount: Invalid or missing Bank account"
}
{
"code": 303,
"message": "Invalid bank code"
}
{
"code": 504,
"message": "User unauthorized due to cadastral situation."
"reason": "Underage user detected",
"reason_code": 105
}
Each country has different requirements and therefore we ask for different fields you need to send on the requests.
Go to the Countries Validations page to check each country requirements and validations.
In Mexico, we accept cashouts sent directly to debit cards.
When that happens, you need to send the request through a different endpoint, otherwise your request will be declined with Invalid bank account, it shouldn't be a credit card
.
PROD endpoint for Debit Cards: Email [email protected] with your cashout API Key
STG endpoint for Debit Cards: https://cc-api-stg.zimo-pagos.com/v3/cashout
The bank accounts in Mexico are in CLABE format (numeric) and have 18 digits (without dashes). Therefore one way to detect that a bank account specified by the customer is a debit card is by checking with the luhn algorithm if it is a valid card number and/or with a regex for each brand, like the example below.
public static final String SENSIBLE_DATA_PATTERN = new StringBuilder("(?:(?<visa>4[0-9]{12}(?:[0-9]{3})?)")
.append("|(?<mastercard>5[1-5][0-9]{14})")
.append("|(?<discover>6(?:011|5[0-9]{2})[0-9]{12})")
.append("|(?<amex>3[47][0-9]{13})")
.append("|(?<diners>3(?:0[0-5]|[68][0-9])?[0-9]{11})")
.append("|(?<jcb>(?:2131|1800|35[0-9]{3})[0-9]{11}))")
.toString();
private boolean validateCreditCard(CashoutRequestDto request) {
final String bankAccount = request.getBank_account();
if (StringUtils.isEmpty(bankAccount) || !LuhnCheckDigit.LUHN_CHECK_DIGIT.isValid(bankAccount) ||
bankAccount.matches(Constants.SENSIBLE_DATA_PATTERN)) {
return false;
}
return true;
}
If true, send the request through the cc-api
endpoint, if false send it through the normal endpoint. The integration and requirements remains exactly the same, only changing the error message returned in case of invalid bank account and that we validate the bank_account
sent to be a valid credit card number using the Luhn Algorithm.
Sending a debit card number through the non-cc endpoint will make the request to fail with the following error:
{
"code": 300,
"message": "bank_account: Invalid bank account, it shouldn't be a credit card"
}
Invalid bank_account error on the cc-api endpoint:
{
"code": 300,
"message": "bankAccount: invalid credit card number"
}
Learn about the API Codes returned by our Cashouts APIs
0
The cashout was accepted by Zimopagos but it wasn't sent to the bank yet. It can still be Canceled. See
1
The money reached the customer's account
2
The cashout was cancelled by you
3
The cashout was rejected by the bank due to invalid bank account, account closed, etc.
4
The cashout was sent to the bank for processing. At this point it can't be cancelled anymore
5
Cashout set to on hold by you. It won't be processed until manually changed again to Pending status
The error information is the one (if) provided by the Bank.
800
ERROR_ACCOUNT_INCORRECT
Invalid bank account
801
ERROR_ACCOUNT_CLOSED
Bank account is closed
802
ERROR_AMOUNT_INCORRECT
Invalid amount
803
ERROR_BANK_INVALID
Invalid bank code
804
ERROR_BANK_BRANCH_INCORRECT
Invalid bank branch
805
ERROR_BENEFICIARY_DOCUMENT_ID_INVALID
Invalid beneficiary document
806
ERROR_BENEFICIARY_NAME_INCORRECT
Beneficiary name doesn't match bank details
807
ERROR_REJECTED_BY_BANK
Rejected by bank
808
ERROR_OTHER
Other error
809
WITHDRAWAL_EXPIRED
Withdrawal expired
810
LIMIT_EXCEEDED
Beneficiary limit exceeded
811
RISK_POLICY
Violates bank risk policy
812
BLOCKED_FROZEN_ACCOUNT
Bank account blocked/frozen
813
DOCUMENT_ACCOUNT_MISMATCH
Beneficiary document doesn't match bank details
814
INVALID_PIX_KEY
Invalid Pix Key
815
INVALID_IFSC_CODE
Invalid IFSC code
816
INVALID_ACCOUNT_OR_IFSC_CODE
Invalid bank account or IFSC code
817
INVALID_NBIN
Invalid NBIN
818
ACCOUNT_UNABLE
The bank account is unable to receive transfers
819
INVALID_ACCOUNT_TYPE
Invalid bank account type
820
REJECTED_BY_MERCHANT_REQUEST
Rejected by merchant's request
821
MONTHLY_LIMIT_EXCEEDED_FOR_USER
Monthly limit exceeded for user
822
ACCOUNT_NAME_REQUIRED_TO_BE_IN_KATAKANA
Account name required to be in Katakana
824
REJECTED_BY_THIRD_PARTY_CONTROL
Rejected by third party control
826
WITHDRAWAL_REVERSED
Withdrawal reversed
300
Invalid params + [param name] + [reason]
302
Invalid control string.
303
Invalid bank code
401
Invalid credentials
402
Unregistered IP address (Go to API Access to whitelist the IP in the Merchant Panel)
502
Invalid request body - Please check that the JSON is well formatted
503
The transaction cannot be completed due to regulatory limits applied to the beneficiary account.
504
User unauthorized due to cadastral situation.
508
Limit exceeded: {TRANSACTION|DAILY|MONTHLY|USER MONTHLY QUANTITY}
509
Cashout not found with this ID
510
Invalid status: cashout is not Pending
511
External ID already used
514
Insufficient funds
515
Invalid user status: {BLACKLISTED|BLOCKED|SUSPENDED}
518
Country not available
519
Merchant not enabled. Contact your Account Manager
524
Invalid Credentials. Contact [email protected]
525
Close loop rejection
526
Invalid currency
533
Invalid Amount. The minimum amount is {currency} {amount} or equivalent in USD
537
Could not make the cashout. Contact [email protected]
538
Invalid account status: {BLACKLISTED}
539
Payout method unavailable. The country and/or bank selected is not available. Please check with your Account Manager
540
Beneficiary email or phone is required
541
email already used by another beneficiary
542
phone already used by another beneficiary
543
must be a
702
Could not cancel cashout
703
Could not make the cashout. Contact [email protected]
101
400
USER_REJECTED_KYC_CHECK
Transaction related to blacklisted user.
The transaction was rejected because one of its attributes was related to a blacklisted user
102
400
USER_REJECTED_KYC_CHECK
Email risk
High risk detected by our fraud prevention engine related to the user's email address
103
400
USER_REJECTED_KYC_CHECK
Credit card risk
High risk detected by our fraud prevention engine related to the credit card used
104
400
USER_REJECTED_KYC_CHECK
User rejected after KYC check
User rejected by our KYC controls
105
400
USER_REJECTED_KYC_CHECK
Underage user detected
User does not meet the minimum age requirement
106
400
USER_REJECTED_KYC_CHECK
Mismatch between user name and document name
The user's name does not match the name associated with the document provided
107
400
USER_REJECTED_KYC_CHECK
Document status is not OK
Some irregularities have been detected while validating the document information
108
400
USER_REJECTED_KYC_CHECK
PEP user detected
The user is a Politically Exposed Person (PEP)
109
400
USER_REJECTED_KYC_CHECK
High risk detected
High risk detected by our fraud prevention engine
110
400
USER_REJECTED_KYC_CHECK
Failed biometric check
Something went wrong while performing the biometric check on the user
111
400
USER_REJECTED_KYC_CHECK
Failed OTP verification
Something went wrong while performing the OTP check on the user
112
400
USER_REJECTED_KYC_CHECK
3DS Authentication failed
Transaction rejected due to failed 3DS
113
400
USER_REJECTED_KYC_CHECK
Document does not exist
Invalid Document
114
400
USER_REJECTED_KYC_CHECK
User rejected after CNPJ validations
Invalid/Irregular CNPJ (Brasil Only)
115
400
USER_REJECTED_KYC_CHECK
Invalid document format
Format of the provided document is invalid. (Mexico Only)
116
400
USER_REJECTED_KYC_CHECK
Regulatory reasons
Rejected due to regulatory reasons
The error information is the one (if) provided by the Bank.
510
Invalid status transition
Status transition does not meet cashout status workflow
509
Cashout not found with this ID
There is no cashout under provided ID
521
Status ... not supported for this type of request
Provided Status does not exist
Create refunds requests from a completed deposit
POST
https://api-stg.zimo-pagos.com/v3/refunds
This endpoint allows you to create a full or a partial refund over a completed deposit.
The refunds
endpoint allows you to create a full/partial(depending on the market) refund over a Credit Card deposit in completed state or full/partial refunds over other payment methods' deposits in completed state.
In the case of credit cards, since the refund will be processed to the same card, all you need to send are the fields to identify the deposit.
In the case of other payment methods where we don't have the account of the payer, you need to send the beneficiary's ID, bank account details and bank code retrieved with the
You can create as many refunds as needed over a completed deposit, as long as the total amount of those refunds doesn't exceed the original amount deposited.
In order to start creating refunds, you need to:
Send the request with POST method.
Use the headers described .
Specify a valid deposit_id
and invoice_id
related to the deposit to be refunded.
Send the Authorization header calculated in the same way than for deposits, as .
Send the body of the request as JSON.
bank_account
ObjectWhen the refund is made over a CREDIT CARD deposit, it might be (depending upon availability) completed instantaneously, and so all the details of the refund are returned.
In case the result is SUCCESS, it means the refund was successfully created and the user should receive the money back into their card soon.
In case the result is REJECTED, the response of the API will return two fields called reason
and reason_code
providing more information about the rejection reason.
In case the result is IN_PROGRESS, it means the refund will be processed asynchronously and so a notification will be sent to the notification_url
specified at the time of creating the refund as soon as it gets completed or rejected. for more information about the notifications of the refunds.