@payment-kit-js/vanilla 0.5.17 → 0.5.19
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.
- package/README.md +14 -0
- package/dist/{bnpl-shared-DGs1YzS9.mjs → bnpl-shared-CL900HFN.mjs} +2 -2
- package/dist/{bnpl-shared-DGs1YzS9.mjs.map → bnpl-shared-CL900HFN.mjs.map} +1 -1
- package/dist/{bnpl-shared-BQwCBD45.d.mts → bnpl-shared-D-Kd58Qz.d.mts} +2 -2
- package/dist/{bnpl-shared-BQwCBD45.d.mts.map → bnpl-shared-D-Kd58Qz.d.mts.map} +1 -1
- package/dist/cdn/paymentkit.js +263 -61
- package/dist/cdn/paymentkit.js.map +3 -3
- package/dist/cdn/paymentkit.min.js +24 -24
- package/dist/cdn/paymentkit.min.js.map +3 -3
- package/dist/index.d.mts +2 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +75 -6
- package/dist/index.mjs.map +1 -1
- package/dist/{next-action-handlers-CLOt1wzO.mjs → next-action-handlers-DzhzSvEB.mjs} +19 -19
- package/dist/next-action-handlers-DzhzSvEB.mjs.map +1 -0
- package/dist/payment-methods/affirm.d.mts +2 -2
- package/dist/payment-methods/affirm.mjs +2 -2
- package/dist/payment-methods/afterpay.d.mts +2 -2
- package/dist/payment-methods/afterpay.mjs +2 -2
- package/dist/payment-methods/apple-pay.d.mts +2 -2
- package/dist/payment-methods/apple-pay.d.mts.map +1 -1
- package/dist/payment-methods/apple-pay.mjs +2 -2
- package/dist/payment-methods/apple-pay.mjs.map +1 -1
- package/dist/payment-methods/bnpl-shared.d.mts +2 -2
- package/dist/payment-methods/bnpl-shared.mjs +2 -2
- package/dist/payment-methods/card.d.mts +1 -1
- package/dist/payment-methods/card.d.mts.map +1 -1
- package/dist/payment-methods/card.mjs +14 -8
- package/dist/payment-methods/card.mjs.map +1 -1
- package/dist/payment-methods/google-pay.d.mts +25 -3
- package/dist/payment-methods/google-pay.d.mts.map +1 -1
- package/dist/payment-methods/google-pay.mjs +131 -10
- package/dist/payment-methods/google-pay.mjs.map +1 -1
- package/dist/payment-methods/klarna.d.mts +2 -2
- package/dist/payment-methods/klarna.mjs +2 -2
- package/dist/payment-methods/next-action-handlers.mjs +1 -1
- package/dist/payment-methods/paypal.d.mts +1 -1
- package/dist/payment-methods/paypal.mjs +1 -1
- package/dist/{types-B3mjYfOm.d.mts → types-Cjcc3xak.d.mts} +6 -9
- package/dist/types-Cjcc3xak.d.mts.map +1 -0
- package/dist/{utils-Dc6zwOe1.mjs → utils-DIqrx4XF.mjs} +10 -7
- package/dist/utils-DIqrx4XF.mjs.map +1 -0
- package/package.json +2 -2
- package/dist/next-action-handlers-CLOt1wzO.mjs.map +0 -1
- package/dist/types-B3mjYfOm.d.mts.map +0 -1
- package/dist/utils-Dc6zwOe1.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -7,3 +7,17 @@ Vanilla JavaScript SDK for PaymentKit. A type-safe, framework-agnostic payment p
|
|
|
7
7
|
For complete documentation, guides, and examples, visit:
|
|
8
8
|
|
|
9
9
|
**[PaymentKit.js Documentation](https://docs.paymentkit.com/guides/integration/sdk-reference/payment-kit-js/getting-started)**
|
|
10
|
+
|
|
11
|
+
## Content-Security-Policy Requirements
|
|
12
|
+
|
|
13
|
+
If your site uses a Content-Security-Policy header, you must add the following domains to your `script-src` directive to allow fraud prevention scripts:
|
|
14
|
+
|
|
15
|
+
- **Production:** `https://static.airwallex.com`
|
|
16
|
+
- **Sandbox:** `https://static-demo.airwallex.com`
|
|
17
|
+
|
|
18
|
+
Example:
|
|
19
|
+
```
|
|
20
|
+
Content-Security-Policy: script-src 'self' https://static.airwallex.com;
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
If these domains are blocked, PaymentKit.js will log an error to the console with the required domain.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as definePaymentMethod, n as collectFraudMetadata, o as getOrCreateCheckoutRequestId } from "./utils-
|
|
1
|
+
import { i as definePaymentMethod, n as collectFraudMetadata, o as getOrCreateCheckoutRequestId } from "./utils-DIqrx4XF.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/payment-methods/bnpl-shared.ts
|
|
4
4
|
const createSubmitPayment = (states, config) => {
|
|
@@ -104,4 +104,4 @@ function createBnplPaymentMethod(config) {
|
|
|
104
104
|
|
|
105
105
|
//#endregion
|
|
106
106
|
export { createBnplPaymentMethod as t };
|
|
107
|
-
//# sourceMappingURL=bnpl-shared-
|
|
107
|
+
//# sourceMappingURL=bnpl-shared-CL900HFN.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bnpl-shared-DGs1YzS9.mjs","names":["submitPayment: TInternalFuncs[\"submitPayment\"]","requestBody: BnplStartRequest","localStates: BnplStates"],"sources":["../src/payment-methods/bnpl-shared.ts"],"sourcesContent":["/**\n * Shared BNPL (Buy Now Pay Later) payment method factory.\n * Used by Klarna, Afterpay, and Affirm payment methods.\n */\n\nimport type { PaymentKitErrors, PaymentKitStates, TInternalFuncs } from \"../types\";\nimport { collectFraudMetadata, definePaymentMethod, getOrCreateCheckoutRequestId } from \"../utils\";\n\nexport type BnplCustomerInfo = {\n first_name: string;\n last_name: string;\n email?: string;\n};\n\nexport type BnplStartRequest = {\n processor_id: string;\n customer_info: BnplCustomerInfo;\n fraud_metadata: {\n ipAddress?: string;\n browserInfo?: { [key: string]: unknown };\n processorFraudInfo?: { [key: string]: unknown };\n };\n setup_future_usage?: boolean;\n};\n\nexport type BnplStartResponse = {\n approval_url: string;\n popup_token: string;\n checkout_attempt_id: string;\n};\n\nexport type BnplStatusResponse = {\n completed: boolean;\n status: \"success\" | \"failed\" | \"cancelled\";\n result?: unknown;\n error?: string;\n};\n\nexport type BnplCheckoutResponse = {\n id: string;\n checkoutAttemptId: string;\n checkoutSessionId: string;\n state: string;\n customerId?: string;\n paymentMethodId?: string;\n processorUsed?: string;\n subscriptionId?: string;\n invoiceId?: string;\n invoiceNumber?: number;\n};\n\nexport type BnplSubmitOptions = {\n processorId: string;\n customerInfo: BnplCustomerInfo;\n setupFutureUsage?: boolean;\n};\n\ntype BnplStates = PaymentKitStates & {\n popup?: Window | null;\n pollInterval?: ReturnType<typeof setInterval>;\n};\n\nexport type BnplProviderConfig = {\n name: string;\n endpointPath: string;\n supportsSetupFutureUsage?: boolean;\n};\n\nconst createSubmitPayment = (states: BnplStates, config: BnplProviderConfig) => {\n const { name, endpointPath, supportsSetupFutureUsage } = config;\n const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);\n\n const submitPayment: TInternalFuncs[\"submitPayment\"] = async (_fields, options) => {\n const { apiBaseUrl, secureToken, environment } = states;\n const bnplOptions = options as BnplSubmitOptions;\n\n if (!bnplOptions?.processorId) {\n return { errors: { processor_id: \"Processor ID is required\" } as PaymentKitErrors };\n }\n\n if (!bnplOptions?.customerInfo?.first_name || !bnplOptions?.customerInfo?.last_name) {\n return {\n errors: {\n customer_name: \"Customer first and last name are required\",\n } as PaymentKitErrors,\n };\n }\n\n try {\n const checkoutRequestId = getOrCreateCheckoutRequestId(environment);\n\n const requestBody: BnplStartRequest = {\n processor_id: bnplOptions.processorId,\n customer_info: bnplOptions.customerInfo,\n fraud_metadata: collectFraudMetadata(),\n };\n\n if (supportsSetupFutureUsage && bnplOptions.setupFutureUsage !== undefined) {\n requestBody.setup_future_usage = bnplOptions.setupFutureUsage;\n }\n\n const startResponse = await fetch(`${apiBaseUrl}/api/checkout/${secureToken}/stripe/${endpointPath}/start`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-request-id\": checkoutRequestId,\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!startResponse.ok) {\n let errorMessage = `Failed to start ${capitalizedName} checkout (${startResponse.status})`;\n try {\n const errorData = await startResponse.json();\n errorMessage = errorData.detail || errorMessage;\n } catch {\n errorMessage = startResponse.statusText || errorMessage;\n }\n return {\n errors: {\n [name]: errorMessage,\n } as PaymentKitErrors,\n };\n }\n\n const { approval_url, popup_token, checkout_attempt_id } = (await startResponse.json()) as BnplStartResponse;\n\n const popup = window.open(approval_url, capitalizedName, \"width=600,height=700\");\n\n if (!popup) {\n return {\n errors: {\n [name]: `Failed to open ${capitalizedName} popup. Please allow popups for this site.`,\n } as PaymentKitErrors,\n };\n }\n\n states.popup = popup;\n\n return new Promise((resolve) => {\n let popupClosedGracePolls = 0;\n const MAX_GRACE_POLLS = 5;\n\n const pollInterval = setInterval(async () => {\n try {\n const statusResponse = await fetch(\n `${apiBaseUrl}/api/checkout/${secureToken}/popup/status?popup_token=${popup_token}`,\n );\n\n if (!statusResponse.ok) {\n clearInterval(pollInterval);\n popup.close();\n resolve({\n errors: {\n [name]: `Failed to check ${capitalizedName} status`,\n } as PaymentKitErrors,\n });\n return;\n }\n\n const statusResult = (await statusResponse.json()) as BnplStatusResponse;\n\n if (statusResult.completed) {\n clearInterval(pollInterval);\n popup.close();\n\n if (statusResult.status === \"success\") {\n // Result is returned directly from popup status endpoint\n const result = statusResult.result || {\n id: checkout_attempt_id,\n checkoutAttemptId: checkout_attempt_id,\n checkoutSessionId: secureToken,\n state: \"checkout_succeeded\",\n };\n\n resolve({ data: result });\n } else {\n resolve({\n errors: {\n [name]: statusResult.error || `${capitalizedName} checkout ${statusResult.status}`,\n } as PaymentKitErrors,\n });\n }\n return;\n }\n\n if (popup.closed) {\n popupClosedGracePolls++;\n if (popupClosedGracePolls >= MAX_GRACE_POLLS) {\n clearInterval(pollInterval);\n resolve({\n errors: {\n [name]: `${capitalizedName} popup closed by user`,\n } as PaymentKitErrors,\n });\n }\n return;\n }\n } catch (error) {\n clearInterval(pollInterval);\n popup.close();\n resolve({\n errors: {\n [name]: `Polling error: ${error}`,\n } as PaymentKitErrors,\n });\n }\n }, 2000);\n\n states.pollInterval = pollInterval;\n });\n } catch (error) {\n return {\n errors: {\n [name]: `${capitalizedName} checkout error: ${error}`,\n } as PaymentKitErrors,\n };\n }\n };\n\n return submitPayment;\n};\n\nexport function createBnplPaymentMethod(config: BnplProviderConfig) {\n return definePaymentMethod((paymentKitStates) => {\n const localStates: BnplStates = { ...paymentKitStates };\n\n return {\n name: config.name,\n externalFuncs: {},\n internalFuncs: {\n submitPayment: createSubmitPayment(localStates, config),\n cleanup: () => {\n if (localStates.pollInterval) {\n clearInterval(localStates.pollInterval);\n }\n if (localStates.popup && !localStates.popup.closed) {\n localStates.popup.close();\n }\n },\n },\n };\n });\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"bnpl-shared-CL900HFN.mjs","names":["submitPayment: TInternalFuncs[\"submitPayment\"]","requestBody: BnplStartRequest","localStates: BnplStates"],"sources":["../src/payment-methods/bnpl-shared.ts"],"sourcesContent":["/**\n * Shared BNPL (Buy Now Pay Later) payment method factory.\n * Used by Klarna, Afterpay, and Affirm payment methods.\n */\n\nimport type { PaymentKitErrors, PaymentKitStates, TInternalFuncs } from \"../types\";\nimport { collectFraudMetadata, definePaymentMethod, getOrCreateCheckoutRequestId } from \"../utils\";\n\nexport type BnplCustomerInfo = {\n first_name: string;\n last_name: string;\n email?: string;\n};\n\nexport type BnplStartRequest = {\n processor_id: string;\n customer_info: BnplCustomerInfo;\n fraud_metadata: {\n ipAddress?: string;\n browserInfo?: { [key: string]: unknown };\n processorFraudInfo?: { [key: string]: unknown };\n };\n setup_future_usage?: boolean;\n};\n\nexport type BnplStartResponse = {\n approval_url: string;\n popup_token: string;\n checkout_attempt_id: string;\n};\n\nexport type BnplStatusResponse = {\n completed: boolean;\n status: \"success\" | \"failed\" | \"cancelled\";\n result?: unknown;\n error?: string;\n};\n\nexport type BnplCheckoutResponse = {\n id: string;\n checkoutAttemptId: string;\n checkoutSessionId: string;\n state: string;\n customerId?: string;\n paymentMethodId?: string;\n processorUsed?: string;\n subscriptionId?: string;\n invoiceId?: string;\n invoiceNumber?: number;\n};\n\nexport type BnplSubmitOptions = {\n processorId: string;\n customerInfo: BnplCustomerInfo;\n setupFutureUsage?: boolean;\n};\n\ntype BnplStates = PaymentKitStates & {\n popup?: Window | null;\n pollInterval?: ReturnType<typeof setInterval>;\n};\n\nexport type BnplProviderConfig = {\n name: string;\n endpointPath: string;\n supportsSetupFutureUsage?: boolean;\n};\n\nconst createSubmitPayment = (states: BnplStates, config: BnplProviderConfig) => {\n const { name, endpointPath, supportsSetupFutureUsage } = config;\n const capitalizedName = name.charAt(0).toUpperCase() + name.slice(1);\n\n const submitPayment: TInternalFuncs[\"submitPayment\"] = async (_fields, options) => {\n const { apiBaseUrl, secureToken, environment } = states;\n const bnplOptions = options as BnplSubmitOptions;\n\n if (!bnplOptions?.processorId) {\n return { errors: { processor_id: \"Processor ID is required\" } as PaymentKitErrors };\n }\n\n if (!bnplOptions?.customerInfo?.first_name || !bnplOptions?.customerInfo?.last_name) {\n return {\n errors: {\n customer_name: \"Customer first and last name are required\",\n } as PaymentKitErrors,\n };\n }\n\n try {\n const checkoutRequestId = getOrCreateCheckoutRequestId(environment);\n\n const requestBody: BnplStartRequest = {\n processor_id: bnplOptions.processorId,\n customer_info: bnplOptions.customerInfo,\n fraud_metadata: collectFraudMetadata(),\n };\n\n if (supportsSetupFutureUsage && bnplOptions.setupFutureUsage !== undefined) {\n requestBody.setup_future_usage = bnplOptions.setupFutureUsage;\n }\n\n const startResponse = await fetch(`${apiBaseUrl}/api/checkout/${secureToken}/stripe/${endpointPath}/start`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-request-id\": checkoutRequestId,\n },\n body: JSON.stringify(requestBody),\n });\n\n if (!startResponse.ok) {\n let errorMessage = `Failed to start ${capitalizedName} checkout (${startResponse.status})`;\n try {\n const errorData = await startResponse.json();\n errorMessage = errorData.detail || errorMessage;\n } catch {\n errorMessage = startResponse.statusText || errorMessage;\n }\n return {\n errors: {\n [name]: errorMessage,\n } as PaymentKitErrors,\n };\n }\n\n const { approval_url, popup_token, checkout_attempt_id } = (await startResponse.json()) as BnplStartResponse;\n\n const popup = window.open(approval_url, capitalizedName, \"width=600,height=700\");\n\n if (!popup) {\n return {\n errors: {\n [name]: `Failed to open ${capitalizedName} popup. Please allow popups for this site.`,\n } as PaymentKitErrors,\n };\n }\n\n states.popup = popup;\n\n return new Promise((resolve) => {\n let popupClosedGracePolls = 0;\n const MAX_GRACE_POLLS = 5;\n\n const pollInterval = setInterval(async () => {\n try {\n const statusResponse = await fetch(\n `${apiBaseUrl}/api/checkout/${secureToken}/popup/status?popup_token=${popup_token}`,\n );\n\n if (!statusResponse.ok) {\n clearInterval(pollInterval);\n popup.close();\n resolve({\n errors: {\n [name]: `Failed to check ${capitalizedName} status`,\n } as PaymentKitErrors,\n });\n return;\n }\n\n const statusResult = (await statusResponse.json()) as BnplStatusResponse;\n\n if (statusResult.completed) {\n clearInterval(pollInterval);\n popup.close();\n\n if (statusResult.status === \"success\") {\n // Result is returned directly from popup status endpoint\n const result = statusResult.result || {\n id: checkout_attempt_id,\n checkoutAttemptId: checkout_attempt_id,\n checkoutSessionId: secureToken,\n state: \"checkout_succeeded\",\n };\n\n resolve({ data: result });\n } else {\n resolve({\n errors: {\n [name]: statusResult.error || `${capitalizedName} checkout ${statusResult.status}`,\n } as PaymentKitErrors,\n });\n }\n return;\n }\n\n if (popup.closed) {\n popupClosedGracePolls++;\n if (popupClosedGracePolls >= MAX_GRACE_POLLS) {\n clearInterval(pollInterval);\n resolve({\n errors: {\n [name]: `${capitalizedName} popup closed by user`,\n } as PaymentKitErrors,\n });\n }\n return;\n }\n } catch (error) {\n clearInterval(pollInterval);\n popup.close();\n resolve({\n errors: {\n [name]: `Polling error: ${error}`,\n } as PaymentKitErrors,\n });\n }\n }, 2000);\n\n states.pollInterval = pollInterval;\n });\n } catch (error) {\n return {\n errors: {\n [name]: `${capitalizedName} checkout error: ${error}`,\n } as PaymentKitErrors,\n };\n }\n };\n\n return submitPayment;\n};\n\nexport function createBnplPaymentMethod(config: BnplProviderConfig) {\n return definePaymentMethod((paymentKitStates) => {\n const localStates: BnplStates = { ...paymentKitStates };\n\n return {\n name: config.name,\n externalFuncs: {},\n internalFuncs: {\n submitPayment: createSubmitPayment(localStates, config),\n cleanup: () => {\n if (localStates.pollInterval) {\n clearInterval(localStates.pollInterval);\n }\n if (localStates.popup && !localStates.popup.closed) {\n localStates.popup.close();\n }\n },\n },\n };\n });\n}\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as PaymentMethod } from "./types-Cjcc3xak.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/payment-methods/bnpl-shared.d.ts
|
|
4
4
|
|
|
@@ -61,4 +61,4 @@ type BnplProviderConfig = {
|
|
|
61
61
|
declare function createBnplPaymentMethod(config: BnplProviderConfig): PaymentMethod<{}, string>;
|
|
62
62
|
//#endregion
|
|
63
63
|
export { BnplStartResponse as a, createBnplPaymentMethod as c, BnplStartRequest as i, BnplCustomerInfo as n, BnplStatusResponse as o, BnplProviderConfig as r, BnplSubmitOptions as s, BnplCheckoutResponse as t };
|
|
64
|
-
//# sourceMappingURL=bnpl-shared-
|
|
64
|
+
//# sourceMappingURL=bnpl-shared-D-Kd58Qz.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bnpl-shared-
|
|
1
|
+
{"version":3,"file":"bnpl-shared-D-Kd58Qz.d.mts","names":[],"sources":["../src/payment-methods/bnpl-shared.ts"],"sourcesContent":[],"mappings":";;;;;;;AAQA;AAMY,KANA,gBAAA,GAMgB;EAWhB,UAAA,EAAA,MAAA;EAMA,SAAA,EAAA,MAAA;EAOA,KAAA,CAAA,EAAA,MAAA;AAaZ,CAAA;AAWY,KAhDA,gBAAA,GAgDkB;EAiKd,YAAA,EAAA,MAAA;iBA/MC;;;;;;;;;;;;KASL,iBAAA;;;;;KAMA,kBAAA;;;;;;KAOA,oBAAA;;;;;;;;;;;;KAaA,iBAAA;;gBAEI;;;KASJ,kBAAA;;;;;iBAiKI,uBAAA,SAAgC,qBAAkB"}
|
package/dist/cdn/paymentkit.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* PaymentKit.js v0.5.
|
|
2
|
+
* PaymentKit.js v0.5.19
|
|
3
3
|
* https://paymentkit.com
|
|
4
4
|
*
|
|
5
5
|
* @license MIT
|
|
@@ -42,7 +42,7 @@ var PaymentKit = (() => {
|
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
// package.json
|
|
45
|
-
var version = "0.5.
|
|
45
|
+
var version = "0.5.19";
|
|
46
46
|
|
|
47
47
|
// src/analytics/mock-adapter.ts
|
|
48
48
|
var MockAnalyticsAdapter = class {
|
|
@@ -6049,6 +6049,10 @@ var PaymentKit = (() => {
|
|
|
6049
6049
|
apiBaseUrl: "http://localhost:9000"
|
|
6050
6050
|
},
|
|
6051
6051
|
sandbox: {
|
|
6052
|
+
baseUrl: "https://app.paymentkit.com/customer",
|
|
6053
|
+
apiBaseUrl: "https://app.paymentkit.com"
|
|
6054
|
+
},
|
|
6055
|
+
staging: {
|
|
6052
6056
|
baseUrl: "https://staging.paymentkit.com/customer",
|
|
6053
6057
|
apiBaseUrl: "https://staging.paymentkit.com"
|
|
6054
6058
|
},
|
|
@@ -6082,10 +6086,10 @@ var PaymentKit = (() => {
|
|
|
6082
6086
|
if (environment === "tunnel") {
|
|
6083
6087
|
return getTunnelUrls();
|
|
6084
6088
|
}
|
|
6085
|
-
const
|
|
6086
|
-
const urls = STATIC_ENVIRONMENT_URLS[env];
|
|
6089
|
+
const urls = STATIC_ENVIRONMENT_URLS[environment];
|
|
6087
6090
|
if (!urls) {
|
|
6088
|
-
|
|
6091
|
+
console.warn(`[PaymentKit] Invalid environment "${environment}", falling back to local`);
|
|
6092
|
+
return STATIC_ENVIRONMENT_URLS.local;
|
|
6089
6093
|
}
|
|
6090
6094
|
return urls;
|
|
6091
6095
|
}
|
|
@@ -6107,22 +6111,22 @@ var PaymentKit = (() => {
|
|
|
6107
6111
|
var ENV_TO_SLUG = {
|
|
6108
6112
|
local: "dev",
|
|
6109
6113
|
tunnel: "dev",
|
|
6110
|
-
sandbox: "
|
|
6114
|
+
sandbox: "prod",
|
|
6115
|
+
staging: "stg",
|
|
6111
6116
|
production: "prod"
|
|
6112
6117
|
};
|
|
6113
|
-
var WINDOW_KEY = "__paymentKitRequestId__";
|
|
6114
6118
|
function generateCheckoutRequestId(environment) {
|
|
6115
|
-
const envSlug = ENV_TO_SLUG[environment]
|
|
6119
|
+
const envSlug = ENV_TO_SLUG[environment] ?? "dev";
|
|
6116
6120
|
const randomPart = nanoid(12);
|
|
6117
6121
|
return `pk_${envSlug}_${randomPart}`;
|
|
6118
6122
|
}
|
|
6119
6123
|
function getOrCreateCheckoutRequestId(environment) {
|
|
6120
|
-
if (typeof window !== "undefined" && window
|
|
6121
|
-
return window
|
|
6124
|
+
if (typeof window !== "undefined" && window.__paymentKitRequestId__) {
|
|
6125
|
+
return window.__paymentKitRequestId__;
|
|
6122
6126
|
}
|
|
6123
6127
|
const requestId = generateCheckoutRequestId(environment);
|
|
6124
6128
|
if (typeof window !== "undefined") {
|
|
6125
|
-
window
|
|
6129
|
+
window.__paymentKitRequestId__ = requestId;
|
|
6126
6130
|
}
|
|
6127
6131
|
return requestId;
|
|
6128
6132
|
}
|
|
@@ -6423,7 +6427,7 @@ var PaymentKit = (() => {
|
|
|
6423
6427
|
}, {});
|
|
6424
6428
|
return { isSuccess: false, errors };
|
|
6425
6429
|
}
|
|
6426
|
-
return { isSuccess: true };
|
|
6430
|
+
return { isSuccess: true, errors: {} };
|
|
6427
6431
|
};
|
|
6428
6432
|
|
|
6429
6433
|
// src/utils/index.ts
|
|
@@ -6460,6 +6464,18 @@ var PaymentKit = (() => {
|
|
|
6460
6464
|
}
|
|
6461
6465
|
|
|
6462
6466
|
// src/index.ts
|
|
6467
|
+
function appendScriptToDOM(script) {
|
|
6468
|
+
const target = document.body ?? document.head;
|
|
6469
|
+
target.appendChild(script);
|
|
6470
|
+
}
|
|
6471
|
+
function getFraudScriptId(url) {
|
|
6472
|
+
if (url.includes("airwallex.com")) {
|
|
6473
|
+
return "airwallex-fraud-api";
|
|
6474
|
+
}
|
|
6475
|
+
const urlObj = new URL(url);
|
|
6476
|
+
const hash = btoa(urlObj.origin + urlObj.pathname).replace(/[^a-zA-Z0-9]/g, "").slice(0, 12);
|
|
6477
|
+
return `pk-fraud-script-${hash}`;
|
|
6478
|
+
}
|
|
6463
6479
|
var createTunnelXConnection = (baseUrl, apiBaseUrl, token) => {
|
|
6464
6480
|
const iframe = createCheckoutIFrame("tunnel-x", baseUrl, {
|
|
6465
6481
|
checkout_token: token,
|
|
@@ -6468,14 +6484,17 @@ var PaymentKit = (() => {
|
|
|
6468
6484
|
Object.assign(iframe.style, { width: "0", height: "0", position: "absolute", visibility: "hidden" });
|
|
6469
6485
|
document.body.appendChild(iframe);
|
|
6470
6486
|
const connection = connectToTunnelXIframe(iframe, {});
|
|
6487
|
+
let destroyed = false;
|
|
6471
6488
|
const unmount = () => {
|
|
6489
|
+
if (destroyed) return;
|
|
6490
|
+
destroyed = true;
|
|
6472
6491
|
connection.destroy();
|
|
6473
|
-
|
|
6492
|
+
iframe.remove();
|
|
6474
6493
|
};
|
|
6475
6494
|
return { unmount, connection };
|
|
6476
6495
|
};
|
|
6477
6496
|
var PaymentKit = ({
|
|
6478
|
-
environment,
|
|
6497
|
+
environment = "production",
|
|
6479
6498
|
secureToken,
|
|
6480
6499
|
paymentMethods,
|
|
6481
6500
|
cardTokenizationMode,
|
|
@@ -6507,7 +6526,9 @@ var PaymentKit = (() => {
|
|
|
6507
6526
|
cardTokenizationMode,
|
|
6508
6527
|
vgsVaultId,
|
|
6509
6528
|
vgsEnvironment,
|
|
6510
|
-
_sessionConfigReady: void 0
|
|
6529
|
+
_sessionConfigReady: void 0,
|
|
6530
|
+
_fraudScriptIds: [],
|
|
6531
|
+
_fraudScriptsReady: void 0
|
|
6511
6532
|
};
|
|
6512
6533
|
if (cardTokenizationMode === void 0) {
|
|
6513
6534
|
const sessionConfigUrl = `${apiBaseUrl}/api/checkout-sessions/token/${secureToken}`;
|
|
@@ -6538,6 +6559,48 @@ var PaymentKit = (() => {
|
|
|
6538
6559
|
);
|
|
6539
6560
|
paymentKitStates.cardTokenizationMode = "direct";
|
|
6540
6561
|
}
|
|
6562
|
+
if (session?.fraud_script_urls?.length) {
|
|
6563
|
+
const loadPromises = [];
|
|
6564
|
+
session.fraud_script_urls.forEach((url) => {
|
|
6565
|
+
const scriptId = getFraudScriptId(url);
|
|
6566
|
+
if (document.getElementById(scriptId)) {
|
|
6567
|
+
console.log(`[PaymentKit] Fraud script already present: ${scriptId}`);
|
|
6568
|
+
loadPromises.push(Promise.resolve());
|
|
6569
|
+
return;
|
|
6570
|
+
}
|
|
6571
|
+
const script = document.createElement("script");
|
|
6572
|
+
script.type = "text/javascript";
|
|
6573
|
+
script.async = true;
|
|
6574
|
+
script.id = scriptId;
|
|
6575
|
+
script.src = url;
|
|
6576
|
+
script.dataset.orderSessionId = checkoutRequestId;
|
|
6577
|
+
const loadPromise2 = new Promise((resolve) => {
|
|
6578
|
+
script.onload = () => {
|
|
6579
|
+
console.log(`[PaymentKit] Fraud script loaded: ${scriptId}`);
|
|
6580
|
+
resolve();
|
|
6581
|
+
};
|
|
6582
|
+
script.onerror = () => {
|
|
6583
|
+
console.error(
|
|
6584
|
+
`[PaymentKit] Failed to load fraud prevention script. If using Content-Security-Policy, add to script-src: ${new URL(url).origin}`
|
|
6585
|
+
);
|
|
6586
|
+
resolve();
|
|
6587
|
+
};
|
|
6588
|
+
});
|
|
6589
|
+
loadPromises.push(loadPromise2);
|
|
6590
|
+
paymentKitStates._fraudScriptIds.push(scriptId);
|
|
6591
|
+
appendScriptToDOM(script);
|
|
6592
|
+
});
|
|
6593
|
+
paymentKitStates._fraudScriptsReady = Promise.all(loadPromises).then(() => {
|
|
6594
|
+
console.log(`[PaymentKit] All ${loadPromises.length} fraud fingerprinting script(s) ready`);
|
|
6595
|
+
});
|
|
6596
|
+
session.fraud_script_urls.forEach((url) => {
|
|
6597
|
+
const scriptId = getFraudScriptId(url);
|
|
6598
|
+
console.log(
|
|
6599
|
+
`[PaymentKit] Fraud script injected: id=${scriptId}, data-order-session-id=${checkoutRequestId}, src=${url}`
|
|
6600
|
+
);
|
|
6601
|
+
});
|
|
6602
|
+
console.log(`[PaymentKit] Injected ${session.fraud_script_urls.length} fraud fingerprinting script(s)`);
|
|
6603
|
+
}
|
|
6541
6604
|
} else {
|
|
6542
6605
|
console.log("[PaymentKit] Session response missing card_tokenization_mode \u2014 defaulting to direct mode");
|
|
6543
6606
|
paymentKitStates.cardTokenizationMode = "direct";
|
|
@@ -6583,6 +6646,13 @@ var PaymentKit = (() => {
|
|
|
6583
6646
|
});
|
|
6584
6647
|
};
|
|
6585
6648
|
const cleanup = () => {
|
|
6649
|
+
for (const scriptId of paymentKitStates._fraudScriptIds) {
|
|
6650
|
+
const script = document.getElementById(scriptId);
|
|
6651
|
+
if (script) {
|
|
6652
|
+
script.remove();
|
|
6653
|
+
}
|
|
6654
|
+
}
|
|
6655
|
+
paymentKitStates._fraudScriptIds = [];
|
|
6586
6656
|
for (const pm of pmInstances) {
|
|
6587
6657
|
if (pm.internalFuncs.cleanup) {
|
|
6588
6658
|
pm.internalFuncs.cleanup();
|
|
@@ -7023,21 +7093,21 @@ var PaymentKit = (() => {
|
|
|
7023
7093
|
closeButton.setAttribute("aria-label", "Cancel verification");
|
|
7024
7094
|
closeButton.setAttribute("type", "button");
|
|
7025
7095
|
closeButton.style.cssText = `
|
|
7026
|
-
position: absolute;
|
|
7027
|
-
top:
|
|
7028
|
-
right:
|
|
7029
|
-
width: 32px;
|
|
7030
|
-
height: 32px;
|
|
7031
|
-
border: none;
|
|
7032
|
-
background: white;
|
|
7033
|
-
border-radius: 8px;
|
|
7034
|
-
cursor: pointer;
|
|
7035
|
-
display: flex;
|
|
7036
|
-
align-items: center;
|
|
7037
|
-
justify-content: center;
|
|
7038
|
-
z-index: 10;
|
|
7039
|
-
transition: background 0.15s ease;
|
|
7040
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
7096
|
+
position: absolute !important;
|
|
7097
|
+
top: 8px !important;
|
|
7098
|
+
right: 8px !important;
|
|
7099
|
+
width: 32px !important;
|
|
7100
|
+
height: 32px !important;
|
|
7101
|
+
border: none !important;
|
|
7102
|
+
background: white !important;
|
|
7103
|
+
border-radius: 8px !important;
|
|
7104
|
+
cursor: pointer !important;
|
|
7105
|
+
display: flex !important;
|
|
7106
|
+
align-items: center !important;
|
|
7107
|
+
justify-content: center !important;
|
|
7108
|
+
z-index: 10 !important;
|
|
7109
|
+
transition: background 0.15s ease !important;
|
|
7110
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15) !important;
|
|
7041
7111
|
`;
|
|
7042
7112
|
closeButton.innerHTML = `
|
|
7043
7113
|
<svg width="12" height="12" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
@@ -7045,10 +7115,10 @@ var PaymentKit = (() => {
|
|
|
7045
7115
|
</svg>
|
|
7046
7116
|
`;
|
|
7047
7117
|
closeButton.onmouseenter = () => {
|
|
7048
|
-
closeButton.style.background
|
|
7118
|
+
closeButton.style.setProperty("background", "#f5f5f5", "important");
|
|
7049
7119
|
};
|
|
7050
7120
|
closeButton.onmouseleave = () => {
|
|
7051
|
-
closeButton.style.background
|
|
7121
|
+
closeButton.style.setProperty("background", "white", "important");
|
|
7052
7122
|
};
|
|
7053
7123
|
const iframe = document.createElement("iframe");
|
|
7054
7124
|
iframe.src = url;
|
|
@@ -7093,9 +7163,7 @@ var PaymentKit = (() => {
|
|
|
7093
7163
|
container.style.opacity = "0";
|
|
7094
7164
|
container.style.transform = "scale(0.95) translateY(10px)";
|
|
7095
7165
|
setTimeout(() => {
|
|
7096
|
-
|
|
7097
|
-
overlay.parentNode.removeChild(overlay);
|
|
7098
|
-
}
|
|
7166
|
+
overlay.remove();
|
|
7099
7167
|
}, 250);
|
|
7100
7168
|
});
|
|
7101
7169
|
};
|
|
@@ -7643,12 +7711,7 @@ var PaymentKit = (() => {
|
|
|
7643
7711
|
console.log("[ApplePay] Airwallex prepared state:", preparedAirwallexState);
|
|
7644
7712
|
return { success: true, applePay: true };
|
|
7645
7713
|
}
|
|
7646
|
-
const startResult = await callStripeStartEndpoint(
|
|
7647
|
-
apiBaseUrl,
|
|
7648
|
-
secureToken,
|
|
7649
|
-
options,
|
|
7650
|
-
checkoutRequestId
|
|
7651
|
-
);
|
|
7714
|
+
const startResult = await callStripeStartEndpoint(apiBaseUrl, secureToken, options, checkoutRequestId);
|
|
7652
7715
|
if (startResult.error || !startResult.data) {
|
|
7653
7716
|
return { success: false, error: startResult.error || "Failed to start Apple Pay" };
|
|
7654
7717
|
}
|
|
@@ -7981,12 +8044,7 @@ var PaymentKit = (() => {
|
|
|
7981
8044
|
preparedAirwallexState = null;
|
|
7982
8045
|
}
|
|
7983
8046
|
}
|
|
7984
|
-
const startResult = await callStripeStartEndpoint(
|
|
7985
|
-
apiBaseUrl,
|
|
7986
|
-
secureToken,
|
|
7987
|
-
applePayOptions,
|
|
7988
|
-
checkoutRequestId
|
|
7989
|
-
);
|
|
8047
|
+
const startResult = await callStripeStartEndpoint(apiBaseUrl, secureToken, applePayOptions, checkoutRequestId);
|
|
7990
8048
|
if (startResult.error || !startResult.data) {
|
|
7991
8049
|
return { errors: { apple_pay: startResult.error || "Failed to start Apple Pay" } };
|
|
7992
8050
|
}
|
|
@@ -8485,10 +8543,7 @@ var PaymentKit = (() => {
|
|
|
8485
8543
|
cleanupDirect = () => {
|
|
8486
8544
|
const connection = cardInputConnections[type];
|
|
8487
8545
|
connection?.destroy();
|
|
8488
|
-
|
|
8489
|
-
parent.removeChild(iframe);
|
|
8490
|
-
} catch {
|
|
8491
|
-
}
|
|
8546
|
+
iframe.remove();
|
|
8492
8547
|
states.cardInputConnections[type] = void 0;
|
|
8493
8548
|
};
|
|
8494
8549
|
parent.appendChild(iframe);
|
|
@@ -8530,7 +8585,7 @@ var PaymentKit = (() => {
|
|
|
8530
8585
|
const requestOptions = withRequestId(checkoutRequestId);
|
|
8531
8586
|
const tunnelX = await TunnelXManager.createFromPenpalConnection(states.tunnelXConnection);
|
|
8532
8587
|
const skipCustomerValidation = options?.skipCustomerValidation === true;
|
|
8533
|
-
const validateFormResult = skipCustomerValidation ? { isSuccess: true } : await validateFormFields(fields);
|
|
8588
|
+
const validateFormResult = skipCustomerValidation ? { isSuccess: true, errors: {} } : await validateFormFields(fields);
|
|
8534
8589
|
if (!isVgsMode) {
|
|
8535
8590
|
const validateCardResult = await validateCardFields(states);
|
|
8536
8591
|
if (!(validateCardResult.isSuccess && validateFormResult.isSuccess)) {
|
|
@@ -8576,13 +8631,19 @@ var PaymentKit = (() => {
|
|
|
8576
8631
|
}
|
|
8577
8632
|
console.log("Card setup intent is set \u2705", cardSetupIntent);
|
|
8578
8633
|
console.log("Fields", fields);
|
|
8634
|
+
const fraudMetadata = {
|
|
8635
|
+
...collectFraudMetadata(),
|
|
8636
|
+
processorFraudInfo: {
|
|
8637
|
+
airwallexDeviceId: states.checkoutRequestId
|
|
8638
|
+
}
|
|
8639
|
+
};
|
|
8579
8640
|
let currentResult = await tunnelX.publicEndpoints.cardCheckout(
|
|
8580
8641
|
{
|
|
8581
8642
|
checkoutToken: states.secureToken,
|
|
8582
8643
|
publicCardCheckoutRequest: {
|
|
8583
8644
|
cardSetupIntentId: states.cardSetupIntentId,
|
|
8584
8645
|
customerInfo: mapFieldsToCustomerInfo(fields),
|
|
8585
|
-
fraudMetadata
|
|
8646
|
+
fraudMetadata
|
|
8586
8647
|
}
|
|
8587
8648
|
},
|
|
8588
8649
|
requestOptions
|
|
@@ -8805,6 +8866,12 @@ var PaymentKit = (() => {
|
|
|
8805
8866
|
return { errors, isSuccess: false };
|
|
8806
8867
|
}
|
|
8807
8868
|
const { pan_alias, cvc_alias, exp_month, exp_year } = cardResult.data.attributes;
|
|
8869
|
+
if (!cvc_alias) {
|
|
8870
|
+
console.warn(
|
|
8871
|
+
`${logPrefix} VGS createCard response missing cvc_alias (303 dedup):`,
|
|
8872
|
+
JSON.stringify(cardResult.data.attributes)
|
|
8873
|
+
);
|
|
8874
|
+
}
|
|
8808
8875
|
const fullYear = exp_year < 100 ? 2e3 + exp_year : exp_year;
|
|
8809
8876
|
const formattedExp = `${String(exp_month).padStart(2, "0")}/${fullYear}`;
|
|
8810
8877
|
const cmpCardId = cardResult.data.id;
|
|
@@ -8815,7 +8882,7 @@ var PaymentKit = (() => {
|
|
|
8815
8882
|
updateCardSetupIntentReq: {
|
|
8816
8883
|
cardPan: pan_alias,
|
|
8817
8884
|
cardExp: formattedExp,
|
|
8818
|
-
cardCvc: cvc_alias,
|
|
8885
|
+
...cvc_alias ? { cardCvc: cvc_alias } : {},
|
|
8819
8886
|
cmpCardId,
|
|
8820
8887
|
fraudMetadata: collectFraudMetadata()
|
|
8821
8888
|
}
|
|
@@ -9217,12 +9284,41 @@ var PaymentKit = (() => {
|
|
|
9217
9284
|
}
|
|
9218
9285
|
return { data: await response.json() };
|
|
9219
9286
|
}
|
|
9220
|
-
function validateOptions2(options) {
|
|
9221
|
-
if (!options?.processorId) {
|
|
9287
|
+
function validateOptions2(options, autoPrepareConfig) {
|
|
9288
|
+
if (!options?.processorId && !autoPrepareConfig?.processorId) {
|
|
9222
9289
|
return { processor_id: "Processor ID is required" };
|
|
9223
9290
|
}
|
|
9224
9291
|
return null;
|
|
9225
9292
|
}
|
|
9293
|
+
async function checkGooglePayAvailability() {
|
|
9294
|
+
if (!window.google?.payments?.api?.PaymentsClient) {
|
|
9295
|
+
console.log("[GooglePay] Google Pay API not loaded");
|
|
9296
|
+
return false;
|
|
9297
|
+
}
|
|
9298
|
+
try {
|
|
9299
|
+
const client = new window.google.payments.api.PaymentsClient({
|
|
9300
|
+
environment: "TEST"
|
|
9301
|
+
});
|
|
9302
|
+
const request = {
|
|
9303
|
+
apiVersion: 2,
|
|
9304
|
+
apiVersionMinor: 0,
|
|
9305
|
+
allowedPaymentMethods: [
|
|
9306
|
+
{
|
|
9307
|
+
type: "CARD",
|
|
9308
|
+
parameters: {
|
|
9309
|
+
allowedAuthMethods: ["PAN_ONLY", "CRYPTOGRAM_3DS"],
|
|
9310
|
+
allowedCardNetworks: ["VISA", "MASTERCARD", "AMEX", "DISCOVER", "JCB"]
|
|
9311
|
+
}
|
|
9312
|
+
}
|
|
9313
|
+
]
|
|
9314
|
+
};
|
|
9315
|
+
const response = await client.isReadyToPay(request);
|
|
9316
|
+
return response.result;
|
|
9317
|
+
} catch (error) {
|
|
9318
|
+
console.error("[GooglePay] availability check error:", error);
|
|
9319
|
+
return false;
|
|
9320
|
+
}
|
|
9321
|
+
}
|
|
9226
9322
|
function getMockScenarioStr2(mockScenario) {
|
|
9227
9323
|
return mockScenario && mockScenario !== "none" /* None */ ? mockScenario : void 0;
|
|
9228
9324
|
}
|
|
@@ -9456,14 +9552,19 @@ var PaymentKit = (() => {
|
|
|
9456
9552
|
}
|
|
9457
9553
|
return toGooglePayResult(response, secureToken);
|
|
9458
9554
|
}
|
|
9459
|
-
var defSubmitPayment3 = (states) => {
|
|
9555
|
+
var defSubmitPayment3 = (states, getAutoPrepareConfig) => {
|
|
9460
9556
|
const submitPayment = async (_fields, options) => {
|
|
9461
9557
|
const { apiBaseUrl, secureToken, environment } = states;
|
|
9462
9558
|
const gpayOptions = options;
|
|
9463
|
-
const
|
|
9559
|
+
const autoPrepareConfig = getAutoPrepareConfig();
|
|
9560
|
+
const validationError = validateOptions2(gpayOptions, autoPrepareConfig);
|
|
9464
9561
|
if (validationError) {
|
|
9465
9562
|
return { errors: validationError };
|
|
9466
9563
|
}
|
|
9564
|
+
const effectiveOptions = {
|
|
9565
|
+
...gpayOptions,
|
|
9566
|
+
processorId: gpayOptions.processorId || autoPrepareConfig?.processorId || ""
|
|
9567
|
+
};
|
|
9467
9568
|
try {
|
|
9468
9569
|
const mockScenarioStr = getMockScenarioStr2(gpayOptions.mockScenario);
|
|
9469
9570
|
const checkoutRequestId = getOrCreateCheckoutRequestId(environment);
|
|
@@ -9471,7 +9572,7 @@ var PaymentKit = (() => {
|
|
|
9471
9572
|
const startResult = await callStartEndpoint(
|
|
9472
9573
|
apiBaseUrl,
|
|
9473
9574
|
secureToken,
|
|
9474
|
-
|
|
9575
|
+
effectiveOptions,
|
|
9475
9576
|
mockScenarioStr,
|
|
9476
9577
|
checkoutRequestId
|
|
9477
9578
|
);
|
|
@@ -9517,12 +9618,113 @@ var PaymentKit = (() => {
|
|
|
9517
9618
|
return submitPayment;
|
|
9518
9619
|
};
|
|
9519
9620
|
var GooglePayPaymentMethod = definePaymentMethod((paymentKitStates) => {
|
|
9621
|
+
const { apiBaseUrl, secureToken, environment } = paymentKitStates;
|
|
9622
|
+
let autoPrepareConfig = null;
|
|
9623
|
+
let onGooglePayReadyCallbacks = [];
|
|
9624
|
+
let isGooglePayReadyState = false;
|
|
9625
|
+
let autoPrepareInProgress = false;
|
|
9626
|
+
let cleanupGeneration = 0;
|
|
9627
|
+
let pendingAutoPrepareArgs = null;
|
|
9628
|
+
let pendingPrepareResolvers = [];
|
|
9629
|
+
function instanceSetGooglePayReady(ready) {
|
|
9630
|
+
isGooglePayReadyState = ready;
|
|
9631
|
+
for (const cb of onGooglePayReadyCallbacks) cb(ready);
|
|
9632
|
+
}
|
|
9633
|
+
function instanceClearPreparedGooglePay() {
|
|
9634
|
+
instanceSetGooglePayReady(false);
|
|
9635
|
+
}
|
|
9636
|
+
async function instanceAutoPrepare(apBase, sToken, env) {
|
|
9637
|
+
if (autoPrepareInProgress) {
|
|
9638
|
+
pendingAutoPrepareArgs = { apiBaseUrl: apBase, secureToken: sToken, environment: env };
|
|
9639
|
+
return new Promise((resolve) => pendingPrepareResolvers.push(resolve));
|
|
9640
|
+
}
|
|
9641
|
+
autoPrepareInProgress = true;
|
|
9642
|
+
const capturedGeneration = cleanupGeneration;
|
|
9643
|
+
instanceSetGooglePayReady(false);
|
|
9644
|
+
try {
|
|
9645
|
+
const result = await apiCall2(`${apBase}/api/checkout-sessions/token/${sToken}`, {
|
|
9646
|
+
method: "GET"
|
|
9647
|
+
});
|
|
9648
|
+
if (cleanupGeneration !== capturedGeneration) return;
|
|
9649
|
+
if (result.error || !result.data) {
|
|
9650
|
+
console.warn("[GooglePay] Auto-prepare: failed to fetch session config:", result.error);
|
|
9651
|
+
return;
|
|
9652
|
+
}
|
|
9653
|
+
const processorId = result.data.express_checkout_processor_id;
|
|
9654
|
+
if (!processorId) {
|
|
9655
|
+
console.log("[GooglePay] Auto-prepare: no express checkout processor configured");
|
|
9656
|
+
return;
|
|
9657
|
+
}
|
|
9658
|
+
const processorTypeRaw = result.data.express_checkout_processor_type;
|
|
9659
|
+
const processorType = processorTypeRaw === "airwallex" || processorTypeRaw === "stripe" ? processorTypeRaw : void 0;
|
|
9660
|
+
autoPrepareConfig = { processorId, processorType };
|
|
9661
|
+
const isAvailable = await checkGooglePayAvailability();
|
|
9662
|
+
if (cleanupGeneration !== capturedGeneration) return;
|
|
9663
|
+
instanceSetGooglePayReady(isAvailable);
|
|
9664
|
+
} catch (err) {
|
|
9665
|
+
if (cleanupGeneration === capturedGeneration) {
|
|
9666
|
+
console.error("[GooglePay] Auto-prepare failed:", err);
|
|
9667
|
+
}
|
|
9668
|
+
} finally {
|
|
9669
|
+
autoPrepareInProgress = false;
|
|
9670
|
+
const stale = cleanupGeneration !== capturedGeneration;
|
|
9671
|
+
const pending = pendingAutoPrepareArgs;
|
|
9672
|
+
const resolvers = pendingPrepareResolvers.splice(0);
|
|
9673
|
+
if (!stale && pending) {
|
|
9674
|
+
pendingAutoPrepareArgs = null;
|
|
9675
|
+
instanceAutoPrepare(pending.apiBaseUrl, pending.secureToken, pending.environment).then(() => {
|
|
9676
|
+
for (const r2 of resolvers) r2();
|
|
9677
|
+
});
|
|
9678
|
+
} else {
|
|
9679
|
+
pendingAutoPrepareArgs = null;
|
|
9680
|
+
for (const r2 of resolvers) r2();
|
|
9681
|
+
}
|
|
9682
|
+
}
|
|
9683
|
+
}
|
|
9684
|
+
instanceAutoPrepare(apiBaseUrl, secureToken, environment).catch(
|
|
9685
|
+
(err) => console.error("[GooglePay] Unhandled init error:", err)
|
|
9686
|
+
);
|
|
9520
9687
|
return {
|
|
9521
9688
|
name: "google_pay",
|
|
9522
|
-
externalFuncs: {
|
|
9689
|
+
externalFuncs: {
|
|
9690
|
+
/**
|
|
9691
|
+
* Register a callback to be notified when Google Pay becomes ready (or stops being ready).
|
|
9692
|
+
* Fires immediately with the current state, then on every state change.
|
|
9693
|
+
* Multiple registrations are all notified — none are silently overwritten.
|
|
9694
|
+
*
|
|
9695
|
+
* @example
|
|
9696
|
+
* paymentKit.google_pay.onGooglePayReady((isReady) => {
|
|
9697
|
+
* googlePayButton.disabled = !isReady;
|
|
9698
|
+
* });
|
|
9699
|
+
*/
|
|
9700
|
+
onGooglePayReady: (callback) => {
|
|
9701
|
+
onGooglePayReadyCallbacks.push(callback);
|
|
9702
|
+
callback(isGooglePayReadyState);
|
|
9703
|
+
},
|
|
9704
|
+
/**
|
|
9705
|
+
* Notify the SDK that the payment amount has changed (e.g. coupon applied).
|
|
9706
|
+
* The SDK will disable Google Pay, re-prepare with the new amount, then re-enable.
|
|
9707
|
+
* The returned promise resolves when re-prepare is fully complete.
|
|
9708
|
+
*
|
|
9709
|
+
* @example
|
|
9710
|
+
* await paymentKit.google_pay.notifyAmountChanged();
|
|
9711
|
+
*/
|
|
9712
|
+
notifyAmountChanged: () => {
|
|
9713
|
+
instanceClearPreparedGooglePay();
|
|
9714
|
+
autoPrepareConfig = null;
|
|
9715
|
+
return instanceAutoPrepare(apiBaseUrl, secureToken, environment);
|
|
9716
|
+
}
|
|
9717
|
+
},
|
|
9523
9718
|
internalFuncs: {
|
|
9524
|
-
submitPayment: defSubmitPayment3(paymentKitStates),
|
|
9719
|
+
submitPayment: defSubmitPayment3(paymentKitStates, () => autoPrepareConfig),
|
|
9525
9720
|
cleanup: () => {
|
|
9721
|
+
cleanupGeneration++;
|
|
9722
|
+
onGooglePayReadyCallbacks = [];
|
|
9723
|
+
isGooglePayReadyState = false;
|
|
9724
|
+
autoPrepareConfig = null;
|
|
9725
|
+
pendingAutoPrepareArgs = null;
|
|
9726
|
+
pendingPrepareResolvers = [];
|
|
9727
|
+
autoPrepareInProgress = false;
|
|
9526
9728
|
}
|
|
9527
9729
|
}
|
|
9528
9730
|
};
|