Baker Server API

ajurcevic edited this page Apr 16, 2016 · 22 revisions

Certain features will only be available when supporting Baker with an external server. You will need a server to:

  • Host the shelf JSON file
  • Support auto-renewable subscriptions
  • Track In-App Purchases

While the shelf JSON can be a static file that you periodically update by hand, to support subscriptions and track purchases your server will need to implement some more logic.

Note that you will need to implement the server-side code yourself (or find an existing solution). This page lists the API calls that Baker will use to push and pull information from your server. This means that the server will have to offer the API, while Baker will use it.

You can find a sample PHP implementation of a server in the Baker Server Example repo.

Parameters

All API calls from Baker contain at least 3 parameters: app_id, user_id and environment (since 5fb6d2a).

app_id

The app_id is a unique identifier for your app (in case the server needs to manage more than one). By default, it is the same as the application's Bundle ID (e.g. com.example.MyBook).

user_id

A random value automatically generated by Baker, user_id will allow you to track a specific user. Note that, if a user removes and reinstalls the app, a new ID will be generated. This ensures that a user will be able to "log out" from a given ID.

environment

(since 5fb6d2a)

The environment is a value that could be used by the endpoint to return different content for production and debugging/testing apps. The parameter will be set as follows:

  • debug when the DEBUG preprocessor directive is set to 1
  • production otherwise

API endpoints

Baker will make calls to the following endpoints to manage issues and purchases. Baker will make no assumptions as to the URLs for the various endpoints: you'll have to specify them in the Constants.h file, based on your server implementation.

Shelf JSON

This endpoint MUST be implemented to support Baker in Newsstand mode (see 4.0-tutorial-for-Newsstand for more info).

Baker will call this API endpoint to retrieve the Newsstand shelf JSON. The shelf JSON is a list of all the issues Baker will display in the shelf for your app.

When calling this endpoint, Baker will send a GET request to the URL specified in the NEWSSTAND_MANIFEST_URL constant.

GET <NEWSSTAND_MANIFEST_URL>

Request parameters

  • app_id
  • user_id
  • environment (since 5fb6d2a)

Response body example

See Newsstand shelf JSON.

Purchase confirmation

This endpoint MUST be implemented if you're using In-App Purchases and Auto-renewable Subscriptions.

After each In-App Purchase, Baker will call this API endpoint to send the transaction receipt back to the server. Specifically, this endpoint will be called when:

  • a single issue has been purchased
  • a subscription (either free or auto-renewable) has been purchased
  • a user restores her purchases

Implementations should make sure the operation is idempotent, as it is quite usual to receive the same receipt more than once (e.g. when an existing purchase is restored).

When calling this endpoint, Baker will send a POST request to the URL specified in the PURCHASE_CONFIRMATION_URL constant. The request will include the transaction receipt for the purchase encoded in base64. It will also include the purchase type. No data is needed in the response from the server.

POST <PURCHASE_CONFIRMATION_URL>

Request parameters

  • app_id
  • user_id
  • environment (since 5fb6d2a)
  • receipt_data: the App Store receipt, encoded in base64
  • type: the purchase type, either issue, free-subscription or auto-renewable-subscription

Response body example

This call does not require any response.

Purchased issues and subscriptions

This endpoint MUST be implemented if you're using In-App Purchases and Auto-renewable Subscriptions.

Baker will call this API endpoint to get a list of purchased issues and whether the user has an active subscription or not. Baker will unlock for download all purchased issues.

When calling this endpoint, Baker will send a GET request to the URL specified in the PURCHASES_URL constant. The response should be a JSON hash containing:

  • a list of product IDs for all purchased issues
  • the current subscription status (true = subscribed, false = not subscribed)
GET <PURCHASES_URL>

Request parameters

  • app_id
  • user_id
  • environment (since 5fb6d2a)

Response body example

{
  "issues": ["com.example.MyBook.jan2013", "com.example.MyBook.feb2013", "com.example.MyBook.mar2013"],
  "subscribed": false
}

This is mainly used for auto-renewable subscriptions. Although a user subscribes through Baker, the application has no way of knowing what the subscription status is for a given user at a given time: the subscription might have been automatically renewed, or the user might have chosen to turn it off, or the duration might have been extended by a Marketing Opt-In Incentive.

Baker calls the server to get a list of the purchased issues and determines which issues to unlock based on the response. Unlocked issues will be displayed as "purchased" and it will be possible for the user to download them. All the remaining issues will show their price and the user will have to buy them before she can download them.

Note that the response should take into account both single purchases and subscriptions, either currently valid or active in the past. This means that all issues that were published while a subscription was active should be considered as "purchased". Users tend to expect to be able to download content that was available to them as part of a subscription, even if they're not subscribed anymore.

APNS device token

This endpoint MUST be implemented if you're using Push Notifications.

When the user decides to enable push notifications, an APNS device token will be generated by Apple. The token is needed to send push notifications to the connected device (see Apple's documentation on the Apple Push Notification Service). After the token has been generated, Baker will call this API endpoint to send the APNS device token to the server.

When calling this endpoint, Baker will send a POST request to the URL specified in the POST_APNS_TOKEN_URL constant. The request will include the APNS device token. No data is needed in the response from the server.

POST <POST_APNS_TOKEN_URL>

Request parameters

  • app_id
  • user_id
  • environment (since 5fb6d2a)
  • apns_token: the APNS device token

Response body example

This call does not require any response.

Advanced usage

Baker supports placeholders in the URL constants, to allow for a more RESTful API. Note that this section is totally optional and it won't add any functionality to the API.

The supported placeholders are :app_id and :user_id. When Baker calls an API endpoint, the placeholders will automatically be replaced with the relevant values.

For example, the following PURCHASES_URL definition

#define PURCHASES_URL @"http://example.com/:app_id/:user_id/purchases"

would result in a call to a URL similar to

http://example.com/com.example.Baker/0ADC7F77-3B9F-49A4-8D9E-6300CC7EE51A/purchases
                   \___ :app_id ___/ \____________ :user_id ____________/

Note that, when either app_id or user_id are not part of the URL, they will still be passed in as parameters to the call (in the query string for a GET call and in the body for a POST call).

RESTful API example

This is an example of how a RESTful API might look like:

#define NEWSSTAND_MANIFEST_URL    @"http://example.com/issues/:app_id/:user_id"
#define PURCHASE_CONFIRMATION_URL @"http://example.com/confirmpurchase/:app_id/:user_id"
#define PURCHASES_URL             @"http://example.com/purchases/:app_id/:user_id"
#define POST_APNS_TOKEN_URL       @"http://example.com/apns/:app_id/:user_id"