# Callbacks

Callback functions passed in the `options` object to [Finix.PaymentForm()](https://docs.finix.com/js/payment-form). Each callback fires in response to a specific form lifecycle event.

## onLoad

Fires once when the Payment Form iframe finishes loading. Takes no parameters.

```javascript
onLoad: function () { ... }
```

Use `onLoad` to show UI that depends on the form being ready — for example, enabling a custom submit button or hiding a loading spinner.

## onUpdate

Fires every time the form state changes — field values, validation errors, focus and blur events, card brand detection, and payment method switching.

```javascript
onUpdate: function (state, binInformation, hasErrors) { ... }
```

| Parameter         | Type       | Description                                                                                                 |
| ------------------ | ---------- | ----------------------------------------------------------------------------------------------------------- |
| `state`           | `object`   | Form state including metadata about which inputs are valid, dirty, or focused — does not expose payment data |
| `binInformation`  | `object`   | High-level BIN data such as BIN number and card brand                                                     |
| `hasErrors`      | `boolean`  | `true` if the form currently has validation errors — useful for enabling or disabling a custom submit button |

## onSubmit

Fires when the form is submitted. Providing `onSubmit` in the options automatically renders a submit button inside the form.

```javascript
onSubmit: function (error, response) { ... }
```

| Parameter      | Type                          | Description                                                                                      |
| --------------- | ----------------------------- | ------------------------------------------------------------------------------------------------ |
| `error`        | `object | null`              | Error object if submission failed; `null` on success                                             |
| `response`     | `object | null`              | Response object containing the token data on success; `null` on error                           |

Use `onSubmit` when you want the form to render and manage its own submit button. For a custom button outside the form, use `form.submit()` [method](https://docs.finix.com/js/form-instance) instead.

See [Token Response](https://docs.finix.com/js/token-response) for the full response shape.

## Example Code

```javascript
Finix.PaymentForm("payment-form", "sandbox", "APgPDQrLD52TYvqazjHJJchM", {
  onLoad: function () {
    // Form iframe has finished loading — safe to show dependent UI
    document.getElementById("pay-btn").disabled = false;
    document.getElementById("loading-spinner").style.display = "none";
  },
});

Finix.PaymentForm("payment-form", "sandbox", "APgPDQrLD52TYvqazjHJJchM", {
  onUpdate: function (state, binInformation, hasErrors) {
    // state: form field states keyed by field name
    // binInformation: { cardBrand, bin } (card payments only)
    // hasErrors: true if any field has a validation error

document.getElementById("pay-btn").disabled = hasErrors;

// Detect card brand
    if (binInformation?.cardBrand) {
      console.log("Card brand:", binInformation.cardBrand);
    }
  },
});

Finix.PaymentForm("payment-form", "sandbox", "APgPDQrLD52TYvqazjHJJchM", {
  onUpdate: function (state, binInformation, hasErrors) {
    // Each field in state has: errors, isDirty, isFocused, errorMessages
    // Note: most fields do not expose a value; exceptions include country and current_payment_method
    const nameField = state["name"]; // card_holder_name / account_holder_name maps to "name"
    const addressLine1 = state["address.line1"];

console.log("Name has errors:", nameField?.errors);
    console.log("Name is focused:", nameField?.isFocused);
  },
});

Finix.PaymentForm("payment-form", "sandbox", "APgPDQrLD52TYvqazjHJJchM", {
  // Providing onSubmit automatically renders a submit button in the form
  onSubmit: function (error, response) {
    if (error) {
      // error contains status code and error details
      console.error("Tokenization failed:", error);
      return;
    }
    const tokenData = response.data || {};
    const token = tokenData.id; // use to create a Payment Instrument
    console.log("Token:", token);
  },
});
```
