Agent Runbook - v6 Migration

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 — 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.
  • 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 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 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 forMeaningFix per
1Payrails.init(Init calls that must become awaitedguide §1
2payrails-styles.cssCSS import that no longer resolvesguide §1
3preloadCardFormRemoved static methodguide §2
4onClientInitializedArgument/helper changes inside handlerguide §3
5events: inside options of dropin(, cardForm(, paymentButton(, googlePayButton(, applePayButton(, paypalButton(, leanButton(, genericRedirectButton(, dynamicElement(Removed callback bagsguide §4
6onAuthorizeSuccess, onAuthorizeFailed, onAuthorizePending, onSuccess, onFailed, onPending, onRequestStart, onButtonClicked, onPaymentButtonClicked, onThreeDSecureChallenge, onDeliveryAddressChanged, onSessionExpired, onPaymentSessionExpiredInstance-level bag callbacksguide §4 tables
7onChange, onFocus, onReady, onValidate, onValidationChange, onStateChanged, onSaveInstrumentCheckboxChanged, onPreferredSchemeChanged, onBillingAddressChanged, onPaymentOptionSelected (in Payrails element options)Element-level bag callbacksguide §4 tables
8onGooglePayAvailable, onApplePayAvailable, onPaypalAvailableAvailability callbacks → promiseguide §5
9styles: inside options of cardForm(, paymentButton(, dropin(, cardList(, dynamicElement(, genericRedirectButton(, leanButton(, collectContainer(Structured styles → appearanceguide §6
10inputStyles, labelStyles, errorTextStylesDead collect-element style fieldsguide §6
11PayrailsContainerType, containerTypeRemoved type / optionguide §7

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).
  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.
  6. Replace event bags with .on() (inventory 5–7) using the mapping tables
    in
    guide §4.
    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).
  8. Migrate styling (inventory 9–10) to appearance using the per-element
    mapping tables in guide §6.
    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.

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 changesassets.payrails.io in script-src/style-src is usually
    infrastructure config outside the repo.
  • Visual sign-off — v6 ships a redesign
    (guide §8); 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



Did this page help you?