import { PaymentCalculatedCheckout, PaymentCheckoutExecution, PaymentPartialCheckout, PaymentProduct, PaymentProviderData, PaymentUser, PaymentUserData } from "./types.js";
import { AbstractPaymentServerProvider } from "./server-providers/abstract-payment-server-provider.js";
export declare abstract class AbstractPaymentServer<U extends PaymentUser = any, P extends PaymentProduct = any, PP extends AbstractPaymentServerProvider = any> {
    providers: PP[];
    constructor(paymentProviders: PP[]);
    handleWebhook(providerName: string, webhookData: any): Promise<void>;
    abstract retrieveUser(customerData: {
        id: string;
    } | {
        email: string;
    }): Promise<U>;
    /**
     * Checkout execution
     *
     * Keep in mind to watch success field,
     *
     *
     * @param user
     * @param checkout
     */
    checkout(user: U, checkout: PaymentCalculatedCheckout | PaymentCheckoutExecution): Promise<PaymentCheckoutExecution>;
    cancelCheckout(user: U, checkoutId: string, reason: string): Promise<PaymentUserData>;
    protected providerCheckout(user: U, checkout: PaymentCalculatedCheckout): Promise<PaymentCheckoutExecution>;
    private saveProductsProviderData;
    private mergeProviderData;
    /**
     * Implement this method for retrieving checkouts from your data source
     */
    abstract retrieveCheckout(user: U, checkoutId: string): Promise<PaymentCheckoutExecution | PaymentCalculatedCheckout>;
    /**
     * Implement this method for retrieving checkouts from your data source
     */
    abstract retrieveCheckoutByProviderId(user: U, providerCheckoutId: string): Promise<PaymentCheckoutExecution>;
    /**
     * Implement this method for:
     * - persisting successful checkouts
     * - updating succeeded checkouts
     *
     * @example
     * if (!checkout._id) {
     *     insertDB(checkout)
     * } else {
     *     updateDb(checkout._id, checkout)
     * }
     */
    protected abstract saveCheckout(user: U, checkout: PaymentCheckoutExecution): Promise<PaymentCheckoutExecution>;
    /**
     * Implement this method per project, should fill as many field as possible
     * items.product is required
     *
     * @param user
     * @param partialCheckout
     */
    abstract calculateCheckout(user: U, partialCheckout: PaymentPartialCheckout): Promise<PaymentCalculatedCheckout>;
    /**
     * Sometimes products need to be created on provider, implement this method for persisting that changes
     *
     * @param product
     * @param providersData
     * @protected
     */
    protected abstract updateProductProvidersData<PPPD extends PaymentProviderData>(product: string, providersData: PPPD[]): Promise<void>;
    /**
     * Persist user will allow you to save user payment properties, implementation should be similar to example
     *
     * @example
     * collection.updateOne({_id: user._id}, {$set: {payment: paymentData}});
     *
     *
     * @param user
     * @param paymentData
     * @protected
     */
    protected abstract updateUserPaymentProperties(user: U, paymentData: U["payment"]): Promise<void>;
}
