@shware/purchase 8.0.0 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/subscription/index.cjs +11 -3
- package/dist/subscription/index.cjs.map +1 -1
- package/dist/subscription/index.d.cts +26 -7
- package/dist/subscription/index.d.cts.map +1 -1
- package/dist/subscription/index.d.mts +26 -7
- package/dist/subscription/index.d.mts.map +1 -1
- package/dist/subscription/index.mjs +11 -3
- package/dist/subscription/index.mjs.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -42,7 +42,12 @@ import {
|
|
|
42
42
|
- `SUBSCRIPTION_STATUSES`: the union of every store's states (`TRIALING`, `ACTIVE`,
|
|
43
43
|
`IN_GRACE_PERIOD`, `PAST_DUE`, `ON_HOLD`, `PAUSED`, `CANCELED`, `EXPIRED`, ...). Each platform
|
|
44
44
|
mapper returns one of these.
|
|
45
|
-
- `AVAILABLE_STATUSES`: `ACTIVE`, `TRIALING`, `IN_GRACE_PERIOD`, the statuses that
|
|
45
|
+
- `AVAILABLE_STATUSES`: `ACTIVE`, `TRIALING`, `IN_GRACE_PERIOD`, `PAST_DUE`, the statuses that
|
|
46
|
+
grant access. A failing renewal keeps access while the store retries and means the customer to
|
|
47
|
+
be served: `IN_GRACE_PERIOD` on the App Store and Play, `PAST_DUE` on Stripe (Smart Retries are
|
|
48
|
+
Stripe's grace period). It loses access once the store has given up (`UNPAID`) or retries
|
|
49
|
+
without serving the customer (`ON_HOLD`: Play's account hold, and an App Store billing retry
|
|
50
|
+
without a grace period, which a host's Apple mapper should map to `ON_HOLD`, not `PAST_DUE`).
|
|
46
51
|
- `CancellationDetails`: why a subscription stopped renewing, one record for all platforms:
|
|
47
52
|
`initiator` (`CANCELLATION_INITIATORS`: `user`, `system`, `developer`), the store's own `reason`,
|
|
48
53
|
`feedback` (`CANCELLATION_FEEDBACKS`), `comment` and `resubscribeIntent` (`RESUBSCRIBE_INTENTS`).
|
|
@@ -79,7 +79,8 @@ const CLOSED_DISPUTE_STATUSES = [
|
|
|
79
79
|
* [Stripe Subscription Status](https://stripe.com/docs/api/subscriptions/object#subscription_object-status)
|
|
80
80
|
* [Stripe Subscription Lifecycle](https://docs.stripe.com/billing/subscriptions/overview)
|
|
81
81
|
*
|
|
82
|
-
* provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD
|
|
82
|
+
* provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD, PAST_DUE
|
|
83
|
+
* (see `AVAILABLE_STATUSES`)
|
|
83
84
|
*/
|
|
84
85
|
const SUBSCRIPTION_STATUSES = [
|
|
85
86
|
"TRIALING",
|
|
@@ -97,11 +98,18 @@ const SUBSCRIPTION_STATUSES = [
|
|
|
97
98
|
"REPLACED",
|
|
98
99
|
"EXPIRED"
|
|
99
100
|
];
|
|
100
|
-
/**
|
|
101
|
+
/**
|
|
102
|
+
* Statuses where it is safe to provision your product for the customer. A failing renewal keeps
|
|
103
|
+
* the product while the store retries and the customer is meant to be served (IN_GRACE_PERIOD on
|
|
104
|
+
* the App Store and Play, PAST_DUE on Stripe); it loses it once the store has given up (UNPAID on
|
|
105
|
+
* Stripe) or is retrying without serving the customer (ON_HOLD on Play and on the App Store without
|
|
106
|
+
* a grace period).
|
|
107
|
+
*/
|
|
101
108
|
const AVAILABLE_STATUSES = [
|
|
102
109
|
"ACTIVE",
|
|
103
110
|
"TRIALING",
|
|
104
|
-
"IN_GRACE_PERIOD"
|
|
111
|
+
"IN_GRACE_PERIOD",
|
|
112
|
+
"PAST_DUE"
|
|
105
113
|
];
|
|
106
114
|
/** Who stopped the subscription from renewing. */
|
|
107
115
|
const CANCELLATION_INITIATORS = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/subscription/index.ts"],"sourcesContent":["export const PLATFORMS = ['APPLE', 'GOOGLE', 'STRIPE'] as const;\n\nexport type Platform = (typeof PLATFORMS)[number];\n\n/**\n * What a payment was for, on every platform.\n *\n * - ONE_TIME: a one-time purchase.\n * - SUBSCRIPTION_START: the first paid charge of a subscription.\n * - SUBSCRIPTION_RENEWAL: a charge for a new billing period on the regular cycle.\n * - SUBSCRIPTION_UPDATE: a charge mid-period, outside the cycle: the proration of a plan change, or\n * a manual invoice on the subscription. Kept apart from renewals so renewal rates stay honest.\n */\nexport const PAYMENT_TYPES = [\n 'ONE_TIME',\n 'SUBSCRIPTION_START',\n 'SUBSCRIPTION_RENEWAL',\n 'SUBSCRIPTION_UPDATE',\n] as const;\n\nexport type PaymentType = (typeof PAYMENT_TYPES)[number];\n\n/**\n * Where a refund stands, on every platform. Stripe reports all of them; Apple and Google report a\n * refund once it is done (SUCCEEDED), and Apple can take it back (REVERSED, `REFUND_REVERSED`).\n */\nexport const REFUND_STATUSES = ['PENDING', 'SUCCEEDED', 'FAILED', 'CANCELED', 'REVERSED'] as const;\n\nexport type RefundStatus = (typeof REFUND_STATUSES)[number];\n\n/**\n * Where a refund may move from the status it has. Notifications arrive out of order and are\n * redelivered, so a status only ever moves forward along these edges:\n * - PENDING settles into anything (Stripe: succeeded / failed / canceled).\n * - SUCCEEDED can still become FAILED (Stripe: the money could not be returned after all) or\n * REVERSED (Apple: REFUND_REVERSED).\n * - FAILED, CANCELED and REVERSED are final: nothing a platform sends afterwards reopens them.\n * Nothing moves back to PENDING, and a status never \"moves\" to itself (a redelivery is a no-op).\n */\nexport const REFUND_STATUS_TRANSITIONS: Readonly<Record<RefundStatus, readonly RefundStatus[]>> = {\n PENDING: ['SUCCEEDED', 'FAILED', 'CANCELED', 'REVERSED'],\n SUCCEEDED: ['FAILED', 'REVERSED'],\n FAILED: [],\n CANCELED: [],\n REVERSED: [],\n};\n\n/**\n * Stripe's dispute statuses, as they are: the `warning_*` ones are inquiries and early fraud\n * warnings that may never become a chargeback, `prevented` is one Stripe blocked before it was\n * filed. Only LOST costs money. Stripe only: Apple and Google absorb chargebacks themselves and\n * report them as refunds.\n */\nexport const DISPUTE_STATUSES = [\n 'WARNING_NEEDS_RESPONSE',\n 'WARNING_UNDER_REVIEW',\n 'WARNING_CLOSED',\n 'NEEDS_RESPONSE',\n 'UNDER_REVIEW',\n 'PREVENTED',\n 'WON',\n 'LOST',\n] as const;\n\nexport type DisputeStatus = (typeof DISPUTE_STATUSES)[number];\n\n/** A dispute in one of these is over; nothing Stripe sends afterwards reopens it. */\nexport const CLOSED_DISPUTE_STATUSES: readonly DisputeStatus[] = [\n 'WON',\n 'LOST',\n 'WARNING_CLOSED',\n 'PREVENTED',\n];\n\n/**\n * [Stripe Subscription Status](https://stripe.com/docs/api/subscriptions/object#subscription_object-status)\n * [Stripe Subscription Lifecycle](https://docs.stripe.com/billing/subscriptions/overview)\n *\n * provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD\n */\nexport const SUBSCRIPTION_STATUSES = [\n /**\n * The subscription is currently in a trial period and it’s safe to provision your product for\n * your customer. The subscription transitions automatically to active when the first payment\n * is made.\n *\n * Google: play(LineItems[0].OfferDetails.OfferId == 'xx')\n *\n * Platform: Apple, Google, Stripe\n * */\n 'TRIALING',\n\n /**\n * The subscription is in good standing and the most recent payment is successful. It’s safe to\n * provision your product for your customer.\n *\n * Platform: Apple, Google, Stripe\n * */\n 'ACTIVE',\n\n /**\n * Apple: The subscription enters the billing retry period. If the subtype is GRACE_PERIOD,\n * continue to provide service through the grace period. If the subtype is empty, the\n * subscription isn’t in a grace period and you can stop providing the subscription service.\n *\n * Google: Subscription is in grace period. The state is only available when the subscription\n * is an auto renewing plan. In this state, all items are in grace period.\n *\n * Platform: Apple, Google\n * */\n 'IN_GRACE_PERIOD',\n\n /**\n * A successful payment needs to be made within 23 hours to activate the subscription. Or the\n * payment requires action, like customer authentication. Subscriptions can also be incomplete\n * if there’s a pending payment and the PaymentIntent status would be processing.\n *\n * Platform: Stripe\n * */\n 'INCOMPLETE',\n\n /**\n * The initial payment on the subscription failed and no successful payment was made within 23\n * hours of creating the subscription. These subscriptions don’t bill customers. This status\n * exists so you can track customers that failed to activate their subscriptions.\n *\n * Platform: Stripe\n * */\n 'INCOMPLETE_EXPIRED',\n\n /**\n * Subscription was created but awaiting payment during signup. In this state, all items are\n * awaiting payment.\n *\n * Platform: Google\n * */\n 'PENDING',\n\n /**\n * Pending transaction for subscription is canceled. If this pending purchase was for an\n * existing subscription, use linkedPurchaseToken to get the current state of that subscription.\n *\n * Platform: Google\n * */\n 'PENDING_PURCHASE_CANCELED',\n\n /**\n * Payment on the latest finalized invoice either failed or wasn’t attempted. The subscription\n * continues to create invoices. Your subscription settings determine the subscription’s next\n * state. If the invoice is still unpaid after all Smart Retries have been attempted, you can\n * configure the subscription to move to canceled, unpaid, or leave it as past_due. To move the\n * subscription to active, pay the most recent invoice before its due date.\n *\n * Platform: Stripe\n * */\n 'PAST_DUE',\n\n /**\n * Subscription is on hold (suspended). The state is only available when the subscription is an\n * auto renewing plan. In this state, all items are on hold. Grace period ends or Active period\n * ends but not grace period\n *\n * Platform: Google\n * */\n 'ON_HOLD',\n\n /**\n * The subscription has been canceled. During cancellation, automatic collection for all unpaid\n * invoices is disabled (auto_advance=false). This is a terminal state that can’t be updated.\n *\n * Platform: Apple, Google, Stripe\n * */\n 'CANCELED',\n\n /**\n * The latest invoice hasn’t been paid but the subscription remains in place. The latest invoice\n * remains open and invoices continue to be generated but payments aren’t attempted. You should\n * revoke access to your product when the subscription is unpaid since payments were already\n * attempted and retried when it was past_due. To move the subscription to active, pay the most\n * recent invoice before its due date.\n *\n * Platform: Stripe\n * */\n 'UNPAID',\n\n /**\n * Google: Subscription is paused. The state is only available when the subscription is an auto\n * renewing plan. In this state, all items are in paused state.\n *\n * Stripe: The subscription has ended its trial period without a default payment method and the\n * trial_settings.end_behavior.missing_payment_method is set to pause. Invoices will no longer\n * be created for the subscription. After a default payment method has been attached to the\n * customer, you can resume the subscription.\n *\n * Platform: Google, Stripe\n * */\n 'PAUSED',\n\n /**\n * For example, a user buys a subscription and receives a purchase token A. The\n * linkedPurchaseToken field will not be set in the API response because the purchase token\n * belongs to a brand new subscription.\n *\n * If the user upgrades their subscription, a new purchase token B will be generated. Since the\n * upgrade is replacing the subscription from purchase token A, the linkedPurchaseToken field\n * for token B will be set to point to token A. Notice it points backwards in time to the\n * original purchase token.\n *\n * +---------------------------+ +------------------------+ +------------------------+\n * | Step 1 first purchase | | Step 2 upgrades | | Step 3 downgrades |\n * | purchaseToken: A |->| purchaseToken: B |->| purchaseToken: C |\n * | linkedPurchaseToken: null | | linkedPurchaseToken: A | | linkedPurchaseToken: B |\n * +---------------------------+ +------------------------+ +------------------------+\n *\n * Platform: Google\n * */\n 'REPLACED',\n\n /**\n * Google: Subscription is expired. All items have expiryTime in the past.\n *\n * Platform: Apple, Google\n * */\n 'EXPIRED',\n] as const;\n\nexport type SubscriptionStatus = (typeof SUBSCRIPTION_STATUSES)[number];\n\n/** statuses where it is safe to provision your product for the customer */\nexport const AVAILABLE_STATUSES = [\n 'ACTIVE',\n 'TRIALING',\n 'IN_GRACE_PERIOD',\n] as const satisfies readonly SubscriptionStatus[];\n\n/** Who stopped the subscription from renewing. */\nexport const CANCELLATION_INITIATORS = [\n /** The customer: the store's cancel flow, our own cancel dialog, or a declined price increase. */\n 'user',\n /** The platform: a failed payment, a refund or revocation, a product no longer for sale. */\n 'system',\n /** Us: a cancellation through the platform's API or console. */\n 'developer',\n] as const;\n\nexport type CancellationInitiator = (typeof CANCELLATION_INITIATORS)[number];\n\n/** What a cancel survey may report, whichever platform asked the question. */\nexport const CANCELLATION_FEEDBACKS = [\n 'customer_service',\n 'low_quality',\n 'missing_features',\n 'switched_service',\n 'too_complex',\n 'too_expensive',\n 'unused',\n 'other',\n] as const;\n\nexport type CancellationFeedback = (typeof CANCELLATION_FEEDBACKS)[number];\n\nexport const RESUBSCRIBE_INTENTS = ['maybe', 'no', 'yes'] as const;\n\nexport type ResubscribeIntent = (typeof RESUBSCRIBE_INTENTS)[number];\n\n/**\n * Why a subscription stopped renewing, in one record shared by every platform. Every key is\n * optional and every value a string, so a platform may add what only it reports without a\n * schema change; the keys below are the ones they have in common. When the subscription was\n * cancelled is not in here: it is a column of its own, `canceledAt`.\n *\n * - `initiator`: see {@link CANCELLATION_INITIATORS}.\n * - `reason`: the platform's own code, kept verbatim for analytics — Stripe's\n * `cancellation_details.reason`, Google's `cancelSurveyResult.reason`, Apple's notification\n * subtype or `expirationIntent`.\n * - `feedback`: the customer's survey answer in the shared vocabulary {@link CANCELLATION_FEEDBACKS}.\n * - `comment`: free text the customer typed.\n * - `resubscribeIntent`: whether they said they would come back, when the cancel flow asked.\n */\nexport interface CancellationDetails {\n [key: string]: string | null | undefined;\n initiator?: CancellationInitiator | null;\n reason?: string | null;\n feedback?: CancellationFeedback | null;\n comment?: string | null;\n resubscribeIntent?: ResubscribeIntent | null;\n}\n"],"mappings":";;AAAA,MAAa,YAAY;CAAC;CAAS;CAAU;AAAQ;;;;;;;;;;AAarD,MAAa,gBAAgB;CAC3B;CACA;CACA;CACA;AACF;;;;;AAQA,MAAa,kBAAkB;CAAC;CAAW;CAAa;CAAU;CAAY;AAAU;;;;;;;;;;AAaxF,MAAa,4BAAqF;CAChG,SAAS;EAAC;EAAa;EAAU;EAAY;CAAU;CACvD,WAAW,CAAC,UAAU,UAAU;CAChC,QAAQ,CAAC;CACT,UAAU,CAAC;CACX,UAAU,CAAC;AACb;;;;;;;AAQA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAKA,MAAa,0BAAoD;CAC/D;CACA;CACA;CACA;AACF;;;;;;;AAQA,MAAa,wBAAwB;CAUnC;CAQA;CAYA;CASA;CASA;CAQA;CAQA;CAWA;CASA;CAQA;CAWA;CAaA;CAoBA;CAOA;AACF;;AAKA,MAAa,qBAAqB;CAChC;CACA;CACA;AACF;;AAGA,MAAa,0BAA0B;CAErC;CAEA;CAEA;AACF;;AAKA,MAAa,yBAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,sBAAsB;CAAC;CAAS;CAAM;AAAK"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/subscription/index.ts"],"sourcesContent":["export const PLATFORMS = ['APPLE', 'GOOGLE', 'STRIPE'] as const;\n\nexport type Platform = (typeof PLATFORMS)[number];\n\n/**\n * What a payment was for, on every platform.\n *\n * - ONE_TIME: a one-time purchase.\n * - SUBSCRIPTION_START: the first paid charge of a subscription.\n * - SUBSCRIPTION_RENEWAL: a charge for a new billing period on the regular cycle.\n * - SUBSCRIPTION_UPDATE: a charge mid-period, outside the cycle: the proration of a plan change, or\n * a manual invoice on the subscription. Kept apart from renewals so renewal rates stay honest.\n */\nexport const PAYMENT_TYPES = [\n 'ONE_TIME',\n 'SUBSCRIPTION_START',\n 'SUBSCRIPTION_RENEWAL',\n 'SUBSCRIPTION_UPDATE',\n] as const;\n\nexport type PaymentType = (typeof PAYMENT_TYPES)[number];\n\n/**\n * Where a refund stands, on every platform. Stripe reports all of them; Apple and Google report a\n * refund once it is done (SUCCEEDED), and Apple can take it back (REVERSED, `REFUND_REVERSED`).\n */\nexport const REFUND_STATUSES = ['PENDING', 'SUCCEEDED', 'FAILED', 'CANCELED', 'REVERSED'] as const;\n\nexport type RefundStatus = (typeof REFUND_STATUSES)[number];\n\n/**\n * Where a refund may move from the status it has. Notifications arrive out of order and are\n * redelivered, so a status only ever moves forward along these edges:\n * - PENDING settles into anything (Stripe: succeeded / failed / canceled).\n * - SUCCEEDED can still become FAILED (Stripe: the money could not be returned after all) or\n * REVERSED (Apple: REFUND_REVERSED).\n * - FAILED, CANCELED and REVERSED are final: nothing a platform sends afterwards reopens them.\n * Nothing moves back to PENDING, and a status never \"moves\" to itself (a redelivery is a no-op).\n */\nexport const REFUND_STATUS_TRANSITIONS: Readonly<Record<RefundStatus, readonly RefundStatus[]>> = {\n PENDING: ['SUCCEEDED', 'FAILED', 'CANCELED', 'REVERSED'],\n SUCCEEDED: ['FAILED', 'REVERSED'],\n FAILED: [],\n CANCELED: [],\n REVERSED: [],\n};\n\n/**\n * Stripe's dispute statuses, as they are: the `warning_*` ones are inquiries and early fraud\n * warnings that may never become a chargeback, `prevented` is one Stripe blocked before it was\n * filed. Only LOST costs money. Stripe only: Apple and Google absorb chargebacks themselves and\n * report them as refunds.\n */\nexport const DISPUTE_STATUSES = [\n 'WARNING_NEEDS_RESPONSE',\n 'WARNING_UNDER_REVIEW',\n 'WARNING_CLOSED',\n 'NEEDS_RESPONSE',\n 'UNDER_REVIEW',\n 'PREVENTED',\n 'WON',\n 'LOST',\n] as const;\n\nexport type DisputeStatus = (typeof DISPUTE_STATUSES)[number];\n\n/** A dispute in one of these is over; nothing Stripe sends afterwards reopens it. */\nexport const CLOSED_DISPUTE_STATUSES: readonly DisputeStatus[] = [\n 'WON',\n 'LOST',\n 'WARNING_CLOSED',\n 'PREVENTED',\n];\n\n/**\n * [Stripe Subscription Status](https://stripe.com/docs/api/subscriptions/object#subscription_object-status)\n * [Stripe Subscription Lifecycle](https://docs.stripe.com/billing/subscriptions/overview)\n *\n * provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD, PAST_DUE\n * (see `AVAILABLE_STATUSES`)\n */\nexport const SUBSCRIPTION_STATUSES = [\n /**\n * The subscription is currently in a trial period and it’s safe to provision your product for\n * your customer. The subscription transitions automatically to active when the first payment\n * is made.\n *\n * Google: play(LineItems[0].OfferDetails.OfferId == 'xx')\n *\n * Platform: Apple, Google, Stripe\n * */\n 'TRIALING',\n\n /**\n * The subscription is in good standing and the most recent payment is successful. It’s safe to\n * provision your product for your customer.\n *\n * Platform: Apple, Google, Stripe\n * */\n 'ACTIVE',\n\n /**\n * Apple: The subscription enters the billing retry period. If the subtype is GRACE_PERIOD,\n * continue to provide service through the grace period. If the subtype is empty, the\n * subscription isn’t in a grace period and you can stop providing the subscription service.\n *\n * Google: Subscription is in grace period. The state is only available when the subscription\n * is an auto renewing plan. In this state, all items are in grace period.\n *\n * Platform: Apple, Google\n * */\n 'IN_GRACE_PERIOD',\n\n /**\n * A successful payment needs to be made within 23 hours to activate the subscription. Or the\n * payment requires action, like customer authentication. Subscriptions can also be incomplete\n * if there’s a pending payment and the PaymentIntent status would be processing.\n *\n * Platform: Stripe\n * */\n 'INCOMPLETE',\n\n /**\n * The initial payment on the subscription failed and no successful payment was made within 23\n * hours of creating the subscription. These subscriptions don’t bill customers. This status\n * exists so you can track customers that failed to activate their subscriptions.\n *\n * Platform: Stripe\n * */\n 'INCOMPLETE_EXPIRED',\n\n /**\n * Subscription was created but awaiting payment during signup. In this state, all items are\n * awaiting payment.\n *\n * Platform: Google\n * */\n 'PENDING',\n\n /**\n * Pending transaction for subscription is canceled. If this pending purchase was for an\n * existing subscription, use linkedPurchaseToken to get the current state of that subscription.\n *\n * Platform: Google\n * */\n 'PENDING_PURCHASE_CANCELED',\n\n /**\n * Payment on the latest finalized invoice either failed or wasn’t attempted. The subscription\n * continues to create invoices. Your subscription settings determine the subscription’s next\n * state. If the invoice is still unpaid after all Smart Retries have been attempted, you can\n * configure the subscription to move to canceled, unpaid, or leave it as past_due. To move the\n * subscription to active, pay the most recent invoice before its due date.\n *\n * This is Stripe's grace period: the customer keeps the product while Stripe retries (Smart\n * Retries, up to about three weeks), as an App Store or Play customer does in IN_GRACE_PERIOD,\n * so it is in `AVAILABLE_STATUSES`. A retry the customer is not served through (an App Store\n * billing retry without a grace period) is ON_HOLD, not PAST_DUE.\n *\n * Platform: Stripe\n * */\n 'PAST_DUE',\n\n /**\n * Google: Subscription is on hold (suspended). The state is only available when the\n * subscription is an auto renewing plan. In this state, all items are on hold. Grace period\n * ends or Active period ends but not grace period.\n *\n * Apple: the billing retry period of a subscription that has no grace period (or whose grace\n * period ended). Apple keeps retrying the charge for up to 60 days; the subscription is not\n * over, but the customer is not served meanwhile.\n *\n * Either way the store is still trying to collect and the customer has no access until a\n * payment goes through; the way out is a working payment method.\n *\n * Platform: Apple, Google\n * */\n 'ON_HOLD',\n\n /**\n * The subscription has been canceled. During cancellation, automatic collection for all unpaid\n * invoices is disabled (auto_advance=false). This is a terminal state that can’t be updated.\n *\n * Platform: Apple, Google, Stripe\n * */\n 'CANCELED',\n\n /**\n * The latest invoice hasn’t been paid but the subscription remains in place. The latest invoice\n * remains open and invoices continue to be generated but payments aren’t attempted. You should\n * revoke access to your product when the subscription is unpaid since payments were already\n * attempted and retried when it was past_due. To move the subscription to active, pay the most\n * recent invoice before its due date.\n *\n * Platform: Stripe\n * */\n 'UNPAID',\n\n /**\n * Google: Subscription is paused. The state is only available when the subscription is an auto\n * renewing plan. In this state, all items are in paused state.\n *\n * Stripe: The subscription has ended its trial period without a default payment method and the\n * trial_settings.end_behavior.missing_payment_method is set to pause. Invoices will no longer\n * be created for the subscription. After a default payment method has been attached to the\n * customer, you can resume the subscription.\n *\n * Platform: Google, Stripe\n * */\n 'PAUSED',\n\n /**\n * For example, a user buys a subscription and receives a purchase token A. The\n * linkedPurchaseToken field will not be set in the API response because the purchase token\n * belongs to a brand new subscription.\n *\n * If the user upgrades their subscription, a new purchase token B will be generated. Since the\n * upgrade is replacing the subscription from purchase token A, the linkedPurchaseToken field\n * for token B will be set to point to token A. Notice it points backwards in time to the\n * original purchase token.\n *\n * +---------------------------+ +------------------------+ +------------------------+\n * | Step 1 first purchase | | Step 2 upgrades | | Step 3 downgrades |\n * | purchaseToken: A |->| purchaseToken: B |->| purchaseToken: C |\n * | linkedPurchaseToken: null | | linkedPurchaseToken: A | | linkedPurchaseToken: B |\n * +---------------------------+ +------------------------+ +------------------------+\n *\n * Platform: Google\n * */\n 'REPLACED',\n\n /**\n * Google: Subscription is expired. All items have expiryTime in the past.\n *\n * Platform: Apple, Google\n * */\n 'EXPIRED',\n] as const;\n\nexport type SubscriptionStatus = (typeof SUBSCRIPTION_STATUSES)[number];\n\n/**\n * Statuses where it is safe to provision your product for the customer. A failing renewal keeps\n * the product while the store retries and the customer is meant to be served (IN_GRACE_PERIOD on\n * the App Store and Play, PAST_DUE on Stripe); it loses it once the store has given up (UNPAID on\n * Stripe) or is retrying without serving the customer (ON_HOLD on Play and on the App Store without\n * a grace period).\n */\nexport const AVAILABLE_STATUSES = [\n 'ACTIVE',\n 'TRIALING',\n 'IN_GRACE_PERIOD',\n 'PAST_DUE',\n] as const satisfies readonly SubscriptionStatus[];\n\n/** Who stopped the subscription from renewing. */\nexport const CANCELLATION_INITIATORS = [\n /** The customer: the store's cancel flow, our own cancel dialog, or a declined price increase. */\n 'user',\n /** The platform: a failed payment, a refund or revocation, a product no longer for sale. */\n 'system',\n /** Us: a cancellation through the platform's API or console. */\n 'developer',\n] as const;\n\nexport type CancellationInitiator = (typeof CANCELLATION_INITIATORS)[number];\n\n/** What a cancel survey may report, whichever platform asked the question. */\nexport const CANCELLATION_FEEDBACKS = [\n 'customer_service',\n 'low_quality',\n 'missing_features',\n 'switched_service',\n 'too_complex',\n 'too_expensive',\n 'unused',\n 'other',\n] as const;\n\nexport type CancellationFeedback = (typeof CANCELLATION_FEEDBACKS)[number];\n\nexport const RESUBSCRIBE_INTENTS = ['maybe', 'no', 'yes'] as const;\n\nexport type ResubscribeIntent = (typeof RESUBSCRIBE_INTENTS)[number];\n\n/**\n * Why a subscription stopped renewing, in one record shared by every platform. Every key is\n * optional and every value a string, so a platform may add what only it reports without a\n * schema change; the keys below are the ones they have in common. When the subscription was\n * cancelled is not in here: it is a column of its own, `canceledAt`.\n *\n * - `initiator`: see {@link CANCELLATION_INITIATORS}.\n * - `reason`: the platform's own code, kept verbatim for analytics — Stripe's\n * `cancellation_details.reason`, Google's `cancelSurveyResult.reason`, Apple's notification\n * subtype or `expirationIntent`.\n * - `feedback`: the customer's survey answer in the shared vocabulary {@link CANCELLATION_FEEDBACKS}.\n * - `comment`: free text the customer typed.\n * - `resubscribeIntent`: whether they said they would come back, when the cancel flow asked.\n */\nexport interface CancellationDetails {\n [key: string]: string | null | undefined;\n initiator?: CancellationInitiator | null;\n reason?: string | null;\n feedback?: CancellationFeedback | null;\n comment?: string | null;\n resubscribeIntent?: ResubscribeIntent | null;\n}\n"],"mappings":";;AAAA,MAAa,YAAY;CAAC;CAAS;CAAU;AAAQ;;;;;;;;;;AAarD,MAAa,gBAAgB;CAC3B;CACA;CACA;CACA;AACF;;;;;AAQA,MAAa,kBAAkB;CAAC;CAAW;CAAa;CAAU;CAAY;AAAU;;;;;;;;;;AAaxF,MAAa,4BAAqF;CAChG,SAAS;EAAC;EAAa;EAAU;EAAY;CAAU;CACvD,WAAW,CAAC,UAAU,UAAU;CAChC,QAAQ,CAAC;CACT,UAAU,CAAC;CACX,UAAU,CAAC;AACb;;;;;;;AAQA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAKA,MAAa,0BAAoD;CAC/D;CACA;CACA;CACA;AACF;;;;;;;;AASA,MAAa,wBAAwB;CAUnC;CAQA;CAYA;CASA;CASA;CAQA;CAQA;CAgBA;CAgBA;CAQA;CAWA;CAaA;CAoBA;CAOA;AACF;;;;;;;;AAWA,MAAa,qBAAqB;CAChC;CACA;CACA;CACA;AACF;;AAGA,MAAa,0BAA0B;CAErC;CAEA;CAEA;AACF;;AAKA,MAAa,yBAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,sBAAsB;CAAC;CAAS;CAAM;AAAK"}
|
|
@@ -42,7 +42,8 @@ export declare const CLOSED_DISPUTE_STATUSES: readonly DisputeStatus[];
|
|
|
42
42
|
* [Stripe Subscription Status](https://stripe.com/docs/api/subscriptions/object#subscription_object-status)
|
|
43
43
|
* [Stripe Subscription Lifecycle](https://docs.stripe.com/billing/subscriptions/overview)
|
|
44
44
|
*
|
|
45
|
-
* provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD
|
|
45
|
+
* provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD, PAST_DUE
|
|
46
|
+
* (see `AVAILABLE_STATUSES`)
|
|
46
47
|
*/
|
|
47
48
|
export declare const SUBSCRIPTION_STATUSES: readonly [
|
|
48
49
|
/**
|
|
@@ -110,15 +111,27 @@ export declare const SUBSCRIPTION_STATUSES: readonly [
|
|
|
110
111
|
* configure the subscription to move to canceled, unpaid, or leave it as past_due. To move the
|
|
111
112
|
* subscription to active, pay the most recent invoice before its due date.
|
|
112
113
|
*
|
|
114
|
+
* This is Stripe's grace period: the customer keeps the product while Stripe retries (Smart
|
|
115
|
+
* Retries, up to about three weeks), as an App Store or Play customer does in IN_GRACE_PERIOD,
|
|
116
|
+
* so it is in `AVAILABLE_STATUSES`. A retry the customer is not served through (an App Store
|
|
117
|
+
* billing retry without a grace period) is ON_HOLD, not PAST_DUE.
|
|
118
|
+
*
|
|
113
119
|
* Platform: Stripe
|
|
114
120
|
* */
|
|
115
121
|
'PAST_DUE',
|
|
116
122
|
/**
|
|
117
|
-
* Subscription is on hold (suspended). The state is only available when the
|
|
118
|
-
* auto renewing plan. In this state, all items are on hold. Grace period
|
|
119
|
-
* ends but not grace period
|
|
123
|
+
* Google: Subscription is on hold (suspended). The state is only available when the
|
|
124
|
+
* subscription is an auto renewing plan. In this state, all items are on hold. Grace period
|
|
125
|
+
* ends or Active period ends but not grace period.
|
|
120
126
|
*
|
|
121
|
-
*
|
|
127
|
+
* Apple: the billing retry period of a subscription that has no grace period (or whose grace
|
|
128
|
+
* period ended). Apple keeps retrying the charge for up to 60 days; the subscription is not
|
|
129
|
+
* over, but the customer is not served meanwhile.
|
|
130
|
+
*
|
|
131
|
+
* Either way the store is still trying to collect and the customer has no access until a
|
|
132
|
+
* payment goes through; the way out is a working payment method.
|
|
133
|
+
*
|
|
134
|
+
* Platform: Apple, Google
|
|
122
135
|
* */
|
|
123
136
|
'ON_HOLD',
|
|
124
137
|
/**
|
|
@@ -176,8 +189,14 @@ export declare const SUBSCRIPTION_STATUSES: readonly [
|
|
|
176
189
|
* */
|
|
177
190
|
'EXPIRED'];
|
|
178
191
|
export type SubscriptionStatus = (typeof SUBSCRIPTION_STATUSES)[number];
|
|
179
|
-
/**
|
|
180
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Statuses where it is safe to provision your product for the customer. A failing renewal keeps
|
|
194
|
+
* the product while the store retries and the customer is meant to be served (IN_GRACE_PERIOD on
|
|
195
|
+
* the App Store and Play, PAST_DUE on Stripe); it loses it once the store has given up (UNPAID on
|
|
196
|
+
* Stripe) or is retrying without serving the customer (ON_HOLD on Play and on the App Store without
|
|
197
|
+
* a grace period).
|
|
198
|
+
*/
|
|
199
|
+
export declare const AVAILABLE_STATUSES: readonly ["ACTIVE", "TRIALING", "IN_GRACE_PERIOD", "PAST_DUE"];
|
|
181
200
|
/** Who stopped the subscription from renewing. */
|
|
182
201
|
export declare const CANCELLATION_INITIATORS: readonly [
|
|
183
202
|
/** The customer: the store's cancel flow, our own cancel dialog, or a declined price increase. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/subscription/index.ts"],"mappings":";qBAAa;YAED,mBAAmB;;;;;;;;;;qBAWlB;YAOD,sBAAsB;;;;;qBAMrB;YAED,uBAAuB;;;;;;;;;;qBAWtB,2BAA2B,SAAS,OAAO,uBAAuB;;;;;;;qBAclE;YAWD,wBAAwB;;qBAGvB,kCAAkC
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../../src/subscription/index.ts"],"mappings":";qBAAa;YAED,mBAAmB;;;;;;;;;;qBAWlB;YAOD,sBAAsB;;;;;qBAMrB;YAED,uBAAuB;;;;;;;;;;qBAWtB,2BAA2B,SAAS,OAAO,uBAAuB;;;;;;;qBAclE;YAWD,wBAAwB;;qBAGvB,kCAAkC;;;;;;;;qBAclC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA8JD,6BAA6B;;;;;;;;qBAS5B;;qBAQA;;;;;;;YASD,gCAAgC;;qBAG/B;YAWD,+BAA+B;qBAE9B;YAED,4BAA4B;;;;;;;;;;;;;;;iBAgBvB;GACd;EACD,YAAY;EACZ;EACA,WAAW;EACX;EACA,oBAAoB"}
|
|
@@ -42,7 +42,8 @@ export declare const CLOSED_DISPUTE_STATUSES: readonly DisputeStatus[];
|
|
|
42
42
|
* [Stripe Subscription Status](https://stripe.com/docs/api/subscriptions/object#subscription_object-status)
|
|
43
43
|
* [Stripe Subscription Lifecycle](https://docs.stripe.com/billing/subscriptions/overview)
|
|
44
44
|
*
|
|
45
|
-
* provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD
|
|
45
|
+
* provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD, PAST_DUE
|
|
46
|
+
* (see `AVAILABLE_STATUSES`)
|
|
46
47
|
*/
|
|
47
48
|
export declare const SUBSCRIPTION_STATUSES: readonly [
|
|
48
49
|
/**
|
|
@@ -110,15 +111,27 @@ export declare const SUBSCRIPTION_STATUSES: readonly [
|
|
|
110
111
|
* configure the subscription to move to canceled, unpaid, or leave it as past_due. To move the
|
|
111
112
|
* subscription to active, pay the most recent invoice before its due date.
|
|
112
113
|
*
|
|
114
|
+
* This is Stripe's grace period: the customer keeps the product while Stripe retries (Smart
|
|
115
|
+
* Retries, up to about three weeks), as an App Store or Play customer does in IN_GRACE_PERIOD,
|
|
116
|
+
* so it is in `AVAILABLE_STATUSES`. A retry the customer is not served through (an App Store
|
|
117
|
+
* billing retry without a grace period) is ON_HOLD, not PAST_DUE.
|
|
118
|
+
*
|
|
113
119
|
* Platform: Stripe
|
|
114
120
|
* */
|
|
115
121
|
'PAST_DUE',
|
|
116
122
|
/**
|
|
117
|
-
* Subscription is on hold (suspended). The state is only available when the
|
|
118
|
-
* auto renewing plan. In this state, all items are on hold. Grace period
|
|
119
|
-
* ends but not grace period
|
|
123
|
+
* Google: Subscription is on hold (suspended). The state is only available when the
|
|
124
|
+
* subscription is an auto renewing plan. In this state, all items are on hold. Grace period
|
|
125
|
+
* ends or Active period ends but not grace period.
|
|
120
126
|
*
|
|
121
|
-
*
|
|
127
|
+
* Apple: the billing retry period of a subscription that has no grace period (or whose grace
|
|
128
|
+
* period ended). Apple keeps retrying the charge for up to 60 days; the subscription is not
|
|
129
|
+
* over, but the customer is not served meanwhile.
|
|
130
|
+
*
|
|
131
|
+
* Either way the store is still trying to collect and the customer has no access until a
|
|
132
|
+
* payment goes through; the way out is a working payment method.
|
|
133
|
+
*
|
|
134
|
+
* Platform: Apple, Google
|
|
122
135
|
* */
|
|
123
136
|
'ON_HOLD',
|
|
124
137
|
/**
|
|
@@ -176,8 +189,14 @@ export declare const SUBSCRIPTION_STATUSES: readonly [
|
|
|
176
189
|
* */
|
|
177
190
|
'EXPIRED'];
|
|
178
191
|
export type SubscriptionStatus = (typeof SUBSCRIPTION_STATUSES)[number];
|
|
179
|
-
/**
|
|
180
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Statuses where it is safe to provision your product for the customer. A failing renewal keeps
|
|
194
|
+
* the product while the store retries and the customer is meant to be served (IN_GRACE_PERIOD on
|
|
195
|
+
* the App Store and Play, PAST_DUE on Stripe); it loses it once the store has given up (UNPAID on
|
|
196
|
+
* Stripe) or is retrying without serving the customer (ON_HOLD on Play and on the App Store without
|
|
197
|
+
* a grace period).
|
|
198
|
+
*/
|
|
199
|
+
export declare const AVAILABLE_STATUSES: readonly ["ACTIVE", "TRIALING", "IN_GRACE_PERIOD", "PAST_DUE"];
|
|
181
200
|
/** Who stopped the subscription from renewing. */
|
|
182
201
|
export declare const CANCELLATION_INITIATORS: readonly [
|
|
183
202
|
/** The customer: the store's cancel flow, our own cancel dialog, or a declined price increase. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/subscription/index.ts"],"mappings":";qBAAa;YAED,mBAAmB;;;;;;;;;;qBAWlB;YAOD,sBAAsB;;;;;qBAMrB;YAED,uBAAuB;;;;;;;;;;qBAWtB,2BAA2B,SAAS,OAAO,uBAAuB;;;;;;;qBAclE;YAWD,wBAAwB;;qBAGvB,kCAAkC
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/subscription/index.ts"],"mappings":";qBAAa;YAED,mBAAmB;;;;;;;;;;qBAWlB;YAOD,sBAAsB;;;;;qBAMrB;YAED,uBAAuB;;;;;;;;;;qBAWtB,2BAA2B,SAAS,OAAO,uBAAuB;;;;;;;qBAclE;YAWD,wBAAwB;;qBAGvB,kCAAkC;;;;;;;;qBAclC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;YA8JD,6BAA6B;;;;;;;;qBAS5B;;qBAQA;;;;;;;YASD,gCAAgC;;qBAG/B;YAWD,+BAA+B;qBAE9B;YAED,4BAA4B;;;;;;;;;;;;;;;iBAgBvB;GACd;EACD,YAAY;EACZ;EACA,WAAW;EACX;EACA,oBAAoB"}
|
|
@@ -78,7 +78,8 @@ const CLOSED_DISPUTE_STATUSES = [
|
|
|
78
78
|
* [Stripe Subscription Status](https://stripe.com/docs/api/subscriptions/object#subscription_object-status)
|
|
79
79
|
* [Stripe Subscription Lifecycle](https://docs.stripe.com/billing/subscriptions/overview)
|
|
80
80
|
*
|
|
81
|
-
* provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD
|
|
81
|
+
* provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD, PAST_DUE
|
|
82
|
+
* (see `AVAILABLE_STATUSES`)
|
|
82
83
|
*/
|
|
83
84
|
const SUBSCRIPTION_STATUSES = [
|
|
84
85
|
"TRIALING",
|
|
@@ -96,11 +97,18 @@ const SUBSCRIPTION_STATUSES = [
|
|
|
96
97
|
"REPLACED",
|
|
97
98
|
"EXPIRED"
|
|
98
99
|
];
|
|
99
|
-
/**
|
|
100
|
+
/**
|
|
101
|
+
* Statuses where it is safe to provision your product for the customer. A failing renewal keeps
|
|
102
|
+
* the product while the store retries and the customer is meant to be served (IN_GRACE_PERIOD on
|
|
103
|
+
* the App Store and Play, PAST_DUE on Stripe); it loses it once the store has given up (UNPAID on
|
|
104
|
+
* Stripe) or is retrying without serving the customer (ON_HOLD on Play and on the App Store without
|
|
105
|
+
* a grace period).
|
|
106
|
+
*/
|
|
100
107
|
const AVAILABLE_STATUSES = [
|
|
101
108
|
"ACTIVE",
|
|
102
109
|
"TRIALING",
|
|
103
|
-
"IN_GRACE_PERIOD"
|
|
110
|
+
"IN_GRACE_PERIOD",
|
|
111
|
+
"PAST_DUE"
|
|
104
112
|
];
|
|
105
113
|
/** Who stopped the subscription from renewing. */
|
|
106
114
|
const CANCELLATION_INITIATORS = [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/subscription/index.ts"],"sourcesContent":["export const PLATFORMS = ['APPLE', 'GOOGLE', 'STRIPE'] as const;\n\nexport type Platform = (typeof PLATFORMS)[number];\n\n/**\n * What a payment was for, on every platform.\n *\n * - ONE_TIME: a one-time purchase.\n * - SUBSCRIPTION_START: the first paid charge of a subscription.\n * - SUBSCRIPTION_RENEWAL: a charge for a new billing period on the regular cycle.\n * - SUBSCRIPTION_UPDATE: a charge mid-period, outside the cycle: the proration of a plan change, or\n * a manual invoice on the subscription. Kept apart from renewals so renewal rates stay honest.\n */\nexport const PAYMENT_TYPES = [\n 'ONE_TIME',\n 'SUBSCRIPTION_START',\n 'SUBSCRIPTION_RENEWAL',\n 'SUBSCRIPTION_UPDATE',\n] as const;\n\nexport type PaymentType = (typeof PAYMENT_TYPES)[number];\n\n/**\n * Where a refund stands, on every platform. Stripe reports all of them; Apple and Google report a\n * refund once it is done (SUCCEEDED), and Apple can take it back (REVERSED, `REFUND_REVERSED`).\n */\nexport const REFUND_STATUSES = ['PENDING', 'SUCCEEDED', 'FAILED', 'CANCELED', 'REVERSED'] as const;\n\nexport type RefundStatus = (typeof REFUND_STATUSES)[number];\n\n/**\n * Where a refund may move from the status it has. Notifications arrive out of order and are\n * redelivered, so a status only ever moves forward along these edges:\n * - PENDING settles into anything (Stripe: succeeded / failed / canceled).\n * - SUCCEEDED can still become FAILED (Stripe: the money could not be returned after all) or\n * REVERSED (Apple: REFUND_REVERSED).\n * - FAILED, CANCELED and REVERSED are final: nothing a platform sends afterwards reopens them.\n * Nothing moves back to PENDING, and a status never \"moves\" to itself (a redelivery is a no-op).\n */\nexport const REFUND_STATUS_TRANSITIONS: Readonly<Record<RefundStatus, readonly RefundStatus[]>> = {\n PENDING: ['SUCCEEDED', 'FAILED', 'CANCELED', 'REVERSED'],\n SUCCEEDED: ['FAILED', 'REVERSED'],\n FAILED: [],\n CANCELED: [],\n REVERSED: [],\n};\n\n/**\n * Stripe's dispute statuses, as they are: the `warning_*` ones are inquiries and early fraud\n * warnings that may never become a chargeback, `prevented` is one Stripe blocked before it was\n * filed. Only LOST costs money. Stripe only: Apple and Google absorb chargebacks themselves and\n * report them as refunds.\n */\nexport const DISPUTE_STATUSES = [\n 'WARNING_NEEDS_RESPONSE',\n 'WARNING_UNDER_REVIEW',\n 'WARNING_CLOSED',\n 'NEEDS_RESPONSE',\n 'UNDER_REVIEW',\n 'PREVENTED',\n 'WON',\n 'LOST',\n] as const;\n\nexport type DisputeStatus = (typeof DISPUTE_STATUSES)[number];\n\n/** A dispute in one of these is over; nothing Stripe sends afterwards reopens it. */\nexport const CLOSED_DISPUTE_STATUSES: readonly DisputeStatus[] = [\n 'WON',\n 'LOST',\n 'WARNING_CLOSED',\n 'PREVENTED',\n];\n\n/**\n * [Stripe Subscription Status](https://stripe.com/docs/api/subscriptions/object#subscription_object-status)\n * [Stripe Subscription Lifecycle](https://docs.stripe.com/billing/subscriptions/overview)\n *\n * provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD\n */\nexport const SUBSCRIPTION_STATUSES = [\n /**\n * The subscription is currently in a trial period and it’s safe to provision your product for\n * your customer. The subscription transitions automatically to active when the first payment\n * is made.\n *\n * Google: play(LineItems[0].OfferDetails.OfferId == 'xx')\n *\n * Platform: Apple, Google, Stripe\n * */\n 'TRIALING',\n\n /**\n * The subscription is in good standing and the most recent payment is successful. It’s safe to\n * provision your product for your customer.\n *\n * Platform: Apple, Google, Stripe\n * */\n 'ACTIVE',\n\n /**\n * Apple: The subscription enters the billing retry period. If the subtype is GRACE_PERIOD,\n * continue to provide service through the grace period. If the subtype is empty, the\n * subscription isn’t in a grace period and you can stop providing the subscription service.\n *\n * Google: Subscription is in grace period. The state is only available when the subscription\n * is an auto renewing plan. In this state, all items are in grace period.\n *\n * Platform: Apple, Google\n * */\n 'IN_GRACE_PERIOD',\n\n /**\n * A successful payment needs to be made within 23 hours to activate the subscription. Or the\n * payment requires action, like customer authentication. Subscriptions can also be incomplete\n * if there’s a pending payment and the PaymentIntent status would be processing.\n *\n * Platform: Stripe\n * */\n 'INCOMPLETE',\n\n /**\n * The initial payment on the subscription failed and no successful payment was made within 23\n * hours of creating the subscription. These subscriptions don’t bill customers. This status\n * exists so you can track customers that failed to activate their subscriptions.\n *\n * Platform: Stripe\n * */\n 'INCOMPLETE_EXPIRED',\n\n /**\n * Subscription was created but awaiting payment during signup. In this state, all items are\n * awaiting payment.\n *\n * Platform: Google\n * */\n 'PENDING',\n\n /**\n * Pending transaction for subscription is canceled. If this pending purchase was for an\n * existing subscription, use linkedPurchaseToken to get the current state of that subscription.\n *\n * Platform: Google\n * */\n 'PENDING_PURCHASE_CANCELED',\n\n /**\n * Payment on the latest finalized invoice either failed or wasn’t attempted. The subscription\n * continues to create invoices. Your subscription settings determine the subscription’s next\n * state. If the invoice is still unpaid after all Smart Retries have been attempted, you can\n * configure the subscription to move to canceled, unpaid, or leave it as past_due. To move the\n * subscription to active, pay the most recent invoice before its due date.\n *\n * Platform: Stripe\n * */\n 'PAST_DUE',\n\n /**\n * Subscription is on hold (suspended). The state is only available when the subscription is an\n * auto renewing plan. In this state, all items are on hold. Grace period ends or Active period\n * ends but not grace period\n *\n * Platform: Google\n * */\n 'ON_HOLD',\n\n /**\n * The subscription has been canceled. During cancellation, automatic collection for all unpaid\n * invoices is disabled (auto_advance=false). This is a terminal state that can’t be updated.\n *\n * Platform: Apple, Google, Stripe\n * */\n 'CANCELED',\n\n /**\n * The latest invoice hasn’t been paid but the subscription remains in place. The latest invoice\n * remains open and invoices continue to be generated but payments aren’t attempted. You should\n * revoke access to your product when the subscription is unpaid since payments were already\n * attempted and retried when it was past_due. To move the subscription to active, pay the most\n * recent invoice before its due date.\n *\n * Platform: Stripe\n * */\n 'UNPAID',\n\n /**\n * Google: Subscription is paused. The state is only available when the subscription is an auto\n * renewing plan. In this state, all items are in paused state.\n *\n * Stripe: The subscription has ended its trial period without a default payment method and the\n * trial_settings.end_behavior.missing_payment_method is set to pause. Invoices will no longer\n * be created for the subscription. After a default payment method has been attached to the\n * customer, you can resume the subscription.\n *\n * Platform: Google, Stripe\n * */\n 'PAUSED',\n\n /**\n * For example, a user buys a subscription and receives a purchase token A. The\n * linkedPurchaseToken field will not be set in the API response because the purchase token\n * belongs to a brand new subscription.\n *\n * If the user upgrades their subscription, a new purchase token B will be generated. Since the\n * upgrade is replacing the subscription from purchase token A, the linkedPurchaseToken field\n * for token B will be set to point to token A. Notice it points backwards in time to the\n * original purchase token.\n *\n * +---------------------------+ +------------------------+ +------------------------+\n * | Step 1 first purchase | | Step 2 upgrades | | Step 3 downgrades |\n * | purchaseToken: A |->| purchaseToken: B |->| purchaseToken: C |\n * | linkedPurchaseToken: null | | linkedPurchaseToken: A | | linkedPurchaseToken: B |\n * +---------------------------+ +------------------------+ +------------------------+\n *\n * Platform: Google\n * */\n 'REPLACED',\n\n /**\n * Google: Subscription is expired. All items have expiryTime in the past.\n *\n * Platform: Apple, Google\n * */\n 'EXPIRED',\n] as const;\n\nexport type SubscriptionStatus = (typeof SUBSCRIPTION_STATUSES)[number];\n\n/** statuses where it is safe to provision your product for the customer */\nexport const AVAILABLE_STATUSES = [\n 'ACTIVE',\n 'TRIALING',\n 'IN_GRACE_PERIOD',\n] as const satisfies readonly SubscriptionStatus[];\n\n/** Who stopped the subscription from renewing. */\nexport const CANCELLATION_INITIATORS = [\n /** The customer: the store's cancel flow, our own cancel dialog, or a declined price increase. */\n 'user',\n /** The platform: a failed payment, a refund or revocation, a product no longer for sale. */\n 'system',\n /** Us: a cancellation through the platform's API or console. */\n 'developer',\n] as const;\n\nexport type CancellationInitiator = (typeof CANCELLATION_INITIATORS)[number];\n\n/** What a cancel survey may report, whichever platform asked the question. */\nexport const CANCELLATION_FEEDBACKS = [\n 'customer_service',\n 'low_quality',\n 'missing_features',\n 'switched_service',\n 'too_complex',\n 'too_expensive',\n 'unused',\n 'other',\n] as const;\n\nexport type CancellationFeedback = (typeof CANCELLATION_FEEDBACKS)[number];\n\nexport const RESUBSCRIBE_INTENTS = ['maybe', 'no', 'yes'] as const;\n\nexport type ResubscribeIntent = (typeof RESUBSCRIBE_INTENTS)[number];\n\n/**\n * Why a subscription stopped renewing, in one record shared by every platform. Every key is\n * optional and every value a string, so a platform may add what only it reports without a\n * schema change; the keys below are the ones they have in common. When the subscription was\n * cancelled is not in here: it is a column of its own, `canceledAt`.\n *\n * - `initiator`: see {@link CANCELLATION_INITIATORS}.\n * - `reason`: the platform's own code, kept verbatim for analytics — Stripe's\n * `cancellation_details.reason`, Google's `cancelSurveyResult.reason`, Apple's notification\n * subtype or `expirationIntent`.\n * - `feedback`: the customer's survey answer in the shared vocabulary {@link CANCELLATION_FEEDBACKS}.\n * - `comment`: free text the customer typed.\n * - `resubscribeIntent`: whether they said they would come back, when the cancel flow asked.\n */\nexport interface CancellationDetails {\n [key: string]: string | null | undefined;\n initiator?: CancellationInitiator | null;\n reason?: string | null;\n feedback?: CancellationFeedback | null;\n comment?: string | null;\n resubscribeIntent?: ResubscribeIntent | null;\n}\n"],"mappings":";AAAA,MAAa,YAAY;CAAC;CAAS;CAAU;AAAQ;;;;;;;;;;AAarD,MAAa,gBAAgB;CAC3B;CACA;CACA;CACA;AACF;;;;;AAQA,MAAa,kBAAkB;CAAC;CAAW;CAAa;CAAU;CAAY;AAAU;;;;;;;;;;AAaxF,MAAa,4BAAqF;CAChG,SAAS;EAAC;EAAa;EAAU;EAAY;CAAU;CACvD,WAAW,CAAC,UAAU,UAAU;CAChC,QAAQ,CAAC;CACT,UAAU,CAAC;CACX,UAAU,CAAC;AACb;;;;;;;AAQA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAKA,MAAa,0BAAoD;CAC/D;CACA;CACA;CACA;AACF;;;;;;;AAQA,MAAa,wBAAwB;CAUnC;CAQA;CAYA;CASA;CASA;CAQA;CAQA;CAWA;CASA;CAQA;CAWA;CAaA;CAoBA;CAOA;AACF;;AAKA,MAAa,qBAAqB;CAChC;CACA;CACA;AACF;;AAGA,MAAa,0BAA0B;CAErC;CAEA;CAEA;AACF;;AAKA,MAAa,yBAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,sBAAsB;CAAC;CAAS;CAAM;AAAK"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/subscription/index.ts"],"sourcesContent":["export const PLATFORMS = ['APPLE', 'GOOGLE', 'STRIPE'] as const;\n\nexport type Platform = (typeof PLATFORMS)[number];\n\n/**\n * What a payment was for, on every platform.\n *\n * - ONE_TIME: a one-time purchase.\n * - SUBSCRIPTION_START: the first paid charge of a subscription.\n * - SUBSCRIPTION_RENEWAL: a charge for a new billing period on the regular cycle.\n * - SUBSCRIPTION_UPDATE: a charge mid-period, outside the cycle: the proration of a plan change, or\n * a manual invoice on the subscription. Kept apart from renewals so renewal rates stay honest.\n */\nexport const PAYMENT_TYPES = [\n 'ONE_TIME',\n 'SUBSCRIPTION_START',\n 'SUBSCRIPTION_RENEWAL',\n 'SUBSCRIPTION_UPDATE',\n] as const;\n\nexport type PaymentType = (typeof PAYMENT_TYPES)[number];\n\n/**\n * Where a refund stands, on every platform. Stripe reports all of them; Apple and Google report a\n * refund once it is done (SUCCEEDED), and Apple can take it back (REVERSED, `REFUND_REVERSED`).\n */\nexport const REFUND_STATUSES = ['PENDING', 'SUCCEEDED', 'FAILED', 'CANCELED', 'REVERSED'] as const;\n\nexport type RefundStatus = (typeof REFUND_STATUSES)[number];\n\n/**\n * Where a refund may move from the status it has. Notifications arrive out of order and are\n * redelivered, so a status only ever moves forward along these edges:\n * - PENDING settles into anything (Stripe: succeeded / failed / canceled).\n * - SUCCEEDED can still become FAILED (Stripe: the money could not be returned after all) or\n * REVERSED (Apple: REFUND_REVERSED).\n * - FAILED, CANCELED and REVERSED are final: nothing a platform sends afterwards reopens them.\n * Nothing moves back to PENDING, and a status never \"moves\" to itself (a redelivery is a no-op).\n */\nexport const REFUND_STATUS_TRANSITIONS: Readonly<Record<RefundStatus, readonly RefundStatus[]>> = {\n PENDING: ['SUCCEEDED', 'FAILED', 'CANCELED', 'REVERSED'],\n SUCCEEDED: ['FAILED', 'REVERSED'],\n FAILED: [],\n CANCELED: [],\n REVERSED: [],\n};\n\n/**\n * Stripe's dispute statuses, as they are: the `warning_*` ones are inquiries and early fraud\n * warnings that may never become a chargeback, `prevented` is one Stripe blocked before it was\n * filed. Only LOST costs money. Stripe only: Apple and Google absorb chargebacks themselves and\n * report them as refunds.\n */\nexport const DISPUTE_STATUSES = [\n 'WARNING_NEEDS_RESPONSE',\n 'WARNING_UNDER_REVIEW',\n 'WARNING_CLOSED',\n 'NEEDS_RESPONSE',\n 'UNDER_REVIEW',\n 'PREVENTED',\n 'WON',\n 'LOST',\n] as const;\n\nexport type DisputeStatus = (typeof DISPUTE_STATUSES)[number];\n\n/** A dispute in one of these is over; nothing Stripe sends afterwards reopens it. */\nexport const CLOSED_DISPUTE_STATUSES: readonly DisputeStatus[] = [\n 'WON',\n 'LOST',\n 'WARNING_CLOSED',\n 'PREVENTED',\n];\n\n/**\n * [Stripe Subscription Status](https://stripe.com/docs/api/subscriptions/object#subscription_object-status)\n * [Stripe Subscription Lifecycle](https://docs.stripe.com/billing/subscriptions/overview)\n *\n * provision product for customer when Status = TRIALING, ACTIVE, IN_GRACE_PERIOD, PAST_DUE\n * (see `AVAILABLE_STATUSES`)\n */\nexport const SUBSCRIPTION_STATUSES = [\n /**\n * The subscription is currently in a trial period and it’s safe to provision your product for\n * your customer. The subscription transitions automatically to active when the first payment\n * is made.\n *\n * Google: play(LineItems[0].OfferDetails.OfferId == 'xx')\n *\n * Platform: Apple, Google, Stripe\n * */\n 'TRIALING',\n\n /**\n * The subscription is in good standing and the most recent payment is successful. It’s safe to\n * provision your product for your customer.\n *\n * Platform: Apple, Google, Stripe\n * */\n 'ACTIVE',\n\n /**\n * Apple: The subscription enters the billing retry period. If the subtype is GRACE_PERIOD,\n * continue to provide service through the grace period. If the subtype is empty, the\n * subscription isn’t in a grace period and you can stop providing the subscription service.\n *\n * Google: Subscription is in grace period. The state is only available when the subscription\n * is an auto renewing plan. In this state, all items are in grace period.\n *\n * Platform: Apple, Google\n * */\n 'IN_GRACE_PERIOD',\n\n /**\n * A successful payment needs to be made within 23 hours to activate the subscription. Or the\n * payment requires action, like customer authentication. Subscriptions can also be incomplete\n * if there’s a pending payment and the PaymentIntent status would be processing.\n *\n * Platform: Stripe\n * */\n 'INCOMPLETE',\n\n /**\n * The initial payment on the subscription failed and no successful payment was made within 23\n * hours of creating the subscription. These subscriptions don’t bill customers. This status\n * exists so you can track customers that failed to activate their subscriptions.\n *\n * Platform: Stripe\n * */\n 'INCOMPLETE_EXPIRED',\n\n /**\n * Subscription was created but awaiting payment during signup. In this state, all items are\n * awaiting payment.\n *\n * Platform: Google\n * */\n 'PENDING',\n\n /**\n * Pending transaction for subscription is canceled. If this pending purchase was for an\n * existing subscription, use linkedPurchaseToken to get the current state of that subscription.\n *\n * Platform: Google\n * */\n 'PENDING_PURCHASE_CANCELED',\n\n /**\n * Payment on the latest finalized invoice either failed or wasn’t attempted. The subscription\n * continues to create invoices. Your subscription settings determine the subscription’s next\n * state. If the invoice is still unpaid after all Smart Retries have been attempted, you can\n * configure the subscription to move to canceled, unpaid, or leave it as past_due. To move the\n * subscription to active, pay the most recent invoice before its due date.\n *\n * This is Stripe's grace period: the customer keeps the product while Stripe retries (Smart\n * Retries, up to about three weeks), as an App Store or Play customer does in IN_GRACE_PERIOD,\n * so it is in `AVAILABLE_STATUSES`. A retry the customer is not served through (an App Store\n * billing retry without a grace period) is ON_HOLD, not PAST_DUE.\n *\n * Platform: Stripe\n * */\n 'PAST_DUE',\n\n /**\n * Google: Subscription is on hold (suspended). The state is only available when the\n * subscription is an auto renewing plan. In this state, all items are on hold. Grace period\n * ends or Active period ends but not grace period.\n *\n * Apple: the billing retry period of a subscription that has no grace period (or whose grace\n * period ended). Apple keeps retrying the charge for up to 60 days; the subscription is not\n * over, but the customer is not served meanwhile.\n *\n * Either way the store is still trying to collect and the customer has no access until a\n * payment goes through; the way out is a working payment method.\n *\n * Platform: Apple, Google\n * */\n 'ON_HOLD',\n\n /**\n * The subscription has been canceled. During cancellation, automatic collection for all unpaid\n * invoices is disabled (auto_advance=false). This is a terminal state that can’t be updated.\n *\n * Platform: Apple, Google, Stripe\n * */\n 'CANCELED',\n\n /**\n * The latest invoice hasn’t been paid but the subscription remains in place. The latest invoice\n * remains open and invoices continue to be generated but payments aren’t attempted. You should\n * revoke access to your product when the subscription is unpaid since payments were already\n * attempted and retried when it was past_due. To move the subscription to active, pay the most\n * recent invoice before its due date.\n *\n * Platform: Stripe\n * */\n 'UNPAID',\n\n /**\n * Google: Subscription is paused. The state is only available when the subscription is an auto\n * renewing plan. In this state, all items are in paused state.\n *\n * Stripe: The subscription has ended its trial period without a default payment method and the\n * trial_settings.end_behavior.missing_payment_method is set to pause. Invoices will no longer\n * be created for the subscription. After a default payment method has been attached to the\n * customer, you can resume the subscription.\n *\n * Platform: Google, Stripe\n * */\n 'PAUSED',\n\n /**\n * For example, a user buys a subscription and receives a purchase token A. The\n * linkedPurchaseToken field will not be set in the API response because the purchase token\n * belongs to a brand new subscription.\n *\n * If the user upgrades their subscription, a new purchase token B will be generated. Since the\n * upgrade is replacing the subscription from purchase token A, the linkedPurchaseToken field\n * for token B will be set to point to token A. Notice it points backwards in time to the\n * original purchase token.\n *\n * +---------------------------+ +------------------------+ +------------------------+\n * | Step 1 first purchase | | Step 2 upgrades | | Step 3 downgrades |\n * | purchaseToken: A |->| purchaseToken: B |->| purchaseToken: C |\n * | linkedPurchaseToken: null | | linkedPurchaseToken: A | | linkedPurchaseToken: B |\n * +---------------------------+ +------------------------+ +------------------------+\n *\n * Platform: Google\n * */\n 'REPLACED',\n\n /**\n * Google: Subscription is expired. All items have expiryTime in the past.\n *\n * Platform: Apple, Google\n * */\n 'EXPIRED',\n] as const;\n\nexport type SubscriptionStatus = (typeof SUBSCRIPTION_STATUSES)[number];\n\n/**\n * Statuses where it is safe to provision your product for the customer. A failing renewal keeps\n * the product while the store retries and the customer is meant to be served (IN_GRACE_PERIOD on\n * the App Store and Play, PAST_DUE on Stripe); it loses it once the store has given up (UNPAID on\n * Stripe) or is retrying without serving the customer (ON_HOLD on Play and on the App Store without\n * a grace period).\n */\nexport const AVAILABLE_STATUSES = [\n 'ACTIVE',\n 'TRIALING',\n 'IN_GRACE_PERIOD',\n 'PAST_DUE',\n] as const satisfies readonly SubscriptionStatus[];\n\n/** Who stopped the subscription from renewing. */\nexport const CANCELLATION_INITIATORS = [\n /** The customer: the store's cancel flow, our own cancel dialog, or a declined price increase. */\n 'user',\n /** The platform: a failed payment, a refund or revocation, a product no longer for sale. */\n 'system',\n /** Us: a cancellation through the platform's API or console. */\n 'developer',\n] as const;\n\nexport type CancellationInitiator = (typeof CANCELLATION_INITIATORS)[number];\n\n/** What a cancel survey may report, whichever platform asked the question. */\nexport const CANCELLATION_FEEDBACKS = [\n 'customer_service',\n 'low_quality',\n 'missing_features',\n 'switched_service',\n 'too_complex',\n 'too_expensive',\n 'unused',\n 'other',\n] as const;\n\nexport type CancellationFeedback = (typeof CANCELLATION_FEEDBACKS)[number];\n\nexport const RESUBSCRIBE_INTENTS = ['maybe', 'no', 'yes'] as const;\n\nexport type ResubscribeIntent = (typeof RESUBSCRIBE_INTENTS)[number];\n\n/**\n * Why a subscription stopped renewing, in one record shared by every platform. Every key is\n * optional and every value a string, so a platform may add what only it reports without a\n * schema change; the keys below are the ones they have in common. When the subscription was\n * cancelled is not in here: it is a column of its own, `canceledAt`.\n *\n * - `initiator`: see {@link CANCELLATION_INITIATORS}.\n * - `reason`: the platform's own code, kept verbatim for analytics — Stripe's\n * `cancellation_details.reason`, Google's `cancelSurveyResult.reason`, Apple's notification\n * subtype or `expirationIntent`.\n * - `feedback`: the customer's survey answer in the shared vocabulary {@link CANCELLATION_FEEDBACKS}.\n * - `comment`: free text the customer typed.\n * - `resubscribeIntent`: whether they said they would come back, when the cancel flow asked.\n */\nexport interface CancellationDetails {\n [key: string]: string | null | undefined;\n initiator?: CancellationInitiator | null;\n reason?: string | null;\n feedback?: CancellationFeedback | null;\n comment?: string | null;\n resubscribeIntent?: ResubscribeIntent | null;\n}\n"],"mappings":";AAAA,MAAa,YAAY;CAAC;CAAS;CAAU;AAAQ;;;;;;;;;;AAarD,MAAa,gBAAgB;CAC3B;CACA;CACA;CACA;AACF;;;;;AAQA,MAAa,kBAAkB;CAAC;CAAW;CAAa;CAAU;CAAY;AAAU;;;;;;;;;;AAaxF,MAAa,4BAAqF;CAChG,SAAS;EAAC;EAAa;EAAU;EAAY;CAAU;CACvD,WAAW,CAAC,UAAU,UAAU;CAChC,QAAQ,CAAC;CACT,UAAU,CAAC;CACX,UAAU,CAAC;AACb;;;;;;;AAQA,MAAa,mBAAmB;CAC9B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;AAKA,MAAa,0BAAoD;CAC/D;CACA;CACA;CACA;AACF;;;;;;;;AASA,MAAa,wBAAwB;CAUnC;CAQA;CAYA;CASA;CASA;CAQA;CAQA;CAgBA;CAgBA;CAQA;CAWA;CAaA;CAoBA;CAOA;AACF;;;;;;;;AAWA,MAAa,qBAAqB;CAChC;CACA;CACA;CACA;AACF;;AAGA,MAAa,0BAA0B;CAErC;CAEA;CAEA;AACF;;AAKA,MAAa,yBAAyB;CACpC;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;AAIA,MAAa,sBAAsB;CAAC;CAAS;CAAM;AAAK"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shware/purchase",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "9.0.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"access": "public"
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
|
-
"@shware/utils": "^
|
|
59
|
+
"@shware/utils": "^2.0.0",
|
|
60
60
|
"@types/ms": "^2.1.0",
|
|
61
61
|
"ms": "^2.1.3"
|
|
62
62
|
},
|