UNPKG

@liberquack/utils

Version:
375 lines (374 loc) 10.6 kB
import { ArrayType, Narrow } from "../utils.js"; import type { PaymentExternalProductData } from "./server-providers/abstract-payment-server-provider.js"; export declare type PaymentProviderMinimalProperties = { provider: string; }; export declare type PaymentEnforceProviderBase<T extends PaymentProviderMinimalProperties> = T; export declare type PaymentUserAccount = PaymentProviderMinimalProperties; /** * TODO: Delete it, was replaced by PaymentCheckoutExecution * @Deprecated */ export declare type PaymentUserData = { /** * Convinience property for accessing the last checkout */ lastCheckout?: PaymentCheckoutExecution; /** * Some payment providers, like stripe, may have important data * about our user, for example, registered cards */ externalProviderAccounts?: PaymentUserAccount[]; /** * Convinience property for accessing data about subscription */ subscription?: PaymentUserSubscriptionProperties; }; /** * The idea is that you append these data to your user, * for example * * type MyUserType = PaymentUser & { * name:string * } */ export declare type PaymentUser = { getId(): string; email?: string; payment?: PaymentUserData; }; /** * Essencial data about subscriptions */ export declare type PaymentUserSubscriptionProperties = { provider: string; /** * Id of subscription registered on provider */ externalId: string; productIds: string[]; nextBill: Date; planningCancelDate?: Date; planningDowngradeToPlan?: string; planningDowngradeDate?: Date; }; /** * The idea is that you append these data to your user, * for example * * type Product = PaymentProduct & { * color: " * } */ export declare type PaymentProduct = { getId(): string; /** * Human-readable product name */ title: string; /** * Array of prices, purpose is to be able to charge * in different currencies */ prices: Array<{ /** * Product price */ price: number; /** * Currency, when empty, api will use it's defualt currency * * If the checkout has different currencies, it will throw error, * or... Ideally will convert the prices for the currency with higher weight * the weight will be in total amount of checkout */ currency: string; }>; /** * Indicate if this product was inlined in a checkout, * it means the product didn't exist prior the payment, meaning it was created on demand * during the payment * * Inline products give flexibility by allowing the frontend to create checkout with * dynamic prices, products and data */ inline?: boolean; /** * Product code should be used instead of _id through the application, * it should be a string for example MY_PRODUCT_BLUE_VERSION * * _id may not be appropriate for building urls */ code: string; /** * "product" - for one time payments * "plan" - used for recurring payments * * If a checkout has a plan included with product, the first payment will be * priced as <plan + products> and rest will be only <plan> */ type: "product" | "plan"; /** * When the product or plan is registered within our providers, the data will * be reflected in this property */ externalPaymentData?: Array<PaymentProviderData>; }; /** * It's a container for holding provider data */ export declare type PaymentProviderData = { provider: string; data: any; }; /** * If multiple optional fields are used at once * the total discount is going be the sum of all discounts */ export declare type PaymentCoupon = { code: string; expiresAt?: Date; maxUsageCount?: number; /** * Applied on subtotal, it should be >0 and <=1 * * subtotal: 100 * pct_off: 0.5 * discount = 50 */ pctOff?: number; /** * Applied on subtotal, it should be >0 * * subtotal: 100 * value_off: 1.99 * discount = 1.99 */ valueOff?: number; /** * Applied on items only */ items?: Array<{ /** * product_id for applying the discount */ productId: string; /** * Applied on item price, it should be >0 and <=1 * * item price: 100 * pct_off: 0.5 * discount = 50 */ pctOff?: number; /** * Applied on item price, it should be >0 * * item price: 100 * value_off: 1.99 * discount = 1.99 */ valueOff?: number; }>; }; /** * PaymentPartialCheckout should be it's first state with basic information, * it should be sent to the api, for being enhanced and calculated * * @example * paymentClient.calculateCheckout(partialCheckout) */ export declare type PaymentPartialCheckout = PaymentProviderMinimalProperties & { userId: string; coupon_codes?: PaymentCoupon["code"][]; /** * items represent the products you have in your database, * after you call paymentClient.calculate(partialCheckout), * these each entry will be populated */ items: Array<{ productId: string; quantity: number; }>; /** * inlineItems represent non pre-registered products, * ideally when you call paymentClient.calculate(partialCheckout), * the api will do the necessary work, for example, creating these products */ inlineItems?: Array<Pick<PaymentProduct, "type" | "title"> & ArrayType<PaymentProduct["prices"]> & { quantity: number; }>; }; /** * PaymentCalculatedCheckout is the calculated data, it's one step closed * from being sent to the payment provider for completing the purchase */ export declare type PaymentCalculatedCheckout = PaymentProviderMinimalProperties & { coupon_codes?: PaymentCoupon["code"][]; userId: string; /** * externalData should persist some communication data between the provider and the api, * also could be useful on client side * * For more, see PaymentProviderData */ externalData?: PaymentProviderData; /** * Some providers need to have products registered on their system, * if that's the case, the generated data, like, product id on their system * should be placed in this field * * That field should be populated only once, when the provider generates that data */ externalProductData?: Array<PaymentExternalProductData>; /** * clientData is a field for sharing information * only on client side, may hold references and * complex data * * Should not be sent back to the server */ clientData?: any; /** * External id for retrieving data from payment provider * * Some providers will generate externalId during calculateCheckout, * if that's not the case, set it to false */ externalId?: string | false; /** * The sum of products and plans before any discounts */ subtotal: number; /** * Applied on subtotal, it should be >0 and <=1 * * subtotal: 100 * pct_off: 0.5 * discount = 50 */ pctOff: number; /** * Applied on subtotal, it should be >0 * * subtotal: 100 * value_off: 1.99 * discount = 1.99 */ valueOff: number; /** * Shipping price */ shipping: number; /** * Governamental taxes */ tax: number; /** * This is the final price */ total: number; /** * Currency, when empty, api will use it's defualt currency * * If the checkout has different currencies, it will throw error, * or... Ideally will convert the prices for the currency with higher weight * the weight will be in total amount of checkout */ currency: string; items: Array<{ /** * Indicates if this product item comes from an inline source, * Check more on PaymentPartialCheckout["inlineItems"] */ inline?: boolean; /** * Product Id */ productId: string; /** * Product data, it's a conviniance property * so you don't need to execute additional api calls */ product: PaymentProduct; /** * Check PaymentProduct["type"] for more information */ type: PaymentProduct["type"]; /** * Quantity of this product during the checkout */ quantity: number; /** * Applied on item, it should be >0 and <=1 * * item: 100 * pct_off: 0.5 * discount = 50 */ pctOff: number; /** * Applied on item, it should be >0 * * item: 100 * value_off: 1.99 * discount = 1.99 */ valueOff: number; /** * This is the final item price */ total: number; /** * This is the currency */ currency: string; }>; }; /** * PaymentCompletedCheckout as the name says, represents a completed checkout */ export declare type PaymentCheckoutExecution = PaymentCalculatedCheckout & { success: boolean; /** * Human readable error, should be easy and understandable * for your final user */ errorMessage?: string; /** * Subscription details, keep in mind that every time * it's renewed, the system should understand it as a * new checkout entry */ subscription?: PaymentUserSubscriptionProperties; /** * Check PaymentCalculatedCheckout["externalId"] */ externalId: string | false; cancelReason?: string; cancelRequestDate?: Date; }; export declare type NarrowCalculatedCheckout<T extends { provider: string; externalData: any; clientData: any; }> = Narrow<PaymentCalculatedCheckout, { provider: T["provider"]; externalData: Narrow<PaymentProviderData, { provider: T["provider"]; data: T["externalData"]; }>; clientData?: T["clientData"]; }>; export declare type NarrowCompletedCheckout<T extends { provider: string; externalData: any; clientData: any; }> = Narrow<PaymentCheckoutExecution, { provider: T["provider"]; externalData: Narrow<PaymentProviderData, { provider: T["provider"]; data: T["externalData"]; }>; clientData?: T["clientData"]; }>;