# Scheduled Payments (Pix Agendado)

With our payment initiation functionality, you can schedule payments to occur in the future (also called PIX RECORRENTE) using any of the following modes:

- **SINGLE**: Schedule a payment to occur at a specific moment in the future.
- **DAILY**: Schedule several payments to occur every day, starting from a specific date.
- **WEEKLY**: Schedule several payments to occur every week, starting from a specific date.
- **MONTHLY**: Schedule several payments to occur every month, starting from a specific date.
- **CUSTOM**: Schedule several payments to occur on specific dates in the future.

## Scheduling a payment

1. Create a [Payment Request](/reference/payment-request-create) including a `schedule` object:

```json title="POST /payments/requests"
{
  "amount": 1333.33, // The amount to be paid every day/week/month/custom schedule
  "description": "My payment request 2",
  "schedule": {
    "type": "DAILY",
    "startDate": "2024-06-26", // Date of the first payment
    "occurrences": 2 // How many times to repeat it
  },
  "recipientId": "376af75c-05fa-4a50-9347-d790a2d19940"
}
```

2. Authorize the Payment Request with our Payments App (by visiting the `paymentUrl` in the response).

3. After the user chooses the institution to pay with, enters their CPF/CNPJ and clicks Pay, a Payment Intent with status CONSENT_AWAITING_AUTHORIZATION is created. This triggers the `payment_intent/created` webhook. The user is now redirected to their institution to authorize the scheduled payment.

4. Once authorized, the Payment Intent will change status to `PAYMENT_COMPLETED`. This triggers the `payment_intent/completed` webhook. Now, one or more Scheduled Payments (payments to occur in the future) will be created. Each creation will trigger the `scheduled_payment/created` webhook.

5. You can now obtain the list of [Scheduled Payments](/reference/payment-schedules-list):

```json title="GET /payment-requests/{id}/schedules"
{
  "total": 2,
  "totalPages": 1,
  "page": 1,
  "results": [
    {
      "id": "9f12b911-a064-4310-89f2-8d411e10b160",
      "status": "SCHEDULED",
      "scheduledDate": "2024-06-26",
      "description": "My payment request 1/2"
    },
    {
      "id": "1f1f04e8-0bcf-4baf-bbbd-8bedf8478503",
      "status": "SCHEDULED",
      "scheduledDate": "2024-06-27",
      "description": "My payment request 2/2"
    }
  ]
}
```

6. On each of the scheduled dates, a payment will be triggered in the institution. This will result in the Scheduled Payment changing status to COMPLETED or ERROR in the case of failure. This triggers the `scheduled_payment/completed` or `scheduled_payment/error` webhook.

7. If the user cancels a Scheduled Payment from the institution, it will change status to CANCELED and trigger the `scheduled_payment/canceled` webhook.

8. After all Scheduled Payments are COMPLETED, the Payment Request will change status to COMPLETED.

## Modifying or cancelling scheduled payments

If the user has not authorized a scheduled payment yet, you can modify it using the `PATCH /payment-requests/{id}` endpoint, or delete it using the `DELETE /payment-requests/{id}` endpoint.

After the user has authorized a Scheduled Payment, you can not add or edit the resulting Schedules. However, you can delete a particular schedule or cancel the entire payment altogether.

The authorizing user can also cancel all schedules from their bank directly. You can react to this change with a webhook.

## Schedule Modes

Here are examples of how to set up all the different schedule modes:

```json title="SINGLE"
{
  "amount": 1333.33,
  "description": "Test",
  "schedule": {
    "type": "SINGLE",
    "date": "2024-06-26"
  },
  "recipientId": "376af75c-05fa-4a50-9347-d790a2d19940"
}
```

```json title="DAILY"
{
  "amount": 1333.33,
  "description": "Test",
  "schedule": {
    "type": "DAILY",
    "startDate": "2024-06-26",
    "occurrences": 2
  },
  "recipientId": "376af75c-05fa-4a50-9347-d790a2d19940"
}
```

```json title="WEEKLY"
{
  "amount": 1333.33,
  "description": "Test",
  "schedule": {
    "type": "WEEKLY",
    "startDate": "2024-06-26",
    "dayOfWeek": "MONDAY",
    "occurrences": 2
  },
  "recipientId": "376af75c-05fa-4a50-9347-d790a2d19940"
}
```

```json title="MONTHLY"
{
  "amount": 1333.33,
  "description": "Test",
  "schedule": {
    "type": "MONTHLY",
    "startDate": "2024-06-26",
    "dayOfMonth": 1,
    "occurrences": 2
  },
  "recipientId": "376af75c-05fa-4a50-9347-d790a2d19940"
}
```

```json title="CUSTOM"
{
  "amount": 1333.33,
  "description": "Test",
  "schedule": {
    "type": "CUSTOM",
    "dates": ["2024-06-26", "2024-06-28"]
  },
  "recipientId": "376af75c-05fa-4a50-9347-d790a2d19940"
}
```

## Using a custom UI

If you want to use your own UI to implement the Scheduled Payment flow instead of our Payments App:

1. Create the payment request, including a `callbackUrl` to your website:

```json title="POST /payments/requests"
{
  "amount": 1333.33,
  "description": "My payment request 2",
  "schedule": {
    "type": "DAILY",
    "startDate": "2024-06-26", // Date of the first payment
    "occurrences": 2 // How many times to repeat it
  },
  "recipientId": "376af75c-05fa-4a50-9347-d790a2d19940",
  "callbackUrls": {
    "success": "<your-website>/success",
    "error": "<your-website>/error"
  }
}
```

2. Create a [Payment Intent](/reference/payment-intent-create) for that Payment Request:

```json title="POST /payments/intents"
{
  "paymentRequestId": "4f05247c-d9ee-4d5b-a0ea-c1c52cc30f69",
  "connectorId": 600, // this is sandbox
  "parameters": {
    "cpf": "76109277673"
  }
}
```

3. Redirect the user to the `consentUrl` in the response, which will take them to the institution's Open Finance Payment Initiation screen to authorize the payment.

4. You will be redirected back to the corresponding `callbackUrl` (success or error).

## Testing in sandbox

You can run the custom UI flow above end to end against the sandbox bank.

<Callout variant="info" title="Requires scheduled payments to be enabled on your account">
Scheduled PIX uses your own payment initiation agreement, so payment initiation for scheduled payments must be enabled on your account — in sandbox too. Without it, creating the Payment Intent (`POST /payments/intents`) for a Payment Request with a `schedule` returns `403` with the code `PAYMENT_INITIATION_NOT_ALLOWED`, also when the request has `isSandbox: true`. Contact Pluggy support to enable it.
</Callout>

1. Create the Payment Request with `isSandbox: true` and a `schedule` — for example `SINGLE` with a future `date`.
2. Create the Payment Intent with connector **`600`** and the sandbox CPF `76109277673`, as in the example above.
3. Open the `consentUrl`, log in with `user-ok` / `password-ok` and approve.

<Callout variant="warning" title="The sandbox does not wait for the scheduled date">
The sandbox settles a scheduled payment request **at consent time**, as a single payment dated today, instead of creating one payment per occurrence and executing each one on its date. Use it to check that your integration creates the request, sends the user through the consent and handles the `scheduled_payment/completed` webhook. Because the individual occurrences are never scheduled, the sandbox does not send `payment_intent/completed`, `scheduled_payment/created` or `scheduled_payment/all_created`, and the Payment Request is left in `SCHEDULED` rather than moved to `COMPLETED`. Validate those steps against a real institution.
</Callout>

An `amount` of **`404.04`** makes the sandbox reject the payment when you create the Payment Intent, so you can test that error path too. See [Testing payments and boletos](/docs/guides/sandbox#testing-payments-and-boletos) for the other payment types.