diff --git a/examples/dynamic-checkout-init/index.html b/examples/dynamic-checkout-init/index.html
new file mode 100644
index 0000000..a94eb9f
--- /dev/null
+++ b/examples/dynamic-checkout-init/index.html
@@ -0,0 +1,405 @@
+
+
+
+ ProcessOut.js Dynamic Checkout (initDynamicCheckout)
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/dynamic-checkout/index.html b/examples/dynamic-checkout/index.html
index 7424644..f2728fb 100644
--- a/examples/dynamic-checkout/index.html
+++ b/examples/dynamic-checkout/index.html
@@ -134,6 +134,11 @@
+
+
Dispatched Events
@@ -190,6 +195,7 @@ Dispatched Events
try {
const client = new ProcessOut.ProcessOut(formValues.projectId)
+
const dynamicCheckout = client.setupDynamicCheckout(
{
invoiceId: formValues.invoiceId,
@@ -201,9 +207,9 @@ Dispatched Events
hideSavedPaymentMethods: formValues.hideSavedPaymentMethods,
showStatusMessage: formValues.showStatusMessage,
payButtonText: formValues.payButtonText,
- additionalData: formValues.additionalData.value,
cvcLabel: formValues.cvcLabel,
cvcPlaceholder: formValues.cvcPlaceholder,
+ additionalData: formValues.additionalData.value,
},
{
payButtonColor: formValues.payButtonColor,
@@ -212,12 +218,46 @@ Dispatched Events
)
dynamicCheckout.mount("#dynamic-cko-container")
+
+ updateCodePreview(formValues)
} catch (error) {
showFormError(error && error.message ? error.message : String(error))
- dynamicCheckoutContainer.innerHTML = ""
+ dynamicCheckoutContainer.textContent = ""
}
}
+ function updateCodePreview(formValues) {
+ const config = {
+ invoiceId: formValues.invoiceId,
+ clientSecret: formValues.clientSecret,
+ locale: formValues.locale,
+ capturePayments: formValues.capturePayments,
+ allowFallbackToSale: formValues.allowFallbackToSale,
+ enforceSavePaymentMethod: formValues.enforceSavePaymentMethod,
+ hideSavedPaymentMethods: formValues.hideSavedPaymentMethods,
+ showStatusMessage: formValues.showStatusMessage,
+ payButtonText: formValues.payButtonText,
+ cvcLabel: formValues.cvcLabel,
+ cvcPlaceholder: formValues.cvcPlaceholder,
+ additionalData: formValues.additionalData.value,
+ }
+
+ const theme = {
+ payButtonColor: formValues.payButtonColor,
+ payButtonTextColor: formValues.payButtonTextColor,
+ }
+
+ const code =
+ 'const client = new ProcessOut.ProcessOut("' + formValues.projectId + '")\n\n' +
+ "const checkout = client.setupDynamicCheckout(\n" +
+ " " + JSON.stringify(config, null, 2).replace(/\n/g, "\n ") + ",\n" +
+ " " + JSON.stringify(theme, null, 2).replace(/\n/g, "\n ") + ",\n" +
+ ")\n\n" +
+ 'checkout.mount("#dynamic-cko-container")'
+
+ document.getElementById("code-preview").textContent = code
+ }
+
function getFormValues() {
const projectId = document.getElementById("project-id").value.trim()
const invoiceId = document.getElementById("invoice-id").value.trim()
diff --git a/examples/dynamic-checkout/styles.css b/examples/dynamic-checkout/styles.css
index c4baf06..cd23583 100644
--- a/examples/dynamic-checkout/styles.css
+++ b/examples/dynamic-checkout/styles.css
@@ -153,6 +153,21 @@ pre {
padding: 10px;
}
+.code-preview {
+ background: #1e293b;
+ color: #e2e8f0;
+ border-radius: 12px;
+ padding: 16px;
+ margin: 0;
+ overflow-x: auto;
+ white-space: pre;
+ font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
+ font-size: 12px;
+ line-height: 1.6;
+ max-height: 480px;
+ overflow-y: auto;
+}
+
#dynamic-cko-container {
width: 100%;
max-width: 420px;
diff --git a/index.html b/index.html
index 58e6e68..ccd81cf 100644
--- a/index.html
+++ b/index.html
@@ -54,6 +54,9 @@ ProcessOut.js Development Environment
Dynamic Checkout
+
+ Dynamic Checkout (initDynamicCheckout)
+
Native APM
diff --git a/package.json b/package.json
index 266adb3..8ea841f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "processout.js",
- "version": "1.8.5",
+ "version": "1.8.6",
"description": "ProcessOut.js is a JavaScript library for ProcessOut's payment processing API.",
"scripts": {
"build:processout": "tsc -p src/processout && uglifyjs --compress --keep-fnames --ie8 dist/processout.js -o dist/processout.js",
diff --git a/src/dynamic-checkout/clients/apple-pay.ts b/src/dynamic-checkout/clients/apple-pay.ts
index e732a72..24be88d 100644
--- a/src/dynamic-checkout/clients/apple-pay.ts
+++ b/src/dynamic-checkout/clients/apple-pay.ts
@@ -2,6 +2,8 @@
module ProcessOut {
export class ApplePayClient {
+ private static readonly METHOD_KEY = "applepay"
+
processOutInstance: ProcessOut
paymentConfig: DynamicCheckoutPaymentConfig
@@ -16,6 +18,7 @@ module ProcessOut {
getViewContainer: () => HTMLElement,
) {
const applePayScript = document.createElement("script")
+
applePayScript.src = applePaySdkUrl
applePayScript.onload = () => {
buttonContainer.innerHTML = ``
@@ -139,21 +142,23 @@ module ProcessOut {
invoiceData: Invoice,
getViewContainer: () => HTMLElement,
) {
+ const methodOptions = this.paymentConfig.getOptionsForMethod(ApplePayClient.METHOD_KEY)
+
this.processOutInstance.makeCardPayment(
invoiceData.id,
cardToken,
{
- authorize_only: !this.paymentConfig.capturePayments,
- allow_fallback_to_sale: this.paymentConfig.allowFallbackToSale,
+ authorize_only: !methodOptions.capturePayments,
+ allow_fallback_to_sale: !!methodOptions.allowFallbackToSale,
},
invoiceId => {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
getViewContainer().appendChild(
new DynamicCheckoutPaymentSuccessView(this.processOutInstance, this.paymentConfig)
.element,
)
} else if (
- !this.paymentConfig.showStatusMessage &&
+ !methodOptions.showStatusMessage &&
!this.paymentConfig.invoiceDetails.return_url
) {
getViewContainer().appendChild(
@@ -169,13 +174,13 @@ module ProcessOut {
})
},
error => {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
getViewContainer().appendChild(
new DynamicCheckoutPaymentErrorView(this.processOutInstance, this.paymentConfig)
.element,
)
} else if (
- !this.paymentConfig.showStatusMessage &&
+ !methodOptions.showStatusMessage &&
!this.paymentConfig.invoiceDetails.return_url
) {
getViewContainer().appendChild(
@@ -194,7 +199,7 @@ module ProcessOut {
},
undefined,
invoiceId => {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
getViewContainer().appendChild(
new DynamicCheckoutPaymentPendingView(this.processOutInstance, this.paymentConfig)
.element,
diff --git a/src/dynamic-checkout/clients/google-pay.ts b/src/dynamic-checkout/clients/google-pay.ts
index 32eb8c3..5569fc0 100644
--- a/src/dynamic-checkout/clients/google-pay.ts
+++ b/src/dynamic-checkout/clients/google-pay.ts
@@ -48,6 +48,8 @@ module ProcessOut {
}
}
export class GooglePayClient {
+ private static readonly METHOD_KEY = "googlepay"
+
googleClient: any
processOutInstance: ProcessOut
paymentConfig: DynamicCheckoutPaymentConfig
@@ -120,6 +122,8 @@ module ProcessOut {
}
private makePayment(invoiceData: Invoice, getViewContainer: () => HTMLElement) {
+ const methodOptions = this.paymentConfig.getOptionsForMethod(GooglePayClient.METHOD_KEY)
+
this.googleClient
.loadPaymentData(this.paymentRequest)
.then(paymentData => {
@@ -136,21 +140,18 @@ module ProcessOut {
invoiceData.id,
token,
{
- authorize_only: !this.paymentConfig.capturePayments,
- allow_fallback_to_sale: this.paymentConfig.allowFallbackToSale,
+ authorize_only: !methodOptions.capturePayments,
+ allow_fallback_to_sale: !!methodOptions.allowFallbackToSale,
},
invoiceId => {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
getViewContainer().appendChild(
new DynamicCheckoutPaymentSuccessView(
this.processOutInstance,
this.paymentConfig,
).element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
getViewContainer().appendChild(
new DynamicCheckoutPaymentInfoView(
this.processOutInstance,
@@ -166,17 +167,14 @@ module ProcessOut {
})
},
error => {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
getViewContainer().appendChild(
new DynamicCheckoutPaymentErrorView(
this.processOutInstance,
this.paymentConfig,
).element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
getViewContainer().appendChild(
new DynamicCheckoutPaymentInfoView(
this.processOutInstance,
@@ -195,7 +193,7 @@ module ProcessOut {
},
undefined,
invoiceId => {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
getViewContainer().appendChild(
new DynamicCheckoutPaymentPendingView(this.processOutInstance, this.paymentConfig).element,
)
diff --git a/src/dynamic-checkout/config/payment-config.ts b/src/dynamic-checkout/config/payment-config.ts
index fa93987..9bb6eda 100644
--- a/src/dynamic-checkout/config/payment-config.ts
+++ b/src/dynamic-checkout/config/payment-config.ts
@@ -1,13 +1,103 @@
///
module ProcessOut {
- interface DynamicCheckoutAdditionalDataByGateway {
- [gatewayName: string]: Record
+ // ---------------------------------------------------------------------------
+ // Internal helpers
+ // ---------------------------------------------------------------------------
+
+ type DynamicCheckoutMethodKey = string
+
+ interface DynamicCheckoutMethodScopedConfig {
+ _global?: T
+ [methodKey: string]: T | undefined
+ }
+
+ function cloneMethodScopedConfig>(
+ config?: DynamicCheckoutMethodScopedConfig,
+ ): DynamicCheckoutMethodScopedConfig {
+ const clonedConfig: DynamicCheckoutMethodScopedConfig = {}
+
+ if (!config) {
+ return clonedConfig
+ }
+
+ for (const key in config) {
+ if (config[key]) {
+ clonedConfig[key] = {
+ ...config[key],
+ }
+ }
+ }
+
+ return clonedConfig
+ }
+
+ function getScopedConfigValue>(
+ config: DynamicCheckoutMethodScopedConfig,
+ methodKey: DynamicCheckoutMethodKey,
+ ): T {
+ return {
+ ...(config._global || {}),
+ ...(config[methodKey] || {}),
+ } as T
+ }
+
+ // ---------------------------------------------------------------------------
+ // Shared value types (used by both old and new public APIs)
+ // ---------------------------------------------------------------------------
+
+ export type DynamicCheckoutAdditionalPaymentDataType = Record
+
+ export type DynamicCheckoutOptionsType = {
+ capturePayments?: boolean
+ allowFallbackToSale?: boolean
+ enforceSavePaymentMethod?: boolean
+ hideSavedPaymentMethods?: boolean
+ showStatusMessage?: boolean
+ }
+
+ export type DynamicCheckoutTextOverridesType = {
+ payButtonText?: string
+ cvcLabel?: string
+ cvcPlaceholder?: string
+ }
+
+ // ---------------------------------------------------------------------------
+ // Public API: initDynamicCheckout (current)
+ // ---------------------------------------------------------------------------
+
+ export type DynamicCheckoutPaymentMethodKey =
+ | "card"
+ | "applepay"
+ | "googlepay"
+ | (string & {})
+
+ export type DynamicCheckoutPaymentMethodOverrideType = {
+ options?: DynamicCheckoutOptionsType
+ theme?: DynamicCheckoutThemeType
+ text?: DynamicCheckoutTextOverridesType
+ additionalData?: DynamicCheckoutAdditionalPaymentDataType
}
+ export type DynamicCheckoutInitConfigType = {
+ invoiceId: string
+ clientSecret?: string
+ locale?: string
+ options?: DynamicCheckoutOptionsType
+ theme?: DynamicCheckoutThemeType
+ text?: DynamicCheckoutTextOverridesType
+ paymentMethodOverrides?: Partial<
+ Record
+ >
+ }
+
+ // ---------------------------------------------------------------------------
+ // Public API: setupDynamicCheckout (deprecated)
+ // ---------------------------------------------------------------------------
+
+ /** @deprecated Use DynamicCheckoutInitConfigType instead */
export type DynamicCheckoutPublicConfigType = {
invoiceId: string
- projectId: string
locale?: string
clientSecret?: string
capturePayments?: boolean
@@ -16,92 +106,281 @@ module ProcessOut {
hideSavedPaymentMethods?: boolean
showStatusMessage?: boolean
payButtonText?: string
- additionalData?: DynamicCheckoutAdditionalDataByGateway
+ additionalData?: Record
cvcLabel?: string
cvcPlaceholder?: string
}
+ /** @deprecated Use DynamicCheckoutInitConfigType instead */
+ export type DynamicCheckoutInitPublicConfigType = {
+ invoiceId: string
+ locale?: string
+ clientSecret?: string
+ options?: DynamicCheckoutMethodScopedConfig
+ theme?: DynamicCheckoutMethodScopedConfig
+ textOverrides?: DynamicCheckoutMethodScopedConfig
+ additionalPaymentData?: DynamicCheckoutMethodScopedConfig
+ }
+
+ // ---------------------------------------------------------------------------
+ // Internal normalized config (all public APIs normalize into this)
+ // ---------------------------------------------------------------------------
+
+ export type DynamicCheckoutNormalizedPublicConfigType = {
+ invoiceId: string
+ projectId: string
+ locale?: string
+ clientSecret?: string
+ optionsByMethod?: DynamicCheckoutMethodScopedConfig
+ themeByMethod?: DynamicCheckoutMethodScopedConfig
+ textOverridesByMethod?: DynamicCheckoutMethodScopedConfig
+ additionalPaymentDataByMethod?: DynamicCheckoutMethodScopedConfig
+ }
+
export type DynamicCheckoutInternalConfigType = {
invoiceDetails: Invoice
}
- export type DynamicCheckoutConfigType = DynamicCheckoutPublicConfigType &
+ export type DynamicCheckoutConfigType = DynamicCheckoutNormalizedPublicConfigType &
DynamicCheckoutInternalConfigType
+ // ---------------------------------------------------------------------------
+ // Normalization functions
+ // ---------------------------------------------------------------------------
+
+ export function normalizeDynamicCheckoutConfig(
+ config: DynamicCheckoutInitConfigType & { projectId: string },
+ ): DynamicCheckoutNormalizedPublicConfigType {
+ const optionsByMethod: DynamicCheckoutMethodScopedConfig = {
+ _global: { ...(config.options || {}) },
+ }
+
+ const themeByMethod: DynamicCheckoutMethodScopedConfig = {
+ _global: config.theme ? { ...config.theme } : {},
+ }
+
+ const textOverridesByMethod: DynamicCheckoutMethodScopedConfig = {
+ _global: config.text ? { ...config.text } : {},
+ }
+
+ const additionalPaymentDataByMethod: DynamicCheckoutMethodScopedConfig = {}
+
+ if (config.paymentMethodOverrides) {
+ for (const key in config.paymentMethodOverrides) {
+ const override = config.paymentMethodOverrides[key]
+
+ if (!override) {
+ continue
+ }
+
+ if (override.options) {
+ optionsByMethod[key] = { ...override.options }
+ }
+
+ if (override.theme) {
+ themeByMethod[key] = { ...override.theme }
+ }
+
+ if (override.text) {
+ textOverridesByMethod[key] = { ...override.text }
+ }
+
+ if (override.additionalData) {
+ additionalPaymentDataByMethod[key] = { ...override.additionalData }
+ }
+ }
+ }
+
+ return {
+ invoiceId: config.invoiceId,
+ projectId: config.projectId,
+ locale: config.locale,
+ clientSecret: config.clientSecret,
+ optionsByMethod,
+ themeByMethod,
+ textOverridesByMethod,
+ additionalPaymentDataByMethod,
+ }
+ }
+
+ /** @deprecated */
+ export function normalizeDynamicCheckoutSetupConfig(
+ config: DynamicCheckoutPublicConfigType & {
+ projectId: string
+ },
+ theme?: DynamicCheckoutThemeType,
+ ): DynamicCheckoutNormalizedPublicConfigType {
+ return {
+ invoiceId: config.invoiceId,
+ projectId: config.projectId,
+ locale: config.locale,
+ clientSecret: config.clientSecret,
+ optionsByMethod: {
+ _global: {
+ capturePayments: config.capturePayments,
+ allowFallbackToSale: config.allowFallbackToSale,
+ enforceSavePaymentMethod: config.enforceSavePaymentMethod,
+ hideSavedPaymentMethods: config.hideSavedPaymentMethods,
+ showStatusMessage: config.showStatusMessage,
+ },
+ },
+ themeByMethod: {
+ _global: theme ? { ...theme } : {},
+ },
+ textOverridesByMethod: {
+ _global: {
+ payButtonText: config.payButtonText,
+ cvcLabel: config.cvcLabel,
+ cvcPlaceholder: config.cvcPlaceholder,
+ },
+ },
+ additionalPaymentDataByMethod: cloneMethodScopedConfig(config.additionalData),
+ }
+ }
+
+ /** @deprecated */
+ export function normalizeDynamicCheckoutInitConfig(
+ config: DynamicCheckoutInitPublicConfigType & {
+ projectId: string
+ },
+ ): DynamicCheckoutNormalizedPublicConfigType {
+ return {
+ invoiceId: config.invoiceId,
+ projectId: config.projectId,
+ locale: config.locale,
+ clientSecret: config.clientSecret,
+ optionsByMethod: cloneMethodScopedConfig(config.options),
+ themeByMethod: cloneMethodScopedConfig(config.theme),
+ textOverridesByMethod: cloneMethodScopedConfig(config.textOverrides),
+ additionalPaymentDataByMethod: cloneMethodScopedConfig(config.additionalPaymentData),
+ }
+ }
+
+ // ---------------------------------------------------------------------------
+ // Runtime config class
+ // ---------------------------------------------------------------------------
+
export class DynamicCheckoutPaymentConfig {
- invoiceId: DynamicCheckoutPublicConfigType["invoiceId"]
- projectId: DynamicCheckoutPublicConfigType["projectId"]
- clientSecret: DynamicCheckoutPublicConfigType["clientSecret"]
- locale: DynamicCheckoutPublicConfigType["locale"] = "en"
- capturePayments: DynamicCheckoutPublicConfigType["capturePayments"] = false
- allowFallbackToSale: DynamicCheckoutPublicConfigType["allowFallbackToSale"] = false
- enforceSavePaymentMethod: DynamicCheckoutPublicConfigType["enforceSavePaymentMethod"] = false
- hideSavedPaymentMethods: DynamicCheckoutPublicConfigType["hideSavedPaymentMethods"] = false
- showStatusMessage: DynamicCheckoutPublicConfigType["showStatusMessage"] = true
- payButtonText: DynamicCheckoutPublicConfigType["payButtonText"] = ""
- additionalData: DynamicCheckoutPublicConfigType["additionalData"] = {}
- cvcLabel: DynamicCheckoutPublicConfigType["cvcLabel"] = ""
- cvcPlaceholder: DynamicCheckoutPublicConfigType["cvcPlaceholder"] = ""
+ invoiceId: DynamicCheckoutNormalizedPublicConfigType["invoiceId"]
+ projectId: DynamicCheckoutNormalizedPublicConfigType["projectId"]
+ clientSecret: DynamicCheckoutNormalizedPublicConfigType["clientSecret"]
+ locale: DynamicCheckoutNormalizedPublicConfigType["locale"] = "en"
+ capturePayments: boolean = false
+ allowFallbackToSale: boolean = false
+ enforceSavePaymentMethod: boolean = false
+ hideSavedPaymentMethods: boolean = false
+ showStatusMessage: boolean = true
+ payButtonText: string = ""
+ additionalData: DynamicCheckoutAdditionalPaymentDataType = {}
+ cvcLabel: string = ""
+ cvcPlaceholder: string = ""
invoiceDetails: DynamicCheckoutInternalConfigType["invoiceDetails"]
- constructor(config: DynamicCheckoutPublicConfigType) {
+ private optionsByMethod: DynamicCheckoutMethodScopedConfig = {}
+ private themeByMethod: DynamicCheckoutMethodScopedConfig = {}
+ private textOverridesByMethod: DynamicCheckoutMethodScopedConfig =
+ {}
+ private additionalPaymentDataByMethod: DynamicCheckoutMethodScopedConfig =
+ {}
+
+ constructor(config: DynamicCheckoutNormalizedPublicConfigType) {
this.setInitialConfig(config)
}
- public getConfig(): DynamicCheckoutPublicConfigType & DynamicCheckoutInternalConfigType {
+ public getConfig(): DynamicCheckoutConfigType {
return {
invoiceId: this.invoiceId,
projectId: this.projectId,
locale: this.locale,
+ clientSecret: this.clientSecret,
invoiceDetails: this.invoiceDetails,
+ optionsByMethod: cloneMethodScopedConfig(this.optionsByMethod),
+ themeByMethod: cloneMethodScopedConfig(this.themeByMethod),
+ textOverridesByMethod: cloneMethodScopedConfig(this.textOverridesByMethod),
+ additionalPaymentDataByMethod: cloneMethodScopedConfig(this.additionalPaymentDataByMethod),
+ }
+ }
+
+ public setInvoiceDetails(invoiceDetails: Invoice) {
+ this.invoiceDetails = invoiceDetails
+ }
+
+ public getOptionsForMethod(methodKey: DynamicCheckoutMethodKey): DynamicCheckoutOptionsType {
+ return {
capturePayments: this.capturePayments,
allowFallbackToSale: this.allowFallbackToSale,
enforceSavePaymentMethod: this.enforceSavePaymentMethod,
hideSavedPaymentMethods: this.hideSavedPaymentMethods,
showStatusMessage: this.showStatusMessage,
- additionalData: this.additionalData,
+ ...getScopedConfigValue(this.optionsByMethod, methodKey),
+ }
+ }
+
+ public getThemeForMethod(methodKey: DynamicCheckoutMethodKey): DynamicCheckoutThemeType {
+ return getScopedConfigValue(this.themeByMethod, methodKey)
+ }
+
+ public getTextOverridesForMethod(
+ methodKey: DynamicCheckoutMethodKey,
+ ): DynamicCheckoutTextOverridesType {
+ return {
payButtonText: this.payButtonText,
cvcLabel: this.cvcLabel,
cvcPlaceholder: this.cvcPlaceholder,
+ ...getScopedConfigValue(this.textOverridesByMethod, methodKey),
}
}
- public setInvoiceDetails(invoiceDetails: Invoice) {
- this.invoiceDetails = invoiceDetails
+ public getAdditionalDataForMethod(
+ methodKey: DynamicCheckoutMethodKey,
+ ): DynamicCheckoutAdditionalPaymentDataType {
+ return getScopedConfigValue(this.additionalPaymentDataByMethod, methodKey)
}
- public getAdditionalDataForGateway(gatewayName: string): Record {
- return this.additionalData[gatewayName] || {}
+ public getAdditionalDataForGateway(
+ gatewayName: DynamicCheckoutMethodKey,
+ ): DynamicCheckoutAdditionalPaymentDataType {
+ return this.getAdditionalDataForMethod(gatewayName)
}
- private setInitialConfig(config: DynamicCheckoutPublicConfigType) {
+ private setInitialConfig(config: DynamicCheckoutNormalizedPublicConfigType) {
if (!this.isValidConfig(config)) {
throw new Error(
"You must instantiate Dynamic Checkout with a valid config in order to use it",
)
}
+ this.optionsByMethod = cloneMethodScopedConfig(config.optionsByMethod)
+ this.themeByMethod = cloneMethodScopedConfig(config.themeByMethod)
+ this.textOverridesByMethod = cloneMethodScopedConfig(config.textOverridesByMethod)
+ this.additionalPaymentDataByMethod = cloneMethodScopedConfig(
+ config.additionalPaymentDataByMethod,
+ )
+
+ const globalOptions = this.getOptionsForMethod("_global")
+ const globalTextOverrides = this.getTextOverridesForMethod("_global")
+
this.invoiceId = config.invoiceId
this.projectId = config.projectId
this.clientSecret = config.clientSecret
this.locale = config.locale || "en"
- this.capturePayments = config.capturePayments || false
- this.allowFallbackToSale = config.allowFallbackToSale || false
- this.enforceSavePaymentMethod = config.enforceSavePaymentMethod || false
- this.hideSavedPaymentMethods = config.hideSavedPaymentMethods || false
- this.payButtonText = config.payButtonText || ""
- this.additionalData = config.additionalData || {}
- this.cvcLabel = config.cvcLabel || ""
- this.cvcPlaceholder = config.cvcPlaceholder || ""
-
- if (config.showStatusMessage !== undefined && config.showStatusMessage !== null) {
- this.showStatusMessage = config.showStatusMessage
+ this.capturePayments = globalOptions.capturePayments || false
+ this.allowFallbackToSale = globalOptions.allowFallbackToSale || false
+ this.enforceSavePaymentMethod = globalOptions.enforceSavePaymentMethod || false
+ this.hideSavedPaymentMethods = globalOptions.hideSavedPaymentMethods || false
+ this.payButtonText = globalTextOverrides.payButtonText ?? ""
+ this.additionalData = this.getAdditionalDataForMethod("_global")
+ this.cvcLabel = globalTextOverrides.cvcLabel ?? ""
+ this.cvcPlaceholder = globalTextOverrides.cvcPlaceholder ?? ""
+
+ if (globalOptions.showStatusMessage !== undefined && globalOptions.showStatusMessage !== null) {
+ this.showStatusMessage = globalOptions.showStatusMessage
} else {
this.showStatusMessage = true
}
}
- private isValidConfig(config: DynamicCheckoutPublicConfigType) {
+ private isValidConfig(config: DynamicCheckoutNormalizedPublicConfigType) {
return !!config.projectId && !!config.invoiceId
}
}
diff --git a/src/dynamic-checkout/dynamic-checkout.ts b/src/dynamic-checkout/dynamic-checkout.ts
index 5c58651..4cc4721 100644
--- a/src/dynamic-checkout/dynamic-checkout.ts
+++ b/src/dynamic-checkout/dynamic-checkout.ts
@@ -6,21 +6,15 @@ module ProcessOut {
widgetWrapper: Element
processOutInstance: ProcessOut
paymentConfig: DynamicCheckoutPaymentConfig
- theme: DynamicCheckoutTheme
invoiceDetails: Invoice
constructor(
processOutInstance: ProcessOut,
- config: DynamicCheckoutPublicConfigType,
- theme?: DynamicCheckoutThemeType,
+ config: DynamicCheckoutNormalizedPublicConfigType,
) {
this.processOutInstance = processOutInstance
this.paymentConfig = new DynamicCheckoutPaymentConfig(config)
- if (theme) {
- this.theme = new DynamicCheckoutTheme(theme)
- }
-
this.applyDefaultStyles()
}
@@ -45,7 +39,6 @@ module ProcessOut {
this,
this.processOutInstance,
this.paymentConfig,
- this.theme,
)
this.loadView(paymentMethodsView.element)
diff --git a/src/dynamic-checkout/payment-methods/apm.ts b/src/dynamic-checkout/payment-methods/apm.ts
index 6bdede5..674d629 100644
--- a/src/dynamic-checkout/payment-methods/apm.ts
+++ b/src/dynamic-checkout/payment-methods/apm.ts
@@ -16,14 +16,12 @@ module ProcessOut {
protected processOutInstance: ProcessOut
private paymentConfig: DynamicCheckoutPaymentConfig
private paymentMethod: PaymentMethod
- private theme: DynamicCheckoutThemeType
private resetContainerHtml: () => HTMLElement
constructor(
processOutInstance: ProcessOut,
paymentMethod: PaymentMethod,
paymentConfig: DynamicCheckoutPaymentConfig,
- theme: DynamicCheckoutThemeType,
resetContainerHtml: () => HTMLElement,
) {
super(
@@ -36,16 +34,40 @@ module ProcessOut {
this.processOutInstance = processOutInstance
this.paymentConfig = paymentConfig
this.paymentMethod = paymentMethod
- this.theme = theme
this.resetContainerHtml = resetContainerHtml
super.appendChildren(this.getChildrenElement())
}
+ private getMethodKey() {
+ return this.paymentMethod.apm.gateway_name
+ }
+
+ private getMethodOptions() {
+ return this.paymentConfig.getOptionsForMethod(this.getMethodKey())
+ }
+
+ private getMethodTheme() {
+ return this.paymentConfig.getThemeForMethod(this.getMethodKey())
+ }
+
+ private getTextOverrides() {
+ return this.paymentConfig.getTextOverridesForMethod(this.getMethodKey())
+ }
+
+ private getAdditionalPaymentData() {
+ return this.paymentConfig.getAdditionalDataForMethod(this.getMethodKey())
+ }
+
+ private shouldShowStatusMessage() {
+ return this.getMethodOptions().showStatusMessage
+ }
+
private proceedToApmPayment() {
const { apm } = this.paymentMethod
const { clientSecret } = this.paymentConfig
const canSavePaymentMethod = apm.saving_allowed
+ const methodOptions = this.getMethodOptions()
const actionHandlerOptions = new ActionHandlerOptions(
apm.gateway_name,
@@ -53,9 +75,9 @@ module ProcessOut {
)
const cardPaymentOptions = {
- authorize_only: !this.paymentConfig.capturePayments,
- allow_fallback_to_sale: this.paymentConfig.allowFallbackToSale,
- save_source: canSavePaymentMethod && this.paymentConfig.enforceSavePaymentMethod,
+ authorize_only: !methodOptions.capturePayments,
+ allow_fallback_to_sale: !!methodOptions.allowFallbackToSale,
+ save_source: canSavePaymentMethod && !!methodOptions.enforceSavePaymentMethod,
}
const requestOptions = {
@@ -69,7 +91,7 @@ module ProcessOut {
if (
canSavePaymentMethod &&
saveForFutureCheckbox &&
- !this.paymentConfig.enforceSavePaymentMethod
+ !methodOptions.enforceSavePaymentMethod
) {
cardPaymentOptions["save_source"] = saveForFutureCheckbox.checked
}
@@ -91,7 +113,7 @@ module ProcessOut {
requestOptions: RequestOptions,
) {
const { apm } = this.paymentMethod
- const additionalData = this.paymentConfig.getAdditionalDataForGateway(apm.gateway_name)
+ const additionalData = this.getAdditionalPaymentData()
const redirectUrl =
Object.keys(additionalData).length > 0
@@ -116,15 +138,12 @@ module ProcessOut {
paymentToken,
cardPaymentOptions,
invoiceId => {
- if (this.paymentConfig.showStatusMessage) {
+ if (this.shouldShowStatusMessage()) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentSuccessView(this.processOutInstance, this.paymentConfig)
.element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!this.shouldShowStatusMessage() && !this.paymentConfig.invoiceDetails.return_url) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig)
.element,
@@ -269,7 +288,7 @@ module ProcessOut {
paymentToken,
options,
invoiceId => {
- if (this.paymentConfig.showStatusMessage) {
+ if (this.shouldShowStatusMessage()) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentSuccessView(
this.processOutInstance,
@@ -277,7 +296,7 @@ module ProcessOut {
).element,
)
} else if (
- !this.paymentConfig.showStatusMessage &&
+ !this.shouldShowStatusMessage() &&
!this.paymentConfig.invoiceDetails.return_url
) {
this.resetContainerHtml().appendChild(
@@ -296,7 +315,7 @@ module ProcessOut {
})
},
error => {
- if (this.paymentConfig.showStatusMessage) {
+ if (this.shouldShowStatusMessage()) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentErrorView(
this.processOutInstance,
@@ -304,7 +323,7 @@ module ProcessOut {
).element,
)
} else if (
- !this.paymentConfig.showStatusMessage &&
+ !this.shouldShowStatusMessage() &&
!this.paymentConfig.invoiceDetails.return_url
) {
this.resetContainerHtml().appendChild(
@@ -358,13 +377,13 @@ module ProcessOut {
tab_closed: error.metadata?.reason === "tab_closed",
})
} else {
- if (this.paymentConfig.showStatusMessage) {
+ if (this.shouldShowStatusMessage()) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentErrorView(this.processOutInstance, this.paymentConfig)
.element,
)
} else if (
- !this.paymentConfig.showStatusMessage &&
+ !this.shouldShowStatusMessage() &&
!this.paymentConfig.invoiceDetails.return_url
) {
this.resetContainerHtml().appendChild(
@@ -388,15 +407,12 @@ module ProcessOut {
)
},
error => {
- if (this.paymentConfig.showStatusMessage) {
+ if (this.shouldShowStatusMessage()) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentErrorView(this.processOutInstance, this.paymentConfig)
.element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!this.shouldShowStatusMessage() && !this.paymentConfig.invoiceDetails.return_url) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig)
.element,
@@ -422,8 +438,11 @@ module ProcessOut {
name: "save-apm-for-future",
id: `save-apm-for-future-${this.paymentMethod.apm.gateway_name}`,
}
+ const methodOptions = this.getMethodOptions()
+ const textOverrides = this.getTextOverrides()
+ const theme = this.getMethodTheme()
- if (this.paymentConfig.enforceSavePaymentMethod) {
+ if (methodOptions.enforceSavePaymentMethod) {
saveForFutureAttributes.checked = "checked"
saveForFutureAttributes.disabled = "disabled"
}
@@ -482,7 +501,7 @@ module ProcessOut {
tagName: "button",
classNames: ["dco-payment-method-button-pay-button"],
textContent:
- this.paymentConfig.payButtonText ||
+ textOverrides.payButtonText ||
`${Translations.getText(
"continue-with-apm-button",
this.paymentConfig.locale,
@@ -501,12 +520,12 @@ module ProcessOut {
HTMLElements.appendChildren(childrenWrapper, children)
- if (this.theme && this.theme.payButtonColor) {
- payButton.style.backgroundColor = this.theme.payButtonColor
+ if (theme && theme.payButtonColor) {
+ payButton.style.backgroundColor = theme.payButtonColor
}
- if (this.theme && this.theme.payButtonTextColor) {
- payButton.style.color = this.theme.payButtonTextColor
+ if (theme && theme.payButtonTextColor) {
+ payButton.style.color = theme.payButtonTextColor
}
payButton.addEventListener("click", () => {
diff --git a/src/dynamic-checkout/payment-methods/card.ts b/src/dynamic-checkout/payment-methods/card.ts
index 31b7864..be4874c 100644
--- a/src/dynamic-checkout/payment-methods/card.ts
+++ b/src/dynamic-checkout/payment-methods/card.ts
@@ -5,7 +5,6 @@ module ProcessOut {
private procesoutInstance: ProcessOut
private paymentMethod: PaymentMethod
private paymentConfig: DynamicCheckoutPaymentConfig
- private theme: DynamicCheckoutThemeType
private resetContainerHtml: () => HTMLElement
private isCardRestricted: boolean = false
private tokenizedCardId?: string
@@ -14,7 +13,6 @@ module ProcessOut {
procesoutInstance: ProcessOut,
paymentMethod: PaymentMethod,
paymentConfig: DynamicCheckoutPaymentConfig,
- theme: DynamicCheckoutThemeType,
resetContainerHtml: () => HTMLElement,
) {
const { display } = paymentMethod
@@ -35,7 +33,6 @@ module ProcessOut {
this.procesoutInstance = procesoutInstance
this.paymentMethod = paymentMethod
this.paymentConfig = paymentConfig
- this.theme = theme
this.resetContainerHtml = resetContainerHtml
const cardForm = this.getChildrenElement()
@@ -44,6 +41,18 @@ module ProcessOut {
this.setupCardForm(cardForm)
}
+ private getMethodOptions() {
+ return this.paymentConfig.getOptionsForMethod("card")
+ }
+
+ private getMethodTheme() {
+ return this.paymentConfig.getThemeForMethod("card")
+ }
+
+ private getTextOverrides() {
+ return this.paymentConfig.getTextOverridesForMethod("card")
+ }
+
private setupCardForm(form: HTMLElement): void {
this.procesoutInstance.setupForm(
form,
@@ -122,11 +131,12 @@ module ProcessOut {
private handleTokenizeSuccess(cardToken: string) {
this.tokenizedCardId = cardToken
const canSavePaymentMethod = this.paymentMethod.card.saving_allowed
+ const methodOptions = this.getMethodOptions()
const cardPaymentOptions = {
- authorize_only: !this.paymentConfig.capturePayments,
- allow_fallback_to_sale: this.paymentConfig.allowFallbackToSale,
- save_source: canSavePaymentMethod && this.paymentConfig.enforceSavePaymentMethod,
+ authorize_only: !methodOptions.capturePayments,
+ allow_fallback_to_sale: methodOptions.allowFallbackToSale,
+ save_source: canSavePaymentMethod && methodOptions.enforceSavePaymentMethod,
}
const saveForFutureCheckbox = document.getElementById(
@@ -136,7 +146,7 @@ module ProcessOut {
if (
canSavePaymentMethod &&
saveForFutureCheckbox &&
- !this.paymentConfig.enforceSavePaymentMethod
+ !methodOptions.enforceSavePaymentMethod
) {
cardPaymentOptions["save_source"] = saveForFutureCheckbox.checked
}
@@ -169,6 +179,8 @@ module ProcessOut {
}
private handleCardPaymentSuccess(invoiceId: string, data?: any) {
+ const methodOptions = this.getMethodOptions()
+
DynamicCheckoutEventsUtils.dispatchPaymentSuccessEvent({
invoice_id: invoiceId,
return_url: this.paymentConfig.invoiceDetails.return_url || null,
@@ -177,14 +189,11 @@ module ProcessOut {
customer_token_id: data?.customer_token_id,
})
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentSuccessView(this.procesoutInstance, this.paymentConfig).element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig).element,
)
@@ -192,7 +201,7 @@ module ProcessOut {
}
private handleCardPaymentPending(invoiceId: string) {
- if (this.paymentConfig.showStatusMessage) {
+ if (this.getMethodOptions().showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentPendingView(this.procesoutInstance, this.paymentConfig).element,
)
@@ -207,14 +216,13 @@ module ProcessOut {
}
private handleCardPaymentError(error) {
- if (this.paymentConfig.showStatusMessage) {
+ const methodOptions = this.getMethodOptions()
+
+ if (methodOptions.showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentErrorView(this.procesoutInstance, this.paymentConfig).element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig).element,
)
@@ -276,13 +284,17 @@ module ProcessOut {
name: "save-card-for-future",
}
- if (this.paymentConfig.enforceSavePaymentMethod) {
+ const methodOptions = this.getMethodOptions()
+ const textOverrides = this.getTextOverrides()
+ const theme = this.getMethodTheme()
+
+ if (methodOptions.enforceSavePaymentMethod) {
saveForFutureAttributes.checked = "checked"
saveForFutureAttributes.disabled = "disabled"
}
const payButtonText =
- this.paymentConfig.payButtonText ||
+ textOverrides.payButtonText ||
`${Translations.getText(
"pay-button-text",
this.paymentConfig.locale,
@@ -335,12 +347,12 @@ module ProcessOut {
},
])
- if (this.theme && this.theme.payButtonColor) {
- payButton.style.backgroundColor = this.theme.payButtonColor
+ if (theme && theme.payButtonColor) {
+ payButton.style.backgroundColor = theme.payButtonColor
}
- if (this.theme && this.theme.payButtonTextColor) {
- payButton.style.color = this.theme.payButtonTextColor
+ if (theme && theme.payButtonTextColor) {
+ payButton.style.color = theme.payButtonTextColor
}
HTMLElements.appendChildren(saveForFutureWrapper, [saveForFutureCheckbox, saveForFutureLabel])
@@ -364,14 +376,18 @@ module ProcessOut {
}
private getCvcLabel() {
+ const textOverrides = this.getTextOverrides()
+
return (
- this.paymentConfig.cvcLabel || Translations.getText("cvc-label", this.paymentConfig.locale)
+ textOverrides.cvcLabel || Translations.getText("cvc-label", this.paymentConfig.locale)
)
}
private getCvcPlaceholder() {
+ const textOverrides = this.getTextOverrides()
+
return (
- this.paymentConfig.cvcPlaceholder ||
+ textOverrides.cvcPlaceholder ||
Translations.getText("cvc-placeholder", this.paymentConfig.locale)
)
}
diff --git a/src/dynamic-checkout/payment-methods/native-apm.ts b/src/dynamic-checkout/payment-methods/native-apm.ts
index efb05a1..1d985cc 100644
--- a/src/dynamic-checkout/payment-methods/native-apm.ts
+++ b/src/dynamic-checkout/payment-methods/native-apm.ts
@@ -8,7 +8,6 @@ module ProcessOut {
private paymentConfig: DynamicCheckoutPaymentConfig
private isMounted: boolean
private paymentMethodName: string
- private theme: DynamicCheckoutThemeType
private resetContainerHtml: () => HTMLElement
protected processOutInstance: ProcessOut
@@ -18,7 +17,6 @@ module ProcessOut {
processOutInstance: ProcessOut,
paymentMethod: PaymentMethod,
paymentConfig: DynamicCheckoutPaymentConfig,
- theme: DynamicCheckoutThemeType,
resetContainerHtml: () => HTMLElement,
onPaymentSubmit?: () => void,
) {
@@ -31,25 +29,25 @@ module ProcessOut {
this.paymentMethodName = apm.gateway_name
this.processOutInstance = processOutInstance
this.resetContainerHtml = resetContainerHtml
- this.theme = theme
this.onPaymentSubmit = onPaymentSubmit
const wrapper = this.getNativeApmWrapper()
super.appendChildren(wrapper)
+ const theme = this.paymentConfig.getThemeForMethod(this.paymentMethodName)
+ const textOverrides = this.paymentConfig.getTextOverridesForMethod(this.paymentMethodName)
this.nativeApmInstance = this.processOutInstance.setupNativeApm({
invoiceId,
gatewayConfigurationId: apm.gateway_configuration_id,
returnUrl: invoiceDetails.return_url,
- payButtonText: paymentConfig.payButtonText,
+ payButtonText: textOverrides.payButtonText,
locale: paymentConfig.locale,
})
const backgroundColor =
- this.theme && this.theme.payButtonColor ? this.theme.payButtonColor : "#242C38"
+ theme && theme.payButtonColor ? theme.payButtonColor : "#242C38"
- const color =
- this.theme && this.theme.payButtonTextColor ? this.theme.payButtonTextColor : "white"
+ const color = theme && theme.payButtonTextColor ? theme.payButtonTextColor : "white"
this.nativeApmInstance.setTheme({
buttons: {
@@ -89,13 +87,13 @@ module ProcessOut {
return
}
- if (this.paymentConfig.showStatusMessage) {
+ if (this.paymentConfig.getOptionsForMethod(this.paymentMethodName).showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentSuccessView(this.processOutInstance, this.paymentConfig)
.element,
)
} else if (
- !this.paymentConfig.showStatusMessage &&
+ !this.paymentConfig.getOptionsForMethod(this.paymentMethodName).showStatusMessage &&
!this.paymentConfig.invoiceDetails.return_url
) {
this.resetContainerHtml().appendChild(
@@ -117,13 +115,13 @@ module ProcessOut {
return
}
- if (this.paymentConfig.showStatusMessage) {
+ if (this.paymentConfig.getOptionsForMethod(this.paymentMethodName).showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentErrorView(this.processOutInstance, this.paymentConfig)
.element,
)
} else if (
- !this.paymentConfig.showStatusMessage &&
+ !this.paymentConfig.getOptionsForMethod(this.paymentMethodName).showStatusMessage &&
!this.paymentConfig.invoiceDetails.return_url
) {
this.resetContainerHtml().appendChild(
diff --git a/src/dynamic-checkout/payment-methods/saved-apm.ts b/src/dynamic-checkout/payment-methods/saved-apm.ts
index 0534dda..cf9333d 100644
--- a/src/dynamic-checkout/payment-methods/saved-apm.ts
+++ b/src/dynamic-checkout/payment-methods/saved-apm.ts
@@ -11,7 +11,6 @@ module ProcessOut {
processOutInstance: ProcessOut,
paymentMethod: PaymentMethod,
paymentConfig: DynamicCheckoutPaymentConfig,
- theme: DynamicCheckoutThemeType,
resetContainerHtml: () => HTMLElement,
deleteMode?: boolean,
handleDeletePaymentMethod?: () => void,
@@ -39,12 +38,14 @@ module ProcessOut {
}
private handleApmPayment() {
- const { apm_customer_token, apm } = this.paymentMethod
+ const { apm_customer_token } = this.paymentMethod
const { clientSecret, invoiceId } = this.paymentConfig
+ const methodKey = apm_customer_token.gateway_name
+ const methodOptions = this.paymentConfig.getOptionsForMethod(methodKey)
const cardPaymentOptions = {
- authorize_only: !this.paymentConfig.capturePayments,
- allow_fallback_to_sale: this.paymentConfig.allowFallbackToSale,
+ authorize_only: !methodOptions.capturePayments,
+ allow_fallback_to_sale: !!methodOptions.allowFallbackToSale,
}
const requestOptions = {
@@ -59,9 +60,7 @@ module ProcessOut {
this.setLoading(this.paymentConfig.locale)
if (apm_customer_token.redirect_url) {
- const additionalData = this.paymentConfig.getAdditionalDataForGateway(
- apm_customer_token.gateway_name,
- )
+ const additionalData = this.paymentConfig.getAdditionalDataForMethod(methodKey)
const redirectUrl = Object.keys(additionalData).length > 0
? this.processOutInstance.appendAdditionalDataToUrl(
@@ -85,17 +84,14 @@ module ProcessOut {
paymentToken,
cardPaymentOptions,
invoiceId => {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentSuccessView(
this.processOutInstance,
this.paymentConfig,
).element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig)
.element,
@@ -109,15 +105,12 @@ module ProcessOut {
})
},
error => {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentErrorView(this.processOutInstance, this.paymentConfig)
.element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig)
.element,
@@ -134,7 +127,7 @@ module ProcessOut {
},
requestOptions,
invoiceId => {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentPendingView(
this.processOutInstance,
@@ -206,10 +199,22 @@ module ProcessOut {
)
}
- private handlePaymentSuccess(invoiceId: string, data) {
- this.resetContainerHtml().appendChild(
- new DynamicCheckoutPaymentSuccessView(this.processOutInstance, this.paymentConfig).element,
- )
+ private handlePaymentSuccess(invoiceId: string) {
+ const methodKey = this.paymentMethod.apm_customer_token
+ ? this.paymentMethod.apm_customer_token.gateway_name
+ : "apm"
+ const methodOptions = this.paymentConfig.getOptionsForMethod(methodKey)
+
+ if (methodOptions.showStatusMessage) {
+ this.resetContainerHtml().appendChild(
+ new DynamicCheckoutPaymentSuccessView(this.processOutInstance, this.paymentConfig)
+ .element,
+ )
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
+ this.resetContainerHtml().appendChild(
+ new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig).element,
+ )
+ }
DynamicCheckoutEventsUtils.dispatchPaymentSuccessEvent({
invoice_id: invoiceId,
@@ -221,7 +226,12 @@ module ProcessOut {
}
private handlePaymentPending(invoiceId: string) {
- if (this.paymentConfig.showStatusMessage) {
+ const methodKey = this.paymentMethod.apm_customer_token
+ ? this.paymentMethod.apm_customer_token.gateway_name
+ : "apm"
+ const methodOptions = this.paymentConfig.getOptionsForMethod(methodKey)
+
+ if (methodOptions.showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentPendingView(this.processOutInstance, this.paymentConfig)
.element,
@@ -238,6 +248,11 @@ module ProcessOut {
}
private handlePaymentError(error) {
+ const methodKey = this.paymentMethod.apm_customer_token
+ ? this.paymentMethod.apm_customer_token.gateway_name
+ : "apm"
+ const methodOptions = this.paymentConfig.getOptionsForMethod(methodKey)
+
if (error.code === "customer.canceled") {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentCancelledView(this.processOutInstance, this.paymentConfig)
@@ -253,9 +268,17 @@ module ProcessOut {
tab_closed: error.metadata?.reason === "tab_closed",
})
} else {
- this.resetContainerHtml().appendChild(
- new DynamicCheckoutPaymentErrorView(this.processOutInstance, this.paymentConfig).element,
- )
+ if (methodOptions.showStatusMessage) {
+ this.resetContainerHtml().appendChild(
+ new DynamicCheckoutPaymentErrorView(this.processOutInstance, this.paymentConfig)
+ .element,
+ )
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
+ this.resetContainerHtml().appendChild(
+ new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig)
+ .element,
+ )
+ }
DynamicCheckoutEventsUtils.dispatchPaymentErrorEvent(
this.paymentConfig.invoiceId,
diff --git a/src/dynamic-checkout/payment-methods/saved-card.ts b/src/dynamic-checkout/payment-methods/saved-card.ts
index 2f71af2..f11a4da 100644
--- a/src/dynamic-checkout/payment-methods/saved-card.ts
+++ b/src/dynamic-checkout/payment-methods/saved-card.ts
@@ -11,7 +11,6 @@ module ProcessOut {
processOutInstance: ProcessOut,
paymentMethod: PaymentMethod,
paymentConfig: DynamicCheckoutPaymentConfig,
- theme: DynamicCheckoutThemeType,
resetContainerHtml: () => HTMLElement,
deleteMode?: boolean,
handleDeletePaymentMethod?: () => void,
@@ -39,6 +38,8 @@ module ProcessOut {
}
private handlePayment() {
+ const methodOptions = this.paymentConfig.getOptionsForMethod("card")
+
this.setLoading(this.paymentConfig.locale)
DynamicCheckoutEventsUtils.dispatchPaymentSubmittedEvent({
@@ -52,8 +53,8 @@ module ProcessOut {
this.paymentConfig.invoiceId,
this.paymentMethod.card_customer_token.customer_token_id,
{
- authorize_only: !this.paymentConfig.capturePayments,
- allow_fallback_to_sale: this.paymentConfig.allowFallbackToSale,
+ authorize_only: !methodOptions.capturePayments,
+ allow_fallback_to_sale: !!methodOptions.allowFallbackToSale,
},
this.handlePaymentSuccess.bind(this),
this.handlePaymentError.bind(this),
@@ -63,15 +64,14 @@ module ProcessOut {
}
private handlePaymentSuccess(invoiceId: string) {
- if (this.paymentConfig.showStatusMessage) {
+ const methodOptions = this.paymentConfig.getOptionsForMethod("card")
+
+ if (methodOptions.showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentSuccessView(this.processOutInstance, this.paymentConfig)
.element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig).element,
)
@@ -85,7 +85,7 @@ module ProcessOut {
}
private handlePaymentPending(invoiceId: string) {
- if (this.paymentConfig.showStatusMessage) {
+ if (this.paymentConfig.getOptionsForMethod("card").showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentPendingView(this.processOutInstance, this.paymentConfig)
.element,
@@ -100,6 +100,8 @@ module ProcessOut {
}
private handlePaymentError(error) {
+ const methodOptions = this.paymentConfig.getOptionsForMethod("card")
+
if (error.code === "customer.canceled") {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentCancelledView(this.processOutInstance, this.paymentConfig)
@@ -113,15 +115,12 @@ module ProcessOut {
tab_closed: error.metadata?.reason === "tab_closed",
})
} else {
- if (this.paymentConfig.showStatusMessage) {
+ if (methodOptions.showStatusMessage) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentErrorView(this.processOutInstance, this.paymentConfig)
.element,
)
- } else if (
- !this.paymentConfig.showStatusMessage &&
- !this.paymentConfig.invoiceDetails.return_url
- ) {
+ } else if (!methodOptions.showStatusMessage && !this.paymentConfig.invoiceDetails.return_url) {
this.resetContainerHtml().appendChild(
new DynamicCheckoutPaymentInfoView(this.processOutInstance, this.paymentConfig)
.element,
diff --git a/src/dynamic-checkout/views/payment-methods.ts b/src/dynamic-checkout/views/payment-methods.ts
index c7ee80b..4c8d31e 100644
--- a/src/dynamic-checkout/views/payment-methods.ts
+++ b/src/dynamic-checkout/views/payment-methods.ts
@@ -6,19 +6,16 @@ module ProcessOut {
dynamicCheckout: DynamicCheckout
paymentConfig: DynamicCheckoutPaymentConfig
paymentMethodsManager: PaymentMethodsManager
- theme: DynamicCheckoutThemeType
element: HTMLElement
constructor(
dynamicCheckout: DynamicCheckout,
processOutInstance: ProcessOut,
paymentConfig: DynamicCheckoutPaymentConfig,
- theme: DynamicCheckoutThemeType,
) {
this.dynamicCheckout = dynamicCheckout
this.processOutInstance = processOutInstance
this.paymentConfig = paymentConfig
- this.theme = theme
this.element = this.createViewElement()
this.loadTingleLibrary()
}
@@ -278,7 +275,6 @@ module ProcessOut {
this.processOutInstance,
paymentMethod,
this.paymentConfig,
- this.theme,
this.resetContainerHtml.bind(this),
deleteMode,
() => this.handleDeletePaymentMethod(paymentMethod),
@@ -291,7 +287,6 @@ module ProcessOut {
this.processOutInstance,
paymentMethod,
this.paymentConfig,
- this.theme,
this.resetContainerHtml.bind(this),
deleteMode,
() => this.handleDeletePaymentMethod(paymentMethod),
@@ -305,14 +300,12 @@ module ProcessOut {
this.processOutInstance,
paymentMethod,
this.paymentConfig,
- this.theme,
this.resetContainerHtml.bind(this),
)
: new NativeApmPaymentMethod(
this.processOutInstance,
paymentMethod,
this.paymentConfig,
- this.theme,
this.resetContainerHtml.bind(this),
() => {
DynamicCheckoutEventsUtils.dispatchPaymentSubmittedEvent({
@@ -330,7 +323,6 @@ module ProcessOut {
this.processOutInstance,
paymentMethod,
this.paymentConfig,
- this.theme,
this.resetContainerHtml.bind(this),
)
diff --git a/src/processout/processout.ts b/src/processout/processout.ts
index 21a0623..1cad04b 100644
--- a/src/processout/processout.ts
+++ b/src/processout/processout.ts
@@ -540,8 +540,9 @@ module ProcessOut {
}
/**
- * SetupDynamicCheckout creates a Dynamic Checkout instance
- * @param {DynamicCheckoutConfigType} config
+ * @deprecated Use initDynamicCheckout instead
+ * @param {DynamicCheckoutPublicConfigType} config
+ * @param {DynamicCheckoutThemeType} theme
* @return {DynamicCheckout}
*/
public setupDynamicCheckout(
@@ -554,7 +555,31 @@ module ProcessOut {
"You must instantiate ProcessOut.js with a valid project ID in order to use ProcessOut's Dynamic Checkout",
)
- return new DynamicCheckout(this, { ...config, projectId: this.projectID }, theme)
+ return new DynamicCheckout(
+ this,
+ normalizeDynamicCheckoutSetupConfig(
+ { ...config, projectId: this.projectID },
+ theme,
+ ),
+ )
+ }
+
+ /**
+ * Creates a Dynamic Checkout instance
+ * @param {DynamicCheckoutInitConfigType} config
+ * @return {DynamicCheckout}
+ */
+ public initDynamicCheckout(config: DynamicCheckoutInitConfigType): DynamicCheckout {
+ if (!this.projectID)
+ throw new Exception(
+ "default",
+ "You must instantiate ProcessOut.js with a valid project ID in order to use ProcessOut's Dynamic Checkout",
+ )
+
+ return new DynamicCheckout(
+ this,
+ normalizeDynamicCheckoutConfig({ ...config, projectId: this.projectID }),
+ )
}
/**