SwiftyStoreKit icon indicating copy to clipboard operation
SwiftyStoreKit copied to clipboard

mac app, SwiftyStoreKit.purchaseProduct, callback has never been executed

Open womandroid opened this issue 7 years ago • 14 comments

hi, i use the following code to purchase non consumable product for my mac app, at the beginning, everything is ok: i fill the test account and password, click confirmation buttons and so on, but after I confirm the last dialog, i wait and wait and wait, but nothing is happend, the callback has never been executed. i try again and again and again, but every time is the same. what should i do? did I do something wrong? thanks.

SwiftyStoreKit.purchaseProduct(productIdentifier) { (result) in
    print(result) //the code here has never been executed
}

Now i found that i should use a new test account to purchase the product, if the account has purchased the product already, the callback will not be executed. what should i do if i want the callback always be executed?

womandroid avatar Nov 01 '16 13:11 womandroid

If you try to purchase a non-consumable product again on iOS, you always get a message confirming that you will not be charged again, and if you continue the callback will be called.

I'm not sure if there are differences on this between iOS and macOS. More investigation needed.

bizz84 avatar Nov 06 '16 22:11 bizz84

There have been some major improvements to the purchase flows recently.

@womandroid Could you retest this on version 0.8.0?

If this issue is not updated in the next few weeks I'll assume everything works fine and will close it.

bizz84 avatar Feb 20 '17 23:02 bizz84

Unfortunately, it still doesn't work for the latest version 0.8.4.

womandroid avatar Apr 09 '17 05:04 womandroid

Here is the log message when I purchase the product by a purchased account:

unhandledTransactions:
productId: com.xxx.app.product, transactionId: null, state: purchasing, date: nil
Unexpected restored transaction for payment com.xxx.app.product
Finishing transaction for payment "com.xxx.app.product" with state: restored

After that, nothing happend. The callback still doesn't execute.

womandroid avatar Apr 10 '17 12:04 womandroid

I have same problem. I found code, if transactionState == .restored { print("Unexpected restored transaction for payment \(transactionProductIdentifier)") } no callback be executed

cp3hnu avatar Sep 19 '17 07:09 cp3hnu

This problem has never been fixed since it was first identified in #105, but I have a proposed fix here, which I have tested in SwiftyStoreKit v0.10.7 with Swift 3 (and the same should apply to v0.11.0).

The problem occurs only in Mac OS when you try to re-purchase a non-consumable item that you have previously purchased. The completion closure never gets called. The reason it works in iOS and not in macOS can be found and fixed in the processTransaction function in the file PaymentsController.swift. When the iOS App Store acknowledges the prior purchase it sends a transactionState == .purchased, but when the Mac App Store acknowledges the prior purchase it sends a transactionState == .restored! The fix is to change

if transactionState == .purchased {

to

if transactionState == .purchased || transactionState == .restored {

and to remove the test for transactionState == .restored at the end of the processTransaction function (which doesn't really do anything anyway). As I am not adept at submitting updates to the code base, I hope someone will read this and apply this change to a future release.

doffen avatar Oct 25 '17 21:10 doffen

@doffen Same here too, but your fix is a little rough. What if I do want to restore? Callback for restore will never be called.

zhudengdengdeng avatar Nov 21 '17 06:11 zhudengdengdeng

I tested restore and it works for me, on both iPhone and Mac OS. zhudengdengdeng, have you seen it fail to restore when using this change?

doffen avatar Nov 22 '17 00:11 doffen

@doffen Sorry for my mistake, I have looked into the code and found no issue.

zhudengdengdeng avatar Nov 23 '17 01:11 zhudengdengdeng

@Sam-Spencer this issue is back again for Mac. It would be great to add a unit test so another contributor isn't deleting it again. Or adding comments there may prevent it from being removed.

I can see you have merged it: https://github.com/bizz84/SwiftyStoreKit/pull/465/files/b216b219bda55252390e2d5b89142963b8a9ee14

But when will the CocoaPod be updated with this fix, please? Many Thanks

houmie avatar Apr 09 '20 18:04 houmie

Mac上复现了这个问题,复现方式: 1.购买自动续订套餐,然后再购买其他续订套餐 会报这个异常 2.续订套餐到期后,再次手动购买续订套餐,就可以复现了

baijiahei888 avatar Aug 19 '20 08:08 baijiahei888

Im also getting this issue. 1- I restore purchases, after success, it verifies all inApps. 2- monthly subscription is detected as previously bought. 3- I select the Yearly Subscription (same group as the monthly). 4- I try to buy the Yearly Subscription so that is switches from the monthly to the yearly. 5- I get a success buy callback, but no Apple Alert or purchase process of anykind. It simply returns as successfully buy immediately. I see in the console the message: "Unexpected restored transaction for payment com.xxx.app.product"

iOS 14.0

what are we suppose to do here ? any ideas?

omarojo avatar Nov 11 '20 04:11 omarojo

Also for me it happens in iOS

santogioia avatar Nov 30 '20 11:11 santogioia

I encountered similar problems a week ago. Purchasing worked. However, restoring my old (expired) purchases first, and purchasing a new subscription afterwards failed. The purchase requests returned already expired restored purchases instead of new ones. I have used two subscriptions: 1 weekly (for fast tests) and 1 yearly (for slow tests). Over the years my sandbox account collected more than 400 transactions.

Before blaming yourself, your software, or SwiftyStoreKit, you should try to purchase your products with Apple’s sample code (available here: https://developer.apple.com/documentation/storekit/in-app_purchase/offering_completing_and_restoring_in-app_purchases)

Compile & run Apple’s software. Then try to restore your old purchases and buy new products again. If it fails, it is not your fault.

The following solution worked for me: (1) create a new sandbox account in iTunes Connect (2) logout of old sandbox account (in iOS-App Settings > App Store > Sandbox-account) (3) login new sandbox account (4) delete your own app on your test device (5) Restart the device (6) then re-install your app using Xcode. (7) delete old sandbox account (8) test purchases with new sandbox account

blankdata avatar Feb 11 '21 06:02 blankdata