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

I receive a popup saying, "You already own this item." #2852

Open
Rohit-vinfotech opened this issue Sep 20, 2024 · 2 comments
Open

I receive a popup saying, "You already own this item." #2852

Rohit-vinfotech opened this issue Sep 20, 2024 · 2 comments

Comments

@Rohit-vinfotech
Copy link

Rohit-vinfotech commented Sep 20, 2024

Please use the Discussion board if you want to get some help. Please use issues to report bugs.

1726828222363

Description

I am facing an issue with consumable product purchases. When a user purchases an item and kills the app before receiving a response, the payment is completed, but the data is not retrieved from the available purchases and purchase history.

Expected Behavior

get response from purchase history and finish the transection

Screenshots

See the attachment

Environment:

  • react-native-iap:^12.15.2
  • react-native:0.70.3
  • Platforms (iOS, Android): Real device

To Reproduce
Steps to reproduce the behavior:

  1. When a user clicks on the "Buy Item" button with UPI.
  2. it opens the UPI app. After entering the UPI PIN.
  3. the payment is successful.
  4. and I immediately close both the payment app and my app.
  5. After some time, I reopen the app and do not get the purchase info from the purchase history and available purchases.
  6. When I attempt the payment again, I receive a popup saying, "You already own this item."

This is my code:

import { Platform } from "react-native";
import Auth from "../Auth";
import {
clearTransactionIOS, finishTransaction,
flushFailedPurchasesCachedAsPendingAndroid,
getAvailablePurchases, getPurchaseHistory,
requestPurchase
} from "react-native-iap";
import sendEventToWeb from "../SendEventToWeb/SendEventToWeb";

const IAP_function = async (productId, info) => {
let data = JSON.parse(info)
const params = Platform.select({
ios: {
sku: productId,
andDangerouslyFinishTransactionAutomaticallyIOS: false
},
android: {
skus: [productId]
}
});
try {
const currentPurchase = await requestPurchase(params);
if (currentPurchase) {
var dictJSON1 = {
...currentPurchase,
...data,
action: "inapppurchase_response",
device_type: Platform.OS == 'ios' ? '2' : '1',
packageName: 'com.my.app',
gotResponseFrom: 'Normal Flow'
};
console.log("Normal Flow ==>", dictJSON1);
sendEventToWeb(dictJSON1);
}

} catch (e) {
    handlePurchaseError(e, productId);
}

};

const handlePurchaseError = async (error, productId) => {
let data = await Auth.getItem(productId)
data = data != null ? JSON.parse(data) : { isCancelled: true }
var dictJSON1 = {
...data,
action: "inapppurchase_response",
device_type: Platform.OS == 'ios' ? '2' : '1',
packageName: 'com.my.app',
...error,
};
sendEventToWeb(dictJSON1);
await Auth.removeItem(productId)
};

const ClearTransections = async (purchase) => {
try {
if (purchase?.transactionId || purchase?.purchaseToken || Platform.OS == 'ios') {
console.log("finishTransaction purchase -=>> ", purchase)
await finishTransaction({ purchase: purchase, isConsumable: true });
await Auth.removeItem(purchase.productId)
flushTransactions()
}
else if (purchase["0"]) {
console.log("finishTransaction purchase[0] -=>> ", purchase["0"])
await finishTransaction({ purchase: purchase["0"], isConsumable: true });
await Auth.removeItem(purchase["0"].productId)
flushTransactions()
}
else if (purchase == null) {
availablePurchases()
}
} catch (e) {
console.log("Clear Transections Failure ==>", e);
}
}

const flushTransactions = async () => {
if (Platform.OS === "android") {
await flushFailedPurchasesCachedAsPendingAndroid();
} else {
await clearTransactionIOS();
}
};

const fetchPurchaseHistory = async () => {
try {
const purchaseHistory = await getPurchaseHistory();
if (purchaseHistory.length > 0) {
purchaseHistory?.map(async item => {
let data = await Auth.getItem(item.productId)
data = data != null ? JSON.parse(data) : { isCancelled: true }
var dictJSON1 = {
...item,
...data,
action: "inapppurchase_response",
device_type: Platform.OS == 'ios' ? '2' : '1',
packageName: 'com.my.app',
gotResponseFrom: 'From Purchase History'
};
if (!data.isCancelled) {
console.log("fetchPurchaseHistory==>", dictJSON1);
sendEventToWeb(dictJSON1);
}
})
}
} catch (error) {
console.error("Error fetching purchase history: ", error);
}
};

const availablePurchases = async (call = 0) => {
try {
const purchaseHistory = await getAvailablePurchases();
if (purchaseHistory.length > 0) {
purchaseHistory?.map(async item => {
let data = await Auth.getItem(item.productId)
data = data != null ? JSON.parse(data) : { isCancelled: true }
var dictJSON1 = {
...item,
...data,
action: "inapppurchase_response",
device_type: Platform.OS == 'ios' ? '2' : '1',
packageName: 'com.my.app',
gotResponseFrom: 'From available Purchases'
};
if (!data.isCancelled) {
console.log("availablePurchases==>", dictJSON1);
sendEventToWeb(dictJSON1);
}
})
} else {
console.log("No pending transactions found.");
if (call == 1) {
fetchPurchaseHistory()
} else {
flushTransactions()
}
}
} catch (error) {
console.error("Error fetching purchase history: ", error);
}
};

@cuchillitos
Copy link

I've already had this issue. My app crashed once after buying the product and before finishing the transaction. The fact that the transaction wasn't properly finished kept the item as an already owned non-consumable.

Hope it helps

@RouberR
Copy link

RouberR commented Sep 27, 2024

@cuchillitos How did you solve this problem?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants