-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Premium Apps: One-Time Purchase SKUs + Managing Your Store #6820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
ff3f79e
9490b78
9a73bd0
529eedc
e46ff71
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,32 +17,40 @@ Entitlements in Discord represent that a user or guild has access to a premium o | |
| 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. | | ||
| guild_id? | snowflake | ID of the guild that is granted access to the entitlement's sku | | ||
| consumed? | boolean | For consumable items, whether or not the entitlement has been consumed | | ||
|
||
###### Entitlement Example | ||
|
||
```json | ||
{ | ||
"id": "1019653849998299136", | ||
"sku_id": "1019475255913222144", | ||
"application_id": "1019370614521200640", | ||
"user_id": "771129655544643584", | ||
"promotion_id": null, | ||
"type": 8, | ||
"deleted": false, | ||
"gift_code_flags": 0, | ||
"consumed": false, | ||
"starts_at": "2022-09-14T17:00:18.704163+00:00", | ||
"ends_at": "2022-10-14T17:00:18.704163+00:00", | ||
"guild_id": "1015034326372454400", | ||
"subscription_id": "1019653835926409216" | ||
"id": "1019653849998299136", | ||
"sku_id": "1019475255913222144", | ||
"application_id": "1019370614521200640", | ||
"user_id": "771129655544643584", | ||
"promotion_id": null, | ||
"type": 8, | ||
"deleted": false, | ||
"gift_code_flags": 0, | ||
"consumed": false, | ||
"starts_at": "2022-09-14T17:00:18.704163+00:00", | ||
"ends_at": "2022-10-14T17:00:18.704163+00:00", | ||
"guild_id": "1015034326372454400", | ||
"subscription_id": "1019653835926409216" | ||
} | ||
``` | ||
|
||
###### Entitlement Types | ||
|
||
| Type | Value | Description | | ||
|--------------------------|-------|--------------------------------------------------| | ||
| APPLICATION_SUBSCRIPTION | 8 | Entitlement was purchased as an app subscription | | ||
| Type | Value | Description | | ||
|--------------------------|-------|----------------------------------------------------------------| | ||
| PURCHASE | 1 | Entitlement was purchased by user | | ||
| PREMIUM_SUBSCRIPTION | 2 | Entitlement for Discord Nitro subscription | | ||
| DEVELOPER_GIFT | 3 | Entitlement was gifted by developer | | ||
| TEST_MODE_PURCHASE | 4 | Entitlement was purchased by a dev in application test mode | | ||
| FREE_PURCHASE | 5 | Entitlement was granted when the SKU was free | | ||
| USER_GIFT | 6 | Entitlement was gifted by another user | | ||
| PREMIUM_PURCHASE | 7 | Entitlement was claimed by user for free as a Nitro Subscriber | | ||
| APPLICATION_SUBSCRIPTION | 8 | Entitlement was purchased as an app subscription | | ||
|
||
## List Entitlements % GET /applications/{application.id#DOCS_RESOURCES_APPLICATION/application-object}/entitlements | ||
|
||
|
@@ -62,24 +70,30 @@ Returns all entitlements for a given app, active and expired. | |
|
||
```json | ||
[ | ||
{ | ||
"id": "1019653849998299136", | ||
"sku_id": "1019475255913222144", | ||
"application_id": "1019370614521200640", | ||
"user_id": "771129655544643584", | ||
"promotion_id": null, | ||
"type": 8, | ||
"deleted": false, | ||
"gift_code_flags": 0, | ||
"consumed": false, | ||
"starts_at": "2022-09-14T17:00:18.704163+00:00", | ||
"ends_at": "2022-10-14T17:00:18.704163+00:00", | ||
"guild_id": "1015034326372454400", | ||
"subscription_id": "1019653835926409216" | ||
} | ||
{ | ||
"id": "1019653849998299136", | ||
"sku_id": "1019475255913222144", | ||
"application_id": "1019370614521200640", | ||
"user_id": "771129655544643584", | ||
"promotion_id": null, | ||
"type": 8, | ||
"deleted": false, | ||
"gift_code_flags": 0, | ||
"consumed": false, | ||
"starts_at": "2022-09-14T17:00:18.704163+00:00", | ||
"ends_at": "2022-10-14T17:00:18.704163+00:00", | ||
"guild_id": "1015034326372454400", | ||
"subscription_id": "1019653835926409216" | ||
} | ||
] | ||
``` | ||
|
||
## Consume an Entitlement % POST /applications/{application.id#DOCS_RESOURCES_APPLICATION/application-object}/entitlements/{entitlement.id#DOCS_MONETIZATION_ENTITLEMENTS/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). | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does that fires any events? such as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will check on this! |
||
|
||
Returns a `204 No Content` on success. | ||
|
||
## Create Test Entitlement % POST /applications/{application.id#DOCS_RESOURCES_APPLICATION/application-object}/entitlements | ||
|
||
Creates a test entitlement to a given SKU for a given guild or user. Discord will act as though that user or guild has entitlement to your premium offering. | ||
|
@@ -98,9 +112,9 @@ After creating a test entitlement, you'll need to reload your Discord client. Af | |
|
||
```json | ||
{ | ||
"sku_id": "999184799365857331", | ||
"owner_id": "847184799365857999", | ||
"owner_type": 1 | ||
"sku_id": "999184799365857331", | ||
"owner_id": "847184799365857999", | ||
"owner_type": 1 | ||
} | ||
``` | ||
|
||
|
@@ -122,18 +136,18 @@ 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" | ||
"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" | ||
} | ||
``` | ||
|
||
|
@@ -151,8 +165,8 @@ If a user's subscription is cancelled, you will _not_ receive an `ENTITLEMENT_DE | |
|
||
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 | ||
- Discord issues a refund for a subscription | ||
- Discord removes an entitlement from a user via internal tooling | ||
|
||
Entitlements are _not_ deleted when they expire. | ||
|
||
|
@@ -170,8 +184,8 @@ This response will create an ephemeral message shown to the user that ran the in | |
|
||
```js | ||
return res.send({ | ||
type: InteractionResponseType.PREMIUM_REQUIRED, // This has a value of 10 | ||
data: {}, | ||
type: InteractionResponseType.PREMIUM_REQUIRED, // This has a value of 10 | ||
data: {}, | ||
}); | ||
``` | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this link to https://discord.com/developers/docs/monetization/skus#customizing-your-skus ? |
||
- Implement the SKU into your app | ||
- Publish a SKU to your store view with the click of a button. | ||
Comment on lines
+5
to
+8
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are these sequential steps that need to be taken? should it be a numbered list instead of bulleted? |
||
|
||
## 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 on the `Monetization -> Manage SKUs` tab, you have a few options for managing your SKUs visibility and publishing to your users: | ||
colinloretz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
- **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. | ||
|
||
 | ||
|
||
### 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. | ||
 | ||
|
||
### 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. | ||
|
||
 |
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,96 @@ | ||||||||||||||
# One-Time Purchases | ||||||||||||||
|
||||||||||||||
One-time purchases enable you to charge your users for premium app 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). | ||||||||||||||
colinloretz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||
|
||||||||||||||
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. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
can keep this acronym in the SKU page but not helpful here idt |
||||||||||||||
|
||||||||||||||
## 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 | ||||||||||||||
Comment on lines
+22
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this just can be inline—this is taking up a lot of vertical space and i dont think it needs to be—just "you can configure the SKU's name, image, description, and price" or something |
||||||||||||||
|
||||||||||||||
 | ||||||||||||||
|
||||||||||||||
## 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. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if it's just published to the store, what does it mean for end users? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. will revisit some of this with more detail after its live 😎 |
||||||||||||||
|
||||||||||||||
 | ||||||||||||||
|
||||||||||||||
## 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 | ||||||||||||||
Comment on lines
+39
to
+41
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||
|
||||||||||||||
### 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. | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this just be "the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is |
||||||||||||||
|
||||||||||||||
#### 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. | ||||||||||||||
colinloretz marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||||||||||
### 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. |
Uh oh!
There was an error while loading. Please reload this page.