import { ConfigArg, RefundOrderInput } from '@vendure/common/lib/generated-types'; import { RequestContext } from '../../api/common/request-context'; import { ConfigArgs, ConfigArgValues, ConfigurableOperationDef, ConfigurableOperationDefOptions } from '../../common/configurable-operation'; import { OnTransitionStartFn, StateMachineConfig } from '../../common/finite-state-machine/types'; import { PaymentMetadata } from '../../common/types/common-types'; import { Order, Payment, PaymentMethod } from '../../entity'; import { PaymentState, PaymentTransitionData } from '../../service/helpers/payment-state-machine/payment-state'; import { RefundState } from '../../service/helpers/refund-state-machine/refund-state'; export type OnPaymentTransitionStartReturnType = ReturnType>['onTransitionStart']>; /** * @description * This object is the return value of the {@link CreatePaymentFn}. * * @docsCategory payment * @docsPage Payment Method Types */ export interface CreatePaymentResult { /** * @description * The amount (as an integer - i.e. $10 = `1000`) that this payment is for. * Typically this should equal the Order total, unless multiple payment methods * are being used for the order. */ amount: number; /** * @description * The {@link PaymentState} of the resulting Payment. * * In a single-step payment flow, this should be set to `'Settled'`. * In a two-step flow, this should be set to `'Authorized'`. * * If using a {@link PaymentProcess}, may be something else * entirely according to your business logic. */ state: Exclude; /** * @description * The unique payment reference code typically assigned by * the payment provider. */ transactionId?: string; /** * @description * If the payment is declined or fails for ome other reason, pass the * relevant error message here, and it gets returned with the * ErrorResponse of the `addPaymentToOrder` mutation. */ errorMessage?: string; /** * @description * This field can be used to store other relevant data which is often * provided by the payment provider, such as security data related to * the payment method or data used in troubleshooting or debugging. * * Any data stored in the optional `public` property will be available * via the Shop API. This is useful for certain checkout flows such as * external gateways, where the payment provider returns a unique * url which must then be passed to the storefront app. */ metadata?: PaymentMetadata; } /** * @description * This object is the return value of the {@link CreatePaymentFn} when there has been an error. * * @docsCategory payment * @docsPage Payment Method Types */ export interface CreatePaymentErrorResult { amount: number; state: 'Error'; transactionId?: string; errorMessage: string; metadata?: PaymentMetadata; } /** * @description * This object is the return value of the {@link CreateRefundFn}. * * @docsCategory payment * @docsPage Payment Method Types */ export interface CreateRefundResult { state: RefundState; transactionId?: string; metadata?: PaymentMetadata; } /** * @description * This object is the return value of the {@link SettlePaymentFn} when the Payment * has been successfully settled. * * @docsCategory payment * @docsPage Payment Method Types */ export interface SettlePaymentResult { success: true; metadata?: PaymentMetadata; } /** * @description * This object is the return value of the {@link SettlePaymentFn} when the Payment * could not be settled. * * @docsCategory payment * @docsPage Payment Method Types */ export interface SettlePaymentErrorResult { success: false; /** * @description * The state to transition this Payment to upon unsuccessful settlement. * Defaults to `Error`. Note that if using a different state, it must be * legal to transition to that state from the `Authorized` state according * to the PaymentState config (which can be customized using the * {@link PaymentProcess}). */ state?: Exclude; /** * @description * The message that will be returned when attempting to settle the payment, and will * also be persisted as `Payment.errorMessage`. */ errorMessage?: string; metadata?: PaymentMetadata; } /** * @description * This object is the return value of the {@link CancelPaymentFn} when the Payment * has been successfully cancelled. * * @docsCategory payment * @docsPage Payment Method Types */ export interface CancelPaymentResult { success: true; metadata?: PaymentMetadata; } /** * @description * This object is the return value of the {@link CancelPaymentFn} when the Payment * could not be cancelled. * * @docsCategory payment * @docsPage Payment Method Types */ export interface CancelPaymentErrorResult { success: false; /** * @description * The state to transition this Payment to upon unsuccessful cancellation. * Defaults to `Error`. Note that if using a different state, it must be * legal to transition to that state from the `Authorized` state according * to the PaymentState config (which can be customized using the * {@link PaymentProcess}). */ state?: Exclude; /** * @description * The message that will be returned when attempting to cancel the payment, and will * also be persisted as `Payment.errorMessage`. */ errorMessage?: string; metadata?: PaymentMetadata; } /** * @description * This function contains the logic for creating a payment. See {@link PaymentMethodHandler} for an example. * * Returns a {@link CreatePaymentResult}. * * @docsCategory payment * @docsPage Payment Method Types */ export type CreatePaymentFn = (ctx: RequestContext, order: Order, amount: number, args: ConfigArgValues, metadata: PaymentMetadata, method: PaymentMethod) => CreatePaymentResult | CreatePaymentErrorResult | Promise; /** * @description * This function contains the logic for settling a payment. See {@link PaymentMethodHandler} for an example. * * @docsCategory payment * @docsPage Payment Method Types */ export type SettlePaymentFn = (ctx: RequestContext, order: Order, payment: Payment, args: ConfigArgValues, method: PaymentMethod) => SettlePaymentResult | SettlePaymentErrorResult | Promise; /** * @description * This function contains the logic for cancelling a payment. See {@link PaymentMethodHandler} for an example. * * @docsCategory payment * @docsPage Payment Method Types */ export type CancelPaymentFn = (ctx: RequestContext, order: Order, payment: Payment, args: ConfigArgValues, method: PaymentMethod) => CancelPaymentResult | CancelPaymentErrorResult | Promise; /** * @description * This function contains the logic for creating a refund. See {@link PaymentMethodHandler} for an example. * * @docsCategory payment * @docsPage Payment Method Types */ export type CreateRefundFn = (ctx: RequestContext, input: RefundOrderInput, amount: number, order: Order, payment: Payment, args: ConfigArgValues, method: PaymentMethod) => CreateRefundResult | Promise; /** * @description * Defines the object which is used to construct the {@link PaymentMethodHandler}. * * @docsCategory payment */ export interface PaymentMethodConfigOptions extends ConfigurableOperationDefOptions { /** * @description * This function provides the logic for creating a payment. For example, * it may call out to a third-party service with the data and should return a * {@link CreatePaymentResult} object contains the details of the payment. */ createPayment: CreatePaymentFn; /** * @description * This function provides the logic for settling a payment, also known as "capturing". * For payment integrations that settle/capture the payment on creation (i.e. the * `createPayment()` method returns with a state of `'Settled'`) this method * need only return `{ success: true }`. */ settlePayment: SettlePaymentFn; /** * @description * This function provides the logic for cancelling a payment, which would be invoked when a call is * made to the `cancelPayment` mutation in the Admin API. Cancelling a payment can apply * if, for example, you have created a "payment intent" with the payment provider but not yet * completed the payment. It allows the incomplete payment to be cleaned up on the provider's end * if it gets cancelled via Vendure. * * @since 1.7.0 */ cancelPayment?: CancelPaymentFn; /** * @description * This function provides the logic for refunding a payment created with this * payment method. Some payment providers may not provide the facility to * programmatically create a refund. In such a case, this method should be * omitted and any Refunds will have to be settled manually by an administrator. */ createRefund?: CreateRefundFn; /** * @description * This function, when specified, will be invoked before any transition from one {@link PaymentState} to another. * The return value (a sync / async `boolean`) is used to determine whether the transition is permitted. */ onStateTransitionStart?: OnTransitionStartFn; } /** * @description * A PaymentMethodHandler contains the code which is used to generate a Payment when a call to the * `addPaymentToOrder` mutation is made. It contains any necessary steps of interfacing with a * third-party payment gateway before the Payment is created and can also define actions to fire * when the state of the payment is changed. * * PaymentMethodHandlers are instantiated using a {@link PaymentMethodConfigOptions} object, which * configures the business logic used to create, settle and refund payments. * * @example * ```ts * import { PaymentMethodHandler, CreatePaymentResult, SettlePaymentResult, LanguageCode } from '\@vendure/core'; * // A mock 3rd-party payment SDK * import gripeSDK from 'gripe'; * * export const examplePaymentHandler = new PaymentMethodHandler({ * code: 'example-payment-provider', * description: [{ * languageCode: LanguageCode.en, * value: 'Example Payment Provider', * }], * args: { * apiKey: { type: 'string' }, * }, * createPayment: async (ctx, order, amount, args, metadata): Promise => { * try { * const result = await gripeSDK.charges.create({ * amount, * apiKey: args.apiKey, * source: metadata.authToken, * }); * return { * amount: order.total, * state: 'Settled' as const, * transactionId: result.id.toString(), * metadata: result.outcome, * }; * } catch (err: any) { * return { * amount: order.total, * state: 'Declined' as const, * metadata: { * errorMessage: err.message, * }, * }; * } * }, * settlePayment: async (ctx, order, payment, args): Promise => { * return { success: true }; * } * }); * ``` * * @docsCategory payment */ export declare class PaymentMethodHandler extends ConfigurableOperationDef { private readonly createPaymentFn; private readonly settlePaymentFn; private readonly cancelPaymentFn?; private readonly createRefundFn?; private readonly onTransitionStartFn?; constructor(config: PaymentMethodConfigOptions); /** * @description * Called internally to create a new Payment * * @internal */ createPayment(ctx: RequestContext, order: Order, amount: number, args: ConfigArg[], metadata: PaymentMetadata, method: PaymentMethod): Promise<{ /** * @description * The amount (as an integer - i.e. $10 = `1000`) that this payment is for. * Typically this should equal the Order total, unless multiple payment methods * are being used for the order. */ amount: number; /** * @description * The {@link PaymentState} of the resulting Payment. * * In a single-step payment flow, this should be set to `'Settled'`. * In a two-step flow, this should be set to `'Authorized'`. * * If using a {@link PaymentProcess}, may be something else * entirely according to your business logic. */ state: Exclude; /** * @description * The unique payment reference code typically assigned by * the payment provider. */ transactionId?: string; /** * @description * If the payment is declined or fails for ome other reason, pass the * relevant error message here, and it gets returned with the * ErrorResponse of the `addPaymentToOrder` mutation. */ errorMessage?: string; metadata: PaymentMetadata; method: string; } | { amount: number; state: "Error"; transactionId?: string; errorMessage: string; metadata: PaymentMetadata; method: string; }>; /** * @description * Called internally to settle a payment * * @internal */ settlePayment(ctx: RequestContext, order: Order, payment: Payment, args: ConfigArg[], method: PaymentMethod): Promise; /** * @description * Called internally to cancel a payment * * @internal */ cancelPayment(ctx: RequestContext, order: Order, payment: Payment, args: ConfigArg[], method: PaymentMethod): Promise; /** * @description * Called internally to create a refund * * @internal */ createRefund(ctx: RequestContext, input: RefundOrderInput, amount: number, order: Order, payment: Payment, args: ConfigArg[], method: PaymentMethod): Promise; /** * @description * This function is called before the state of a Payment is transitioned. If the PaymentMethodHandler * was instantiated with a `onStateTransitionStart` function, that function will be invoked and its * return value used to determine whether the transition can occur. * * @internal */ onStateTransitionStart(fromState: PaymentState, toState: PaymentState, data: PaymentTransitionData): OnPaymentTransitionStartReturnType; }