@getopenpay/openpay-js
Version:
Accept payments through OpenPay, right on your site
1,407 lines (1,236 loc) • 44.8 kB
TypeScript
/// <reference types="applepayjs" />
/// <reference types="googlepay" />
import { PaymentRequest as PaymentRequest_2 } from '@stripe/stripe-js';
import { StripeLinkAuthenticationElement } from '@stripe/stripe-js';
import { Subject } from 'rxjs';
import { z } from 'zod';
declare type AffirmFlowCustomParams = {
processor?: PaymentProcessor;
useRedirectFlow?: boolean;
};
declare type AfterpayFlowCustomParams = {
processor?: PaymentProcessor;
useRedirectFlow?: boolean;
};
declare type AirwallexACHFlowParams = {
verificationMethod?: 'plaid' | 'micro_deposit';
defaultFieldValues?: DefaultFieldValues;
isBusinessAccount?: boolean;
};
declare type AirwallexBACSFlowParams = {
verificationMethod?: 'truelayer' | 'micro_deposit';
defaultFieldValues?: DefaultFieldValues;
// sortCode?: string;
// accountNumber?: string;
};
declare type AirwallexEFTFlowParams = {
verificationMethod?: 'plaid' | 'micro_deposit';
defaultFieldValues?: DefaultFieldValues;
isBusinessAccount?: boolean;
};
declare type AirwallexSEPAFlowParams = {
verificationMethod?: 'truelayer' | 'micro_deposit';
defaultFieldValues?: DefaultFieldValues;
};
declare type AllCallbacks = {
onFocus?: (elementId: string, field: AllFieldNames) => void;
onBlur?: (
elementId: string,
field: AllFieldNames,
extraArgs?: {
obfuscatedValue?: string;
}
) => void;
onChange?: (elementId: string, field: AllFieldNames, errors?: string[]) => void;
onLoad?: (totalAmountAtoms?: number, currency?: string) => void;
onLoadError?: (message: string) => void;
onValidationError?: OnValidationError;
onCheckoutStarted?: OnCheckoutStarted;
onCheckoutSuccess?: OnCheckoutSuccess;
onSetupPaymentMethodSuccess?: OnSetupPaymentMethodSuccess;
onCheckoutError?: OnCheckoutError;
/**
* @deprecated - use `getAvailablePaymentMethods` and `generalSubmit` instead
*/
onPaymentRequestLoad?: (paymentRequests: PRStatuses) => void;
};
declare const AllFieldNames = z.union([FieldNameEnum, PrivateFieldNameEnum]);
declare type AllFieldNames = z.infer<typeof AllFieldNames>;
/**
* Payment requests
*/
declare const Amount = z.object({
amountAtom: z.number(),
/**
* The three-letter ISO 4217 currency code for the payment.
*/
currency: RequiredString,
});
declare type Amount = z.infer<typeof Amount>;
declare type ApplePayFlowCustomParams = {
/**
* In case of multiple processors available for ApplePay, the processor setting will
* determine which processor to use.
* If `processor` is not set or is not available, the first available processor will be used
*
* **Note**: this processor choice is for the whole process of showing PaymentRequest UI, verification and charging.
* It won't perform fallback processor charging when payment failed.
*/
processor?: PaymentProcessor;
overridePaymentRequest?: {
amount?: Amount;
pending?: boolean;
label?: string;
applePayPaymentRequest?: ApplePayPaymentRequest;
};
defaultFieldValues?: DefaultFieldValues;
};
declare type ApplePayPaymentRequest =
| ((current: ApplePayJS.ApplePayPaymentRequest) => Partial<ApplePayJS.ApplePayPaymentRequest>)
| Partial<ApplePayJS.ApplePayPaymentRequest>;
/**
* Styles
*/
declare const BaseElementsStyle = z.object({
backgroundColor: OptionalString,
color: OptionalString,
fontFamily: OptionalString,
fontSize: OptionalString,
fontWeight: OptionalString,
margin: OptionalString,
padding: OptionalString,
letterSpacing: OptionalString,
lineHeight: OptionalString,
hideIcon: OptionalString,
placeholderStyle: z
.object({
color: OptionalString,
fontSize: OptionalString,
fontWeight: OptionalString,
fontFamily: OptionalString,
letterSpacing: OptionalString,
lineHeight: OptionalString,
})
.optional(),
});
declare type BaseElementsStyle = z.infer<typeof BaseElementsStyle>;
declare enum Blockchain {
EVM = 'EVM',
SOL = 'Solana',
}
declare type BlockchainNetwork = keyof typeof Blockchain;
declare const CardCvcElementStyle = BaseElementsStyle.extend({
disableAutoFill: OptionalString,
placeholder: z.string().optional(),
});
declare const CardElementStyle = BaseElementsStyle.extend({
disableAutoFill: OptionalString,
placeholder: z
.object({
cardNumber: OptionalString,
expiry: OptionalString,
cvc: OptionalString,
})
.optional(),
});
declare const CardExpiryElementStyle = BaseElementsStyle.extend({
disableAutoFill: OptionalString,
placeholder: z.string().optional(),
});
declare const CardNumberElementStyle = BaseElementsStyle.extend({
disableAutoFill: OptionalString,
placeholder: z.string().optional(),
/**
* The card icon at the start of the card number input field
* It won't affect after the icon changed to card brand after the user input the card number
*/
icon: z
.object({
color: z.string().optional(),
})
.optional(),
});
declare type CCSubmitParams = {
paymentRouteId?: string;
};
declare interface CdeConnection {
send: (data: CdeMessage) => Promise<unknown>;
tracingContext?: TracingContext;
}
declare type CdeMessage = {
type: string;
} & Record<string, unknown>;
/**
* Core models
*/
declare const CheckoutPaymentMethod = z.object({
provider: z.string(),
processor_name: nullOrUndefOr(z.string()),
metadata: nullOrUndefOr(z.record(z.string(), z.any())),
});
declare type CheckoutPaymentMethod = z.infer<typeof CheckoutPaymentMethod>;
declare type CommonSubmitSettings = {
defaultFieldValues?: DefaultFieldValues;
};
export declare type Config = ElementsFormProps & AllCallbacks;
declare type CurrentStatus<T> = InitialStatus | SuccessStatus<T> | ErrorStatus;
declare interface CustomerResponse {
/**
* The unique identifier that represents the customer
* @example "1234567890abcdef"
*/
customerId: string;
/**
* The external customer reference ID used to tie this customer to a customer in an external system.
* @example "1234567890abcdef"
*/
customerRefId: string | null;
/**
* The payment methods configured for this customer to make payments with.
*/
paymentMethods: Omit<PaymentMethodResponse, 'entityId' | 'customer' | 'dateCreated'>[];
/**
* The date the customer record was created, represented as a Unix timestamp in seconds.
* @example 1716211200
*/
dateCreated: number;
}
declare type CustomInitParams = {
// You can put custom params for your init flows here
// For stripe link
stripeLink?: {
/**
* The height of the Stripe Link button. By default, the height of the buttons are 44px.
* You can override this to specify a custom button height in the range of 40px-55px.
*
* See more: https://docs.stripe.com/js/elements_object/create_express_checkout_element#express_checkout_element_create-options-buttonHeight
*/
buttonHeight?: number;
/**
* If this function returns false, the stripe link submit process is aborted.
* This can be used for additional pre-submit checks (e.g. additional form validation).
* Note that this function must complete within 1 second, or the submission will fail.
*/
overrideLinkSubmit?: () => Promise<boolean>;
/**
* By default, the stripe link button is mounted on OJS initialization.
* If this value is true, the stripe link is not mounted on init, and should instead be manually mounted.
*/
doNotMountOnInit?: boolean;
/**
* If this value is true, the link authentication element is checked for login status silently.
*
* ⚠️ [**Warning**]: This is a workaround for checking Link authentication status without user gesture.
* Stripe don't expose API for this and it's recommended to mount the `linkAuthenticationElement` manually and check the authentication status via `.on('change')`
* You can mount the `linkAuthenticationElement` manually by calling `stripeLink.mountLinkAuthenticationElement(selector)`
*/
silentlyCheckAuthentication?: boolean;
/**
* This callback is called when the authentication status changes when `silentlyCheckAuthentication` is true,
*
* ⚠️ [**Warning**]: This is a workaround for checking authentication status without user gesture.
* This is working with current version of Stripe element (v3). This is not guaranteed to work with future versions of Stripe element.
*/
onAuthenticationStatusChange?: (isAuthenticated: boolean) => void;
/**
* This will be called once the `linkAuthenticationElement` is ready.
* This is just a wrapper for `linkAuthenticationElement.once('ready')`.
*/
onAuthenticationElementReady?: () => void;
};
// For stripe klarna
stripeKlarna?: {
/**
* Additional payment data to be passed to stripe.confirmKlarnaPayment
* This will be merged with the billing details from the form
*/
paymentData?: {
payment_method?: {
billing_details?: {
email?: string;
name?: string;
phone?: string;
address?: {
line1?: string;
line2?: string;
city?: string;
state?: string;
country?: string;
postal_code?: string;
};
};
};
return_url?: string;
setup_future_usage?: 'off_session' | 'on_session';
save_payment_method?: boolean;
};
/**
* Options to be passed to stripe.confirmKlarnaPayment
*/
options?: {
handleActions?: boolean;
};
};
googlePay?: {
env: 'demo' | 'prod';
doNotMountOnInit?: boolean;
};
applePay?: {
env: 'demo' | 'prod';
doNotMountOnInit?: boolean;
};
};
declare type CustomStyles = string;
declare type DefaultFieldValues = Partial<Record<FieldNameEnum, string>> & {
payment_method?: string | SubmitMethod; // This is not coming from checkout setting. TODO: Define a type in future if there are more attrs
show_all_prices?: boolean;
exclusive_prices?: boolean;
price_id_product_mapping?: Record<string, string>;
require_zip_code?: boolean;
require_full_billing_address?: boolean;
require_full_shipping_address?: boolean;
};
declare type ElementProps<T extends ElementType> = {
styles?: ElementsStyle<T>;
};
declare type ElementsFormProps = {
className?: string;
checkoutSecureToken: string;
baseUrl?: string;
formTarget?: string;
customInitParams?: CustomInitParams;
/**
* Whether to enable tracing. Defaults to false.
* Set to true to opt-in to tracing functionality.
*/
allowTracing?: boolean;
preventNavigationDuringSubmission?: boolean;
};
declare type ElementsStyle<T extends ElementType = ElementType> = {
card: z.infer<typeof CardElementStyle>;
'card-number': z.infer<typeof CardNumberElementStyle>;
'card-expiry': z.infer<typeof CardExpiryElementStyle>;
'card-cvc': z.infer<typeof CardCvcElementStyle>;
'cde-bridge': z.infer<typeof BaseElementsStyle>;
}[T];
export declare type ElementType = z.infer<typeof _ElementTypeEnumZod>;
export declare enum ElementTypeEnum {
CARD = 'card',
CARD_NUMBER = 'card-number',
CARD_EXPIRY = 'card-expiry',
CARD_CVC = 'card-cvc',
CDE_BRIDGE = 'cde-bridge',
}
declare const _ElementTypeEnumZod = z.enum(['card', 'card-number', 'card-expiry', 'card-cvc', 'cde-bridge']);
declare enum Environment {
Local = 'local',
Development = 'development',
Staging = 'staging',
Demo = 'demo',
Production = 'production',
}
declare type ErrorStatus = {
status: 'error';
isSuccess: false;
error: unknown; // Anything can be thrown, so we don't want to be strict here
errMsg: string;
};
/**
* Expected input fields
*/
// Supplied by the user
export declare enum FieldName {
FIRST_NAME = 'firstName',
LAST_NAME = 'lastName',
PHONE = 'phone',
EMAIL = 'email',
LINE1 = 'line1',
LINE2 = 'line2',
LINE3 = 'line3',
CITY = 'city',
STATE = 'state',
COUNTRY = 'country',
ZIP_CODE = 'zipCode',
SHIPPING_LINE1 = 'shippingAddressLine1',
SHIPPING_LINE2 = 'shippingAddressLine2',
SHIPPING_LINE3 = 'shippingAddressLine3',
SHIPPING_CITY = 'shippingAddressCity',
SHIPPING_STATE = 'shippingAddressState',
SHIPPING_COUNTRY = 'shippingAddressCountry',
SHIPPING_ZIP_CODE = 'shippingAddressZipCode',
IS_SHIPPING_SAME_AS_BILLING = 'isShippingSameAsBilling',
PROMOTION_CODE = 'promotionCode',
IS_BUSINESS_PURCHASE = 'isBusinessPurchase',
BUSINESS_NAME = 'businessName',
TAX_ID = 'taxId',
TAX_ID_TYPE = 'taxIdType',
}
declare const FieldNameEnum = z.nativeEnum(FieldName);
declare type FieldNameEnum = z.infer<typeof FieldNameEnum>;
declare class FormCallbacks {
private static readonly NOOP = () => {};
private _callbacks: Required<AllCallbacks>;
constructor() {
this._callbacks = FormCallbacks.createEmptyCallbacks();
}
private static createEmptyCallbacks = (): Required<AllCallbacks> => {
const x: AllCallbacks = {};
Object.keys(ZodFormCallbacks.keyof().enum).forEach((key) => {
// @ts-expect-error - trust the process
x[key] = FormCallbacks.NOOP;
});
return x as Required<AllCallbacks>;
};
static fromObject = (obj: unknown) => {
const instance = new FormCallbacks();
instance.setCallbacks(ZodFormCallbacks.parse(obj));
return instance;
};
/**
* Sets ALL form callbacks. Note that all old callbacks are removed.
*/
setCallbacks = (rawCallbacks: AllCallbacks) => {
// Making sure to reinitialize
this._callbacks = FormCallbacks.createEmptyCallbacks();
Object.entries(rawCallbacks).forEach(([key, rawCallback]) => {
const safeCallback = makeCallbackSafe(key, rawCallback ?? FormCallbacks.NOOP, err__);
// @ts-expect-error - trust the process
this._callbacks[key] = safeCallback;
});
};
/**
* Returns a read-only version of the callbacks object.
*/
get get() {
return { ...this._callbacks };
}
}
declare type GeneralSubmit = typeof _generalSubmit;
declare const _generalSubmit = async <T extends SubmitMethod>(method: T, settings?: SubmitSettings<T>) => {
console.log('generalSubmit', method, settings);
};
declare type GooglePayFlowCustomParams = {
/**
* In case of multiple processors available for GooglePay, the processor setting will
* determine which processor to use.
* If `processor` is not set or is not available, the first available processor will be used
*
* **Note**: this processor choice is for the whole process of showing PaymentRequest UI, verification and charging.
* It won't perform fallback processor charging when payment failed.
*/
processor?: PaymentProcessor;
overridePaymentRequest?: {
amount?: Amount;
pending?: boolean;
label?: string;
googlePayPaymentRequest?: GooglePayPaymentRequest;
};
defaultFieldValues?: DefaultFieldValues;
};
declare type GooglePayPaymentRequest =
| ((current: PaymentDataRequest) => Partial<PaymentDataRequest>)
| Partial<PaymentDataRequest>;
declare type InitApplePayFlowResult = {
processor: PaymentProcessor;
isAvailable: boolean;
isLoading: boolean;
startFlow: (customParams?: ApplePayFlowCustomParams) => Promise<void>;
};
declare interface InitFailedEvent {
type: 'initFailed';
message: string;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
data: Record<string, any>;
}
declare type InitGooglePayFlowResult = {
processor: PaymentProcessor;
isAvailable: boolean;
isLoading: boolean;
startFlow: (customParams?: GooglePayFlowCustomParams) => Promise<void>;
};
declare interface InitializedEvent {
entityId: string;
}
declare type InitialStatus = {
status: 'initial';
isSuccess: false;
};
declare type InitLoopCryptoFlowSuccess =
| {
isAvailable: true;
widgetProps: LoopCryptoWidgetProps;
initLoopConnectProps: LoopConnectConfig;
}
| {
isAvailable: false;
};
declare type InitOjsFlow<T extends InitOjsFlowResult> = (params: InitOjsFlowParams) => Promise<T>;
declare type InitOjsFlowParams = {
/**
* Contains the context where OJS is run.
* Ideally this only contains "background" context (OJS-level objects), and not flow-level objects.
*/
context: OjsContext;
/**
* Lifecycle callbacks for OJS flows.
*/
formCallbacks: FormCallbacks;
};
declare type InitOjsFlowResult = {
isAvailable: boolean;
};
declare type InitStripeAffirmFlowResult = {
isAvailable: boolean;
startFlow: (customParams?: AffirmFlowCustomParams) => Promise<void>;
};
declare type InitStripeAfterpayFlowResult = {
isAvailable: boolean;
startFlow: (customParams?: AfterpayFlowCustomParams) => Promise<void>;
};
declare type InitStripeKlarnaFlowResult = {
isAvailable: boolean;
startFlow: (customParams?: KlarnaFlowCustomParams) => Promise<void>;
};
declare type InitStripeLinkFlowResult =
| {
isAvailable: true;
controller: StripeLinkController;
}
| {
isAvailable: false;
};
declare type InitStripePrFlowResult =
| InitStripePrFlowSuccess
| {
isAvailable: false;
reason: string;
};
declare type InitStripePrFlowSuccess = {
processor: 'stripe';
isAvailable: true;
// Passed to RunFlow
pr: PaymentRequest_2;
// Passed to the user
availableProviders: {
applePay: boolean;
googlePay: boolean;
};
startFlow: (provider: PaymentRequestProvider, params?: PaymentRequestStartParams) => Promise<void>;
};
declare type KlarnaFlowCustomParams = {
/**
* In case of multiple processors available for Klarna, the processor setting will
* determine which processor to use.
* If `processor` is not set or is not available, the first available processor will be used
*
* **Note**: this processor choice is for the whole process of showing payment UI, verification and charging.
* It won't perform fallback processor charging when payment failed.
*/
processor?: PaymentProcessor;
isAnonymous?: boolean;
useRedirectFlow?: boolean;
};
declare const LoadedEventPayload = z.object({
type: z.literal(EventType.enum.LOADED),
sessionId: RequiredString,
totalAmountAtoms: z.number(),
currency: OptionalString,
checkoutPaymentMethods: z.array(CheckoutPaymentMethod),
});
declare type LoadedEventPayload = z.infer<typeof LoadedEventPayload>;
declare class LoadedOncePublisher<T> {
private _current: CurrentStatus<T>;
private _subject: Subject<T>;
constructor() {
this._current = { status: 'initial', isSuccess: false };
this._subject = new Subject<T>();
}
set = (value: T) => {
if (this._current.status === 'success') {
throw new Error('LoadedOnce is already in success state');
}
this._current = { status: 'success', isSuccess: true, loadedValue: value };
this._subject.next(value);
this._subject.complete();
};
throw = (error: unknown, errMsg: string) => {
if (this._current.status === 'success') {
throw new Error('LoadedOnce is already in success state');
}
this._current = { status: 'error', isSuccess: false, error, errMsg };
this._subject.error(error);
// Do not complete the subject since a set() call might be made after this
};
get current() {
return this._current;
}
getValueIfLoadedElse = <T_ELSE>(valueIfNotLoaded: T_ELSE): T | T_ELSE => {
if (this._current.status === 'success') return this._current.loadedValue;
return valueIfNotLoaded;
};
subscribe = (fn: (value: Exclude<CurrentStatus<T>, InitialStatus>) => void) => {
if (this._current.status === 'success') {
fn(this._current);
return;
}
if (this._current.status === 'error') {
fn(this._current);
// Do not return, as we will still have the fn subscribed to the subject
}
const subscription = this._subject.subscribe({
next: () => {
if (this._current.status !== 'success') {
throw new Error('Invalid state (next): please make sure to update _current before the subject');
}
fn(this._current);
subscription.unsubscribe();
},
error: () => {
if (this._current.status !== 'error') {
throw new Error('Invalid state (error): please make sure to update _current before the subject');
}
fn(this._current);
// Do not unsubscribe
},
});
};
waitForLoad = (timeoutConfig: { timeoutSec: number; timeoutErrMsg: string }): Promise<T> => {
if (this._current.status === 'success') return Promise.resolve(this._current.loadedValue);
if (this._current.status === 'error') return Promise.reject(this._current.error);
if (this._current.status !== 'initial') assertNever(this._current);
const timeoutParams = {
first: timeoutConfig.timeoutSec * 1000,
with: () => throwError(() => new Error(timeoutConfig.timeoutErrMsg)),
};
/*
* Note: lastValueFrom converts the observable to a promise (https://rxjs.dev/api/index/function/lastValueFrom)
*
* We use lastValueFrom to wait for the observable to close successfully before resolving the Promise.
* To avoid hanging threads forever, we use timeoutParams to throw an error if it takes too long.
* firstValueFrom is theoretically also usable, but it might result in bugs
* if we do decide to emit more values in this Observable/Subject in the future.
*
* For more details, see: https://rxjs.dev/deprecations/to-promise
*/
return lastValueFrom(this._subject.pipe(timeout(timeoutParams)));
};
}
declare interface LoopConnectConfig {
apiToken: string;
entityId: string;
merchantId?: string;
environment?: Environment | `${Environment}`;
customStyles?: CustomStyles;
onInitialized?: (detail: InitializedEvent) => void;
onInitFailed?: (detail: InitFailedEvent) => void;
onWalletChange?: (detail: WalletChangeEvent) => void;
onNetworkChange?: (detail: NetworkChangeEvent) => void;
}
declare type LoopCryptoFlowCustomParams =
| {
customer: Omit<CustomerResponse, 'paymentMethods' | 'merchants' | 'dateCreated'>;
paymentMethod: Omit<PaymentMethodResponse, 'customer' | 'dateCreated'>;
mode: 'setup' | 'payment' | 'subscription';
success: true;
payinId?: string;
}
| {
failureDetails: PayInFailedEvent;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
debugInfo?: Record<string, any>;
success: false;
}
| undefined;
declare type LoopCryptoWidgetProps = {
paymentUsdAmount: number;
suggestedAuthorizationUsdAmount: number;
minAuthorizationUsdAmount: number;
subscriptionRefId?: string;
customerRefId?: string;
invoiceRefId?: string;
allowCustomerToChooseAuth?: boolean;
};
declare interface NetworkChangeEvent {
id: number;
name: string;
chain: BlockchainNetwork;
}
declare type OjsContext = {
/**
* The secure token for the checkout session.
*/
checkoutSecureToken: string;
/**
* The form element for the OJS form (non-CDE form).
*/
formDiv: HTMLElement;
/**
* The elements/partial session ID.
*/
elementsSessionId: string;
/**
* All the checkout payment methods available in the session.
*/
checkoutPaymentMethods: CheckoutPaymentMethod[];
/**
* All the CDE connection objects (one for each CDE iframe).
*/
anyCdeConnection: CdeConnection;
/**
* Custom init params for init flows.
*/
customInitParams: CustomInitParams;
/**
* The base URL of the CDE iframe.
*/
baseUrl: string;
/**
* Whether to prevent navigation during submission.
*/
preventNavigationDuringSubmission?: boolean;
};
declare type OjsFlow<T_PARAMS = unknown, T_INIT_RESULT extends InitOjsFlowResult = InitOjsFlowResult> = {
init?: InitOjsFlow<T_INIT_RESULT>;
run: RunOjsFlow<T_PARAMS, T_INIT_RESULT>;
};
declare type OjsFlowParams<T_PARAMS = void, T_INIT_RESULT = void> = {
/**
* Contains the context where OJS is run.
* Ideally this only contains "background" context (OJS-level objects), and not flow-level objects.
*/
context: OjsContext;
/**
* The checkout payment method object to be used for the flow.
*/
checkoutPaymentMethod: CheckoutPaymentMethod;
/**
* Inputs from non-CDE fields (i.e. those which are part of the OJS form, but not the sensitive CDE form).
*/
nonCdeFormInputs: Record<string, unknown>;
/**
* Form callbacks. Take note that these can be dynamically updated (but the object remains)
*/
formCallbacks: FormCallbacks;
/**
* Custom parameters for the flow.
*/
customParams: T_PARAMS;
/**
* The result of the InitOjsFlow function.
*/
initResult: T_INIT_RESULT;
};
declare const OjsFlows = {
// ✋ Note: For flows that require initialization, please add them to `init-flows.ts`
// Common
commonCC: {
init: async () => {},
run: runCommonCcFlow,
},
// Stripe
stripePR: {
init: initStripePrFlow,
run: runStripePrFlow,
},
stripeLink: {
init: initStripeLinkFlow,
run: runStripeLinkFlow,
},
stripeKlarna: {
init: initStripeKlarnaFlow,
run: runStripeKlarnaFlow,
},
stripeAffirm: {
init: initStripeAffirmFlow,
run: runStripeAffirmFlow,
},
stripeAfterpay: {
init: initStripeAfterpayFlow,
run: runStripeAfterpayFlow,
},
// Pockyt
pockytPaypal: {
init: initPockytPaypalFlow,
run: runPockytPaypalFlow,
},
// PayPal
paypal: {
init: initPaypalFlow,
run: runPaypalFlow,
},
// Klarna
airwallexKlarna: {
init: initAirwallexKlarnaFlow,
run: runAirwallexKlarnaFlow,
},
// Airwallex
airwallexGooglePay: {
init: initAirwallexGooglePayFlow,
run: runAirwallexGooglePayFlow,
},
airwallexApplePay: {
init: initAirwallexApplePayFlow,
run: runAirwallexApplePayFlow,
},
airwallexACH: {
init: async () => {},
run: runAirwallexACHFlow,
},
airwallexEFT: {
init: async () => {},
run: runAirwallexEFTFlow,
},
airwallexBACS: {
init: async () => {},
run: runAirwallexBACSFlow,
},
airwallexSEPA: {
init: async () => {},
run: runAirwallexSEPAFlow,
},
// Loop
loopCrypto: {
init: initLoopFlow,
run: runLoopFlow,
},
authorizeNetApplePay: {
init: initAuthnetApplePayFlow,
run: runAuthnetApplePayFlow,
},
authorizeNetGooglePay: {
init: initAuthnetGooglePayFlow,
run: runAuthnetGooglePayFlow,
},
adyenGooglePay: {
init: initAdyenGooglePayFlow,
run: runAdyenGooglePayFlow,
},
adyenApplePay: {
init: initAdyenApplePayFlow,
run: runAdyenApplePayFlow,
},
// 👉 Add more flows here
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} satisfies Record<string, OjsFlow<any, any>>;
declare type OnCheckoutError = (message: string, errorCode?: string) => void;
declare type OnCheckoutStarted = () => void;
declare type OnCheckoutSuccess = (
invoiceUrls: string[],
subscriptionIds: string[],
customerId: string,
processorsUsed: string[],
paymentMethodId: string
) => void;
declare type OnSetupPaymentMethodSuccess = (paymentMethodId: string) => void;
declare type OnValidationError = (field: AllFieldNames, errors: string[], elementId?: string) => void;
export declare class OpenPayForm {
readonly config: Config;
readonly formId: string;
readonly formTarget: string;
readonly ojsVersion: string;
readonly ojsReleaseVersion: string;
readonly formProperties: {
height: string;
};
readonly referrer: string;
readonly baseUrl: string;
readonly formCallbacks: FormCallbacks;
private registeredElements;
private isDestroyed;
private eventHandler;
private connectionManager;
static ojsFlows: typeof OjsFlows;
private readonly cdeLoadEvent;
private readonly anyCdeConn;
private readonly context;
readonly initFlows: {
readonly stripePR: {
publisher: LoadedOncePublisher<InitStripePrFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly stripeLink: {
publisher: LoadedOncePublisher<InitStripeLinkFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly stripeKlarna: {
publisher: LoadedOncePublisher<InitStripeKlarnaFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly stripeAffirm: {
publisher: LoadedOncePublisher<InitStripeAffirmFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly stripeAfterpay: {
publisher: LoadedOncePublisher<InitStripeAfterpayFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly airwallexGooglePay: {
publisher: LoadedOncePublisher<InitGooglePayFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly airwallexApplePay: {
publisher: LoadedOncePublisher<InitApplePayFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly loop: {
publisher: LoadedOncePublisher<InitLoopCryptoFlowSuccess>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly paypal: {
publisher: LoadedOncePublisher<{
isLoading: boolean;
isAvailable: boolean;
startFlow: () => Promise<void>;
}>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly airwallexKlarna: {
publisher: LoadedOncePublisher<{
isLoading: boolean;
isAvailable: boolean;
startFlow: (customParams?: KlarnaFlowCustomParams) => Promise<void>;
}>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly pockytPaypal: {
publisher: LoadedOncePublisher<{
isLoading: boolean;
isAvailable: boolean;
startFlow: () => Promise<void>;
}>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly authorizeNetGooglePay: {
publisher: LoadedOncePublisher<InitGooglePayFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly authorizeNetApplePay: {
publisher: LoadedOncePublisher<InitApplePayFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly adyenGooglePay: {
publisher: LoadedOncePublisher<InitGooglePayFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
readonly adyenApplePay: {
publisher: LoadedOncePublisher<InitApplePayFlowResult>;
initialize: (initParams: InitOjsFlowParams) => Promise<void>;
};
};
private deviceToken;
private isSubmitting;
constructor(config: Config);
/**
* Starts the form initialization process
*/
private startFormInit;
/**
* Assign the instance to the window as a singleton
*/
private static assignAsSingleton;
/**
* Get the singleton instance of OpenPayForm
*/
static getInstance: () => OpenPayForm | null;
get checkoutSecureToken(): string;
setFormHeight: (height: string) => void;
onCdeLoaded: (payload: LoadedEventPayload) => void;
onCdeLoadError: (errMsg: string) => void;
createElement: <T extends ElementType>(elementType: T, options?: ElementProps<T>) => RegisteredElement;
registerIframe: (type: ElementType, frame: HTMLIFrameElement) => RegisteredElement;
private buildQueryString;
private connectToElement;
private getFormDiv;
/**
* Builds the OJS context object. Take note that this is a pure function.
*/
private static buildOjsFlowContext;
/**
* Runs the common credit card flow
*/
submitCard: (params?: CCSubmitParams) => Promise<void>;
private checkValidFormInstance;
getAvailablePaymentMethods: () => Promise<{
name: SubmitMethods;
processors: PaymentProcessor[];
isAvailable: boolean;
controller?: unknown;
}[]>;
/**
* @deprecated
* We're normalizing the submit method to be the same in both React and Vanilla versions.
* Please use `submitWith` instead.
*/
generalSubmit: GeneralSubmit;
submitWith: GeneralSubmit;
/**
* Alias for submitCard
*/
submit: (params?: CCSubmitParams) => Promise<void>;
destroy: () => void;
/**
* Updates form callbacks after initialization
*/
updateCallbacks: (newCallbacks: AllCallbacks) => void;
}
declare enum PayInFailed {
// Create payment method
METHOD_CREATION_FAILED = 'methodCreationFailed',
INSUFFICIENT_BALANCE = 'insufficientBalance',
INSUFFICIENT_AUTHORIZATION = 'insufficientAuthorization',
SIGNED_MESSAGE_REQUIRED = 'signedMessageRequired',
CUSTOMER_CREATION_FAILED = 'customerCreationFailed',
// Create pay-in
PAYMENT_FAILED = 'paymentFailed',
TRANSACTION_FAILED = 'transactionFailed',
}
declare interface PayInFailedData {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
error: Record<string, any> | undefined;
}
declare interface PayInFailedEvent {
type: PayInFailed;
message: string;
data: PayInFailedData;
}
declare type PaymentDataRequest = google.payments.api.PaymentDataRequest;
declare interface PaymentMethodPreAuthorization {
/**
* The balance of the payment method formatted in the token amount
* @example "100"
*/
balance: string;
/**
* The authorization amount of the payment method formatted in the token amount
* @example "49.9"
*/
authorization: string;
}
declare interface PaymentMethodResponse {
/**
* The unique identifier for the payment method
* @example "1234567890abcdef"
*/
paymentMethodId: string;
/**
* The unique identifier of the merchant this payment method is associated with
* @example "67e55044-10b1-426f-9247-bb680e5fe0c8"
*/
merchantId: string;
/**
* The name of the payment method
* @example "My Crypto Wallet"
*/
paymentMethodName: string;
/**
* The customers that are associated with the payment method
*/
customer: Omit<CustomerResponse, 'paymentMethods' | 'merchants' | 'dateCreated'>;
/**
* The blockchain network ID the payment method is associated with
* @example 1
*/
networkId: number;
/**
* The blockchain wallet address where payments will be sent from
* @example "0x1234567890abcdef"
*/
walletAddress: string;
/**
* Whether the payment method is the default payment method for wallet address
* @example true
*/
isDefault: boolean;
/**
* The token associated with the payment method
*/
token: PaymentMethodToken;
/**
* The status of the payment method, including the wallet's balance and authorization status
*/
preAuthorization: PaymentMethodPreAuthorization | null;
/**
* The date the payment method record was created, represented as a Unix timestamp in seconds.
* @example 1716211200
*/
dateCreated: number;
}
declare interface PaymentMethodToken extends Omit<TokenResponse, 'networkId'> {
/**
* The exchange rate of the token
*/
exchangeRates: PaymentMethodTokenExchangeRate[];
}
declare interface PaymentMethodTokenExchangeRate {
/**
* The currency code. Only "USD" is supported at this time.
* @example "USD"
*/
currency: string;
/**
* The price of the token in the specified currency code. Accurate to 4 decimal places, e.g. a price of "1.9900" represents $1.99
* @example "10000"
*/
price: string;
/**
* The Unix timestamp (in seconds) when this exchange rate was last updated
* @example 1715731200
*/
timestamp: number;
}
declare const PaymentProcessor = z.enum(['stripe', 'airwallex', 'authorize_net', 'adyen', 'paypal', 'pockyt', 'loop']);
declare type PaymentProcessor = z.infer<typeof PaymentProcessor>;
declare const PaymentRequestProvider = z.enum(['apple_pay', 'google_pay']);
declare type PaymentRequestProvider = z.infer<typeof PaymentRequestProvider>;
declare type PaymentRequestStartParams = {
overridePaymentRequest?: {
amount?: Amount;
pending?: boolean;
label?: string;
applePayPaymentRequest?: ApplePayPaymentRequest;
};
};
declare type PaymentRequestStatus = {
isLoading: boolean;
isAvailable: boolean;
startFlow: (params?: PaymentRequestStartParams) => Promise<void>;
};
declare type PaypalFlowCustomParams = {
isAnonymous?: boolean;
useRedirectFlow?: boolean;
};
declare type ProcessorSpecificSubmitSettings<T extends SubmitMethod = SubmitMethod> = {
[SubmitMethods.card]: CCSubmitParams;
[SubmitMethods.pockytPaypal]: { useRedirectFlow?: boolean };
[SubmitMethods.applePay]: ApplePayFlowCustomParams;
[SubmitMethods.googlePay]: GooglePayFlowCustomParams;
[SubmitMethods.loopCrypto]: LoopCryptoFlowCustomParams;
[SubmitMethods.paypal]: PaypalFlowCustomParams;
[SubmitMethods.klarna]: KlarnaFlowCustomParams;
[SubmitMethods.affirm]: AffirmFlowCustomParams;
[SubmitMethods.afterpay]: AfterpayFlowCustomParams;
[SubmitMethods.stripeLink]: unknown;
// TODO: The following methods are deprecated and will be removed in the future.
// Use googlePay/applePay instead
[SubmitMethods.airwallexGooglePay]: GooglePayFlowCustomParams;
[SubmitMethods.airwallexApplePay]: ApplePayFlowCustomParams;
[SubmitMethods.authorizenetGooglePay]: GooglePayFlowCustomParams;
[SubmitMethods.authorizenetApplePay]: ApplePayFlowCustomParams;
[SubmitMethods.adyenGooglePay]: GooglePayFlowCustomParams;
[SubmitMethods.adyenApplePay]: ApplePayFlowCustomParams;
[SubmitMethods.airwallexACH]: AirwallexACHFlowParams;
[SubmitMethods.airwallexEFT]: AirwallexEFTFlowParams;
[SubmitMethods.airwallexBACS]: AirwallexBACSFlowParams;
[SubmitMethods.airwallexSEPA]: AirwallexSEPAFlowParams;
}[T];
declare type PRStatuses = Record<PaymentRequestProvider, PaymentRequestStatus>;
declare type RegisteredElement = {
type: ElementType;
node: HTMLIFrameElement;
mount: (selector: string) => void;
};
declare type RunOjsFlow<T_PARAMS = undefined, T_INIT_RESULT = undefined> = (
params: OjsFlowParams<T_PARAMS, T_INIT_RESULT>
) => Promise<void>;
export declare type StripeLinkController = {
mountButton: (selector?: string) => void;
dismountButton: () => void;
waitForButtonToMount: () => Promise<HTMLElement>;
mountLinkAuthenticationElement: (selector: string) => StripeLinkAuthenticationElement;
};
declare const SubmitMethod = z.nativeEnum(SubmitMethods);
declare type SubmitMethod = z.infer<typeof SubmitMethod>;
export declare enum SubmitMethods {
card = 'card',
pockytPaypal = 'pockyt-paypal',
applePay = 'apple-pay',
googlePay = 'google-pay',
loopCrypto = 'loop-crypto',
paypal = 'paypal',
klarna = 'klarna',
affirm = 'affirm',
afterpay = 'afterpay',
/**
* This submit method only for Available payment methods.
* Manual submission for StripeLink is not available
*/
stripeLink = 'stripe-link',
// TODO: The following methods are deprecated and will be removed in the future.
/**
* @deprecated Use googlePay instead
*/
airwallexGooglePay = 'airwallex-google-pay',
/**
* @deprecated Use applePay instead
*/
airwallexApplePay = 'airwallex-apple-pay',
/**
* @deprecated Use googlePay instead
*/
authorizenetGooglePay = 'authorizenet-google-pay',
/**
* @deprecated Use applePay instead
*/
authorizenetApplePay = 'authorizenet-apple-pay',
/**
* @deprecated Use googlePay instead
*/
adyenGooglePay = 'adyen-google-pay',
/**
* @deprecated Use applePay instead
*/
adyenApplePay = 'adyen-apple-pay',
// DD
airwallexACH = 'airwallex-ach',
airwallexEFT = 'airwallex-eft',
airwallexBACS = 'airwallex-bacs',
airwallexSEPA = 'airwallex-sepa',
}
export declare type SubmitSettings<T extends SubmitMethod = SubmitMethod> = ProcessorSpecificSubmitSettings<T> &
CommonSubmitSettings;
declare type SuccessStatus<T> = {
status: 'success';
isSuccess: true;
loadedValue: T;
};
declare interface TokenResponse {
/**
* The unique identifier for the token used by the payment type.
* @example "123e4567-e89b-12d3-a456-426614174000"
*/
tokenId: string;
/**
* The blockchain network ID the token is associated with
* @example 1
*/
networkId: number;
/**
* The token symbol that identifies the token on the blockchain network
* @example "USDC"
*/
symbol: string;
/**
* The token contract address for the payment type
* @example "0x1234567890abcdef"
*/
address: string;
/**
* The number of decimal places used to represent token amounts
* @example 6
*/
decimals: number;
}
declare type TracingContext = {
checkoutSecureToken?: string;
deviceToken?: string;
formId?: string;
version?: string;
releaseVersion?: string;
baseUrl?: string;
referrer?: string;
};
declare interface WalletChangeEvent {
address: string;
ens: string | undefined;
}
export { }