Implement Orders and Fulfillment #

This guide covers setting up the Orders and Fulfillment services to grant players their items.

  1. Set up a third-party provider.
  2. Set up your social backend partner config.
  3. Configure an Order Provider Plugin.
  4. Configure an OrderMappingSpecs.json content file.
    • This maps each order provider’s item to a Pragma SKU ID.
  5. Define Player Data operations to call on fulfillment.
  6. Configure a FulfillmentMappingSpecs.json content file.
    • This associates a Pragma SKU ID with Player Data operations to fulfill or revoke.

1. Set up a third party provider #

Before integrating with Pragma Engine, you’ll need to set up an account with a third party provider. For more information on each third-party provider’s system, refer to their respective documentation:

See Epic Games Store’s Ecom Interface Overview documentation.
See Twitch’s Drops Guide documentation for details on how to grant in-game rewards to Twitch stream viewers.
Contact your customer support representative for more information.
Contact your customer support representative for more information.
The Orders service allows for integration with multiple third party providers.

2. Ensure your social backend partner is configured #

To enable your Pragma game shard to communicate with your Pragma social shard, we’ll need to set up the backend communication channel. To set up this configuration, add a SocialBackendPartnerClientConfig with a bearerToken that has the encrypted Social Partner token.

game:
  serviceConfigs:
    SocialBackendPartnerClientConfig:
      bearerToken: <encrypted social partner token>
Check out the Generate Partner tokens guide if you need help generating Partner tokens.

3. Configure an Order Provider Plugin #

Under the social config, add your Order Provider Plugin.

social: 
  pluginConfigs:
    ThirdPartyNodeService.orderProviderPlugins:
      plugins:
        Steam:
          class: "pragma.order.SteamOrderProviderPlugin"
          config:
            appId: "{steamAppId}"
            steamWebAPIKey: "{steamWebApiKey}"
Example: social config with all providers
social:
  pluginConfigs:
    ThirdPartyNodeService.orderProviderPlugins:
      plugins:
        Steam:
          class: "pragma.order.SteamOrderProviderPlugin"
          config:
            appId: "{steamAppId}"
            steamWebAPIKey: "{steamWebApiKey}"
        Twitch:
          class: "pragma.order.TwitchOrderProviderPlugin"
          config:
            clientId: "{twitchClientId}"
            clientSecret: "{twitchClientSecret}"
            gameId: "{twitchGameId}"
        Epic:
          class: "pragma.order.EpicOrderProviderPlugin"
          config:
            clientId: "{epicClientId}"
            clientSecret: "{epicClientSecret}"
            sandboxId: "{epicSandboxId}" 
            deploymentId: "{epicDeploymentId}"
            clawbackPollingEnabled: true # enables refund processing
You can implement your own custom Order Provider Plugin. See the Create a Custom Order Provider Plugin guide for details.

4. Configure an Order Mappings Specs content file #

Below is an example OrderMappingsSpecs.json with Steam, Epic, and Twitch sources defined for the one item:

[
    {
        "skuId": "SmallGoldBundle",
        "sources": [
            {
                "provider": "STEAM",
                "steamSource": {
                    "inventory": {
                        "itemDefId": "475"    
                    }
                }
            },
            {
                "provider" : "EPIC",
                "epicSource" : {
                    "entitlement" : {
                      "audienceItemId" : "231f97b3e1a44fb7b496e1832ec6b3d6"
                    }
                }
            },
            { 
                "provider": "TWITCH",
                "twitchSource": {
                    "rewardId": "twitch_item_drop"
                }
            }
        ]
    }
]
SKU ID must be unique for each order entry.

See the src/main/proto/pragma/order/orderContent.proto file for more information about what data is required for each provider.

5. Define Player Data operations to call on fulfillment #

The fulFillmentOperation defined in the JSON file needs to be configured to specify which Player Data operation should be called to fulfill an order. Define operations under [project]/[project]-player-data/player-data/src/main/kotlin/[studio]/...

The example below shows how to implement a grantCoins operation.

Please note that this example is not intended for production and only includes the basic implementation for granting coins. You may want to add additional logic, such as custom errors and transaction tracking.

FulfillmentOperations.kt

@SerializedName("<USE-CURRENT-EPOCH-SECONDS>")
data class Currency(
    @FieldNumber(1) val id: String,
    @FieldNumber(2) var balance: Int,
): Component

data class GrantCoins(
    val id: String,
    val amount: Int
): PlayerDataRequest
class GrantCoinsResponse: PlayerDataResponse

class FulfillmentOperations(
    contentLibrary: PlayerDataContentLibrary
) : PlayerDataSubService(contentLibrary) {

    // Requirement: you must allow the SERVICE SessionType
    // this provides access for the Fulfillment Service to call the operation
    @PlayerDataOperation(sessionTypes = [SessionType.SERVICE])
    fun grantCoins(
        request: GrantCoins,
        context: Context
    ): GrantCoinsResponse {

        // You can access the AccountRpc.IdProvider Enum name with
        // this would be helpful if you wanted to add tracking of each currency update
        // called through processing a fulfillment
        val platformId = context.getDataBy("platformId")

        val entity = context.snapshot.getOrCreateUniqueEntity("Currencies")
        var coinsComponent = entity
            .getComponentsByType<Currency>()
            .singleOrNull { it.id == request.id }
        if (coinsComponent == null) {
            val id = entity.addComponent(Currency(request.id, 0))
            coinsComponent = entity.getComponentById(id)
        }
        coinsComponent!!.balance += request.amount
        return GrantCoinsResponse()
    }
}

Build the project to run player data code generation and run tests.

./pragma build

See the Player Data Overview page for more information.

6. Configure a Fulfillment Mapping Specs content file #

Below is an example FulfillmentMappingSpecs.json:

[
  {
    "skuId": "SmallGoldBundle",
    "operations": {
      "fulfillmentOperation": {
        "grantCoins": { // custom Player Data operation
          "id": "gold",
          "amount": "60"
        }
      }
    }
  },
  {
    "skuId": "SmallOrbBundle",
    "operations": {
      "fulfillmentOperation": {
        "updateCurrency": { // custom Player Data operation
          "id": "elemental_orbs",
          "amount": "60"
        }
      },
      "revocationOperation": {
        "updateCurrency": {
          "id": "elemental_orbs",
          "amount": "-60"
        }
      }
    }
  }
]

Chargebacks & Refunds #

Pragma handles any incoming chargeback and refund requests using the revocationOperation you defined.

View fulfillment history in Game Operator Portal #

To view a player’s fulfillment history:

  1. From the Accounts page, click on the relevant player name to view individual account information.
  2. See the Orders tab for details.
    • The four possible order statuses include: FULFILLED, FULFILLMENT_FAILED, REVOKED, and REVOKED_FAILED.