Overview
The Ecom Interface gives developers using Epic Online Services the ability to interact with the Epic Games Store. With this interface, you can manage products ranging from full games and downloadable content (DLC) to virtual goods and in-game currency. This includes making offers, completing purchase transactions, verifying ownership, and redeeming purchased items.
Tip: To help you better understand the Ecom Interface functionality, certain terms through this page are in bold. Definitions for these terms can be found in the Ecom Interface Glossary
Getting Started
To use the Ecom Interface, your product must have an Epic Account Services (EAS) application configured and must obtain user consent to access Basic Profile data. You can set up an EAS application on the Developer Portal or review the Epic Account Services documentation to learn more. Without EAS and user consent, you will be able to initialize the EOS SDK and the Ecom Interface, but all Ecom Interface function calls to the back-end service will fail.
To access the Ecom Interface, acquire an EOS_HEcom
handle through the Platform Interface function, EOS_Platform_GetEcomInterface
. All Ecom Interface functions require this handle as their first parameter. You must ensure that the EOS_HPlatform
handle is ticking in order for callbacks to trigger when requests are completed.
Review the Ownership Verification using Web API documentation for using Web APIs with the Ecom Interface.
Operating an In-Game Store
You can operate an in-game store by carrying out two functions: presenting catalog offers (sometimes called offers) from the store, and enabling the user to purchase these catalog offers. The SDK provides functionality to retrieve lists of offers from the store's catalog to display in-game. Offer data includes one or more catalog items (sometimes called audience) that the user will gain after purchasing the offer, as well as release details that you can use to present information about the offer to the user.
Once the user chooses to make a purchase, the checkout API pushes the data to the overlay, which displays the checkout flow for the user to finalize the purchase. When the purchase is completed, a callback is triggered to inform the game of the result of the transaction, providing a transaction handle so that the game can carry out fulfillment.
Purchase related functionality of the Ecom interface is disabled if the EOS_PF_DISABLE_OVERLAY
flag is set, or if the overlay is otherwise unavailable.
Catalog Offer Data
Catalog offers (type EOS_Ecom_CatalogOffer
) contain localized pricing information and descriptive text, based on the puser browsing the store. Price localization includes applying discounts and converting to the local currency. A localized price will include a currency code, such as USD (which represents US dollars), and is represented in the smallest possible unit of that currency. For example, an offer that costs 2.99 US dollars would correspond to the value 299.
Presenting the Store's Catalog
You can retrieve the list of catalog offers by calling the EOS_Ecom_QueryOffers
function. This function takes an EOS_Ecom_QueryOffersOptions
data structure and will call your delegate, of type EOS_Ecom_QueryOffersCallbackInfo
, upon completion. Initialize your EOS_Ecom_QueryOffersOptions
structure as follows:
Property | Value |
---|---|
ApiVersion | EOS_ECOM_QUERYOFFERS_API_LATEST |
LocalUserId | The EOS_EpicAccountId of the local user who is requesting the query |
OverrideCatalogNamespace | Optional product namespace (sandbox), if different than the one specified during SDK initialization |
If the ResultCode
in the EOS_Ecom_QueryOffersCallbackInfo
that the delegate receives indicates success, the offer data you requested is available in a temporary cache. Use EOS_Ecom_GetOfferCount
to determine the number of offers stored in the cache, and EOS_Ecom_CopyOfferByIndex
to get a copy of an individual offer (of type EOS_Ecom_CatalogOffer
) from it. Each catalog item within the offer contains data about images and release details associated with that Item, which you can pull out separately. When you no longer need your copy of an Offer, use EOS_Ecom_CatalogOffer_Release
to release it.
Displaying Individual Item Data
After retrieving an offer from the cache, you can call EOS_Ecom_GetOfferItemCount
to determine how many catalog items that offer contains, and then use EOS_Ecom_CopyOfferItemByIndex
to retrieve a copy of an individual EOS_Ecom_CatalogItem
. This structure contains additional localized text as well as the ID of the entitlement that it will provide upon purchase. To release the memory allocated to your copy of the data, call EOS_Ecom_CatalogItem_Release
.
To retrieve release details for a catalog item from the cache, first use EOS_Ecom_GetItemReleaseCount
to discover the number of data entries present. You can then use EOS_Ecom_CopyItemReleaseByIndex
to get an individual piece of data (of type EOS_Ecom_CatalogRelease
). Call EOS_Ecom_CatalogRelease_Release
to release this data when you no longer need it.
Buying from the Store
When a user buys something from the store, that user purchases a catalog offer. Once the purchase is complete, the user will own the catalog item(s) contained within the offer, each of which adds one or more entitlements to the buyer's user account.
There are three actions involved in buying from the store: making the purchase, verifying ownership, and (optionally) redeeming entitlements.
When a user decides to make a purchase, call EOS_Ecom_Checkout
with an EOS_Ecom_CheckoutOptions
structure. Initialize the structure as follows:
Property | Value |
---|---|
ApiVersion | EOS_ECOM_CHECKOUT_API_LATEST |
LocalUserId | The EOS_EpicAccountId of the local user who is making the purchase |
OverrideCatalogNamespace | Optional product namespace (sandbox), if different from the one specified during SDK initialization |
EntryCount | The number of EOS_EcomCheckoutEntry elements being supplied to this structure in the Entries parameter. |
Entries | An array of EOS_Ecom_CheckoutEntry elements, which contain the EOS_Ecom_CatalogOfferId data for each offer the user wishes to purchase, and the same ApiVersion as this structure |
This information is used to generate a purchase token. The overlay is displayed, enabling the user to review the purchase, select payment options, and confirm or cancel the transaction. When the overlay closes, whether by succeeding, failing, or being canceled by the user, your callback (of type EOS_Ecom_OnCheckoutCallback
) will run with an EOS_Ecom_CheckoutCallbackInfo
parameter detailing the transaction. Within the callback information, the TransactionId
will be non-null if the transaction succeeded, and null if it failed or was canceled.
If any additional calls to EOS_Ecom_Checkout
are made before the first returns via the callback, an EOS_AlreadyPending
error will be returned.
Accessing Completed Purchase Data
If you have a valid transaction ID following a successful user purchase, you can pass it to the EOS_Ecom_CopyTransactionById
function to receive an EOS_Ecom_HTransaction
. EOS_Ecom_Transaction_GetEntitlementsCount
returns the number of entitlements associated with the transaction, and EOS_Ecom_Transaction_CopyEntitlementByIndex
will retrieve an individual entitlement. Call EOS_Ecom_Entitlement_Release
to release this data when you no longer need it.
Entitlements associated with transaction IDs contain the same data as those obtained through the EOS_Ecom_QueryEntitlement
function, but are subject to a different caching policy. Because of this difference, entitlements that you acquire using a transaction ID following a purchase will remain in a transaction-specific cache until you explicitly call EOS_Ecom_Transaction_Release
.
Verifying Ownership
Verifying ownership within the game client is not recommended and may be bypassed by users using software cheats. If possible, verify ownership on a trusted server using the Ecom Web APIs.
Latest recommendations to assist with preventing piracy
To help prevent piracy, we recommend that developers implement ownership verification checks for their game and any DLC. Online ownership verification on a trusted server/API is strongly recommended, and is generally considered the only effective way to prevent piracy. Client side verification can be used to mitigate low complexity attacks such as redistribution of the unmodified game files.
For multiuser or online games:
-
Implement an ownership check on a trusted game server or back-end API using either the Ecom Interface or Web API
- These checks are commonly implemented during authentication or when entering a level/match.
-
Deny access if the user does not pass the ownership check. If implemented properly, users should not be able to circumvent these checks by altering the API responses or modifying the game client itself.
-
Monitor for accounts with abnormally high activity levels and apply bans if one account is shared with multiple end users.
- We recommend limiting the number of concurrent sessions per account to 1.
For all games:
While fully protecting against piracy using client side controls is not possible, there are several options for mitigating low effort attacks/sharing including:
-
Verify the digital signature and SHA1 checksums of your game executable and all executable code (.exe/.dll/.so/etc) before invoking the ownership verification APIs. This includes verifying the EOS SDK and any other 3rd party libraries. Deny access if tampering is detected.
-
Require online activation and return a cryptographically verifiable token which enables offline access only after the user passes online verification.
-
This token can be tied to specific hardware/user properties and expire after a predefined period.
-
You must protect the embedded public key in your game binary from modifications for this to be effective.
-
Deny activation if the account in question activates too frequently or activates across many different devices.
-
-
Utilize commercially available obfuscation/anti-tamper solutions to increase the complexity of reverse engineering and modifying your tamper checks.
-
Do not store DLC as part of the main game files. Distribute DLC content via the Epic Games Store or require an additional download which is gated by a server side ownership check.
The Ecom Interface provides two methods for ownership verification: direct verification and token-based verification. Direct verification integrates directly with the Epic Entitlement Service, while token-based verification provides a signed token that the user can verify, or can pass to a third-party service. The direct method is useful for trusted game servers or less secure checks on client systems for simple validation. The token-based method provides a token that includes information about the game client, user, and Entitlement as well as a signature that the game client or an external service can verify. If integrating with a third-party service that performs ownership verification, the token-based method is recommended because it avoids granting the outside service access to the user's data.
If you prefer to access ownership information for your titles and services via RESTful endpoints, see the Ecom Web APIs.
Direct Ownership Verification
The recommended approach to verify user purchases is from your own back-end service, as this is not susceptible to malicious behavior from users. Please refer to the Ecom Web API documentation for details.
To determine whether or not a user owns a specific catalog item, call EOS_Ecom_QueryOwnership
and pass in an EOS_Ecom_QueryOwnershipOptions
structure. This will retrieve ownership information from the server and pass it to the EOS_Ecom_OnQueryOwnershipCallback
callback function that you provide. The callback function will also receive a void pointer that you specify, which can contain any information your product requires to understand the context of the request. To begin, fill out the EOS_Ecom_QueryOwnershipOptions
structure with the following information:
Property | Value |
---|---|
ApiVersion | EOS_ECOM_QUERYOWNERSHIP_API_LATEST |
LocalUserId | The EOS_EpicAccountId of the local user whose ownership to query; needed for localization of Catalog Item description text and pricing information |
CatalogItemIds | List of catalog item IDs to check for ownership |
CatalogItemIdCount | Number of elements in CatalogItemIds |
CatalogNamespace | Optional product namespace (sandbox), if different than the one specified during SDK initialization |
Upon completion, the SDK will invoke your callback function with the data you requested (and your void pointer) stored in an EOS_Ecom_OnQueryOwnershipCallback
structure. This structure contains an array of EOS_Ecom_ItemOwnership
members, each of which describes one of the items you queried, and indicates whether the user owns it or not. Items that the server doesn't recognize will come back as not owned.
Token-Based Ownership Verification
The recommended approach to verify user purchases is from your own back-end service, as this is not susceptible to malicious behavior from users. Refer to the Ecom Web API documentation for details.
To check ownership and cache the results locally for a few minutes, use EOS_Ecom_QueryOwnershipToken
. This function takes an EOS_Ecom_QueryOwnershipTokenOptions
structure, initialized as follows:
Property | Value |
---|---|
ApiVersion | EOS_ECOM_QUERYOWNERSHIPTOKEN_API_LATEST |
LocalUserId | The EOS_EpicAccountId of the local user whose ownership you wish to query |
CatalogItemIds | An array of up to 32 (EOS_ECOM_QUERYOWNERSHIPTOKEN_MAX_CATALOGITEM_IDS ) catalog items to check for entitlement, of type EOS_Ecom_CatalogItemId |
CatalogItemIdCount | The number of catalog items in CatalogItemIds |
CatalogNamespace | Optional product namespace, if not the one specified during initialization |
When the operation completes, your callback function (of type EOS_Ecom_OnQueryOwnershipTokenCallback
) will receive an EOS_Ecom_QueryOwnershipTokenCallbackInfo
structure that includes a JSON Web Token (JWT) with a five-minute expiration time. You can verify the JWT with a public key, and unpack it to extract the Key ID. You may also send it along to a third-party service, which can then verify that the ownership information came from the Epic Games Store. The public key, retrieved by an additional web call or shared with your organization, will be in the form of a JSON Web Key (JWK) that can be used to verify the signature in the JWT. To make an HTTP request, send a GET to https://ecommerceintegration-public-service-ecomprod02.ol.epicgames.com/ecommerceintegration/api/public/publickeys/{kid}
. A sample request follows:
Ownership Verification Token Details
The Ownership Verification Token is a JWT signed using RS512 (RSA PKCS#1 signature with SHA-512, RSA key size 2048), which expires five minutes after it is created. The token contains the following claims:
Claim | Description |
---|---|
jti | A unique identifier for this token |
sub | The account ID for the account that was used to request the token |
clid | The client ID for the client that was used to request the token |
ent | An array of entitlements that were verified for this token; if this value is empty, the account is not entitled to any of the requested entitlements for a given sandboxId |
iat | A Unix timestamp representing the time the token was issued |
exp | A Unix timestamp representing the time the token will expire |
Fulfilling Purchases
After making a purchase, the user's account gains an entitlement, but the user may not see the effect of their purchase in the game yet. In some cases, fulfilling a purchase can be as simple as checking that the user owns a specific entitlement and applying some game logic to the result. In these cases, verifying ownership through the SDK is sufficient. In other cases, such as purchases involving consumable items or game currency, you may also need to fulfill the order in-game or with a third-party back-end service by redeeming the entitlement.
Enumerating and redeeming entitlements within the game client is not recommended and may be bypassed by users using software cheats. If possible, enumerate and redeem on a trusted server using the Ecom Web APIs.
Direct Entitlement Enumeration
The recommended approach to verify user purchases is from your own back-end service, as this is not susceptible to malicious behavior from users. Please refer to the Ecom Web API documentation for details.
To retrieve a user's account entitlements, call the EOS_Ecom_QueryEntitlements
function with an EOS_Ecom_QueryEntitlementsOptions
structure.
Note that the EOS_Ecom_QueryEntitlements
API should not be used to verify purchased durable content, as it does not take into account the relationship between associated catalog items, such as the individual DLC contained with a Season Pass. As such, EOS_Ecom_QueryEntitlements
is typically used for consumable offers, with durable content being managed as detailed in the Verifying Ownership section above.
EOS_Ecom_QueryEntitlementsOptions
is initialized as follows:
Property | Value |
---|---|
ApiVersion | EOS_ECOM_QUERYENTITLEMENTS_API_LATEST |
LocalUserId | The EOS_EpicAccountId of the local user whose entitlements you want to retrieve |
EntitlementNames | An array of entitlement names (typically equal to the catalog item ID) that you want to check |
EntitlementNameCount | The number of entitlement names included in the EntitlementNames property. Accepts up to a maximum of EOS_ECOM_QUERYENTITLEMENTS_MAX_ENTITLEMENT_IDS. If 0 is provided, will request all entitlements associated with the user account. |
bIncludeRedeemed | If true, entitlements that have been redeemed will be included in the results. |
When the operation completes, the SDK will cache the resulting information and run your callback function (of type EOS_Ecom_OnQueryEntitlementsCallback
) with an EOS_Ecom_QueryEntitlementsCallbackInfo
parameter. If the ResultCode
of this parameter is EOS_Success
, the cache contains the data you requested. You can call EOS_Ecom_GetEntitlementsCount
to determine the number of entitlements in the cache, and EOS_Ecom_CopyEntitlementByIndex
to retrieve a copy of an individual element (of type EOS_Ecom_Entitlement
), including the the Catalog Item ID that provided the entitlement, the unique ID for that entitlement, and other related data.
Token-Based Entitlement Enumeration
The recommended approach to verify user purchases is from your own back-end service, as this is not susceptible to malicious behavior from users. Please refer to the Ecom Web API documentation for details.
To enumerate entitlements and cache the results locally for a few minutes, use EOS_Ecom_QueryEntitlementToken
. This function takes an EOS_Ecom_QueryEntitlementTokenOptions
structure, initialized as follows:
Property | Value |
---|---|
ApiVersion | EOS_ECOM_QUERYENTITLEMENTTOKEN_API_LATEST |
LocalUserId | The EOS_EpicAccountId of the local user whose entitlements you want to retrieve |
EntitlementNames | An array of entitlement names (typically equal to the Catalog Item ID) that you want to check |
EntitlementNameCount | The number of entitlement names included in the EntitlementNames property. Accepts up to a maximum of EOS_ECOM_QUERYENTITLEMENTS_MAX_ENTITLEMENT_IDS. If 0 is provided, will request all entitlements associated with the user account. |
When the operation completes, your callback function (of type EOS_Ecom_OnQueryEntitlementTokenCallback
) will receive an EOS_Ecom_QueryEntitlementTokenCallbackInfo
structure that includes a JSON Web Token (JWT) with a five-minute expiration time. You can verify the JWT with a public key, and unpack it to extract the Key ID. You may also send it along to a third-party service, which can then verify that the entitlement information came from the Epic Games Store. The public key, retrieved by an additional web call or shared with your organization, will be in the form of a JSON Web Key (JWK) that can be used to verify the signature in the JWT. To make an HTTP request, send a GET to https://ecommerceintegration-public-service-ecomprod02.ol.epicgames.com/ecommerceintegration/api/public/publickeys/{kid}
. A sample request follows:
Entitlement Enumeration Token Details
The entitlement Enumeration Token is a JWT signed using RS512 (RSA PKCS#1 signature with SHA-512, RSA key size 2048), which expires five minutes after it is created. The token contains the following claims:
Claim | Description |
---|---|
jti | A unique identifier for this token |
sub | The account ID for the account that was used to request the token |
clid | The client ID for the client that was used to request the token |
ent | An array of entitlements that were verified for this token; if this value is empty, the account is not entitled to any of the requested entitlements |
iat | A Unix timestamp representing the time the token was issued |
exp | A Unix timestamp representing the time the token will expire |
Redeeming an entitlement
The recommended approach to verify user purchases is from your own back-end service, as this is not susceptible to malicious behavior from pusers. Please refer to the Ecom Web API documentation for details.
After fulfilling a consumable entitlement, or managing its fulfillment through a third-party service, call the EOS_Ecom_RedeemEntitlements
function with an EOS_Ecom_RedeemEntitlementsOptions
structure. Initialize the structure as follows:
Property | Value |
---|---|
ApiVersion | EOS_ECOM_REDEEMENTITLEMENTS_API_LATEST |
LocalUserId | The ID of the user account that is redeeming entitlements |
EntitlementIdCount | The number of elements in EntitlementIds |
EntitlementIds | The entitlements (of type EOS_Ecom_EntitlementId ) to redeem |
Upon completion, your callback of type EOS_Ecom_OnRedeemEntitlementsCallback
will receive an EOS_Ecom_RedeemEntitlementsCallbackInfo
structure.
After redeeming an entitlement, it will no longer show up in the results from EOS_Ecom_QueryEntitlements
calls, unless the EOS_Ecom_QueryEntitlementsOptions
parameter has its bIncludeRedeemed
set to true
. Note that the Entitlement is still stored in the cache after it is redeemed. There is no way to clear the cache.
Ecom Interface Glossary
This section contains terms and definitions commonly used within the Ecom Interface.
Term | Definition |
---|---|
Catalog Offers | A catalog offer (also referred to as offer) is a pairing of one or more catalog items and an associated price (which can be 0). When an offer is purchased, an entitlement is granted for each of the items contained in the offer. |
Catalog Item | A catalog item (also referred to as audience) can represent an entire game, virtual goods like in-game currency or weapon skins, or other types of downloadable content. An item is used to define how entitlements are granted to accounts. Catalog items can be configured to grant other catalog items through the Epic Games Store's dynamic bundling feature, which allows you to update associated offers over time. For example, through this feature, you can allow season pass owners to seamlessly gain ownership rights for new DLC as it is released. |
Entitlement | An entitlement is anything a user owns within the Epic Games Store infrastructure. An entitlement can grant access to one or more catalog items. |
Consumable Entitlement | Consumable entitlements have limited persistence, decreasing a use count each time the Item is used in game. This is commonly used for things like in-game currency, XP boosts, and other Items that can be used up and replenished with additional purchases. In some cases, an external service fulfills the entitlement. Once that external service has received the information about the entitlement, it is redeemed and its use count is decremented to 0, effectively removing it from the user account. The external service accepts responsibility for handling the in-game effects of the Item past that point. |
Durable Entitlement | Entitlements for purchases that persist, like certain forms of downloadable content, or even entire games. |
Fulfillment | Once a consumable entitlement is part of a user account, the entitlement still needs to be fulfilled. It can be implicit (checked by SDK APIs), or a third-party service can accept responsibility for the fulfillment through back-end service API calls. |
The following table contains the different ID types used within the Ecom Interface and information about where each comes from and what they each describe.
ID Type | Description |
---|---|
Catalog Offer ID | A Catalog Offer ID is the unique identifier for an offer in the store. These IDs are unique within a Product. The checkout process requires a Catalog Offer ID. |
Catalog Item ID | Catalog item IDs are unique within a Product and identify a single catalog Item. You need this ID in order to check whether or not a specific user owns the corresponding catalog item. |
Entitlement Name | Each catalog item can have an entitlement name associated with it. These entitlement names can be used for grouping. However, the entitlement name is usually the same value as the Catalog Item ID. The Ecom Interface allows querying for entitlements based on the entitlement name associated with the catalog item in the catalog offer that granted it. |
Entitlement ID | Fulfilled catalog offers and their catalog items manifest on the user account as a particular entitlement stored with that user. Each entitlement will have its own unique identifier. This ID is used by the ECom Interface when redeeming entitlements. |