// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../core/resource'; import * as SubscriptionsAPI from './subscriptions'; import * as DiscountsAPI from './discounts'; import * as MiscAPI from './misc'; import * as PaymentsAPI from './payments'; import * as CreditEntitlementsAPI from './credit-entitlements/credit-entitlements'; import { APIPromise } from '../core/api-promise'; import { DefaultPageNumberPagination, type DefaultPageNumberPaginationParams, PagePromise, } from '../core/pagination'; import { buildHeaders } from '../internal/headers'; import { RequestOptions } from '../internal/request-options'; import { path } from '../internal/utils/path'; export class Subscriptions extends APIResource { /** * @example * ```ts * // Automatically fetches more pages as needed. * for await (const subscriptionListResponse of client.subscriptions.list()) { * // ... * } * ``` */ list( query: SubscriptionListParams | null | undefined = {}, options?: RequestOptions, ): PagePromise { return this._client.getAPIList('/subscriptions', DefaultPageNumberPagination, { query, ...options, }); } /** * @deprecated */ create(body: SubscriptionCreateParams, options?: RequestOptions): APIPromise { return this._client.post('/subscriptions', { body, ...options }); } /** * @example * ```ts * const subscription = await client.subscriptions.retrieve( * 'sub_Iuaq622bbmmfOGrVTqdXv', * ); * ``` */ retrieve(subscriptionID: string, options?: RequestOptions): APIPromise { return this._client.get(path`/subscriptions/${subscriptionID}`, options); } /** * @example * ```ts * const subscription = await client.subscriptions.update( * 'sub_Iuaq622bbmmfOGrVTqdXv', * ); * ``` */ update( subscriptionID: string, body: SubscriptionUpdateParams, options?: RequestOptions, ): APIPromise { return this._client.patch(path`/subscriptions/${subscriptionID}`, { body, ...options }); } /** * @example * ```ts * const response = await client.subscriptions.charge( * 'sub_Iuaq622bbmmfOGrVTqdXv', * { product_price: 0 }, * ); * ``` */ charge( subscriptionID: string, body: SubscriptionChargeParams, options?: RequestOptions, ): APIPromise { return this._client.post(path`/subscriptions/${subscriptionID}/charge`, { body, ...options }); } /** * @example * ```ts * await client.subscriptions.changePlan( * 'sub_Iuaq622bbmmfOGrVTqdXv', * { * product_id: 'product_id', * proration_billing_mode: 'prorated_immediately', * quantity: 0, * }, * ); * ``` */ changePlan( subscriptionID: string, body: SubscriptionChangePlanParams, options?: RequestOptions, ): APIPromise { return this._client.post(path`/subscriptions/${subscriptionID}/change-plan`, { body, ...options, headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), }); } /** * Get detailed usage history for a subscription that includes usage-based billing * (metered components). This endpoint provides insights into customer usage * patterns and billing calculations over time. * * ## What You'll Get: * * - **Billing periods**: Each item represents a billing cycle with start and end * dates * - **Meter usage**: Detailed breakdown of usage for each meter configured on the * subscription * - **Usage calculations**: Total units consumed, free threshold units, and * chargeable units * - **Historical tracking**: Complete audit trail of usage-based charges * * ## Use Cases: * * - **Customer support**: Investigate billing questions and usage discrepancies * - **Usage analytics**: Analyze customer consumption patterns over time * - **Billing transparency**: Provide customers with detailed usage breakdowns * - **Revenue optimization**: Identify usage trends to optimize pricing strategies * * ## Filtering Options: * * - **Date range filtering**: Get usage history for specific time periods * - **Meter-specific filtering**: Focus on usage for a particular meter * - **Pagination**: Navigate through large usage histories efficiently * * ## Important Notes: * * - Only returns data for subscriptions with usage-based (metered) components * - Usage history is organized by billing periods (subscription cycles) * - Free threshold units are calculated and displayed separately from chargeable * units * - Historical data is preserved even if meter configurations change * * ## Example Query Patterns: * * - Get last 3 months: * `?start_date=2024-01-01T00:00:00Z&end_date=2024-03-31T23:59:59Z` * - Filter by meter: `?meter_id=mtr_api_requests` * - Paginate results: `?page_size=20&page_number=1` * - Recent usage: `?start_date=2024-03-01T00:00:00Z` (from March 1st to now) * * @example * ```ts * // Automatically fetches more pages as needed. * for await (const subscriptionRetrieveUsageHistoryResponse of client.subscriptions.retrieveUsageHistory( * 'sub_Iuaq622bbmmfOGrVTqdXv', * )) { * // ... * } * ``` */ retrieveUsageHistory( subscriptionID: string, query: SubscriptionRetrieveUsageHistoryParams | null | undefined = {}, options?: RequestOptions, ): PagePromise< SubscriptionRetrieveUsageHistoryResponsesDefaultPageNumberPagination, SubscriptionRetrieveUsageHistoryResponse > { return this._client.getAPIList( path`/subscriptions/${subscriptionID}/usage-history`, DefaultPageNumberPagination, { query, ...options }, ); } /** * @example * ```ts * const response = * await client.subscriptions.updatePaymentMethod( * 'sub_Iuaq622bbmmfOGrVTqdXv', * { payment_method: { type: 'new' } }, * ); * ``` */ updatePaymentMethod( subscriptionID: string, params: SubscriptionUpdatePaymentMethodParams, options?: RequestOptions, ): APIPromise { const { payment_method } = params; return this._client.post(path`/subscriptions/${subscriptionID}/update-payment-method`, { body: payment_method, ...options, }); } /** * @example * ```ts * const response = * await client.subscriptions.previewChangePlan( * 'sub_Iuaq622bbmmfOGrVTqdXv', * { * product_id: 'product_id', * proration_billing_mode: 'prorated_immediately', * quantity: 0, * }, * ); * ``` */ previewChangePlan( subscriptionID: string, body: SubscriptionPreviewChangePlanParams, options?: RequestOptions, ): APIPromise { return this._client.post(path`/subscriptions/${subscriptionID}/change-plan/preview`, { body, ...options, }); } /** * @example * ```ts * const response = * await client.subscriptions.retrieveCreditUsage( * 'sub_Iuaq622bbmmfOGrVTqdXv', * ); * ``` */ retrieveCreditUsage( subscriptionID: string, options?: RequestOptions, ): APIPromise { return this._client.get(path`/subscriptions/${subscriptionID}/credit-usage`, options); } /** * @example * ```ts * await client.subscriptions.cancelChangePlan( * 'sub_Iuaq622bbmmfOGrVTqdXv', * ); * ``` */ cancelChangePlan(subscriptionID: string, options?: RequestOptions): APIPromise { return this._client.delete(path`/subscriptions/${subscriptionID}/change-plan/scheduled`, { ...options, headers: buildHeaders([{ Accept: '*/*' }, options?.headers]), }); } } export type SubscriptionListResponsesDefaultPageNumberPagination = DefaultPageNumberPagination; export type SubscriptionRetrieveUsageHistoryResponsesDefaultPageNumberPagination = DefaultPageNumberPagination; /** * Response struct representing subscription details */ export interface AddonCartResponseItem { addon_id: string; quantity: number; } export interface AttachAddon { addon_id: string; /** * Number of units of this addon. */ quantity: number; } export type CancellationFeedback = | 'too_expensive' | 'missing_features' | 'switched_service' | 'unused' | 'customer_service' | 'low_quality' | 'too_complex' | 'other'; /** * Response struct representing credit entitlement cart details for a subscription */ export interface CreditEntitlementCartResponse { credit_entitlement_id: string; credit_entitlement_name: string; credits_amount: string; /** * Customer's current overage balance for this entitlement */ overage_balance: string; /** * Controls how overage is handled at the end of a billing cycle. * * | Preset | Charge at billing | Credits reduce overage | Preserve overage at reset | * | -------------------------- | :---------------: | :--------------------: | :-----------------------: | * | `forgive_at_reset` | No | No | No | * | `invoice_at_billing` | Yes | No | No | * | `carry_deficit` | No | No | Yes | * | `carry_deficit_auto_repay` | No | Yes | Yes | */ overage_behavior: CreditEntitlementsAPI.CbbOverageBehavior; overage_enabled: boolean; product_id: string; /** * Customer's current remaining credit balance for this entitlement */ remaining_balance: string; rollover_enabled: boolean; /** * Unit label for the credit entitlement (e.g., "API Calls", "Tokens") */ unit: string; expires_after_days?: number | null; low_balance_threshold_percent?: number | null; max_rollover_count?: number | null; overage_limit?: string | null; rollover_percentage?: number | null; rollover_timeframe_count?: number | null; /** * Unit of a duration count (e.g. license-key validity period). */ rollover_timeframe_interval?: TimeInterval | null; } /** * Response struct representing usage-based meter cart details for a subscription */ export interface MeterCartResponseItem { currency: MiscAPI.Currency; free_threshold: number; measurement_unit: string; meter_id: string; name: string; description?: string | null; price_per_unit?: string | null; } /** * Response struct representing meter-credit entitlement mapping cart details for a * subscription */ export interface MeterCreditEntitlementCartResponse { credit_entitlement_id: string; meter_id: string; meter_name: string; meter_units_per_credit: string; product_id: string; } export interface OnDemandSubscription { /** * If set as True, does not perform any charge and only authorizes payment method * details for future use. */ mandate_only: boolean; /** * Whether adaptive currency fees should be included in the product_price (true) or * added on top (false). This field is ignored if adaptive pricing is not enabled * for the business. */ adaptive_currency_fees_inclusive?: boolean | null; /** * Optional currency of the product price. If not specified, defaults to the * currency of the product. */ product_currency?: MiscAPI.Currency | null; /** * Optional product description override for billing and line items. If not * specified, the stored description of the product will be used. */ product_description?: string | null; /** * Product price for the initial charge to customer If not specified the stored * price of the product will be used Represented in the lowest denomination of the * currency (e.g., cents for USD). For example, to charge $1.00, pass `100`. */ product_price?: number | null; } export interface ScheduledPlanChange { /** * The scheduled plan change ID */ id: string; /** * Addons included in the scheduled change */ addons: Array; /** * When this scheduled change was created */ created_at: string; /** * When the change will be applied */ effective_at: string; /** * The product ID the subscription will change to */ product_id: string; /** * Quantity for the new plan */ quantity: number; /** * Description of the product being changed to */ product_description?: string | null; /** * Name of the product being changed to */ product_name?: string | null; } export namespace ScheduledPlanChange { export interface Addon { /** * The addon ID */ addon_id: string; /** * Name of the addon */ name: string; /** * Quantity of the addon */ quantity: number; } } /** * Response struct representing subscription details */ export interface Subscription { /** * Addons associated with this subscription */ addons: Array; /** * Billing address details for payments */ billing: PaymentsAPI.BillingAddress; /** * Brand id this subscription belongs to */ brand_id: string; /** * Indicates if the subscription will cancel at the next billing date */ cancel_at_next_billing_date: boolean; /** * Timestamp when the subscription was created */ created_at: string; /** * Credit entitlement cart settings for this subscription */ credit_entitlement_cart: Array; /** * Currency used for the subscription payments */ currency: MiscAPI.Currency; /** * Customer details associated with the subscription */ customer: PaymentsAPI.CustomerLimitedDetails; /** * Additional custom data associated with the subscription */ metadata: MiscAPI.Metadata; /** * Meter credit entitlement cart settings for this subscription */ meter_credit_entitlement_cart: Array; /** * Meters associated with this subscription (for usage-based billing) */ meters: Array; /** * Timestamp of the next scheduled billing. Indicates the end of current billing * period */ next_billing_date: string; /** * Wether the subscription is on-demand or not */ on_demand: boolean; /** * Number of payment frequency intervals */ payment_frequency_count: number; /** * Time interval for payment frequency (e.g. month, year) */ payment_frequency_interval: TimeInterval; /** * Timestamp of the last payment. Indicates the start of current billing period */ previous_billing_date: string; /** * Identifier of the product associated with this subscription */ product_id: string; /** * Number of units/items included in the subscription */ quantity: number; /** * Amount charged before tax for each recurring payment in the currency's smallest * unit (cents for USD, yen for JPY, fils for KWD) */ recurring_pre_tax_amount: number; /** * Current status of the subscription */ status: SubscriptionStatus; /** * Unique identifier for the subscription */ subscription_id: string; /** * Number of subscription period intervals */ subscription_period_count: number; /** * Time interval for the subscription period (e.g. month, year) */ subscription_period_interval: TimeInterval; /** * Indicates if the recurring_pre_tax_amount is tax inclusive */ tax_inclusive: boolean; /** * Number of days in the trial period (0 if no trial) */ trial_period_days: number; /** * Free-text cancellation comment, if any */ cancellation_comment?: string | null; /** * Customer-supplied churn reason, if any */ cancellation_feedback?: CancellationFeedback | null; /** * Cancelled timestamp if the subscription is cancelled */ cancelled_at?: string | null; /** * Customer's responses to custom fields collected during checkout */ custom_field_responses?: Array | null; /** * Business / legal name associated with the tax id (B2B). When set this is used on * the invoice in place of the customer's personal name. */ customer_business_name?: string | null; /** * DEPRECATED: Use discounts[].cycles_remaining instead. */ discount_cycles_remaining?: number | null; /** * DEPRECATED: Use discounts instead. Returns the first discount's ID if present. */ discount_id?: string | null; /** * All stacked discounts applied, ordered by position */ discounts?: Array | null; /** * Timestamp when the subscription will expire */ expires_at?: string | null; /** * Saved payment method id used for recurring charges */ payment_method_id?: string | null; /** * Scheduled plan change details, if any */ scheduled_change?: ScheduledPlanChange | null; /** * Tax identifier provided for this subscription (if applicable) */ tax_id?: string | null; } export type SubscriptionStatus = 'pending' | 'active' | 'on_hold' | 'cancelled' | 'failed' | 'expired'; /** * Unit of a duration count (e.g. license-key validity period). */ export type TimeInterval = 'Day' | 'Week' | 'Month' | 'Year'; export interface UpdateSubscriptionPlanReq { /** * Unique identifier of the product to subscribe to */ product_id: string; /** * Proration Billing Mode */ proration_billing_mode: | 'prorated_immediately' | 'full_immediately' | 'difference_immediately' | 'do_not_bill'; /** * Number of units to subscribe for. Must be at least 1. */ quantity: number; /** * Whether adaptive currency fees should be included in the price (true) or added * on top (false). If not specified, uses the subscription's stored setting. */ adaptive_currency_fees_inclusive?: boolean | null; /** * Addons for the new plan. Note : Leaving this empty would remove any existing * addons */ addons?: Array | null; /** * @deprecated Use `discount_id` instead. */ discount_code?: string | null; /** * Stacked discount codes to apply to the new plan. Max 20. Cannot be used together * with discount_code. If provided, replaces any existing discount codes. Empty * array removes all discounts. If not provided (None), existing discounts with * preserve_on_plan_change=true are preserved. */ discount_codes?: Array | null; /** * When to apply the plan change. * * - `immediately` (default): Apply the plan change right away * - `next_billing_date`: Schedule the change for the next billing date */ effective_at?: 'immediately' | 'next_billing_date'; /** * Metadata for the payment. If not passed, the metadata of the subscription will * be taken */ metadata?: MiscAPI.Metadata | null; /** * Controls behavior when the plan change payment fails. * * - `prevent_change`: Keep subscription on current plan until payment succeeds * - `apply_change` (default): Apply plan change immediately regardless of payment * outcome * * If not specified, uses the business-level default setting. */ on_payment_failure?: 'prevent_change' | 'apply_change' | null; } export interface SubscriptionCreateResponse { /** * Addons associated with this subscription */ addons: Array; /** * Customer details associated with this subscription */ customer: PaymentsAPI.CustomerLimitedDetails; /** * Additional metadata associated with the subscription */ metadata: MiscAPI.Metadata; /** * First payment id for the subscription */ payment_id: string; /** * Tax will be added to the amount and charged to the customer on each billing * cycle */ recurring_pre_tax_amount: number; /** * Unique identifier for the subscription */ subscription_id: string; /** * Client secret used to load Dodo checkout SDK NOTE : Dodo checkout SDK will be * coming soon */ client_secret?: string | null; /** * @deprecated Use `discounts` instead. */ discount_id?: string | null; /** * All stacked discount IDs applied, in order of application */ discount_ids?: Array | null; /** * Expiry timestamp of the payment link */ expires_on?: string | null; /** * One time products associated with the purchase of subscription */ one_time_product_cart?: Array | null; /** * URL to checkout page */ payment_link?: string | null; } export namespace SubscriptionCreateResponse { export interface OneTimeProductCart { product_id: string; quantity: number; } } /** * Response struct representing subscription details */ export interface SubscriptionListResponse { /** * Billing address details for payments */ billing: PaymentsAPI.BillingAddress; /** * Indicates if the subscription will cancel at the next billing date */ cancel_at_next_billing_date: boolean; /** * Timestamp when the subscription was created */ created_at: string; /** * Currency used for the subscription payments */ currency: MiscAPI.Currency; /** * Customer details associated with the subscription */ customer: PaymentsAPI.CustomerLimitedDetails; /** * All stacked discounts applied, in order of application */ discounts: Array; /** * Additional custom data associated with the subscription */ metadata: MiscAPI.Metadata; /** * Timestamp of the next scheduled billing. Indicates the end of current billing * period */ next_billing_date: string; /** * Wether the subscription is on-demand or not */ on_demand: boolean; /** * Number of payment frequency intervals */ payment_frequency_count: number; /** * Time interval for payment frequency (e.g. month, year) */ payment_frequency_interval: TimeInterval; /** * Timestamp of the last payment. Indicates the start of current billing period */ previous_billing_date: string; /** * Identifier of the product associated with this subscription */ product_id: string; /** * Number of units/items included in the subscription */ quantity: number; /** * Amount charged before tax for each recurring payment in the currency's smallest * unit (cents for USD, yen for JPY, fils for KWD) */ recurring_pre_tax_amount: number; /** * Current status of the subscription */ status: SubscriptionStatus; /** * Unique identifier for the subscription */ subscription_id: string; /** * Number of subscription period intervals */ subscription_period_count: number; /** * Time interval for the subscription period (e.g. month, year) */ subscription_period_interval: TimeInterval; /** * Indicates if the recurring_pre_tax_amount is tax inclusive */ tax_inclusive: boolean; /** * Number of days in the trial period (0 if no trial) */ trial_period_days: number; /** * Cancelled timestamp if the subscription is cancelled */ cancelled_at?: string | null; /** * Business / legal name associated with the tax id (B2B). When set this is used on * the invoice in place of the customer's personal name. */ customer_business_name?: string | null; /** * DEPRECATED: Use discounts[].cycles_remaining instead. */ discount_cycles_remaining?: number | null; /** * DEPRECATED: Use discounts instead. */ discount_id?: string | null; /** * Saved payment method id used for recurring charges */ payment_method_id?: string | null; /** * Name of the product associated with this subscription */ product_name?: string | null; /** * Scheduled plan change details, if any */ scheduled_change?: ScheduledPlanChange | null; /** * Tax identifier provided for this subscription (if applicable) */ tax_id?: string | null; } export namespace SubscriptionListResponse { /** * Lightweight discount info for list endpoints. Array order represents position * (no explicit position field). */ export interface Discount { /** * The unique discount ID */ discount_id: string; /** * Remaining billing cycles for this discount on this subscription */ discount_cycles_remaining?: number | null; } } export interface SubscriptionChargeResponse { payment_id: string; } export interface SubscriptionPreviewChangePlanResponse { immediate_charge: SubscriptionPreviewChangePlanResponse.ImmediateCharge; /** * Response struct representing subscription details */ new_plan: Subscription; } export namespace SubscriptionPreviewChangePlanResponse { export interface ImmediateCharge { /** * When the plan change will be effective */ effective_at: string; line_items: Array; summary: ImmediateCharge.Summary; } export namespace ImmediateCharge { export interface Subscription { id: string; currency: MiscAPI.Currency; product_id: string; proration_factor: number; quantity: number; tax_inclusive: boolean; type: 'subscription'; unit_price: number; description?: string | null; name?: string | null; tax?: number | null; tax_rate?: number | null; } export interface Addon { id: string; currency: MiscAPI.Currency; name: string; proration_factor: number; quantity: number; /** * Represents the different categories of taxation applicable to various products * and services. */ tax_category: MiscAPI.TaxCategory; tax_inclusive: boolean; tax_rate: number; type: 'addon'; unit_price: number; description?: string | null; tax?: number | null; } export interface Meter { id: string; chargeable_units: string; currency: MiscAPI.Currency; free_threshold: number; name: string; price_per_unit: string; subtotal: number; tax_inclusive: boolean; tax_rate: number; type: 'meter'; units_consumed: string; description?: string | null; tax?: number | null; } export interface Summary { currency: MiscAPI.Currency; /** * Net credit movement in the smallest currency unit (e.g. cents). **Negative** – * credits were deducted from the customer's balance to offset the charge (typical * on upgrades). **Positive** – credits were added to the customer's balance, * either from a downgrade proration refund or from topping-up the wallet to meet a * gateway minimum-charge threshold. **Zero** – no credit movement occurred. */ customer_credits: number; settlement_amount: number; settlement_currency: MiscAPI.Currency; total_amount: number; settlement_tax?: number | null; tax?: number | null; } } } /** * Credit usage status for all entitlements linked to a subscription */ export interface SubscriptionRetrieveCreditUsageResponse { items: Array; subscription_id: string; } export namespace SubscriptionRetrieveCreditUsageResponse { /** * Per-entitlement credit usage status for a subscription */ export interface Item { /** * Customer's current credit balance for this entitlement (customer-wide) */ balance: string; credit_entitlement_id: string; credit_entitlement_name: string; /** * True if overage has reached or exceeded the limit. When true, further deductions * that would increase overage will fail. */ limit_reached: boolean; /** * Current overage amount accrued (customer-wide) */ overage: string; /** * Whether overage is enabled for this entitlement on this subscription */ overage_enabled: boolean; /** * Unit label for the credit entitlement (e.g. "API Calls", "Tokens") */ unit: string; /** * Maximum allowed overage before deductions are blocked. None means unlimited * overage (when overage_enabled is true). */ overage_limit?: string | null; /** * How much more overage can accumulate before being blocked. None if overage is * not enabled or there is no limit (unlimited). A value of 0 means the next * deduction that increases overage will be blocked. */ remaining_headroom?: string | null; } } export interface SubscriptionRetrieveUsageHistoryResponse { /** * End date of the billing period */ end_date: string; /** * List of meters and their usage for this billing period */ meters: Array; /** * Start date of the billing period */ start_date: string; } export namespace SubscriptionRetrieveUsageHistoryResponse { export interface Meter { /** * Meter identifier */ id: string; /** * Chargeable units (after free threshold) as string for precision */ chargeable_units: string; /** * Total units consumed as string for precision */ consumed_units: string; /** * Currency for the price per unit */ currency: MiscAPI.Currency; /** * Free threshold units for this meter */ free_threshold: number; /** * Meter name */ name: string; /** * Price per unit in string format for precision */ price_per_unit: string; /** * Total price charged for this meter in the currency's smallest unit (cents for * USD, yen for JPY, fils for KWD) */ total_price: number; } } export interface SubscriptionUpdatePaymentMethodResponse { client_secret?: string | null; expires_on?: string | null; payment_id?: string | null; payment_link?: string | null; } export interface SubscriptionListParams extends DefaultPageNumberPaginationParams { /** * filter by Brand id */ brand_id?: string; /** * Filter by cancel_at_next_billing_date (subscriptions scheduled for cancellation) */ cancel_at_next_billing_date?: boolean; /** * Get events after this created time */ created_at_gte?: string; /** * Get events created before this time */ created_at_lte?: string; /** * Filter by customer id */ customer_id?: string; /** * Filter by product id */ product_id?: string; /** * Filter by status */ status?: 'pending' | 'active' | 'on_hold' | 'cancelled' | 'failed' | 'expired'; } export interface SubscriptionCreateParams { /** * Billing address information for the subscription */ billing: PaymentsAPI.BillingAddress; /** * Customer details for the subscription */ customer: PaymentsAPI.CustomerRequest; /** * Unique identifier of the product to subscribe to */ product_id: string; /** * Number of units to subscribe for. Must be at least 1. */ quantity: number; /** * Attach addons to this subscription */ addons?: Array | null; /** * List of payment methods allowed during checkout. * * Customers will **never** see payment methods that are **not** in this list. * However, adding a method here **does not guarantee** customers will see it. * Availability still depends on other factors (e.g., customer location, merchant * settings). */ allowed_payment_method_types?: Array | null; /** * Fix the currency in which the end customer is billed. If Dodo Payments cannot * support that currency for this transaction, it will not proceed */ billing_currency?: MiscAPI.Currency | null; /** * Optional business / legal name associated with the tax id. When provided * together with a valid tax id for a B2B purchase, this name is rendered on the * invoice instead of the customer's personal name. */ customer_business_name?: string | null; /** * @deprecated Use `discount_id` instead. */ discount_code?: string | null; /** * Stacked discount codes to apply, in order of application. Max 20. Cannot be used * together with discount_code. */ discount_codes?: Array | null; /** * Override merchant default 3DS behaviour for this subscription */ force_3ds?: boolean | null; /** * Override the merchant-level mandate floor (in INR paise) for INR e-mandates on * Indian-card recurring payments. The mandate amount sent to the processor is * `max(this_floor, actual_billing_amount)`, so this is effectively the * customer-facing authorization ceiling whenever billing is lower. When unset, the * merchant setting applies; when that's also unset, the system default of ₹15,000 * applies. */ mandate_min_amount_inr_paise?: number | null; /** * Additional metadata for the subscription Defaults to empty if not specified */ metadata?: MiscAPI.Metadata; on_demand?: OnDemandSubscription | null; /** * List of one time products that will be bundled with the first payment for this * subscription */ one_time_product_cart?: Array | null; /** * If true, generates a payment link. Defaults to false if not specified. */ payment_link?: boolean | null; /** * Optional payment method ID to use for this subscription. If provided, * customer_id must also be provided (via AttachExistingCustomer). The payment * method will be validated for eligibility with the subscription's currency. */ payment_method_id?: string | null; /** * If true, redirects the customer immediately after payment completion False by * default */ redirect_immediately?: boolean; /** * If true, the customer's phone number is required to create this subscription. * Typically set alongside `payment_link=true` so merchants can enforce phone * collection on the hosted payment page. Defaults to false. */ require_phone_number?: boolean; /** * Optional URL to redirect after successful subscription creation */ return_url?: string | null; /** * If true, returns a shortened payment link. Defaults to false if not specified. */ short_link?: boolean | null; /** * Display saved payment methods of a returning customer False by default */ show_saved_payment_methods?: boolean; /** * Tax ID in case the payment is B2B. If tax id validation fails the payment * creation will fail */ tax_id?: string | null; /** * Optional trial period in days If specified, this value overrides the trial * period set in the product's price Must be between 0 and 10000 days */ trial_period_days?: number | null; } export interface SubscriptionUpdateParams { billing?: PaymentsAPI.BillingAddress | null; /** * When set, the subscription will remain active until the end of billing period */ cancel_at_next_billing_date?: boolean | null; cancel_reason?: | 'cancelled_by_customer' | 'cancelled_by_merchant' | 'cancelled_by_merchant_send_dunning' | 'dodo_team' | null; /** * Free-text cancellation comment (only valid when cancelling or scheduling * cancellation). */ cancellation_comment?: string | null; /** * Customer-supplied churn reason (only valid when cancelling or scheduling * cancellation). */ cancellation_feedback?: CancellationFeedback | null; /** * Update credit entitlement cart settings */ credit_entitlement_cart?: Array | null; /** * Optional business / legal name associated with the tax id. When provided * together with a valid tax id for a B2B subscription, this name is rendered on * the invoice instead of the customer's personal name. Send `null` to explicitly * clear the business name. */ customer_business_name?: string | null; customer_name?: string | null; disable_on_demand?: SubscriptionUpdateParams.DisableOnDemand | null; /** * Arbitrary key-value metadata. Values can be string, integer, number, or boolean. */ metadata?: MiscAPI.Metadata | null; next_billing_date?: string | null; status?: SubscriptionStatus | null; /** * New number of `subscription_period_interval` units the subscription entitlement * should span. Used together with `subscription_period_interval` to extend the * subscription period. The resulting period must not be shorter than the current * one (this endpoint only extends). */ subscription_period_count?: number | null; /** * New interval unit for the subscription period. When changing the period, this * may be supplied alongside `subscription_period_count`; if omitted the existing * interval is retained. */ subscription_period_interval?: TimeInterval | null; tax_id?: string | null; } export namespace SubscriptionUpdateParams { export interface CreditEntitlementCart { credit_entitlement_id: string; credits_amount?: string | null; expires_after_days?: number | null; low_balance_threshold_percent?: number | null; max_rollover_count?: number | null; overage_enabled?: boolean | null; overage_limit?: string | null; rollover_enabled?: boolean | null; rollover_percentage?: number | null; rollover_timeframe_count?: number | null; /** * Unit of a duration count (e.g. license-key validity period). */ rollover_timeframe_interval?: SubscriptionsAPI.TimeInterval | null; } export interface DisableOnDemand { next_billing_date: string; } } export interface SubscriptionChargeParams { /** * The product price. Represented in the lowest denomination of the currency (e.g., * cents for USD). For example, to charge $1.00, pass `100`. */ product_price: number; /** * Whether adaptive currency fees should be included in the product_price (true) or * added on top (false). This field is ignored if adaptive pricing is not enabled * for the business. */ adaptive_currency_fees_inclusive?: boolean | null; /** * Specify how customer balance is used for the payment */ customer_balance_config?: SubscriptionChargeParams.CustomerBalanceConfig | null; /** * Metadata for the payment. If not passed, the metadata of the subscription will * be taken */ metadata?: MiscAPI.Metadata | null; /** * Optional currency of the product price. If not specified, defaults to the * currency of the product. */ product_currency?: MiscAPI.Currency | null; /** * Optional product description override for billing and line items. If not * specified, the stored description of the product will be used. */ product_description?: string | null; } export namespace SubscriptionChargeParams { /** * Specify how customer balance is used for the payment */ export interface CustomerBalanceConfig { /** * Allows Customer Credit to be purchased to settle payments */ allow_customer_credits_purchase?: boolean | null; /** * Allows Customer Credit Balance to be used to settle payments */ allow_customer_credits_usage?: boolean | null; } } export interface SubscriptionChangePlanParams { /** * Unique identifier of the product to subscribe to */ product_id: string; /** * Proration Billing Mode */ proration_billing_mode: | 'prorated_immediately' | 'full_immediately' | 'difference_immediately' | 'do_not_bill'; /** * Number of units to subscribe for. Must be at least 1. */ quantity: number; /** * Whether adaptive currency fees should be included in the price (true) or added * on top (false). If not specified, uses the subscription's stored setting. */ adaptive_currency_fees_inclusive?: boolean | null; /** * Addons for the new plan. Note : Leaving this empty would remove any existing * addons */ addons?: Array | null; /** * @deprecated Use `discount_id` instead. */ discount_code?: string | null; /** * Stacked discount codes to apply to the new plan. Max 20. Cannot be used together * with discount_code. If provided, replaces any existing discount codes. Empty * array removes all discounts. If not provided (None), existing discounts with * preserve_on_plan_change=true are preserved. */ discount_codes?: Array | null; /** * When to apply the plan change. * * - `immediately` (default): Apply the plan change right away * - `next_billing_date`: Schedule the change for the next billing date */ effective_at?: 'immediately' | 'next_billing_date'; /** * Metadata for the payment. If not passed, the metadata of the subscription will * be taken */ metadata?: MiscAPI.Metadata | null; /** * Controls behavior when the plan change payment fails. * * - `prevent_change`: Keep subscription on current plan until payment succeeds * - `apply_change` (default): Apply plan change immediately regardless of payment * outcome * * If not specified, uses the business-level default setting. */ on_payment_failure?: 'prevent_change' | 'apply_change' | null; } export interface SubscriptionRetrieveUsageHistoryParams extends DefaultPageNumberPaginationParams { /** * Filter by end date (inclusive) */ end_date?: string | null; /** * Filter by specific meter ID */ meter_id?: string | null; /** * Filter by start date (inclusive) */ start_date?: string | null; } export interface SubscriptionUpdatePaymentMethodParams { payment_method: SubscriptionUpdatePaymentMethodParams.New | SubscriptionUpdatePaymentMethodParams.Existing; } export namespace SubscriptionUpdatePaymentMethodParams { export interface New { type: 'new'; /** * List of payment methods allowed during checkout. * * Customers will **never** see payment methods that are **not** in this list. * However, adding a method here **does not guarantee** customers will see it. * Availability still depends on other factors (e.g., customer location, merchant * settings). */ allowed_payment_method_types?: Array | null; return_url?: string | null; } export interface Existing { payment_method_id: string; type: 'existing'; } } export interface SubscriptionPreviewChangePlanParams { /** * Unique identifier of the product to subscribe to */ product_id: string; /** * Proration Billing Mode */ proration_billing_mode: | 'prorated_immediately' | 'full_immediately' | 'difference_immediately' | 'do_not_bill'; /** * Number of units to subscribe for. Must be at least 1. */ quantity: number; /** * Whether adaptive currency fees should be included in the price (true) or added * on top (false). If not specified, uses the subscription's stored setting. */ adaptive_currency_fees_inclusive?: boolean | null; /** * Addons for the new plan. Note : Leaving this empty would remove any existing * addons */ addons?: Array | null; /** * @deprecated Use `discount_id` instead. */ discount_code?: string | null; /** * Stacked discount codes to apply to the new plan. Max 20. Cannot be used together * with discount_code. If provided, replaces any existing discount codes. Empty * array removes all discounts. If not provided (None), existing discounts with * preserve_on_plan_change=true are preserved. */ discount_codes?: Array | null; /** * When to apply the plan change. * * - `immediately` (default): Apply the plan change right away * - `next_billing_date`: Schedule the change for the next billing date */ effective_at?: 'immediately' | 'next_billing_date'; /** * Metadata for the payment. If not passed, the metadata of the subscription will * be taken */ metadata?: MiscAPI.Metadata | null; /** * Controls behavior when the plan change payment fails. * * - `prevent_change`: Keep subscription on current plan until payment succeeds * - `apply_change` (default): Apply plan change immediately regardless of payment * outcome * * If not specified, uses the business-level default setting. */ on_payment_failure?: 'prevent_change' | 'apply_change' | null; } export declare namespace Subscriptions { export { type AddonCartResponseItem as AddonCartResponseItem, type AttachAddon as AttachAddon, type CancellationFeedback as CancellationFeedback, type CreditEntitlementCartResponse as CreditEntitlementCartResponse, type MeterCartResponseItem as MeterCartResponseItem, type MeterCreditEntitlementCartResponse as MeterCreditEntitlementCartResponse, type OnDemandSubscription as OnDemandSubscription, type ScheduledPlanChange as ScheduledPlanChange, type Subscription as Subscription, type SubscriptionStatus as SubscriptionStatus, type TimeInterval as TimeInterval, type UpdateSubscriptionPlanReq as UpdateSubscriptionPlanReq, type SubscriptionCreateResponse as SubscriptionCreateResponse, type SubscriptionListResponse as SubscriptionListResponse, type SubscriptionChargeResponse as SubscriptionChargeResponse, type SubscriptionPreviewChangePlanResponse as SubscriptionPreviewChangePlanResponse, type SubscriptionRetrieveCreditUsageResponse as SubscriptionRetrieveCreditUsageResponse, type SubscriptionRetrieveUsageHistoryResponse as SubscriptionRetrieveUsageHistoryResponse, type SubscriptionUpdatePaymentMethodResponse as SubscriptionUpdatePaymentMethodResponse, type SubscriptionListResponsesDefaultPageNumberPagination as SubscriptionListResponsesDefaultPageNumberPagination, type SubscriptionRetrieveUsageHistoryResponsesDefaultPageNumberPagination as SubscriptionRetrieveUsageHistoryResponsesDefaultPageNumberPagination, type SubscriptionListParams as SubscriptionListParams, type SubscriptionCreateParams as SubscriptionCreateParams, type SubscriptionUpdateParams as SubscriptionUpdateParams, type SubscriptionChargeParams as SubscriptionChargeParams, type SubscriptionChangePlanParams as SubscriptionChangePlanParams, type SubscriptionRetrieveUsageHistoryParams as SubscriptionRetrieveUsageHistoryParams, type SubscriptionUpdatePaymentMethodParams as SubscriptionUpdatePaymentMethodParams, type SubscriptionPreviewChangePlanParams as SubscriptionPreviewChangePlanParams, }; }