v1 to v2 Migration Guide
This guide covers what changed between SDK v1 (@zkp2p/pay-sdk@1.x) and v2
(@zkp2p/pay-sdk@2.0.0 / @zkp2p/pay-shared@2.0.0).
Required SDK Upgrade
npm install @zkp2p/pay-sdk@2.0.0 @zkp2p/pay-shared@2.0.0
Summary
v2 unifies Zelle on a single rail. Previously a Zelle payment could carry a
bank-specific rail value (zelle-chase, zelle-bofa, zelle-citi); as of v2
the rail is always the base platform:
payment.railis alwayszellefor Zelle payments — in API responses, checkout aggregates, and webhook payloads.- The customer's bank pick is exposed separately as the new
payment.paymentMethodIdfield (zelle-chase|zelle-bofa|zelle-citi,nullfor non-Zelle rails). It is display/routing metadata, not a rail. enabledRailsandpreselectedMethodcontinue to use base platform values (zelle) — nothing changes there.
Breaking Changes
payment.rail no longer carries Zelle bank variants
If your integration matched on zelle-chase, zelle-bofa, or zelle-citi
(for example in webhook handlers or reconciliation), match on zelle instead.
Read the bank from payment.paymentMethodId if you need it for display.
// v1
if (payment.rail.startsWith('zelle')) { /* ... */ }
// v2
if (payment.rail === 'zelle') {
const bank = payment.paymentMethodId; // 'zelle-chase' | 'zelle-bofa' | 'zelle-citi' | null
}
Historic payments created before the cutover keep their original stored rail values in your records; only new payments are affected.
Removed @zkp2p/pay-shared exports
The following Zelle-variant helpers were removed. They existed to support the retired per-bank rails and have no v2 equivalent because quoting and settlement are now variant-free:
ZELLE_QUOTE_PLATFORMSexpandZelleQuotePlatformszelleCompatibleMethodsSUPPORTED_ZELLE_RAIL_VARIANTSisSupportedZelleRailVariant
If you validated bank picks with isSupportedZelleRailVariant, use the new
ZELLE_PAYMENT_METHOD_IDS set instead.
Renamed export
ZELLE_VARIANT_ACTION_SUFFIX→ZELLE_METHOD_ACTION_SUFFIX(same keys and values; now keyed bypaymentMethodId).
New in v2
payment.paymentMethodIdon payment objects (see TypeScript Types).- Create-payment accepts an optional
paymentMethodIdwhenrailiszelle(zelle-chase|zelle-bofa|zelle-citi). Hosted checkout sends it automatically; direct API integrations may pass it to preserve the customer's bank pick across sessions. - New
@zkp2p/pay-sharedhelpers:ZELLE_PAYMENT_METHOD_IDS,ZELLE_BUYER_TEE_ACTION_TYPES,isGenericZellePaymentMethodHash.
No Action Needed If…
- You only use
createCheckout/ hosted checkout URLs and handle webhooks by order status: nothing in your integration observes Zelle bank variants. - You already treat
railvalues as opaque base-platform strings.