You must implement and expose the “Authorization” and “ Adjustments” endpoints on your backend so that we can communicate.
Every time a user uses their card in any online or physical store.
When the network (Mastercard, Visa, etc.) requests reconciliation of all payments presented by merchants.
If there is a discrepancy in the reconciliation, we will request a correction to your API. We expect a quick response to ensure a good experience. If the response is delayed, reject the transaction.
Since an HTTP request can time out, make sure that it is processed only once when retrying. We’ll send you an x-idempotency-key header with a unique ID with each request for that purpose. Process with a cache in memory (for example: redis).
At the beginning of each transaction, check if the idempotency key we sent you is already in the in-memory cache and do the following:
Cache in memory the idempotency key → request with a in-transit status with a TTL of 3 minutes.
When you approve or reject the transaction, you’ll need to cache the result and update the idempotency key status to ‘finished’.
In case of a duplicate request, you will need to check the transaction status in the cache.
finished
status, respond with an HTTP code 200 with the expected body for the endpoint and complete it with the cache result.in-transit
status you will need to respond with an HTTP code 425 (Too Early: RFC 8470) with the expected body for the endpoint. We’ll look for the response to this request again a few milliseconds later.If you receive a second request with the same idempotence ID and the first is still in progress, you should respond with an HTTP status 425 and an empty body.
The communication between our backends must be strictly secure since the endpoints will allow crediting and deducting funds.
For this purpose, we require you to implement three measures:
All communication with us must be via HTTPS, regardless of who issues the certificate.
These are some of the most recognized providers
We always communicate with your backend from specific IPs. We recommend that you only accept requests from the following IPs and reject any others:
Pomelo IPs:
34.226.254.178
44.198.3.59
34.223.185.46
100.20.205.117
34.206.159.176
52.0.20.124
35.84.78.117
52.43.46.111
To ensure that the only participants in the communication are our backends (Pomelo and the Client), we provide you with an api-key and api-secret during onboarding to digitally sign the content of the communication.
The process looks something like this:
api-key
and api-secret
keys.During a payment authorization, Pomelo signs each authorization request with hmac-sha256 using the api-secret
.
api-key
.api-secret
.During the onboarding process, we create an api-key and api-secret specific to you.
It is also possible to use gpg or an email plugin (such as https://flowcrypt.com/).
Let’s look at an example using openssl on the command line.
$ echo -e 'api-key=$(openssl rand -base64 32)\napi-secret=$(openssl rand -base64 32)' > api-credentials.txt
$ cat api-credentials.txt
api-key=tgeAkX0795jKTxrVR0cJbb//D8UlhHn0KZwTcDG3gyg=
api-secret=un/OHwD+fMN1TTSaEhs0vupQEDQS7DVaUdlNOu7Fpyw=
$ openssl genrsa -out private.pem 2048
$ openssl rsa -in private.pem -pubout -out public.pem
public key
by email or Slack.$ openssl rsautl -encrypt -in api-credentials.txt -out api-credentials.txt.enc -inkey public.pem -pubin
api-credentials.txt.enc
file by email or Slackapi-credentials.txt.enc
file with your private.pem private key
:$ openssl rsautl -decrypt -in api-credentials.txt.enc -inkey private.pem
api-key=tgeAkX0795jKTxrVR0cJbb//D8UlhHn0KZwTcDG3gyg=
api-secret=un/OHwD+fMN1TTSaEhs0vupQEDQS7DVaUdlNOu7Fpyw=
api-secret
in a safe place that is accessible only through the “Authorize payments” application, associated with the api-key
.Along with the authorization or adjustment request we’ll send you HTTP headers with the signature, timestamp and the api-key so that you can verify the signature is correct.
The HTTP headers we send are:
x-api-key
: this header allows you to identify which api-secret you have to use in the event that multiple api-key and api-secret pairs have been configured.
x-signature
: This header contains the digital signature (body + timestamp + endpoint) that must be verified to ensure request integrity. If the signature does not match, reject the order.
x-timestamp
: this header contains the moment the order was signed in unix-epoch format so that you can verify that the signature has not expired.
x-endpoint
: the endpoint to which the request is made. Use this header to regenerate the signature to be validated, check with your service endpoint and confirm that they match.
Important: In addition to checking the signature that we send you, when generating the response, you must sign the body along with the timestamp and the response endpoint with your api-secret
after impacting the operation. Please note that the signature will be validated and the transaction rejected if the signature does not match or has expired.
You can test the implementation of your backend with some typical operations that we will send with a Postman collection, which is included in our [public sample repository] (https://github.com/pomelo-la/cards-transactions-examples). You can import the collection to a Postman instance and thus simulate real orders to your backend, including the signature generation and checking algorithm.
In the repository, you will also find examples of implementation of the signature generation and validation algorithm in several languages.
This is an optional process, but we recommend running it daily.
In the SFTP server that we will provide, you will find these files:
Contains the details of each transaction from the previous day.
El nombre del archivo tiene el siguiente formato: transaction_yyyy-mm-dd_<nombre cliente>_<pais>.csv
{Atributo} | Description | Allowed values |
---|---|---|
TRANSACTION_ID | Unique ID to identify the transaction. | |
LOCAL_TRANSACTION_DATE_TIME | ||
TRANSACTION_TYPE | Indicates the transaction type. | PURCHASE WITHDRAWAL EXTRACASH BALANCE_INQUIRY REFUND PAYMENT REVERSAL_PURCHASE REVERSAL_WITHDRAWAL REVERSAL_EXTRACASH REVERSAL_REFUND REVERSAL_PAYMENT |
PRODUCT_TYPE | This is the product type | PREPAID CREDIT DEBIT |
PROVIDER | It is the brand of the issued card. | VISA MASTERCARD |
AFFINITY_GROUP_ID | ||
USER_ID | Pomelo cardholder’s user ID. | |
CARD_ID | ||
BIN | The first six or eight digits of the PAN. | |
LAST_FOUR | The last four digits of the PAN. | |
ORIGIN | DOMESTIC: The transaction occurred in the issuer’s country. INTERNATIONAL: The transaction was not made in the issuer’s country. | |
MERCHANT_ID | ||
MERCHANT_MCC | The merchant category code as defined in ISO-18245. | |
MERCHANT_NAME | ||
LOCAL_AMOUNT | This is the total transaction amount that must be deducted from the user's balance, with taxes and fees added (where applicable). Always converted to the card's local currency. | |
LOCAL_CURRENCY | The LOCAL_TOTAL currency code in ISO_4217 ALPHA-3 format. | |
TRANSACTION_AMOUNT | The transaction value before taxes and in the original currency sent by the merchant. | |
TRANSACTION_CURRENCY | The TRANSACTION_TOTAL currency code in [ISO_4217] (https://en.wikipedia.org/wiki/ISO_4217#Active_codes) formato ALPHA-3. | |
SETTLEMENT_AMOUNT | The transaction amount in USD, as sent by the network. For Argentina always show it in USD, and in the local currency for the other countries. | |
SETTLEMENT_CURRENCY | The currency code of SETTLEMENT_TOTAL in ISO_4217 ALPHA-3 format. For Argentina always show it in USD, and in the local currency for the other countries. | |
ENTRY_MODE | How the card was used at the merchant's point of sale. | UNKNOWN MANUAL CHIP CONTACTLESS CREDENTIAL_ON_FILE MAG_STRIPE OTHERS |
STATUS | Transaction status. | APPROVED REJECTED HELD |
STATUS_DETAIL | Additional reason why the transaction is approved or rejected. | See table below |
SOURCE | Indicates which flow/process triggered the transaction, as seen from Pomelo. | ONLINE: Originated during transactional flow from real-time transactions sent over the network CLEARING: Originated during the agreement process between Pomelo and the network when managing the settlement file PURGE: Transactions that were not presented in the network settlement file. |
ORIGINAL_TRANSACTION_ID | This value may be empty if the transaction is not related to another. | |
COUNTRY_CODE | This is the country code in [ISO-3166] format (https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes). | |
POINT_TYPE | POS ECOMMERCE ATM MOTO | |
CLIENT_NAME | El nombre del cliente que aprueba o rechaza la transacción, dado que el reporte se segmenta por cliente, va a tener el mismo valor para todas las filas | |
CLIENT_COUNTRY_CODE | El coódigo de país del cliente en formato ISO-3166 | |
AMOUNT_DETAILS | El detalle de la composición del monto local, en el mismo formato que es enviado de forma ONLINE. Codificado en base64 | |
INSTALLMENTS_GRACE_PERIOD | [OPCIONAL*] El período de gracia refiere a la cantidad de meses previo a que comiencen los pagos en cuotas. Puede ir de 0 a 99. | |
INSTALLMENTS_QUANTITY | [OPCIONAL*] La cantidad de cuotas | |
INSTALLMENTS_CREDIT_TYPE | [OPCIONAL*] El tipo de crédito otorgado | NO_PROMOTION WITHOUT_INTEREST WITH_INTEREST BUY_TODAY_PAY_LATER |
*_Para los clientes que operen con crédito, se agregan los datos del contrato de cuotas.
Status detail | Description |
---|---|
CARD_BLOCKED | The card status is BLOCKED. |
CARD_DISABLED | The card status is DISABLED |
CARD_NOT_ACTIVE | The card status is EMBOSSED or CREATED |
CARD_NOT_CONFIGURED | The card is missing configurations. |
CARD_NOT_FOUND | We cannot find the card’s PAN. |
CLIENT_TIMEOUT | The client is slow to respond. |
CLIENT_UNAVAILABLE | We cannot connect to the client or we receive a 5XX. |
CLIENT_SIGNATURE_ERROR | When there is a failure in the client's signature. |
CRYPTO_ERROR | There is a cryptogram error (EMV). |
DUPLICATE_TRANSMISSION_DETECTED | We received a repeated transaction from the network. |
EXPIRED_CARD | The card status is EXPIRED. |
EXTRA_FIELDS | Messaging from the network comes with unexpected fields. |
INSUFFICIENT_FUNDS | The client replies that the account has no funds. |
INTERNAL_ERROR | Unexpected failure in the Pomelo system. |
INVALID_AMOUNT | The affinity group’s limits are exceeded. |
INVALID_CVV | The CVV does not match. |
INVALID_EXPIRATION_DATE | The expiration date received does not match the card. |
INVALID_MERCHANT | The customer rejects the merchant for a specific reason. |
INVALID_PIN | The PIN is incorrect |
PIN_TRY_LIMIT_EXCEED | Se ha ingresado incorrectamente el PIN y se excedio el limite de intentos. |
INVALID_TRANSACTION | The transaction is invalid. |
LOST_CARD | The card status is LOST. |
MISSING_FIELDS | Messaging from the network comes without the required fields. |
NOT_DECLINED | A transaction has a value of 0, verifying the account is active. |
ORIGINAL_NOT_FOUND | An attempt is made to reverse a transaction that we did not find. |
OTHER | The case is not recognized. |
RESTRICTED_USER | The user's status is not ACTIVE. |
SECURITY_VIOLATION | Exceeds a fraud threshold. |
SERVICE_UNAVAILABLE | The client or a Pomelo service is down. |
STOLEN_CARD | The card’s status is STOLEN. |
SYSTEM_ERROR | Client's unexpected error. |
APPROVED | The client approves a transaction. |
TRANSACTION_NOT_PERMITTED | The transaction type is not allowed in the affinity group. |
REJECTED_FRAUD | The transaction was rejected by the fraud engine. |
Is it at Pomelo? | Is it at the client? | Does it have the same status? | Action |
---|---|---|---|
Y | Y | Y | Do nothing / Mark as matching |
Y | Y | N | 1) Register an adjustment that debits/credits the end user if applicable. 2) Mark as matching. |
Y | N | N | 1) IF STATUS == APPROVED: Register an adjustment that debits/credits the end user if applicable. 2) Mark as matching. |
N | Y | N | It is not a possible use case. |
If you are trying to adjust a credit to an end user who does not have sufficient funds in their account, keep trying to get the funds from that user.
It becomes a debt between the customer and the end user.
Contains the details for each transaction that traders submitted the previous day.
El nombre del archivo tiene el siguiente formato: presentment_yyyy-mm-dd_<nombre cliente>_<pais>.csv
Attribute | Description | Allowed values |
---|---|---|
PRESENTMENT_ID | ||
TRANSACTION_ID | The original transaction ID the presentation generated. | |
LOCAL_TRANSACTION_DATE_TIME | ||
TRANSACTION_TYPE | Indicates the transaction type. | PURCHASE WITHDRAWAL EXTRACASH REFUND PAYMENT |
PRODUCT_TYPE | This is the product type. | PREPAID CREDIT DEBIT |
PROVIDER | It is the brand of the issued card. | VISA MASTERCARD |
AFFINITY_GROUP_ID | ||
USER_ID | Pomelo cardholder’s user ID | |
CARD_ID | ||
BIN | The first six or eight digits of the PAN. | |
LAST_FOUR | The last four digits of the PAN. | |
ORIGIN | DOMESTIC: The transaction occurred in the issuer’s country. INTERNATIONAL: The transaction was not made in the issuer’s country. | |
MERCHANT_ID | ||
MERCHANT_MCC | The merchant category code as defined in ISO-18245. | |
MERCHANT_NAME | ||
TRANSACTION_AMOUNT | The transaction value before taxes and in the original currency sent by the merchant. | |
TRANSACTION_CURRENCY | The TRANSACTION_TOTAL currency code in [ISO_4217] (https://en.wikipedia.org/wiki/ISO_4217#Active_codes) formato ALPHA-3. | |
SETTLEMENT_AMOUNT | The transaction value presented by the brand. | |
SETTLEMENT_CURRENCY | The currency code of SETTLEMENT_AMOUNT in ISO_4217 ALPHA-3 format. For Argentina always show it in USD, and in the local currency for the other countries. | |
DEBT_AMOUNT | The transaction value in the currency to be paid to Pomelo. If the sum is to be paid to Pomelo, it is always a positive value; otherwise, it will be negative. | |
DEBT_CURRENCY | The DEBT_AMOUNT currency code in ISO_4217 ALPHA-3 format. If it is a domestic transaction it must be paid in local currency, otherwise in USD. | |
RECONCILIATION_DATE | ||
INTERCHANGE_FEE | Transaction commission to be applied to the exchange. | |
INTERCHANGE_RATE | Alphanumeric value that identifies the transaction exchange rate presented by the purchaser. | |
TAX | This is the exchange rate tax in accordance with local regulations. These values must have VAT calculated. | |
FUNCTION_CODE | This is the presentation type. | FIRST_PRESENTMENT SECOND_PRESENTMENT_FULL SECOND_PRESENTMENT_PARTIAL |
REVERSE_PRESENTMENT | This means that the presentation was reverted from the network. | TRUE FALSE |
REASON_CODE | Reason for the second presentation. | |
ICA_ACQUIRER | ||
TAX_ID | ID asociado a los impuestos de la transacción | |
INSTALLMENTS_GRACE_PERIOD | [OPCIONAL*] El período de gracia refiere a la cantidad de meses previo a que comiencen los pagos en cuotas. Puede ir de 0 a 99. | |
INSTALLMENTS_QUANTITY | [OPCIONAL*] La cantidad de cuotas | |
CURRENT_INSTALLMENT | [OPCIONAL*] Indica qué número de cuota está pagando el cliente. | |
INSTALLMENTS_CREDIT_TYPE | [OPCIONAL*] El tipo de crédito otorgado | NO_PROMOTION WITHOUT_INTEREST WITH_INTEREST BUY_TODAY_PAY_LATER |
USD_EXCHANGE_RATE | Which will indicate the exchange rate of Banco Nación at the close of the previous day | |
DEBT_AMOUNT_ARS | The amount of the debt expressed in ARS, multiplying the exchange rate for the amount of the debt amount. In case the Debt Amount is already in ARS, the multiplication is not performed |
*_Para los clientes que operen con crédito, se agregan los datos del contrato de cuotas.
Our finance team will send daily notifications for the debt owed. This will include all presentations we receive in the presentation file.
There is an SFTP server from which you can download Transaction and Presentation files.
Pomelo has two environments for SFTP servers, production and development.
To connect to the SFTP servers, first send a public key to create a user.
Here is the data to connect to each environment:
Host: sftp.pomelo.la
Port: 22
User: <tu_usuario> # the one created from your public keys.
Host: sftp-dev.pomelo.la
{Puerto}: 22
User: <tu_usuario> # the one created from your public keys.
To create a public key, use the command applicable to your operating system:
$Cliente
to the proper namessh-keygen -t rsa -b 2048 -C $Cliente
The command will create a 2048-bit RSA key pair by default. You can also create a larger 4096-bit key by entering -b 4096.
The command produces this output:
Generating public/prive rsa key pair.
Enter a file to save the key (/your_home/.ssh/id_rsa):
Press Enter
to save the key pair in .ssh /, or specify another location.
Press Enter
to leave it blank and use the key only to establish SSH connections. Enter a password for an additional layer of security.
cat ~/.ssh/id_rsa.pub
The key generated will start with ssh-rsa.
You can now copy and paste your public SSH key into your Shell console, or any server, to establish a secure connection.
Create SSH keys using PuTTY. Install PuTTY from the developer page: https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
Install PuTTY from the developer page: https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html
PuTTYgen
.Run as administrator
.Yes
if the system asks you Do you want to allow this app to make changes to your device?
While the PuTTY keygen tool offers several other algorithms, here is how to create RSA keys, one of the most often used:
Build
.Save Public Key
button. Then choose a location to save the key and assign a name to it.Conversions
menu at the top.Yes
.The /transactions/authorizations endpoint allows you to authorize transactions.
A request to authorize or reject the transaction will be sent.
We expect a quick response to ensure a good experience. If the response is delayed, reject the transaction.
The /transactions/adjustments/{type}
endpoint allows you to make credit and debit adjustments to transactions.
A request informing you that the network (MC, VISA) forced an authorization will be sent.
This endpoint is used during reconciliation and online flows, mainly to make adjustments during the settlement process and also in the event of returns.
This service allows notifications when a transaction is resolved, either by Pomelo or by the brand (Mastercard, Visa, etc.).
We are waiting for a 2XX response to ensure the notification was received. Otherwise, we will send it again.