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<Required<StateMachineConfig<any>>['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<PaymentState, 'Error'>;
    /**
     * @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<PaymentState, 'Settled'>;
    /**
     * @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<PaymentState, 'Cancelled'>;
    /**
     * @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<T extends ConfigArgs> = (ctx: RequestContext, order: Order, amount: number, args: ConfigArgValues<T>, metadata: PaymentMetadata, method: PaymentMethod) => CreatePaymentResult | CreatePaymentErrorResult | Promise<CreatePaymentResult | CreatePaymentErrorResult>;
/**
 * @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<T extends ConfigArgs> = (ctx: RequestContext, order: Order, payment: Payment, args: ConfigArgValues<T>, method: PaymentMethod) => SettlePaymentResult | SettlePaymentErrorResult | Promise<SettlePaymentResult | SettlePaymentErrorResult>;
/**
 * @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<T extends ConfigArgs> = (ctx: RequestContext, order: Order, payment: Payment, args: ConfigArgValues<T>, method: PaymentMethod) => CancelPaymentResult | CancelPaymentErrorResult | Promise<CancelPaymentResult | CancelPaymentErrorResult>;
/**
 * @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<T extends ConfigArgs> = (ctx: RequestContext, input: RefundOrderInput, amount: number, order: Order, payment: Payment, args: ConfigArgValues<T>, method: PaymentMethod) => CreateRefundResult | Promise<CreateRefundResult>;
/**
 * @description
 * Defines the object which is used to construct the {@link PaymentMethodHandler}.
 *
 * @docsCategory payment
 */
export interface PaymentMethodConfigOptions<T extends ConfigArgs> extends ConfigurableOperationDefOptions<T> {
    /**
     * @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<T>;
    /**
     * @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<T>;
    /**
     * @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<T>;
    /**
     * @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<T>;
    /**
     * @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<PaymentState, PaymentTransitionData>;
}
/**
 * @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<CreatePaymentResult> => {
 *     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<SettlePaymentResult> => {
 *     return { success: true };
 *   }
 * });
 * ```
 *
 * @docsCategory payment
 */
export declare class PaymentMethodHandler<T extends ConfigArgs = ConfigArgs> extends ConfigurableOperationDef<T> {
    private readonly createPaymentFn;
    private readonly settlePaymentFn;
    private readonly cancelPaymentFn?;
    private readonly createRefundFn?;
    private readonly onTransitionStartFn?;
    constructor(config: PaymentMethodConfigOptions<T>);
    /**
     * @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<PaymentState, "Error">;
        /**
         * @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<SettlePaymentResult | SettlePaymentErrorResult>;
    /**
     * @description
     * Called internally to cancel a payment
     *
     * @internal
     */
    cancelPayment(ctx: RequestContext, order: Order, payment: Payment, args: ConfigArg[], method: PaymentMethod): Promise<CancelPaymentResult | CancelPaymentErrorResult | undefined>;
    /**
     * @description
     * Called internally to create a refund
     *
     * @internal
     */
    createRefund(ctx: RequestContext, input: RefundOrderInput, amount: number, order: Order, payment: Payment, args: ConfigArg[], method: PaymentMethod): Promise<false | CreateRefundResult>;
    /**
     * @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;
}
