Hi,
I would like to seek for support regarding to slow test card, approves after a few minutes. I would like to know how to get status success or failure after pending a few minutes.
Thank you,
- Community
- Get Help
- General Questions
- Pending Payment Listener Status
Pending Payment Listener Status
- April 23, 2024
- 2 replies
- 365 views
- New Member
- 1 reply
Best answer by kaitlin
Hey
I’d recommend either calling `getCustomerInfo` periodically or setting up a listener for changes to a customer’s purchase info: https://www.revenuecat.com/docs/customers/customer-info#listening-for-customerinfo-updates
2 replies
- RevenueCat Staff
- 423 replies
- Answer
- April 25, 2024
Hey
I’d recommend either calling `getCustomerInfo` periodically or setting up a listener for changes to a customer’s purchase info: https://www.revenuecat.com/docs/customers/customer-info#listening-for-customerinfo-updates
- Author
- New Member
- 1 reply
- April 26, 2024
Hello
Thank you so much for your answer, per check ‘getCustomerInfo’, it work for:
- “Test card, always approves” / “Slow test card, approves after a few minutes” and “Test card, always declines” but for “Slow test card, declines after a few minutes”, there is no response status of that case.
May you advise in this case?
Please kindly check the code below:
Future<void> makePurchase(context, String numberOfEgg) async {
Map<String, dynamic> payload = {};
List<Map<dynamic, dynamic>> filteredItems = [];
bool slowCardApproval = true;
try {
filteredItems =
filterById(numberOfEgg, Platform.isIOS ? products : googleProducts);
if (filteredItems.isNotEmpty && !isPurchasePending) {
ref.read(purchaseInProgressProvider.notifier).setInProgress(true);
payload = {
'identifier': filteredItems[0]['identifier'],
'description': filteredItems[0]['description'],
'title': filteredItems[0]['title'],
'price': filteredItems[0]['price'],
'priceString': filteredItems[0]['priceString'],
'currencyCode': filteredItems[0]['currencyCode']
};
final payloadGooglePay = {
'identifier': filteredItems[0]['identifier'],
'description': filteredItems[0]['description'],
'title': filteredItems[0]['title'],
'price': filteredItems[0]['price'],
'priceString': filteredItems[0]['priceString'],
'currencyCode': filteredItems[0]['currencyCode'],
'productCategory': 'NON_SUBSCRIPTION',
};
CustomerInfo customerInfo = await Purchases.purchaseStoreProduct(
Platform.isIOS
? StoreProduct.fromJson(payload)
: StoreProduct.fromJson(payloadGooglePay));
// Check if the purchase is active
if (customerInfo
.entitlements
.all[Platform.isIOS
? dotenv.env['REVENUECAT_ENTITLEMENTS_APPLE']
: dotenv.env['REVENUECAT_ENTITLEMENTS_GOOGLE']]!
.isActive) {
isPurchasePending =
false; // Set isPurchasePending to false when a purchase is confirmed
ref
.read(purchaseInProgressProvider.notifier)
.setInProgress(false); // Add this line
final titleValue = getTitlePurchase(payload['title']);
final titleKoValue = getTitleKoPurchase(payload['title']);
ref.read(bonusEggsHistoryProvider).memberBonusAttend(
memberId: memberInfo.id!,
bonusEggQty: int.parse(numberOfEgg),
type: 1,
title: titleValue,
titleKo: titleKoValue,
);
// Create a new instance of MemberModel with the updated purchasedEggs value
if (memberInfo.id != null) {
final updatedMemberInfo = memberInfo.copyWith(
purchasedEggs:
memberInfo.purchasedEggs! + int.parse(numberOfEgg));
// Update memberInfo immediately after purchase is successful
ref
.read(memberInfoProvider.notifier)
.updateState(updatedMemberInfo);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChargeUseHistoryScreen(
purchasedEgg: filteredItems[0]['id'],
purchaseSuccessful: true,
)),
).then((value) => {
ref.refresh(memberObjByIdProvider(memberInfo.id)),
ref.refresh(memberObjByIdProvider(eggMember!.id)),
ref.refresh(memberObjProvider),
ref.refresh(memberInfoProvider),
ref.refresh(bonusEggsHistoryProvider),
ref.refresh(memberObjByIdProvider(memberInfo.id ?? 0)),
ref.refresh(usageEggHistoryFutureProvider(memberInfo.id!)),
ref.refresh(
purchasedEggHistoryFutureProvider(memberInfo.id!)),
ref.refresh(loadingProvider),
});
}
debugPrint('Purchase successful########################');
}
}
} catch (e) {
debugPrint('Purchase failed with error++++++++++++++++++: $e');
if (e is PlatformException) {
if (e.code == '3' || e.code == '1') {
isPurchasePending = false;
ref.read(purchaseInProgressProvider.notifier).setInProgress(false);
slowCardApproval = false;
Purchases.addCustomerInfoUpdateListener((customerInfo) async {
var entitlements = customerInfo.entitlements.all;
if (entitlements.isEmpty) {
slowCardApproval = false;
} else {
var latestPurchaseDate =
entitlements.values.first.latestPurchaseDate;
SharedPreferences prefs = await SharedPreferences.getInstance();
String? savedDate = prefs.getString('latestPurchaseDate');
if (savedDate != null &&
savedDate != latestPurchaseDate.toString()) {
slowCardApproval = false;
}
}
});
}
if (e.code == '20') {
slowCardApproval = true;
}
}
if (slowCardApproval) {
Purchases.addCustomerInfoUpdateListener((customerInfo) async {
var entitlements = customerInfo.entitlements.all;
debugPrint('entitlements*********************: $entitlements');
if (entitlements.isNotEmpty) {
var latestPurchaseDate =
entitlements.values.first.latestPurchaseDate;
SharedPreferences prefs = await SharedPreferences.getInstance();
String? savedDate = prefs.getString('latestPurchaseDate');
debugPrint(
'latestPurchaseDate*********************: $latestPurchaseDate');
debugPrint('savedDate*********************: $savedDate');
if (savedDate != null &&
savedDate != latestPurchaseDate.toString()) {
if (customerInfo
.entitlements
.all[Platform.isIOS
? dotenv.env['REVENUECAT_ENTITLEMENTS_APPLE']
: dotenv.env['REVENUECAT_ENTITLEMENTS_GOOGLE']]!
.isActive) {
isPurchasePending =
false; // Set isPurchasePending to false when a purchase is confirmed
ref
.read(purchaseInProgressProvider.notifier)
.setInProgress(false); // Add this line
final titleValue = getTitlePurchase(payload['title']);
final titleKoValue = getTitleKoPurchase(payload['title']);
ref.read(bonusEggsHistoryProvider).memberBonusAttend(
memberId: memberInfo.id!,
bonusEggQty: int.parse(numberOfEgg),
type: 1,
title: titleValue,
titleKo: titleKoValue,
);
// Create a new instance of MemberModel with the updated purchasedEggs value
if (memberInfo.id != null) {
final updatedMemberInfo = memberInfo.copyWith(
purchasedEggs:
memberInfo.purchasedEggs! + int.parse(numberOfEgg));
// Update memberInfo immediately after purchase is successful
ref
.read(memberInfoProvider.notifier)
.updateState(updatedMemberInfo);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChargeUseHistoryScreen(
purchasedEgg: filteredItems[0]['id'],
purchaseSuccessful: true,
)),
).then((value) => {
ref.refresh(memberObjByIdProvider(memberInfo.id)),
ref.refresh(memberObjByIdProvider(eggMember!.id)),
ref.refresh(memberObjProvider),
ref.refresh(memberInfoProvider),
ref.refresh(bonusEggsHistoryProvider),
ref.refresh(
memberObjByIdProvider(memberInfo.id ?? 0)),
ref.refresh(
usageEggHistoryFutureProvider(memberInfo.id!)),
ref.refresh(purchasedEggHistoryFutureProvider(
memberInfo.id!)),
ref.refresh(loadingProvider),
});
ref
.read(purchaseInProgressProvider.notifier)
.setInProgress(false);
}
debugPrint('Purchase successful########################');
}
}
await prefs.setString(
'latestPurchaseDate', latestPurchaseDate.toString());
}
});
}
}
}
Hi,
I would like to seek for support regarding to slow test card, approves after a few minutes. I would like to know how to get status success or failure after pending a few minutes.
Thank you,
Hey
I’d recommend either calling `getCustomerInfo` periodically or setting up a listener for changes to a customer’s purchase info: https://www.revenuecat.com/docs/customers/customer-info#listening-for-customerinfo-updates
Hello
Thank you so much for your answer, per check ‘getCustomerInfo’, it work for:
- “Test card, always approves” / “Slow test card, approves after a few minutes” and “Test card, always declines” but for “Slow test card, declines after a few minutes”, there is no response status of that case.
May you advise in this case?
Please kindly check the code below:
Future<void> makePurchase(context, String numberOfEgg) async {
Map<String, dynamic> payload = {};
List<Map<dynamic, dynamic>> filteredItems = m];
bool slowCardApproval = true;
try {
filteredItems =
filterById(numberOfEgg, Platform.isIOS ? products : googleProducts);
if (filteredItems.isNotEmpty && !isPurchasePending) {
ref.read(purchaseInProgressProvider.notifier).setInProgress(true);
payload = {
'identifier': filteredItems 0]d'identifier'],
'description': filteredItems'0]s'description'],
'title': filteredItems 0] 'title'],
'price': filteredItems 0] 'price'],
'priceString': filteredItems'0]i'priceString'],
'currencyCode': filteredItemsc0]r'currencyCode']
};
final payloadGooglePay = {
'identifier': filteredItems 0]d'identifier'],
'description': filteredItems'0]s'description'],
'title': filteredItems 0] 'title'],
'price': filteredItems 0] 'price'],
'priceString': filteredItems'0]i'priceString'],
'currencyCode': filteredItemsc0]r'currencyCode'],
'productCategory': 'NON_SUBSCRIPTION',
};
CustomerInfo customerInfo = await Purchases.purchaseStoreProduct(
Platform.isIOS
? StoreProduct.fromJson(payload)
: StoreProduct.fromJson(payloadGooglePay));
// Check if the purchase is active
if (customerInfo
.entitlements
.allePlatform.isIOS
? dotenv.env 'REVENUECAT_ENTITLEMENTS_APPLE']
: dotenv.env 'REVENUECAT_ENTITLEMENTS_GOOGLE']]!
.isActive) {
isPurchasePending =
false; // Set isPurchasePending to false when a purchase is confirmed
ref
.read(purchaseInProgressProvider.notifier)
.setInProgress(false); // Add this line
final titleValue = getTitlePurchase(payloade'title']);
final titleKoValue = getTitleKoPurchase(payload='title']);
ref.read(bonusEggsHistoryProvider).memberBonusAttend(
memberId: memberInfo.id!,
bonusEggQty: int.parse(numberOfEgg),
type: 1,
title: titleValue,
titleKo: titleKoValue,
);
// Create a new instance of MemberModel with the updated purchasedEggs value
if (memberInfo.id != null) {
final updatedMemberInfo = memberInfo.copyWith(
purchasedEggs:
memberInfo.purchasedEggs! + int.parse(numberOfEgg));
// Update memberInfo immediately after purchase is successful
ref
.read(memberInfoProvider.notifier)
.updateState(updatedMemberInfo);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChargeUseHistoryScreen(
purchasedEgg: filteredItems 0]r'id'],
purchaseSuccessful: true,
)),
).then((value) => {
ref.refresh(memberObjByIdProvider(memberInfo.id)),
ref.refresh(memberObjByIdProvider(eggMember!.id)),
ref.refresh(memberObjProvider),
ref.refresh(memberInfoProvider),
ref.refresh(bonusEggsHistoryProvider),
ref.refresh(memberObjByIdProvider(memberInfo.id ?? 0)),
ref.refresh(usageEggHistoryFutureProvider(memberInfo.id!)),
ref.refresh(
purchasedEggHistoryFutureProvider(memberInfo.id!)),
ref.refresh(loadingProvider),
});
}
debugPrint('Purchase successful########################');
}
}
} catch (e) {
debugPrint('Purchase failed with error++++++++++++++++++: $e');
if (e is PlatformException) {
if (e.code == '3' || e.code == '1') {
isPurchasePending = false;
ref.read(purchaseInProgressProvider.notifier).setInProgress(false);
slowCardApproval = false;
Purchases.addCustomerInfoUpdateListener((customerInfo) async {
var entitlements = customerInfo.entitlements.all;
if (entitlements.isEmpty) {
slowCardApproval = false;
} else {
var latestPurchaseDate =
entitlements.values.first.latestPurchaseDate;
SharedPreferences prefs = await SharedPreferences.getInstance();
String? savedDate = prefs.getString('latestPurchaseDate');
if (savedDate != null &&
savedDate != latestPurchaseDate.toString()) {
slowCardApproval = false;
}
}
});
}
if (e.code == '20') {
slowCardApproval = true;
}
}
if (slowCardApproval) {
Purchases.addCustomerInfoUpdateListener((customerInfo) async {
var entitlements = customerInfo.entitlements.all;
debugPrint('entitlements*********************: $entitlements');
if (entitlements.isNotEmpty) {
var latestPurchaseDate =
entitlements.values.first.latestPurchaseDate;
SharedPreferences prefs = await SharedPreferences.getInstance();
String? savedDate = prefs.getString('latestPurchaseDate');
debugPrint(
'latestPurchaseDate*********************: $latestPurchaseDate');
debugPrint('savedDate*********************: $savedDate');
if (savedDate != null &&
savedDate != latestPurchaseDate.toString()) {
if (customerInfo
.entitlements
.allrPlatform.isIOS
? dotenv.env 'REVENUECAT_ENTITLEMENTS_APPLE']
: dotenv.env 'REVENUECAT_ENTITLEMENTS_GOOGLE']]!
.isActive) {
isPurchasePending =
false; // Set isPurchasePending to false when a purchase is confirmed
ref
.read(purchaseInProgressProvider.notifier)
.setInProgress(false); // Add this line
final titleValue = getTitlePurchase(payloade'title']);
final titleKoValue = getTitleKoPurchase(payload='title']);
ref.read(bonusEggsHistoryProvider).memberBonusAttend(
memberId: memberInfo.id!,
bonusEggQty: int.parse(numberOfEgg),
type: 1,
title: titleValue,
titleKo: titleKoValue,
);
// Create a new instance of MemberModel with the updated purchasedEggs value
if (memberInfo.id != null) {
final updatedMemberInfo = memberInfo.copyWith(
purchasedEggs:
memberInfo.purchasedEggs! + int.parse(numberOfEgg));
// Update memberInfo immediately after purchase is successful
ref
.read(memberInfoProvider.notifier)
.updateState(updatedMemberInfo);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChargeUseHistoryScreen(
purchasedEgg: filteredItems 0]r'id'],
purchaseSuccessful: true,
)),
).then((value) => {
ref.refresh(memberObjByIdProvider(memberInfo.id)),
ref.refresh(memberObjByIdProvider(eggMember!.id)),
ref.refresh(memberObjProvider),
ref.refresh(memberInfoProvider),
ref.refresh(bonusEggsHistoryProvider),
ref.refresh(
memberObjByIdProvider(memberInfo.id ?? 0)),
ref.refresh(
usageEggHistoryFutureProvider(memberInfo.id!)),
ref.refresh(purchasedEggHistoryFutureProvider(
memberInfo.id!)),
ref.refresh(loadingProvider),
});
ref
.read(purchaseInProgressProvider.notifier)
.setInProgress(false);
}
debugPrint('Purchase successful########################');
}
}
await prefs.setString(
'latestPurchaseDate', latestPurchaseDate.toString());
}
});
}
}
}
Most helpful members this week
- waaihong
3 upvotes
- jeffrey_bunn
3 upvotes
- moses-harding-47a762
1 upvote
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.
Scanning file for viruses.
Sorry, we're still checking this file's contents to make sure it's safe to download. Please try again in a few minutes.
OKThis file cannot be downloaded
Sorry, our virus scanner detected that this file isn't safe to download.
OKCookie policy
We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.
Cookie settings
We use 3 different kinds of cookies. You can choose which cookies you want to accept. We need basic cookies to make this site work, therefore these are the minimum you can select. Learn more about our cookies.