---
updatedAt: 2026-09-16T09:27:47.000Z
---

Fetch the complete documentation index at: https://developer.pay.nl/llms.txt. Use this file to discover all available pages before exploring further. Append .md to any documentation page URL to get its markdown version.

# Handle events

The SDK provides several events you can listen to in order to control the payment flow:

| Event               | Description                                                                                  | Handler Signature                       |
| ------------------- | -------------------------------------------------------------------------------------------- | --------------------------------------- |
| `onReady`           | Called when checkout is initialized and ready                                                | `(event: CheckoutReadyEvent) => void`   |
| `onSubmit`          | Called when user submits payment. **Call&#x20;**`event.resolve()`**&#x20;to continue**       | `(event: PaymentSubmitEvent) => void`   |
| `onSuccess`         | Called when payment succeeds. **Call&#x20;**`event.resolve()`**&#x20;to complete**           | `(event: PaymentSuccessEvent) => void`  |
| `onError`           | Called when payment fails. **Call&#x20;**`event.resolve()`**&#x20;to allow retry**           | `(event: PaymentErrorEvent) => void`    |
| `onPartialPaid`     | Called when an order is partially paid. **Call&#x20;**`event.resolve()`**&#x20;to continue** | `(event: PartialPaymentEvent) => void`  |
| `onInfoUpdated`     | Called when info (e.g., cart contents) is updated                                            | `(event: InfoUpdatedEvent) => void`     |
| `onShippingUpdated` | Called when shipping selection changes                                                       | `(event: ShippingUpdatedEvent) => void` |
| `onStateChange`     | Called when the SDK lifecycle state changes (`NOT_READY`, `INITIALIZING`, `READY`)           | `(state: CheckoutState) => void`        |

# Using Events for Custom Logic

You can use the `onSubmit` event to run async logic before the payment is processed:

```typescript
onSubmit: async (event) => {
  // Perform async merchant logic
  // e.g., create internal order, freeze stock, validate inventory
  try {
    await merchantApi.createOrder({
      items: cartItems,
      customer: customerInfo
    });
    // Async done - continue with payment
    event.resolve();
  } catch (error) {
    // Cancel payment if order creation fails
    event.reject(error);
  }
}
```

You can use the `onSuccess` event to handle post-payment logic:

```typescript
onSuccess: async (event) => {
  // Log the transaction
  console.log('Order ID:', event.orderId);
  console.log('Payment status:', event.paymentStatus); // { code, action }

  // Redirect to return URL or show success page
  window.location.href = event.returnUrl;

  // Mark handler as complete
  event.resolve();
}
```

Attach the handlers to the `checkout.events` object after initialization:

```typescript
const checkout = await window.PayPartsSDK.init({ sessionToken, apiUrl });

checkout.events = {
  onReady: (event) => console.log('Ready', event.config),
  onSubmit: async (event) => {
    await merchantApi.createOrder(cartItems);
    event.resolve();
  },
  onSuccess: (event) => {
    window.location.href = event.returnUrl;
    event.resolve();
  },
  onError: (event) => {
    console.error(event.error, event.errors);
    event.resolve();
  },
};
```