1 import { type Api } from '@proton/shared/lib/interfaces';
3 import { PAYMENT_METHOD_TYPES } from '../constants';
4 import { type PaymentVerificator, createPaymentTokenForExistingPayment } from '../createPaymentToken';
7 ChargeablePaymentParameters,
8 ChargeablePaymentToken,
9 NonChargeablePaymentToken,
11 SavedPaymentMethodExternal,
12 SavedPaymentMethodInternal,
14 } from '../interface';
15 import { PaymentProcessor } from './paymentProcessor';
17 interface SavedPaymentState {
19 paymentMethodId: string;
21 | PAYMENT_METHOD_TYPES.CARD
22 | PAYMENT_METHOD_TYPES.PAYPAL
23 | PAYMENT_METHOD_TYPES.CHARGEBEE_SEPA_DIRECT_DEBIT;
29 | PAYMENT_METHOD_TYPES.CARD
30 | PAYMENT_METHOD_TYPES.PAYPAL
31 | PAYMENT_METHOD_TYPES.CHARGEBEE_CARD
32 | PAYMENT_METHOD_TYPES.CHARGEBEE_PAYPAL
33 | PAYMENT_METHOD_TYPES.CHARGEBEE_SEPA_DIRECT_DEBIT
34 ): PAYMENT_METHOD_TYPES.CARD | PAYMENT_METHOD_TYPES.PAYPAL | PAYMENT_METHOD_TYPES.CHARGEBEE_SEPA_DIRECT_DEBIT {
36 case PAYMENT_METHOD_TYPES.CARD:
37 case PAYMENT_METHOD_TYPES.PAYPAL:
39 case PAYMENT_METHOD_TYPES.CHARGEBEE_CARD:
40 return PAYMENT_METHOD_TYPES.CARD;
41 case PAYMENT_METHOD_TYPES.CHARGEBEE_PAYPAL:
42 return PAYMENT_METHOD_TYPES.PAYPAL;
43 case PAYMENT_METHOD_TYPES.CHARGEBEE_SEPA_DIRECT_DEBIT:
44 return PAYMENT_METHOD_TYPES.CHARGEBEE_SEPA_DIRECT_DEBIT;
48 export class SavedPaymentProcessor extends PaymentProcessor<SavedPaymentState> {
49 public fetchedPaymentToken: ChargeablePaymentToken | NonChargeablePaymentToken | null = null;
52 public verifyPayment: PaymentVerificator,
54 amountAndCurrency: AmountAndCurrency,
55 savedMethod: SavedPaymentMethodInternal | SavedPaymentMethodExternal | SavedPaymentMethod,
56 public onTokenIsChargeable?: (data: ChargeablePaymentParameters) => Promise<unknown>
61 paymentMethodId: savedMethod.ID,
62 type: convertType(savedMethod.Type),
69 async fetchPaymentToken(): Promise<ChargeablePaymentToken | NonChargeablePaymentToken | null> {
70 if (this.amountAndCurrency.Amount === 0) {
74 this.fetchedPaymentToken = await createPaymentTokenForExistingPayment(
75 this.state.method.paymentMethodId,
76 this.state.method.type,
78 this.amountAndCurrency
81 return this.fetchedPaymentToken;
84 async verifyPaymentToken(): Promise<ChargeablePaymentParameters> {
85 if (this.amountAndCurrency.Amount === 0) {
86 return this.tokenCreated();
89 if (this.fetchedPaymentToken === null) {
90 throw new Error('Payment token was not fetched. Please call fetchPaymentToken() first.');
93 if (this.fetchedPaymentToken.chargeable) {
94 return this.tokenCreated(this.fetchedPaymentToken);
97 const token: V5PaymentToken = await this.verifyPayment({
98 Token: this.fetchedPaymentToken.PaymentToken,
99 ApprovalURL: this.fetchedPaymentToken.approvalURL,
100 ReturnHost: this.fetchedPaymentToken.returnHost,
103 return this.tokenCreated(token);
106 updateSavedMethod(savedMethod: SavedPaymentMethodInternal | SavedPaymentMethodExternal | SavedPaymentMethod) {
107 this.state.method = {
108 paymentMethodId: savedMethod.ID,
109 type: convertType(savedMethod.Type),
114 this.fetchedPaymentToken = null;
117 private tokenCreated(token?: V5PaymentToken): ChargeablePaymentParameters {
118 const result: ChargeablePaymentParameters = {
119 type: PAYMENT_METHOD_TYPES.CARD,
121 ...this.amountAndCurrency,
125 void this.onTokenIsChargeable?.(result);