@payment-kit-js/vanilla 0.4.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/airwallex-apple-pay-adapter-BE15xREr.mjs +237 -0
  2. package/dist/airwallex-apple-pay-adapter-BE15xREr.mjs.map +1 -0
  3. package/dist/airwallex-apple-pay-adapter-I_pnNYdy.d.mts +98 -0
  4. package/dist/airwallex-apple-pay-adapter-I_pnNYdy.d.mts.map +1 -0
  5. package/dist/{airwallex-google-pay-adapter-BCmTZip5.mjs → airwallex-google-pay-adapter-CHol_8f2.mjs} +1 -1
  6. package/dist/{airwallex-google-pay-adapter-BCmTZip5.mjs.map → airwallex-google-pay-adapter-CHol_8f2.mjs.map} +1 -1
  7. package/dist/{airwallex-google-pay-adapter-Be2Af4N9.d.mts → airwallex-google-pay-adapter-CY379Rre.d.mts} +1 -1
  8. package/dist/{airwallex-google-pay-adapter-Be2Af4N9.d.mts.map → airwallex-google-pay-adapter-CY379Rre.d.mts.map} +1 -1
  9. package/dist/cdn/paymentkit.js +789 -420
  10. package/dist/cdn/paymentkit.js.map +4 -4
  11. package/dist/cdn/paymentkit.min.js +6 -6
  12. package/dist/cdn/paymentkit.min.js.map +4 -4
  13. package/dist/{connect-card-BrtCmsjz.mjs → connect-card-CMZkeppE.mjs} +1 -1
  14. package/dist/{connect-card-BrtCmsjz.mjs.map → connect-card-CMZkeppE.mjs.map} +1 -1
  15. package/dist/{connect-card-DTfXuTsW.d.mts → connect-card-Cxy51W6t.d.mts} +1 -1
  16. package/dist/{connect-card-DTfXuTsW.d.mts.map → connect-card-Cxy51W6t.d.mts.map} +1 -1
  17. package/dist/connect-tunnel-x-BhVAej5Q.mjs.map +1 -1
  18. package/dist/{connect-tunnel-x-Dxcg5Y7Y.d.mts → connect-tunnel-x-lv6Wtdme.d.mts} +6 -1
  19. package/dist/connect-tunnel-x-lv6Wtdme.d.mts.map +1 -0
  20. package/dist/index.d.mts +3 -3
  21. package/dist/index.d.mts.map +1 -1
  22. package/dist/index.mjs +76 -14
  23. package/dist/index.mjs.map +1 -1
  24. package/dist/{next-action-handlers-BZs04hYb.mjs → next-action-handlers-CTx8tRt0.mjs} +1 -1
  25. package/dist/{next-action-handlers-BZs04hYb.mjs.map → next-action-handlers-CTx8tRt0.mjs.map} +1 -1
  26. package/dist/payment-methods/airwallex-apple-pay-adapter.d.mts +2 -0
  27. package/dist/payment-methods/airwallex-apple-pay-adapter.mjs +3 -0
  28. package/dist/payment-methods/airwallex-google-pay-adapter.d.mts +1 -1
  29. package/dist/payment-methods/airwallex-google-pay-adapter.mjs +1 -1
  30. package/dist/payment-methods/apple-pay.d.mts +37 -17
  31. package/dist/payment-methods/apple-pay.d.mts.map +1 -1
  32. package/dist/payment-methods/apple-pay.mjs +203 -37
  33. package/dist/payment-methods/apple-pay.mjs.map +1 -1
  34. package/dist/payment-methods/card.d.mts +3 -3
  35. package/dist/payment-methods/card.d.mts.map +1 -1
  36. package/dist/payment-methods/card.mjs +208 -41
  37. package/dist/payment-methods/card.mjs.map +1 -1
  38. package/dist/payment-methods/google-pay.d.mts +5 -5
  39. package/dist/payment-methods/google-pay.d.mts.map +1 -1
  40. package/dist/payment-methods/google-pay.mjs +6 -7
  41. package/dist/payment-methods/google-pay.mjs.map +1 -1
  42. package/dist/payment-methods/next-action-handlers.mjs +1 -1
  43. package/dist/payment-methods/paypal.d.mts +3 -3
  44. package/dist/payment-methods/paypal.mjs +3 -3
  45. package/dist/payment-methods/paypal.mjs.map +1 -1
  46. package/dist/payment-methods/stripe-apple-pay-adapter.d.mts +1 -1
  47. package/dist/payment-methods/stripe-apple-pay-adapter.mjs +1 -1
  48. package/dist/payment-methods/stripe-google-pay-adapter.d.mts +1 -1
  49. package/dist/payment-methods/stripe-google-pay-adapter.mjs +1 -1
  50. package/dist/payment-methods/vgs-collect-loader.d.mts +28 -0
  51. package/dist/payment-methods/vgs-collect-loader.d.mts.map +1 -0
  52. package/dist/payment-methods/vgs-collect-loader.mjs +3 -0
  53. package/dist/penpal/connect-card.d.mts +1 -1
  54. package/dist/penpal/connect-card.mjs +1 -1
  55. package/dist/penpal/connect-tunnel-x.d.mts +1 -1
  56. package/dist/{stripe-apple-pay-adapter-Bg7nCy3P.mjs → stripe-apple-pay-adapter-Cd9LVNnp.mjs} +1 -1
  57. package/dist/{stripe-apple-pay-adapter-Bg7nCy3P.mjs.map → stripe-apple-pay-adapter-Cd9LVNnp.mjs.map} +1 -1
  58. package/dist/{stripe-apple-pay-adapter-Bq3f1mqv.d.mts → stripe-apple-pay-adapter-DhpGclW9.d.mts} +1 -1
  59. package/dist/{stripe-apple-pay-adapter-Bq3f1mqv.d.mts.map → stripe-apple-pay-adapter-DhpGclW9.d.mts.map} +1 -1
  60. package/dist/{stripe-google-pay-adapter-xktEycOD.d.mts → stripe-google-pay-adapter-C3NCBSO3.d.mts} +1 -1
  61. package/dist/{stripe-google-pay-adapter-xktEycOD.d.mts.map → stripe-google-pay-adapter-C3NCBSO3.d.mts.map} +1 -1
  62. package/dist/{stripe-google-pay-adapter-DjrgDYWe.mjs → stripe-google-pay-adapter-CqcUEoM3.mjs} +1 -1
  63. package/dist/{stripe-google-pay-adapter-DjrgDYWe.mjs.map → stripe-google-pay-adapter-CqcUEoM3.mjs.map} +1 -1
  64. package/dist/{types-CPuloCtF.d.mts → types-CZk3V0Qt.d.mts} +24 -6
  65. package/dist/types-CZk3V0Qt.d.mts.map +1 -0
  66. package/dist/{utils-Dgyk7RkM.mjs → utils-B70Y8YcZ.mjs} +20 -9
  67. package/dist/utils-B70Y8YcZ.mjs.map +1 -0
  68. package/dist/vgs-collect-loader-D3_xOA-G.mjs +93 -0
  69. package/dist/vgs-collect-loader-D3_xOA-G.mjs.map +1 -0
  70. package/package.json +4 -2
  71. package/dist/connect-tunnel-x-Dxcg5Y7Y.d.mts.map +0 -1
  72. package/dist/types-CPuloCtF.d.mts.map +0 -1
  73. package/dist/utils-Dgyk7RkM.mjs.map +0 -1
@@ -16,4 +16,4 @@ const connectToCardParent = (methods) => {
16
16
 
17
17
  //#endregion
18
18
  export { connectToCardParent as n, connectToCardIframe as t };
19
- //# sourceMappingURL=connect-card-BrtCmsjz.mjs.map
19
+ //# sourceMappingURL=connect-card-CMZkeppE.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect-card-BrtCmsjz.mjs","names":[],"sources":["../src/penpal/connect-card.ts"],"sourcesContent":["import type { CardSetupIntent, PublicCardCheckoutResponse } from \"@pkg/sdk/models\";\nimport type { Connection } from \"penpal\";\nimport { connectToWindow } from \".\";\n\ntype CardIFrameMethods = {\n onSubmit: (cardSetupIntentId: string) => Promise<CardSetupIntent | { error: CardErrorCode }>;\n onValidate: () => Promise<CardErrorCode | undefined>;\n};\n\ntype CardParentMethods = {\n onLoaded: () => void;\n onFocusChange: (isFocused: boolean) => void;\n};\n\nexport type CardInputType = \"card_pan\" | \"card_exp\" | \"card_cvc\";\n\nexport type CardErrorCode =\n | \"invalid\"\n | \"required\"\n | \"unknown_error\"\n | \"penpal_not_connected\"\n | \"missing_checkout_token\";\n\nexport type IFrameConnection = Connection<CardIFrameMethods>;\n\nexport type ParentConnection = Connection<CardParentMethods>;\n\nexport type CheckoutResponse = PublicCardCheckoutResponse;\n\nexport const connectToCardIframe = (iframe: HTMLIFrameElement, methods: CardParentMethods) => {\n return connectToWindow<CardIFrameMethods>({ window: iframe.contentWindow as Window, methods });\n};\n\nexport const connectToCardParent = (methods: CardIFrameMethods) => {\n return connectToWindow<CardParentMethods>({ window: window.parent, methods });\n};\n"],"mappings":";;;AA6BA,MAAa,uBAAuB,QAA2B,YAA+B;AAC5F,QAAO,gBAAmC;EAAE,QAAQ,OAAO;EAAyB;EAAS,CAAC;;AAGhG,MAAa,uBAAuB,YAA+B;AACjE,QAAO,gBAAmC;EAAE,QAAQ,OAAO;EAAQ;EAAS,CAAC"}
1
+ {"version":3,"file":"connect-card-CMZkeppE.mjs","names":[],"sources":["../src/penpal/connect-card.ts"],"sourcesContent":["import type { CardSetupIntent, PublicCardCheckoutResponse } from \"@pkg/sdk/models\";\nimport type { Connection } from \"penpal\";\nimport { connectToWindow } from \".\";\n\ntype CardIFrameMethods = {\n onSubmit: (cardSetupIntentId: string) => Promise<CardSetupIntent | { error: CardErrorCode }>;\n onValidate: () => Promise<CardErrorCode | undefined>;\n};\n\ntype CardParentMethods = {\n onLoaded: () => void;\n onFocusChange: (isFocused: boolean) => void;\n};\n\nexport type CardInputType = \"card_pan\" | \"card_exp\" | \"card_cvc\";\n\nexport type CardErrorCode =\n | \"invalid\"\n | \"required\"\n | \"unknown_error\"\n | \"penpal_not_connected\"\n | \"missing_checkout_token\";\n\nexport type IFrameConnection = Connection<CardIFrameMethods>;\n\nexport type ParentConnection = Connection<CardParentMethods>;\n\nexport type CheckoutResponse = PublicCardCheckoutResponse;\n\nexport const connectToCardIframe = (iframe: HTMLIFrameElement, methods: CardParentMethods) => {\n return connectToWindow<CardIFrameMethods>({ window: iframe.contentWindow as Window, methods });\n};\n\nexport const connectToCardParent = (methods: CardIFrameMethods) => {\n return connectToWindow<CardParentMethods>({ window: window.parent, methods });\n};\n"],"mappings":";;;AA6BA,MAAa,uBAAuB,QAA2B,YAA+B;AAC5F,QAAO,gBAAmC;EAAE,QAAQ,OAAO;EAAyB;EAAS,CAAC;;AAGhG,MAAa,uBAAuB,YAA+B;AACjE,QAAO,gBAAmC;EAAE,QAAQ,OAAO;EAAQ;EAAS,CAAC"}
@@ -20,4 +20,4 @@ declare const connectToCardIframe: (iframe: HTMLIFrameElement, methods: CardPare
20
20
  declare const connectToCardParent: (methods: CardIFrameMethods) => Connection<CardParentMethods>;
21
21
  //#endregion
22
22
  export { ParentConnection as a, IFrameConnection as i, CardInputType as n, connectToCardIframe as o, CheckoutResponse as r, connectToCardParent as s, CardErrorCode as t };
23
- //# sourceMappingURL=connect-card-DTfXuTsW.d.mts.map
23
+ //# sourceMappingURL=connect-card-Cxy51W6t.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect-card-DTfXuTsW.d.mts","names":[],"sources":["../src/penpal/connect-card.ts"],"sourcesContent":[],"mappings":";;;KAIK,iBAAA;EAAA,QAAA,EAAA,CAAA,iBAAiB,EAAA,MAAA,EAAA,GACqB,OADrB,CAC6B,eAD7B,GAAA;IAC6B,KAAA,EAA2B,aAA3B;EAA2B,CAAA,CAAA;EAAnC,UAAA,EAAA,GAAA,GACvB,OADuB,CACf,aADe,GAAA,SAAA,CAAA;CACf;KAGvB,iBAAA,GAHe;EAAO,QAAA,EAAA,GAAA,GAAA,IAAA;EAGtB,aAAA,EAAA,CAAA,SAAiB,EAAA,OAAA,EAAA,GAAA,IAAA;AAKtB,CAAA;AAEY,KAFA,aAAA,GAEa,UAAA,GAAA,UAAA,GAAA,UAAA;AAOb,KAPA,aAAA,GAOgB,SAAc,GAAA,UAAA,GAAA,eAAD,GAAA,sBAAA,GAAA,wBAAA;AAE7B,KAFA,gBAAA,GAAmB,UAEW,CAFA,iBAEX,CAAA;AAEnB,KAFA,gBAAA,GAAmB,UAEA,CAFW,iBAEX,CAAA;AAElB,KAFD,gBAAA,GAAmB,0BAI9B;AAF2C,cAA/B,mBAA+B,EAAA,CAAA,MAAA,EAAA,iBAAA,EAAA,OAAA,EAA4B,iBAA5B,EAAA,GAA6C,UAA7C,CAA6C,iBAA7C,CAAA;AAA4B,cAI3D,mBAJ2D,EAAA,CAAA,OAAA,EAI3B,iBAJ2B,EAAA,GAIV,UAJU,CAIV,iBAJU,CAAA"}
1
+ {"version":3,"file":"connect-card-Cxy51W6t.d.mts","names":[],"sources":["../src/penpal/connect-card.ts"],"sourcesContent":[],"mappings":";;;KAIK,iBAAA;EAAA,QAAA,EAAA,CAAA,iBAAiB,EAAA,MAAA,EAAA,GACqB,OADrB,CAC6B,eAD7B,GAAA;IAC6B,KAAA,EAA2B,aAA3B;EAA2B,CAAA,CAAA;EAAnC,UAAA,EAAA,GAAA,GACvB,OADuB,CACf,aADe,GAAA,SAAA,CAAA;CACf;KAGvB,iBAAA,GAHe;EAAO,QAAA,EAAA,GAAA,GAAA,IAAA;EAGtB,aAAA,EAAA,CAAA,SAAiB,EAAA,OAAA,EAAA,GAAA,IAAA;AAKtB,CAAA;AAEY,KAFA,aAAA,GAEa,UAAA,GAAA,UAAA,GAAA,UAAA;AAOb,KAPA,aAAA,GAOgB,SAAc,GAAA,UAAA,GAAA,eAAD,GAAA,sBAAA,GAAA,wBAAA;AAE7B,KAFA,gBAAA,GAAmB,UAEW,CAFA,iBAEX,CAAA;AAEnB,KAFA,gBAAA,GAAmB,UAEA,CAFW,iBAEX,CAAA;AAElB,KAFD,gBAAA,GAAmB,0BAI9B;AAF2C,cAA/B,mBAA+B,EAAA,CAAA,MAAA,EAAA,iBAAA,EAAA,OAAA,EAA4B,iBAA5B,EAAA,GAA6C,UAA7C,CAA6C,iBAA7C,CAAA;AAA4B,cAI3D,mBAJ2D,EAAA,CAAA,OAAA,EAI3B,iBAJ2B,EAAA,GAIV,UAJU,CAIV,iBAJU,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"connect-tunnel-x-BhVAej5Q.mjs","names":[],"sources":["../src/penpal/connect-tunnel-x.ts"],"sourcesContent":["import type { RequestOptions } from \"@pkg/sdk/lib/sdks\";\nimport type {\n CardSetupIntent,\n CreateCardSetupIntentRes,\n PublicCardCheckoutRequest,\n PublicCardCheckoutResponse,\n} from \"@pkg/sdk/models\";\nimport type { Connection } from \"penpal\";\nimport { connectToWindow } from \".\";\n\n// Note: this file is paired with customer-portal/src/routes/embeds/v1/tunnel-x\n// The methods below should also be present in CheckoutTunnelX\n\ntype TunnelXIFrameMethods = {\n startPayment: () => void;\n confirmPayment: () => void;\n submitCheckout: (values: Record<string, string>) => Promise<unknown>;\n getCheckoutPreview: () => void;\n getCardSetupIntent: (cardSetupIntentId: string) => Promise<CardSetupIntent>;\n createCardSetupIntent: (secureToken: string) => Promise<CreateCardSetupIntentRes>;\n queryPublicEndpoint: (methodName: string, params: unknown, options?: RequestOptions) => Promise<unknown>;\n};\n\ntype TunnelXParentMethods = Record<string, never>;\n\nexport type TunnelXIFrameConnection = Connection<TunnelXIFrameMethods>;\n\nexport type TunnelXParentConnection = Connection<TunnelXParentMethods>;\n\nexport const connectToTunnelXIframe = (iframe: HTMLIFrameElement, methods: TunnelXParentMethods) => {\n return connectToWindow<TunnelXIFrameMethods>({ window: iframe.contentWindow as Window, methods });\n};\n\nexport const connectToTunnelXParent = (methods: TunnelXIFrameMethods) => {\n return connectToWindow<TunnelXParentMethods>({ window: window.parent, methods });\n};\n\n/**\n * SDK type for publicEndpoints proxy.\n * Matches the methods on PublicCors from @pkg/sdk that are called through queryPublicEndpoint.\n * Parameter types match the SDK's operation request types.\n * All methods accept an optional RequestOptions parameter for passing headers (e.g., x-request-id).\n */\ntype PublicEndpointsProxy = {\n createCardSetupIntent: (\n params: { checkoutToken: string },\n options?: RequestOptions,\n ) => Promise<CreateCardSetupIntentRes>;\n getCardSetupIntent: (\n params: { checkoutToken: string; cardSetupIntentId: string },\n options?: RequestOptions,\n ) => Promise<CardSetupIntent>;\n cardCheckout: (\n params: {\n checkoutToken: string;\n publicCardCheckoutRequest: PublicCardCheckoutRequest;\n },\n options?: RequestOptions,\n ) => Promise<PublicCardCheckoutResponse>;\n cardCheckoutVerify: (\n params: { checkoutToken: string },\n options?: RequestOptions,\n ) => Promise<PublicCardCheckoutResponse>;\n};\n\nexport class TunnelXManager {\n private penpalConn: TunnelXIFrameConnection;\n public _methods: TunnelXIFrameMethods;\n\n static createFromPenpalConnection = async (penpalConn: TunnelXIFrameConnection) => {\n const methods = await penpalConn.promise;\n const manager = new TunnelXManager(penpalConn, methods);\n return manager;\n };\n\n private constructor(penpalConn: TunnelXIFrameConnection, penpalMethods: TunnelXIFrameMethods) {\n this.penpalConn = penpalConn;\n this._methods = penpalMethods;\n }\n\n /**\n * Makes publicEndpoints act like a real PK client, but actually forwards all calls\n * through queryPublicEndpoint and sends it through penpal.\n */\n get publicEndpoints(): PublicEndpointsProxy {\n const handler = {\n get: (_target: Record<string, never>, prop: string) => {\n return async (...args: unknown[]) => {\n return await this._methods.queryPublicEndpoint(prop, args[0], args[1] as RequestOptions | undefined);\n };\n },\n };\n return new Proxy({}, handler) as unknown as PublicEndpointsProxy;\n }\n\n destroy() {\n this.penpalConn.destroy();\n }\n}\n"],"mappings":";;;AA6BA,MAAa,0BAA0B,QAA2B,YAAkC;AAClG,QAAO,gBAAsC;EAAE,QAAQ,OAAO;EAAyB;EAAS,CAAC;;AAGnG,MAAa,0BAA0B,YAAkC;AACvE,QAAO,gBAAsC;EAAE,QAAQ,OAAO;EAAQ;EAAS,CAAC;;AA+BlF,IAAa,iBAAb,MAAa,eAAe;CAC1B,AAAQ;CACR,AAAO;CAEP,OAAO,6BAA6B,OAAO,eAAwC;AAGjF,SADgB,IAAI,eAAe,YADnB,MAAM,WAAW,QACsB;;CAIzD,AAAQ,YAAY,YAAqC,eAAqC;AAC5F,OAAK,aAAa;AAClB,OAAK,WAAW;;;;;;CAOlB,IAAI,kBAAwC;AAQ1C,SAAO,IAAI,MAAM,EAAE,EAPH,EACd,MAAM,SAAgC,SAAiB;AACrD,UAAO,OAAO,GAAG,SAAoB;AACnC,WAAO,MAAM,KAAK,SAAS,oBAAoB,MAAM,KAAK,IAAI,KAAK,GAAiC;;KAGzG,CAC4B;;CAG/B,UAAU;AACR,OAAK,WAAW,SAAS"}
1
+ {"version":3,"file":"connect-tunnel-x-BhVAej5Q.mjs","names":[],"sources":["../src/penpal/connect-tunnel-x.ts"],"sourcesContent":["import type { RequestOptions } from \"@pkg/sdk/lib/sdks\";\nimport type {\n CardSetupIntent,\n CreateCardSetupIntentRes,\n PublicCardCheckoutRequest,\n PublicCardCheckoutResponse,\n UpdateCardSetupIntentReq,\n} from \"@pkg/sdk/models\";\nimport type { Connection } from \"penpal\";\nimport { connectToWindow } from \".\";\n\n// Note: this file is paired with customer-portal/src/routes/embeds/v1/tunnel-x\n// The methods below should also be present in CheckoutTunnelX\n\ntype TunnelXIFrameMethods = {\n startPayment: () => void;\n confirmPayment: () => void;\n submitCheckout: (values: Record<string, string>) => Promise<unknown>;\n getCheckoutPreview: () => void;\n getCardSetupIntent: (cardSetupIntentId: string) => Promise<CardSetupIntent>;\n createCardSetupIntent: (secureToken: string) => Promise<CreateCardSetupIntentRes>;\n queryPublicEndpoint: (methodName: string, params: unknown, options?: RequestOptions) => Promise<unknown>;\n};\n\ntype TunnelXParentMethods = Record<string, never>;\n\nexport type TunnelXIFrameConnection = Connection<TunnelXIFrameMethods>;\n\nexport type TunnelXParentConnection = Connection<TunnelXParentMethods>;\n\nexport const connectToTunnelXIframe = (iframe: HTMLIFrameElement, methods: TunnelXParentMethods) => {\n return connectToWindow<TunnelXIFrameMethods>({ window: iframe.contentWindow as Window, methods });\n};\n\nexport const connectToTunnelXParent = (methods: TunnelXIFrameMethods) => {\n return connectToWindow<TunnelXParentMethods>({ window: window.parent, methods });\n};\n\n/**\n * SDK type for publicEndpoints proxy.\n * Matches the methods on PublicCors from @pkg/sdk that are called through queryPublicEndpoint.\n * Parameter types match the SDK's operation request types.\n * All methods accept an optional RequestOptions parameter for passing headers (e.g., x-request-id).\n */\ntype PublicEndpointsProxy = {\n createCardSetupIntent: (\n params: { checkoutToken: string },\n options?: RequestOptions,\n ) => Promise<CreateCardSetupIntentRes>;\n updateCardSetupIntent: (\n params: {\n checkoutToken: string;\n cardSetupIntentId: string;\n updateCardSetupIntentReq: UpdateCardSetupIntentReq;\n },\n options?: RequestOptions,\n ) => Promise<CardSetupIntent>;\n getCardSetupIntent: (\n params: { checkoutToken: string; cardSetupIntentId: string },\n options?: RequestOptions,\n ) => Promise<CardSetupIntent>;\n cardCheckout: (\n params: {\n checkoutToken: string;\n publicCardCheckoutRequest: PublicCardCheckoutRequest;\n },\n options?: RequestOptions,\n ) => Promise<PublicCardCheckoutResponse>;\n cardCheckoutVerify: (\n params: { checkoutToken: string },\n options?: RequestOptions,\n ) => Promise<PublicCardCheckoutResponse>;\n};\n\nexport class TunnelXManager {\n private penpalConn: TunnelXIFrameConnection;\n public _methods: TunnelXIFrameMethods;\n\n static createFromPenpalConnection = async (penpalConn: TunnelXIFrameConnection) => {\n const methods = await penpalConn.promise;\n const manager = new TunnelXManager(penpalConn, methods);\n return manager;\n };\n\n private constructor(penpalConn: TunnelXIFrameConnection, penpalMethods: TunnelXIFrameMethods) {\n this.penpalConn = penpalConn;\n this._methods = penpalMethods;\n }\n\n /**\n * Makes publicEndpoints act like a real PK client, but actually forwards all calls\n * through queryPublicEndpoint and sends it through penpal.\n */\n get publicEndpoints(): PublicEndpointsProxy {\n const handler = {\n get: (_target: Record<string, never>, prop: string) => {\n return async (...args: unknown[]) => {\n return await this._methods.queryPublicEndpoint(prop, args[0], args[1] as RequestOptions | undefined);\n };\n },\n };\n return new Proxy({}, handler) as unknown as PublicEndpointsProxy;\n }\n\n destroy() {\n this.penpalConn.destroy();\n }\n}\n"],"mappings":";;;AA8BA,MAAa,0BAA0B,QAA2B,YAAkC;AAClG,QAAO,gBAAsC;EAAE,QAAQ,OAAO;EAAyB;EAAS,CAAC;;AAGnG,MAAa,0BAA0B,YAAkC;AACvE,QAAO,gBAAsC;EAAE,QAAQ,OAAO;EAAQ;EAAS,CAAC;;AAuClF,IAAa,iBAAb,MAAa,eAAe;CAC1B,AAAQ;CACR,AAAO;CAEP,OAAO,6BAA6B,OAAO,eAAwC;AAGjF,SADgB,IAAI,eAAe,YADnB,MAAM,WAAW,QACsB;;CAIzD,AAAQ,YAAY,YAAqC,eAAqC;AAC5F,OAAK,aAAa;AAClB,OAAK,WAAW;;;;;;CAOlB,IAAI,kBAAwC;AAQ1C,SAAO,IAAI,MAAM,EAAE,EAPH,EACd,MAAM,SAAgC,SAAiB;AACrD,UAAO,OAAO,GAAG,SAAoB;AACnC,WAAO,MAAM,KAAK,SAAS,oBAAoB,MAAM,KAAK,IAAI,KAAK,GAAiC;;KAGzG,CAC4B;;CAG/B,UAAU;AACR,OAAK,WAAW,SAAS"}
@@ -25,6 +25,11 @@ type PublicEndpointsProxy = {
25
25
  createCardSetupIntent: (params: {
26
26
  checkoutToken: string;
27
27
  }, options?: RequestOptions) => Promise<CreateCardSetupIntentRes>;
28
+ updateCardSetupIntent: (params: {
29
+ checkoutToken: string;
30
+ cardSetupIntentId: string;
31
+ updateCardSetupIntentReq: UpdateCardSetupIntentReq;
32
+ }, options?: RequestOptions) => Promise<CardSetupIntent>;
28
33
  getCardSetupIntent: (params: {
29
34
  checkoutToken: string;
30
35
  cardSetupIntentId: string;
@@ -51,4 +56,4 @@ declare class TunnelXManager {
51
56
  }
52
57
  //#endregion
53
58
  export { connectToTunnelXParent as a, connectToTunnelXIframe as i, TunnelXManager as n, TunnelXParentConnection as r, TunnelXIFrameConnection as t };
54
- //# sourceMappingURL=connect-tunnel-x-Dxcg5Y7Y.d.mts.map
59
+ //# sourceMappingURL=connect-tunnel-x-lv6Wtdme.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-tunnel-x-lv6Wtdme.d.mts","names":[],"sources":["../src/penpal/connect-tunnel-x.ts"],"sourcesContent":[],"mappings":";;;AAQyC,KAMpC,oBAAA,GAAoB;EAGE,YAAA,EAAA,GAAA,GAAA,IAAA;EAA2B,cAAA,EAAA,GAAA,GAAA,IAAA;EAEO,cAAA,EAAA,CAAA,MAAA,EAFlC,MAEkC,CAAA,MAAA,EAAA,MAAA,CAAA,EAAA,GAFP,OAEO,CAAA,OAAA,CAAA;EAAR,kBAAA,EAAA,GAAA,GAAA,IAAA;EACK,kBAAA,EAAA,CAAA,iBAAA,EAAA,MAAA,EAAA,GADL,OACK,CADG,eACH,CAAA;EAAR,qBAAA,EAAA,CAAA,WAAA,EAAA,MAAA,EAAA,GAAA,OAAA,CAAQ,wBAAR,CAAA;EACqB,mBAAA,EAAA,CAAA,UAAA,EAAA,MAAA,EAAA,MAAA,EAAA,OAAA,EAAA,OAAA,CAAA,EAAA,cAAA,EAAA,GAAmB,OAAnB,CAAA,OAAA,CAAA;CAAmB;KAGrF,oBAAA,GAAuB,MAHqE,CAAA,MAAA,EAAA,KAAA,CAAA;AAG5F,KAEO,uBAAA,GAA0B,UAFJ,CAEe,oBAFf,CAAA;AAEtB,KAEA,uBAAA,GAA0B,UAFW,CAEA,oBAFX,CAAA;AAE1B,cAEC,sBAFoC,EAAA,CAAA,MAAA,EAEF,iBAFT,EAAA,OAAU,EAE2B,oBAF3B,EAAA,GAE+C,UAF/C,CAE+C,oBAF/C,CAAA;AAEnC,cAIA,sBAFZ,EAAA,CAAA,OAAA,EAE+C,oBAF/C,EAAA,GAEmE,UAFnE,CAEmE,oBAFnE,CAAA;;;;;;AAED;KAUK,oBAAA,GAV2C;EAAoB,qBAAA,EAAA,CAAA,MAAA,EAAA;IAAA,aAAA,EAAA,MAAA;EAAA,CAAA,EAAA,OAAA,CAAA,EAatD,cAbsD,EAAA,GAc7D,OAd6D,CAcrD,wBAdqD,CAAA;EAU/D,qBAAA,EAAoB,CAAA,MAAA,EAAA;IAGX,aAAA,EAAA,MAAA;IACC,iBAAA,EAAA,MAAA;IAAR,wBAAA,EAKyB,wBALzB;EAKyB,CAAA,EAAA,OAAA,CAAA,EAElB,cAFkB,EAAA,GAGzB,OAHyB,CAGjB,eAHiB,CAAA;EAElB,kBAAA,EAAA,CAAA,MAAA,EAAA;IACC,aAAA,EAAA,MAAA;IAAR,iBAAA,EAAA,MAAA;EAGO,CAAA,EAAA,OAAA,CAAA,EAAA,cAAA,EAAA,GACP,OADO,CACC,eADD,CAAA;EACC,YAAA,EAAA,CAAA,MAAA,EAAA;IAAR,aAAA,EAAA,MAAA;IAI0B,yBAAA,EAAA,yBAAA;EAEnB,CAAA,EAAA,OAAA,CAAA,EAAA,cAAA,EAAA,GACP,OADO,CACC,0BADD,CAAA;EACC,kBAAA,EAAA,CAAA,MAAA,EAAA;IAAR,aAAA,EAAA,MAAA;EAGO,CAAA,EAAA,OAAA,CAAA,EAAA,cAAA,EAAA,GACP,OADO,CACC,0BADD,CAAA;CACC;AAAR,cAGM,cAAA,CAHN;EAAO,QAAA,UAAA;EAGD,QAAA,EAEM,oBAFQ;EAER,OAAA,0BAAA,EAAA,CAAA,UAAA,EAEsC,uBAFtC,EAAA,GAE6D,OAF7D,CAE6D,cAF7D,CAAA;EAEsC,QAAA,WAAA,CAAA;EAAuB;;;;yBAevD"}
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import { n as PaymentKitFields, t as PaymentKit$1 } from "./types-CPuloCtF.mjs";
2
- import "./connect-card-DTfXuTsW.mjs";
3
- import "./connect-tunnel-x-Dxcg5Y7Y.mjs";
1
+ import { n as PaymentKitFields, t as PaymentKit$1 } from "./types-CZk3V0Qt.mjs";
2
+ import "./connect-card-Cxy51W6t.mjs";
3
+ import "./connect-tunnel-x-lv6Wtdme.mjs";
4
4
 
5
5
  //#region src/index.d.ts
6
6
  declare const PaymentKit: PaymentKit$1;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;cA0BM,YAAY"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;cA2BM,YAAY"}
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  import "./penpal-BFKeZTVz.mjs";
2
2
  import { n as connectToTunnelXIframe } from "./connect-tunnel-x-BhVAej5Q.mjs";
3
- import { r as createCheckoutIFrame } from "./utils-Dgyk7RkM.mjs";
3
+ import { o as getOrCreateCheckoutRequestId, r as createCheckoutIFrame } from "./utils-B70Y8YcZ.mjs";
4
4
  import posthog from "posthog-js";
5
5
 
6
6
  //#region package.json
7
- var version = "0.4.1";
7
+ var version = "0.5.2";
8
8
 
9
9
  //#endregion
10
10
  //#region src/analytics/mock-adapter.ts
@@ -238,7 +238,8 @@ const AnalyticsService = new AnalyticsServiceClass();
238
238
  * at appropriate points in the checkout flow.
239
239
  *
240
240
  * Usage:
241
- * const tracker = new CheckoutTimingTracker(secureToken);
241
+ * const requestId = getOrCreateCheckoutRequestId(environment);
242
+ * const tracker = new CheckoutTimingTracker(secureToken, requestId);
242
243
  * tracker.trackPageReady();
243
244
  * // ... iframe loads ...
244
245
  * tracker.trackInputReady();
@@ -251,10 +252,12 @@ var CheckoutTimingTracker = class CheckoutTimingTracker {
251
252
  static pageReadyTracked = false;
252
253
  startTime;
253
254
  checkoutSessionId;
255
+ requestId;
254
256
  inputReadyTracked = false;
255
- constructor(checkoutSessionId) {
257
+ constructor(checkoutSessionId, requestId) {
256
258
  this.startTime = performance.now();
257
259
  this.checkoutSessionId = checkoutSessionId;
260
+ this.requestId = requestId;
258
261
  }
259
262
  /**
260
263
  * Track when SDK is initialized and ready.
@@ -266,6 +269,7 @@ var CheckoutTimingTracker = class CheckoutTimingTracker {
266
269
  CheckoutTimingTracker.pageReadyTracked = true;
267
270
  AnalyticsService.capture("checkout_page_ready", {
268
271
  checkout_session_id: this.checkoutSessionId,
272
+ request_id: this.requestId,
269
273
  elapsed_ms: this.getElapsedMs()
270
274
  });
271
275
  }
@@ -279,6 +283,7 @@ var CheckoutTimingTracker = class CheckoutTimingTracker {
279
283
  this.inputReadyTracked = true;
280
284
  AnalyticsService.capture("checkout_input_ready", {
281
285
  checkout_session_id: this.checkoutSessionId,
286
+ request_id: this.requestId,
282
287
  elapsed_ms: this.getElapsedMs()
283
288
  });
284
289
  }
@@ -288,6 +293,7 @@ var CheckoutTimingTracker = class CheckoutTimingTracker {
288
293
  trackSubmit() {
289
294
  AnalyticsService.capture("checkout_submit", {
290
295
  checkout_session_id: this.checkoutSessionId,
296
+ request_id: this.requestId,
291
297
  elapsed_ms: this.getElapsedMs()
292
298
  });
293
299
  }
@@ -300,6 +306,7 @@ var CheckoutTimingTracker = class CheckoutTimingTracker {
300
306
  AnalyticsService.capture("checkout_success", {
301
307
  checkout_session_id: this.checkoutSessionId,
302
308
  checkout_attempt_id: checkoutAttemptId,
309
+ request_id: this.requestId,
303
310
  total_elapsed_ms: this.getElapsedMs()
304
311
  });
305
312
  }
@@ -314,6 +321,7 @@ var CheckoutTimingTracker = class CheckoutTimingTracker {
314
321
  AnalyticsService.capture("checkout_fail", {
315
322
  checkout_session_id: this.checkoutSessionId,
316
323
  checkout_attempt_id: checkoutAttemptId,
324
+ request_id: this.requestId,
317
325
  error_code: errorCode,
318
326
  error_message: errorMessage,
319
327
  total_elapsed_ms: this.getElapsedMs()
@@ -329,15 +337,11 @@ var CheckoutTimingTracker = class CheckoutTimingTracker {
329
337
 
330
338
  //#endregion
331
339
  //#region src/types.ts
332
- const ENVIRONMENT_URLS = {
340
+ const STATIC_ENVIRONMENT_URLS = {
333
341
  local: {
334
342
  baseUrl: "http://localhost:9101",
335
343
  apiBaseUrl: "http://localhost:9000"
336
344
  },
337
- loclx: {
338
- baseUrl: "https://pkmateuscportal.loclx.io",
339
- apiBaseUrl: "https://pkmateusapi.loclx.io"
340
- },
341
345
  sandbox: {
342
346
  baseUrl: "https://staging.paymentkit.com/customer",
343
347
  apiBaseUrl: "https://staging.paymentkit.com"
@@ -347,9 +351,28 @@ const ENVIRONMENT_URLS = {
347
351
  apiBaseUrl: "https://paymentkit.com"
348
352
  }
349
353
  };
354
+ function getTunnelUrls() {
355
+ if (typeof window !== "undefined") {
356
+ const apiBaseUrl = new URLSearchParams(window.location.search).get("api_base_url");
357
+ if (apiBaseUrl) return {
358
+ baseUrl: window.location.origin,
359
+ apiBaseUrl
360
+ };
361
+ const hostname = window.location.hostname;
362
+ if (hostname.includes("loclx.io")) {
363
+ const apiHostname = hostname.replace(/cportal|playground/, "api");
364
+ return {
365
+ baseUrl: `https://${hostname}`,
366
+ apiBaseUrl: `https://${apiHostname}`
367
+ };
368
+ }
369
+ }
370
+ return STATIC_ENVIRONMENT_URLS.local;
371
+ }
350
372
  function getUrlsForEnvironment(environment) {
351
- const urls = ENVIRONMENT_URLS[environment];
352
- if (!urls) throw new Error(`Invalid environment: ${environment}. Must be one of: local, loclx, sandbox, production`);
373
+ if (environment === "tunnel") return getTunnelUrls();
374
+ const urls = STATIC_ENVIRONMENT_URLS[environment];
375
+ if (!urls) throw new Error(`Invalid environment: ${environment}. Must be one of: local, tunnel, sandbox, production`);
353
376
  return urls;
354
377
  }
355
378
 
@@ -371,12 +394,14 @@ const createTunnelXConnection = (baseUrl, apiBaseUrl, token) => {
371
394
  connection
372
395
  };
373
396
  };
374
- const PaymentKit = ({ environment, secureToken, paymentMethods, __enableAnalyticsTestMode }) => {
397
+ const PaymentKit = ({ environment, secureToken, paymentMethods, cardTokenizationMode, vgsVaultId, vgsEnvironment, __enableAnalyticsTestMode }) => {
375
398
  const { baseUrl, apiBaseUrl } = getUrlsForEnvironment(environment);
376
399
  console.log(`[PaymentKit] v${version} initialized (env: ${environment})`);
400
+ const checkoutRequestId = getOrCreateCheckoutRequestId(environment);
401
+ console.log(`[PaymentKit] checkout_request_id: ${checkoutRequestId}`);
377
402
  AnalyticsService.init(apiBaseUrl, __enableAnalyticsTestMode);
378
403
  AnalyticsService.identify(secureToken);
379
- const timingTracker = new CheckoutTimingTracker(secureToken);
404
+ const timingTracker = new CheckoutTimingTracker(secureToken, checkoutRequestId);
380
405
  timingTracker.trackPageReady();
381
406
  const { connection: tunnelXConnection, unmount: unmountTunnelX } = createTunnelXConnection(baseUrl, apiBaseUrl, secureToken);
382
407
  const paymentKitStates = {
@@ -385,8 +410,45 @@ const PaymentKit = ({ environment, secureToken, paymentMethods, __enableAnalytic
385
410
  secureToken,
386
411
  environment,
387
412
  tunnelXConnection,
388
- timingTracker
413
+ timingTracker,
414
+ checkoutRequestId,
415
+ cardTokenizationMode,
416
+ vgsVaultId,
417
+ vgsEnvironment,
418
+ _sessionConfigReady: void 0
389
419
  };
420
+ if (cardTokenizationMode === void 0) {
421
+ const sessionConfigUrl = `${apiBaseUrl}/api/checkout-sessions/token/${secureToken}`;
422
+ console.log(`[PaymentKit] cardTokenizationMode not provided — auto-detecting from session API: ${sessionConfigUrl}`);
423
+ paymentKitStates._sessionConfigReady = fetch(sessionConfigUrl).then((resp) => {
424
+ if (!resp.ok) {
425
+ console.warn(`[PaymentKit] Session config fetch failed with status ${resp.status}`);
426
+ return null;
427
+ }
428
+ return resp.json();
429
+ }).then((session) => {
430
+ if (session && typeof session === "object" && typeof session.card_tokenization_mode === "string") {
431
+ paymentKitStates.cardTokenizationMode = session.card_tokenization_mode || "direct";
432
+ console.log(`[PaymentKit] Session config detected — cardTokenizationMode: ${paymentKitStates.cardTokenizationMode}`);
433
+ const vaultId = session.vgs_vault_id;
434
+ const vgsEnv = session.vgs_environment;
435
+ if (vaultId && /^tnt[a-z0-9]+$/.test(vaultId) && (vgsEnv === "sandbox" || vgsEnv === "live")) {
436
+ paymentKitStates.vgsVaultId = vaultId;
437
+ paymentKitStates.vgsEnvironment = vgsEnv;
438
+ console.log(`[PaymentKit] VGS config valid — vaultId: ${vaultId}, environment: ${vgsEnv}`);
439
+ } else if (paymentKitStates.cardTokenizationMode === "vgs") {
440
+ console.warn(`[PaymentKit] Invalid VGS config from session API (vaultId: ${vaultId}, env: ${vgsEnv}), falling back to direct mode`);
441
+ paymentKitStates.cardTokenizationMode = "direct";
442
+ }
443
+ } else {
444
+ console.log("[PaymentKit] Session response missing card_tokenization_mode — defaulting to direct mode");
445
+ paymentKitStates.cardTokenizationMode = "direct";
446
+ }
447
+ }).catch((err) => {
448
+ console.error("[PaymentKit] Session config fetch error — falling back to direct mode:", err);
449
+ paymentKitStates.cardTokenizationMode = "direct";
450
+ });
451
+ } else console.log(`[PaymentKit] cardTokenizationMode explicitly set: ${cardTokenizationMode}`);
390
452
  const pmInstances = paymentMethods.map((paymentMethod) => paymentMethod(paymentKitStates));
391
453
  const externalFuncsMapByPm = pmInstances.reduce((acc, { name, externalFuncs }) => {
392
454
  acc[name] = externalFuncs;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["ENVIRONMENT_URLS: Record<PaymentKitEnvironment, EnvironmentUrls>","PaymentKit: PaymentKitType","PACKAGE_VERSION","externalFuncsMapByPm: ExternalFuncsMapByPm<PaymentMethods>","submit: PaymentKitReturnType[\"submit\"]"],"sources":["../package.json","../src/analytics/mock-adapter.ts","../src/analytics/posthog-adapter.ts","../src/analytics/service.ts","../src/analytics/checkout-timing.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@payment-kit-js/vanilla\",\n \"version\": \"0.4.1\",\n \"main\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.mts\",\n \"module\": \"./dist/index.mjs\",\n \"exports\": {\n \".\": \"./dist/index.mjs\",\n \"./payment-methods/apple-pay\": \"./dist/payment-methods/apple-pay.mjs\",\n \"./payment-methods/card\": \"./dist/payment-methods/card.mjs\",\n \"./payment-methods/google-pay\": \"./dist/payment-methods/google-pay.mjs\",\n \"./payment-methods/next-action-handlers\": \"./dist/payment-methods/next-action-handlers.mjs\",\n \"./payment-methods/paypal\": \"./dist/payment-methods/paypal.mjs\",\n \"./payment-methods/stripe-apple-pay-adapter\": \"./dist/payment-methods/stripe-apple-pay-adapter.mjs\",\n \"./payment-methods/stripe-google-pay-adapter\": \"./dist/payment-methods/stripe-google-pay-adapter.mjs\",\n \"./penpal/connect-card\": \"./dist/penpal/connect-card.mjs\",\n \"./penpal/connect-tunnel-x\": \"./dist/penpal/connect-tunnel-x.mjs\",\n \"./package.json\": \"./package.json\"\n },\n \"license\": \"MIT\",\n \"description\": \"Vanilla package for PaymentKit\",\n \"files\": [\n \"dist\",\n \"dist/cdn\"\n ],\n \"scripts\": {\n \"dev\": \"yarn tsdown --watch ./src\",\n \"build:npm\": \"yarn tsdown\",\n \"build:cdn\": \"node build-cdn.mjs\",\n \"build\": \"yarn build:npm && yarn build:cdn\"\n },\n \"packageManager\": \"yarn@4.10.3\",\n \"dependencies\": {\n \"nanoid\": \"^5.0.7\",\n \"penpal\": \"^7.0.4\",\n \"posthog-js\": \"^1.196.0\",\n \"valibot\": \"^1.1.0\"\n },\n \"devDependencies\": {\n \"@pkg/sdk\": \"workspace:*\",\n \"@pkg/tsconfig\": \"workspace:*\",\n \"@stripe/stripe-js\": \"^8.6.1\",\n \"@types/applepayjs\": \"^14.0.9\",\n \"esbuild\": \"^0.24.2\",\n \"tsdown\": \"^0.15.10\",\n \"typescript\": \"^5.9.3\"\n },\n \"stableVersion\": \"0.4.1\"\n}\n","import type { AnalyticsAdapter, CapturedEvent } from \"./types\";\n\n/**\n * Mock analytics adapter for testing.\n *\n * Records all captured events for assertion in tests.\n */\nexport class MockAnalyticsAdapter implements AnalyticsAdapter {\n private events: CapturedEvent[] = [];\n private distinctId: string | null = null;\n\n identify(distinctId: string): void {\n this.distinctId = distinctId;\n }\n\n capture(event: string, properties?: Record<string, unknown>): void {\n this.events.push({\n event,\n distinct_id: this.distinctId,\n properties,\n timestamp: Date.now(),\n });\n }\n\n isInitialized(): boolean {\n return true;\n }\n\n // Test helper methods\n\n /**\n * Get all captured events.\n */\n getEvents(): CapturedEvent[] {\n return [...this.events];\n }\n\n /**\n * Get events by name.\n */\n getEventsByName(eventName: string): CapturedEvent[] {\n return this.events.filter((e) => e.event === eventName);\n }\n\n /**\n * Clear all captured events.\n */\n clear(): void {\n this.events = [];\n }\n}\n","import posthog from \"posthog-js\";\nimport type { AnalyticsAdapter } from \"./types\";\n\n// PostHog API key (PaymentKit internal)\nconst POSTHOG_API_KEY = \"phc_u9YDYUeUxo3CYn16XGrrwpVb8ycXgcjz5DarvIKRAAG\";\n\n/**\n * PostHog implementation of the analytics adapter.\n *\n * Singleton stored in window to ensure only one instance exists across\n * all script loads. Configures PostHog to use the reverse proxy at\n * /ingest to avoid ad blockers.\n */\nexport class PostHogAdapter implements AnalyticsAdapter {\n private initialized = false;\n\n /**\n * Get or create the PostHog adapter singleton (stored in window).\n *\n * @param apiBaseUrl - The API base URL for the reverse proxy\n * @throws Error if called with a different apiBaseUrl than the first call\n */\n static getInstance(apiBaseUrl: string): PostHogAdapter {\n if (typeof window === \"undefined\") {\n throw new Error(\"[PaymentKit Analytics] PostHog requires a browser environment\");\n }\n\n const existing = window.__paymentKitPostHog__;\n if (existing) {\n if (existing.apiBaseUrl !== apiBaseUrl) {\n throw new Error(\n `[PaymentKit Analytics] PostHog already initialized with apiBaseUrl \"${existing.apiBaseUrl}\", ` +\n `cannot re-initialize with different apiBaseUrl \"${apiBaseUrl}\"`,\n );\n }\n return existing.instance;\n }\n\n const instance = new PostHogAdapter(apiBaseUrl);\n window.__paymentKitPostHog__ = { instance, apiBaseUrl };\n return instance;\n }\n\n private constructor(apiBaseUrl: string) {\n this.initPostHog(apiBaseUrl);\n }\n\n private initPostHog(apiBaseUrl: string): void {\n try {\n posthog.init(POSTHOG_API_KEY, {\n // Use reverse proxy to avoid ad blockers\n api_host: `${apiBaseUrl}/ingest`,\n // PostHog UI host (for toolbar, if ever needed)\n ui_host: \"https://us.posthog.com\",\n // Memory persistence - no cookies in embedded checkout iframe\n persistence: \"memory\",\n // Disable session recording - not needed for metrics\n disable_session_recording: true,\n // Manual events only - no autocapture\n autocapture: false,\n // Manual pageview control\n capture_pageview: false,\n // Disable batching - send events immediately to avoid data loss on page close\n request_batching: false,\n // Disable bot detection - allows events from automated tests and debugging environments\n // PostHog detects Playwright/headless browsers as bots by default\n opt_out_useragent_filter: true,\n // Callback when PostHog is ready\n loaded: () => {\n this.initialized = true;\n },\n });\n } catch (e) {\n console.warn(\"[PaymentKit Analytics] Failed to initialize PostHog:\", e);\n }\n }\n\n identify(distinctId: string): void {\n try {\n posthog.identify(distinctId);\n } catch (e) {\n // Silent fail - never break checkout\n console.warn(\"[PaymentKit Analytics] Failed to identify:\", e);\n }\n }\n\n capture(event: string, properties?: Record<string, unknown>): void {\n try {\n posthog.capture(event, properties);\n } catch (e) {\n // Silent fail - never break checkout\n console.warn(\"[PaymentKit Analytics] Failed to capture event:\", e);\n }\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n}\n","import { MockAnalyticsAdapter } from \"./mock-adapter\";\nimport { PostHogAdapter } from \"./posthog-adapter\";\nimport type { AnalyticsAdapter } from \"./types\";\n\n/**\n * Analytics service singleton.\n *\n * Provides a global interface for capturing analytics events.\n * Supports multiple adapters that receive all events (composite pattern).\n *\n * Usage:\n * // Initialize (typically done once at SDK init)\n * AnalyticsService.init(\"http://localhost:9000\");\n *\n * // Capture events - broadcasts to all registered adapters\n * AnalyticsService.capture(\"checkout_page_ready\", { session_id: \"...\" });\n *\n * // For testing - add a mock adapter\n * import { MockAnalyticsAdapter } from \"./mock-adapter\";\n * const mock = new MockAnalyticsAdapter();\n * AnalyticsService.addAdapter(mock);\n *\n * // Or use the built-in test mock (exposed globally as window.__paymentKitAnalytics__)\n * AnalyticsService.enableTestMode();\n * // Events can be read via window.__paymentKitAnalytics__.getEvents()\n */\nclass AnalyticsServiceClass {\n private adapters: AnalyticsAdapter[] = [];\n private testMock: MockAnalyticsAdapter | null = null;\n\n /**\n * Initialize the analytics service with PostHog.\n *\n * @param apiBaseUrl - The API base URL for the reverse proxy\n * @param enableTestMode - Enable test mode for capturing events in tests\n */\n init(apiBaseUrl: string, enableTestMode?: boolean): void {\n try {\n // Add PostHog adapter (singleton - safe to call multiple times with same URL)\n this.addAdapter(PostHogAdapter.getInstance(apiBaseUrl));\n\n // Enable test mode if explicitly requested\n if (enableTestMode) {\n this.enableTestMode();\n }\n } catch (e) {\n // Silent fail - analytics should never break checkout\n console.warn(\"[PaymentKit Analytics] Init failed:\", e);\n }\n }\n\n /**\n * Enable test mode by adding a mock adapter and exposing it globally.\n * The mock adapter is accessible via window.__paymentKitAnalytics__\n */\n enableTestMode(): void {\n if (this.testMock) return; // Already enabled\n\n this.testMock = new MockAnalyticsAdapter();\n this.addAdapter(this.testMock);\n\n // Expose globally for Playwright/test access\n if (typeof window !== \"undefined\") {\n window.__paymentKitAnalytics__ = this.testMock;\n }\n }\n\n /**\n * Get the test mock adapter (if test mode is enabled).\n */\n getTestMock(): MockAnalyticsAdapter | null {\n return this.testMock;\n }\n\n /**\n * Add an analytics adapter.\n * Events will be broadcast to all registered adapters.\n * Duplicate adapters (same instance) are ignored.\n *\n * @param adapter - The adapter to add\n */\n addAdapter(adapter: AnalyticsAdapter): void {\n if (!this.adapters.includes(adapter)) {\n this.adapters.push(adapter);\n }\n }\n\n /**\n * Clear all adapters.\n */\n clearAdapters(): void {\n this.adapters = [];\n this.testMock = null;\n if (typeof window !== \"undefined\") {\n delete window.__paymentKitAnalytics__;\n }\n }\n\n /**\n * Set the distinct_id for all adapters.\n * This is used to correlate frontend events with backend events.\n * Should be called with the checkout session secure token.\n */\n identify(distinctId: string): void {\n for (const adapter of this.adapters) {\n try {\n adapter.identify(distinctId);\n } catch {\n // Silent fail - never break checkout\n }\n }\n }\n\n /**\n * Capture an analytics event.\n * Broadcasts to all registered adapters. Silently fails on errors.\n */\n capture(event: string, properties?: Record<string, unknown>): void {\n for (const adapter of this.adapters) {\n try {\n adapter.capture(event, properties);\n } catch {\n // Silent fail - never break checkout\n }\n }\n }\n\n /**\n * Check if any adapter is initialized.\n */\n isInitialized(): boolean {\n return this.adapters.some((adapter) => adapter.isInitialized());\n }\n}\n\n/**\n * Global analytics service instance.\n */\nexport const AnalyticsService = new AnalyticsServiceClass();\n","import { AnalyticsService } from \"./service\";\n\n/**\n * Tracks timing metrics throughout the checkout flow.\n *\n * Create one instance per checkout session and call the track methods\n * at appropriate points in the checkout flow.\n *\n * Usage:\n * const tracker = new CheckoutTimingTracker(secureToken);\n * tracker.trackPageReady();\n * // ... iframe loads ...\n * tracker.trackInputReady();\n * // ... user submits ...\n * tracker.trackSubmit();\n * // ... API response ...\n * tracker.trackSuccess(attemptId);\n */\nexport class CheckoutTimingTracker {\n // Class-level guard to prevent duplicate page_ready events across PaymentKit instances\n private static pageReadyTracked = false;\n\n private startTime: number;\n private checkoutSessionId: string;\n private inputReadyTracked = false;\n\n constructor(checkoutSessionId: string) {\n this.startTime = performance.now();\n this.checkoutSessionId = checkoutSessionId;\n }\n\n /**\n * Track when SDK is initialized and ready.\n * Call immediately after PaymentKit() initialization.\n * Only tracks once per page load (subsequent calls are no-ops).\n */\n trackPageReady(): void {\n if (CheckoutTimingTracker.pageReadyTracked) return;\n CheckoutTimingTracker.pageReadyTracked = true;\n\n AnalyticsService.capture(\"checkout_page_ready\", {\n checkout_session_id: this.checkoutSessionId,\n elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Track when card input iframe is loaded and ready for input.\n * Should only be called once (for first iframe, typically card_pan).\n * Subsequent calls are no-ops.\n */\n trackInputReady(): void {\n if (this.inputReadyTracked) return;\n this.inputReadyTracked = true;\n\n AnalyticsService.capture(\"checkout_input_ready\", {\n checkout_session_id: this.checkoutSessionId,\n elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Track when user clicks submit button.\n */\n trackSubmit(): void {\n AnalyticsService.capture(\"checkout_submit\", {\n checkout_session_id: this.checkoutSessionId,\n elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Track successful checkout.\n *\n * @param checkoutAttemptId - The checkout attempt ID\n */\n trackSuccess(checkoutAttemptId: string): void {\n AnalyticsService.capture(\"checkout_success\", {\n checkout_session_id: this.checkoutSessionId,\n checkout_attempt_id: checkoutAttemptId,\n total_elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Track failed checkout.\n *\n * @param checkoutAttemptId - The checkout attempt ID (may be null if failed early)\n * @param errorCode - The error code from the checkout response\n * @param errorMessage - The customer-facing error message\n */\n trackFail(checkoutAttemptId: string | null, errorCode: string | null, errorMessage: string | null): void {\n AnalyticsService.capture(\"checkout_fail\", {\n checkout_session_id: this.checkoutSessionId,\n checkout_attempt_id: checkoutAttemptId,\n error_code: errorCode,\n error_message: errorMessage,\n total_elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Get elapsed time in milliseconds since tracker creation.\n */\n private getElapsedMs(): number {\n return Math.round(performance.now() - this.startTime);\n }\n}\n","import type { CheckoutTimingTracker } from \"./analytics\";\nimport type { CardErrorCode } from \"./penpal/connect-card\";\nimport type { TunnelXIFrameConnection } from \"./penpal/connect-tunnel-x\";\n\nexport type PaymentKitEnvironment = \"local\" | \"loclx\" | \"sandbox\" | \"production\";\n\ntype EnvironmentUrls = {\n baseUrl: string;\n apiBaseUrl: string;\n};\n\n// TODO: Cleanup this after launch to only use SDK instead of plain fetch.\nconst ENVIRONMENT_URLS: Record<PaymentKitEnvironment, EnvironmentUrls> = {\n local: {\n baseUrl: \"http://localhost:9101\",\n apiBaseUrl: \"http://localhost:9000\",\n },\n loclx: {\n baseUrl: \"https://pkmateuscportal.loclx.io\",\n apiBaseUrl: \"https://pkmateusapi.loclx.io\",\n },\n sandbox: {\n baseUrl: \"https://staging.paymentkit.com/customer\",\n apiBaseUrl: \"https://staging.paymentkit.com\",\n },\n production: {\n baseUrl: \"https://paymentkit.com/customer\",\n apiBaseUrl: \"https://paymentkit.com\",\n },\n};\n\nexport function getUrlsForEnvironment(environment: string): EnvironmentUrls {\n const env = environment as PaymentKitEnvironment;\n const urls = ENVIRONMENT_URLS[env];\n if (!urls) {\n throw new Error(`Invalid environment: ${environment}. Must be one of: local, loclx, sandbox, production`);\n }\n return urls;\n}\n\ntype FormFieldNames = \"customer_name\" | \"customer_email\" | \"customer_country\" | \"customer_zip_code\";\n\nexport type FormErrorCodes = \"required\" | \"invalid\";\n\nexport type TInternalFuncs = {\n submitPayment: (\n fields: PaymentKitFields,\n options?: unknown,\n ) => Promise<{ data: { [key: string]: unknown }; errors?: never } | { data?: never; errors: PaymentKitErrors }>;\n cleanup?: () => void;\n};\n\nexport type PaymentKit = <T extends readonly PaymentMethod<unknown>[]>(options: {\n environment: string;\n secureToken: string;\n paymentMethods: T;\n /** @internal Enable analytics test mode for e2e testing */\n __enableAnalyticsTestMode?: boolean;\n}) => ExternalFuncsMapByPm<T> & {\n submit: PaymentKitSubmitHandler<T>;\n cleanup: () => void;\n};\n\ntype PaymentKitSubmitHandler<T extends readonly PaymentMethod<unknown>[]> = <\n N extends keyof ExternalFuncsMapByPm<T>,\n>(options: {\n fields: PaymentKitFields;\n paymentMethod: N;\n options?: unknown;\n onError: (error: PaymentKitErrors) => void;\n onSuccess: (data: { [key: string]: unknown }) => void;\n}) => void;\n\nexport type PaymentKitStates = {\n baseUrl: string;\n apiBaseUrl: string;\n secureToken: string;\n environment: string;\n tunnelXConnection: TunnelXIFrameConnection;\n timingTracker: CheckoutTimingTracker;\n};\n\nexport type PaymentKitErrors = {\n root?: string;\n card_pan?: CardErrorCode;\n card_exp?: CardErrorCode;\n card_cvc?: CardErrorCode;\n paypal?: string;\n google_pay?: string;\n apple_pay?: string;\n processor_id?: string;\n amount?: string;\n currency?: string;\n country?: string;\n} & { [key in FormFieldNames]?: FormErrorCodes | string };\n\nexport type PaymentKitFields = { [key in FormFieldNames]: string };\n\nexport type PaymentMethod<TExternalFuncs = unknown, TName = string> = (paymentKitStates: PaymentKitStates) => {\n name: TName;\n externalFuncs: TExternalFuncs;\n internalFuncs: TInternalFuncs;\n};\n\nexport type ExternalFuncsMapByPm<T extends readonly PaymentMethod<unknown>[]> = {\n [K in T[number] as ReturnType<K>[\"name\"]]: ReturnType<K>[\"externalFuncs\"];\n};\n","import { version as PACKAGE_VERSION } from \"../package.json\";\nimport { AnalyticsService, CheckoutTimingTracker } from \"./analytics\";\nimport { connectToTunnelXIframe } from \"./penpal/connect-tunnel-x\";\nimport type { ExternalFuncsMapByPm, PaymentKitFields, PaymentKit as PaymentKitType } from \"./types\";\nimport { getUrlsForEnvironment } from \"./types\";\nimport { createCheckoutIFrame } from \"./utils\";\n\ntype PaymentKitReturnType = ReturnType<PaymentKitType>;\n\nconst createTunnelXConnection = (baseUrl: string, apiBaseUrl: string, token: string) => {\n const iframe = createCheckoutIFrame(\"tunnel-x\", baseUrl, {\n checkout_token: token,\n api_base_url: apiBaseUrl,\n });\n document.body.appendChild(iframe);\n\n const connection = connectToTunnelXIframe(iframe, {});\n\n const unmount = () => {\n connection.destroy();\n document.body.removeChild(iframe);\n };\n\n return { unmount, connection };\n};\n\nconst PaymentKit: PaymentKitType = ({ environment, secureToken, paymentMethods, __enableAnalyticsTestMode }) => {\n type PaymentMethods = typeof paymentMethods;\n\n // Resolve URLs from environment\n const { baseUrl, apiBaseUrl } = getUrlsForEnvironment(environment);\n\n // Log version for debugging\n console.log(`[PaymentKit] v${PACKAGE_VERSION} initialized (env: ${environment})`);\n\n // Initialize analytics and identify with secure token for correlation\n AnalyticsService.init(apiBaseUrl, __enableAnalyticsTestMode);\n AnalyticsService.identify(secureToken);\n\n // Create timing tracker for this checkout session\n const timingTracker = new CheckoutTimingTracker(secureToken);\n\n // Track page ready immediately\n timingTracker.trackPageReady();\n\n const { connection: tunnelXConnection, unmount: unmountTunnelX } = createTunnelXConnection(\n baseUrl,\n apiBaseUrl,\n secureToken,\n );\n\n const paymentKitStates = {\n baseUrl,\n apiBaseUrl,\n secureToken,\n environment,\n tunnelXConnection,\n timingTracker,\n };\n\n const pmInstances = paymentMethods.map((paymentMethod) => paymentMethod(paymentKitStates));\n\n const externalFuncsMapByPm: ExternalFuncsMapByPm<PaymentMethods> = pmInstances.reduce(\n (acc, { name, externalFuncs }) => {\n // @ts-expect-error - typecase this better in future\n acc[name] = externalFuncs;\n return acc;\n },\n {} as ExternalFuncsMapByPm<PaymentMethods>,\n );\n\n const submit: PaymentKitReturnType[\"submit\"] = ({\n paymentMethod: paymentMethodName,\n fields,\n options,\n onSuccess,\n onError,\n }) => {\n const paymentMethod = pmInstances.find(({ name }) => name === paymentMethodName);\n if (!paymentMethod) {\n onError({ root: \"payment_method_not_found\" });\n return;\n }\n paymentMethod.internalFuncs\n .submitPayment(fields, options)\n .then(({ data, errors }) => {\n errors ? onError(errors) : onSuccess(data);\n })\n .catch((e) => {\n console.error(\"PaymentKit:submit:catch\", e);\n\n // Try to extract error message from response\n if (e?.response?.data) {\n onError(e.response.data);\n } else if (e?.message) {\n onError({ root: e.message });\n } else {\n onError({ root: \"unknown_error\" });\n }\n });\n };\n\n const cleanup = () => {\n // Clean up all payment method instances\n for (const pm of pmInstances) {\n if (pm.internalFuncs.cleanup) {\n pm.internalFuncs.cleanup();\n }\n }\n unmountTunnelX();\n };\n\n return {\n submit,\n cleanup,\n ...externalFuncsMapByPm,\n };\n};\n\nexport type { PaymentKitFields };\n\nexport default PaymentKit;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["STATIC_ENVIRONMENT_URLS: Record<Exclude<PaymentKitEnvironment, \"tunnel\">, EnvironmentUrls>","PaymentKit: PaymentKitType","PACKAGE_VERSION","externalFuncsMapByPm: ExternalFuncsMapByPm<PaymentMethods>","submit: PaymentKitReturnType[\"submit\"]"],"sources":["../package.json","../src/analytics/mock-adapter.ts","../src/analytics/posthog-adapter.ts","../src/analytics/service.ts","../src/analytics/checkout-timing.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@payment-kit-js/vanilla\",\n \"version\": \"0.5.2\",\n \"main\": \"./dist/index.mjs\",\n \"types\": \"./dist/index.d.mts\",\n \"module\": \"./dist/index.mjs\",\n \"exports\": {\n \".\": \"./dist/index.mjs\",\n \"./payment-methods/airwallex-apple-pay-adapter\": \"./dist/payment-methods/airwallex-apple-pay-adapter.mjs\",\n \"./payment-methods/airwallex-google-pay-adapter\": \"./dist/payment-methods/airwallex-google-pay-adapter.mjs\",\n \"./payment-methods/apple-pay\": \"./dist/payment-methods/apple-pay.mjs\",\n \"./payment-methods/card\": \"./dist/payment-methods/card.mjs\",\n \"./payment-methods/google-pay\": \"./dist/payment-methods/google-pay.mjs\",\n \"./payment-methods/next-action-handlers\": \"./dist/payment-methods/next-action-handlers.mjs\",\n \"./payment-methods/paypal\": \"./dist/payment-methods/paypal.mjs\",\n \"./payment-methods/stripe-apple-pay-adapter\": \"./dist/payment-methods/stripe-apple-pay-adapter.mjs\",\n \"./payment-methods/stripe-google-pay-adapter\": \"./dist/payment-methods/stripe-google-pay-adapter.mjs\",\n \"./payment-methods/vgs-collect-loader\": \"./dist/payment-methods/vgs-collect-loader.mjs\",\n \"./penpal/connect-card\": \"./dist/penpal/connect-card.mjs\",\n \"./penpal/connect-tunnel-x\": \"./dist/penpal/connect-tunnel-x.mjs\",\n \"./package.json\": \"./package.json\"\n },\n \"license\": \"MIT\",\n \"description\": \"Vanilla package for PaymentKit\",\n \"files\": [\n \"dist\",\n \"dist/cdn\"\n ],\n \"scripts\": {\n \"dev\": \"yarn tsdown --watch ./src\",\n \"build:npm\": \"yarn tsdown\",\n \"build:cdn\": \"node build-cdn.mjs\",\n \"build\": \"yarn build:npm && yarn build:cdn\"\n },\n \"packageManager\": \"yarn@4.10.3\",\n \"dependencies\": {\n \"nanoid\": \"^5.0.7\",\n \"penpal\": \"^7.0.4\",\n \"posthog-js\": \"^1.196.0\",\n \"valibot\": \"^1.1.0\"\n },\n \"devDependencies\": {\n \"@pkg/sdk\": \"workspace:*\",\n \"@pkg/tsconfig\": \"workspace:*\",\n \"@stripe/stripe-js\": \"^8.6.1\",\n \"@types/applepayjs\": \"^14.0.9\",\n \"esbuild\": \"^0.24.2\",\n \"tsdown\": \"^0.15.10\",\n \"typescript\": \"^5.9.3\"\n },\n \"stableVersion\": \"0.5.2\"\n}\n","import type { AnalyticsAdapter, CapturedEvent } from \"./types\";\n\n/**\n * Mock analytics adapter for testing.\n *\n * Records all captured events for assertion in tests.\n */\nexport class MockAnalyticsAdapter implements AnalyticsAdapter {\n private events: CapturedEvent[] = [];\n private distinctId: string | null = null;\n\n identify(distinctId: string): void {\n this.distinctId = distinctId;\n }\n\n capture(event: string, properties?: Record<string, unknown>): void {\n this.events.push({\n event,\n distinct_id: this.distinctId,\n properties,\n timestamp: Date.now(),\n });\n }\n\n isInitialized(): boolean {\n return true;\n }\n\n // Test helper methods\n\n /**\n * Get all captured events.\n */\n getEvents(): CapturedEvent[] {\n return [...this.events];\n }\n\n /**\n * Get events by name.\n */\n getEventsByName(eventName: string): CapturedEvent[] {\n return this.events.filter((e) => e.event === eventName);\n }\n\n /**\n * Clear all captured events.\n */\n clear(): void {\n this.events = [];\n }\n}\n","import posthog from \"posthog-js\";\nimport type { AnalyticsAdapter } from \"./types\";\n\n// PostHog API key (PaymentKit internal)\nconst POSTHOG_API_KEY = \"phc_u9YDYUeUxo3CYn16XGrrwpVb8ycXgcjz5DarvIKRAAG\";\n\n/**\n * PostHog implementation of the analytics adapter.\n *\n * Singleton stored in window to ensure only one instance exists across\n * all script loads. Configures PostHog to use the reverse proxy at\n * /ingest to avoid ad blockers.\n */\nexport class PostHogAdapter implements AnalyticsAdapter {\n private initialized = false;\n\n /**\n * Get or create the PostHog adapter singleton (stored in window).\n *\n * @param apiBaseUrl - The API base URL for the reverse proxy\n * @throws Error if called with a different apiBaseUrl than the first call\n */\n static getInstance(apiBaseUrl: string): PostHogAdapter {\n if (typeof window === \"undefined\") {\n throw new Error(\"[PaymentKit Analytics] PostHog requires a browser environment\");\n }\n\n const existing = window.__paymentKitPostHog__;\n if (existing) {\n if (existing.apiBaseUrl !== apiBaseUrl) {\n throw new Error(\n `[PaymentKit Analytics] PostHog already initialized with apiBaseUrl \"${existing.apiBaseUrl}\", ` +\n `cannot re-initialize with different apiBaseUrl \"${apiBaseUrl}\"`,\n );\n }\n return existing.instance;\n }\n\n const instance = new PostHogAdapter(apiBaseUrl);\n window.__paymentKitPostHog__ = { instance, apiBaseUrl };\n return instance;\n }\n\n private constructor(apiBaseUrl: string) {\n this.initPostHog(apiBaseUrl);\n }\n\n private initPostHog(apiBaseUrl: string): void {\n try {\n posthog.init(POSTHOG_API_KEY, {\n // Use reverse proxy to avoid ad blockers\n api_host: `${apiBaseUrl}/ingest`,\n // PostHog UI host (for toolbar, if ever needed)\n ui_host: \"https://us.posthog.com\",\n // Memory persistence - no cookies in embedded checkout iframe\n persistence: \"memory\",\n // Disable session recording - not needed for metrics\n disable_session_recording: true,\n // Manual events only - no autocapture\n autocapture: false,\n // Manual pageview control\n capture_pageview: false,\n // Disable batching - send events immediately to avoid data loss on page close\n request_batching: false,\n // Disable bot detection - allows events from automated tests and debugging environments\n // PostHog detects Playwright/headless browsers as bots by default\n opt_out_useragent_filter: true,\n // Callback when PostHog is ready\n loaded: () => {\n this.initialized = true;\n },\n });\n } catch (e) {\n console.warn(\"[PaymentKit Analytics] Failed to initialize PostHog:\", e);\n }\n }\n\n identify(distinctId: string): void {\n try {\n posthog.identify(distinctId);\n } catch (e) {\n // Silent fail - never break checkout\n console.warn(\"[PaymentKit Analytics] Failed to identify:\", e);\n }\n }\n\n capture(event: string, properties?: Record<string, unknown>): void {\n try {\n posthog.capture(event, properties);\n } catch (e) {\n // Silent fail - never break checkout\n console.warn(\"[PaymentKit Analytics] Failed to capture event:\", e);\n }\n }\n\n isInitialized(): boolean {\n return this.initialized;\n }\n}\n","import { MockAnalyticsAdapter } from \"./mock-adapter\";\nimport { PostHogAdapter } from \"./posthog-adapter\";\nimport type { AnalyticsAdapter } from \"./types\";\n\n/**\n * Analytics service singleton.\n *\n * Provides a global interface for capturing analytics events.\n * Supports multiple adapters that receive all events (composite pattern).\n *\n * Usage:\n * // Initialize (typically done once at SDK init)\n * AnalyticsService.init(\"http://localhost:9000\");\n *\n * // Capture events - broadcasts to all registered adapters\n * AnalyticsService.capture(\"checkout_page_ready\", { session_id: \"...\" });\n *\n * // For testing - add a mock adapter\n * import { MockAnalyticsAdapter } from \"./mock-adapter\";\n * const mock = new MockAnalyticsAdapter();\n * AnalyticsService.addAdapter(mock);\n *\n * // Or use the built-in test mock (exposed globally as window.__paymentKitAnalytics__)\n * AnalyticsService.enableTestMode();\n * // Events can be read via window.__paymentKitAnalytics__.getEvents()\n */\nclass AnalyticsServiceClass {\n private adapters: AnalyticsAdapter[] = [];\n private testMock: MockAnalyticsAdapter | null = null;\n\n /**\n * Initialize the analytics service with PostHog.\n *\n * @param apiBaseUrl - The API base URL for the reverse proxy\n * @param enableTestMode - Enable test mode for capturing events in tests\n */\n init(apiBaseUrl: string, enableTestMode?: boolean): void {\n try {\n // Add PostHog adapter (singleton - safe to call multiple times with same URL)\n this.addAdapter(PostHogAdapter.getInstance(apiBaseUrl));\n\n // Enable test mode if explicitly requested\n if (enableTestMode) {\n this.enableTestMode();\n }\n } catch (e) {\n // Silent fail - analytics should never break checkout\n console.warn(\"[PaymentKit Analytics] Init failed:\", e);\n }\n }\n\n /**\n * Enable test mode by adding a mock adapter and exposing it globally.\n * The mock adapter is accessible via window.__paymentKitAnalytics__\n */\n enableTestMode(): void {\n if (this.testMock) return; // Already enabled\n\n this.testMock = new MockAnalyticsAdapter();\n this.addAdapter(this.testMock);\n\n // Expose globally for Playwright/test access\n if (typeof window !== \"undefined\") {\n window.__paymentKitAnalytics__ = this.testMock;\n }\n }\n\n /**\n * Get the test mock adapter (if test mode is enabled).\n */\n getTestMock(): MockAnalyticsAdapter | null {\n return this.testMock;\n }\n\n /**\n * Add an analytics adapter.\n * Events will be broadcast to all registered adapters.\n * Duplicate adapters (same instance) are ignored.\n *\n * @param adapter - The adapter to add\n */\n addAdapter(adapter: AnalyticsAdapter): void {\n if (!this.adapters.includes(adapter)) {\n this.adapters.push(adapter);\n }\n }\n\n /**\n * Clear all adapters.\n */\n clearAdapters(): void {\n this.adapters = [];\n this.testMock = null;\n if (typeof window !== \"undefined\") {\n delete window.__paymentKitAnalytics__;\n }\n }\n\n /**\n * Set the distinct_id for all adapters.\n * This is used to correlate frontend events with backend events.\n * Should be called with the checkout session secure token.\n */\n identify(distinctId: string): void {\n for (const adapter of this.adapters) {\n try {\n adapter.identify(distinctId);\n } catch {\n // Silent fail - never break checkout\n }\n }\n }\n\n /**\n * Capture an analytics event.\n * Broadcasts to all registered adapters. Silently fails on errors.\n */\n capture(event: string, properties?: Record<string, unknown>): void {\n for (const adapter of this.adapters) {\n try {\n adapter.capture(event, properties);\n } catch {\n // Silent fail - never break checkout\n }\n }\n }\n\n /**\n * Check if any adapter is initialized.\n */\n isInitialized(): boolean {\n return this.adapters.some((adapter) => adapter.isInitialized());\n }\n}\n\n/**\n * Global analytics service instance.\n */\nexport const AnalyticsService = new AnalyticsServiceClass();\n","import { AnalyticsService } from \"./service\";\n\n/**\n * Tracks timing metrics throughout the checkout flow.\n *\n * Create one instance per checkout session and call the track methods\n * at appropriate points in the checkout flow.\n *\n * Usage:\n * const requestId = getOrCreateCheckoutRequestId(environment);\n * const tracker = new CheckoutTimingTracker(secureToken, requestId);\n * tracker.trackPageReady();\n * // ... iframe loads ...\n * tracker.trackInputReady();\n * // ... user submits ...\n * tracker.trackSubmit();\n * // ... API response ...\n * tracker.trackSuccess(attemptId);\n */\nexport class CheckoutTimingTracker {\n // Class-level guard to prevent duplicate page_ready events across PaymentKit instances\n private static pageReadyTracked = false;\n\n private startTime: number;\n private checkoutSessionId: string;\n private requestId: string;\n private inputReadyTracked = false;\n\n constructor(checkoutSessionId: string, requestId: string) {\n this.startTime = performance.now();\n this.checkoutSessionId = checkoutSessionId;\n this.requestId = requestId;\n }\n\n /**\n * Track when SDK is initialized and ready.\n * Call immediately after PaymentKit() initialization.\n * Only tracks once per page load (subsequent calls are no-ops).\n */\n trackPageReady(): void {\n if (CheckoutTimingTracker.pageReadyTracked) return;\n CheckoutTimingTracker.pageReadyTracked = true;\n\n AnalyticsService.capture(\"checkout_page_ready\", {\n checkout_session_id: this.checkoutSessionId,\n request_id: this.requestId,\n elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Track when card input iframe is loaded and ready for input.\n * Should only be called once (for first iframe, typically card_pan).\n * Subsequent calls are no-ops.\n */\n trackInputReady(): void {\n if (this.inputReadyTracked) return;\n this.inputReadyTracked = true;\n\n AnalyticsService.capture(\"checkout_input_ready\", {\n checkout_session_id: this.checkoutSessionId,\n request_id: this.requestId,\n elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Track when user clicks submit button.\n */\n trackSubmit(): void {\n AnalyticsService.capture(\"checkout_submit\", {\n checkout_session_id: this.checkoutSessionId,\n request_id: this.requestId,\n elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Track successful checkout.\n *\n * @param checkoutAttemptId - The checkout attempt ID\n */\n trackSuccess(checkoutAttemptId: string): void {\n AnalyticsService.capture(\"checkout_success\", {\n checkout_session_id: this.checkoutSessionId,\n checkout_attempt_id: checkoutAttemptId,\n request_id: this.requestId,\n total_elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Track failed checkout.\n *\n * @param checkoutAttemptId - The checkout attempt ID (may be null if failed early)\n * @param errorCode - The error code from the checkout response\n * @param errorMessage - The customer-facing error message\n */\n trackFail(checkoutAttemptId: string | null, errorCode: string | null, errorMessage: string | null): void {\n AnalyticsService.capture(\"checkout_fail\", {\n checkout_session_id: this.checkoutSessionId,\n checkout_attempt_id: checkoutAttemptId,\n request_id: this.requestId,\n error_code: errorCode,\n error_message: errorMessage,\n total_elapsed_ms: this.getElapsedMs(),\n });\n }\n\n /**\n * Get elapsed time in milliseconds since tracker creation.\n */\n private getElapsedMs(): number {\n return Math.round(performance.now() - this.startTime);\n }\n}\n","import type { CheckoutTimingTracker } from \"./analytics\";\nimport type { CardErrorCode } from \"./penpal/connect-card\";\nimport type { TunnelXIFrameConnection } from \"./penpal/connect-tunnel-x\";\n\nexport type PaymentKitEnvironment = \"local\" | \"tunnel\" | \"sandbox\" | \"production\";\n\ntype EnvironmentUrls = {\n baseUrl: string;\n apiBaseUrl: string;\n};\n\n// TODO: Cleanup this after launch to only use SDK instead of plain fetch.\nconst STATIC_ENVIRONMENT_URLS: Record<Exclude<PaymentKitEnvironment, \"tunnel\">, EnvironmentUrls> = {\n local: {\n baseUrl: \"http://localhost:9101\",\n apiBaseUrl: \"http://localhost:9000\",\n },\n sandbox: {\n baseUrl: \"https://staging.paymentkit.com/customer\",\n apiBaseUrl: \"https://staging.paymentkit.com\",\n },\n production: {\n baseUrl: \"https://paymentkit.com/customer\",\n apiBaseUrl: \"https://paymentkit.com\",\n },\n};\n\nfunction getTunnelUrls(): EnvironmentUrls {\n if (typeof window !== \"undefined\") {\n const params = new URLSearchParams(window.location.search);\n const apiBaseUrl = params.get(\"api_base_url\");\n if (apiBaseUrl) {\n return {\n baseUrl: window.location.origin,\n apiBaseUrl,\n };\n }\n // For loclx-style tunnels where API hostname is derived from the current hostname\n const hostname = window.location.hostname;\n if (hostname.includes(\"loclx.io\")) {\n const apiHostname = hostname.replace(/cportal|playground/, \"api\");\n return {\n baseUrl: `https://${hostname}`,\n apiBaseUrl: `https://${apiHostname}`,\n };\n }\n }\n // Fallback\n return STATIC_ENVIRONMENT_URLS.local;\n}\n\nexport function getUrlsForEnvironment(environment: string): EnvironmentUrls {\n if (environment === \"tunnel\") {\n return getTunnelUrls();\n }\n const env = environment as Exclude<PaymentKitEnvironment, \"tunnel\">;\n const urls = STATIC_ENVIRONMENT_URLS[env];\n if (!urls) {\n throw new Error(`Invalid environment: ${environment}. Must be one of: local, tunnel, sandbox, production`);\n }\n return urls;\n}\n\ntype FormFieldNames = \"customer_name\" | \"customer_email\" | \"customer_country\" | \"customer_zip_code\";\n\nexport type FormErrorCodes = \"required\" | \"invalid\";\n\nexport type TInternalFuncs = {\n submitPayment: (\n fields: PaymentKitFields,\n options?: unknown,\n ) => Promise<{ data: { [key: string]: unknown }; errors?: never } | { data?: never; errors: PaymentKitErrors }>;\n cleanup?: () => void;\n};\n\nexport type PaymentKit = <T extends readonly PaymentMethod<unknown>[]>(options: {\n environment: string;\n secureToken: string;\n paymentMethods: T;\n /** Card tokenization mode from checkout session */\n cardTokenizationMode?: \"direct\" | \"vgs\";\n /** VGS vault ID from checkout session */\n vgsVaultId?: string;\n /** VGS environment from checkout session */\n vgsEnvironment?: string;\n /** @internal Enable analytics test mode for e2e testing */\n __enableAnalyticsTestMode?: boolean;\n}) => ExternalFuncsMapByPm<T> & {\n submit: PaymentKitSubmitHandler<T>;\n cleanup: () => void;\n};\n\ntype PaymentKitSubmitHandler<T extends readonly PaymentMethod<unknown>[]> = <\n N extends keyof ExternalFuncsMapByPm<T>,\n>(options: {\n fields: Partial<PaymentKitFields>;\n paymentMethod: N;\n options?: unknown;\n onError: (error: PaymentKitErrors) => void;\n onSuccess: (data: { [key: string]: unknown }) => void;\n}) => void;\n\nexport type PaymentKitStates = {\n baseUrl: string;\n apiBaseUrl: string;\n secureToken: string;\n environment: string;\n tunnelXConnection: TunnelXIFrameConnection;\n timingTracker: CheckoutTimingTracker;\n /** Checkout request ID for correlating all API calls and analytics events */\n checkoutRequestId: string;\n /** Card tokenization mode: 'direct' (KMS) or 'vgs' (VGS Collect + proxy) */\n cardTokenizationMode?: \"direct\" | \"vgs\";\n /** VGS vault ID (only when cardTokenizationMode is 'vgs') */\n vgsVaultId?: string;\n /** VGS environment: 'sandbox' or 'live' (only when cardTokenizationMode is 'vgs') */\n vgsEnvironment?: string;\n /** @internal Promise that resolves when session config (incl. VGS mode) is auto-detected */\n _sessionConfigReady?: Promise<void>;\n};\n\nexport type PaymentKitErrors = {\n root?: string;\n card_pan?: CardErrorCode;\n card_exp?: CardErrorCode;\n card_cvc?: CardErrorCode;\n paypal?: string;\n google_pay?: string;\n apple_pay?: string;\n processor_id?: string;\n amount?: string;\n currency?: string;\n country?: string;\n} & { [key in FormFieldNames]?: FormErrorCodes | string };\n\nexport type PaymentKitFields = { [key in FormFieldNames]: string };\n\nexport type PaymentMethod<TExternalFuncs = unknown, TName = string> = (paymentKitStates: PaymentKitStates) => {\n name: TName;\n externalFuncs: TExternalFuncs;\n internalFuncs: TInternalFuncs;\n};\n\nexport type ExternalFuncsMapByPm<T extends readonly PaymentMethod<unknown>[]> = {\n [K in T[number] as ReturnType<K>[\"name\"]]: ReturnType<K>[\"externalFuncs\"];\n};\n","import { version as PACKAGE_VERSION } from \"../package.json\";\nimport { AnalyticsService, CheckoutTimingTracker } from \"./analytics\";\nimport { connectToTunnelXIframe } from \"./penpal/connect-tunnel-x\";\nimport type { ExternalFuncsMapByPm, PaymentKitFields, PaymentKit as PaymentKitType } from \"./types\";\nimport { getUrlsForEnvironment } from \"./types\";\nimport { createCheckoutIFrame } from \"./utils\";\nimport { getOrCreateCheckoutRequestId } from \"./utils/checkout-request-id\";\n\ntype PaymentKitReturnType = ReturnType<PaymentKitType>;\n\nconst createTunnelXConnection = (baseUrl: string, apiBaseUrl: string, token: string) => {\n const iframe = createCheckoutIFrame(\"tunnel-x\", baseUrl, {\n checkout_token: token,\n api_base_url: apiBaseUrl,\n });\n document.body.appendChild(iframe);\n\n const connection = connectToTunnelXIframe(iframe, {});\n\n const unmount = () => {\n connection.destroy();\n document.body.removeChild(iframe);\n };\n\n return { unmount, connection };\n};\n\nconst PaymentKit: PaymentKitType = ({\n environment,\n secureToken,\n paymentMethods,\n cardTokenizationMode,\n vgsVaultId,\n vgsEnvironment,\n __enableAnalyticsTestMode,\n}) => {\n type PaymentMethods = typeof paymentMethods;\n\n // Resolve URLs from environment\n const { baseUrl, apiBaseUrl } = getUrlsForEnvironment(environment);\n\n // Log version for debugging\n console.log(`[PaymentKit] v${PACKAGE_VERSION} initialized (env: ${environment})`);\n\n // Generate checkout request ID for correlating all API calls and analytics events\n // This is idempotent - same ID is reused across multiple PaymentKit instantiations\n const checkoutRequestId = getOrCreateCheckoutRequestId(environment);\n console.log(`[PaymentKit] checkout_request_id: ${checkoutRequestId}`);\n\n // Initialize analytics and identify with secure token for correlation\n AnalyticsService.init(apiBaseUrl, __enableAnalyticsTestMode);\n AnalyticsService.identify(secureToken);\n\n // Create timing tracker for this checkout session\n const timingTracker = new CheckoutTimingTracker(secureToken, checkoutRequestId);\n\n // Track page ready immediately\n timingTracker.trackPageReady();\n\n const { connection: tunnelXConnection, unmount: unmountTunnelX } = createTunnelXConnection(\n baseUrl,\n apiBaseUrl,\n secureToken,\n );\n\n const paymentKitStates = {\n baseUrl,\n apiBaseUrl,\n secureToken,\n environment,\n tunnelXConnection,\n timingTracker,\n checkoutRequestId,\n cardTokenizationMode,\n vgsVaultId,\n vgsEnvironment,\n _sessionConfigReady: undefined as Promise<void> | undefined,\n };\n\n // Auto-detect VGS mode from session API if not explicitly provided.\n // The promise resolves before any card mount or submit needs the mode.\n if (cardTokenizationMode === undefined) {\n const sessionConfigUrl = `${apiBaseUrl}/api/checkout-sessions/token/${secureToken}`;\n console.log(\n `[PaymentKit] cardTokenizationMode not provided — auto-detecting from session API: ${sessionConfigUrl}`,\n );\n paymentKitStates._sessionConfigReady = fetch(sessionConfigUrl)\n .then((resp) => {\n if (!resp.ok) {\n console.warn(`[PaymentKit] Session config fetch failed with status ${resp.status}`);\n return null;\n }\n return resp.json();\n })\n .then((session) => {\n if (session && typeof session === \"object\" && typeof session.card_tokenization_mode === \"string\") {\n paymentKitStates.cardTokenizationMode = session.card_tokenization_mode || \"direct\";\n console.log(\n `[PaymentKit] Session config detected — cardTokenizationMode: ${paymentKitStates.cardTokenizationMode}`,\n );\n\n // Validate VGS config from API before trusting it\n const vaultId = session.vgs_vault_id;\n const vgsEnv = session.vgs_environment;\n if (vaultId && /^tnt[a-z0-9]+$/.test(vaultId) && (vgsEnv === \"sandbox\" || vgsEnv === \"live\")) {\n paymentKitStates.vgsVaultId = vaultId;\n paymentKitStates.vgsEnvironment = vgsEnv;\n console.log(`[PaymentKit] VGS config valid — vaultId: ${vaultId}, environment: ${vgsEnv}`);\n } else if (paymentKitStates.cardTokenizationMode === \"vgs\") {\n console.warn(\n `[PaymentKit] Invalid VGS config from session API (vaultId: ${vaultId}, env: ${vgsEnv}), falling back to direct mode`,\n );\n paymentKitStates.cardTokenizationMode = \"direct\";\n }\n } else {\n console.log(\"[PaymentKit] Session response missing card_tokenization_mode — defaulting to direct mode\");\n paymentKitStates.cardTokenizationMode = \"direct\";\n }\n })\n .catch((err) => {\n console.error(\"[PaymentKit] Session config fetch error — falling back to direct mode:\", err);\n paymentKitStates.cardTokenizationMode = \"direct\";\n });\n } else {\n console.log(`[PaymentKit] cardTokenizationMode explicitly set: ${cardTokenizationMode}`);\n }\n\n const pmInstances = paymentMethods.map((paymentMethod) => paymentMethod(paymentKitStates));\n\n const externalFuncsMapByPm: ExternalFuncsMapByPm<PaymentMethods> = pmInstances.reduce(\n (acc, { name, externalFuncs }) => {\n // @ts-expect-error - typecase this better in future\n acc[name] = externalFuncs;\n return acc;\n },\n {} as ExternalFuncsMapByPm<PaymentMethods>,\n );\n\n const submit: PaymentKitReturnType[\"submit\"] = ({\n paymentMethod: paymentMethodName,\n fields,\n options,\n onSuccess,\n onError,\n }) => {\n const paymentMethod = pmInstances.find(({ name }) => name === paymentMethodName);\n if (!paymentMethod) {\n onError({ root: \"payment_method_not_found\" });\n return;\n }\n paymentMethod.internalFuncs\n .submitPayment(fields, options)\n .then(({ data, errors }) => {\n errors ? onError(errors) : onSuccess(data);\n })\n .catch((e) => {\n console.error(\"PaymentKit:submit:catch\", e);\n\n // Try to extract error message from response\n if (e?.response?.data) {\n onError(e.response.data);\n } else if (e?.message) {\n onError({ root: e.message });\n } else {\n onError({ root: \"unknown_error\" });\n }\n });\n };\n\n const cleanup = () => {\n // Clean up all payment method instances\n for (const pm of pmInstances) {\n if (pm.internalFuncs.cleanup) {\n pm.internalFuncs.cleanup();\n }\n }\n unmountTunnelX();\n };\n\n return {\n submit,\n cleanup,\n ...externalFuncsMapByPm,\n };\n};\n\nexport type { PaymentKitFields };\n\nexport default PaymentKit;\n"],"mappings":"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"}
@@ -268,4 +268,4 @@ const handleNextAction = async (nextAction) => {
268
268
 
269
269
  //#endregion
270
270
  export { handleNextAction as t };
271
- //# sourceMappingURL=next-action-handlers-BZs04hYb.mjs.map
271
+ //# sourceMappingURL=next-action-handlers-CTx8tRt0.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"next-action-handlers-BZs04hYb.mjs","names":[],"sources":["../src/utils/3ds-iframe-modal.ts","../src/payment-methods/next-action-handlers.ts"],"sourcesContent":["/**\n * 3DS iframe modal for displaying authentication pages.\n *\n * This module provides an iframe modal used by payment processors\n * that need to display a 3DS authentication page.\n */\n\ntype IframeModalResult = { success: true; data: Record<string, unknown> } | { success: false; error: string };\n\ntype ThreeDSCompleteMessage = {\n type: \"3ds_complete\";\n processor: string | null;\n isSuccess: boolean;\n error?: string;\n};\n\ntype IframeModalMessageHandler = (\n event: MessageEvent<ThreeDSCompleteMessage>,\n) => { handled: true; result: IframeModalResult } | { handled: false };\n\ninterface IframeModalOptions {\n /** URL to load in the iframe */\n url: string;\n /** Size of the iframe in pixels */\n size: { width: number; height: number };\n /** Border radius for the iframe in pixels (default: 16) */\n radius?: number;\n /** Handler to process postMessage events from the iframe */\n onMessage: IframeModalMessageHandler;\n}\n\n/**\n * Shows an iframe modal and waits for a result via postMessage.\n *\n * Features:\n * - Close/cancel button positioned outside the iframe\n * - Responsive design (works on mobile)\n * - Keyboard accessibility (Escape to close, focus trap)\n * - Fade-in/fade-out animations\n * - Iframe load error handling\n *\n * @param options - Modal configuration options\n * @returns Promise that resolves with success/failure result\n *\n * @example\n * ```ts\n * const result = await show3DSIframeModal({\n * url: \"https://bank.com/3ds-auth\",\n * size: { width: 605, height: 500 },\n * radius: 6,\n * onMessage: (event) => {\n * if (event.data?.type === \"auth_complete\") {\n * return {\n * handled: true,\n * result: event.data.succeeded\n * ? { success: true, data: { id: event.data.id } }\n * : { success: false, error: event.data.error }\n * };\n * }\n * return { handled: false };\n * },\n * });\n * ```\n */\n\nexport default function show3DSIframeModal(options: IframeModalOptions): Promise<IframeModalResult> {\n const { url, size, radius = 6, onMessage } = options;\n\n return new Promise((resolve) => {\n let resolved = false;\n\n // Create modal overlay with fade-in animation\n const overlay = document.createElement(\"div\");\n overlay.id = \"pk-iframe-modal-overlay\";\n overlay.setAttribute(\"role\", \"dialog\");\n overlay.setAttribute(\"aria-modal\", \"true\");\n overlay.setAttribute(\"aria-label\", \"3D Secure Verification\");\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n transition: background 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n `;\n\n // Create container for iframe and close button\n const container = document.createElement(\"div\");\n container.style.cssText = `\n position: relative;\n width: ${size.width}px;\n height: ${size.height}px;\n max-width: calc(100vw - 32px);\n max-height: calc(100vh - 64px);\n overflow: visible;\n opacity: 0;\n transform: scale(0.95) translateY(10px);\n transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n `;\n\n // Create close button (positioned outside top-right of iframe)\n const closeButton = document.createElement(\"button\");\n closeButton.id = \"pk-iframe-modal-close\";\n closeButton.setAttribute(\"aria-label\", \"Cancel verification\");\n closeButton.setAttribute(\"type\", \"button\");\n closeButton.style.cssText = `\n position: absolute;\n top: -40px;\n right: 0;\n width: 32px;\n height: 32px;\n border: none;\n background: white;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n transition: background 0.15s ease;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n `;\n closeButton.innerHTML = `\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1 1L13 13M1 13L13 1\" stroke=\"#666\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n `;\n closeButton.onmouseenter = (): void => {\n closeButton.style.background = \"#f5f5f5\";\n };\n closeButton.onmouseleave = (): void => {\n closeButton.style.background = \"white\";\n };\n\n // Create iframe (hidden initially until loaded)\n const iframe = document.createElement(\"iframe\");\n iframe.src = url;\n iframe.setAttribute(\"title\", \"3D Secure Verification\");\n iframe.style.cssText = `\n width: 100%;\n height: 100%;\n border: none;\n opacity: 0;\n border-radius: ${radius}px;\n background: white;\n transition: opacity 0.2s ease;\n position: relative;\n z-index: 1;\n `;\n\n // Handle iframe load success\n iframe.onload = (): void => {\n iframe.style.opacity = \"1\";\n };\n\n // Handle iframe load error\n iframe.onerror = (): void => {\n if (!resolved) {\n console.error(\"[IframeModal] Failed to load iframe\");\n cleanupWithAnimation();\n resolve({ success: false, error: \"Failed to load verification page. Please try again.\" });\n }\n };\n\n container.appendChild(closeButton);\n container.appendChild(iframe);\n overlay.appendChild(container);\n document.body.appendChild(overlay);\n\n // Trigger fade-in animation\n requestAnimationFrame(() => {\n overlay.style.background = \"rgba(0, 0, 0, 0.5)\";\n container.style.opacity = \"1\";\n container.style.transform = \"scale(1) translateY(0)\";\n });\n\n // Cleanup with fade-out animation\n const cleanupWithAnimation = (): void => {\n if (resolved) return;\n resolved = true;\n\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"keydown\", handleKeydown);\n\n // Use requestAnimationFrame to ensure transition is applied\n requestAnimationFrame(() => {\n overlay.style.background = \"rgba(0, 0, 0, 0)\";\n container.style.opacity = \"0\";\n container.style.transform = \"scale(0.95) translateY(10px)\";\n\n setTimeout(() => {\n if (overlay.parentNode) {\n overlay.parentNode.removeChild(overlay);\n }\n }, 250);\n });\n };\n\n // Handle close button click\n const handleCancel = (): void => {\n if (!resolved) {\n console.log(\"[IframeModal] User cancelled\");\n cleanupWithAnimation();\n resolve({ success: false, error: \"Verification cancelled\" });\n }\n };\n\n closeButton.onclick = handleCancel;\n\n // Handle Escape key\n const handleKeydown = (event: KeyboardEvent): void => {\n if (event.key === \"Escape\") {\n handleCancel();\n }\n // Trap focus within modal (Tab key cycles through close button and iframe)\n if (event.key === \"Tab\") {\n event.preventDefault();\n if (document.activeElement === closeButton) {\n iframe.focus();\n } else {\n closeButton.focus();\n }\n }\n };\n\n window.addEventListener(\"keydown\", handleKeydown);\n\n // Set initial focus to close button for accessibility\n closeButton.focus();\n\n const handleMessage = (event: MessageEvent): void => {\n const messageResult = onMessage(event);\n if (messageResult.handled) {\n cleanupWithAnimation();\n resolve(messageResult.result);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n}\n","/**\n * Next action handlers for processor-specific user actions (e.g., 3DS authentication).\n *\n * This module abstracts processor-specific logic away from the generic card payment flow.\n * Each handler implements the logic needed for a specific next action type.\n */\n\nimport type { PublicCardCheckoutResponse } from \"@pkg/sdk/models\";\nimport type { Stripe } from \"@stripe/stripe-js\";\nimport show3DSIframeModal from \"../utils/3ds-iframe-modal\";\n\n// Helper to wait for a condition\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n// Check if Stripe.js is loaded via script tag\nconst isStripeJsPresent = (): boolean => \"Stripe\" in window;\n\n/**\n * Get the Stripe instance from the global window object.\n * Expects Stripe.js to be loaded via HTML script tag.\n * Polls for up to 5 seconds waiting for Stripe to be available.\n */\nconst getLoadedStripe = async (publishableKey: string): Promise<Stripe> => {\n // Poll for Stripe.js to be loaded (up to 5 seconds)\n for (let i = 0; i < 10; i++) {\n if (isStripeJsPresent()) {\n break;\n }\n await sleep(500);\n }\n\n if (!isStripeJsPresent()) {\n throw new Error(\n \"Stripe.js not loaded. Add this script tag to your HTML <head>:\\n\" +\n '<script src=\"https://js.stripe.com/v3/\"></script>',\n );\n }\n\n // @ts-expect-error Stripe is loaded globally via script tag\n const stripe: Stripe = new window.Stripe(publishableKey);\n return stripe;\n};\n\n/**\n * Result of handling a next action.\n */\nexport type NextActionResult = { success: true } | { success: false; error: string };\n\n/**\n * Handle Stripe 3DS authentication.\n */\nconst handleStripe3ds = async (\n nextAction: Extract<PublicCardCheckoutResponse[\"nextAction\"], { type: \"stripe_3ds\" }>,\n): Promise<NextActionResult> => {\n const { clientSecret, stripePk } = nextAction;\n\n const stripe = await getLoadedStripe(stripePk);\n\n // Show 3DS modal\n const { error: stripeError } = await stripe.confirmCardPayment(clientSecret);\n\n if (stripeError) {\n console.error(\"[3DS:Stripe] Authentication failed:\", stripeError.message);\n return { success: false, error: stripeError.message || \"3DS authentication failed\" };\n }\n\n return { success: true };\n};\n\n/**\n * Handle Airwallex 3DS authentication via iframe.\n *\n * Renders an iframe with the 3DS authentication URL. The iframe will redirect\n * to the 3DS callback page which sends a postMessage back to complete the flow.\n */\nconst handleAirwallex3ds = async (\n nextAction: Extract<PublicCardCheckoutResponse[\"nextAction\"], { type: \"airwallex_3ds\" }>,\n): Promise<NextActionResult> => {\n return show3DSIframeModal({\n url: nextAction.url,\n size: { width: 605, height: 550 },\n onMessage: (event) => {\n if (event.data.type !== \"3ds_complete\") {\n return { handled: false };\n }\n\n const { isSuccess, error } = event.data;\n\n if (isSuccess) {\n return { handled: true, result: { success: true, data: {} } };\n } else {\n console.error(\"[3DS:Airwallex] Authentication failed:\", error);\n return {\n handled: true,\n result: { success: false, error: error || \"3DS authentication failed\" },\n };\n }\n },\n });\n};\n\n/**\n * Handle a next action based on its type.\n * Routes to the appropriate processor-specific handler.\n *\n * @param nextAction - The next action from the checkout response\n * @returns Result indicating success or failure with error message\n */\nexport const handleNextAction = async (\n nextAction: NonNullable<PublicCardCheckoutResponse[\"nextAction\"]>,\n): Promise<NextActionResult> => {\n switch (nextAction.type) {\n case \"stripe_3ds\":\n return handleStripe3ds(nextAction);\n case \"airwallex_3ds\":\n return handleAirwallex3ds(nextAction);\n default:\n // TypeScript will catch if we miss a case when new action types are added\n return { success: false, error: `Unknown next action type: ${(nextAction as { type: string }).type}` };\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"next-action-handlers-CTx8tRt0.mjs","names":[],"sources":["../src/utils/3ds-iframe-modal.ts","../src/payment-methods/next-action-handlers.ts"],"sourcesContent":["/**\n * 3DS iframe modal for displaying authentication pages.\n *\n * This module provides an iframe modal used by payment processors\n * that need to display a 3DS authentication page.\n */\n\ntype IframeModalResult = { success: true; data: Record<string, unknown> } | { success: false; error: string };\n\ntype ThreeDSCompleteMessage = {\n type: \"3ds_complete\";\n processor: string | null;\n isSuccess: boolean;\n error?: string;\n};\n\ntype IframeModalMessageHandler = (\n event: MessageEvent<ThreeDSCompleteMessage>,\n) => { handled: true; result: IframeModalResult } | { handled: false };\n\ninterface IframeModalOptions {\n /** URL to load in the iframe */\n url: string;\n /** Size of the iframe in pixels */\n size: { width: number; height: number };\n /** Border radius for the iframe in pixels (default: 16) */\n radius?: number;\n /** Handler to process postMessage events from the iframe */\n onMessage: IframeModalMessageHandler;\n}\n\n/**\n * Shows an iframe modal and waits for a result via postMessage.\n *\n * Features:\n * - Close/cancel button positioned outside the iframe\n * - Responsive design (works on mobile)\n * - Keyboard accessibility (Escape to close, focus trap)\n * - Fade-in/fade-out animations\n * - Iframe load error handling\n *\n * @param options - Modal configuration options\n * @returns Promise that resolves with success/failure result\n *\n * @example\n * ```ts\n * const result = await show3DSIframeModal({\n * url: \"https://bank.com/3ds-auth\",\n * size: { width: 605, height: 500 },\n * radius: 6,\n * onMessage: (event) => {\n * if (event.data?.type === \"auth_complete\") {\n * return {\n * handled: true,\n * result: event.data.succeeded\n * ? { success: true, data: { id: event.data.id } }\n * : { success: false, error: event.data.error }\n * };\n * }\n * return { handled: false };\n * },\n * });\n * ```\n */\n\nexport default function show3DSIframeModal(options: IframeModalOptions): Promise<IframeModalResult> {\n const { url, size, radius = 6, onMessage } = options;\n\n return new Promise((resolve) => {\n let resolved = false;\n\n // Create modal overlay with fade-in animation\n const overlay = document.createElement(\"div\");\n overlay.id = \"pk-iframe-modal-overlay\";\n overlay.setAttribute(\"role\", \"dialog\");\n overlay.setAttribute(\"aria-modal\", \"true\");\n overlay.setAttribute(\"aria-label\", \"3D Secure Verification\");\n overlay.style.cssText = `\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n background: rgba(0, 0, 0, 0);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10000;\n transition: background 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n `;\n\n // Create container for iframe and close button\n const container = document.createElement(\"div\");\n container.style.cssText = `\n position: relative;\n width: ${size.width}px;\n height: ${size.height}px;\n max-width: calc(100vw - 32px);\n max-height: calc(100vh - 64px);\n overflow: visible;\n opacity: 0;\n transform: scale(0.95) translateY(10px);\n transition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n `;\n\n // Create close button (positioned outside top-right of iframe)\n const closeButton = document.createElement(\"button\");\n closeButton.id = \"pk-iframe-modal-close\";\n closeButton.setAttribute(\"aria-label\", \"Cancel verification\");\n closeButton.setAttribute(\"type\", \"button\");\n closeButton.style.cssText = `\n position: absolute;\n top: -40px;\n right: 0;\n width: 32px;\n height: 32px;\n border: none;\n background: white;\n border-radius: 8px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n transition: background 0.15s ease;\n box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);\n `;\n closeButton.innerHTML = `\n <svg width=\"12\" height=\"12\" viewBox=\"0 0 14 14\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M1 1L13 13M1 13L13 1\" stroke=\"#666\" stroke-width=\"2\" stroke-linecap=\"round\"/>\n </svg>\n `;\n closeButton.onmouseenter = (): void => {\n closeButton.style.background = \"#f5f5f5\";\n };\n closeButton.onmouseleave = (): void => {\n closeButton.style.background = \"white\";\n };\n\n // Create iframe (hidden initially until loaded)\n const iframe = document.createElement(\"iframe\");\n iframe.src = url;\n iframe.setAttribute(\"title\", \"3D Secure Verification\");\n iframe.style.cssText = `\n width: 100%;\n height: 100%;\n border: none;\n opacity: 0;\n border-radius: ${radius}px;\n background: white;\n transition: opacity 0.2s ease;\n position: relative;\n z-index: 1;\n `;\n\n // Handle iframe load success\n iframe.onload = (): void => {\n iframe.style.opacity = \"1\";\n };\n\n // Handle iframe load error\n iframe.onerror = (): void => {\n if (!resolved) {\n console.error(\"[IframeModal] Failed to load iframe\");\n cleanupWithAnimation();\n resolve({ success: false, error: \"Failed to load verification page. Please try again.\" });\n }\n };\n\n container.appendChild(closeButton);\n container.appendChild(iframe);\n overlay.appendChild(container);\n document.body.appendChild(overlay);\n\n // Trigger fade-in animation\n requestAnimationFrame(() => {\n overlay.style.background = \"rgba(0, 0, 0, 0.5)\";\n container.style.opacity = \"1\";\n container.style.transform = \"scale(1) translateY(0)\";\n });\n\n // Cleanup with fade-out animation\n const cleanupWithAnimation = (): void => {\n if (resolved) return;\n resolved = true;\n\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"keydown\", handleKeydown);\n\n // Use requestAnimationFrame to ensure transition is applied\n requestAnimationFrame(() => {\n overlay.style.background = \"rgba(0, 0, 0, 0)\";\n container.style.opacity = \"0\";\n container.style.transform = \"scale(0.95) translateY(10px)\";\n\n setTimeout(() => {\n if (overlay.parentNode) {\n overlay.parentNode.removeChild(overlay);\n }\n }, 250);\n });\n };\n\n // Handle close button click\n const handleCancel = (): void => {\n if (!resolved) {\n console.log(\"[IframeModal] User cancelled\");\n cleanupWithAnimation();\n resolve({ success: false, error: \"Verification cancelled\" });\n }\n };\n\n closeButton.onclick = handleCancel;\n\n // Handle Escape key\n const handleKeydown = (event: KeyboardEvent): void => {\n if (event.key === \"Escape\") {\n handleCancel();\n }\n // Trap focus within modal (Tab key cycles through close button and iframe)\n if (event.key === \"Tab\") {\n event.preventDefault();\n if (document.activeElement === closeButton) {\n iframe.focus();\n } else {\n closeButton.focus();\n }\n }\n };\n\n window.addEventListener(\"keydown\", handleKeydown);\n\n // Set initial focus to close button for accessibility\n closeButton.focus();\n\n const handleMessage = (event: MessageEvent): void => {\n const messageResult = onMessage(event);\n if (messageResult.handled) {\n cleanupWithAnimation();\n resolve(messageResult.result);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n}\n","/**\n * Next action handlers for processor-specific user actions (e.g., 3DS authentication).\n *\n * This module abstracts processor-specific logic away from the generic card payment flow.\n * Each handler implements the logic needed for a specific next action type.\n */\n\nimport type { PublicCardCheckoutResponse } from \"@pkg/sdk/models\";\nimport type { Stripe } from \"@stripe/stripe-js\";\nimport show3DSIframeModal from \"../utils/3ds-iframe-modal\";\n\n// Helper to wait for a condition\nconst sleep = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n// Check if Stripe.js is loaded via script tag\nconst isStripeJsPresent = (): boolean => \"Stripe\" in window;\n\n/**\n * Get the Stripe instance from the global window object.\n * Expects Stripe.js to be loaded via HTML script tag.\n * Polls for up to 5 seconds waiting for Stripe to be available.\n */\nconst getLoadedStripe = async (publishableKey: string): Promise<Stripe> => {\n // Poll for Stripe.js to be loaded (up to 5 seconds)\n for (let i = 0; i < 10; i++) {\n if (isStripeJsPresent()) {\n break;\n }\n await sleep(500);\n }\n\n if (!isStripeJsPresent()) {\n throw new Error(\n \"Stripe.js not loaded. Add this script tag to your HTML <head>:\\n\" +\n '<script src=\"https://js.stripe.com/v3/\"></script>',\n );\n }\n\n // @ts-expect-error Stripe is loaded globally via script tag\n const stripe: Stripe = new window.Stripe(publishableKey);\n return stripe;\n};\n\n/**\n * Result of handling a next action.\n */\nexport type NextActionResult = { success: true } | { success: false; error: string };\n\n/**\n * Handle Stripe 3DS authentication.\n */\nconst handleStripe3ds = async (\n nextAction: Extract<PublicCardCheckoutResponse[\"nextAction\"], { type: \"stripe_3ds\" }>,\n): Promise<NextActionResult> => {\n const { clientSecret, stripePk } = nextAction;\n\n const stripe = await getLoadedStripe(stripePk);\n\n // Show 3DS modal\n const { error: stripeError } = await stripe.confirmCardPayment(clientSecret);\n\n if (stripeError) {\n console.error(\"[3DS:Stripe] Authentication failed:\", stripeError.message);\n return { success: false, error: stripeError.message || \"3DS authentication failed\" };\n }\n\n return { success: true };\n};\n\n/**\n * Handle Airwallex 3DS authentication via iframe.\n *\n * Renders an iframe with the 3DS authentication URL. The iframe will redirect\n * to the 3DS callback page which sends a postMessage back to complete the flow.\n */\nconst handleAirwallex3ds = async (\n nextAction: Extract<PublicCardCheckoutResponse[\"nextAction\"], { type: \"airwallex_3ds\" }>,\n): Promise<NextActionResult> => {\n return show3DSIframeModal({\n url: nextAction.url,\n size: { width: 605, height: 550 },\n onMessage: (event) => {\n if (event.data.type !== \"3ds_complete\") {\n return { handled: false };\n }\n\n const { isSuccess, error } = event.data;\n\n if (isSuccess) {\n return { handled: true, result: { success: true, data: {} } };\n } else {\n console.error(\"[3DS:Airwallex] Authentication failed:\", error);\n return {\n handled: true,\n result: { success: false, error: error || \"3DS authentication failed\" },\n };\n }\n },\n });\n};\n\n/**\n * Handle a next action based on its type.\n * Routes to the appropriate processor-specific handler.\n *\n * @param nextAction - The next action from the checkout response\n * @returns Result indicating success or failure with error message\n */\nexport const handleNextAction = async (\n nextAction: NonNullable<PublicCardCheckoutResponse[\"nextAction\"]>,\n): Promise<NextActionResult> => {\n switch (nextAction.type) {\n case \"stripe_3ds\":\n return handleStripe3ds(nextAction);\n case \"airwallex_3ds\":\n return handleAirwallex3ds(nextAction);\n default:\n // TypeScript will catch if we miss a case when new action types are added\n return { success: false, error: `Unknown next action type: ${(nextAction as { type: string }).type}` };\n }\n};\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { a as ApplePayEncryptedToken, i as AirwallexApplePayShowResult, n as AirwallexApplePayConfig, o as MerchantValidationCallback, r as AirwallexApplePayMockScenario, t as AirwallexApplePayAdapter } from "../airwallex-apple-pay-adapter-I_pnNYdy.mjs";
2
+ export { AirwallexApplePayAdapter, AirwallexApplePayConfig, AirwallexApplePayMockScenario, AirwallexApplePayShowResult, ApplePayEncryptedToken, MerchantValidationCallback };
@@ -0,0 +1,3 @@
1
+ import { n as AirwallexApplePayMockScenario, t as AirwallexApplePayAdapter } from "../airwallex-apple-pay-adapter-BE15xREr.mjs";
2
+
3
+ export { AirwallexApplePayAdapter, AirwallexApplePayMockScenario };
@@ -1,2 +1,2 @@
1
- import { a as GooglePayEncryptedToken, i as AirwallexShowPaymentResult, n as AirwallexGooglePayConfig, r as AirwallexGooglePayMockScenario, t as AirwallexGooglePayAdapter } from "../airwallex-google-pay-adapter-Be2Af4N9.mjs";
1
+ import { a as GooglePayEncryptedToken, i as AirwallexShowPaymentResult, n as AirwallexGooglePayConfig, r as AirwallexGooglePayMockScenario, t as AirwallexGooglePayAdapter } from "../airwallex-google-pay-adapter-CY379Rre.mjs";
2
2
  export { AirwallexGooglePayAdapter, AirwallexGooglePayConfig, AirwallexGooglePayMockScenario, AirwallexShowPaymentResult, GooglePayEncryptedToken };
@@ -1,3 +1,3 @@
1
- import { n as AirwallexGooglePayMockScenario, t as AirwallexGooglePayAdapter } from "../airwallex-google-pay-adapter-BCmTZip5.mjs";
1
+ import { n as AirwallexGooglePayMockScenario, t as AirwallexGooglePayAdapter } from "../airwallex-google-pay-adapter-CHol_8f2.mjs";
2
2
 
3
3
  export { AirwallexGooglePayAdapter, AirwallexGooglePayMockScenario };