diff --git a/docs/change_log/2023-09-26-premium-app-subscriptions-available-in-the-us.md b/docs/change_log/2023-09-26-premium-app-subscriptions-available-in-the-us.md index b68aa26a4a..851e1817c2 100644 --- a/docs/change_log/2023-09-26-premium-app-subscriptions-available-in-the-us.md +++ b/docs/change_log/2023-09-26-premium-app-subscriptions-available-in-the-us.md @@ -10,13 +10,13 @@ Starting today, eligible US-based developers can monetize their verified apps wi * Manage subscription SKUs in the Developer Portal * View monetization analytics in the Developer Portal * Team owners can setup and manage payouts in Developer Portal -* New endpoints for working with [SKUs](#DOCS_MONETIZATION_SKUS) and [Entitlements](#DOCS_MONETIZATION_ENTITLEMENTS): - * [List SKUs](#DOCS_MONETIZATION_SKUS/list-skus) `GET /applications//skus` - * [List Entitlements](#DOCS_MONETIZATION_ENTITLEMENTS/list-entitlements) `GET /applications//entitlements` - * [Create Test Entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/create-test-entitlement) `POST /applications//entitlements` - * [Delete Test Entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/delete-test-entitlement) `DELETE /applications//entitlements/` -* [Gateway Events](#DOCS_MONETIZATION_ENTITLEMENTS/gateway-events) for working with entitlements: `ENTITLEMENT_CREATE`, `ENTITLEMENT_UPDATE`, `ENTITLEMENT_DELETE` -* New [`PREMIUM_REQUIRED (10)` interaction response type](#DOCS_MONETIZATION_ENTITLEMENTS/premiumrequired-interaction-response) is available to prompt users to upgrade -* New `entitlements` field, which is an array of [entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/) objects, available in interaction data payloads when [receiving and responding to interactions](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-object-interaction-structure) +* New endpoints for working with [SKUs](#DOCS_RESOURCES_SKU) and [Entitlements](#DOCS_RESOURCES_ENTITLEMENT): + * [List SKUs](#DOCS_RESOURCES_SKU/list-skus) `GET /applications//skus` + * [List Entitlements](#DOCS_RESOURCES_ENTITLEMENT/list-entitlements) `GET /applications//entitlements` + * [Create Test Entitlement](#DOCS_RESOURCES_ENTITLEMENT/create-test-entitlement) `POST /applications//entitlements` + * [Delete Test Entitlement](#DOCS_RESOURCES_ENTITLEMENT/delete-test-entitlement) `DELETE /applications//entitlements/` +* [Gateway Events](#DOCS_TOPICS_GATEWAY_EVENTS/entitlements) for working with entitlements: `ENTITLEMENT_CREATE`, `ENTITLEMENT_UPDATE`, `ENTITLEMENT_DELETE` +* New [`PREMIUM_REQUIRED (10)` interaction response type](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-response-object-interaction-callback-type) is available to prompt users to upgrade +* New `entitlements` field, which is an array of [entitlement](#DOCS_RESOURCES_ENTITLEMENT/) objects, available in interaction data payloads when [receiving and responding to interactions](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-object-interaction-structure) To learn more about eligibility details and how to enable monetization for your app, check out the [Monetization Overview](#DOCS_MONETIZATION_OVERVIEW). diff --git a/docs/change_log/2023-11-29-premium-app-subscriptions-new-ways-for-testing-app-subscriptions.md b/docs/change_log/2023-11-29-premium-app-subscriptions-new-ways-for-testing-app-subscriptions.md index 796b42abd1..6df18642f4 100644 --- a/docs/change_log/2023-11-29-premium-app-subscriptions-new-ways-for-testing-app-subscriptions.md +++ b/docs/change_log/2023-11-29-premium-app-subscriptions-new-ways-for-testing-app-subscriptions.md @@ -8,6 +8,6 @@ topics: Following feedback on Premium App Subscriptions, we've made it easier for developers to test their app subscriptions. The goal is to provide you with flexibility during testing and prevent you from having to use live payment methods. * Team members will automatically receive a 100% discount on a subscription for your app, allowing you to test the end-to-end payment flow -* Developers can create and delete [test entitlements](#DOCS_MONETIZATION_ENTITLEMENTS/create-test-entitlement) to toggle access to an application's premium features +* Developers can create and delete [test entitlements](#DOCS_RESOURCES_ENTITLEMENT/create-test-entitlement) to toggle access to an application's premium features -Read more about [Testing your App Subscriptions Implementation](#DOCS_MONETIZATION_APP_SUBSCRIPTIONS/testing-your-implementation) for details. +Read more about [Testing your App Subscriptions Implementation](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS/testing-your-app-subscription-implementation) for details. diff --git a/docs/change_log/2024-04-24-premium-apps-one-time-purchases-and-store.md b/docs/change_log/2024-04-24-premium-apps-one-time-purchases-and-store.md index c9fca29f18..79c582bda0 100644 --- a/docs/change_log/2024-04-24-premium-apps-one-time-purchases-and-store.md +++ b/docs/change_log/2024-04-24-premium-apps-one-time-purchases-and-store.md @@ -10,7 +10,7 @@ Two new features are now available for Premium Apps: One-Time Purchases and Stor * **Durable Items**: A one-time purchase that is permanent and is not subject to either renewal or consumption, such as lifetime access to an app's premium features. * **Consumable Items**: A one-time, non-renewable purchase that provides access, such as a temporary power-up or boost in a game. -Learn more about implementing [One-Time Purchases](#DOCS_MONETIZATION_ONE-TIME_PURCHASES). +Learn more about [Implementing One-Time Purchases](#DOCS_MONETIZATION_IMPLEMENTING_ONE-TIME_PURCHASES). **A Store for Your Premium App** @@ -22,7 +22,7 @@ To explore these features, eligibility details, and how to enable monetization f The following were added to our public Monetization documentation with this update: -* New [SKU Object Types](#DOCS_MONETIZATION_SKUS/sku-object-sku-types) -* New [Entitlement Object Types](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object-entitlement-types) -* [Consume an Entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/consume-an-entitlement) API endpoint -* `consumed` field on the [Entitlement](#DOCS_MONETIZATION_ENTITLEMENTS) resource +* New [SKU Object Types](#DOCS_RESOURCES_SKU/sku-object-sku-types) +* New [Entitlement Object Types](#DOCS_RESOURCES_ENTITLEMENT/entitlement-object-entitlement-types) +* [Consume an Entitlement](#DOCS_RESOURCES_ENTITLEMENT/consume-an-entitlement) API endpoint +* `consumed` field on the [Entitlement](#DOCS_RESOURCES_ENTITLEMENT) resource diff --git a/docs/change_log/2024-06-17-premium-apps-new-premium-button-style-deep-linking-url-schemes.md b/docs/change_log/2024-06-17-premium-apps-new-premium-button-style-deep-linking-url-schemes.md index 240e6c5a88..92015d1e85 100644 --- a/docs/change_log/2024-06-17-premium-apps-new-premium-button-style-deep-linking-url-schemes.md +++ b/docs/change_log/2024-06-17-premium-apps-new-premium-button-style-deep-linking-url-schemes.md @@ -5,7 +5,7 @@ date: "2024-06-17" **New Premium Button Style** -Introduces a new `premium` [button style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) to be used with a `sku_id` which points to an active [SKU](#DOCS_MONETIZATION_SKUS/sku-object). This allows developers to customize their premium experience by returning specific subscription or one-time purchase products. +Introduces a new `premium` [button style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) to be used with a `sku_id` which points to an active [SKU](#DOCS_RESOURCES_SKU/sku-object). This allows developers to customize their premium experience by returning specific subscription or one-time purchase products. Learn more about using [button components with interactions](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/buttons). @@ -14,11 +14,11 @@ Learn more about using [button components with interactions](#DOCS_INTERACTIONS_ The `PREMIUM_REQUIRED (10)` interaction response type is now deprecated in favor of using custom premium buttons. This will continue to function but may be eventually unsupported. It is recommended to migrate your bots to use the more flexible [premium button component](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles). -Learn more about [gating features with premium interactions](#DOCS_MONETIZATION_APP_SUBSCRIPTIONS/gating-premium-interactions). +Learn more about [gating features with premium interactions](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS/prompting-users-to-subscribe). **Deep Linking URL Schemes for SKUs and Store** Introduces two new url schemes for linking directly to the Application Directory. When these links are used in chat, they are rendered as rich embeds that users can interact with to launch an app's store or open a SKU detail modal. -* New [Store URL Scheme](#DOCS_MONETIZATION_MANAGING_YOUR_STORE/linking-to-your-store): `https://discord.com/application-directory/:appID/store` -* New [SKU URL Scheme](#DOCS_MONETIZATION_SKUS/linking-to-your-skus): `https://discord.com/application-directory/:appID/store/:skuID` +* New [Store URL Scheme](#DOCS_MONETIZATION_MANAGING_SKUS/linking-to-your-store): `https://discord.com/application-directory/:appID/store` +* New [SKU URL Scheme](#DOCS_MONETIZATION_MANAGING_SKUS/linking-to-a-specific-sku): `https://discord.com/application-directory/:appID/store/:skuID` diff --git a/docs/change_log/2024-08-28-subscription-api-and-entitlement-migration.md b/docs/change_log/2024-08-28-subscription-api-and-entitlement-migration.md new file mode 100644 index 0000000000..a3340e5d99 --- /dev/null +++ b/docs/change_log/2024-08-28-subscription-api-and-entitlement-migration.md @@ -0,0 +1,90 @@ +--- +title: "Premium Apps: Entitlement Migration and New Subscription API" +date: "2024-08-28" +topics: +- "Premium Apps" +breaking: true +--- + +We are migrating our entitlement system to a new behavior where entitlements will not end until explicitly canceled, representing a breaking change for subscription management. We are introducing a [Subscription API](#DOCS_RESOURCES_SUBSCRIPTION) and [Subscription Events](#DOCS_TOPICS_GATEWAY_EVENTS/subscriptions) to allow handling subscription-related events. + +> warn +> This change will be rolled out to all existing applications that have entitlements for user and guild subscription SKUs, starting on October 1, 2024. + +#### Entitlement Migration Details +- `ENTITLEMENT_CREATE` events will now be triggered with a null `ends_at` value for all ongoing subscriptions, indicating an indefinite entitlement. +- `ENTITLEMENT_UPDATE` events will occur only when a subscription is canceled, with the `ends_at` value indicating the end date. +- Discord-managed Subscription entitlements will have an `type` value of `PURCHASE` (type `1`) instead of `APPLICATION_SUBSCRIPTION` (type `8`). + +### Migration Plan & Guide: +As of **October 1, 2024**, all existing entitlements that grant access to user-subscription and guild-subscription SKUs will automatically transfer to the new system on their renewal date. This means we will have a month-long migration window to allow all of your entitlements to migrate to the new system upon renewal. + +Developers are advised to update their systems to handle the new `ENTITLEMENT_CREATE` and `ENTITLEMENT_UPDATE` events according to the following migration guide before the rollout date to avoid service disruptions. + +### Introducing a New Subscription API +With the new entitlement behavior, entitlements for subscription SKUs will no longer emit events at the start of a new subscription billing period. Instead, subscription lifecycle management can be handled through the new [Subscription API](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS/using-the-subscription-api). +Developers should refer to the [Subscription resource](#DOCS_RESOURCES_SUBSCRIPTION) for information on calling the Subscription API and responding to Subscription events. For in-depth implementation details, see our [Implementing App Subscriptions](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS/using-the-subscription-api) guide. You can start using this API now. + +### Monetization Documentation Updates +As part of these changes, we've updated the documentation for Premium Apps. +- Created a new [Enabling Monetization](#DOCS_MONETIZATION_ENABLING_MONETIZATION) page to cover setting up your team, managing payouts, and enabling monetization for your apps +- Created a new [Managing SKUs](#DOCS_MONETIZATION_MANAGING_SKUS/creating-a-sku) page to document how to create, update, publish, and promote your SKUs +- Moved and added [Entitlement](#DOCS_RESOURCES_ENTITLEMENT), [SKU](#DOCS_RESOURCES_SKU) and [Subscription](#DOCS_RESOURCES_SUBSCRIPTION) resources to the **Resources** section +- Updated guides for [Implementing App Subscriptions](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS) and [Implementing One-Time Purchases](#DOCS_MONETIZATION_IMPLEMENTING_ONE-TIME_PURCHASES) + +### Subscription Entitlement Migration Guide + +Starting on **October 1, 2024**, we will be migrating our existing entitlement system to a new behavior where **entitlements do not expire until explicitly canceled**. This migration guide outlines the changes and impacts of this migration on developers and guides how to manage these changes effectively. + +> warn +> With this update, entitlements for subscription SKUs will no longer emit events when a new subscription billing period begins. If you need to know when a subscription has been renewed, use the new [Subscription API](#DOCS_RESOURCES_SUBSCRIPTION) and related [Subscription Gateway Events](#DOCS_TOPICS_GATEWAY_EVENTS/subscriptions). + +### Current System + +Currently, entitlements for Subscription SKUs purchased through Discord have: +- An `ends_at` date that corresponds to the subscription interval. This date is updated at each billing cycle. +- A entitlement `type` value of `APPLICATION_SUBSCRIPTION` (type `8`). +- An `ENTITLEMENT_UPDATE` event is triggered at the start of each new subscription period. + +### New System + +Post-migration, entitlements for Subscription SKUs purchased through Discord will: +- No longer have an end date (`ends_at` will be `null`) until the user decides to cancel the subscription. +- Now have an entitlement `type` value of `PURCHASE` (type `1`). +- No `ENTITLEMENT_UPDATE` events will be triggered until the subscription is canceled. + +### Migration Timeline + +- **Migration Start Date:** October 1, 2024 +- **Migration End Date:** October 31, 2024 + +### Migration Impacts + +### 1) Existing Entitlements Scheduled to Renew + +- **During Migration Window:** + - These will automatically transfer to the new system. + - A new `ENTITLEMENT_CREATE` event will be triggered to indicate the migration. This does not indicate a net new entitlement. + - No further events will be generated until cancellation, which will then trigger an `ENTITLEMENT_UPDATE` event. + +### 2) Existing Entitlements Set to End + +- **During Migration Window:** + - These entitlements will naturally expire and not renew under the new system. + - No new entitlement events will be generated for these cases. + +### Developer Actions +- **Pre-Migration:** + - Review and understand the new entitlement event structure. + - Adjust your system to handle `ends_at` being null, which now indicates an indefinite entitlement. + - Adjust your system not to expect type `APPLICATION_SUBSCRIPTION` (type `8`) for Discord-managed subscription entitlements. +- **Post-Migration:** + - Monitor for `ENTITLEMENT_CREATE` and `ENTITLEMENT_UPDATE` events. + - Update your handling of `ends_at` timestamps to manage cancellations effectively. + + +- The Entitlement Migration begins on October 1, 2024 +- You have an existing user subscription that has an existing `ends_at` timestamp for October 10, 2024. +- If the subscription renews successfully, you will receive an `ENTITLEMENT_UPDATE` event on October 10, 2024, with an `ends_at` value of null +- If you receive an `ENTITLEMENT_UPDATE` event with an `ends_at` timestamp, the entitlement for this subscription is expected to end at the timestamp value unless you receive subsequent `ENTITLEMENT_UPDATE` events between the cancellation and the `ends_at` value. + \ No newline at end of file diff --git a/docs/interactions/Message_Components.md b/docs/interactions/Message_Components.md index 4b6d7bb1b1..cdf2b72f86 100644 --- a/docs/interactions/Message_Components.md +++ b/docs/interactions/Message_Components.md @@ -90,16 +90,16 @@ Buttons are interactive components that render in messages. They can be clicked ###### Button Structure -| Field | Type | Description | -|------------|-----------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------| -| type | integer | `2` for a button | -| style | integer | A [button style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) | -| label? | string | Text that appears on the button; max 80 characters | -| emoji? | partial [emoji](#DOCS_RESOURCES_EMOJI/emoji-object) | `name`, `id`, and `animated` | -| custom_id? | string | Developer-defined identifier for the button; max 100 characters | -| sku_id? | snowflake | Identifier for a purchasable [SKU](#DOCS_MONETIZATION_SKUS/sku-object), only available when using premium-style buttons | -| url? | string | URL for link-style buttons | -| disabled? | boolean | Whether the button is disabled (defaults to `false`) | +| Field | Type | Description | +|------------|-----------------------------------------------------|---------------------------------------------------------------------------------------------------------------------| +| type | integer | `2` for a button | +| style | integer | A [button style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) | +| label? | string | Text that appears on the button; max 80 characters | +| emoji? | partial [emoji](#DOCS_RESOURCES_EMOJI/emoji-object) | `name`, `id`, and `animated` | +| custom_id? | string | Developer-defined identifier for the button; max 100 characters | +| sku_id? | snowflake | Identifier for a purchasable [SKU](#DOCS_RESOURCES_SKU/sku-object), only available when using premium-style buttons | +| url? | string | URL for link-style buttons | +| disabled? | boolean | Whether the button is disabled (defaults to `false`) | Buttons come in a variety of styles to convey different types of actions. These styles also define what fields are valid for a button. diff --git a/docs/interactions/Receiving_and_Responding.mdx b/docs/interactions/Receiving_and_Responding.mdx index 2795fbedd7..356def163c 100644 --- a/docs/interactions/Receiving_and_Responding.mdx +++ b/docs/interactions/Receiving_and_Responding.mdx @@ -34,7 +34,7 @@ For [Message Components](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/) it includes ide | app_permissions\*\*\* | string | Bitwise set of permissions the app has in the source location of the interaction | | locale?\*\*\*\* | string | Selected [language](#DOCS_REFERENCE/locales) of the invoking user | | guild_locale? | string | [Guild's preferred locale](#DOCS_RESOURCES_GUILD/guild-object), if invoked in a guild | -| entitlements | array of [entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object) objects | For [monetized apps](#DOCS_MONETIZATION_OVERVIEW), any entitlements for the invoking user, representing access to premium [SKUs](#DOCS_MONETIZATION_SKUS) | +| entitlements | array of [entitlement](#DOCS_RESOURCES_ENTITLEMENT/entitlement-object) objects | For [monetized apps](#DOCS_MONETIZATION_OVERVIEW), any entitlements for the invoking user, representing access to premium [SKUs](#DOCS_RESOURCES_SKU) | | authorizing_integration_owners | dictionary with keys of [application integration types](#DOCS_RESOURCES_APPLICATION/application-object-application-integration-types) | Mapping of installation contexts that the interaction was authorized for to related user or guild IDs. See [Authorizing Integration Owners Object](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-object-authorizing-integration-owners-object) for details | | context? | [interaction context type](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-object-interaction-context-types) | Context where the interaction was triggered from | diff --git a/docs/monetization/App_Subscriptions.md b/docs/monetization/App_Subscriptions.md deleted file mode 100644 index 4786a29e10..0000000000 --- a/docs/monetization/App_Subscriptions.md +++ /dev/null @@ -1,125 +0,0 @@ -# App Subscriptions - -App Subscriptions enable you to charge your users for premium app functionality with a recurring subscription. Before you can add an app subscription to your app, you must complete the [Monetization Eligibility Checklist](#DOCS_MONETIZATION_OVERVIEW/eligibility-checklist). - -Once you've confirmed eligibility for your app and team, you will be able to set up a [SKU](#DOCS_MONETIZATION_SKUS) (stock-keeping unit) to represent your app's premium offering. - -## Types of Subscriptions - -When creating subscriptions, you will need to choose between user or guild subscriptions: - -- **User Subscriptions**: Offers premium features to an individual user across any server where your app installed. -- **Guild Subscriptions**: Provides premium benefits to all members within a specific server. - -Currently, you can only have one published subscription SKU for your app, so you cannot offer both types of subscriptions. - -## Configuring App Subscriptions - -Once you have an idea what type of subscription you want to offer for your app, you can create and [customize your SKU](#DOCS_MONETIZATION_SKUS/customizing-your-skus) to reflect the premium features that you are adding to your app. This is a good place to outline the benefits your users will receive from having an app subscription. - -Once an app has a published SKU, there are 4 ways users will be able to subscribe: - -- Server admins can use the **Integrations** tab within a server's settings menu -- Bot user profiles include an Upgrade button -- App Directory profiles offer a Premium tab containing subscription details and an Upgrade option -- Attempting to run a premium command will display the Upgrade button in the response - -If you don't have any premium commands, your users will still be able to upgrade to your premium app via the Integrations settings menu, bot user profiles and App Directory profiles. - -## Implementing App Subscriptions - -When a user subscribes to your app, there are a few things you will need to implement in your code to check for subscription status and access. - -- Gating your App with Premium Interactions -- Working with Entitlements -- Handling Gateway Events for Entitlements - -### Gating Premium Interactions - -Each interaction payload includes an `entitlements` field containing an array of full [entitlement objects](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object). You can use this field to determine if the user or guild is subscribed to your app. If the user or guild is not subscribed and you wish to present them with a means to do so you can use a [button](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/buttons) with a [premium style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) and a `sku_id` attached. You may also use these buttons to present users with options to make a [One-Time Purchase](#DOCS_MONETIZATION_ONE-TIME_PURCHASES). - -```javascript -return new JsonResponse({ - type: 4, // InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE - data: { - content: "This command requires Nelly Premium! Upgrade now to get access to these features!", - components: [{ - type: MessageComponentTypes.ACTION_ROW, - components: [ - { - type: MessageComponentTypes.BUTTON, - style: 6, // ButtonStyleTypes.PREMIUM - sku_id: '1234965026943668316', - }, - ], - }] - }, -}); -``` - -![A premium button](premium-button.png) - -#### Type 10 Interaction Response - -> warn -> `PREMIUM_REQUIRED` type 10 interaction response is deprecated. Please use `ButtonStyle.PREMIUM` to handle purchases. - -Interactions like [commands](#DOCS_INTERACTIONS_APPLICATION_COMMANDS) commonly respond to users with a message or modal response. If you'd like to make a command only available to users with a subscription, you can reply with a `PREMIUM_REQUIRED` interaction response `type: 10`. Users without a subscription will be prompted to upgrade when they attempt to use these commands. - -```javascript -return new JsonResponse({ - type: 10, // PREMIUM_REQUIRED interaction response type - data: {}, -}); -``` - -![Interaction Response](monetization-interaction-response.png) - -If someone is already subscribed, this command will show the upgrade prompt with a disabled upgrade button. In order to avoid this, your interaction handler should check to see if the user or guild has an active entitlement for your SKU. - -Each interaction payload includes an `entitlements` field containing an array of full [entitlement objects](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object). - -You can use this field to determine if the user or guild is subscribed to your app. - -### Keeping Track of Entitlements - -When a user purchases a subscription, an entitlement is created. [Entitlements](#DOCS_MONETIZATION_ENTITLEMENTS) represent the user's access to your premium offering. You can keep track of entitlements using Gateway Events and the HTTP API. - -#### Entitlement Gateway Events - -When users subscribe or renew a subscription with your app, Discord will emit [entitlement gateway events](#DOCS_MONETIZATION_ENTITLEMENTS/gateway-events). - -Upon a user's purchase of a SKU, you'll receive an [`ENTITLEMENT_CREATE`](#DOCS_MONETIZATION_ENTITLEMENTS/new-entitlement) event. A successful renewal triggers an [`ENTITLEMENT_UPDATE`](#DOCS_MONETIZATION_ENTITLEMENTS/updated-entitlement) event. - -> info -> An [`ENTITLEMENT_DELETE`](#DOCS_MONETIZATION_ENTITLEMENTS/deleted-entitlement) event only occurs when Discord refunds a subscription or removes an entitlement, not when an entitlement expires or is canceled. - -#### Entitlement HTTP Endpoints - -For apps requiring background processing or not solely reliant on interactions, keeping track of entitlements is essential. You can utilize the [List Entitlements](#DOCS_MONETIZATION_ENTITLEMENTS/list-entitlements) endpoint to list active and expired entitlements. Your app can filter entitlements by a specific user or guild by using the `?user_id=XYZ` or `?guild_Id=XYZ` query params. - -For example, you might keep track of our entitlements in a database and check a user's subscription status before performing a cron job or other task. - -## Testing Your Implementation - -### Using Test Entitlements - -You can test your implementation by [creating](#DOCS_MONETIZATION_ENTITLEMENTS/create-test-entitlement) and [deleting](#DOCS_MONETIZATION_ENTITLEMENTS/delete-test-entitlement) test entitlements. These entitlements will allow you to test your premium offering in both a subscribed and unsubscribed state as a user or guild. - -> info -> Test Entitlements do not have a `starts_at` or `ends_at` field as they are valid until they are deleted. - -### Testing Payment Flow with Live Entitlements - -If you'd like to test the full payment flow for your app, you can do so by interacting with the `Upgrade` button. Any team members associated with your app will automatically see a 100% discount on the price of the subscription, allowing you to purchase without the use of live payment method. - -After checkout, you will have a live subscription that includes a `starts_at` and `ends_at` value. If you cancel this subscription, it will remain an active entitlement until the `ends_at` timestamp. This subscription will renew until cancelled and can be used in testing subscription renewals in your app. - -> info -> You can only delete entitlements created using the [create test entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/create-test-entitlement) endpoint. If you need to toggle access to your premium features during your development process, it is best to use test entitlements. - -## Receiving Payouts - -Once an app has made its first $100 it will become eligible for payout. A review will be conducted and if everything looks good, your team will begin to receive payouts. - -For more information, read the [Premium Apps Payouts](https://support-dev.discord.com/hc/articles/17299902720919) Help Center article. diff --git a/docs/monetization/Enabling_Monetization.mdx b/docs/monetization/Enabling_Monetization.mdx new file mode 100644 index 0000000000..7db5e22703 --- /dev/null +++ b/docs/monetization/Enabling_Monetization.mdx @@ -0,0 +1,85 @@ +# Enabling Monetization + +Before you can add monetization to your app, you must ensure that your app and team meet the eligibility criteria. + +## Steps to Enable Monetization + +1. Set up your developer team and app to be eligible for monetization +2. Complete the eligibility criteria for monetization +3. Set up developer team payouts to get paid +4. Create your premium offering +5. Implement monetization in your app +6. Start offering your premium features + +Once these are complete, you can [create SKUs](#DOCS_MONETIZATION_MANAGING_SKUS/creating-a-sku) to represent your premium offerings and [add support for your premium offering](#DOCS_MONETIZATION_ENABLING_MONETIZATION/step-5-implement-monetization-in-your-app) in your app. + +## Step 1. Set Up Your Developer Team and App + +Before monetization can be enabled, you will need: + +- A [team](#DOCS_TOPICS_TEAMS) in the developer portal. If you don't have one, you can [create one on the Teams page](https://discord.com/developers/teams) +- A [verified app](https://support-dev.discord.com/hc/en-us/articles/23926564536471-How-Do-I-Get-My-App-Verified) that is _owned by that team_ +- Your app and team must be eligible for monetization. See the Eligibility Checklist below for details. + +## Step 2. Complete the Eligibility Checklist + +Before you can start creating SKUs and offering payments in your app, your app and team must be eligible for monetization. When a team owner enables monetization, they'll be taken through a series of steps and checks to ensure the following criteria are met: + + +- App must be verified +- App belongs to a developer team +- Team owner must be at least 18 years old +- Team must have verified emails and 2FA set up +- App uses slash commands, or has been approved for the privileged `Message Content` intent +- App has a link to your Terms of Service + - This document is an agreement between you and users governing the use of your app. +- App has a link to your Privacy Policy + - This document should clearly and accurately describe to users of your app the user data you collect and how you use and share such data with us and third parties, consistent with our Developer Terms of Service and Developer Policy. +- App must not contain any harmful or bad language in the name, description, commands, or role connection metadata. +- Payouts must be set up with a valid payment method +- Agreement to the [Monetization Terms](https://support.discord.com/hc/articles/5330075836311) and [Discord Developer Policy](https://support-dev.discord.com/hc/en-us/articles/8563934450327-Discord-Developer-Policy). + + +## Step 3. Set Up Team Payouts + +Let's set up Team Payouts so you can get paid! Discord processes all payouts through Stripe, so part of setting up payouts will go through Stripe's onboarding flow. + +- Only the owner of the team can enable payout settings for the team. +- Once your app has made its first $100 it will become eligible for payout. +- A review will be conducted and if everything looks good, your team will begin to receive payouts. + +#### If You are Based in the United States, European Union, or United Kingdom + +- Click on [your team](https://discord.com/developers/teams) on the Teams page. +- Select **Payout Settings**. + - If you do not see **Payout Settings**, you are not the owner of the team. Only the owner of the team can enable payout settings for the team. +- Complete the onboarding flow through Stripe. + +#### If You are Based Outside of the United States, European Union, or United Kingdom + +> info +> Premium Apps is not currently available outside of these regions. These features will be made available to more regions soon. + +For more information, read the [Premium Apps Payouts](https://support-dev.discord.com/hc/articles/17299902720919) Help Center article. + +## Step 4: Create Your Premium Offering + +You are now ready to start setting up your SKUs and offering premium features in your app. Check out our guide on [Managing your Premium Offerings](#DOCS_MONETIZATION_MANAGING_SKUS/creating-a-sku) to create one-time purchases and subscriptions for your app. + +## Step 5: Implement Monetization in your App + +Now that you've set up your app for monetization, you can start adding code to support your premium features. We have guides for the following monetization strategies: + + + + Learn how to start and manage recurring subscriptions within your app. + + + Learn how to implement one-time purchases in your app. + + + +## Step 6: Start Offering Your Premium Features +Congratulations! You've successfully set up your app for monetization. Now you can start earning money from your app and providing premium features to your users. + +You can now [link to your Store](#DOCS_MONETIZATION_MANAGING_SKUS/linking-to-your-store) page, [link to a specific SKU](#DOCS_MONETIZATION_MANAGING_SKUS/linking-to-a-specific-sku), or [include a premium styled button in Message Components](#DOCS_MONETIZATION_MANAGING_SKUS/responding-with-a-premium-button) to allow your users to make purchases. diff --git a/docs/monetization/Implementing_App_Subscriptions.mdx b/docs/monetization/Implementing_App_Subscriptions.mdx new file mode 100644 index 0000000000..efc9512f6b --- /dev/null +++ b/docs/monetization/Implementing_App_Subscriptions.mdx @@ -0,0 +1,117 @@ +# Implementing App Subscriptions + +Charge users for premium app functionality with a recurring user or guild subscription. + +- Before you can add an app subscription to your app, you must [Enable Monetization](#DOCS_MONETIZATION_ENABLING_MONETIZATION) for your app. +- Once you've confirmed eligibility for your app and team, you will be able to set up a [SKU](#DOCS_RESOURCES_SKU) (stock-keeping unit) to represent your subscription. + +--- + +## Types of Subscriptions + +When creating subscriptions, you will need to choose between user or guild subscriptions: + +- **User Subscriptions**: Offers premium features to an individual user across any server where your app installed. +- **Guild Subscriptions**: Provides premium benefits to all members within a specific server. + +--- + +## How App Subscriptions Work + +> danger +> **Starting on October 1st, 2024**, the `ENTITLEMENT_CREATE` and `ENTITLEMENT_UPDATE` event behavior is changing. Please see the [Change Log and Entitlement Migration Guide](#DOCS_CHANGE_LOG/subscription-api-and-entitlement-migration) for more information on what is changing and how to prepare. + +- When a user purchases your subscription SKU, Discord creates an [Entitlement](#DOCS_RESOURCES_ENTITLEMENT) for the user (or guild) and that specific Subscription [SKU](#DOCS_RESOURCES_SKU). +- You will receive an `ENTITLEMENT_CREATE` event via the Gateway. +- This entitlement will be available via the `LIST Entitlements` API endpoint. +- This entitlement will be available on `Interaction Payloads` initiated from the entitled user or users in a guild (for guild subscriptions). +- This subscription will be available via the `LIST Subscriptions` API endpoint. +- This entitlement is granted and updated with a new `ends_at` date for each succesful billing interval until the user decides to cancel their subscription. +- When a user cancels their subscription, you will **not** receive an `ENTITLEMENT_UPDATE` with a new `ends_at` value, the entitlement will just expire at the current `ends_at` value. + + +- When a user purchases your subscription SKU, Discord creates an [Entitlement](#DOCS_RESOURCES_ENTITLEMENT) for the user (or guild) and that specific Subscription [SKU](#DOCS_RESOURCES_SKU). +- You will receive an `ENTITLEMENT_CREATE` event via the Gateway. +- This entitlement will be available via the `LIST Entitlements` API endpoint. +- This entitlement will be available on `Interaction Payloads` initiated from the entitled user or users in a guild (for guild subscriptions). +- This subscription will be available via the `LIST Subscriptions` API endpoint. +- This entitlement is granted indefinitely until the user decides to cancel their subscription. `ends_at` will be null. +- When a user cancels their subscription, you will receive an `ENTITLEMENT_UPDATE` event with an `ends_at` timestamp representing when the subscription ends and when related premium functionality should be revoked. +- If the user changes their mind and reactivates their subscription, you will receive another `ENTITLEMENT_UPDATE` event setting the `ends_at` timestamp to null. + + Please see the [Change Log and Entitlement Migration Guide](#DOCS_CHANGE_LOG/subscription-api-and-entitlement-migration) for more information on what is changing and how to prepare. + + +--- + +## Working with Entitlements + +When a user purchases a subscription, an entitlement is created. [Entitlements](#DOCS_RESOURCES_ENTITLEMENT) represent the user's access to your consumable or durable item. + +Depending on your app's features, you can use a combination of [Gateway events](#DOCS_TOPICS_GATEWAY_EVENTS/entitlements), the [Entitlement HTTP API](#DOCS_RESOURCES_ENTITLEMENT), and [interaction payloads](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING) to keep track of user and guild entitlements and grant perks to users who have subscribed to your app. + +### Accessing Entitlements with Gateway Events + +> danger +> **Starting on October 1st, 2024**, the `ENTITLEMENT_CREATE` and `ENTITLEMENT_UPDATE` event behavior is changing. Please see the [Change Log and Entitlement Migration Guide](#DOCS_CHANGE_LOG/subscription-api-and-entitlement-migration) for more information on what is changing and how to prepare. + +When users subscribe or renew a subscription with your app, Discord will emit [Entitlement Gateway events](#DOCS_TOPICS_GATEWAY_EVENTS/entitlements). + +For subscription SKUs, you will receive the following events: + +- [`ENTITLEMENT_CREATE`](#DOCS_TOPICS_GATEWAY_EVENTS/entitlement-create): When a user subscribes to your app. +- [`ENTITLEMENT_UPDATE`](#DOCS_TOPICS_GATEWAY_EVENTS/entitlement-update): When a user renews their subscription. +- [`ENTITLEMENT_DELETE`](#DOCS_TOPICS_GATEWAY_EVENTS/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 + +For apps requiring background processing or not solely reliant on interactions, keeping track of entitlements is essential. You can utilize the [List Entitlements](#DOCS_RESOURCES_ENTITLEMENT/list-entitlements) endpoint to list active and expired entitlements. Your app can filter entitlements by a specific user or guild by using the `?user_id=XYZ` or `?guild_Id=XYZ` query params. + +For example, you might keep track of our entitlements in a database and check if a user still has access to a specific SKU before performing a cron job or other task. + +### Accessing Entitlements on Interaction Payloads + +Entitlements are also available on the `Interaction Payload` when a user interacts with your app. You can find the entitlements on the `entitlements` field of the `Interaction Payload` when [receiving and responding to interactions](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING). You can use this field to determine if the user or guild is subscribed to your app. + +--- + +## Prompting Users to Subscribe + +[Responding with a premium button](#DOCS_MONETIZATION_MANAGING_SKUS/responding-with-a-premium-button) gives you the ability to prompt users to subscribe to your app when they attempt to use a premium feature without a subscription. + +You can do this by sending a message with a [button](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/buttons) with a [premium style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) and a `sku_id` that allows the user to upgrade to your premium offering. + +--- + +## Using the Subscription API + +> 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. + +- [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. +- [Subscription Gateway events](#DOCS_TOPICS_GATEWAY_EVENTS/subscriptions): Discord will emit gateway events when a subscription is created, updated, and very rarely, deleted. + +--- + +## Testing Your App Subscription Implementation + +### Using Test Entitlements + +You can test your implementation by [creating](#DOCS_RESOURCES_ENTITLEMENT/create-test-entitlement) and [deleting](#DOCS_RESOURCES_ENTITLEMENT/delete-test-entitlement) test entitlements. These entitlements will allow you to test your premium offering in both a subscribed and unsubscribed state as a user or guild. + +This method will not let you test out the full payment flow in Discord but will allow you to test your app's behavior when a user is subscribed or unsubscribed. See [Using Live Entitlements](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS/using-live-entitlements) if you'd like to see the full payment flow. + +> info +> Test Entitlements do not have a `starts_at` or `ends_at` field as they are valid until they are deleted. + +### Using Live Entitlements + +If you'd like to test the full payment flow for your app, you can do so by interacting with your Store page or a [premium styled button](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS/prompting-users-to-subscribe). Any team members associated with your app will automatically see a 100% discount on the price of the subscription, allowing you to purchase without the use of live payment method. + +After checkout, you will have a live subscription that includes a `starts_at` and `ends_at` value. If you cancel this subscription, it will remain an active entitlement until the `ends_at` timestamp. This subscription will renew until canceled and can be used in testing subscription renewals in your app. + +> info +> You can only delete entitlements created using the [create entitlement](#DOCS_RESOURCES_ENTITLEMENT/create-test-entitlement) endpoint. If you need to toggle access to your premium features during your development process, it is best to use Test Entitlements. \ No newline at end of file diff --git a/docs/monetization/Implementing_One-Time_Purchases.md b/docs/monetization/Implementing_One-Time_Purchases.md new file mode 100644 index 0000000000..2d0c7c506f --- /dev/null +++ b/docs/monetization/Implementing_One-Time_Purchases.md @@ -0,0 +1,108 @@ +# Implementing One-Time Purchases + +One-time purchases enable you to charge your users for premium functionality with in-app items. + +- Before you can add one-time purchases to your app, you must [Enable Monetization](#DOCS_MONETIZATION_ENABLING_MONETIZATION) for your app. +- Once you've confirmed eligibility for your app and team, you will be able to set up a [SKU](#DOCS_RESOURCES_SKU) (stock-keeping unit) to represent your one-time purchases. + +--- + +## Types of One-Time Purchases + +When creating items for one-time purchase, you can choose between durable and consumable items: + +- **Durable Items**: A one-time purchase that is permanent and is not subject to either renewal or consumption, such as lifetime access to an app's premium features. +- **Consumable Items**: A one-time, non-renewable purchase that provides access, such as a temporary power-up or boost in a game. + +--- + +## How One-Time Purchases Work + +#### For Durable SKUs +- When a user purchases your durable SKU, Discord creates an [Entitlement](#DOCS_RESOURCES_ENTITLEMENT) for the purchasing user and that specific [SKU](#DOCS_RESOURCES_SKU). +- You will receive an `ENTITLEMENT_CREATE` event via the Gateway. +- This entitlement is now available via the `LIST Entitlements` API endpoint. +- This entitlement will be available on `Interaction Payloads` initiated from the entitled user. + +#### For Consumable SKUs +- When a user purchases your consumable SKU, Discord creates an [Entitlement](#DOCS_RESOURCES_ENTITLEMENT) for the purchasing user and that specific SKU. +- You will receive an `ENTITLEMENT_CREATE` event via the Gateway. +- This entitlement is now available via the `LIST Entitlements` API endpoint. +- This entitlement will be available on `Interaction Payloads` initiated from the entitled user or users in a guild (for guild subscriptions). +- The purchasing user is unable to make another purchase of this specific SKU until you consume the entitlement using the [Consume Entitlement API](#DOCS_RESOURCES_ENTITLEMENT/consume-an-entitlement) endpoint. +- When you receive an `ENTITLEMENT_CREATE` event for a consumable SKU, you should process the item purchase in your app and consume the entitlement as soon as possible. + +--- + +## Working with Entitlements + +When a user purchases a one-time purchase SKU, an entitlement is created. [Entitlements](#DOCS_RESOURCES_ENTITLEMENT) represent the user's access to your consumable or durable item. + +Depending on your app's features, you can use a combination of [Gateway events](#DOCS_TOPICS_GATEWAY_EVENTS/entitlements), the [Entitlement HTTP API](#DOCS_RESOURCES_ENTITLEMENT), and [interaction payloads](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING) to keep track of entitlements to users who have purchased items in your app. + +### Accessing Entitlements with Gateway Events +When a user purchases a SKU, Discord will emit an [`ENTITLEMENT_CREATE`](#DOCS_TOPICS_GATEWAY_EVENTS/entitlements) event. This event will contain the entitlement object that represents the user's access to the SKU. You can use this event to keep track of the user's entitlements in near-time. For One-Time Purchases, you may also receive an `ENTITLEMENT_DELETE` event if the user's entitlement is revoked. + +### Accessing Entitlements with the HTTP API +Entitlements are available via the [List Entitlements](#DOCS_RESOURCES_ENTITLEMENT/list-entitlements) endpoint. You can filter entitlements by a specific user or set of SKUs by using the `?user_id=XYZ` or `?sku_ids=XYZ` query parameters. + +### Accessing Entitlements on Interaction Payloads +Entitlements are also available on the `Interaction Payload` when a user interacts with your app. You can find the entitlements on the `entitlements` field of the `Interaction Payload` when [receiving and responding to interactions](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING). + +Depending on your app's needs, you can use a combination of these methods to keep track of user entitlements. + +--- + +## One-Time Purchase Considerations + +When implementing one-time purchases, you should consider the following: + +### For Durable One-Time Purchases + +When offering durable items, users will have access to the SKU indefinitely. Durable items can't be consumed, so you don't need to worry about the user losing access to the item except in the case of a refund. + +### For Consumable One-Time Purchases +When offering consumable items, users can only have one unconsumed entitlement at a time. To handle consumable items in your app or game, you should process and store the consumable item in your app and then make a call to the [Consume Entitlement](#DOCS_RESOURCES_ENTITLEMENT/consume-an-entitlement) endpoint so that the user can purchase more of this item in the future. + +Consuming the entitlement will update the entitlement to return a true value in the entitlement's `consumed` field. You will need to think through how your app keeps track of consumable items to decide on the best strategy for when to consume these entitlements and store the state of the consumable item and quantity in your app. + +--- + +## Prompting Users to Purchase an Item + +[Responding with a premium button](#DOCS_MONETIZATION_MANAGING_SKUS/responding-with-a-premium-button) gives you the ability to prompt users to subscribe to your app when they attempt to use a premium feature without a subscription. + +You can do this by sending a message with a [button](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/buttons) with a [premium style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) and a `sku_id` that allows the user to upgrade to your premium offering. + + +--- + +## Testing Your One-Time Purchase Implementation + +> warn +> The method of testing purchases for One-Time Purchases differs from the method for App Subscriptions. **Do NOT use Test Entitlements for One-Time Purchases.** + +### Using Application Test Mode + +While in Application Test Mode, you can freely make "purchases" of One-Time Purchase SKUs tied to your application. That means you can test buying your consumable and durable items by going through the In-App Purchase flow without any credit card charges. + +> info +> You still need to have a valid payment method on file to "purchase" SKUs in Application Test Mode. It just won't be charged at checkout. + +To enable it, first, make sure you have a payment method on file in `User Settings -> Billing` and then: + +1. Open up the Discord app +2. Click on the Settings cog in the bottom left corner +3. Go to the `Advanced` page under App Settings +4. Toggle "Developer Mode" **on** and "Application Test Mode" **on**, and enter your application ID. You can leave the other settings as-is. +5. Exit user settings + +Once you enabled Application Test Mode successfully, you should see an orange bar across the top of your screen with the name of your app. + +You can now navigate to your Store page and purchase your one-time purchase items without being charged. + +The entitlements tied to items purchased in Application Test Mode can be identified by entitlements with a `type` value of 4 to represent `TEST_MODE_PURCHASE`. + +> warn +> The "Go To SKU" button does not currently work. To purchase your SKU in test mode, go to your Store page. + diff --git a/docs/monetization/Managing_SKUs.mdx b/docs/monetization/Managing_SKUs.mdx new file mode 100644 index 0000000000..29a609bf3e --- /dev/null +++ b/docs/monetization/Managing_SKUs.mdx @@ -0,0 +1,221 @@ +# Managing SKUs + +The premium items and subscriptions you offer in your app are represented by SKUs. **SKU** stands for Stock Keeping Unit and is a unique identifier for your premium offerings. + +[SKUs](#DOCS_RESOURCES_SKU) are the building blocks of your premium offerings and you can manage them in the Developer Portal. + +--- + +## Creating a SKU + +To create a new SKU, navigate to your [app's settings](https://discord.com/developers/applications) and select the `Monetization -> Manage SKUs` tab. From there, you can create a new SKU by clicking the `Create SKU` button. + +When you click on `Create SKU`, you have the option to select from the following: + +- **User Subscription**: An auto-recurring subscription that grants benefits to one user in all servers +- **Guild Subscription**: An auto-recurring subscription that grants benefits to all users in one server +- **Consumable**: A one-time purchase that provides a temporary benefit, which is consumed upon use. +- **Durable**: A one-time purchase that **grants** a permanent addition or enhancement. + +Once you select the SKU type, enter a name for your SKU to continue. + +### 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). +- SKU prices must be selected from the list of available prices. + +> info +> If you need more SKUs than the 50 limit, consider creating a consumable in-app currency SKU that can be used to purchase items that are tracked in your app. + +--- + +## Customizing Your SKUs + +Once you've created a SKU, you can customize it to match your app's branding and the benefits you want to offer. You can customize: + +- A name for your premium SKU, max 80 characters. +- A description for your premium SKU, max 160 characters +- An image for your premium SKU +- A price for your premium SKU + +Your list of benefits will displayed on your app's Store page, the App Directory, and during the purchase and cancellation flows to explain to users the benefits of your premium offering. These benefits can have: +- Up to 6 benefits +- An emoji, standard or custom +- A name, max 80 characters +- A description, max 160 characters + +![Example of SKU benefits](sku-benefits.png) + +### Pricing Your SKUs + +When setting the price for your SKU, you can select from a list of predefined prices. The prices are automatically converted to the user's local currency based on their locale. + +Subscription SKUs are automatically charged each month unless canceled. Changing the price of this SKU will only change it for new subscribers. Existing subscribers will continue to be charged the existing price. + + +To set an icon using a standard Unicode emoji, enter the emoji in the `Unicode Emoji or Custom Emoji Name` field. + +> info +> Using an emoji keyboard can make it easier to pick an icon to display alongside your SKU benefit. +> MacOS: `control + command + space bar` +> Windows: `Windows + .` + +![Set a unicode emoji](sku-unicode.png) + + + +To use a custom emoji, set a value for both fields: + +- Name of your custom emoji +- ID of the custom emoji + +> info +> You can find the ID of the emoji in the Discord app by escaping the emoji in a message with a backslash character `\`. For example, `\:uwu:` will render with the name and ID of the emoji. + +![Set a custom emoji](sku-custom.png) + + +--- + +## Publishing and Unpublishing SKUs + +When you initially create a SKU, it will be in an `Unavailable` state. This SKU is not yet available for purchase by users. You can edit the SKU to add a price, benefits, and other details before publishing it. + +While creating and editing SKUs in your [app's settings](https://discord.com/developers/applications) on the `Monetization -> Manage SKUs` tab, you have a few options for managing your SKUs visibility and publishing to your users: + +- Publish SKU +- Unpublish SKU +- Delete SKU + +### Publishing a SKU + +When publishing a SKU, you have the option to make it **Available via the Store and API** or **Available via the API Only**. + +#### Publishing to Store & API + +Available to be purchased and visible in your app's store. + +#### Publishing to API Only + +You can only make API calls or use the Embedded App SDK to grant entitlements for this SKU. + +### Unpublishing a SKU + +> warn +> **Danger:** Unpublishing a SKU can affect your users' existing subscriptions and entitlements + +Unpublishing a SKU removes it from the Store and the API, making it unavailable for purchase. + +Unpublishing a SKU has the following effects: +- For subscription SKUs, subscriptions will not be renewed for users and guilds that have this SKU at the end of the billing period. +- Users and guilds will still be entitled to the SKU until the end of the billing period. +- For consumable and durable SKUs, users will still be entitled to the SKU if they purchased it before it was unpublished. +- Does not delete a SKU. + +### Deleting a SKU + +> warn +> **Danger:** Deleting a SKU can affect your users' existing subscriptions and entitlements + +Deletes a SKU in the UI and makes it unavailable for publishing. Deleted SKUs are still listed when calling [List SKUs](#DOCS_RESOURCES_SKU/list-skus) in the API. + +Deleting a SKU has the following effects: +- For subscription SKUs, users and guilds will be immediately unsubscribed from the SKU. Their entitlement will still be valid until the end of the billing period. +- For consumable and durable SKUs, users will still be entitled to the SKU if they purchased it before it was unpublished. + +--- + +## Editing a Published SKU +If you wish to change a SKU that is published, you can do so at any time by first unpublishing the currently published one. When you unpublish a SKU, it is no longer available for sale, but users who have already subscribed will remain subscribed. You must continue to make the premium offering available to them until the end of their subscription. + +### Changing a Subscription SKU Price + +When you change the price of a user or guild subscription SKU, it will only affect new subscribers. Existing subscribers will continue to be charged the price of the SKU at the time they subscribed. + +--- + +## Integrating SKUs in Your App + +After you've published your SKUs, you are ready to start implementing your premium features in your app. See our guides to get started. + + + + Learn how to start and manage recurring subscriptions within your app. + + + Learn how to implement one-time purchases in your app. + + + +--- + +## Viewing your Store Page + +Users can access an app's Store page from the Bot User's profile in a server. This allows users to view an available subscription and one-time purchases, select a subscription to view its perks, benefits, and details, and make a purchase directly from an app's Store page. + +> info +> Only subscriptions and items that have been published to the Store will be visible to users on the Store page. + +#### Accessing your Store page from a Bot User's Profile +![Accessing the store as a user](botuser-profile.png) + +#### Subscriptions in Your Store page +![Subscriptions in your Store View](premium-subscriptions.png) + +#### Items in Your Store page +![Items in your Store View](premium-items.png) + +--- + +## Linking to a Specific SKU + +You can link directly to a specific SKU using our Application Directory Store URL scheme: + +`https://discord.com/application-directory/:appID/store/:skuID` + +- When used in chat, it will render as a rich embed that allows users to launch a modal to view either the SKU details or checkout flow +- When used as a direct URL in a browser, it will take the user to your product in the Application Directory on web + +![Embed for direct link to SKU](sku_embed.png) + +--- + +## Linking To Your Store + +You can link directly to your Store page using our Application Directory Store URL scheme: + +`https://discord.com/application-directory/:appID/store` + +- When used in chat, it will render as a rich embed that allows users to launch a modal to your Store page +- When used as a direct URL in a browser, it will take the user to your Store page in the Application Directory on web + +![Embed for direct link to Store](store_embed.png) + +--- + +## Responding with a Premium Button + +You can prompt users to purchase item or subscription SKUs using a [button](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/buttons) with a [premium style](#DOCS_INTERACTIONS_MESSAGE_COMPONENTS/button-object-button-styles) and a `sku_id`. You can use this premium button style anywhere you would use message components, such as in a command response. + +```javascript +return new JsonResponse({ + type: 4, // InteractionResponseType.CHANNEL_MESSAGE_WITH_SOURCE + data: { + content: "This command requires Nelly Premium! Upgrade now to get access to these features!", + components: [{ + type: MessageComponentTypes.ACTION_ROW, + components: [ + { + type: MessageComponentTypes.BUTTON, + style: 6, // ButtonStyleTypes.PREMIUM + sku_id: '1234965026943668316', + }, + ], + }] + }, +}); +``` + +![A premium button](premium-button.png) \ No newline at end of file diff --git a/docs/monetization/Managing_Your_Store.md b/docs/monetization/Managing_Your_Store.md deleted file mode 100644 index 012196d790..0000000000 --- a/docs/monetization/Managing_Your_Store.md +++ /dev/null @@ -1,63 +0,0 @@ -# Managing Your Store - -Developers now have the ability to set up a Store page in the Developer Portal. To set up your Premium App's Store view take the following steps: - -- Create a SKU -- Add a SKU image and benefits -- Implement the SKU into your app -- Publish a SKU to your store view with the click of a button. - -## Adding SKUs to your Store - -Once you've created SKUs for an [App Subscription](#DOCS_MONETIZATION_APP_SUBSCRIPTIONS) or [One-Time Purchase](#DOCS_MONETIZATION_ONE-TIME_PURCHASES), you can add those SKUs to your Store to make them available for purchase by your users. - -### Manage SKUs - -While creating and editing SKUs in your [app's settings](https://discord.com/developers/applications) on the `Monetization -> Manage SKUs` tab, you have a few options for managing your SKUs visibility and publishing to your users: - -- **Add to store**: Will add a published SKU to your Store -- **Remove from store**: Will remove a published SKU from your Store, keeping it published to the API -- **Publish SKU**: Will let you publish a new SKU and make it **Available via Store & API** or **Available via API Only**. -- **Unpublish SKU**: Will unpublish the SKU from both the Store and the API. Users who already have this SKU will still be entitled to the SKU even if it becomes unpublished. You can republish a SKU at any time. - -> preview -> We will have more updates on publishing SKUs to the API vs the Store as we release more monetization features. - -### Manage Store - -Under the `Monetization -> Manage Store` tab, you can organize your SKUs for both subscriptions and items. You can add new or existing SKUs or update the order your SKUs appear to your users in the Store. - -> info -> Currently you can only have one Subscription published on your app and in your Store. - -## User Access for Your Store - -Users can now access an App's store page from the Bot User's profile in a server. This allows users to view an available subscription and one-time purchases, select a subscription to view its perks, benefits and details, and make a purchase directly from an App's Store page. - -![Accessing the store as a user](botuser-profile.png) - -### Viewing Subscriptions in Your Store - -Currently, you can only have one active App Subscription SKU for your app. If your app has either a user or guild subscription, you can add it to your Store for users to purchase. - -> preview -> Support for multiple subscription SKUs is coming soon. - -![Subscriptions in your Store View](premium-subscriptions.png) - -### Viewing Items in Your Store - -As you build out your One-Time Purchase SKUs, you can add as many durable and consumable items to your Store as needed by your app. - -![Items in your Store View](premium-items.png) - -## Linking To Your Store - -You can link directly to your Store using our Application Directory Store URL scheme: - -`https://discord.com/application-directory/:appID/store` - -- When used in chat, it will render as a rich embed that allows users to launch a modal to your Store -- When used as a direct URL in a browser, it will take the user to your store in the Application Directory on web - -![Embed for direct link to Store](store_embed.png) \ No newline at end of file diff --git a/docs/monetization/One-Time_Purchases.md b/docs/monetization/One-Time_Purchases.md deleted file mode 100644 index f94b7739eb..0000000000 --- a/docs/monetization/One-Time_Purchases.md +++ /dev/null @@ -1,96 +0,0 @@ -# One-Time Purchases - -One-time purchases enable you to charge your users for premium functionality with in-app items. Before you can add one-time purchases to your app, you must complete the [Monetization Eligibility Checklist](#DOCS_MONETIZATION_OVERVIEW/eligibility-checklist) in your [app's settings](https://discord.com/developers/applications). - -Once you've confirmed eligibility for your app and team, you will be able to set up a [SKU](#DOCS_MONETIZATION_SKUS) (stock-keeping unit) to represent your app's premium offering via subscriptions or items. - -## Types of One-Time Purchases - -When creating items for one-time purchase, you can choose between durable and consumable items: - -- **Durable Items**: A one-time purchase that is permanent and is not subject to either renewal or consumption, such as lifetime access to an app's premium features. -- **Consumable Items**: A one-time, non-renewable purchase that provides access, such as a temporary power-up or boost in a game. - -You can offer as many one-time purchase SKUs as needed by your app. - -## Configuring One-Time Purchases - -Once you have an idea what type of items you want to offer for your app, you can create either durable or consumable SKUs to reflect the benefits that the user will receive from purchasing your new item. - -As you are setting up a new SKU, you can configure: - -- SKU Image -- Name -- Product Description -- Price - -![Configuring your SKU](sku-configure.png) - -## Publishing Your One-Time Purchases - -Once you have configured your SKU, you can publish the SKU to either just the API or the API and your Store. Learn more about [Managing Your Store](#DOCS_MONETIZATION_MANAGING_YOUR_STORE) to curate what items you make available to your users. - -![Publishing your SKU](sku-publish.png) - -## Implementing One-Time Purchases - -When a user subscribes to your app, there are a few things you will need to implement in your code to check for subscription status and access. - -- Working with Entitlements -- Handling Gateway Events for Entitlements -- Handling Entitlements for Consumable SKUs - -### Keeping Track of Entitlements - -When a user purchases a one-time purchase SKU, an entitlement is created. [Entitlements](#DOCS_MONETIZATION_ENTITLEMENTS) represent the user's access to your consumable or durable item. You can keep track of entitlements using Gateway Events and the HTTP API. - -#### Entitlement Gateway Events - -When users subscribe or renew a subscription with your app, Discord will emit [entitlement gateway events](#DOCS_MONETIZATION_ENTITLEMENTS/gateway-events). - -Upon a user's purchase of a SKU, you'll receive an [`ENTITLEMENT_CREATE`](#DOCS_MONETIZATION_ENTITLEMENTS/new-entitlement) event. - -#### Entitlement HTTP Endpoints - -For apps requiring background processing, keeping track of entitlements is essential. You can utilize the [List Entitlements](#DOCS_MONETIZATION_ENTITLEMENTS/list-entitlements) endpoint to list entitlements. Your app can filter entitlements by a specific user or set of SKUs by using the `?user_id=XYZ` or `?sku_ids=XYZ` query params. - -#### Handling Consumable One-Time Purchases - -When offering consumable items, users can only have one unconsumed entitlement at a time. In order to handle consumable items in your app or game, you should process and store the consumable item in your app and then make a call to the [Consume Entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/consume-an-entitlement) endpoint so that the user can purchase more of this item in the future. - -Consuming the entitlement will update the entitlement to return a true value in the entitlement's `consumed` field. You will need to think through how your app uses consumable items to decide on the best strategy for when to consume these entitlements. - -## Testing Your Implementation - -> warn -> The method of testing purchases for One-Time Purchases differs from the method for App Subscriptions. **Do NOT use Test Entitlements for One-Time Purchases.** - -### Using Application Test Mode - -While in Application Test Mode, you can freely make "purchases" of One-Time Purchase SKUs tied to your application. That means you can test buying your consumable and durable items by going through the IAP flow without any credit card charges. - -> info -> You still need to have a valid payment method on file to "purchase" SKUs in Application Test Mode. It just won't be charged at checkout. - -To enable it, first make sure you have a payment method on file in User Settings -> Billing and then: - -1. Open up the Discord app -2. Click on the Settings cog in the bottom left corner -3. Go to the `Advanced` page under App Settings -4. Toggle "Developer Mode" **on** and "Application Test Mode" **on**, and enter your application ID. You can leave the other settings as-is. -5. Exit user settings - -Once you enabled Application Test Mode successfully, you should now see an orange bar across the top of your screen with the name of your app. - -You can now navigate to your [Store](#DOCS_MONETIZATION_MANAGING_YOUR_STORE) page and purchase your one-time purchase items without being charged. - -The entitlements tied to items that are purchased in Application Test Mode can be identified by entitlements with a `type` value of 4 to represent `TEST_MODE_PURCHASE`. - -> info -> The "Go To SKU" button does not currently work. There will be an update there soon. To purchase your SKU in test mode, go to your Store page. - -## Receiving Payouts - -Once an app has made its first $100 it will become eligible for payout. A review will be conducted and if everything looks good, your team will begin to receive payouts. - -For more information, read the [Premium Apps Payouts](https://support-dev.discord.com/hc/articles/17299902720919) Help Center article. diff --git a/docs/monetization/Overview.md b/docs/monetization/Overview.md deleted file mode 100644 index 314a2c3051..0000000000 --- a/docs/monetization/Overview.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -sidebar_label: Overview ---- - -# Monetizing Your Discord App - -Premium Apps is a set of monetization features for apps on Discord that allows developers to: - -- Sell monthly recurring [subscriptions](#DOCS_MONETIZATION_APP_SUBSCRIPTIONS) for your app's premium functionality within Discord -- Sell [one-time purchases](#DOCS_MONETIZATION_ONE-TIME_PURCHASES) for both durable and consumable items or functionality within your app -- Highlight your app's premium benefits on the App Directory and on your own [Store](#DOCS_MONETIZATION_MANAGING_YOUR_STORE) page -- Offer native product tie-ins and upsells on the App Directory, app profiles, and in chat - -![Premium App screenshot](premium-example.png) - -## Eligibility Checklist - -Before you can start creating SKUs and offering subscriptions for your app, your app and team must be eligible for monetization. - -Only team owners can enable monetization for an app. When a team owner enables monetization, they'll be taken through a series of steps and checks to ensure the following criteria are met: - -- App must be verified -- App belongs to a developer team -- Team owner must be at least 18 years old -- Team must have verified emails and 2FA set up -- App uses slash commands, or has been approved for the privileged `Message Content` intent -- App has a link to your Terms of Service - - This document is an agreement between you and users governing the use of your app. -- App has a link to your Privacy Policy - - This document should clearly and accurately describe to users of your app the user data you collect and how you use and share such data with us and third parties, consistent with our Developer Terms of Service and Developer Policy. -- App must not contain any harmful or bad language in the name, description, commands, or role connection metadata. -- Payouts must be setup with a valid payment method -- Agreement to the [Monetization Terms](https://support.discord.com/hc/articles/5330075836311) and [Discord App Subscriptions Policy](https://support-dev.discord.com/hc/articles/17442400631959). - -## Setting Up Monetization - -Adding monetization to your app is a three-step process: - -1. Set up your app and developer team to offer subscriptions and one-time purchases -2. Create and customize a SKU for your app subscription or one-time purchase -3. Adding support for SKUs and Entitlements to your app - -### Configuring Your App - -Before monetization can be enabled, you will need: - -- A [team](#DOCS_TOPICS_TEAMS) in the developer portal. If you don't have one, you can [create one on the Teams page](https://discord.com/developers/teams) -- A [verified app](https://support.discord.com/hc/en-us/articles/360040720412-Bot-Verification-and-Data-Allowlisting#h_46b3869c-6d50-43fc-b07c-9ed7569a1160) that is _owned by that team_ - -### Setting Up Team Payouts - -In the meantime, you can begin setting up your payout information so you can get paid! Discord does all payout processing through Stripe, so part of setting up payouts will be going through Stripe's onboarding flow. - -Only the owner of the team can enable payout settings for the team. - -#### If You are Based in the United States, European Union, or United Kingdom - -- Click on [your team](https://discord.com/developers/teams) on the Teams page. -- Select "Payout Settings" - - If you do not see "Payout Settings", you are not the owner of the team. Only the owner of the team can enable payout settings for the team. -- Complete the onboarding flow through Stripe - -#### If You are Based Outside of the United States, European Union, or United Kingdom - -Premium Apps is not currently available outside of these regions. These features will be made available to more regions soon. - -### Implementing Your Premium Features - -Once your team and app are all set up for monetization, you are ready to [customize your subscription](#DOCS_MONETIZATION_SKUS/customizing-your-skus) and [implement your premium features](#DOCS_MONETIZATION_APP_SUBSCRIPTIONS) in your app! diff --git a/docs/monetization/Overview.mdx b/docs/monetization/Overview.mdx new file mode 100644 index 0000000000..c3a7067753 --- /dev/null +++ b/docs/monetization/Overview.mdx @@ -0,0 +1,52 @@ +--- +sidebar_label: Overview +--- + +# Monetizing Your Discord App + +![Monetizing Your Discord App](monetization-overview.png) + +### Offer native payment and checkout in your app using our Monetization APIs. + +Premium Apps lets you prompt customers to start subscriptions or purchase one-time items with our easy-to-use checkout and payment process. Discord notifies your app of the user's purchase, allowing you to grant access to your premium features. + +- Sell monthly recurring [subscriptions](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS) for your app's premium functionality within Discord +- Sell [one-time purchases](#DOCS_MONETIZATION_IMPLEMENTING_ONE-TIME_PURCHASES) for both durable and consumable items or functionality within your app +- Highlight your app's premium benefits on the App Directory and on your own [Store](#DOCS_MONETIZATION_MANAGING_SKUS/viewing-your-store-page) page +- Offer native product tie-ins and upsells on the App Directory, app profiles, and in-chat +- With secure transactions & fraud detection, your customers can securely pay for purchases without leaving Discord + +--- + +## Components of a Premium App + +To integrate a premium feature into your application, there are three primary components of our Monetization API: + +- [SKUs](#DOCS_RESOURCES_SKU) represent specific items or subscription options your app offers. Each SKU is a unique offering. +- [Entitlements](#DOCS_RESOURCES_ENTITLEMENT) indicate whether a user has access to a specific premium offering or SKU. +- [Subscriptions](#DOCS_RESOURCES_SUBSCRIPTION) represent an ongoing agreement where a user commits to paying for an entitlement on a recurring basis until canceled. + +### Types of SKUs + +There are two types of SKUs that you can create for your app: + +#### One-Time Purchase SKUs + +A one-time purchase SKU represents a single item or feature that a user can purchase once. Developers can offer two types of one-time purchases: +- Durable items: Items that a user can purchase once and keep forever. For example, a user might purchase a "premium" upgrade that unlocks premium features in an app. +- Consumable items: Items that a user can purchase once and use up. For example, a user might purchase a "boost" item that gives them a temporary boost in an app. + +#### Subscription SKUs + +A subscription SKU represents a recurring purchase that a user can subscribe to for a set period of time. Developers can offer two types of subscriptions: + +- User subscriptions: A user subscribes to a SKU for themselves. In this case, only the purchasing user is considered entitled to the SKU. +- Guild subscriptions: A user subscribes to a SKU for their guild. All members of that guild are considered entitled to the SKU. + +--- + +## Next Steps + +Ready to start monetizing your app? + +Follow our full guide for [Enabling Monetization](#DOCS_MONETIZATION_ENABLING_MONETIZATION) and implementing premium features in your app. \ No newline at end of file diff --git a/docs/quick_start/Overview_of_Apps.mdx b/docs/quick_start/Overview_of_Apps.mdx index 34e1114196..bae3fcf623 100644 --- a/docs/quick_start/Overview_of_Apps.mdx +++ b/docs/quick_start/Overview_of_Apps.mdx @@ -46,7 +46,7 @@ Apps can also update a user's **[rich presence](#DOCS_RICH_PRESENCE_OVERVIEW)** ### Add premium features -**[App subscriptions](#DOCS_MONETIZATION_APP_SUBSCRIPTIONS)** let apps charge users and/or servers for premium functionality on a recurring basis natively within Discord. You can read more about eligibility and adding monetization features to your app in the [Monetization](#DOCS_MONETIZATION_OVERVIEW) documentation. +**[App subscriptions](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS)** let apps charge users and/or servers for premium functionality on a recurring basis natively within Discord. You can read more about eligibility and adding monetization features to your app in the [Monetization](#DOCS_MONETIZATION_OVERVIEW) documentation. ### ...and more diff --git a/docs/monetization/Entitlements.md b/docs/resources/Entitlement.md similarity index 68% rename from docs/monetization/Entitlements.md rename to docs/resources/Entitlement.md index 9fa9e9aa85..c4eb10c51b 100644 --- a/docs/monetization/Entitlements.md +++ b/docs/resources/Entitlement.md @@ -1,8 +1,12 @@ -# Entitlements +--- +sidebar_label: Entitlement +--- + +# Entitlements Resource -## Entitlement Resource +Entitlements in Discord represent that a user or guild has access to a premium offering in your application. -Entitlements in Discord represent that a user or guild has access to a premium offering in your application. +Refer to the [Monetization Overview](#DOCS_MONETIZATION_OVERVIEW) for more information on how to use Entitlements in your app. ### Entitlement Object @@ -14,7 +18,7 @@ Entitlements in Discord represent that a user or guild has access to a premium o | sku_id | snowflake | ID of the SKU | | application_id | snowflake | ID of the parent application | | user_id? | snowflake | ID of the user that is granted access to the entitlement's sku | -| type | integer | [Type of entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object-entitlement-types) | +| type | integer | [Type of entitlement](#DOCS_RESOURCES_ENTITLEMENT/entitlement-object-entitlement-types) | | deleted | boolean | Entitlement was deleted | | starts_at? | ISO8601 timestamp | Start date at which the entitlement is valid. Not present when using test entitlements. | | ends_at? | ISO8601 timestamp | Date at which the entitlement is no longer valid. Not present when using test entitlements. | @@ -90,9 +94,9 @@ Returns all entitlements for a given app, active and expired. ] ``` -## Consume an Entitlement % POST /applications/{application.id#DOCS_RESOURCES_APPLICATION/application-object}/entitlements/{entitlement.id#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object}/consume +## Consume an Entitlement % POST /applications/{application.id#DOCS_RESOURCES_APPLICATION/application-object}/entitlements/{entitlement.id#DOCS_RESOURCES_ENTITLEMENT/entitlement-object}/consume -For One-Time Purchase consumable SKUs, marks a given entitlement for the user as consumed. The entitlement will have `consumed: true` when using [List Entitlements](#DOCS_MONETIZATION_ENTITLEMENTS/list-entitlements). +For One-Time Purchase consumable SKUs, marks a given entitlement for the user as consumed. The entitlement will have `consumed: true` when using [List Entitlements](#DOCS_RESOURCES_ENTITLEMENT/list-entitlements). Returns a `204 No Content` on success. @@ -120,81 +124,8 @@ After creating a test entitlement, you'll need to reload your Discord client. Af } ``` -## Delete Test Entitlement % DELETE /applications/{application.id#DOCS_RESOURCES_APPLICATION/application-object}/entitlements/{entitlement.id#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object} +## Delete Test Entitlement % DELETE /applications/{application.id#DOCS_RESOURCES_APPLICATION/application-object}/entitlements/{entitlement.id#DOCS_RESOURCES_ENTITLEMENT/entitlement-object} Deletes a currently-active test entitlement. Discord will act as though that user or guild _no longer has_ entitlement to your premium offering. -Returns `204 No Content` on success. - ---- - -## Gateway Events - -### New Entitlement - -`ENTITLEMENT_CREATE` - -Fires when a user subscribes to a SKU. Contains an entitlement object. - -```json -{ - "id": "1083167266843000832", - "sku_id": "1083142056391606272", - "application_id": "1083108937882013696", - "user_id": "1072239583707664384", - "promotion_id": null, - "type": 8, - "deleted": false, - "gift_code_flags": 0, - "consumed": false, - "starts_at": "2023-03-08T23:19:58.010876+00:00", - "ends_at": "2023-04-08T23:19:58.010876+00:00", - "subscription_id": "1083167255652597760" -} -``` - -### Updated Entitlement - -`ENTITLEMENT_UPDATE` - -Fires when a user's subscription renews for the next billing period. The `ends_at` field will have an updated value with the new expiration date. - -If a user's subscription is cancelled, you will _not_ receive an `ENTITLEMENT_DELETE` event. Instead, you will simply not receive an `UPDATE` event with a new `ends_at` date at the end of the billing period. - -### Deleted Entitlement - -`ENTITLEMENT_DELETE` - -Fires when a user's entitlement is deleted. Entitlement deletions are infrequent, and occur when: - -- Discord issues a refund for a subscription -- Discord removes an entitlement from a user via internal tooling - -Entitlements are _not_ deleted when they expire. - ---- - -## Using Entitlements in Interactions - -### PREMIUM_REQUIRED Interaction Response - -If your app has monetization enabled, it will have access to a new [`PREMIUM_REQUIRED` interaction response (`type: 10`)](#DOCS_INTERACTIONS_RECEIVING_AND_RESPONDING/interaction-response-object-interaction-callback-type). This can be sent in response to all interaction types except for `APPLICATION_COMMAND_AUTOCOMPLETE` and `PING`. The response does not allow returning the `content`, `embeds`, or `attachments` fields. - -This response will create an ephemeral message shown to the user that ran the interaction, instructing them that whatever they tried to do requires the premium benefits of your app. It also contains an "Upgrade" button to subscribe. The response message is static, but will be automatically updated with the name of your premium SKU. - -![Interaction Response](monetization-interaction-response.png) - -```js -return res.send({ - type: InteractionResponseType.PREMIUM_REQUIRED, // This has a value of 10 - data: {}, -}); -``` - ---- - -### Checking Entitlements in Interactions - -To check what the current guild or user has entitlements to, your app can inspect the `entitlements` field. `entitlements` is an array of [entitlement objects](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object) for the current guild and user. - -You can reference `entitlements` during interactions to handle subscription status, rather than fetching entitlements from the API or your database. +Returns `204 No Content` on success. \ No newline at end of file diff --git a/docs/monetization/SKUs.md b/docs/resources/SKU.md similarity index 61% rename from docs/monetization/SKUs.md rename to docs/resources/SKU.md index 568c303575..52e36ac26b 100644 --- a/docs/monetization/SKUs.md +++ b/docs/resources/SKU.md @@ -1,5 +1,5 @@ --- -sidebar_label: SKUs +sidebar_label: SKU --- # SKU Resource @@ -10,14 +10,14 @@ SKUs (stock-keeping units) in Discord represent premium offerings that can be ma ###### SKU Structure -| Field | Type | Description | -|----------------|-----------|-----------------------------------------------------------------------------------------------------------------------------| -| id | snowflake | ID of SKU | -| type | integer | [Type of SKU](#DOCS_MONETIZATION_SKUS/sku-object-sku-types) | -| application_id | snowflake | ID of the parent application | -| name | string | Customer-facing name of your premium offering | -| slug | string | System-generated URL slug based on the SKU's name | -| flags | integer | [SKU flags](#DOCS_MONETIZATION_SKUS/sku-object-sku-flags) combined as a [bitfield](https://en.wikipedia.org/wiki/Bit_field) | +| Field | Type | Description | +|----------------|-----------|-------------------------------------------------------------------------------------------------------------------------| +| id | snowflake | ID of SKU | +| type | integer | [Type of SKU](#DOCS_RESOURCES_SKU/sku-object-sku-types) | +| application_id | snowflake | ID of the parent application | +| name | string | Customer-facing name of your premium offering | +| slug | string | System-generated URL slug based on the SKU's name | +| flags | integer | [SKU flags](#DOCS_RESOURCES_SKU/sku-object-sku-flags) combined as a [bitfield](https://en.wikipedia.org/wiki/Bit_field) | ###### SKU Example @@ -65,68 +65,6 @@ The `flags` field can be used to differentiate user and server subscriptions wit | GUILD_SUBSCRIPTION | `1 << 7` | Recurring SKU that can be purchased by a user and applied to a single server. Grants access to every user in that server. | | USER_SUBSCRIPTION | `1 << 8` | Recurring SKU purchased by a user for themselves. Grants access to the purchasing user in every server. | -## Customizing Your SKUs - -Within your app's settings, you're able to customize details about your premium offering: - -- A name for your premium SKU, max 80 characters. -- A description for your premium SKU, max 160 characters -- An icon for your premium SKU - -![Example SKU customization](sku-customization.png) - -### Adding Benefits to Your SKU - -You're able to customize a list of up to 6 benefits to explain your premium offering to users. Benefits are displayed on the App Directory and during the purchase and cancellation flows, and each can have: - -- A name, max 80 characters -- A description, max 160 characters -- An emoji, standard or custom - -![Example of SKU benefits](sku-benefits.png) - -#### Using a Unicode Emoji - -To set an icon using a standard Unicode emoji, enter the emoji in the `Unicode Emoji or Custom Emoji Name` field. - -> info -> Using an emoji keyboard can make it easier to pick an icon to display alongside your SKU benefit. -> MacOS: `control + command + space bar` -> Windows: `Windows + .` - -![Set a unicode emoji](sku-unicode.png) - -#### Using a Custom Emoji - -To use a custom emoji, set a value for both fields: - -- Name of your custom emoji -- ID of the custom emoji - -> info -> You can find the ID of the emoji in the Discord app by escaping the emoji in a message with a backslash character `\`. For example, `\:uwu:` will render with the name and ID of the emoji. - -![Set a custom emoji](sku-custom.png) - -## Publishing Your SKUs - -When you're ready to launch, you can go to your [app's settings](https://discord.com/developers/applications) and change your SKU to "Published", and your premium offering will be live and available for purchase by users. - -From then on, we'll send you daily dashboard emails containing information about purchases, cancellations, and other premium information. - -Congratulations on going live! 🥳 - -## Linking to your SKUs - -You can link directly to a specific SKU using our Application Directory Store URL scheme: - -`https://discord.com/application-directory/:appID/store/:skuID` - -- When used in chat, it will render as a rich embed that allows users to launch a modal to view either the SKU details or checkout flow -- When used as a direct URL in a browser, it will take the user to your product in the Application Directory on web - -![Embed for direct link to SKU](sku_embed.png) - ## List SKUs % GET /applications/{application.id#DOCS_RESOURCES_APPLICATION/application-object}/skus Returns all SKUs for a given application. diff --git a/docs/resources/Subscription.md b/docs/resources/Subscription.md new file mode 100644 index 0000000000..75ca6311fa --- /dev/null +++ b/docs/resources/Subscription.md @@ -0,0 +1,74 @@ +--- +sidebar_label: Subscription +--- + +# Subscription Resource + +Subscriptions in Discord represent a user making recurring payments for at least one SKU over an ongoing period. Successful payments grant the user access to entitlements associated with the SKU. + +## 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. | + +The start of a subscription is determined by its ID. When the subscription renews, its current period is updated. + +If the user cancels the subscription, the subscription will enter the `ENDING` status and the `canceled_at` timestamp will reflect the time of the cancellation. + +### Subscription Example + +```json +{ + "id": "1278078770116427839", + "user_id": "1088605110638227537", + "sku_ids": ["1158857122189168803"], + "entitlement_ids": [], + "current_period_start": "2024-08-27T19:48:44.406602+00:00", + "current_period_end": "2024-09-27T19:48:44.406602+00:00", + "status": 0, + "canceled_at": null +} +``` + +### Subscription Statuses + +| Type | Value | Description | +|----------|-------|-------------------------------------------------| +| ACTIVE | 1 | Subscription is active and scheduled to renew. | +| ENDING | 2 | Subscription is active but will not renew. | +| INACTIVE | 3 | Subscription is inactive and not being charged. | + +> info +> Subscription status should not be used to grant perks. Use [entitlements](#DOCS_RESOURCES_ENTITLEMENT/entitlement-object) as an indication of whether a user should have access to a specific SKU. See our guide on [Implementing App Subscriptions](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS) for more information. + +Subscriptions can start and change between any of these statuses within the current period. A subscription can be `ACTIVE` outside its current period or `INACTIVE` within its current period. + +Some examples of this behavior include: +- While a failed payment is being retried, the subscription would remain `ACTIVE` until it succeeds or our system determines the payment is not recoverable. +- A refund or chargeback during the current period would make the subscription `INACTIVE`. + +## List SKU Subscriptions % GET /skus/{sku.id#DOCS_RESOURCES_SKU/sku-object}/subscriptions + +Returns all subscriptions containing the SKU, filtered by user. Returns a list of [subscription](#DOCS_RESOURCES_SUBSCRIPTION/subscription-object) objects. + +### Query String Params + +| Field | Type | Description | Default | +|----------|-----------|-------------------------------------------------------------------------------|---------| +| before? | snowflake | List subscriptions before this ID | absent | +| after? | snowflake | List subscriptions after this ID | absent | +| limit? | integer | Number of results to return (1-100) | 50 | +| user_id? | snowflake | User ID for which to return subscriptions. Required except for OAuth queries. | absent | + +## Get SKU Subscription % GET /skus/{sku.id#DOCS_RESOURCES_SKU/sku-object}/subscriptions/{subscription.id#DOCS_MONETIZATION_SUBSCRIPTIONS/subscription-object} + +Get a subscription by its ID. Returns a [subscription](#DOCS_RESOURCES_SUBSCRIPTION/subscription-object) object. \ No newline at end of file diff --git a/docs/topics/Gateway_Events.md b/docs/topics/Gateway_Events.md index 4b4f69cb78..9171211ed5 100644 --- a/docs/topics/Gateway_Events.md +++ b/docs/topics/Gateway_Events.md @@ -334,6 +334,9 @@ Receive events are Gateway events encapsulated in an [event payload](#DOCS_TOPIC | [Stage Instance Create](#DOCS_TOPICS_GATEWAY_EVENTS/stage-instance-create) | Stage instance was created | | [Stage Instance Update](#DOCS_TOPICS_GATEWAY_EVENTS/stage-instance-update) | Stage instance was updated | | [Stage Instance Delete](#DOCS_TOPICS_GATEWAY_EVENTS/stage-instance-delete) | Stage instance was deleted or closed | +| [Subscription Create](#DOCS_TOPICS_GATEWAY_EVENTS/subscription-create) | Premium App Subscription was created | +| [Subscription Update](#DOCS_TOPICS_GATEWAY_EVENTS/subscription-update) | Premium App Subscription was updated | +| [Subscription Delete](#DOCS_TOPICS_GATEWAY_EVENTS/subscription-delete) | Premium App Subscription was deleted | | [Typing Start](#DOCS_TOPICS_GATEWAY_EVENTS/typing-start) | User started typing in a channel | | [User Update](#DOCS_TOPICS_GATEWAY_EVENTS/user-update) | Properties about the user changed | | [Voice Channel Effect Send](#DOCS_TOPICS_GATEWAY_EVENTS/voice-channel-effect-send) | Someone sent an effect in a voice channel the current user is connected to | @@ -553,15 +556,33 @@ Sent when a message is pinned or unpinned in a text channel. This is not sent wh #### Entitlement Create -Sent when an entitlement is created. The inner payload is an [entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object) object. +> danger +> Starting on October 1st, 2024, the `ENTITLEMENT_CREATE` event will have an `ends_at` value of null. Please see the [Change Log and Entitlement Migration Guide](#DOCS_CHANGE_LOG/subscription-api-and-entitlement-migration) for more information. + +Sent when an entitlement is created. The inner payload is an [entitlement](#DOCS_RESOURCES_ENTITLEMENT/entitlement-object) object. #### Entitlement Update -Sent when an entitlement is updated. The inner payload is an [entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object) object. When an entitlement for a subscription is renewed, the `ends_at` field may have an updated value with the new expiration date. +> danger +> Starting on October 1st, 2024, the `ENTITLEMENT_UPDATE` event behavior will be changing. You will no longer receive an `ENTITLEMENT_UPDATE` event on successful renewal When a user cancels, you will receive an `ENTITLEMENT_UPDATE` events with a valid `ends_at` value reflecting when their subscription ends. Please see the [Change Log and Entitlement Migration Guide](#DOCS_CHANGE_LOG/subscription-api-and-entitlement-migration) for more information. + +Sent when an entitlement is updated. The inner payload is an [entitlement](#DOCS_RESOURCES_ENTITLEMENT/entitlement-object) object. + +For subscription entitlements, when a user's subscription is renewed you will receive an `ENTITLEMENT_UPDATE` event with a new `ends_at` date that reflects the end of the new billing period. + +If a user cancels their subscription, you will stop receiving `ENTITLEMENT_UPDATE` events that update the `ends_at` value. #### Entitlement Delete -Sent when an entitlement is deleted. The inner payload is an [entitlement](#DOCS_MONETIZATION_ENTITLEMENTS/entitlement-object) object. Entitlements are not deleted when they expire. +Sent when an entitlement is deleted. The inner payload is an [entitlement](#DOCS_RESOURCES_ENTITLEMENT/entitlement-object) object. + +Entitlement deletions are infrequent, and occur when: + +- Discord issues a refund for a subscription +- Discord removes an entitlement from a user via internal tooling +- Discord deletes an app-managed entitlement they created via the API + +Entitlements are _not_ deleted when they expire. ### Guilds @@ -1284,6 +1305,25 @@ Sent when a [Stage instance](#DOCS_RESOURCES_STAGE_INSTANCE) has been updated. I Sent when a [Stage instance](#DOCS_RESOURCES_STAGE_INSTANCE) has been deleted (i.e. the Stage has been closed). Inner payload is a [Stage instance](#DOCS_RESOURCES_STAGE_INSTANCE/stage-instance-object) +### Subscriptions + +#### Subscription Create + +> info +> Subscription status should not be used to grant perks. Use [entitlements](#DOCS_RESOURCES_ENTITLEMENT/entitlement-object) as an indication of whether a user should have access to a specific SKU. See our guide on [Implementing App Subscriptions](#DOCS_MONETIZATION_IMPLEMENTING_APP_SUBSCRIPTIONS) for more information. + +Sent when a [Subscription](#DOCS_RESOURCES_SUBSCRIPTION) for a Premium App is created. Inner payload is a [Subscription](#DOCS_RESOURCES_SUBSCRIPTION/subscription-object). + +A Subscription's `status` can be either **inactive** or **active** when this event is received. You will receive subsequent `SUBSCRIPTION_UPDATE` events if the `status` is updated to **active**. As a best practice, you should not grant any perks to users until the entitlements are created. + +#### Subscription Update + +Sent when a [Subscription](#DOCS_RESOURCES_SUBSCRIPTION) for a Premium App has been updated. Inner payload is a [Subscription](#DOCS_RESOURCES_SUBSCRIPTION/subscription-object) object. + +#### Subscription Delete + +Sent when a [Subscription](#DOCS_RESOURCES_SUBSCRIPTION) for a Premium App has been deleted. Inner payload is a [Subscription](#DOCS_RESOURCES_SUBSCRIPTION/subscription-object) object. + ### Polls #### Message Poll Vote Add diff --git a/images/monetization-overview.png b/images/monetization-overview.png new file mode 100644 index 0000000000..dc450ec99a Binary files /dev/null and b/images/monetization-overview.png differ