> ## Documentation Index
> Fetch the complete documentation index at: https://devs.tapipay.la/llms.txt
> Use this file to discover all available pages before exploring further.

# Autopay SDK

> Embed the autopay management screen so your user can manage their enrolled payment methods.

The **autopay management** view lets your end user manage their **autopay** enrollment embedded in your site, without entering the full portal. From there they can:

<CardGroup cols={3}>
  <Card title="View" icon="eye">
    The methods they have enrolled: card or CLABE account.
  </Card>

  <Card title="Enroll" icon="plus">
    A new method, when they do not have one yet.
  </Card>

  <Card title="Remove" icon="trash">
    An existing method.
  </Card>
</CardGroup>

It uses the **same SDK** as the [payment methods widget](/en/payment-portal/payment-methods-sdk): same installation, same company identification options and same `destroy()`. The two differences are that it mounts with `view: "autopay"` and that it emits its own events.

<Note>
  Installation, entrypoints, `loadTapipay()` and the staging environment are identical. They are covered in [Payment methods SDK](/en/payment-portal/payment-methods-sdk#installation).
</Note>

## Quick start

<Tabs>
  <Tab title="Script tag">
    ```html theme={null}
    <div id="autopay"></div>
    <script src="https://app.tapipay.la/embed.js"></script>
    <script>
      tapipay.initialize({
        container: "#autopay",
        organization: "acme-corp",
        identifier: "CLI-00042",
        view: "autopay"
      });

      tapipay.on("autopayLoaded", function (data) {
        console.log("Active enrollments:", data.count, data.mediaTypes);
      });
    </script>
    ```
  </Tab>

  <Tab title="Data-attrs">
    ```html theme={null}
    <div
      data-tapipay-widget
      data-organization="acme-corp"
      data-identifier="CLI-00042"
      data-view="autopay"
    ></div>
    <script src="https://app.tapipay.la/embed.js"></script>
    ```
  </Tab>

  <Tab title="React">
    ```tsx theme={null}
    import { TapipayWidget } from "@npmtapi/embed/react";

    export function AutopayPage({ clientId }: { clientId: string }) {
      return (
        <TapipayWidget
          organization="acme-corp"
          identifier={clientId}
          view="autopay"
          onAutopayLoaded={(data) => console.log("Active enrollments:", data.count)}
          onAutopayRemoved={(data) => console.log("Method removed:", data.mediaType)}
        />
      );
    }
    ```
  </Tab>
</Tabs>

Just like the payment widget, you can identify your company with `organization` (the `slug`) **or** with `companyCode`. Replace `organization: "acme-corp"` with `companyCode: "MX-S-12345"` in any of the examples.

## The `view` option

| Option | Type                      | Required | Default      | Description                                                                                                                |
| ------ | ------------------------- | -------- | ------------ | -------------------------------------------------------------------------------------------------------------------------- |
| `view` | `"payments" \| "autopay"` | No       | `"payments"` | With `"autopay"` it mounts autopay management. Omitted, it mounts the payments view. In data-attrs: `data-view="autopay"`. |

Every other option (`container`, `organization` / `companyCode`, `identifier`, `environment`) is the same as in the [payments view](/en/payment-portal/payment-methods-sdk#options). `externalRequestId` and `selectionStrategy` do not apply here: they belong to the payments view.

The URL the SDK mounts is the payments view URL with `/autopay` appended:

```text theme={null}
https://app.tapipay.la/s/acme-corp/embed/CLI-00042/autopay
https://app.tapipay.la/c/MX-S-12345/embed/CLI-00042/autopay
```

## Events

<Warning>
  **Privacy.** Autopay events expose **only the minimum**: the method type (`mediaType`) and the last 4 digits (`lastFour`). The `id` is an opaque hash, not the internal identifier. The holder name, the full number or CLABE, the brand, the bank and tokens are **never** exposed.
</Warning>

```javascript theme={null}
// Active enrollments finished loading
tapipay.on("autopayLoaded", function (data) {
  console.log("Active enrollments:", data.count, data.mediaTypes);
});

// A new autopay enrollment became active
tapipay.on("autopayActivated", function (data) {
  console.log("Enrollment active:", data.mediaType, data.lastFour);
});

// The user successfully removed a method
tapipay.on("autopayRemoved", function (data) {
  console.log("Method removed:", data.mediaType, data.lastFour);
});

// Loading enrollments or removing one failed
tapipay.on("autopayError", function (data) {
  console.log("Autopay error:", data.stage, data.message);
});

// Remove a listener
tapipay.off("autopayLoaded", handler);
```

| Event              | When it fires                                                                                                                                                                                            |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `autopayLoaded`    | When active enrollments finish loading, and **every time the set changes** (new enrollment, removal or refetch), so you can keep your count in sync. It does not fire during loading or on a load error. |
| `autopayActivated` | When a **new** autopay enrollment becomes active. Once per enrollment.                                                                                                                                   |
| `autopayRemoved`   | When the user successfully removes a method.                                                                                                                                                             |
| `autopayError`     | On a failure loading enrollments or removing one.                                                                                                                                                        |

### Payloads

```typescript theme={null}
type TapipayAutopayMediaType = "card" | "bank_account";

interface TapipayAutopayAdhesionSummary {
  id: string;                            // opaque hash of the enrollment
  mediaType: TapipayAutopayMediaType;
  lastFour: string | null;               // last 4 digits (card or CLABE)
}

interface TapipayAutopayLoadedEvent {
  count: number;                         // number of active enrollments
  mediaTypes: TapipayAutopayMediaType[]; // types present, no duplicates
  adhesions: TapipayAutopayAdhesionSummary[];
}

interface TapipayAutopayActivatedEvent {
  id: string;
  mediaType: TapipayAutopayMediaType;
  lastFour: string | null;
}

interface TapipayAutopayRemovedEvent {
  id: string;
  mediaType: TapipayAutopayMediaType;
  lastFour: string | null;
}

interface TapipayAutopayErrorEvent {
  stage: "load" | "remove";              // which phase failed
  message: string;                       // neutral message, no personal data
}
```

### In React

| Prop                 | Matching event     |
| -------------------- | ------------------ |
| `onAutopayLoaded`    | `autopayLoaded`    |
| `onAutopayActivated` | `autopayActivated` |
| `onAutopayRemoved`   | `autopayRemoved`   |
| `onAutopayError`     | `autopayError`     |

<Tip>
  `autopayLoaded` fires again every time the list changes, so you can use it as the single source for your enrolled methods counter: no need to add and subtract by hand with `autopayActivated` and `autopayRemoved`.
</Tip>

## How it relates to the API

A debt or subscription created with `autopay: true` is charged through autopay, without the user picking a method on every charge. For that charge to work, the user needs **an enrolled method**: this screen is where they enroll it.

<Card title="Payment methods and autopay" icon="credit-card" href="/en/concepts/payment-methods">
  How `autopay` works on debts and subscriptions, and how it relates to `paymentMethods`.
</Card>
