diff --git a/docs/change_log/2024-12-12-premium-apps-multiple-subscription-tiers.md b/docs/change_log/2024-12-12-premium-apps-multiple-subscription-tiers.md new file mode 100644 index 0000000000..652392e15c --- /dev/null +++ b/docs/change_log/2024-12-12-premium-apps-multiple-subscription-tiers.md @@ -0,0 +1,30 @@ +--- +title: "Premium Apps: Multiple Subscription Tiers" +date: "2024-12-12" +topics: +- "Premium Apps" +--- + +Developers with monetization enabled can now create and publish multiple subscription SKUs of the same type for their app. This allows developers to offer different subscription tiers with varying benefits and pricing. Users can upgrade and downgrade between published subscription SKUs. + +### What's Changed + +#### Developer Portal +- Under the `Monetization` tab, you can now publish multiple subscription SKUs of the same type for your app. + +#### App's Store Page +- When multiple subscription SKUs are published: Users can now upgrade or downgrade between different published subscription SKUs. + +#### User App Subscription Settings +- When multiple subscription SKUs are published: Users can now upgrade or downgrade between different published subscription SKUs. +- These settings are available under `User Settings → Subscriptions → App Subscriptions`. + +#### Subscription Object +- New field `renewal_sku_ids` added to the [subscription object](#DOCS_RESOURCES_SUBSCRIPTION/subscription-object) response for `SUBSCRIPTION_UPDATE` events and API endpoints. +- `renewal_sku_ids` is a list of snowflakes that indicate the SKU(s) that the user will be subscribed to at renewal. + +#### Updated Guide: Managing SKUs +- The [Managing SKUs](#DOCS_MONETIZATION_MANAGING_SKUS/creating-a-sku) guide has been updated to include information about creating and managing multiple subscription SKUs. + +#### Updated Guide: Implementing App Subscriptions +- The [Implementing App Subscriptions](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS/supporting-upgrades-and-downgrades) guide has been updated to include information about supporting upgrades and downgrades between multiple subscription SKUs. \ No newline at end of file diff --git a/docs/monetization/Implementing_App_Subscriptions.mdx b/docs/monetization/Implementing_App_Subscriptions.mdx index 12a5152e14..175329c066 100644 --- a/docs/monetization/Implementing_App_Subscriptions.mdx +++ b/docs/monetization/Implementing_App_Subscriptions.mdx @@ -39,6 +39,7 @@ Because entitlements are granted indefinitely and don't update on renewal or can | `SUBSCRIPTION_CREATE` | Subscription is created | `status` is either `0 (active)` if an entitlement has been granted or `1 (ending)` if an entitlement has not yet been granted | | `SUBSCRIPTION_UPDATE` | Subscription is granted an entitlement | `status` is `0 (active)` | | `SUBSCRIPTION_UPDATE` | Subscription is renewed | `current_period_start`, `current_period_end` timestamps updated | +| `SUBSCRIPTION_UPDATE` | Subscription is upgraded or downgraded | `sku_ids`, `entitlement_ids`, `renewal_sku_ids` may be updated | | `SUBSCRIPTION_UPDATE` | Subscription is canceled | `canceled_at` timestamp updated, `status` is `1 (ending)` | | `SUBSCRIPTION_UPDATE` | Subscription ends | `status` is `2 (inactive)`, this event is processed asynchronously and will not be immediate | | `SUBSCRIPTION_UPDATE` | Subscription is resumed/uncanceled by user | `status` is `0 (active)` | @@ -60,7 +61,7 @@ For subscription SKUs, you will receive the following entitlement events: | Event | Description | |----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `ENTITLEMENT_CREATE` | When a user is granted an entitlement to your app's subscription SKU | -| `ENTITLEMENT_UPDATE` | When a subscription ends | +| `ENTITLEMENT_UPDATE` | When an entitlement to a subscription SKU ends | | `ENTITLEMENT_DELETE` | When Discord refunds a subscription, removes an entitlement, or when a developer [deletes a Test Entitlement](#DOCS_RESOURCES_ENTITLEMENT/delete-test-entitlement) | ### Accessing Entitlements with the HTTP API @@ -91,6 +92,94 @@ You can do this by sending a message with a [button](#DOCS_INTERACTIONS_MESSAGE_ If you are using the [Embedded App SDK](#DOCS_DEVELOPER_TOOLS_EMBEDDED_APP_SDK) to build an [Activity](#DOCS_ACTIVITIES_OVERVIEW), you can also launch the purchase flow for a specific SKU using the SDK. Check out the [Implementing In-App Purchases for Activities](#DOCS_MONETIZATION_IMPLEMENTING_IAP_FOR_ACTIVITIES) guide to learn more about monetization with the Embedded App SDK. +### Purchasing from the Store Page + +Users can start, upgrade, or downgrade their subscription from your app's [Store](#DOCS_MONETIZATION_MANAGING_SKUS/viewing-your-store-page) page. You can link directly to your Store page using our [Application Directory Store URL scheme](#DOCS_MONETIZATION_MANAGING_SKUS/linking-to-your-store). + +--- + +## Supporting Subscriptions + +To support subscriptions in your app, you need to [create a subscription SKU](#DOCS_MONETIZATION_MANAGING_SKUS/creating-a-sku) and handle the following scenarios: + +### Starting a new subscription + +When a user subscribes to a new subscription, you will receive the following events: + +| Event | Event Trigger | +|-----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `SUBSCRIPTION_CREATE` | when the subscription is initially created. `status` is `0 (active)` if the entitlement has been granted or `1 (ending)` if the entitlement has not yet been granted. | +| `ENTITLEMENT_CREATE` | when the user is granted an entitlement for the new subscription | +| `SUBSCRIPTION_UPDATE` | when the subscription is updated with the `entitlement_ids`, `renewal_sku_ids`, and `status` (`0 (active)`) | + +### Cancelling an existing subscription + +Users can cancel their subscription at any time from their Subscription settings. + +When a user cancels their subscription, you will receive the following events: + +| Event | Event Trigger | +|-----------------------|-------------------------------------------------------------------------------------------------------------------------------------| +| `SUBSCRIPTION_UPDATE` | when the subscription is updated to end with a `status` of `1 (ending)` and `canceled_at` is set to the timestamp the user canceled | + +The user's subscription and entitlement are still valid until the subscription `current_period_end` is reached. + +If the subscription is not resumed before the subscription `current_period_end`, it will end and you will receive the following events: + +| Event | Event Trigger | +|-----------------------|----------------------------------------------------------------------------| +| `ENTITLEMENT_UPDATE` | when the current entitlement ends. `ends_at` gets updated with a timestamp | +| `SUBSCRIPTION_UPDATE` | when the subscription is updated with the `status` of `2 (inactive)` | + +### Resuming a cancelled subscription + +Users can resume their subscription at any time before the `current_period_end` is reached in their Subscription settings. + +When a user resumes their subscription, you will receive the following events: + +| Event | Event Trigger | +|-----------------------|-----------------------------------------------------------------------------------------------------------| +| `SUBSCRIPTION_UPDATE` | when the subscription is set to continue with a `status` of `0 (active)` and `canceled_at` is set to null | + +--- + +## Supporting Upgrades and Downgrades + +If you offer multiple subscription tiers in your app, users can upgrade or downgrade their subscription at any time from your [Store page](#DOCS_MONETIZATION_MANAGING_SKUS/viewing-your-store-page) or their App Subscription settings. + +To create multiple subscription tiers, you will need to [create multiple subscription SKUs](#DOCS_MONETIZATION_MANAGING_SKUS/creating-a-sku) and support the following scenarios in your app: + +### Upgrading an existing subscription + +If an user is on a lower tier subscription and upgrades to subscription tier that is the same price or higher, the user is charged the difference in price between the two subscriptions and the subscription period resets at the time of upgrading. + +When the subscription is upgraded, the current entitlement for the lower tier will end immediately and you will receive the following events: + +| Event | Event Trigger | +|-----------------------|--------------------------------------------------------------------------------------------------------------------------| +| `ENTITLEMENT_UPDATE` | when the current entitlement ends. `ends_at` gets updated with a timestamp | +| `ENTITLEMENT_CREATE` | when a new entitlement is created for the upgrade subscription SKU | +| `SUBSCRIPTION_UPDATE` | when the subscription is updated with the new `entitlement_ids`, `sku_ids`, `current_period_start`, `current_period_end` | + + +### Downgrading an existing subscription + +If an user is on a higher tier subscription and downgrades to a lower tier subscription, the user is not charged immediately because the price is lower than what was already paid. + +The user has already paid for their current plan until `subscription.current_period_end` so their current plan will be valid until then and you will receive the following event: + +| Event | Event Trigger | +|-----------------------|--------------------------------------------------------------------------------------------------| +| `SUBSCRIPTION_UPDATE` | when the subscription is updated to reflect the renewal SKU ID in `subscription.renewal_sku_ids` | + +Once the user's current subscription expires on `subscription.current_period_end`, you will receive the following events: + +| Event | Event Trigger | +|-----------------------|--------------------------------------------------------------------------------------------------------------------------| +| `ENTITLEMENT_UPDATE` | when the current entitlement ends. `ends_at` gets updated with a timestamp | +| `ENTITLEMENT_CREATE` | when a new entitlement is created for the downgraded subscription SKU | +| `SUBSCRIPTION_UPDATE` | when the subscription is updated with the new `entitlement_ids`, `sku_ids`, `current_period_start`, `current_period_end` | + --- ## Using the Subscription API @@ -98,7 +187,7 @@ If you are using the [Embedded App SDK](#DOCS_DEVELOPER_TOOLS_EMBEDDED_APP_SDK) > info > When implementing monetization, [Entitlements](#DOCS_RESOURCES_ENTITLEMENT) should be considered the source of truth for a user's access to a specific SKU. The Subscription API is intended for reporting and lifecycle management purposes that happen outside the flow of a user's interaction with your app. -You can use the [Subscription API](#DOCS_RESOURCES_SUBSCRIPTION) to check on the status of your app subscriptions. This API allows you to list all subscriptions for your app for reporting purposes and to check on the status of subscriptions without having to access entitlements directly. +You can use the [Subscription API](#DOCS_RESOURCES_SUBSCRIPTION) to check on the status of your app subscriptions. This API allows you to list subscriptions by user for reporting purposes and to check on the status of subscriptions without having to access entitlements directly. - [List SKU Subscriptions](#DOCS_RESOURCES_SUBSCRIPTION/list-sku-subscriptions): List all subscriptions for a specific SKU in your app. - [Get SKU Subscription](#DOCS_RESOURCES_SUBSCRIPTION/get-sku-subscription): Get a specific subscription in your app. diff --git a/docs/monetization/Managing_SKUs.mdx b/docs/monetization/Managing_SKUs.mdx index 5ae1a51093..3f2b71f352 100644 --- a/docs/monetization/Managing_SKUs.mdx +++ b/docs/monetization/Managing_SKUs.mdx @@ -19,11 +19,19 @@ When you click on `Create SKU`, you have the option to select from the following Once you select the SKU type, enter a name for your SKU to continue. +### Creating Subscription Tiers + +You can create multiple subscription tiers to offer different benefits at different price points. Each tier can have its own set of benefits and price and is represented by unique SKUs. + +To support upgrading and downgrading between subscription tiers, see our guide on [Implementing App Subscriptions](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS/supporting-upgrades-and-downgrades). + +![Supporting multiple subscription tiers](multisub.png) + ### SKU Limitations There are some limitations to the number of SKUs you can create: - You can create up to 50 total SKUs per app. -- Currently, you can only have **one** published subscription SKU per app (user or guild). +- You can offer either user subscription SKUs or guild subscription SKUs, but not both simultaneously. - SKU prices must be selected from the list of available prices. > info @@ -162,7 +170,7 @@ Users can access an app's Store page from the Bot User's profile in a server. Th ![Accessing the store as a user](botuser-profile.png) #### Subscriptions in Your Store page -![Subscriptions in your Store View](premium-subscriptions.png) +![Subscriptions in your Store View](multisub.png) #### Items in Your Store page ![Items in your Store View](premium-items.png) diff --git a/docs/resources/Subscription.md b/docs/resources/Subscription.md index c5d714a5bb..e0b7a83215 100644 --- a/docs/resources/Subscription.md +++ b/docs/resources/Subscription.md @@ -8,17 +8,18 @@ Subscriptions in Discord represent a user making recurring payments for at least ## Subscription Object -| Field | Type | Description | -|----------------------|---------------------|--------------------------------------------------------------------------------------------------------------------------------------------| -| id | snowflake | ID of the subscription | -| user_id | snowflake | ID of the user who is subscribed | -| sku_ids | array of snowflakes | List of SKUs subscribed to | -| entitlement_ids | array of snowflakes | List of entitlements granted for this subscription | -| current_period_start | ISO8601 timestamp | Start of the current subscription period | -| current_period_end | ISO8601 timestamp | End of the current subscription period | -| status | SubscriptionStatus | Current status of the subscription | -| canceled_at | ISO8601 timestamp? | When the subscription was canceled | -| country? | string | ISO3166-1 alpha-2 country code of the payment source used to purchase the subscription. Missing unless queried with a private OAuth scope. | +| Field | Type | Description | +|----------------------|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +| id | snowflake | ID of the subscription | +| user_id | snowflake | ID of the user who is subscribed | +| sku_ids | array of snowflakes | List of SKUs subscribed to | +| entitlement_ids | array of snowflakes | List of entitlements granted for this subscription | +| renewal_sku_ids | ?array of snowflakes | List of SKUs that this user will be subscribed to at renewal | +| current_period_start | ISO8601 timestamp | Start of the current subscription period | +| current_period_end | ISO8601 timestamp | End of the current subscription period | +| status | SubscriptionStatus | Current status of the subscription | +| canceled_at | ?ISO8601 timestamp | When the subscription was canceled | +| country? | string | ISO3166-1 alpha-2 country code of the payment source used to purchase the subscription. Missing unless queried with a private OAuth scope. | The start of a subscription is determined by its ID. When the subscription renews, its current period is updated. @@ -32,6 +33,7 @@ If the user cancels the subscription, the subscription will enter the `ENDING` s "user_id": "1088605110638227537", "sku_ids": ["1158857122189168803"], "entitlement_ids": [], + "renewal_sku_ids": null, "current_period_start": "2024-08-27T19:48:44.406602+00:00", "current_period_end": "2024-09-27T19:48:44.406602+00:00", "status": 0, diff --git a/images/multisub.png b/images/multisub.png new file mode 100644 index 0000000000..22349c2b4d Binary files /dev/null and b/images/multisub.png differ