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

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

Open
womandroid opened this issue Nov 1, 2016 · 14 comments · Fixed by #465
Open

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

womandroid opened this issue Nov 1, 2016 · 14 comments · Fixed by #465
Assignees
Labels
area: purchase flows purchase processes, efficiency and failures difficulty: intermediate this issue is tough, contributions welcome macOS directly related to Mac

Comments

@womandroid
Copy link

womandroid commented Nov 1, 2016

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?

@bizz84 bizz84 added the macOS directly related to Mac label Nov 6, 2016
@bizz84
Copy link
Owner

bizz84 commented Nov 6, 2016

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
Copy link
Owner

bizz84 commented Feb 20, 2017

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.

@womandroid
Copy link
Author

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

@womandroid
Copy link
Author

womandroid commented Apr 10, 2017

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.

@cp3hnu
Copy link

cp3hnu commented Sep 19, 2017

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

@doffen
Copy link

doffen commented Oct 25, 2017

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.

@zhudengdengdeng
Copy link
Contributor

@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.

@doffen
Copy link

doffen commented Nov 22, 2017

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?

@zhudengdengdeng
Copy link
Contributor

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

@Sam-Spencer Sam-Spencer self-assigned this Mar 21, 2020
@Sam-Spencer Sam-Spencer added area: purchase flows purchase processes, efficiency and failures difficulty: intermediate this issue is tough, contributions welcome labels Mar 21, 2020
@houmie
Copy link

houmie commented Apr 9, 2020

@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

@baijiahei888
Copy link

baijiahei888 commented Aug 19, 2020

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

@omarojo
Copy link

omarojo commented Nov 11, 2020

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?

@santogioia
Copy link

Also for me it happens in iOS

@blankdata
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: purchase flows purchase processes, efficiency and failures difficulty: intermediate this issue is tough, contributions welcome macOS directly related to Mac
Projects
None yet