0

I have been using SwiftyStoreKit.verifyReceipt to make sure that the user is still subscribed to the auto renewable membership. I run this code at viewWillAppear, it works well, but the problem is that it keep asking for the Apple ID and password each time, is it because the app is still under development / the in app purchase have not been verified by Apple or I am using SwiftyStoreKit.verifyReceipt incorrectly.

Documentation: https://github.com/bizz84/SwiftyStoreKit

My Code in viewWillAppear:

 let appleValidator = AppleReceiptValidator(service: .production, sharedSecret: "123")
                            SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in


                                switch result {
                                case .success(let receipt):
                                    let productId = "123"
                                    // Verify the purchase of a Subscription
                                    let purchaseResult = SwiftyStoreKit.verifySubscription(
                                        ofType: .autoRenewable, // or .nonRenewing (see below)
                                        productId: productId,
                                        inReceipt: receipt)


                                    switch purchaseResult {
                                    case .purchased(let expiryDate, let items):
                                        print("\(productId) is valid until \(expiryDate)\n\(items)\n")
                                        OneSignal.sendTag("isUserVIPMember", value: "true")
                                    case .expired(let expiryDate, let items):
                                        print("\(productId) is expired since \(expiryDate)\n\(items)\n")
                                        OneSignal.sendTag("isUserVIPMember", value: "false")
                                    case .notPurchased:
                                        print("The user has never purchased \(productId)")
                                        OneSignal.sendTag("isUserVIPMember", value: "false")
                                    }

                                case .error(let error):
                                    print("Receipt verification failed: \(error)")


                                }
                            }
jmapps9
  • 87
  • 1
  • 7

1 Answers1

0

My assumption would be that verifyReceipt doesn't use the local receipt, but requests it from the App Store. Requesting the receipt require the consent of the user and therefore would explain why he has to enter his credentials.

The code on Github states that the default value of forceRefresh is false, but could you add forceRefresh: false to the verifyReceipt call.

Also could you please check if receiptString contains any data?

let receiptData = SwiftyStoreKit.localReceiptData
let receiptString = receiptData.base64EncodedString(options: [])

And if so, please try to do SwiftyStoreKit.verifySubscription() with the local receipt. Do you still have to enter your credentials?

I have no idea what kind of app you are building, but I would recommend not to verify the receipt in viewWillAppear. The local receipt won't change anyway (except for renewals). So do it once on app start or if it is really crucial that the user loses access, to what ever he gets with your subscription, I would recommend to use a custom server. The server will be notified if something changes in the subscription status of a user.

Side note: At the moment I would advise against the usage of SwiftyStoreKit, because they verify the receipt against the server endpoint from Apple and this is only allowed from another server. Chances are that Apple will reject your app.

Warning

Do not call the App Store server verifyReceipt endpoint from your app. You can't build a trusted connection between a user’s device and the App Store directly, because you don’t control either end of that connection, which makes it susceptible to a man-in-the-middle attack.

Source

Community
  • 1
  • 1
Paul Schröder
  • 1,440
  • 1
  • 10
  • 19
  • Do you know how I can use their code to verify the code locally. It is really bizarre sometime it does not ask for the apple id and sometime it keeps asking for it. I am also not sure if this is just because the IAP is not verified by Apple. – jmapps9 Mar 24 '20 at 01:30
  • Have you tested the things I suggested? Unfortunately, as far as I understand their open issue (https://github.com/bizz84/SwiftyStoreKit/issues/101) there is currently no way to do it with `SwiftyStoreKit` alone. But, using the suggested `TPInAppReceipt` is definitely a good addition to verify the receipt locally. – Paul Schröder Mar 24 '20 at 11:06