import {
loadStripe,
Stripe,
StripeElements,
StripeElementsOptionsMode,
StripePaymentElementChangeEvent,
} from '@stripe/stripe-js';
import {Elements, PaymentElement, useElements, useStripe} from '@stripe/react-stripe-js';
import {applyFilters} from '@wordpress/hooks';
import type {Gateway, GatewaySettings} from '@givewp/forms/types';
import {__, sprintf} from '@wordpress/i18n';
let stripePromise = null;
let stripePaymentMethod = null;
let stripePaymentMethodIsCreditCard = false;
// @see https://stripe.com/docs/currencies#zero-decimal
const zeroDecimalCurrencies = [
'BIF',
'CLP',
'DJF',
'GNF',
'JPY',
'KMF',
'KRW',
'MGA',
'PYG',
'RWF',
'UGX',
'VND',
'VUV',
'XAF',
'XOF',
'XPF',
];
/**
* Takes in an amount value in dollar units and returns the calculated cents amount
*
* @since 3.0.0
*/
const dollarsToCents = (amount: string, currency: string) => {
if (zeroDecimalCurrencies.includes(currency)) {
return Math.round(parseFloat(amount));
}
return Math.round(parseFloat(amount) * 100);
};
const StripeFields = ({gateway}) => {
const stripe = useStripe();
const elements = useElements();
gateway.stripe = stripe;
gateway.elements = elements;
const handleOnChange = (event: StripePaymentElementChangeEvent) => {
stripePaymentMethod = event.value.type;
stripePaymentMethodIsCreditCard = event.value.type === 'card';
};
return (
);
};
let appearanceOptions = {};
interface StripeSettings extends GatewaySettings {
formId: number;
stripeKey: string;
stripeConnectAccountId: string;
stripeClientSecret: string;
successUrl: string;
stripePaymentIntentId: string;
}
interface StripeGateway extends Gateway {
stripe?: Stripe;
elements?: StripeElements;
settings?: StripeSettings;
}
/**
* @since 3.18.0 added fields conditional when donation amount is zero
* @since 3.13.0 Use only stripeKey to load the Stripe script (when stripeConnectedAccountId is missing) to prevent errors when the account is connected through API keys
* @since 3.12.1 updated afterCreatePayment response type to include billing details address
* @since 3.0.0
*/
const stripePaymentElementGateway: StripeGateway = {
id: 'stripe_payment_element',
initialize() {
const {stripeKey, stripeConnectedAccountId, formId} = this.settings;
if (!stripeKey && !stripeConnectedAccountId) {
throw new Error('Stripe gateway settings are missing. Check your Stripe settings.');
}
appearanceOptions = applyFilters('givewp_stripe_payment_element_appearance_options', {}, formId) as object;
/**
* Create the Stripe object and pass our api keys
* @see https://stripe.com/docs/payments/accept-a-payment-deferred
*/
stripePromise = loadStripe(
stripeKey,
stripeConnectedAccountId
? {
stripeAccount: stripeConnectedAccountId,
}
: {}
);
},
beforeCreatePayment: async function (values): Promise