Managing Offers

After establishing your storefront, you'll want to add offers for sale and group those offers to help players navigate your storefront. You can either do this via the dashboard using a set of CSV templates, or manually via the Inventory Management API.

Here, we'll focus on using the APIs.

Prerequisites

Before reading this doc, you can familiarize yourself with how we handle images, how we manage translations, and how we internationalize prices:

You'll also need an API key for the environment you want to modify. API changes are made immediately, so make sure to test any critical changes in your sandbox environment before modifying production.

API Objects

First, let's discuss the key models that make up the storefront.

Offers are purchasable goods, like a Shield or a package of 500 gold. When a user makes a purchase, they're buying an Offer, and that Offer's unique SKU is what's used to fulfill the purchase on your servers after the purchase is complete.

Offers consist of Items, which are the basic unit of any purchase, like gold or gems. Every Offer consists of one or more Items in various quantities; for example, a package of 500 gold would consist of 500 units of the "gold" Item. (A Shield Offer would consist of 1 unit of the "shield" Item.) Items are only used for display purposes; by defining the concept of "gold" with a singular and plural translation, you can easily generate offers like "500 gold" or "1,000 gold" on the fly. There is no limit to the number of items that an offer can have.

Finally, Offers are organized into Offer Groups, like featured items or limited-time purchases. Every Offer can be associated with one or more Offer Groups.

Creating your first offers

In this walkthrough, we're going to build your storefront from scratch. In the next section, we'll discuss how to manage your store once it's up and running.

Prerequisites

Before you begin, make sure to have the API key for the environment you want to modify. Changes made with your production API key will impact your live, user-facing store, so it's strongly recommended that you set your sandbox environment up first.

Next, you'll need to upload any item or offer images you want to use to our servers via the Assets API. Keep the filenames you used on hand (or use the GET endpoint to list them), as you'll refer to these file names when setting up your inventory.

Finally, if you plan to use a custom pricing sheet, make sure to have the tier codes you want to use for your offers available. For more about pricing sheets, see here.

Items

First, we need to create Item objects. Item objects are used to build offers, and should generally consist of single units of purchasable goods. You can create these objects by calling the POST /storefront/items API:

curl --request POST \
     --url https://api.neonpay.com/storefront/items \
     --header 'X-API-KEY: <your API key>'
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
[
  {
    "code": "<code>",
    "imageFileName": "<image file name>",
    "text": {
      "<locale">: {
        "nameSingular": "<singular name, e.g. "gem">",
        "namePlural": "<plural name, e.g. "gems">",
        "description": "<description>"
      }
    }
  }
]
'

Remember to replace <your API key> with the correct API key for your environment.

code is a unique string that you'll use to refer to the Item object via the API, for example to add the item to an offer.

imageFileName is the file name for an image associated with this item without a specific quantity attached. It must be the same as the file name you used when uploading the image file via the assets API, and must correspond to a file that is not marked for deletion.

Item images and descriptions are only shown in the storefront if an item is part of an offer that contains other items, like a bundle with a mix of gold and gems.

Please note: POST /storefront/items and POST /storefront/offers are both create endpoints, so if you pass any items or offers that already exist, you will receive a 400. If you don't want to create offers or items, you can update an item by code or update an offer by SKU.

Offer groups

Next, we'll create the Offer Group objects that your offers will live in. (If you don't plan to organize your offers into groups, you can skip this section.)

You can create Offer Groups by calling the POST /storefront/offer-groups API:

curl --request POST \
     --url https://api.neonpay.com/storefront/offer-groups \
     --header 'X-API-KEY: <<your API key>>'
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
[
  {
    "code": "<code>",
    "priority": <priority>,
    "text": {
      "<locale>": {
        "label": "<label>",
        "description": "<description>"
      }
    }
  }
]
'

Remember to replace <your API key> with the correct API key for your environment.

code is a unique code you'll use to refer to each Offer Group object via the API, for example to add an offer to an offer group.

priority is an integer used to sort offer groups on the page. The lower the number, the earlier on the page the offer group will appear. Ties are broken arbitrarily, so make sure to use different priorities for each offer group.

All of the fields in text are optional. An Offer Group object without a label or description will have spacing, but no text, between it and its neighbors.

Offers

Finally, we'll create the actual offers by calling the POST /storefront/offers API:

curl --request POST \
     --url https://api.neonpay.com/storefront/offers \
     --header 'X-API-KEY: <your API key>' \
     --header 'accept: application/json' \
     --header 'content-type: application/json' \
     --data '
[
  {
    "sku": "<sku>",
    "priceTierCode": "<price tier code>",
    "imageFileName": "<image file name>",
    "items": [
      {
        "code": "<item code>",
        "quantity": <quantity>,
        "text": {
          "<locale>": {
            "subtitle": "<subtitle>",
            "highlightedSubtitle": "<highlighted subtitle>"
          }
        }
      }
    ],
    "groups": [
      {
        "code": "<code>",
        "style": "<default | featured>",
        "order": 0
      }
    ],
    "text": {
      "<locale>": {
        "name": "<name>",
        "description": "<description>",
        "bannerText": "<banner text>",
        "subtitle": "<subtitle>",
        "highlightedSubtitle": "<highlighted subtitle>"
      }
    },
    "isTargetedOffer": false,
    "shouldPreviewTargetedOffer": false,
    "timeLimits": {
      "previewDate": "2023-01-01T20:00:00.000Z",
      "startDate": "2023-02-01T20:00:00.000Z",
      "endDate": "2023-12-31T20:00:00.000Z"
    }
  }
]
'

Remember to replace <your API key> with the correct API key for your environment.

sku is a unique code that corresponds to a SKU in your inventory management system. You must be able to map this value to the object in the game, so that you can credit the user's account when they make a purchase. See here for more information on how Neon fulfills offers using this SKU.

priceTierCode is the tier code in your pricing sheet corresponding to this offer. See Pricing for more details.

imageFileName is the file name of an image of this offer. It must be the same as the file name you used when uploading the image file via the assets API, and must correspond to a file that is not marked for deletion.

Offer items

items defines the set of Items included in this offer. At minimum, an offer must contain at least one item.

code is the item code you defined when creating the Item object.

quantity is the amount of this item included in this offer.

For offers that contain more than one type of item, you can also define item-specific subtitle and highlighted subtitle values displayed alongside the item-specific text. For example, in this bundle, 1 Hilt is the subtitle value for the moon_mace object, and +2 Extra Blades is the highlightedSubtitle value. The name (Moon Mace of Healing) and description (Harness the power of the earth) are defined on the Item object.

Offer groups

groups controls which offer groups this offer is a part of.

  • code is the offer group code you defined when creating the Offer Group object.
  • style determines how the offer is displayed within the offer group:
    • default is the standard offer presentation, and takes up one unit within the row.
    • promoted takes up two units in the row, and is full-size on smaller viewports.
  • order defines the relative position of this offer within its offer group; the lower the order, the earlier the offer shows up in the group. Ties are broken arbitrarily, so use unique values when defining order.

Offer text

The text field defines a few different strings used to display the offer:

  • name (50 Gold Coins) is the name of the offer, displayed prominently in the storefront and throughout the checkout process .
  • description (Get a golden stash of 50 coins...) is a short explanation of the offer's in-game benefits, only displayed in the item detail view .
  • bannerText (Great Value) can be used to show a value prop for this offer, and is highlighted prominently throughout the storefront.
  • subtitle (40) and highlightedSubtitle (+10 Extra) are short pieces of data explaining the relative value of this item, especially any bonus offers exclusive to the Neon store.

Targeted offers

isTargetedOffer controls whether this offer is a targeted offer, i.e., whether it should only be displayed to logged-in users who are eligible for the item.

By default, targeted offers are only shown to logged-in, eligible users. However, you can set shouldPreviewTargetedOffer to true to show the offer to ineligible or logged-out users, who will see it as a locked item and be unable to purchase it until they log in with an eligible account.

Time-limited offers

timeLimits can be used to schedule offers for display in the future:

  • After previewDate, the offer is visible in the store, but in a locked state and unavailable for purchase.
  • After startDate, the offer is visible in the store and available for purchase.
  • After endDate, the offer is removed from the store, and can no longer be purchased.

Managing your inventory

Now that you've set up your offers, you can visit your storefront and make sure everything looks correct. If you need to make any changes, you can use the dashboard to update your inventory. You can also use the API to manually update individual objects.

Each update endpoint performs a full replacement, so you'll need to include everything you used to create the objects in addition to the updates you want to perform. However, the GET endpoint returns data in the same format as the expected input to the PATCH endpoint. Thus, you can make a GET call for a particular resource, use the response as the request body for a PATCH call, make the desired changes in the request body, and then execute the call.


What’s Next