iOS In-app Purchase

Overview

In-App Purchase mechanism in iOS apps can be divided into two steps:

  1. purchase of the item at App Store
  2. verify purchase confirmation from Apple by provider and deliver the purchased item

For the first step, the in-app purchase items must be filled in at iTunes Connect portal, including their description, prices etc. Each such in-app purchase item will have a unique identifier. Coma-separated list of these unique identifiers must be filled in at Cloud Softphone portal, the app will then fetch the rest of data from iTunes Connect.

When the user makes a successful purchase, the Cloud Softphone app receives a confirmation receipt from Apple. Cloud Softphone then calls a web service on provider side and passes the receipt to it.

This starts the second step. Provider should validate the receipt by Apple to make sure it’s backed by a real purchase. The API to validate receipts is documented by Apple.

Note

There are also code snippets and libraries for various languages available on internet which may be more explanatory, like:

After the receipt is found valid, the script should deliver the purchased item (enable a service, add calling credit etc).

The web service has to be configured at Cloud Softphone web portal.

Parameters

Parameter templates for iOS in-app purchase web service can use any variables from Global parameters and Account parameters scopes. There are also some web-service specific parameters:

receipt

This parameter will be replaced by base64 encoded receipt received from Apple. This is the receipt which needs to be validated.

price

The price the user has paid for the in-app purchase item

currency

The currency in which the purchase was made

productCode

The unique identifier of the in-app purchase item which has been purchased.

Configuration

The web service is configured in Cloud Softphone web portal. The following fields may be filled in:

iapWsUrl

Contains the URL, including URL scheme, of the web service, possibly also with query string.

Example (with query-string):

https://example.com/iap_validate/?username=%account[username]%&receipt=%receipt%&product=%productCode%

iapWsPostData

If filled in, the app will use POST request to validate the receipt

Example ( for application/x-www-form-urlencoded):

username=%account[username]%&receipt=%receipt%&product=%productCode%

Example ( for application/json ):

{ "username" : "%account[username]%" , "receipt" : "%receipt%" , "product" : "%productCode%" }

iapWsContentType

Specifies the value of Content-Type header to be sent in POST request. If not specified, the app will default to application/x-www-form-urlencoded

Response

The response will be considered successful if the HTTP response code is 2xx. For any responses which have other response code, or whose body can’t be parsed, an error message is shown to the user.

Content-type header of the response specifies the format of the body. The following Content-Types are supported:

  • application/xml (default)
  • application/json
  • application/x-www-form-urlencoded

The following fields in the response are recognized:

message

This parameter should be included in case the web service returns non-2xx response code. The contents of this parameter will be shown to the user.

Examples

GET method, XML

request:

GET /iap_validate/?username=johndow&product=credit5&receipt=TG9yZW0gSXBzdW0gRG9sb3IgU2l0IEFtZXQ= HTTP/1.1
Host: example.com
Connection: close
Cache-Control: max-age=0
User-Agent: CloudSoftphone/1.5.6

response:

HTTP/1.1 200 OK
Date: Sun, 15 Mar 2015 00:46:17 GMT
Server: Apache/2.4.7 (Ubuntu)
Vary: Accept-Encoding
Content-Length: 0
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive

POST method, JSON

request:

POST /iap_validate/ HTTP/1.1
Host: example.com
Connection: close
Cache-Control: max-age=0
Content-Length: 183
Content-Type: application/json
User-Agent: CloudSoftphone/1.5.6

{ "username" : "johndow",
  "product"  : "credit5",
  "receipt"  : "TG9yZW0gSXBzdW0gRG9sb3IgU2l0IEFtZXQ="
}

response:

HTTP/1.1 403 Forbidden
Date: Sun, 15 Mar 2015 00:46:17 GMT
Server: Apache/2.4.7 (Ubuntu)
Content-Length: 183
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json

{
    "message" : "Failed to validate your purchase with App Store"
}