@payment-kit-js/vanilla 0.3.0 → 0.4.1

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 (67) hide show
  1. package/dist/airwallex-google-pay-adapter-BCmTZip5.mjs +167 -0
  2. package/dist/airwallex-google-pay-adapter-BCmTZip5.mjs.map +1 -0
  3. package/dist/airwallex-google-pay-adapter-Be2Af4N9.d.mts +140 -0
  4. package/dist/airwallex-google-pay-adapter-Be2Af4N9.d.mts.map +1 -0
  5. package/dist/cdn/paymentkit.js +5768 -83
  6. package/dist/cdn/paymentkit.js.map +4 -4
  7. package/dist/cdn/paymentkit.min.js +58 -3
  8. package/dist/cdn/paymentkit.min.js.map +4 -4
  9. package/dist/{connect-card-DO2EJxu6.mjs → connect-card-BrtCmsjz.mjs} +1 -1
  10. package/dist/{connect-card-DO2EJxu6.mjs.map → connect-card-BrtCmsjz.mjs.map} +1 -1
  11. package/dist/{connect-card-C582hcWw.d.mts → connect-card-DTfXuTsW.d.mts} +1 -1
  12. package/dist/{connect-card-C582hcWw.d.mts.map → connect-card-DTfXuTsW.d.mts.map} +1 -1
  13. package/dist/connect-tunnel-x-BhVAej5Q.mjs.map +1 -1
  14. package/dist/{connect-tunnel-x-B7iMQ7DX.d.mts → connect-tunnel-x-Dxcg5Y7Y.d.mts} +6 -5
  15. package/dist/connect-tunnel-x-Dxcg5Y7Y.d.mts.map +1 -0
  16. package/dist/index.d.mts +3 -3
  17. package/dist/index.d.mts.map +1 -1
  18. package/dist/index.mjs +337 -5
  19. package/dist/index.mjs.map +1 -1
  20. package/dist/next-action-handlers-BZs04hYb.mjs +271 -0
  21. package/dist/next-action-handlers-BZs04hYb.mjs.map +1 -0
  22. package/dist/payment-methods/airwallex-google-pay-adapter.d.mts +2 -0
  23. package/dist/payment-methods/airwallex-google-pay-adapter.mjs +3 -0
  24. package/dist/payment-methods/apple-pay.d.mts +78 -0
  25. package/dist/payment-methods/apple-pay.d.mts.map +1 -0
  26. package/dist/payment-methods/apple-pay.mjs +188 -0
  27. package/dist/payment-methods/apple-pay.mjs.map +1 -0
  28. package/dist/payment-methods/card.d.mts +3 -3
  29. package/dist/payment-methods/card.d.mts.map +1 -1
  30. package/dist/payment-methods/card.mjs +40 -12
  31. package/dist/payment-methods/card.mjs.map +1 -1
  32. package/dist/payment-methods/google-pay.d.mts +25 -7
  33. package/dist/payment-methods/google-pay.d.mts.map +1 -1
  34. package/dist/payment-methods/google-pay.mjs +165 -30
  35. package/dist/payment-methods/google-pay.mjs.map +1 -1
  36. package/dist/payment-methods/next-action-handlers.d.mts.map +1 -1
  37. package/dist/payment-methods/next-action-handlers.mjs +1 -1
  38. package/dist/payment-methods/paypal.d.mts +3 -3
  39. package/dist/payment-methods/paypal.d.mts.map +1 -1
  40. package/dist/payment-methods/paypal.mjs +8 -3
  41. package/dist/payment-methods/paypal.mjs.map +1 -1
  42. package/dist/payment-methods/stripe-apple-pay-adapter.d.mts +2 -0
  43. package/dist/payment-methods/stripe-apple-pay-adapter.mjs +3 -0
  44. package/dist/payment-methods/stripe-google-pay-adapter.d.mts +1 -1
  45. package/dist/payment-methods/stripe-google-pay-adapter.mjs +1 -1
  46. package/dist/penpal/connect-card.d.mts +1 -1
  47. package/dist/penpal/connect-card.mjs +1 -1
  48. package/dist/penpal/connect-tunnel-x.d.mts +1 -1
  49. package/dist/stripe-apple-pay-adapter-Bg7nCy3P.mjs +313 -0
  50. package/dist/stripe-apple-pay-adapter-Bg7nCy3P.mjs.map +1 -0
  51. package/dist/stripe-apple-pay-adapter-Bq3f1mqv.d.mts +141 -0
  52. package/dist/stripe-apple-pay-adapter-Bq3f1mqv.d.mts.map +1 -0
  53. package/dist/{stripe-google-pay-adapter-DMDArVp2.mjs → stripe-google-pay-adapter-DjrgDYWe.mjs} +1 -1
  54. package/dist/{stripe-google-pay-adapter-DMDArVp2.mjs.map → stripe-google-pay-adapter-DjrgDYWe.mjs.map} +1 -1
  55. package/dist/{stripe-google-pay-adapter-DUUB46SG.d.mts → stripe-google-pay-adapter-xktEycOD.d.mts} +1 -1
  56. package/dist/{stripe-google-pay-adapter-DUUB46SG.d.mts.map → stripe-google-pay-adapter-xktEycOD.d.mts.map} +1 -1
  57. package/dist/types-CPuloCtF.d.mts +129 -0
  58. package/dist/types-CPuloCtF.d.mts.map +1 -0
  59. package/dist/{utils-h0dxplHy.mjs → utils-Dgyk7RkM.mjs} +40 -2
  60. package/dist/utils-Dgyk7RkM.mjs.map +1 -0
  61. package/package.json +9 -3
  62. package/dist/connect-tunnel-x-B7iMQ7DX.d.mts.map +0 -1
  63. package/dist/next-action-handlers-DTsWjUIA.mjs +0 -53
  64. package/dist/next-action-handlers-DTsWjUIA.mjs.map +0 -1
  65. package/dist/types-DsVMq4jZ.d.mts +0 -64
  66. package/dist/types-DsVMq4jZ.d.mts.map +0 -1
  67. package/dist/utils-h0dxplHy.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-DO2EJxu6.mjs.map
19
+ //# sourceMappingURL=connect-card-BrtCmsjz.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect-card-DO2EJxu6.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-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"}
@@ -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-C582hcWw.d.mts.map
23
+ //# sourceMappingURL=connect-card-DTfXuTsW.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect-card-C582hcWw.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-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 +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 */\ntype PublicEndpointsProxy = {\n createCardSetupIntent: (params: { checkoutToken: string }) => Promise<CreateCardSetupIntentRes>;\n getCardSetupIntent: (params: { checkoutToken: string; cardSetupIntentId: string }) => Promise<CardSetupIntent>;\n cardCheckout: (params: {\n checkoutToken: string;\n publicCardCheckoutRequest: PublicCardCheckoutRequest;\n }) => Promise<PublicCardCheckoutResponse>;\n cardCheckoutVerify: (params: { checkoutToken: string }) => 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;;AAkBlF,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} 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"}
@@ -19,22 +19,23 @@ declare const connectToTunnelXParent: (methods: TunnelXIFrameMethods) => Connect
19
19
  * SDK type for publicEndpoints proxy.
20
20
  * Matches the methods on PublicCors from @pkg/sdk that are called through queryPublicEndpoint.
21
21
  * Parameter types match the SDK's operation request types.
22
+ * All methods accept an optional RequestOptions parameter for passing headers (e.g., x-request-id).
22
23
  */
23
24
  type PublicEndpointsProxy = {
24
25
  createCardSetupIntent: (params: {
25
26
  checkoutToken: string;
26
- }) => Promise<CreateCardSetupIntentRes>;
27
+ }, options?: RequestOptions) => Promise<CreateCardSetupIntentRes>;
27
28
  getCardSetupIntent: (params: {
28
29
  checkoutToken: string;
29
30
  cardSetupIntentId: string;
30
- }) => Promise<CardSetupIntent>;
31
+ }, options?: RequestOptions) => Promise<CardSetupIntent>;
31
32
  cardCheckout: (params: {
32
33
  checkoutToken: string;
33
34
  publicCardCheckoutRequest: PublicCardCheckoutRequest;
34
- }) => Promise<PublicCardCheckoutResponse>;
35
+ }, options?: RequestOptions) => Promise<PublicCardCheckoutResponse>;
35
36
  cardCheckoutVerify: (params: {
36
37
  checkoutToken: string;
37
- }) => Promise<PublicCardCheckoutResponse>;
38
+ }, options?: RequestOptions) => Promise<PublicCardCheckoutResponse>;
38
39
  };
39
40
  declare class TunnelXManager {
40
41
  private penpalConn;
@@ -50,4 +51,4 @@ declare class TunnelXManager {
50
51
  }
51
52
  //#endregion
52
53
  export { connectToTunnelXParent as a, connectToTunnelXIframe as i, TunnelXManager as n, TunnelXParentConnection as r, TunnelXIFrameConnection as t };
53
- //# sourceMappingURL=connect-tunnel-x-B7iMQ7DX.d.mts.map
54
+ //# sourceMappingURL=connect-tunnel-x-Dxcg5Y7Y.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-tunnel-x-Dxcg5Y7Y.d.mts","names":[],"sources":["../src/penpal/connect-tunnel-x.ts"],"sourcesContent":[],"mappings":";;;AAOyC,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,kBAAA,EAAA,CAAA,MAAoB,EAAA;IAGX,aAAA,EAAA,MAAA;IACC,iBAAA,EAAA,MAAA;EAAR,CAAA,EAAA,OAAA,CAAA,EAGO,cAHP,EAAA,GAIA,OAJA,CAIQ,eAJR,CAAA;EAGO,YAAA,EAAA,CAAA,MAAA,EAAA;IACC,aAAA,EAAA,MAAA;IAAR,yBAAA,EAI0B,yBAJ1B;EAI0B,CAAA,EAAA,OAAA,CAAA,EAEnB,cAFmB,EAAA,GAG1B,OAH0B,CAGlB,0BAHkB,CAAA;EAEnB,kBAAA,EAAA,CAAA,MAAA,EAAA;IACC,aAAA,EAAA,MAAA;EAAR,CAAA,EAAA,OAAA,CAAA,EAGO,cAHP,EAAA,GAIA,OAJA,CAIQ,0BAJR,CAAA;CAGO;AACC,cAGF,cAAA,CAHE;EAAR,QAAA,UAAA;EAAO,QAAA,EAKK,oBALL;EAGD,OAAA,0BAAc,EAAA,CAAA,UAAA,EAI8B,uBAJ9B,EAAA,GAIqD,OAJrD,CAIqD,cAJrD,CAAA;EAER,QAAA,WAAA,CAAA;EAEsC;;;;EAeZ,IAAA,eAAA,CAAA,CAAA,EAApB,oBAAoB"}
package/dist/index.d.mts CHANGED
@@ -1,6 +1,6 @@
1
- import "./connect-card-C582hcWw.mjs";
2
- import "./connect-tunnel-x-B7iMQ7DX.mjs";
3
- import { n as PaymentKitFields, t as PaymentKit$1 } from "./types-DsVMq4jZ.mjs";
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";
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":";;;;;cAyBM,YAAY"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"sourcesContent":[],"mappings":";;;;;cA0BM,YAAY"}
package/dist/index.mjs CHANGED
@@ -1,9 +1,331 @@
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-h0dxplHy.mjs";
3
+ import { r as createCheckoutIFrame } from "./utils-Dgyk7RkM.mjs";
4
+ import posthog from "posthog-js";
4
5
 
5
6
  //#region package.json
6
- var version = "0.3.0";
7
+ var version = "0.4.1";
8
+
9
+ //#endregion
10
+ //#region src/analytics/mock-adapter.ts
11
+ /**
12
+ * Mock analytics adapter for testing.
13
+ *
14
+ * Records all captured events for assertion in tests.
15
+ */
16
+ var MockAnalyticsAdapter = class {
17
+ events = [];
18
+ distinctId = null;
19
+ identify(distinctId) {
20
+ this.distinctId = distinctId;
21
+ }
22
+ capture(event, properties) {
23
+ this.events.push({
24
+ event,
25
+ distinct_id: this.distinctId,
26
+ properties,
27
+ timestamp: Date.now()
28
+ });
29
+ }
30
+ isInitialized() {
31
+ return true;
32
+ }
33
+ /**
34
+ * Get all captured events.
35
+ */
36
+ getEvents() {
37
+ return [...this.events];
38
+ }
39
+ /**
40
+ * Get events by name.
41
+ */
42
+ getEventsByName(eventName) {
43
+ return this.events.filter((e) => e.event === eventName);
44
+ }
45
+ /**
46
+ * Clear all captured events.
47
+ */
48
+ clear() {
49
+ this.events = [];
50
+ }
51
+ };
52
+
53
+ //#endregion
54
+ //#region src/analytics/posthog-adapter.ts
55
+ const POSTHOG_API_KEY = "phc_u9YDYUeUxo3CYn16XGrrwpVb8ycXgcjz5DarvIKRAAG";
56
+ /**
57
+ * PostHog implementation of the analytics adapter.
58
+ *
59
+ * Singleton stored in window to ensure only one instance exists across
60
+ * all script loads. Configures PostHog to use the reverse proxy at
61
+ * /ingest to avoid ad blockers.
62
+ */
63
+ var PostHogAdapter = class PostHogAdapter {
64
+ initialized = false;
65
+ /**
66
+ * Get or create the PostHog adapter singleton (stored in window).
67
+ *
68
+ * @param apiBaseUrl - The API base URL for the reverse proxy
69
+ * @throws Error if called with a different apiBaseUrl than the first call
70
+ */
71
+ static getInstance(apiBaseUrl) {
72
+ if (typeof window === "undefined") throw new Error("[PaymentKit Analytics] PostHog requires a browser environment");
73
+ const existing = window.__paymentKitPostHog__;
74
+ if (existing) {
75
+ if (existing.apiBaseUrl !== apiBaseUrl) throw new Error(`[PaymentKit Analytics] PostHog already initialized with apiBaseUrl "${existing.apiBaseUrl}", cannot re-initialize with different apiBaseUrl "${apiBaseUrl}"`);
76
+ return existing.instance;
77
+ }
78
+ const instance = new PostHogAdapter(apiBaseUrl);
79
+ window.__paymentKitPostHog__ = {
80
+ instance,
81
+ apiBaseUrl
82
+ };
83
+ return instance;
84
+ }
85
+ constructor(apiBaseUrl) {
86
+ this.initPostHog(apiBaseUrl);
87
+ }
88
+ initPostHog(apiBaseUrl) {
89
+ try {
90
+ posthog.init(POSTHOG_API_KEY, {
91
+ api_host: `${apiBaseUrl}/ingest`,
92
+ ui_host: "https://us.posthog.com",
93
+ persistence: "memory",
94
+ disable_session_recording: true,
95
+ autocapture: false,
96
+ capture_pageview: false,
97
+ request_batching: false,
98
+ opt_out_useragent_filter: true,
99
+ loaded: () => {
100
+ this.initialized = true;
101
+ }
102
+ });
103
+ } catch (e) {
104
+ console.warn("[PaymentKit Analytics] Failed to initialize PostHog:", e);
105
+ }
106
+ }
107
+ identify(distinctId) {
108
+ try {
109
+ posthog.identify(distinctId);
110
+ } catch (e) {
111
+ console.warn("[PaymentKit Analytics] Failed to identify:", e);
112
+ }
113
+ }
114
+ capture(event, properties) {
115
+ try {
116
+ posthog.capture(event, properties);
117
+ } catch (e) {
118
+ console.warn("[PaymentKit Analytics] Failed to capture event:", e);
119
+ }
120
+ }
121
+ isInitialized() {
122
+ return this.initialized;
123
+ }
124
+ };
125
+
126
+ //#endregion
127
+ //#region src/analytics/service.ts
128
+ /**
129
+ * Analytics service singleton.
130
+ *
131
+ * Provides a global interface for capturing analytics events.
132
+ * Supports multiple adapters that receive all events (composite pattern).
133
+ *
134
+ * Usage:
135
+ * // Initialize (typically done once at SDK init)
136
+ * AnalyticsService.init("http://localhost:9000");
137
+ *
138
+ * // Capture events - broadcasts to all registered adapters
139
+ * AnalyticsService.capture("checkout_page_ready", { session_id: "..." });
140
+ *
141
+ * // For testing - add a mock adapter
142
+ * import { MockAnalyticsAdapter } from "./mock-adapter";
143
+ * const mock = new MockAnalyticsAdapter();
144
+ * AnalyticsService.addAdapter(mock);
145
+ *
146
+ * // Or use the built-in test mock (exposed globally as window.__paymentKitAnalytics__)
147
+ * AnalyticsService.enableTestMode();
148
+ * // Events can be read via window.__paymentKitAnalytics__.getEvents()
149
+ */
150
+ var AnalyticsServiceClass = class {
151
+ adapters = [];
152
+ testMock = null;
153
+ /**
154
+ * Initialize the analytics service with PostHog.
155
+ *
156
+ * @param apiBaseUrl - The API base URL for the reverse proxy
157
+ * @param enableTestMode - Enable test mode for capturing events in tests
158
+ */
159
+ init(apiBaseUrl, enableTestMode) {
160
+ try {
161
+ this.addAdapter(PostHogAdapter.getInstance(apiBaseUrl));
162
+ if (enableTestMode) this.enableTestMode();
163
+ } catch (e) {
164
+ console.warn("[PaymentKit Analytics] Init failed:", e);
165
+ }
166
+ }
167
+ /**
168
+ * Enable test mode by adding a mock adapter and exposing it globally.
169
+ * The mock adapter is accessible via window.__paymentKitAnalytics__
170
+ */
171
+ enableTestMode() {
172
+ if (this.testMock) return;
173
+ this.testMock = new MockAnalyticsAdapter();
174
+ this.addAdapter(this.testMock);
175
+ if (typeof window !== "undefined") window.__paymentKitAnalytics__ = this.testMock;
176
+ }
177
+ /**
178
+ * Get the test mock adapter (if test mode is enabled).
179
+ */
180
+ getTestMock() {
181
+ return this.testMock;
182
+ }
183
+ /**
184
+ * Add an analytics adapter.
185
+ * Events will be broadcast to all registered adapters.
186
+ * Duplicate adapters (same instance) are ignored.
187
+ *
188
+ * @param adapter - The adapter to add
189
+ */
190
+ addAdapter(adapter) {
191
+ if (!this.adapters.includes(adapter)) this.adapters.push(adapter);
192
+ }
193
+ /**
194
+ * Clear all adapters.
195
+ */
196
+ clearAdapters() {
197
+ this.adapters = [];
198
+ this.testMock = null;
199
+ if (typeof window !== "undefined") delete window.__paymentKitAnalytics__;
200
+ }
201
+ /**
202
+ * Set the distinct_id for all adapters.
203
+ * This is used to correlate frontend events with backend events.
204
+ * Should be called with the checkout session secure token.
205
+ */
206
+ identify(distinctId) {
207
+ for (const adapter of this.adapters) try {
208
+ adapter.identify(distinctId);
209
+ } catch {}
210
+ }
211
+ /**
212
+ * Capture an analytics event.
213
+ * Broadcasts to all registered adapters. Silently fails on errors.
214
+ */
215
+ capture(event, properties) {
216
+ for (const adapter of this.adapters) try {
217
+ adapter.capture(event, properties);
218
+ } catch {}
219
+ }
220
+ /**
221
+ * Check if any adapter is initialized.
222
+ */
223
+ isInitialized() {
224
+ return this.adapters.some((adapter) => adapter.isInitialized());
225
+ }
226
+ };
227
+ /**
228
+ * Global analytics service instance.
229
+ */
230
+ const AnalyticsService = new AnalyticsServiceClass();
231
+
232
+ //#endregion
233
+ //#region src/analytics/checkout-timing.ts
234
+ /**
235
+ * Tracks timing metrics throughout the checkout flow.
236
+ *
237
+ * Create one instance per checkout session and call the track methods
238
+ * at appropriate points in the checkout flow.
239
+ *
240
+ * Usage:
241
+ * const tracker = new CheckoutTimingTracker(secureToken);
242
+ * tracker.trackPageReady();
243
+ * // ... iframe loads ...
244
+ * tracker.trackInputReady();
245
+ * // ... user submits ...
246
+ * tracker.trackSubmit();
247
+ * // ... API response ...
248
+ * tracker.trackSuccess(attemptId);
249
+ */
250
+ var CheckoutTimingTracker = class CheckoutTimingTracker {
251
+ static pageReadyTracked = false;
252
+ startTime;
253
+ checkoutSessionId;
254
+ inputReadyTracked = false;
255
+ constructor(checkoutSessionId) {
256
+ this.startTime = performance.now();
257
+ this.checkoutSessionId = checkoutSessionId;
258
+ }
259
+ /**
260
+ * Track when SDK is initialized and ready.
261
+ * Call immediately after PaymentKit() initialization.
262
+ * Only tracks once per page load (subsequent calls are no-ops).
263
+ */
264
+ trackPageReady() {
265
+ if (CheckoutTimingTracker.pageReadyTracked) return;
266
+ CheckoutTimingTracker.pageReadyTracked = true;
267
+ AnalyticsService.capture("checkout_page_ready", {
268
+ checkout_session_id: this.checkoutSessionId,
269
+ elapsed_ms: this.getElapsedMs()
270
+ });
271
+ }
272
+ /**
273
+ * Track when card input iframe is loaded and ready for input.
274
+ * Should only be called once (for first iframe, typically card_pan).
275
+ * Subsequent calls are no-ops.
276
+ */
277
+ trackInputReady() {
278
+ if (this.inputReadyTracked) return;
279
+ this.inputReadyTracked = true;
280
+ AnalyticsService.capture("checkout_input_ready", {
281
+ checkout_session_id: this.checkoutSessionId,
282
+ elapsed_ms: this.getElapsedMs()
283
+ });
284
+ }
285
+ /**
286
+ * Track when user clicks submit button.
287
+ */
288
+ trackSubmit() {
289
+ AnalyticsService.capture("checkout_submit", {
290
+ checkout_session_id: this.checkoutSessionId,
291
+ elapsed_ms: this.getElapsedMs()
292
+ });
293
+ }
294
+ /**
295
+ * Track successful checkout.
296
+ *
297
+ * @param checkoutAttemptId - The checkout attempt ID
298
+ */
299
+ trackSuccess(checkoutAttemptId) {
300
+ AnalyticsService.capture("checkout_success", {
301
+ checkout_session_id: this.checkoutSessionId,
302
+ checkout_attempt_id: checkoutAttemptId,
303
+ total_elapsed_ms: this.getElapsedMs()
304
+ });
305
+ }
306
+ /**
307
+ * Track failed checkout.
308
+ *
309
+ * @param checkoutAttemptId - The checkout attempt ID (may be null if failed early)
310
+ * @param errorCode - The error code from the checkout response
311
+ * @param errorMessage - The customer-facing error message
312
+ */
313
+ trackFail(checkoutAttemptId, errorCode, errorMessage) {
314
+ AnalyticsService.capture("checkout_fail", {
315
+ checkout_session_id: this.checkoutSessionId,
316
+ checkout_attempt_id: checkoutAttemptId,
317
+ error_code: errorCode,
318
+ error_message: errorMessage,
319
+ total_elapsed_ms: this.getElapsedMs()
320
+ });
321
+ }
322
+ /**
323
+ * Get elapsed time in milliseconds since tracker creation.
324
+ */
325
+ getElapsedMs() {
326
+ return Math.round(performance.now() - this.startTime);
327
+ }
328
+ };
7
329
 
8
330
  //#endregion
9
331
  //#region src/types.ts
@@ -12,6 +334,10 @@ const ENVIRONMENT_URLS = {
12
334
  baseUrl: "http://localhost:9101",
13
335
  apiBaseUrl: "http://localhost:9000"
14
336
  },
337
+ loclx: {
338
+ baseUrl: "https://pkmateuscportal.loclx.io",
339
+ apiBaseUrl: "https://pkmateusapi.loclx.io"
340
+ },
15
341
  sandbox: {
16
342
  baseUrl: "https://staging.paymentkit.com/customer",
17
343
  apiBaseUrl: "https://staging.paymentkit.com"
@@ -23,7 +349,7 @@ const ENVIRONMENT_URLS = {
23
349
  };
24
350
  function getUrlsForEnvironment(environment) {
25
351
  const urls = ENVIRONMENT_URLS[environment];
26
- if (!urls) throw new Error(`Invalid environment: ${environment}. Must be one of: local, sandbox, production`);
352
+ if (!urls) throw new Error(`Invalid environment: ${environment}. Must be one of: local, loclx, sandbox, production`);
27
353
  return urls;
28
354
  }
29
355
 
@@ -45,15 +371,21 @@ const createTunnelXConnection = (baseUrl, apiBaseUrl, token) => {
45
371
  connection
46
372
  };
47
373
  };
48
- const PaymentKit = ({ environment, secureToken, paymentMethods }) => {
374
+ const PaymentKit = ({ environment, secureToken, paymentMethods, __enableAnalyticsTestMode }) => {
49
375
  const { baseUrl, apiBaseUrl } = getUrlsForEnvironment(environment);
50
376
  console.log(`[PaymentKit] v${version} initialized (env: ${environment})`);
377
+ AnalyticsService.init(apiBaseUrl, __enableAnalyticsTestMode);
378
+ AnalyticsService.identify(secureToken);
379
+ const timingTracker = new CheckoutTimingTracker(secureToken);
380
+ timingTracker.trackPageReady();
51
381
  const { connection: tunnelXConnection, unmount: unmountTunnelX } = createTunnelXConnection(baseUrl, apiBaseUrl, secureToken);
52
382
  const paymentKitStates = {
53
383
  baseUrl,
54
384
  apiBaseUrl,
55
385
  secureToken,
56
- tunnelXConnection
386
+ environment,
387
+ tunnelXConnection,
388
+ timingTracker
57
389
  };
58
390
  const pmInstances = paymentMethods.map((paymentMethod) => paymentMethod(paymentKitStates));
59
391
  const externalFuncsMapByPm = pmInstances.reduce((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/types.ts","../src/index.ts"],"sourcesContent":["{\n \"name\": \"@payment-kit-js/vanilla\",\n \"version\": \"0.3.0\",\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/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-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 \"penpal\": \"^7.0.4\",\n \"valibot\": \"^1.1.0\"\n },\n \"devDependencies\": {\n \"@pkg/sdk\": \"workspace:*\",\n \"@pkg/tsconfig\": \"workspace:*\",\n \"@stripe/stripe-js\": \"^5.5.0\",\n \"esbuild\": \"^0.24.2\",\n \"tsdown\": \"^0.15.10\",\n \"typescript\": \"^5.9.3\"\n },\n \"stableVersion\": \"0.3.0\"\n}\n","import type { CardErrorCode } from \"./penpal/connect-card\";\nimport type { TunnelXIFrameConnection } from \"./penpal/connect-tunnel-x\";\n\nexport type PaymentKitEnvironment = \"local\" | \"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 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, 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}) => 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 tunnelXConnection: TunnelXIFrameConnection;\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 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 { 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 }) => {\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 const { connection: tunnelXConnection, unmount: unmountTunnelX } = createTunnelXConnection(\n baseUrl,\n apiBaseUrl,\n secureToken,\n );\n\n const paymentKitStates = {\n baseUrl,\n apiBaseUrl,\n secureToken,\n tunnelXConnection,\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":";;;;;cAEa;;;;ACSb,MAAMA,mBAAmE;CACvE,OAAO;EACL,SAAS;EACT,YAAY;EACb;CACD,SAAS;EACP,SAAS;EACT,YAAY;EACb;CACD,YAAY;EACV,SAAS;EACT,YAAY;EACb;CACF;AAED,SAAgB,sBAAsB,aAAsC;CAE1E,MAAM,OAAO,iBADD;AAEZ,KAAI,CAAC,KACH,OAAM,IAAI,MAAM,wBAAwB,YAAY,8CAA8C;AAEpG,QAAO;;;;;ACxBT,MAAM,2BAA2B,SAAiB,YAAoB,UAAkB;CACtF,MAAM,SAAS,qBAAqB,YAAY,SAAS;EACvD,gBAAgB;EAChB,cAAc;EACf,CAAC;AACF,UAAS,KAAK,YAAY,OAAO;CAEjC,MAAM,aAAa,uBAAuB,QAAQ,EAAE,CAAC;CAErD,MAAM,gBAAgB;AACpB,aAAW,SAAS;AACpB,WAAS,KAAK,YAAY,OAAO;;AAGnC,QAAO;EAAE;EAAS;EAAY;;AAGhC,MAAMC,cAA8B,EAAE,aAAa,aAAa,qBAAqB;CAInF,MAAM,EAAE,SAAS,eAAe,sBAAsB,YAAY;AAGlE,SAAQ,IAAI,iBAAiBC,QAAgB,qBAAqB,YAAY,GAAG;CAEjF,MAAM,EAAE,YAAY,mBAAmB,SAAS,mBAAmB,wBACjE,SACA,YACA,YACD;CAED,MAAM,mBAAmB;EACvB;EACA;EACA;EACA;EACD;CAED,MAAM,cAAc,eAAe,KAAK,kBAAkB,cAAc,iBAAiB,CAAC;CAE1F,MAAMC,uBAA6D,YAAY,QAC5E,KAAK,EAAE,MAAM,oBAAoB;AAEhC,MAAI,QAAQ;AACZ,SAAO;IAET,EAAE,CACH;CAED,MAAMC,UAA0C,EAC9C,eAAe,mBACf,QACA,SACA,WACA,cACI;EACJ,MAAM,gBAAgB,YAAY,MAAM,EAAE,WAAW,SAAS,kBAAkB;AAChF,MAAI,CAAC,eAAe;AAClB,WAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC7C;;AAEF,gBAAc,cACX,cAAc,QAAQ,QAAQ,CAC9B,MAAM,EAAE,MAAM,aAAa;AAC1B,YAAS,QAAQ,OAAO,GAAG,UAAU,KAAK;IAC1C,CACD,OAAO,MAAM;AACZ,WAAQ,MAAM,2BAA2B,EAAE;AAG3C,OAAI,GAAG,UAAU,KACf,SAAQ,EAAE,SAAS,KAAK;YACf,GAAG,QACZ,SAAQ,EAAE,MAAM,EAAE,SAAS,CAAC;OAE5B,SAAQ,EAAE,MAAM,iBAAiB,CAAC;IAEpC;;CAGN,MAAM,gBAAgB;AAEpB,OAAK,MAAM,MAAM,YACf,KAAI,GAAG,cAAc,QACnB,IAAG,cAAc,SAAS;AAG9B,kBAAgB;;AAGlB,QAAO;EACL;EACA;EACA,GAAG;EACJ;;AAKH,kBAAe"}
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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"}