[8.0.4][iOS] finishTransaction promise never finishes
See original GitHub issueVersion of react-native-iap
8.0.4
Version of react-native
0.67.2
Platforms you faced the error (IOS or Android or both?)
iOS
Expected behavior
calling finishTransaction marks the transaction as finished
Actual behavior
Any code after the await RNIap.finishTransaction
is not executed, and the transaction is reattempted after each relaunch of the app.
Tested environment (Emulator? Real Device?)
Real device
Steps to reproduce the behavior
Purchase a product in sandbox, call finishTransaction
, check if some code after the promise is executed.
Here is my listener:
purchaseUpdatedListener = RNIap.purchaseUpdatedListener(
async (purchase: RNIap.InAppPurchase | RNIap.SubscriptionPurchase) => {
const receipt = purchase.transactionReceipt;
try {
if (receipt) {
const decodedReceipt = await decodeAppleReceipt(receipt);
const isValid = await isSubValid(decodedReceipt);
if (isValid) {
const { latest_receipt_info: latestReceipts }: any = decodedReceipt;
const sortedReceiptInfo = latestReceipts.sort(
(
a: { original_purchase_date_ms: number },
b: { original_purchase_date_ms: number },
) => b.original_purchase_date_ms - a.original_purchase_date_ms,
);
let latestReceiptInfo = sortedReceiptInfo[sortedReceiptInfo.length - 1];
console.log(latestReceiptInfo);
const subPrice = await getSubPrice(latestReceiptInfo.product_id);
const subDuration = getSubDuration(latestReceiptInfo.product_id);
latestReceiptInfo = {
...latestReceiptInfo,
subscription_price: subPrice,
};
// Persist the purchase on backend API
const persistedPurchase = await persistSubscriptionIOS(latestReceiptInfo, sessionId);
const persistedPurchaseId: string = persistedPurchase.persistPurchase.id;
latestReceiptInfo = {
...latestReceiptInfo,
persisted_purchase_id: persistedPurchaseId,
source: 'ios',
subscription_duration: subDuration,
};
// Activate the subscription on backend API
const deliveryResult = await activateSubscription(latestReceiptInfo, sessionId);
if (isSuccess(deliveryResult)) {
console.log('deliveryResult is true');
await RNIap.finishTransaction(purchase, false);
console.log('finish transaction done');
onSuccess?.();
}
}
}
} catch (error) {
console.error(error);
}
},
);
The console.log
of finish transaction done
is never executed, neither my onSuccess
callback. However the console.log
before finishTransaction
is logged.
Issue Analytics
- State:
- Created 2 years ago
- Reactions:7
- Comments:41
Top Results From Across the Web
What should I do if finishTransact… | Apple Developer Forums
This indicates that finishTransaction worked. The transaction is finished, the purchase completed. If you try to buy a non-consumable IAP a second time...
Read more >ios - Unable to finish unfinished transactions in payment queue
The app will be repeatedly sent the payment queue notice until you call finish on it, giving you the opportunity to call [[SKPaymentQueue...
Read more >Untitled
Small bakken oil companies, Spice society elmers end reviews, Fairacres mansion omaha, ... Don trip long time coming, Billy and mandy season 3...
Read more >react-native native module for In App Purchase. - FlutterRepos
endConnection();. bug android. opened by umutpiri 45. [8.0.4][iOS] finishTransaction promise never finishes ...
Read more >react-native native module for In App Purchase. - BestofReactjs
initConnection(), Promise<boolean>, Init IAP module. ... opened by umutpiri 45. [8.0.4][iOS] finishTransaction promise never finishes ...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
This seems to be fixed for me in 8.0.5
I ended up just rewriting that function entirely
@objc public func finishTransaction( _ transactionIdentifier: String, resolve: @escaping RCTPromiseResolveBlock = { _ in }, reject: @escaping RCTPromiseRejectBlock = { _, _, _ in } ) { let queue = SKPaymentQueue.default() for transaction in queue.transactions { if transaction.transactionIdentifier == transactionIdentifier { if transaction.transactionState == .purchasing { print("transaction is purchasing still") } else { SKPaymentQueue.default().finishTransaction(transaction) resolve(nil) } } } }