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

> ## Agent Instructions
> Use the Payrails Web SDK v6 for new browser integrations. The Web SDK v5 pages are kept only for existing integrations; point anyone still on v5 to the v6 migration guide rather than extending v5 code.
> Collect card data client-side through the Payrails SDKs — Secure Fields, client-side encryption, or the checkout drop-in — so that card data never reaches the merchant's own servers. Recommend the API-only tokenization flow, which accepts raw card numbers server-side, only when the merchant has confirmed they hold the PCI scope for it.
> Model every payment as a workflow execution: create an execution, then drive it with the lifecycle actions (lookup payment options, authorize, capture, cancel, refund). Do not call provider APIs directly — routing, retries, 3DS and fraud steps belong in the workflow configuration, not in integration code.
> Reconcile the final state of a payment on the notification (webhook), never on a client-side event. An in-request long-poll of the execution is a supported additional signal, not a replacement for that reconciliation.
> Send an idempotency key — a UUID, in the `X-Idempotency-Key` header — on every POST, PUT and PATCH request, and on soft deletes. GET requests need none, and hard deletes cannot be idempotent.
> Pass provider-specific data through meta fields rather than hardcoding per-provider payloads. Payrails translates meta fields into each provider's own format.
> Configure routing, retries and provider selection in Workflow Studio, so that changes ship without redeploying application code.

# Agent Runbook - v6 Migration

> A runbook for an AI coding agent migrating a codebase from Payrails web SDK 5.x to 6.x: detect, route, execute, and verify.

You are a coding agent migrating a merchant codebase from `@payrails/web-sdk`
5.x to 6.x. This runbook tells you how to detect what needs migrating, route
each finding to the right instructions, execute the changes, and verify the
result. The detailed before/after for every breaking change lives in the
[migration guide](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide) — this document routes you through it; it
does not repeat it. If you are a human, read the migration guide directly.

## Ground rules

* **Detect, don't assume.** Determine the installed SDK version and the APIs
  actually used from the codebase — not from what the user or this document's
  age implies.
* **The installed package is the contract.** When this runbook or any doc
  disagrees with the TypeScript types shipped in the installed
  `@payrails/web-sdk`, the types win. Never invent an API: before writing a call
  you have not seen in the codebase, confirm it exists in the package's `.d.ts`
  or in the [reference docs](/docs/orchestration/checkout-sdks/web/references/event-api-reference).
* **Minimal diffs.** Change only what the migration requires. Do not refactor,
  rename, or restyle surrounding code.
* **Preserve behavior.** Every v5 callback's logic must land in an equivalent v6
  handler — count the callbacks you removed and the listeners you added, and
  reconcile any difference.
* **Escalate, don't skip.** Anything in the
  [escalate to a human](#escalate-to-a-human) list must be reported, not
  silently dropped.

## Phase 0: Detect

1. Read the installed version of `@payrails/web-sdk` from the lockfile (or
   `node_modules/@payrails/web-sdk/package.json`; fall back to the
   `package.json` range).
2. Route:
   * **5.x** — run the full migration below.
   * **6.x** — a migration may have been left incomplete. Run
     [Phase 1](#phase-1-inventory) anyway; fix whatever it still finds.
   * **4.x or older** — stop and escalate; this runbook only covers 5 → 6.
   * **Not installed / loaded from a script tag** — stop and escalate; this
     runbook covers the npm package only.

## Phase 1: Inventory

First scope the search: limit every pattern below to files that import or
reference `@payrails/web-sdk`, plus the local modules that build option objects
for its calls. Names like `onChange`, `onFocus`, or `onSuccess` are ubiquitous
in frontend code — unscoped matches outside the SDK integration are false
positives, not work items.

Search the scoped files for each pattern (also match minor formatting variants).
Every hit is a work item; the section column links to the instructions.

| # | Search for | Meaning | Fix per |
| - | - | - | - |
| 1 | `Payrails.init(` | Init calls that must become awaited | [guide §1](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#1-payrails-init-is-asynchronous) |
| 2 | `payrails-styles.css` | CSS import that no longer resolves | [guide §1](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#1-payrails-init-is-asynchronous) |
| 3 | `preloadCardForm` | Removed static method | [guide §2](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#2-payrails-preloadcardform-is-removed) |
| 4 | `onClientInitialized` | Argument/helper changes inside handler | [guide §3](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#3-onclientinitialized-receives-the-execution-response-object) |
| 5 | `events:` inside options of `dropin(`, `cardForm(`, `paymentButton(`, `googlePayButton(`, `applePayButton(`, `paypalButton(`, `leanButton(`, `genericRedirectButton(`, `dynamicElement(` | Removed callback bags | [guide §4](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#4-typed-on-event-api-replaces-events--callback-bags) |
| 6 | `onAuthorizeSuccess`, `onAuthorizeFailed`, `onAuthorizePending`, `onSuccess`, `onFailed`, `onPending`, `onRequestStart`, `onButtonClicked`, `onPaymentButtonClicked`, `onThreeDSecureChallenge`, `onDeliveryAddressChanged`, `onSessionExpired`, `onPaymentSessionExpired` | Instance-level bag callbacks | [guide §4 tables](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#instance-events) |
| 7 | `onChange`, `onFocus`, `onReady`, `onValidate`, `onValidationChange`, `onStateChanged`, `onSaveInstrumentCheckboxChanged`, `onPreferredSchemeChanged`, `onBillingAddressChanged`, `onPaymentOptionSelected` (in Payrails element options) | Element-level bag callbacks | [guide §4 tables](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#element-events) |
| 8 | `onGooglePayAvailable`, `onApplePayAvailable`, `onPaypalAvailable` | Availability callbacks → promise | [guide §5](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#5-wallet-availability-is-a-promise-not-an-event) |
| 9 | `styles:` inside options of `cardForm(`, `paymentButton(`, `dropin(`, `cardList(`, `dynamicElement(`, `genericRedirectButton(`, `leanButton(`, `collectContainer(` | Structured styles → appearance | [guide §6](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#6-styles-becomes-appearance) |
| 10 | `inputStyles`, `labelStyles`, `errorTextStyles` | Dead collect-element style fields | [guide §6](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#collect-elements-field-by-field-mapping) |
| 11 | `PayrailsContainerType`, `containerType` | Removed type / option | [guide §7](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#7-typescript-changes) |

Do **not** flag these — they are unchanged or correct in v6:

* `styles` on standalone `googlePayButton` / `applePayButton` / `paypalButton`
  (provider chrome), and under `paymentMethodsConfiguration.<method>.styles`.
* `events: { onClientInitialized }` at `Payrails.init` — the one surviving bag
  callback (the handler body may still need item 4).
* Existing `.on(...)` subscriptions, `setSavedInstrument`, `setState`,
  `payrails.api(...)`, `translations`, `fonts`.

Also check the deployment configuration: if the site sets a
Content-Security-Policy, `assets.payrails.io` must be allowed in `script-src`
and `style-src`. You usually cannot change this yourself — escalate it.

## Phase 2: Execute

Work in this order; run the project's type-check after each step so regressions
localize to the step that caused them.

1. **Upgrade the dependency** to `@payrails/web-sdk@6` with the project's
   package manager.
2. **Make init awaited** (inventory 1): add `await`, propagate async up through
   the callers, and add rejection handling for `PAYRAILS_INIT_FAILED` where
   other init errors are handled. In SSR frameworks, ensure the call runs only
   in the browser ([guide §1](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#1-payrails-init-is-asynchronous)).
3. **Delete the CSS import** (inventory 2) and any bundler config that
   referenced it.
4. **Delete **`preloadCardForm()`** calls** (inventory 3).
5. **Update **`onClientInitialized`** handler bodies** (inventory 4): the argument
   is the plain response object; helper calls move to the `payrails` instance
   per
   [guide §3](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#3-onclientinitialized-receives-the-execution-response-object).
6. **Replace event bags with **`.on()` (inventory 5–7) using the mapping tables
   in
   [guide §4](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#4-typed-on-event-api-replaces-events--callback-bags).
   Three semantic traps — a mechanical rename is NOT enough:
   * Boolean-return gates (`onRequestStart`, `onButtonClicked`,
     `onDeliveryAddressChanged`) must call `event.preventDefault()`; a thrown
     error no longer blocks the payment.
   * Payment-outcome listeners are session-wide. If the page mounts more than
     one payment element, add `event.paymentMethodCode` / `event.action` filters
     to reproduce the old per-element behavior.
   * `failed` payloads carry the error in `event.data` (`e.data?.code`), not at
     the top level.
7. **Replace availability callbacks** (inventory 8) with
   `await button.isAvailable`
   ([guide §5](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#5-wallet-availability-is-a-promise-not-an-event)).
8. **Migrate styling** (inventory 9–10) to `appearance` using the per-element
   mapping tables in [guide §6](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#6-styles-becomes-appearance).
   Translate each v5 style key via the tables; do not guess selectors. Watch the
   three special cases: drop-in wallet-button chrome moves to
   `paymentMethodsConfiguration.<method>.styles`, Revolut Pay uses
   `revolutOptions`, the Lean dialog uses `dialogCustomization`.
9. **Clean up types** (inventory 11) per
   [guide §7](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#7-typescript-changes).

## Phase 3: Verify

1. **Re-run the Phase 1 inventory.** Items 1–11 must return no unmigrated hits
   (modulo the do-not-flag list).
2. **Type-check and build** the project; both must pass.
3. **Runtime smoke test, if you can run the app:** load the checkout page and
   confirm `Payrails.init` resolves (bundle and stylesheet load from
   `assets.payrails.io`), the payment elements render styled, and no
   `PAYRAILS_INIT_FAILED` error appears in the console.
4. **Report** to the human: version migrated from/to, work items found and fixed
   per inventory row, behavior-affecting choices you made (e.g. where you added
   `paymentMethodCode` filters), and every escalation item below that applies.

## Escalate to a human

Report these instead of deciding yourself:

* **CSP changes** — `assets.payrails.io` in `script-src`/`style-src` is usually
  infrastructure config outside the repo.
* **Visual sign-off** — v6 ships a redesign
  ([guide §8](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#8-refreshed-visual-design)); a human must approve
  the new look and any re-created custom styling.
* **Real payment verification** — completing a test payment in the `TEST`
  environment, 3DS challenges, wallet sheets, and session-expiry refresh need a
  human (or explicit instruction) to exercise.
* **Ambiguous event logic** — if a v5 callback's body encoded per-element
  assumptions you cannot confidently reproduce with filters, show both versions
  and ask.

## Reference map

* [Migration guide](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide) — every breaking change with before/after
  code. Your primary instruction source.
* [Payrails class reference](/docs/orchestration/checkout-sdks/web/references/payrails-api-reference) — option types,
  methods, exports.
* [Events reference](/docs/orchestration/checkout-sdks/web/references/event-api-reference) — every event with
  payload types and cancelation semantics.
* [Migration guide §6](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide#6-styles-becomes-appearance) — the
  authoritative `styles` → `appearance` mapping.
* [Appearance reference](/docs/orchestration/checkout-sdks/web/references/appearance-api-reference) — the
  `appearance` types, rule semantics, and per-element class contract.
* [Getting started](/docs/orchestration/checkout-sdks/web/index) — hub for the remaining how-to
  guides.

<br />


## Related topics

- [v6 Migration Guide for Humans](/docs/orchestration/checkout-sdks/web/v6-migration/v6-migration-guide.md)
- [Token Migration](/docs/token-vault/token-migration/index.md)
- [Self-served migration of card data from PSPs](/docs/token-vault/token-migration/self-serve-migration.md)
