/itunes_receipt_validator

Validate iTunes Transaction and Unified style receipts with local decoding and remote validation.

Primary LanguageRubyMIT LicenseMIT

iTunes Receipt Validator

Code Climate Test Coverage Build Status Gem Version

Decode locally

The difference between this gem and any of the alternatives is that it decodes the base64 encoded receipt with our ItunesReceiptDecoder library to extract the data from the receipt without making a HTTP request to Apple's servers.

No redundent HTTP requests

Because this library decodes the receipt first, it determins the origin of the receipt before making any HTTP requests. This means you don't need to make an additional request to the sandbox or production URLs.

Secondly, if the receipt can't be decoded, it can't be validated. This will prevent unnecessary requests when you receive fraudulent receipts.

Handle any style of receipt

Apple offers two kinds of receipts:

  1. The deprecated [SKPaymentTransaction transactionReceipt] and;
  2. The Grand Unified Receipt [NSBundle appStoreReceiptURL]

Validating both kinds of receipts requires separate logic because the schemas and data are entirely different.

Normalize all the things

No matter if the receipt is a [SKPaymentTransaction transactionReceipt] or [NSBundle appStoreReceiptURL], the responses are normalized with extra helpful methods for all your iOS and OSX receipt validation needs.

Need a complete solution?

We have a cloud service available at mbaasy.com, it takes care of in-app purchase management, receipt validation and reporting so you don't have to. It even offers integration with your own API through webhooks to notify you of new, expired, renewed and cancelled purchases for iOS, OSX and Google Play receipts. It will save you time and money but most of all it allows you to focus on your core project instead of wasting time on receipt validation.

We offer this libary because we believe in the Open Source movement, mbaasy.com is built upon a foundation of Open Source projects, so this libary is our way of giving back to the community.

Install

Install from the command line:

$ gem install itunes_receipt_validator

Or include it in your Gemfile:

gem 'itunes_receipt_validator'

Usage

Initialization

validator = ItunesReceiptValidator.new(
  base64_encoded_receipt,
  shared_secret: 'your_shared_secret'
) # => ItunesReceiptValidator::Receipt

Or intialize with a block:

shared_secrets = {
  'com.example.app1' => 'shared_secret_for_app1'
  'com.example.app2' => 'shared_secret_for_app2'
}
validator = ItunesReceiptValidator.new(base64_encoded_receipt) do |receipt|
  receipt.shared_secret = shared_secrets.fetch(receipt.bundle_id)
end

BYO HTTP requests

If you require more flexibility with upstream HTTP requests to Apple's Validation API you can initialize with your own request method.

validator = ItunesReceiptValidator.new(base64_encoded_receipt) do |receipt|
  receipt.shared_secret = 'your_shared_secret'
  receipt.request_method = lambda do |url, headers, body|
    MyFancyRequest.new(url, headers: headers, body: body)
  end
end

Your custom method exposes a HTTP status code and a response body as status and body respectively.

ItunesReceiptValidator::Receipt methods

validator.sandbox?

Returns true or false (opposite of production?).

validator.production?

Returns true or false (opposite of sandbox?).

validator.bundle_id

Returns the bundle_id of the app (e.g. com.mbaasy.ios).

validator.transactions

Returns a sub-class of Array, with transactions sourced locally from the receipt. See ItunesReceiptValidator::TransactionsProxy methods.

validator.latest_transactions

Returns a sub-class of Array, with transactions sourced from Apple's validation API. See ItunesReceiptValidator::TransactionsProxy methods.

validator.latest_receipt

Returns a base64 encoded string for the latest receipt sourced from Apple's validation API.

validator.local

Returns the ItunesReceiptDecoder::Decode::Transaction or ItunesReceiptDecoder::Decode::Unified instances. See the ItunesReceiptDecoder gem.

validator.remote

Returns the ItunesReceiptValidator::Remote instance.

ItunesReceiptValidator::TransactionsProxy methods

Inerhits from Array and includes Enumerable.

transactions.where(id: 1234)

Like ActiveRecord's where it accepts a hash of arguments and returns a new instance of ItunesReceiptValidator::TransactionsProxy.

ItunesReceiptValidator::Transaction methods

transaction.expired?

Returns true or false. This method will make a request to Apple's validation API to check if the receipt itself has expired, or if the latest transaction retrieved is expired.

transaction.cancelled?

Returns true or false.

transaction.auto_renewing?

Returns true if web_order_line_item_id is present.

transaction.trial_period?

Returns true or false.

transaction.latest

Returns a ItunesReceiptValidator::Transaction by making a request to Apple's validation API and matches it with the original_id.

ItunesReceiptValidator::Transaction properties

transaction.id

The transaction identifier of the item that was purchased.

See Transaction Identifier.

transaction.original_id

For a transaction that restores a previous transaction, the transaction identifier of the original transaction. Otherwise, identical to the transaction identifier.

See Original Transaction Identifier.

transaction.product_id

The product identifier of the item that was purchased.

See Product Identifier.

transaction.quantity

The number of items purchased.

See Quantity.

transaction.first_purchased_at

For a transaction that restores a previous transaction, the date of the original transaction. Cast as a Time instance.

See Original Purchase Date.

transaction.purchased_at

The date and time that the item was purchased. Cast as a Time instance.

See Purchase Date.

transaction.expires_at

The expiration date for the subscription. Cast as a Time instance.

See Subscription Expiration Date.

transaction.cancelled_at

For a transaction that was canceled by Apple customer support, the time and date of the cancellation. Cast as a Time instance.

See Cancellation Date.

transaction.web_order_line_item_id

The primary key for identifying subscription purchases.

See Web Order Line Item ID.

transaction.trial_period

Undocumented with Apple.

Testing

  1. bundle install
  2. rake

Copyright 2015 mbaasy.com. This project is subject to the MIT License.