Open WillMays1 opened 6 years ago
Can anyone help me? I need this resolved asap
@WillMays1 did you find a solution for this? I'm stumbling upon this as well
@haemi No I have not found a solution. I have contacted Apple and they said it is an issue with SwiftyStoreKit and to contact the developer. I have tried to get ahold of him but have had no luck
@WillMays1 Apologies for the late reply.
What error do you get when you make the purchase?
You can use this code to find out:
SwiftyStoreKit.purchaseProduct("your-product-id", quantity: 1, atomically: true) { result in
switch result {
case .success(let purchase):
print("Purchase Success: \(purchase.productId)")
case .error(let error):
switch error.code {
case .unknown: print("Unknown error. Please contact support")
case .clientInvalid: print("Not allowed to make the payment")
case .paymentCancelled: break
case .paymentInvalid: print("The purchase identifier was invalid")
case .paymentNotAllowed: print("The device is not allowed to make the payment")
case .storeProductNotAvailable: print("The product is not available in the current storefront")
case .cloudServicePermissionDenied: print("Access to cloud service information is not allowed")
case .cloudServiceNetworkConnectionFailed: print("Could not connect to the network")
case .cloudServiceRevoked: print("User has revoked permission to use this cloud service")
}
}
}
(if you need to test in production you can replace the print statements with analytics calls).
Also make sure to double check all your iTunes Connect settings, and read all relevant information.
Do I need to add the quantity: 1
when purchasing an auto renewable subscription?
@WillMays1 no, you don't. Quantity is an optional parameter, it defaults to 1 if you omit it.
I have this issue as well -- it works when I use a sandbox ID, but not when I try it with a real apple ID. I get the 'unknown error.' Is there any way to fix this?
Any ideas? My purchase is not working when I use a real Apple ID, and I suspect that is the reason why my build got rejected. Is this because of Swifty?
@bizz84 I have the same issue. And the error return in result is .unkown
. But the users are billed by apple/ It doesn't occur on every purchaseProduct
but only sometimes.
@bizz84 Any news about this issue?
Apologies for the late reply everyone.
SwiftyStoreKit returns "Unknown error" when a transaction is .failed
, but there is no transaction error. According to the docs, this shouldn't happen though:
open class SKPaymentTransaction : NSObject {
// Only set if state is SKPaymentTransactionFailed
@available(iOS 3.0, *)
open var error: Error? { get }
}
SwiftyStoreKit only returns an error if a failed transaction shows up in the payment queue. So I'm inclined to think this is a problem in StoreKit or in your IAP setup in iTunes connect.
Also:
Are you calling completeTransactions()
on app startup?
If you don't you could get mixed up failed transactions that were pending before you started the new purchase (this typically results in the completion block called immediately after calling purchaseProduct()
).
I am experiencing the same issue. It works most of the time, but occasionally we get a user who is gets both a payment confirmation alert. and then immediately gets the unknown purchase error alert.
They insist that they are subscribed, are able to view the subscription in their phone settings, and have been billed.
Calling completeTransactions() on app start up.
What might be the issue in IAP setup in Itunes Connect? Especially if this is only an occasional problem?
I don't understand how both alerts could be shown. Where does that first success alert come from? It must be generated before verifying the receipt, because that happens inside the result from SwiftyStoreKit.purchaseProduct returned as .success.
So how am I getting both? How is it both successfully making the purchase, while also getting an error, before even verifying the receipt from the purchase?
The second is generated only if the result from SwiftyStoreKit.purchaseProduct returns as .error
SwiftyStoreKit.purchaseProduct(product, quantity: 1, atomically: true) { result in NetworkActivityIndicatorManager.networkOperationFinished()
switch result {
case .success(let product):
// fetch content from your server, then:
if product.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(product.transaction)
}
self.verifyPurchaseOfSubscription(purchase, completion: { result in
purchaseSuccessHandler(result)
}, verifyErrorHandler: { error in
verifyErrorHandler(error)
})
print("Purchase Success: \(product.productId)")
case .error(let error):
purchaseErrorHandler(error)
}
}
func alertForPurchaseError(error: SKError) -> UIAlertController {
switch error.code {
case .unknown:
Mixpanel.mainInstance().track(event: "Unknown Purchase Error", properties: ["userID" : self.userID])
return alertWithTitle(title: "Purchase failed", message: "Unknown error. Please contact support or try again in a moment.")
Also getting this error. Maybe it's a new bug introduced from Apple because the error delegate from StoreKit fires along with a success delegate like described in this post.. Just weird it work in test but not in production.
First: I've nothing to do with this project. Second: I've found this issue on google and I've noticed that the last post here is only 11 hours ago and right now I'm also facing an issue with the missing error object of a failed transaction object in a production environment...
So I guess its a new bug from Apple.
@RaimundWege did you discovered if it is a bug from apple?
Hi please if you got it working kindly assist with my issue https://github.com/bizz84/SwiftyStoreKit/issues/412
To solve that issue in my own store implementation I had to add a check for nil
. I thought that the transaction in the case of SKPaymentTransactionStateFailed
always provides an error object. But in some cases the error can be nil
and in my implementation I've added this nil
value to a dictionary... the solution was to add NSNull in that case: error ? error : [NSNull null]
.
I guess this happens when there are some old zombie transactions which were never finished correctly.
i am have the same error at the moment. the problem occurred suddenly.
@RaimundWege could you give as a more detailed explanation how you handled nil case?
It seems there are some problems at the Apple side. This issue happens all over the world
@shi-rudo I only check the error result directly after receiving the notification and when the error object is nil I replace it with [NSNull null]
:
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
[[ATLogger shared] logDebug:[NSString stringWithFormat:@"Running transactions: %lu", (unsigned long)queue.transactions.count]];
for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
case SKPaymentTransactionStatePurchased:
[self purchaseTransaction:transaction];
break;
case SKPaymentTransactionStateRestored:
[self restoreTransaction:transaction];
break;
case SKPaymentTransactionStateFailed:
[self failTransaction:transaction];
break;
case SKPaymentTransactionStatePurchasing:
break;
case SKPaymentTransactionStateDeferred:
break;
default:
break;
}
}
}
- (void)failTransaction:(SKPaymentTransaction *)transaction {
[[ATLogger shared] logError:[NSString stringWithFormat:@"ATStoreKitController fail transaction: %@", transaction.transactionIdentifier] withError:transaction.error];
[self postPurchaseFailureNotificationForIdentifier:transaction.payment.productIdentifier andError:transaction.error];
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
- (void)postPurchaseFailureNotificationForIdentifier:(NSString *)identifier andError:(NSError *)error {
NSDictionary *userInfo = @{kUserInfoProduct:[self productForIdentifier:identifier],
kUserInfoError:(error ? error : [NSNull null])}; // <--- CHECK FOR NIL HERE
[[NSNotificationCenter defaultCenter] postNotificationName:ATPurchaseFailureNotification object:identifier userInfo:userInfo];
}
I recommend to use logs for purchase process debugging.
Platform
In app purchase type
Environment
Not working in production but working in sandbox
When purchasing a subscription, it verifies the receipt correctly. Once it asks the user to buy the subscription I am getting a "Purchase Fail" error. Below is my code: