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

# Checkout Lifecycle, Events & Errors

> Launch provider checkout safely, handle browser UI feedback, and keep server-side payment completion authoritative.

`elements.checkout()` is the hand-off from a selected method to a public payment session. It calls your `createOrder` callback, receives the session created by your backend, and starts the provider's browser presentation.

It does **not** verify a payment. A success-looking provider page, redirect, overlay callback, or browser event never authorizes fulfilment. Complete the provider callback or return in your backend with the SDK's `completePayment()`.

## Checkout sequence

<Steps>
  <Step title="Select method">
    Buyer selects a method in `renderMethods()`.
  </Step>

  <Step title="Initiate payment">
    Buyer clicks your payment button.
  </Step>

  <Step title="Call checkout">
    Your frontend calls `elements.checkout()`.
  </Step>

  <Step title="Trigger callback">
    Your `createOrder` callback calls your HTTPS backend endpoint.
  </Step>

  <Step title="Create session">
    Your backend validates fresh availability and calls SDK `createOrder()`.
  </Step>

  <Step title="Launch session">
    Elements launches the returned public provider session.
  </Step>

  <Step title="Receive callback">
    The provider callback or trusted return reaches your backend.
  </Step>

  <Step title="Verify and fulfil">
    Your backend calls SDK `completePayment()` and decides fulfilment.
  </Step>
</Steps>

```js theme={null}
// Your browser event binding — not provided by Payment Elements.
document.querySelector('#pay-now').addEventListener('click', async () => {
  try {
    await elements.checkout();
  } catch (error) {
    // This is a buyer-safe browser error, not a provider diagnostic.
    // Your application UI function — not provided by Payment Elements.
    showCheckoutMessage(error.message);
  }
});
```

`checkout()` fails before it calls your server when no method is selected. It also requires `createOrder` when you call it. The relevant browser errors are `elements_method_missing` and `elements_create_order_missing`.

<Note>
  `createOrder` is **your backend callback**, not a Payment Elements function. It receives the selected `gateway`, `mode`, customer values, and public `providerOptions`; it must call your backend, where your AvraAPI SDK creates the public payment session. `elements.checkout()` is the package function that invokes this callback and presents that session.
</Note>

## Provider presentations

The returned public session determines how the package starts checkout. Your server chooses the gateway and mode; the browser must not invent them.

| Public session type | Current presentation | Buyer-facing result |
| - | - | - |
| `redirect` | Validated HTTPS redirect | Browser leaves your site for the provider. |
| `redirect_form` | Hidden HTML form submission | Browser posts the signed public fields to the provider. |
| `overlay` | PayHere provider overlay | Provider UI opens over your site. |
| `directpay_v3` | DirectPay overlay or embedded view | `overlay` opens provider UI; `embedded` uses `directPayContainer` or a container created inside the method mount. |
| `onepay_sdk_overlay` | Official OnePay SDK overlay | Uses the public transaction URL and ID only. If it cannot open and fallback is enabled, Elements redirects to the provider-hosted URL. |
| `hosted_session` | Legacy compatibility only | Treated as `redirect`. New integrations use `redirect`. |

<Warning>
  An Elements presentation is not a supported substitute for server-side completion. In particular, a browser return URL and a provider overlay callback are not payment proof.
</Warning>

### DirectPay embedded target

For DirectPay's `embedded` mode, choose a stable page container. The package clears it before mounting each provider session.

```html theme={null}
<div id="directpay-checkout"></div>
```

```js theme={null}
const elements = AvraAPIPaymentElements.create({
  directPayContainer: '#directpay-checkout',
  // Your backend callback — not provided by Payment Elements.
  createOrder,
  // Your application UI function — not provided by Payment Elements.
  onError: ({ code, message }) => showCheckoutMessage(message),
});
```

Only DirectPay uses `directPayContainer`; it does not change redirect, PayHere, or OnePay behaviour.

## State-change events

Pass `onStateChange` when creating Elements. All events are UI signals only.

```js theme={null}
const elements = AvraAPIPaymentElements.create({
  // Your backend callback — not provided by Payment Elements.
  createOrder,
  onStateChange: (event) => {
    switch (event.type) {
      case 'method_change':
        // Your application UI function — not provided by Payment Elements.
        updateSelectedMethod(event.method);
        break;
      case 'checkout_started':
        // Your application UI function — not provided by Payment Elements.
        setCheckoutBusy(true);
        break;
      case 'checkout_cancelled':
      case 'checkout_failed':
      case 'checkout_error':
        // Your application UI function — not provided by Payment Elements.
        setCheckoutBusy(false);
        break;
      case 'payment_methods_unavailable':
        // Your application UI function — not provided by Payment Elements.
        disablePaymentButton(event.message);
        break;
    }
  },
});
```

| Event | When it is emitted | Important fields | Correct use |
| - | - | - | - |
| `method_change` | Buyer selects an available card. | `method` with `gateway`, `mode`, `label`, `providerOptions` | Update the chosen-method UI. |
| `checkout_started` | A provider presentation begins. | `gateway`, `mode` | Disable duplicate checkout clicks or show a loading state. |
| `checkout_completed` | PayHere, DirectPay, or OnePay browser UI reports a completion-like result. | `gateway`, `mode`, provider-specific UI result | Show a waiting state only; wait for server completion. |
| `checkout_cancelled` | Buyer closes PayHere or OnePay's browser presentation. | `gateway`, `mode`, optional `reason` | Re-enable the button or offer another method. |
| `checkout_failed` | OnePay reports a browser failure. | `gateway`, `mode`, `clientResult` | Show a non-final failure state; the server still owns the order decision. |
| `checkout_error` | A provider script, presentation, or provider response fails. | `gateway`, `mode`, `message` | Show a buyer-safe error and allow a retry when appropriate. |
| `checkout_fallback` | OnePay overlay fails and the configured redirect fallback starts. | `gateway`, `mode`, `fallbackMode`, `message` | Inform the buyer that checkout continues at the provider. |
| `payment_methods_unavailable` | No method is available, or the server rejects a stale checkout as unavailable. | `reason`, `message` | Disable payment and refresh availability from your server. |

No event in this table means `payment_status = succeeded`. Do not mark an order paid or fulfil it from any browser event.

## Error handling

`checkout()` rejects with a `PaymentElementsError` when the package can produce a safe error. It has `code`, `message`, `reason` where relevant, and `availabilityUnavailable` for stale-availability failures. `onError` receives `{ code, message }`.

```js theme={null}
try {
  await elements.checkout();
} catch (error) {
  if (error.availabilityUnavailable) {
    // Your application UI function — not provided by Payment Elements.
    showCheckoutMessage('Payment methods changed. Refreshing checkout…');
    // Your application refresh function — not provided by Payment Elements.
    await refreshCheckoutPage();
    return;
  }

  // Your application UI function — not provided by Payment Elements.
  showCheckoutMessage(error.message);
}
```

| Code | Meaning | Buyer-facing handling |
| - | - | - |
| `elements_script_missing` | The browser bundle did not load. | Ask the buyer to retry; check CDN and Content Security Policy deployment. |
| `elements_browser_required` | Code ran outside a browser. | Integration error; do not expose this in a buyer flow. |
| `elements_mount_target_missing` | Mount selector or element was not found. | Integration error; fix the page markup. |
| `elements_create_order_missing` | `checkout()` was called without `createOrder`. | Integration error; provide a backend callback. |
| `elements_method_missing` | Buyer has not selected a method. | Ask them to select an available method. |
| `elements_payment_methods_not_supplied` or `elements_payment_methods_unavailable` | No usable method data was mounted, or every rendered method became unavailable. | Disable payment and refresh server-generated availability. |
| `elements_invalid_session` | Your backend endpoint returned an invalid public session. | Show a generic retry message; inspect server logs. |
| `elements_checkout_mode_unsupported` | Session contains an unsupported checkout type. | Fix the server-side gateway/mode integration. |
| `elements_checkout_in_progress` | Another OnePay overlay is already active in this browser page. | Prevent a duplicate click and wait for the active checkout to close. |
| `elements_provider_mode_invalid` | Provider session and requested mode do not match. | Fix the server-side gateway/mode integration. |
| `elements_provider_script_failed` or `elements_provider_script_invalid` | A provider browser dependency could not load or was invalid. | Offer a retry; check CSP and provider availability. |
| `elements_provider_checkout_failed` | A provider presentation could not complete in the browser. | Show a generic retry or alternate-method option. |
| `elements_provider_response_mismatch` | OnePay returned a browser transaction ID that does not match the prepared session. This arrives through `onError`. | Stop the browser flow and investigate the server-side order correlation. |
| `elements_upg_entitlement_inactive`, `elements_upg_gateway_not_entitled`, `elements_payment_configuration_not_available`, `elements_project_paused` | Fresh server state makes the displayed methods unusable. | Disable payment and refresh server-generated availability. |
| `elements_checkout_failed` | A generic protected checkout failure, including invalid credentials. | Show the generic message only; diagnose server-side. |

## Final payment decision

After the provider callback or return reaches your backend, call the SDK's `completePayment()` using the preserved server-only completion context. Use its normalized status to decide whether to fulfil, leave pending, cancel, fail, or review the merchant order.

Follow [Payment response & completion](/universal-payment-gateway/advanced-setup/webhooks-and-completion) for the authoritative completion flow and outcomes.

## Your application functions in these examples

Payment Elements provides `AvraAPIPaymentElements.create()`, `renderForm()`, `renderMethods()`, `checkout()`, `destroy()`, `onStateChange`, `onError`, and the browser-safe `PaymentElementsError` values documented above. It does **not** provide your backend endpoint or your application UI helpers.

The functions marked **Your ... function** in this page are sample names that you must implement in your own application:

* `createOrder` — calls your backend endpoint; that endpoint uses your server-side AvraAPI SDK `createOrder()` call.
* `showCheckoutMessage`, `updateSelectedMethod`, `setCheckoutBusy`, and `disablePaymentButton` — update your checkout UI.
* `refreshCheckoutPage` — reloads or re-fetches your server-generated checkout availability.
* The final SDK `completePayment()` call — runs only in your backend callback or return handler, never in the Payment Elements browser package.

They are intentionally not functions shipped by `@avraapi/payment-elements`. Replace each sample with your application's own implementation.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.