SwiftyStoreKit icon indicating copy to clipboard operation
SwiftyStoreKit copied to clipboard

SwiftStoreKit.ReceiptError error 1

Open Yetispapa opened this issue 5 years ago • 32 comments

Platform

  • [X ] iOS
  • [ ] macOS
  • [ ] tvOS

In app purchase type

  • [ ] Consumable
  • [ ] Non-consumable
  • [X ] Auto-Renewable Subscription
  • [ ] Non-Renewing Subscription

Environment

  • [ X] Sandbox
  • [X ] Production

Version

0.13.3

Report

Issue summary

We're fetching the receipt in order to validate if the subscription is still valid or not. In order to do so we fetch the receipt and sent the encoded receipt to our server. This is our code:

    SwiftyStoreKit.fetchReceipt(forceRefresh: false) { result in

        switch result {
        case .success(let receiptData):

            let encryptedReceipt = receiptData.base64EncodedString(options: [])

            Log.info("Fetch receipt success")

            //further code to send the receipt to our server

        case .error(let error):
            observer.send(error: error.localizedDescription)
        }
    }

Everything works on my side but unfortunately the Apple reviewer gets the error which is shown in the section below. So error.localizedDescription is the alert message. Now I looked through the errors from SwiftStoreKit and I'm a bit hopeless cause I couldn't find any error with code 1. Could someone help me here?

What did you expect to happen

Fetching receipt is successfull and the receipt will be send to our sever for validation without error

What happened instead

screen shot 2018-08-02 at 11 24 36

Yetispapa avatar Aug 02 '18 09:08 Yetispapa

Would like to know also.

0xTomTom avatar Oct 17 '18 16:10 0xTomTom

This error appears when on a fresh install of the app with no receipt at all, you're trying to get that receipt, either from the iPhone or from the Apple servers, where there's no receipt as well, because you never bought anything. Make sure you handle this error.

Starsky89 avatar Nov 15 '18 09:11 Starsky89

I also have this issue. But I have it when I fetch receipt after successful purchase.

anta-semenov avatar Jan 11 '19 10:01 anta-semenov

Same here. Apple reviewer has such an error after successful subscription. What can be wrong?

ab-zephyr avatar Mar 22 '19 19:03 ab-zephyr

this issue still exists in release 0.15.0

KasykhinAndrey avatar Sep 27 '19 21:09 KasykhinAndrey

in my case I got this error when :

  • trying to get that receipt : SwiftyStoreKit.fetchReceipt
  • Alert appears with title: Sign In to iTunes Store and message: Enter the password for your Apple ID. Cancel button pressed.

result received : FetchReceiptResult ▿ error : 1 element ▿ error : ReceiptError ▿ networkError : 1 element - error : Error Domain=SSErrorDomain Code=16 "Cannot connect to iTunes Store" UserInfo={NSLocalizedDescription=Cannot connect to iTunes Store}

error.localizedDescription "The operation couldn’t be completed. (SwiftyStoreKit.ReceiptError error 1.)"

KasykhinAndrey avatar Sep 27 '19 21:09 KasykhinAndrey

I too have this issue, occurs when I try to verify receipt. Although it's fine for Me, only apple reviewer gets this each time. Does someone know what could be wrong or is this related to submitting our subscription. In appStoreConnect, my subscription is still showing "waiting for review".

SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in ...

sameersyd avatar Jun 13 '20 11:06 sameersyd

Same here in 0.16.0. Everything works fine on my device. But Apple rejected the build and sent the error screenshot.

cclaflin89 avatar Jul 07 '20 06:07 cclaflin89

Same here in 0.16.0. Everything works fine on my device. But Apple rejected the build and sent the error screenshot.

Do you know any alternative? Until these guys fix this?

sameersyd avatar Jul 07 '20 08:07 sameersyd

Not found alternative solution yet.

cclaflin89 avatar Jul 07 '20 08:07 cclaflin89

Please let me know if you did. On Tue, 7 Jul 2020 at 14:20, cclaflin89 [email protected] wrote:

Not found alternative solution yet.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/bizz84/SwiftyStoreKit/issues/392#issuecomment-654700477, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGIO2I6TKMSA5FIDF7CHYC3R2LOVJANCNFSM4FNPZNOQ .

sameersyd avatar Jul 07 '20 08:07 sameersyd

I have also encountered this problem, but have been unable to find a solution, I hope to get help, thank you!

tc976562936 avatar Dec 08 '20 03:12 tc976562936

My app got rejected with the same error.


Update:

~~Something I noticed while reading this Apple document.~~

~~> Use the test environment URL https://sandbox.itunes.apple.com/verifyReceipt when testing your app in the sandbox and while your application is in review. Use the production URL https://buy.itunes.apple.com/verifyReceipt when your app is live in the App Store.~~

~~I wrote my code like this.~~

#if DEBUG
    AppleReceiptValidator(service: .sandbox, sharedSecret: secret)
#else
    AppleReceiptValidator(service: .production, sharedSecret: secret)
#endif

~~Since the app is technically a release build, it uses the production URL. But according to that article, while the app is in review, we should use the sandbox URL.~~

~~Could this be the issue?~~

~~If this is the case, we're at a dead-end when it comes to verifying receipts locally. Since there is no way to change the URLs within the app after the build is submitted, our only option is to go with the server-side validation, it seems.~~


Update 2:

Ignore my previous update. I found the real cause for the issue. See below.

Isuru-Nanayakkara avatar Jan 01 '21 04:01 Isuru-Nanayakkara

I have used a different library to verify receipt, and for other operations such as purchase, I've used SSK.

My app is live!

sameersyd avatar Jan 01 '21 07:01 sameersyd

I have used a different library to verify receipt, and for other operations such as purchase, I've used SSK.

My app is live!

Do you verify the receipts locally? What's the library you used?

Isuru-Nanayakkara avatar Jan 02 '21 08:01 Isuru-Nanayakkara

Do you verify the receipts locally? What's the library you used?

I've used TPInAppReceipt Not a popular one, but works for now.

sameersyd avatar Jan 02 '21 08:01 sameersyd

Do you verify the receipts locally? What's the library you used?

I've used TPInAppReceipt Not a popular one, but works for now.

Thanks :) btw I discovered something just now regarding this whilesifting through Apple docs. See my comment above. I updated it.

Isuru-Nanayakkara avatar Jan 02 '21 08:01 Isuru-Nanayakkara

Thanks :) btw I discovered something just now regarding this whilesifting through Apple docs. See my comment above. I updated it.

Oh Cool! I've always given .production, will this "if else", fix it?

sameersyd avatar Jan 02 '21 08:01 sameersyd

Thanks :) btw I discovered something just now regarding this whilesifting through Apple docs. See my comment above. I updated it.

Oh Cool! I've always given .production, will this "if else", fix it?

No, my code is what's causing the issue, I think. The if block runs while I'm in development, the if else block runs when the app is released. The problem is Apple requires us to still call the sandbox URL while the app is in review. Even though the app is technically a release build so it calls the production URL. This might be what's giving the error.

Isuru-Nanayakkara avatar Jan 02 '21 08:01 Isuru-Nanayakkara

No, my code is what's causing the issue, I think. The if block runs while I'm in development, the if else block runs when the app is released. The problem is Apple requires us to still call the sandbox URL while the app is in review. Even though the app is technically a release build so it calls the production URL. This might be what's giving the error.

Ahh ok. Then I would recommend if you wanna quick fix for now, you can use this TPInApp receipt. As this library does not require the URL, and takes itself. Btw after using this lib, my app has been accepted. I'll attach the code snippet below!

image

sameersyd avatar Jan 02 '21 08:01 sameersyd

No, my code is what's causing the issue, I think. The if block runs while I'm in development, the if else block runs when the app is released. The problem is Apple requires us to still call the sandbox URL while the app is in review. Even though the app is technically a release build so it calls the production URL. This might be what's giving the error.

Ahh ok. Then I would recommend if you wanna quick fix for now, you can use this TPInApp receipt. As this library does not require the URL, and takes itself. Btw after using this lib, my app has been accepted. I'll attach the code snippet below!

image

Thank you. I'll give this approach a try 👍🏼

Isuru-Nanayakkara avatar Jan 02 '21 09:01 Isuru-Nanayakkara

No, my code is what's causing the issue, I think. The if block runs while I'm in development, the if else block runs when the app is released. The problem is Apple requires us to still call the sandbox URL while the app is in review. Even though the app is technically a release build so it calls the production URL. This might be what's giving the error.

Ahh ok. Then I would recommend if you wanna quick fix for now, you can use this TPInApp receipt. As this library does not require the URL, and takes itself. Btw after using this lib, my app has been accepted. I'll attach the code snippet below!

By the way, is local receipt validation ideal for auto-renewable subscriptions? Because I need to get the latest data like the expiration date. Do I have to refresh the receipt at every launch to get the most updated one?

Isuru-Nanayakkara avatar Jan 02 '21 14:01 Isuru-Nanayakkara

By the way, is local receipt validation ideal for auto-renewable subscriptions? Because I need to get the latest data like the expiration date. Do I have to refresh the receipt at every launch to get the most updated one?

Mine is a social media app, I refresh receipt before user uses a premium feature, every time. Not sure about your use-case, but should be fine.

sameersyd avatar Jan 02 '21 16:01 sameersyd

I got this issue fixed! @Starsky89 is correct. This error occurs when you're trying to refresh a receipt that does not exist. This seems to be the underlaying StoreKit error.

Screenshot 2021-01-06 at 8 48 01 AM

It doesn't tell much but upon further searching I came across this thread which confirmed the suspicion.

I changed my code to first check whether the receipt exist or not and then fire the verification code. My app got approved.

Isuru-Nanayakkara avatar Jan 06 '21 03:01 Isuru-Nanayakkara

I got this issue fixed! @Starsky89 is correct. This error occurs when you're trying to refresh a receipt that does not exist. This seems to be the underlaying StoreKit error.

Screenshot 2021-01-06 at 8 48 01 AM

It doesn't tell much but upon further searching I came across this thread which confirmed the suspicion.

I changed my code to first check whether the receipt exist or not and then fire the verification code. My app got approved.

Great! Can you provide code snippet/SC of your function.

sameersyd avatar Jan 06 '21 05:01 sameersyd

I don't do anything special. I just run this check and handle things accordingly.

if SwiftyStoreKit.localReceiptData != nil {
    // Has a receipt. Verify it.
    let validator = AppleReceiptValidator(service: .production, sharedSecret: Constant.Secret.inAppPurchase)
    SwiftyStoreKit.verifyReceipt(using: validator) { result in
        switch result {
        case .success(let receipt):
            // handle success
        case .error(let error):
            // show error
        }
    }
} else {
    // There is no receipt.
    // Possibly a brand new user who has not purchased anything in the app before.
}

Isuru-Nanayakkara avatar Jan 06 '21 07:01 Isuru-Nanayakkara

The reviewers also rejected my app. In their test environment they get a "SwiftStoreKit.ReceiptError error 1" after restoring and verifying subscription purchases. In my sandbox environment, however, everything works fine.

So instead of receiving an empty receipt, they get no receipt and verification fails! (Thus, other approaches like InAppReceipt.refresh will also fail).

Isuru-Nanayakkara is right. You have to check if SwiftyStoreKit.localReceiptData is nil.

This information should be added to the wiki.

blankdata avatar Mar 06 '21 07:03 blankdata

The App subscription works fine in the sandbox environment, but when apple reviewers test the app they got the below error after purchasing the subscription.

" The operation couldn't be completed. (SwiftyStoreKit.ReceiptError error1.) "

only fetch recipt is used , I'm not using validate recipt anywhere in the code, but still I get the error. Please can anyone help.

Code:-

   SwiftyStoreKit.fetchReceipt(forceRefresh: true) { result in
                switch result {
                  case .success(let receiptData):
                      let encryptedReceipt = receiptData.base64EncodedString(options: [])
                      // code to send recipt to backed server for verification and further process
                   case .error(let error):
                      print("Fetch receipt failed: \(error)")
                      AppDelegate.shared().window?.showToastAtMidBottom(message: (error as NSError).localizedDescription, time: 2.0)
                }
    }

Ajaay7 avatar Dec 24 '21 04:12 Ajaay7

@anta-semenov anta-semenov commented on 11 Jan 2019 I also have this issue. But I have it when I fetch receipt after successful purchase.

I also have this issue. But I have it when I fetch receipt after successful purchase.

hi Mr.anta-semenov did you find any solution

Ajaay7 avatar Dec 24 '21 04:12 Ajaay7

I had the same issue when I sent app that worked in sandbox for review. Review team still had the error on its iPad. I had my own IAP manager which worked with StoreKit natively. After that I switched to SwiftyStoreKit with the hope that all common issues are fixed in the library. Seems that the error is pretty common and not obvious for devs. I also use SwiftyStoreKit.fetchReceipt(forceRefresh: true) but according to the SwiftyStoreKit sources it works in the same way as @Isuru-Nanayakkara solution. /// Return receipt data from the application bundle. This is read fromBundle.main.appStoreReceiptURL. public static var localReceiptData: Data? { return sharedInstance.receiptVerificator.appStoreReceiptData }

Code from receiptVerificator var appStoreReceiptData: Data? { guard let receiptDataURL = appStoreReceiptURL, let data = try? Data(contentsOf: receiptDataURL) else { return nil } return data } Does anybody have solution?

UPD: The problem is in accessing receipt at app's start on simulator after erasing its content and settings. I switched to TPInAppReceipt for receipt checks and the problem has gone.

artur-zaremba avatar Dec 29 '21 07:12 artur-zaremba