From 2527a014cdecd5b81c596492df5faa29fa6694ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jasi=C5=84ski?= Date: Wed, 22 Jul 2026 11:29:50 +0200 Subject: [PATCH 1/2] feat: support tokenize-only flow in dynamic checkout --- src/dynamic-checkout/locales/ar.ts | 1 + src/dynamic-checkout/locales/de.ts | 1 + src/dynamic-checkout/locales/en.ts | 1 + src/dynamic-checkout/locales/es.ts | 1 + src/dynamic-checkout/locales/fi.ts | 1 + src/dynamic-checkout/locales/fr.ts | 1 + src/dynamic-checkout/locales/it.ts | 1 + src/dynamic-checkout/locales/ja.ts | 1 + src/dynamic-checkout/locales/ko.ts | 1 + src/dynamic-checkout/locales/nb.ts | 1 + src/dynamic-checkout/locales/pl.ts | 1 + src/dynamic-checkout/locales/pt.ts | 1 + src/dynamic-checkout/locales/ta.ts | 1 + src/dynamic-checkout/locales/vi.ts | 1 + src/dynamic-checkout/payment-methods/card.ts | 23 +++++++++++++------ src/dynamic-checkout/types/api.ts | 1 + src/dynamic-checkout/views/payment-methods.ts | 8 ++++++- 17 files changed, 38 insertions(+), 8 deletions(-) diff --git a/src/dynamic-checkout/locales/ar.ts b/src/dynamic-checkout/locales/ar.ts index 1cc9120..ed6e3dc 100644 --- a/src/dynamic-checkout/locales/ar.ts +++ b/src/dynamic-checkout/locales/ar.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "حفظ لعمليات الدفع المستقبلية", "continue-with-apm-button": "المتابعة باستخدام", "pay-button-text": "ادفع", + "tokenize-payment-button-text": "ترميز الدفع", "card-details-section-title": "تفاصيل البطاقة", "cardholder-name-label": "اسم حامل البطاقة", "billing-address-section-title": "عنوان الفوترة", diff --git a/src/dynamic-checkout/locales/de.ts b/src/dynamic-checkout/locales/de.ts index c870dfd..1d6b0ad 100644 --- a/src/dynamic-checkout/locales/de.ts +++ b/src/dynamic-checkout/locales/de.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Für zukünftige Zahlungen speichern", "continue-with-apm-button": "Weiter mit", "pay-button-text": "Bezahlen", + "tokenize-payment-button-text": "Zahlung tokenisieren", "card-details-section-title": "Kartendetails", "cardholder-name-label": "Name des Karteninhabers", "billing-address-section-title": "Rechnungsadresse", diff --git a/src/dynamic-checkout/locales/en.ts b/src/dynamic-checkout/locales/en.ts index d49dc75..227bf9f 100644 --- a/src/dynamic-checkout/locales/en.ts +++ b/src/dynamic-checkout/locales/en.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Save for future payments", "continue-with-apm-button": "Continue with", "pay-button-text": "Pay", + "tokenize-payment-button-text": "Tokenize payment", "card-details-section-title": "Card details", "cardholder-name-label": "Cardholder name", "billing-address-section-title": "Billing address", diff --git a/src/dynamic-checkout/locales/es.ts b/src/dynamic-checkout/locales/es.ts index b089ce7..3bcbe2a 100644 --- a/src/dynamic-checkout/locales/es.ts +++ b/src/dynamic-checkout/locales/es.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Guardar para pagos futuros", "continue-with-apm-button": "Continuar con", "pay-button-text": "Pagar", + "tokenize-payment-button-text": "Tokenizar pago", "card-details-section-title": "Detalles de la tarjeta", "cardholder-name-label": "Nombre del titular de la tarjeta", "billing-address-section-title": "Dirección de facturación", diff --git a/src/dynamic-checkout/locales/fi.ts b/src/dynamic-checkout/locales/fi.ts index a5c831c..b6f9ff5 100644 --- a/src/dynamic-checkout/locales/fi.ts +++ b/src/dynamic-checkout/locales/fi.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Tallenna tulevia maksuja varten", "continue-with-apm-button": "Jatka tavalla", "pay-button-text": "Maksa", + "tokenize-payment-button-text": "Tokenisoi maksu", "card-details-section-title": "Kortin tiedot", "cardholder-name-label": "Kortinhaltijan nimi", "billing-address-section-title": "Laskutusosoite", diff --git a/src/dynamic-checkout/locales/fr.ts b/src/dynamic-checkout/locales/fr.ts index 3940853..4b71e72 100644 --- a/src/dynamic-checkout/locales/fr.ts +++ b/src/dynamic-checkout/locales/fr.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Enregistrer pour les paiements futurs", "continue-with-apm-button": "Continuer avec", "pay-button-text": "Payer", + "tokenize-payment-button-text": "Tokeniser le paiement", "card-details-section-title": "Détails de la carte", "cardholder-name-label": "Nom du titulaire de la carte", "billing-address-section-title": "Adresse de facturation", diff --git a/src/dynamic-checkout/locales/it.ts b/src/dynamic-checkout/locales/it.ts index eb55b9d..15127a1 100644 --- a/src/dynamic-checkout/locales/it.ts +++ b/src/dynamic-checkout/locales/it.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Salva per pagamenti futuri", "continue-with-apm-button": "Continua con", "pay-button-text": "Paga", + "tokenize-payment-button-text": "Tokenizza pagamento", "card-details-section-title": "Dettagli della carta", "cardholder-name-label": "Nome del titolare della carta", "billing-address-section-title": "Indirizzo di fatturazione", diff --git a/src/dynamic-checkout/locales/ja.ts b/src/dynamic-checkout/locales/ja.ts index 22e9941..c0202ec 100644 --- a/src/dynamic-checkout/locales/ja.ts +++ b/src/dynamic-checkout/locales/ja.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "今後の支払いのために保存", "continue-with-apm-button": "で続行", "pay-button-text": "支払う", + "tokenize-payment-button-text": "支払いをトークン化", "card-details-section-title": "カード情報", "cardholder-name-label": "カード名義人", "billing-address-section-title": "請求先住所", diff --git a/src/dynamic-checkout/locales/ko.ts b/src/dynamic-checkout/locales/ko.ts index 5313315..2ee7aea 100644 --- a/src/dynamic-checkout/locales/ko.ts +++ b/src/dynamic-checkout/locales/ko.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "향후 결제를 위해 저장", "continue-with-apm-button": "계속하기", "pay-button-text": "결제", + "tokenize-payment-button-text": "결제 토큰화", "card-details-section-title": "카드 정보", "cardholder-name-label": "카드 소유자 이름", "billing-address-section-title": "청구지 주소", diff --git a/src/dynamic-checkout/locales/nb.ts b/src/dynamic-checkout/locales/nb.ts index 367c032..fb3c611 100644 --- a/src/dynamic-checkout/locales/nb.ts +++ b/src/dynamic-checkout/locales/nb.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Lagre for fremtidige betalinger", "continue-with-apm-button": "Fortsett med", "pay-button-text": "Betal", + "tokenize-payment-button-text": "Tokeniser betaling", "card-details-section-title": "Kortdetaljer", "cardholder-name-label": "Kortholders navn", "billing-address-section-title": "Faktureringsadresse", diff --git a/src/dynamic-checkout/locales/pl.ts b/src/dynamic-checkout/locales/pl.ts index 8169f6e..f64efa3 100644 --- a/src/dynamic-checkout/locales/pl.ts +++ b/src/dynamic-checkout/locales/pl.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Zapisz na przyszłe płatności", "continue-with-apm-button": "Kontynuuj z", "pay-button-text": "Zapłać", + "tokenize-payment-button-text": "Tokenizuj płatność", "card-details-section-title": "Szczegóły karty", "cardholder-name-label": "Imię i nazwisko posiadacza karty", "billing-address-section-title": "Adres rozliczeniowy", diff --git a/src/dynamic-checkout/locales/pt.ts b/src/dynamic-checkout/locales/pt.ts index 51b6d2d..0cf2ade 100644 --- a/src/dynamic-checkout/locales/pt.ts +++ b/src/dynamic-checkout/locales/pt.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Guardar para pagamentos futuros", "continue-with-apm-button": "Continuar com", "pay-button-text": "Pagar", + "tokenize-payment-button-text": "Tokenizar pagamento", "card-details-section-title": "Detalhes do cartão", "cardholder-name-label": "Nome do titular do cartão", "billing-address-section-title": "Morada de faturação", diff --git a/src/dynamic-checkout/locales/ta.ts b/src/dynamic-checkout/locales/ta.ts index a67866c..6990a76 100644 --- a/src/dynamic-checkout/locales/ta.ts +++ b/src/dynamic-checkout/locales/ta.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "எதிர்கால கட்டணங்களுக்காகச் சேமிக்கவும்", "continue-with-apm-button": "இதனுடன் தொடரவும்", "pay-button-text": "செலுத்து", + "tokenize-payment-button-text": "கட்டணத்தை டோக்கனாக்கு", "card-details-section-title": "அட்டை விவரங்கள்", "cardholder-name-label": "அட்டைதாரரின் பெயர்", "billing-address-section-title": "பில்லிங் முகவரி", diff --git a/src/dynamic-checkout/locales/vi.ts b/src/dynamic-checkout/locales/vi.ts index 2c70671..aab52d5 100644 --- a/src/dynamic-checkout/locales/vi.ts +++ b/src/dynamic-checkout/locales/vi.ts @@ -4,6 +4,7 @@ module ProcessOut { "save-for-future-label": "Lưu cho các lần thanh toán sau", "continue-with-apm-button": "Tiếp tục với", "pay-button-text": "Thanh toán", + "tokenize-payment-button-text": "Mã hóa thanh toán", "card-details-section-title": "Chi tiết thẻ", "cardholder-name-label": "Tên chủ thẻ", "billing-address-section-title": "Địa chỉ thanh toán", diff --git a/src/dynamic-checkout/payment-methods/card.ts b/src/dynamic-checkout/payment-methods/card.ts index e28e4e2..7dfb18c 100644 --- a/src/dynamic-checkout/payment-methods/card.ts +++ b/src/dynamic-checkout/payment-methods/card.ts @@ -144,6 +144,10 @@ module ProcessOut { cardPaymentOptions["save_source"] = saveForFutureCheckbox.checked } + if (this.paymentMethod.card.tokenize_only) { + cardPaymentOptions["save_source"] = true + } + this.processOutInstance.makeCardPayment( this.paymentConfig.invoiceId, cardToken, @@ -318,12 +322,14 @@ module ProcessOut { saveForFutureAttributes.disabled = "disabled" } - const payButtonText = - this.paymentConfig.payButtonText || - `${Translations.getText( - "pay-button-text", - this.paymentConfig.locale, - )} ${this.paymentConfig.invoiceDetails.amount} ${this.paymentConfig.invoiceDetails.currency}` + const defaultPayButtonText = this.paymentMethod.card.tokenize_only + ? Translations.getText("tokenize-payment-button-text", this.paymentConfig.locale) + : `${Translations.getText( + "pay-button-text", + this.paymentConfig.locale, + )} ${this.paymentConfig.invoiceDetails.amount} ${this.paymentConfig.invoiceDetails.currency}` + + const payButtonText = this.paymentConfig.payButtonText || defaultPayButtonText const [ cardFormWrapper, @@ -389,9 +395,12 @@ module ProcessOut { HTMLElements.appendChildren(cardFormSectionsWrapper, cardFormSectionsChildren) + const canShowSaveForFuture = + this.paymentMethod.card.saving_allowed && !this.paymentMethod.card.tokenize_only + const children = [ cardFormSectionsWrapper, - this.paymentMethod.card.saving_allowed ? saveForFutureWrapper : null, + canShowSaveForFuture ? saveForFutureWrapper : null, payButton, ].filter(Boolean) diff --git a/src/dynamic-checkout/types/api.ts b/src/dynamic-checkout/types/api.ts index 417148f..01bad52 100644 --- a/src/dynamic-checkout/types/api.ts +++ b/src/dynamic-checkout/types/api.ts @@ -76,6 +76,7 @@ type Card = { scheme_selection_enabled: boolean scheme_selection_default_order: string[] saving_allowed: boolean + tokenize_only?: boolean billing_address: BillingAddress restrict_to_iins: string[] | null restrict_to_schemes: string[] | null diff --git a/src/dynamic-checkout/views/payment-methods.ts b/src/dynamic-checkout/views/payment-methods.ts index 853f125..8455970 100644 --- a/src/dynamic-checkout/views/payment-methods.ts +++ b/src/dynamic-checkout/views/payment-methods.ts @@ -377,7 +377,7 @@ module ProcessOut { } private getVisiblePaymentMethods() { - if (!this.paymentConfig.hideSavedPaymentMethods) { + if (!this.paymentConfig.hideSavedPaymentMethods && !this.hasTokenizeOnlyCard()) { return this.paymentConfig.invoiceDetails.payment_methods } @@ -386,6 +386,12 @@ module ProcessOut { ) } + private hasTokenizeOnlyCard() { + return this.paymentConfig.invoiceDetails.payment_methods.some( + paymentMethod => paymentMethod.card && paymentMethod.card.tokenize_only, + ) + } + private isSavedPaymentMethod(paymentMethod: PaymentMethod) { return ( paymentMethod.type === "apm_customer_token" || paymentMethod.type === "card_customer_token" From 4db11da39149a347fba49e4dfbc32ad1d3031a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Jasi=C5=84ski?= Date: Wed, 22 Jul 2026 11:56:47 +0200 Subject: [PATCH 2/2] bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 24836bc..75eb8f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "processout.js", - "version": "1.9.8", + "version": "1.9.9", "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",