Ecom Interface Overview

Implement interface for handling purchases and verification of ownership

Epic Games Store
19 mins to read

The Ecom Interface gives developers using Epic Online Services (EOS) the ability to support in-game purchases through the Epic Games Store (EGS). 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.

See the Ecom Web APIs documentation for using Web APIs with the Ecom Interface.

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.

To use the Ecom Interface, your product must have Epic Account Services (EAS) active, and must obtain player/user consent to access Basic Profile data. You can activate EAS on the Developer Portal, or learn more in Epic's documentation. Without EAS and player consent, you will still be able to initialize the EOS SDK and the Ecom Interface, but all Ecom Interface function calls to the back-end service will fail.

Operating an In-Game Store

An in-game store under EOS operates by carrying out two functions: presenting Catalog Offers (sometimes called "Offers") from the store to the player for purchase, and enabling the player to make purchases. The EOS SDK provides functionality to retrieve lists of offers from the store's catalog for display in whatever way the game developer desires. Offer data includes one or more items that the player will gain, as well as key images and release details that you can use to present information about the offer to the player.

Once the player chooses to make a purchase, the checkout process pushes the data to the EGS Overlay, which finalizes the purchasing process. EOS will then notify the game of the result of the transaction, providing a transaction handle so that the game can carry out fulfillment in the event that the purchase was completed successfully.

Purchase related functionality of the Ecom interface is disabled if the EOS_PF_DISABLE_OVERLAY flag is set.

Catalog Offer Data

Catalog Offers (type EOS_Ecom_CatalogOffer) contain localized pricing information and descriptive text, based on the player 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" (to represent 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 defined in the Developer Portal 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:

PropertyValue
ApiVersionEOS_ECOM_QUERYOFFERS_API_LATEST
LocalUserIdThe EOS_EpicAccountId of the local player who is requesting the query
OverrideCatalogNamespaceOptional product namespace, if not the one specified during 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 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 Items that Offer includes, 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.

Images associated with Items are also available in the cache; you can call EOS_Ecom_GetItemImageInfoCount to determine how many images are associated with a given Item, and then use EOS_Ecom_CopyItemImageInfoByIndex to obtain an EOS_Ecom_KeyImageInfo for the image's URL, dimensions, and intended usage. When you no longer need your copy of this data, use EOS_Ecom_KeyImageInfo_Release to free the memory it used.

To retrieve release details for an 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 player buys something from the store, that player is accepting a Catalog Offer. Once the purchase is complete, the player will own the Item (or Items) contained within the Offer, each of which adds one or more Entitlements to the buyer's player account.

There are three actions involved in buying from the store: Making the purchase, verifying ownership, and (optionally) redeeming Entitlements.

When a player decides to make a purchase, call EOS_Ecom_Checkout with an EOS_Ecom_CheckoutOptions structure. Initialize the structure as follows:

PropertyValue
ApiVersionEOS_ECOM_CHECKOUT_API_LATEST
LocalUserIdThe EOS_EpicAccountId of the local player who is making the purchase
OverrideCatalogNamespaceIf not provided, the current SandboxId will be supplied as the catalog namespace.
EntryCountThe number of EOS_EcomCheckoutEntry elements being supplied to this structure in the Entries parameter.
EntriesAn array of EOS_Ecom_CheckoutEntry elements, which contain the EOS_Ecom_CatalogOfferId data for each Offer the player wishes to purchase, and the same ApiVersion as this structure

After making this call, EOS will use this information to generate a purchase token. EOS will then use this purchase token to open its own overlay, enabling the player 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 player, 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 then it will give an EOS_AlreadyPending error.

Accessing Completed Purchase Data

If you have a valid transaction ID following a successful player 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 players 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 multiplayer 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 player does not pass the ownership check. If implemented properly, players 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 player

    • 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 player passes online verification

    • This token can be tied to specific hardware/player 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 player 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, player, 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 player'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 player purchases is from your own back-end service, as this is not susceptible to malicious behavior from players. Please refer to the Ecom Web API documentation for details.

To determine whether or not a player 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:

PropertyValue
ApiVersionEOS_ECOM_QUERYOWNERSHIP_API_LATEST
LocalUserIdThe EOS_EpicAccountId of the local player whose ownership to query; needed for localization of Catalog Item (Item) description text and pricing information
CatalogItemIdsList of Catalog Item IDs to check for ownership
CatalogItemIdCountNumber of elements in CatalogItemIds
CatalogNamespaceOptional product namespace, if not the one specified during initialization

Upon completion, EOS 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 player 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 player purchases is from your own back-end service, as this is not susceptible to malicious behavior from players. Please 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:

PropertyValue
ApiVersionEOS_ECOM_QUERYOWNERSHIPTOKEN_API_LATEST
LocalUserIdThe EOS_EpicAccountId of the local player whose ownership you wish to query
CatalogItemIdsAn array of up to 32 (EOS_ECOM_QUERYOWNERSHIPTOKEN_MAX_CATALOGITEM_IDS) Catalog Items to check for Entitlement, of type EOS_Ecom_CatalogItemId
CatalogItemIdCountThe number of Catalog Items in CatalogItemIds
CatalogNamespaceOptional 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:

GET
/ecommerceintegration/api/public/publickeys/pbvnNIE97vErdePGIRoG41h8hnP_2wIxG8xbwZCIj3g HTTP/1.1
Host: ecommerceintegration-public-service-ecomprod02.ol.epicgames.com
{
"kty": "RSA",
"e": "AQAB",
"kid": "pbvnNIE97vErdePGIRoG41h8hnP_2wIxG8xbwZCIj3g",
"n": "gcStqtD8XD9c9ifNuxXT9Xd_EEZLLCw34yxINRQPt0MxEWkoOFsuisRWGktSFtGrnUuQnp8GQY0k4Pyl_yDItWAcRtO7JUjrhQnxx3xXp_0P8xJMH1ny-RcxHF3bEJWhDzNW5PBpBjQTQZis-83499z-4OlNA7oUnDKEJkqNfzh4mMDFluPxvW_Hwpaw71nhzJI7-N-BdsPsLdqUANajLsFKq9fr06Lek_tm-6-RUxNPE3yS0x0UIsGyapA4Apcczz0xTzRDfwOkq_TyKGZiZc7vtgjkWnqdsCyXZC7dzKJvg0ggO3mKXhqZNNC_2pz24o1X_xCbG8rXtuvX8-ux-Q"
}

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:

ClaimDescription
jtiA unique identifier for this token
subThe account ID for the account that was used to request the token
clidThe client ID for the client that was used to request the token
entAn 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
iatA Unix timestamp representing the time the token was issued
expA Unix timestamp representing the time the token will expire

Fulfilling Purchases

After making a purchase, the player's account gains an Entitlement, but the player 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 player owns a specific Entitlement and applying some game logic to the result. In these cases, verifying ownership through the EOS 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 players 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 player purchases is from your own back-end service, as this is not susceptible to malicious behavior from players. Please refer to the Ecom Web API documentation for details.

To retrieve a player'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:

PropertyValue
ApiVersionEOS_ECOM_QUERYENTITLEMENTS_API_LATEST
LocalUserIdThe EOS_EpicAccountId of the local player whose Entitlements you want to retrieve
EntitlementNamesAn array of Entitlement Names (typically equal to the Catalog Item ID) that you want to check.
EntitlementNameCountThe 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 player account.
bIncludeRedeemedIf true, Entitlements that have been redeemed will be included in the results.

When the operation completes, EOS 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 player purchases is from your own back-end service, as this is not susceptible to malicious behavior from players. 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:

PropertyValue
ApiVersionEOS_ECOM_QUERYENTITLEMENTTOKEN_API_LATEST
LocalUserIdThe EOS_EpicAccountId of the local player whose Entitlements you want to retrieve
EntitlementNamesAn array of Entitlement Names (typically equal to the Catalog Item ID) that you want to check
EntitlementNameCountThe 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 player 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:

GET
/ecommerceintegration/api/public/publickeys/pbvnNIE97vErdePGIRoG41h8hnP_2wIxG8xbwZCIj3g HTTP/1.1
Host: ecommerceintegration-public-service-ecomprod02.ol.epicgames.com
{
"kty": "RSA",
"e": "AQAB",
"kid": "pbvnNIE97vErdePGIRoG41h8hnP_2wIxG8xbwZCIj3g",
"n": "gcStqtD8XD9c9ifNuxXT9Xd_EEZLLCw34yxINRQPt0MxEWkoOFsuisRWGktSFtGrnUuQnp8GQY0k4Pyl_yDItWAcRtO7JUjrhQnxx3xXp_0P8xJMH1ny-RcxHF3bEJWhDzNW5PBpBjQTQZis-83499z-4OlNA7oUnDKEJkqNfzh4mMDFluPxvW_Hwpaw71nhzJI7-N-BdsPsLdqUANajLsFKq9fr06Lek_tm-6-RUxNPE3yS0x0UIsGyapA4Apcczz0xTzRDfwOkq_TyKGZiZc7vtgjkWnqdsCyXZC7dzKJvg0ggO3mKXhqZNNC_2pz24o1X_xCbG8rXtuvX8-ux-Q"
}

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:

ClaimDescription
jtiA unique identifier for this token
subThe account ID for the account that was used to request the token
clidThe client ID for the client that was used to request the token
entAn 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
iatA Unix timestamp representing the time the token was issued
expA Unix timestamp representing the time the token will expire

Redeeming an Entitlement

The recommended approach to verify player purchases is from your own back-end service, as this is not susceptible to malicious behavior from players. 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:

PropertyValue
ApiVersionEOS_ECOM_REDEEMENTITLEMENTS_API_LATEST
LocalUserIdThe ID of the player account that is redeeming Entitlements
EntitlementIdCountThe number of elements in EntitlementIds
EntitlementIdsThe 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.

TermDefinition
Catalog OffersA 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 ItemA 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.
EntitlementAn entitlement is anything a player owns within the Epic Games Store infrastructure. An entitlement can grant access to one or more catalog items.
Consumable EntitlementConsumable 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 player account. The external service accepts responsibility for handling the in-game effects of the Item past that point.
Durable EntitlementEntitlements for purchases that persist, like certain forms of downloadable content, or even entire games.
FulfillmentOnce a consumable entitlement is part of a player 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 TypeDescription
Catalog Offer IDA 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 IDCatalog 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 player owns the corresponding Catalog Item.
Entitlement NameEach 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 IDFulfilled Catalog Offers and their Catalog Items manifest on the player account as a particular Entitlement stored with that player. Each Entitlement will have its own unique identifier. This ID is used by the ECom Interface when redeeming Entitlements.