README.md in apple_receipt-0.1.1 vs README.md in apple_receipt-0.2.0
- old
+ new
@@ -1,10 +1,17 @@
-# AppleReceipt
+# Apple Receipt
+[](https://badge.fury.io/rb/apple_receipt)
[](https://travis-ci.org/koenrh/apple_receipt)
+[](https://beta.gemnasium.com/projects/github.com/koenrh/apple_receipt)
-This gem allows you to to locally/cryptographically verify Apple receipts.
+This gem allows you to read and verify Apple receipts. It was originally built
+to locally (server-side) verify the validity of receipts that are embedded in
+[Status Update Notifications](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html#//apple_ref/doc/uid/TP40008267-CH7-SW13).
+These receipts have a different format than [documented](https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateLocally.html#//apple_ref/doc/uid/TP40010573-CH1-SW2)
+App Store receipts you might be familiar with, which are [PKCS #7](https://tools.ietf.org/html/rfc2315)
+containers with a payload (receipt data) encoded using [ASN.1](https://www.itu.int/itu-t/recommendations/rec.aspx?rec=X.690).
## Installation
Add this line to your application's Gemfile:
@@ -23,48 +30,83 @@
## Usage
```ruby
require 'apple_receipt'
-# check validity (certificate chain, and signature)
+# Check receipt's validity (certificate chain, and signature)
receipt_raw = File.read('./receipt.txt')
receipt = AppleReceipt::Receipt.new(receipt_raw)
receipt.valid?
# => true
-# read purchase info
+# Read receipt's data (data in example shortened for brevity)
receipt.purchase_info
-# => {"original-purchase-date-pst"=>"2017-12-23 09:03:53 America/Los_Angeles",
-# "quantity"=>"1",
-# "unique-vendor-identifier"=>"D895D8DB-AEDF-4530-B7E5-E0C9A9A394B6",
-# "original-purchase-date-ms"=>"1514048633000",
-# "expires-date-formatted"=>"2018-01-23 17:03:44 Etc/GMT",
-# "is-in-intro-offer-period"=>"false",
-# "purchase-date-ms"=>"1514048624000",
-# "expires-date-formatted-pst"=>"2018-01-23 09:03:44 America/Los_Angeles",
-# "is-trial-period"=>"false",
-# "item-id"=>"1190360447",
-# "unique-identifier"=>"fed543dc24065fa2ab23ef08b0b44c0a0c9ed375",
-# "original-transaction-id"=>"160000408504141",
-# "expires-date"=>"1516727024000",
-# "app-item-id"=>"947936149",
-# "transaction-id"=>"160000408504141",
-# "bvrs"=>"7000",
-# "web-order-line-item-id"=>"160000091314729",
-# "version-external-identifier"=>"825366855",
-# "bid"=>"com.foo.bar",
-# "product-id"=>"com.foo.bar.monthly",
-# "purchase-date"=>"2017-12-23 17:03:44 Etc/GMT",
-# "purchase-date-pst"=>"2017-12-23 09:03:44 America/Los_Angeles",
-# "original-purchase-date"=>"2017-12-23 17:03:53 Etc/GMT"}
+# => {
+# "quantity"=>"1",
+# "expires-date-formatted"=>"2018-01-23 17:03:44 Etc/GMT",
+# "is-in-intro-offer-period"=>"false",
+# "is-trial-period"=>"false",
+# "item-id"=>"1190360447",
+# "app-item-id"=>"947936149",
+# "transaction-id"=>"160000408504141",
+# "web-order-line-item-id"=>"160000011000001",
+# "bid"=>"com.foo.bar",
+# "product-id"=>"com.foo.bar.monthly",
+# "purchase-date"=>"2017-12-23 17:03:44 Etc/GMT",
+# "original-purchase-date"=>"2017-12-23 17:03:53 Etc/GMT"
+# }
```
+## Apple receipts
+
+A receipt is encoded as base64, and is formatted as a [NeXTSTEP](https://en.wikipedia.org/wiki/Property_list#NeXTSTEP)
+dictionary:
+
+```
+{
+ "signature" = "[base64-encoded signature]";
+ "purchase-info" = "[base64-encoded purchase data]";
+ "pod" = "[integer]";
+ "signing-status" = "0";
+}
+```
+
+### Signature
+
+The `signature` entry contains base64-encoded binary data, which has the following
+layout:
+
+- **1 byte** - Receipt version (e.g. version 3).
+- **128 bytes** (version 2) or **256 bytes** (version 3) - Signature.
+- **4 bytes** - Length (in number of bytes) of the certificate.
+- **N bytes** - DER-encoded certificate.
+
+The version 2 and 3 receipt certificates are signed, respectively, by:
+
+- **Apple iTunes Store Certification Authority** (version 2)
+ - Serial: 26 (`0x1a`)
+ - Subject: `C=US, O=Apple Inc., OU=Apple Certification Authority, CN=Apple iTunes Store Certification Authority`
+- **Apple Worldwide Developer Relations Certification Authority** (version 3)
+ - Serial: 134752589830791184 (`0x1debcc4396da010`)
+ - Subject: `C=US, O=Apple Inc., OU=Apple Worldwide Developer Relations, CN=Apple Worldwide Developer Relations Certification Authority`
+
+Both certificates chain up to:
+
+- **Apple Root CA**
+ - Serial: 2 (`0x2`)
+ - Subject: `C=US, O=Apple Inc., OU=Apple Certification Authority, CN=Apple Root CA`
+
+### Purchase info
+
+The `purchase-info` entry contains a base64-encoded NeXTSTEP dictionary that contains
+the actual receipt data (purchase info).
+
## Contributing
Bug reports and pull requests are welcome on [GitHub](https://github.com/koenrh/apple_receipt).
This project is intended to be a safe, welcoming space for collaboration, and
contributors are expected to adhere to the [Contributor Covenant](https://www.contributor-covenant.org)
code of conduct.
## License
-The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
+The gem is available as open source under the terms of the [ISC License](https://opensource.org/licenses/ISC).