> Chytapay is a bank-transfer payments platform in Argentina. This page is part of the Integration API docs: https://chytapay.com.ar/api/
> Recommended reconciliation: by CUIL. Environments: test (https://integration-api.test.chytapay.com.ar) and production (https://integration-api.chytapay.com.ar).
> Page: "Create charges" (https://chytapay.com.ar/api/en/crear-cobros/), updated on 2026-09-30.
> Full index for AI assistants: https://chytapay.com.ar/llms.txt

# Create charges

How to create charges one by one or in bulk, with due dates, surcharge, states, payer notifications and safe retries.

&#xA;This page covers how to create, track and cancel charges, one at a time or up to 100 per call. You need a connected merchant account and its `id_token` in `Authorization: Bearer`: see [Connect merchant accounts](https://chytapay.com.ar/api/en/conectar-comercios/).

How a payment request moves from one state to another.

- `draft` becomes `pending` when you set the amount with PATCH.
- `pending` becomes `total_payment` with a full payment, `partial_payment` with a partial payment, and `overdue` if it expires unpaid.
- `partial_payment` becomes `total_payment` when the rest is paid, and `partial_overdue` if it expires first.
- `draft` and `pending` become `canceled` when you cancel them, if they received no payment.

## 1. Create a charge

&#xA;
You identify each charge with your own `referenceId`, which comes back in every response and event.

From your backend, create the charge in Sandbox:

**cURL**

```bash
curl -X POST https://integration-api.test.chytapay.com.ar/payment-request \
  -H "Authorization: Bearer $ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "referenceId": "invoice-1001",
    "amount": 25000,
    "description": "October installment",
    "dueDates": ["2026-10-15", "2026-10-25"],
    "surcharge": { "type": "percentage", "value": 10 },
    "conciliationType": "cuil",
    "sendWhatsappNotification": false,
    "sendEmailNotification": true,
    "customer": {
      "name": "Jane Doe",
      "email": "payer@example.com",
      "taxDocument": "20000000001"
    },
    "metadata": { "order": "1001" }
  }'
```

**Node**

```js
const BASE = 'https://integration-api.test.chytapay.com.ar';

const res = await fetch(`${BASE}/payment-request`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${idToken}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    referenceId: 'invoice-1001',
    amount: 25000,
    description: 'October installment',
    dueDates: ['2026-10-15', '2026-10-25'],
    surcharge: { type: 'percentage', value: 10 },
    conciliationType: 'cuil',
    sendWhatsappNotification: false,
    sendEmailNotification: true,
    customer: {
      name: 'Jane Doe',
      email: 'payer@example.com',
      taxDocument: '20000000001',
    },
    metadata: { order: '1001' },
  }),
});
const charge = await res.json(); // 201
```

**Python**

```python
import requests

BASE = "https://integration-api.test.chytapay.com.ar"

res = requests.post(
    f"{BASE}/payment-request",
    headers={"Authorization": f"Bearer {id_token}"},
    json={
        "referenceId": "invoice-1001",
        "amount": 25000,
        "description": "October installment",
        "dueDates": ["2026-10-15", "2026-10-25"],
        "surcharge": {"type": "percentage", "value": 10},
        "conciliationType": "cuil",
        "sendWhatsappNotification": False,
        "sendEmailNotification": True,
        "customer": {
            "name": "Jane Doe",
            "email": "payer@example.com",
            "taxDocument": "20000000001",
        },
        "metadata": {"order": "1001"},
    },
)
charge = res.json()  # 201
```

**Response**

```json
{
  "type": "standard",
  "paymentRequestId": "<charge uuid>",
  "referenceId": "invoice-1001",
  "amount": 25000,
  "description": "October installment",
  "dueDates": ["2026-10-15", "2026-10-25"],
  "state": "pending",
  "surcharge": { "type": "percentage", "value": 10 },
  "calculatedAmounts": [
    { "dueDate": "2026-10-15", "amount": 25000, "isOriginalAmount": true },
    { "dueDate": "2026-10-25", "amount": 27500, "surchargeApplied": 2500 }
  ],
  "sendWhatsappNotification": false,
  "sendEmailNotification": true,
  "metadata": { "order": "1001" },
  "customer": {
    "name": "Jane Doe",
    "email": "payer@example.com",
    "taxDocument": "20000000001"
  },
  "CVU": "<22-digit CVU>",
  "bankAccountInfo": {
    "accountHolderName": "<merchant account holder>",
    "accountHolderTaxId": "<holder's CUIT>",
    "bankName": "<bank>"
  }
}
```

Use dates within the next 35 days. The example reconciles by CUIL, the recommended mode: first, [validate the document](https://chytapay.com.ar/api/en/conciliacion/#validar-pagador).

### What it returns

**201** with `paymentRequestId`, `state` (`pending`, or `draft` without an amount), `CVU` and `bankAccountInfo` (where the payer transfers) and, with an amount and 2 dates, `calculatedAmounts` (each due date with surcharge). It also returns what you sent, except `customer.taxDocument` in CVU mode.

## 2. Retrieve a charge

&#xA;Request it with `GET /payment-request/{referenceId}`:

```bash
curl https://integration-api.test.chytapay.com.ar/payment-request/invoice-1001 \
  -H "Authorization: Bearer $ID_TOKEN"
```

Same shape as the create response, with an updated `state`. If it doesn't exist for the merchant account, **404**. To list the charges created in a range, use `GET /payment-request?startDate=YYYY-MM-DD&endDate=YYYY-MM-DD`, both dates optional.

## 3. Duplicates and retries

There's no idempotency key: the `referenceId` is unique per integration and merchant account, canceled charges included. Repeating it returns **409** without the existing charge:

```json
{
  "error": "ReferenceIdAlreadyExists",
  "message": "The provided reference ID already exists for this client",
  "referenceId": "invoice-1001"
}
```

Use your entity's id (invoice, order, installment), not one per attempt. If a create times out:

1. Call `GET /payment-request/{referenceId}`. If it returns 200, the charge was created: use that response.
2. If it returns **404**, retry the `POST` with the same body and `referenceId`.
3. If the `POST` returns **409**, another attempt created it: go back to step 1.

If the charge from the GET doesn't match what you meant to create, you reused an old `referenceId` by mistake.

## 4. Cancel a charge

Call `POST /payment-request/{referenceId}/cancel` with no body:

**cURL**

```bash
curl -X POST https://integration-api.test.chytapay.com.ar/payment-request/invoice-1001/cancel \
  -H "Authorization: Bearer $ID_TOKEN"
```

**Response**

```json
{ "referenceId": "invoice-1001", "state": "canceled" }
```

Only charges in `draft` or `pending` with no payments can be canceled: otherwise, **409** `PaymentRequestCannotBeCanceled`. It generates no event: the 200 response is the confirmation. If a transfer comes in later, you get `payment.unmatched` with `reason: "canceled"`, which is [opt-in](https://chytapay.com.ar/api/en/webhooks/#pago-sin-imputar).

## Fields

&#xA;The fields of a standard charge. Omit the optional fields you don't use; don't send `null`.

| Field                             | Required                | Rules                                                                                                                                      |
| --------------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `referenceId`                     | Yes                     | 8 to 100 characters: letters, numbers, `-` and `_`. See [duplicates](https://chytapay.com.ar/api/en/crear-cobros/#duplicados).             |
| `description`                     | Yes                     | What the payer sees. 3 to 500 characters.                                                                                                  |
| `dueDates`                        | Yes                     | 1 or 2 dates: see [due dates](https://chytapay.com.ar/api/en/crear-cobros/#vencimientos).                                                  |
| `customer`                        | Yes                     | The payer (table below).                                                                                                                   |
| `amount`                          | No                      | Pesos, greater than 0, up to 2 decimals, cap of 200,000,000. Without it, a [draft](https://chytapay.com.ar/api/en/crear-cobros/#borrador). |
| `surcharge`                       | With amount and 2 dates | `{ "type", "value" }` for the second due date. Not allowed without `amount`.                                                               |
| `sendWhatsappNotification`        | With amount             | WhatsApp [notifications](https://chytapay.com.ar/api/en/crear-cobros/#avisos). Without an amount, only `false`.                            |
| `sendEmailNotification`           | With amount             | Email notifications. Without an amount, only `false`.                                                                                      |
| `sendWhatsappPaymentConfirmation` | No                      | See [payment confirmation](https://chytapay.com.ar/api/en/crear-cobros/#confirmacion-de-pago).                                             |
| `reminderNotificationDate`        | No                      | `YYYY-MM-DD`. Replaces the advance reminder. Only with an amount.                                                                          |
| `deferredInitialNotificationDate` | No                      | `YYYY-MM-DD`. Defers the initial notification. Only with an amount.                                                                        |
| `conciliationType`                | No                      | `cvu` (default) or `cuil`, the [recommended](https://chytapay.com.ar/api/en/conciliacion/) one.                                            |
| `webhookUrl`                      | No                      | HTTPS, up to 2048 characters. Overrides the [webhook URL](https://chytapay.com.ar/api/en/webhooks/) for this charge.                       |
| `metadata`                        | No                      | Strings: up to 50 keys of 40 characters, values of 500, 8 KB. Returned in the GET and in events.                                           |

| `customer` field | Required                              | Rules                                                                   |
| ---------------- | ------------------------------------- | ----------------------------------------------------------------------- |
| `name`           | Yes                                   | 2 to 150 characters.                                                    |
| `taxDocument`    | With `conciliationType: "cuil"`       | 11-digit CUIL or 7- or 8-digit DNI. Ignored in CVU mode.                |
| `email`          | With `sendEmailNotification: true`    | Valid, up to 320 characters.                                            |
| `phoneNumber`    | With `sendWhatsappNotification: true` | `{ "countryCode": "+54", "number": "..." }`, no spaces, 6 to 15 digits. |

Outside these rules, **400** with the details: see the [errors](https://chytapay.com.ar/api/en/operacion/).

## Due dates and surcharge

`dueDates` takes 1 or 2 dates, after today and no more than 35 days out:

| Format                  | Example              | Due                                                                     |
| ----------------------- | -------------------- | ----------------------------------------------------------------------- |
| `YYYY-MM-DD`            | `"2026-10-15"`       | At the end of that day, Argentina time.                                 |
| `YYYY-MM-DDTHH:MM[:SS]` | `"2026-10-15T18:30"` | At that minute. Without a zone it's `-03:00`; accepts `Z` or an offset. |

With a time, the charge is [short-lived](https://chytapay.com.ar/api/en/crear-cobros/#vida-corta). With 2 dates, the second element of `dueDates` carries `surcharge`, required with an amount (Chytapay doesn't reorder them). The payer owes `amount` up to the first due date and `amount` plus the surcharge from the day after.

`type` is `percentage` (0 to 100, on the amount), `fixed` (pesos, up to 200,000,000) or `none` (`value: 0`). With `amount: 25000` and `{ "type": "percentage", "value": 10 }`, the second due date is 27,500, in `calculatedAmounts`.

## Short-lived charges

For reservations, tickets or any charge that has to close at a set time, send the due date with a time: `"2026-10-15T18:30"`. It changes several things compared to a date alone:

|                     | Date alone                             | With a time                                                                               |
| ------------------- | -------------------------------------- | ----------------------------------------------------------------------------------------- |
| Expires             | At the end of that day, Argentina time | At that minute. Without a zone it's `-03:00`                                              |
| Due dates           | 1 or 2, with a surcharge on the second | **A single one**, no surcharge                                                            |
| Event on expiry     | None                                   | `payment_request.expired`                                                                 |
| Payer notifications | Reminder one day before                | With less than 24 hours there's no advance reminder: the initial and due-date ones remain |
| In bulk             | Yes                                    | No, it returns 400                                                                        |

If the charge is paid in the widget, [the checkout charge](https://chytapay.com.ar/api/en/widget/#cobro-checkout) expires between 3 and 60 minutes.

## Draft without an amount

Without `amount`, the charge starts in `draft`, with one due date, no surcharge and no notifications (flags only `false`, notification dates not allowed). Complete it with `PATCH /payment-request/{referenceId}`:

**cURL**

```bash
curl -X PATCH https://integration-api.test.chytapay.com.ar/payment-request/invoice-1002 \
  -H "Authorization: Bearer $ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "amount": 18000 }'
```

**Response**

```json
{
  "referenceId": "invoice-1002",
  "previousAmount": null,
  "amount": 18000,
  "description": "Enrollment",
  "state": "pending",
  "dueDates": ["2026-10-20"]
}
```

- Only in `draft` with no payments; otherwise, **409**.
- It moves to `pending`. A draft never sends notifications, not even after the PATCH.
- If you don't complete it, Chytapay discards it after a few hours.

## States

Create, GET, cancel, PATCH and bulk return `state`, and `payment_request.*` events return `stateType`. There's no `PAID`: it's `total_payment`.

| State             | Meaning                       |
| ----------------- | ----------------------------- |
| `draft`           | Draft without an amount.      |
| `pending`         | Waiting for payment.          |
| `partial_payment` | Partially paid, balance left. |
| `total_payment`   | Paid.                         |
| `overdue`         | Expired unpaid.               |
| `partial_overdue` | Expired partially paid.       |
| `canceled`        | Canceled.                     |

With 2 dates, the charge stays open until the second due date. A day-only date expires at 00:00 Argentina time, with no event; one with a time expires at that minute with `payment_request.expired`. See the events in [Webhooks](https://chytapay.com.ar/api/en/webhooks/).

## Payer notifications

&#xA;&#xA;
A payer notification is a WhatsApp or email from Chytapay to the payer (not an event to your backend). Channels are chosen in the [fields](https://chytapay.com.ar/api/en/crear-cobros/#campos), only with an amount. After a partial payment, reminders show the balance; paid, past due or canceled, they stop.

### When each notification goes out

Reminders go out at 10 a.m. Argentina time.

| Notification                    | When                                                                | Amount                              |
| ------------------------------- | ------------------------------------------------------------------- | ----------------------------------- |
| Initial                         | On creation, or on `deferredInitialNotificationDate`                | First due date, no surcharge        |
| Advance reminder                | The day before the first due date, or on `reminderNotificationDate` | First due date, no surcharge        |
| Due date                        | That day                                                            | First due date, no surcharge        |
| First due date passed (2 dates) | The day after                                                       | Second due date, **with surcharge** |
| Second due date (2 dates)       | That day                                                            | Second due date, **with surcharge** |

Both dates must be after today and before the first due date, and `reminderNotificationDate` also after `deferredInitialNotificationDate`.

### Payment confirmation

The WhatsApp payment received notification is controlled by `sendWhatsappPaymentConfirmation`, not `sendWhatsappNotification`:

| Value   | CVU mode                           | CUIL mode            |
| ------- | ---------------------------------- | -------------------- |
| Omitted | Sent, on full and partial payments | Not sent             |
| `true`  | Sent, on full and partial payments | Only on full payment |
| `false` | Not sent                           | Not sent             |

In CUIL mode the payer can request it with "Recibir confirmación de pago" (Receive payment confirmation), and `false` doesn't turn that off.

## Create charges in bulk

`POST /payment-request/bulk` creates 1 to 100 charges, all or nothing. Each item is a single charge, except that:

- It always reconciles by CUIL: `customer.taxDocument` is required.
- The same document twice in a batch returns 422.
- A date with a time returns 400.
- `conciliationType`, `type`, `expiresInMinutes` and `webhookUrl` aren't allowed: events go to the integration's URL.

From your backend, send the batch:

**cURL**

```bash
curl -X POST https://integration-api.test.chytapay.com.ar/payment-request/bulk \
  -H "Authorization: Bearer $ID_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "paymentRequests": [
      {
        "referenceId": "installment-2026-10-001",
        "amount": 12000,
        "description": "October installment",
        "dueDates": ["2026-10-15"],
        "sendWhatsappNotification": false,
        "sendEmailNotification": false,
        "customer": { "name": "Jane Doe", "taxDocument": "20000000001" }
      },
      {
        "referenceId": "installment-2026-10-002",
        "amount": 12000,
        "description": "October installment",
        "dueDates": ["2026-10-15"],
        "sendWhatsappNotification": false,
        "sendEmailNotification": false,
        "customer": { "name": "John Smith", "taxDocument": "30405060" }
      }
    ]
  }'
```

**Response**

```json
{
  "batchId": "<batch uuid>",
  "total": 2,
  "created": 2,
  "sharedCvu": "<22-digit CVU>",
  "accountInfo": {
    "accountHolderName": "<merchant account holder>",
    "accountHolderTaxId": "<holder's CUIT>",
    "bankName": "<bank>"
  },
  "paymentRequests": [
    { "referenceId": "installment-2026-10-001", "state": "pending" },
    { "referenceId": "installment-2026-10-002", "state": "pending" }
  ]
}
```

`paymentRequests` follows the request order; retrieve details with GET.

| Code    | When                                                                                                                                                          |
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **201** | All created: store `batchId`.                                                                                                                                 |
| **400** | Empty array, more than 100 items or a field outside the contract.                                                                                             |
| **422** | `errors: [{ index, referenceId, reason }]` with **every** failed item: fix them and resend the batch.                                                         |
| **429** | The batch doesn't fit entirely under the WhatsApp message cap: nothing is created. See [the limits](https://chytapay.com.ar/api/en/operacion/#respuesta-429). |

With 400, 422 or 429 nothing is created. Some `reason` values: `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: ...`.

`sendWhatsappPaymentConfirmation` applies to the whole batch and, if items differ, `false` wins. Notification channels work the other way: if any item turns on WhatsApp or email, it's on for the batch.

## Checkout charge

A `type: "checkout"` charge is paid from the widget: see [the checkout charge](https://chytapay.com.ar/api/en/widget/#cobro-checkout).

## Next steps

- [Reconciliation](https://chytapay.com.ar/api/en/conciliacion/): Why CUIL, how to validate the payer and when to use CVU.
- [Webhooks](https://chytapay.com.ar/api/en/webhooks/): Payment and expiration events, signatures and retries.
- [Checkout widget](https://chytapay.com.ar/api/en/widget/): Checkout charges paid from your website.
- [Operations and errors](https://chytapay.com.ar/api/en/operacion/): Message cap, 429 and errors by endpoint.
