Operations and errors
Environments, go-live checklist, usage limits, errors by endpoint and downloads for the Integration API.
The reference data for running your integration: environments, limits, errors and downloads.
Environments and URLs
Your integration has two environments, Sandbox and Production, with their own credentials. You manage both from the same portal, chytapay.com.ar/portal/login, with the environment selector.
| Service | Sandbox | Production |
|---|---|---|
| Integration API (charges, bulk, payer-lookup) | https:// |
https:// |
Auth API (OAuth: /) |
https:// |
https:// |
| Widget publishable key | pk_ |
pk_ |
The Integration API mounts its routes at the root: /payment-request, /payment-request/bulk and /payer-lookup. The widget uses /v1/payments on the same host.
Test tokens, the test webhook and payment simulation exist only in Sandbox. In Production, livemode is true only for a real payment.
Going live
You request Production under Credenciales (Credentials): if the automatic check approves it, you generate the production credentials with the environment selector on Production, and if not, the request goes to review. Nothing from Sandbox carries over. Before you collect, check:
- Credentials. Generate them under Credenciales (Credentials) and use your production
clientIdandclientSecretagainstauth-api.chytapay.com.ar, and thepk_liveif you use the widget (thesk_liveonly if you create charges through/v1/payments). - Linked merchants. Sandbox links don't exist in production: each merchant repeats the OAuth flow in Connect merchant accounts.
- Webhooks. Set the URL under Configuración (Settings) with the environment on Production, verify the signature with the production secret, and enable
payment.unmatchedif you need it, since it's opt-in. See delivery guarantees and subscriptions. - Errors. Handle 409, 429 and timeouts with the retries table.
- Tokens and events. Renew each merchant account's
idTokenwith therefreshTokenbefore the hour is up, deduplicate byX-Chytapay-Webhook-Idand return2xxwithin 5 seconds.
Retries on your side
There is no idempotency key. The referenceId prevents duplicates: it's unique per integration and merchant account, canceled charges included.
| Situation | What to do |
|---|---|
| Timeout or 5xx on a create | GET /: on 404, retry with the same referenceId. |
409 ReferenceId |
It was already created. Retrieve it with GET; don't generate a new referenceId. |
| 429 on create or bulk | Don't retry in a loop: wait until 00:00 Argentina time. A bulk that doesn't fit entirely under the cap creates nothing. |
| Timeout or 5xx on a bulk | Retrieve one referenceId from the batch with GET: bulk is all or nothing. |
| 422 on a retried bulk | If the reason is The referenceId already exists for this integration, the earlier batch was created. |
| 503 on payer-lookup | ARCA didn't respond. Retry, or continue without validating the payer. |
The create example with timeout and 409 is in Create charges.
Limits
The only daily cap when creating charges is the WhatsApp message cap. There is no cap on requests or on charges created per day. It resets at 00:00 Argentina time (UTC-3).
| Cap | Value | When exceeded |
|---|---|---|
| Your integration's messages | Per integration, all its merchants added together: 20 per day in Sandbox and 200 initial per day in Production. Raise it with Pedir más límite (Request more limit), on the portal Dashboard. | 429 Integration |
| Messages shared across integrations | One global daily cap | 429 Integration |
What counts as a WhatsApp message
Each charge created with sendWhatsappNotification: true counts as one message. Charges that don't ask for a WhatsApp notification don't use the cap. A bulk that doesn't fit entirely under the cap creates nothing.
The 429 response from the message caps
The body carries code (which of the two caps) and message. Your integration's cap adds availableAt (the reset, in Argentina time), maxRequestsPerDay and maxMessagesPerDay. The global one adds requestedMessages and availableAtUnixSeconds (the reset, in Unix seconds). If the cap can't be checked, create and bulk answer 503 IntegrationDailyLimitUnavailableError: retry in a few minutes. The reset is at 00:00 Argentina time: don't retry in a loop, wait until then. With parallel creates near the cap, a charge can be created even though it returned 429: check with GET before recreating it.
Other limits
| Limit | Value | When exceeded |
|---|---|---|
| Items per bulk | 1 to 100 per call | 400 Validation |
| CVU pool, per merchant account | Up to 100 per merchant account | 400 Insufficient |
Payer-lookup
GET /payer-lookup?document= has its own quota, separate from the creation caps: 1000 units per day, per integration and merchant account, reset at 00:00 Argentina time. A CUIL or CUIT costs 1 and a DNI costs 2, because Chytapay queries ARCA for both possible CUILs. When exceeded, 429 PayerLookupDailyLimitExceededError.
- Don't consume: a 400 for an invalid
document, and a 503 answered without querying ARCA. - Do consume: a 200 with
name: null, and a 503 because ARCA didn't respond. - The 429 includes
code,message,availableAtUnixSeconds(the reset, in Unix seconds) andmaxLookupsPerDay(1000).
See how to validate the payer.
CVU pool
The pool belongs to the merchant account, is shared by all its integrations and is taken up by the CVUs of open charges. If no CVU is free, create and bulk return 400 InsufficientActiveAccountsError and create nothing. When a charge closes, its CVU goes back to the pool. See how this affects each mode in Reconciliation.
Errors by endpoint
Decide by the HTTP status, then by code or error, never by the text of message. The tables follow the OpenAPI spec.
Show the error body shapes
Error body format
There is no request id header. The id comes in the body, only in the general shape: log it. Most messages are in English.
| Body shape | When |
|---|---|
{ code, message, id } |
General shape: business 400, 409 Customer, 500 |
{ code, message, id, validation |
400 Validation. validation is a list of { field, message }; message repeats the first one. |
{ error, message, referenceId } |
409 from create |
{ message, errors } |
422 from bulk. errors is a list of { index, referenceId, reason }. |
{ error, message, data } |
409 from PATCH, payer PATCH and cancel |
{ message } |
404 for a nonexistent charge, an integration not ready to collect or a location |
{ code, message } |
503 from payer-lookup |
| Plain text, not JSON | 400, 403 and 404 from the token check |
Common to all endpoints
| HTTP | Body | When it happens and what to do |
|---|---|---|
| 401 | Missing, invalid or expired token. Renew it with the refresh token from Connect merchant accounts. | |
| 400 | Bad request: Missing required authentication data |
The token doesn't carry the account, role or application. Send the merchant's id_ in Authorization: Bearer. |
| 404 | Integration client not found |
The token belongs to another application. Request it with your integration's clientId in that environment. |
| 403 | Not authorized as user of integration client |
The merchant account isn't linked, or was unlinked. Link it through OAuth. |
| 500 | { code, message, id } |
Internal error. On a create or bulk, check with GET before retrying. |
Create a charge: POST /payment-request
| HTTP | code or error |
When it happens and what to do |
|---|---|---|
| 400 | Validation |
A field is missing, has an invalid type or range, or this type doesn't accept it. See validation. |
| 400 | Webhook |
webhook points to an internal or private address. |
| 400 | Insufficient |
No free CVU in the merchant's pool. |
| 409 | ReferenceId |
The referenceId already exists, even if that charge is canceled. The charge isn't returned: retrieve it with GET. |
| 429 | Integration or Integration |
You reached the WhatsApp message cap. See the limits. |
| 409 | Customer |
Two simultaneous creates for the same payer collided. Check with GET and retry if it doesn't exist. |
Create charges in bulk: POST /payment-request/bulk
If the bulk fails, no charge in the batch is created.
| HTTP | code |
When it happens and what to do |
|---|---|---|
| 400 | Validation |
Empty batch or more than 100 items, an item breaks the contract, or a due date has a time (only YYYY-). See validation. |
| 400 | Insufficient |
The merchant's pool isn't large enough for the batch. |
| 404 | The integration isn't ready to collect and retrying won't fix it. Contact support. | |
| 429 | Integration or Integration |
The batch doesn't fit entirely under the WhatsApp message cap: nothing is created. |
| 422 | Items that fail business validation, all listed in errors. Fix them and resend the full batch. |
The 422 reason values are Duplicate referenceId within the batch, The referenceId already exists for this integration, The taxDocument does not resolve to a valid CUIL and Duplicate payer within the batch (the same document in more than one item).
Retrieve a charge: GET /payment-request/{referenceId}
| HTTP | Body | When it happens and what to do |
|---|---|---|
| 404 | { "message": "Payment request not found" } |
No charge with that referenceId for this integration and merchant account. Check that the token belongs to the right merchant. |
Set the amount: PATCH /payment-request/{referenceId}
| HTTP | code or error |
When it happens and what to do |
|---|---|---|
| 400 | Validation |
amount is missing, isn't positive, has more than 2 decimals or exceeds 200,000,000. |
| 404 | The charge doesn't exist. | |
| 409 | Payment |
The charge isn't in draft, or already received payments: only a draft with no payments accepts PATCH. |
Correct the payer: PATCH /payment-request/{referenceId}/customer
| HTTP | code or error |
When it happens and what to do |
|---|---|---|
| 400 | Validation |
tax is missing or invalid (format or check digit), or name, email or phone break the contract. |
| 404 | The charge doesn't exist, or the integration isn't ready to collect. | |
| 409 | Payment |
The payer can't be changed. The reason is in data.. |
Show the data.reason values
data. |
Meaning |
|---|---|
conciliation_ |
The charge uses CVU mode, which doesn't store the payer's document. |
state_ |
The charge is in a final state. |
payment_ |
The charge already received money. |
no_ |
No CVU can hold the new document. Nothing was changed. |
missing_ |
The new payer lacks the contact the reminders require. |
incomplete_ |
The charge has no associated payer. |
concurrent_ |
A concurrent change. Read the charge again and retry. |
See when to use it in correct the payer.
Cancel a charge: POST /payment-request/{referenceId}/cancel
| HTTP | error |
When it happens and what to do |
|---|---|---|
| 404 | The charge doesn't exist. | |
| 409 | Payment |
The charge isn't in draft or pending: it has partial payments, or it's paid, expired or canceled. |
Validate a document: GET /payer-lookup
| HTTP | code |
When it happens and what to do |
|---|---|---|
200 with name: null |
ARCA responded and the document has no holder. Ask the payer to check it. | |
| 400 | Validation |
document isn't an 11-digit CUIL or CUIT, or a 7 or 8-digit DNI. |
| 404 | The account isn't linked. | |
| 429 | Payer |
You reached the 1000 units for the day. |
| 503 | Payer |
ARCA couldn't be queried: the payer wasn't verified. Retry, or continue without validating. |
| 503 | Payer |
The quota couldn't be checked. Retry. |
Assign the location: PUT /my-integration/tenant
| HTTP | Body | When it happens and what to do |
|---|---|---|
| 400 | Validation |
tenant is missing or empty. |
| 404 | { "message": "The specified tenant does not exist or was deleted" } |
The location doesn't exist, was deleted or belongs to another integration. See Locations. |
| 404 | { "message": "No integration account was found for the authenticated user" } |
The merchant account isn't linked. |
OAuth
The errors for authorize, token, refresh and revoke are in Connect merchant accounts.
Common mistakes
- Using the wrong token. The Integration API takes the merchant account's
id_token, not the integration admin's token or theclientSecret. - Recreating after a timeout or retrying a 429 in a loop. See retries and the 429 response.
- Reading
name: nullas an ARCA failure. The document has no holder; the failure is the 503.
Downloads
OpenAPI
Import the spec into Postman, Insomnia, Bruno or any API client, or browse the API Reference:
- Integration API:
https://public-api.chytapay.com.ar/integration-api-swagger - Auth API:
https://public-api.chytapay.com.ar/auth-api-swagger
The spec still declares 10,000,000 as the amount cap for PATCH; the API enforces 200,000,000.
Postman collection
It includes a Sandbox environment (the file is named Test) and a Production one, with the hosts set. It covers all the charge endpoints, payer-lookup and payer correction, with example dates that are always in the future.
- Collection:
/api/assets/postman/Chytapay-Integration-API.postman_collection.json - Test environment:
/api/assets/postman/Chytapay-Test.postman_environment.json - Production environment:
/api/assets/postman/Chytapay-Production.postman_environment.json
Frequently asked questions
Are the limits and the pool per merchant or per integration?
The message cap is per integration (all its merchants added together). The payer-lookup quota is per integration and merchant account. The CVU pool is per merchant account. More answers in Frequently asked questions.