@liberquack/utils
Version:
Quack utilities
375 lines (374 loc) • 10.6 kB
TypeScript
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"];
}>;