Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Local Receipt Validation as recommended by Apple #101

Open
bizz84 opened this issue Nov 4, 2016 · 13 comments
Open

Implement Local Receipt Validation as recommended by Apple #101

bizz84 opened this issue Nov 4, 2016 · 13 comments
Labels
area: receipt-validation validating receipts for customer or purchase verification difficulty: advanced we really need help with this one type: enhancement

Comments

@bizz84
Copy link
Owner

bizz84 commented Nov 4, 2016

As recommended by Apple, local receipt validation can be performed with a number of steps:

To validate the receipt, perform the following tests, in order:

  1. Locate the receipt.
    If no receipt is present, validation fails.

  2. Verify that the receipt is properly signed by Apple.
    If it is not signed by Apple, validation fails.

  3. Verify that the bundle identifier in the receipt matches a hard-coded constant containing the CFBundleIdentifier value you expect in the Info.plist file.
    If they do not match, validation fails.

  4. Verify that the version identifier string in the receipt matches a hard-coded constant containing the CFBundleShortVersionString value you expect in the Info.plist file.
    If they do not match, validation fails.

  5. Compute the hash of the GUID as described in Compute the Hash of the GUID.
    If the result does not match the hash in the receipt, validation fails.

If all of the tests pass, validation passes.

A discussion on how this has been implemented by RMStore is here:
http://stackoverflow.com/questions/19943183/a-complete-solution-to-locally-validate-an-in-app-receipts-and-bundle-receipts-o

Also this series was recently published with some guidelines on how to implement local receipt validation. This links to the SwiftyLocalReceiptValidator project on GitHub, which you can already use independently of SwiftyStoreKit.

Ongoing discussion about how SwiftyStoreKit and SwiftyLocalReceiptValidator may fit together:
andrewcbancroft/SwiftyLocalReceiptValidator#1

@Kymer
Copy link

Kymer commented Jan 12, 2017

Have there been any developments in regards to this issue? I was planning on writing a gist / small library for doing local receipt validation myself. I might contribute if there is still a need for this.

@bizz84
Copy link
Owner Author

bizz84 commented Feb 4, 2017

I don't expect to have time to implement this unfortunately.

Recently we have introduced a ReceiptValidator protocol and an AppleReceiptValidator class to implement validation with the Apple server.

@Kymer If you are planning to write this yourself, I would advise to create a new class that conforms to the ReceiptValidator protocol. This way the new code can be used directly in SwiftyStoreKit without changing existing interfaces.

@bizz84
Copy link
Owner Author

bizz84 commented Feb 20, 2017

Closed linked issue as duplicate: #75

@jabhiji
Copy link

jabhiji commented Aug 22, 2017

Hello, is there a way to clear all data associated with the in app purchase on a device? In particular, can we erase the "localReceiptData"? I see this is a read only property.

@msamoylov
Copy link
Contributor

Yes, can you please make SwiftyStoreKit.localReceiptData swappable?

I'm experiencing issues with testing my receipt when running my macOS from Xcode because it doesn't have a receipt. I have to read Contents/_MASReceipt/receipt from the copy installed from the App Store.

I need the receipt to be able to read original_application_version.

Thanks!

@stanmots
Copy link

@hanming223 But the author said he has no time to implement local receipt validation.

@JulianKahnert
Copy link

JulianKahnert commented May 6, 2019

Hey,
first of all: thank you @bizz84 for maintaining this awesome project! It makes it so much easier to implement StoreKit functionality in any app.
I just found the MerchantKit framework from @benjaminmayo who skipped the OpenSSL implementation by writing a seperate ASN1 parser in Swift. This might be a great starting point, when adding a LocalReceiptValidator ( which implements the ReceiptValidator protocol).
I just wanted to save this thought for later, since I am quite busy in the next few weeks. But I definitely will have a look at it later on. 🙂

@tikhop
Copy link

tikhop commented Jun 27, 2019

Hi,
A while ago I wrote a library to read and verify in app receipt locally. It has been decoding pkcs7 (and asn1 objects) into a sweet swift structure, validating hash and signature using OpenSSL.
A week ago I decided to substitute openssl with own decoder and validator. So far, all functionality, but signature validation work well.

Here is the lib: https://github.com/tikhop/TPInAppReceipt

Personally, I use SwiftyStoreKit for every project where I need to make in app purchase and I use my lib to validate and read receipt. (thank you @bizz84 for simplifying our lives)

If it's really an issue, we can try to combine both projects.

P.

@teologov
Copy link

teologov commented Jul 8, 2019

Hi @tikhop, is there a demo available using your TPInAppReceipt lib with SwiftyStoreKit?

@nuthinking
Copy link

nuthinking commented Jul 10, 2019

@teologov they are kind of independent. That's how I check a subscription:

public static func isSubscribed() -> Bool {
        do {
            let receipt = try InAppReceipt.localReceipt()
            if let _ = receipt.activeAutoRenewableSubscriptionPurchases(ofProductIdentifier: subscriptionProductID, forDate: Date()){
                return true
            }
        } catch {
            print(error)
        }
        return false
    }

What's missing here is the logic to load from the Apple server if expired.

@teologov
Copy link

@nuthinking I tried to conform to ReceiptValidator protocol first, but it's not that convenient. So I just did the same way as you proposed. Thanks!

@gerchicov-bp
Copy link

@bizz84 it is not enhancement. It is a bug

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: receipt-validation validating receipts for customer or purchase verification difficulty: advanced we really need help with this one type: enhancement
Projects
None yet
Development

No branches or pull requests

11 participants