Testing Use Cases
Test Cases
This document provides a bunch of key use cases that you can use to verify the successful integration of RevenueCat into your apps. It outlines essential steps and checks to ensure that in-app purchases, subscriptions, and other revenue-related features are functioning as expected as well as helps you take advantage of the many tools that RevenueCat offers. By following these use cases, you can confidently validate your setup and troubleshoot any issues that may arise prior to launching your app.
Subscription Lifecycle
Purchase Flow
Description: Verify that a user's purchase flow works correctly. For subscriptions, this includes starting a subscription, having the subscription renew, and letting the subscription expire.
Related docs:
Preconditions: App installed, Ensure the device is logged into an account that will make sandbox purchases and RevenueCat configured.
Steps:
- Open the App.
- Open your Paywall or purchase modal.
- Select the product that you would like to test.
- Purchase the product.
- Open up the RevenueCat overview page and check to see if you see a recent purchase for this product with the App User ID of the user that you configured the SDK with.
Expected Results: Purchase goes through successfully, the user has the entitlement, and you are able to see the purchase in the RevenueCat dashboard.
Pass/Fail Criteria: Purchase is seen on the RevenueCat dashboard.
Refund
Description: Use this test guide to verify that you are able to issue a refund for a user and that your app handles refunds gracefully.
Related docs:
Preconditions: App installed, App User ID already has a subscription or purchase.
Steps:
Google Play:
- Open the RevenueCat dashboard for the App User ID that you are testing with that has a current subscription.
- Navigate to the user's purchase event that you would like to refund.
- Click the refund button in the top right corner of the event details.
- Verify that the refund has happened by checking the customer history of this user 24 hours later and ensuring that a
CANCELLATION
event has occurred with the reason field set toCUSTOMER_SUPPORT
.
iOS:
- When a user tries to issue a refund, verify that you immediately direct them to the Apple support page: https://support.apple.com/en-us/HT204084
- Once a user gets a refund granted through Apple, verify that the refund has been seen by us by checking the customer history of this user 24 hours later and ensuring that a
CANCELLATION
event has occurred with the reason field set toCUSTOMER_SUPPORT
.
Since granting refunds is done through the App Store themselves, testing this in the sandbox environment is not currently possible
Expected Results:
- Users are able to request a refund
- For Google Play, you are able to grant the refund via the Dashboard or API
- For iOS, you direct them to Apple customer support
Pass/Fail Criteria: Verify that the refund is seen in RevenueCat in the CANCELLATION
event.
Cancellation
Description: To test that cancellation events work properly, use this test guide.
Related docs:
Preconditions: App installed, RevenueCat configured, and current subscription on App User ID.
Steps:
- Open the app with an App User ID that already has a subscription.
- Ensure that the subscription is renewed properly.
- Cancel the subscription through the settings on your device or through our API for purchases made on Google Play.
- Verify that the user has received a
CANCELLATION
event on their RevenueCat customer history. We will send this event as soon as the cancellation has started, the actual expiration event will come as soon as the current subscription period ends.
Expected Results: Subscription is canceled successfully and we trigger the cancellation event on time.
Pass/Fail Criteria: Subscription is canceled and the cancellation event is in the customer history.
Expiration
Description: To verify that a user's subscription has expired, use this test guide.
Related docs:
Preconditions: App installed, App User ID has a current subscription.
Steps:
- Open the app.
- Navigate to your paywall or subscription page and cancel the current subscription.
- Wait until your current subscription's expiration time and check to ensure that once this time hits the user no longer has access to their entitlements.
- To verify, check the RevenueCat dashboard of the user for an
EXPIRATION
event at the time of the expiration.
Expected Results: Expected Results: The user loses access to the entitlement at the end of the current billing cycle and an EXPIRATION
event follows at the time of expiration.
Pass/Fail Criteria: Verify that the user no longer has access to the entitlement after the expiration has been triggered.
Upgrades and Downgrades
Description: If you have multiple subscription tiers and want to allow people to upgrade/downgrade between them, follow this testing method to ensure everything is working as intended.
Related docs:
Preconditions: App installed, subscription groups set up properly in App Store Connect, and the current logged-in App User ID has a subscription.
Steps:
- Open the app with an app user that already has a subscription.
- Open the subscription page or paywall in your app.
- Start a purchase for a subscription that would be an upgrade.
- Check the RevenueCat dashboard for that App User ID and ensure that you see a
PRODUCT_CHANGE
event. - Check the
PRODUCT_CHANGE
event to see that the old product is the correct product and the new product is the correct product that you selected.
Expected Results: New subscription starts and old subscription ends.
Pass/Fail Criteria:
- Google Play: The new subscription is started on time based on the
PRORATION
method that you use. - iOS: The new subscription is started on time based on Apple's timing for whether this was an upgrade, downgrade, or crossgrade.
Free Trials and Introductory offers
Description: If you are using free trials and/or intro offers, use this testing method to ensure that eligible users are granted them accordingly.
Related docs:
Preconditions: App installed, RevenueCat configured, fresh App User ID created with a new store account, and initial purchases working.
Steps:
- Open the app with a fresh sandbox user.
- Make sure the paywall and paysheet show the free trial and terms.
- Purchase the product with the free trial attached.
- Open that App User ID's customer history in RevenueCat.
- Verify that the purchase event has a free trial by checking to ensure the
period_type
in their purchase was set toTRIAL
. If you are checking for an intro offer, ensure that theperiod_type
isINTRO
.
Expected Results: The customer history indicates that a trial was started or an intro offer was applied.
Pass/Fail Criteria: Subscription is started with the proper offer applied.
Google Offers
Description: Test Google Play offers using the RevenueCat SDK, including automatic application of trials and introductory offers, and manual offer selection for greater control. This includes verifying the correct application of eligible offers based on pre-defined logic and ensuring that developer-determined offers are handled appropriately.
Related Docs
Preconditions:
- The RevenueCat SDK is integrated into the app.
- Google Play base plans and offers are set up, including free trials, introductory offers, and any developer-determined offers.
- The app has purchase functionality implemented via the RevenueCat SDK.
Example Code:
// Example code to select specific offers:
val basePlan = storeProduct.subscriptionOptions?.basePlan
val freeTrialOffer = storeProduct.subscriptionOptions?.freeTrial
val introductoryOffer = storeProduct.subscriptionOptions?.introOffer
val offerForLapsedCustomers = storeProduct.subscriptionOptions?.withTag("lapsed-customers").first()
// To purchase the offer for lapsed customers directly:
Purchases.sharedInstance.purchaseWith(
PurchaseParams.Builder(requireActivity(), offerForLapsedCustomers).build(),
onError = { error, userCancelled ->
// Handle error
},
onSuccess = { storeTransaction, customerInfo ->
// Handle success
}
)
Steps:
-
Automatic Application of Offers
- Use
PurchaseParams.Builder
with aStoreProduct
orPackage
. - Verify that the RevenueCat SDK applies the longest eligible free trial or, if not available, the cheapest introductory offer.
- Use
-
Handling Developer-Determined Offers
- Set up a developer-determined offer on the Google Play Console.
- Ensure the offer is tagged with
rc-ignore-offer
if it should not be automatically applied. - Test purchasing a product and verify that the tagged offer is not automatically selected.
-
Manual Offer Selection
- Use the
subscriptionOptions
property of aStoreProduct
to manually select offers, such as thebasePlan
,freeTrial
, or offers with specific tags. - Pass the selected
SubscriptionOption
toPurchaseParams.Builder
and initiate the purchase. - Confirm that the selected offer is correctly applied during the purchase process.
- Use the
Expected Results:
-
Automatic Application of Offers:
- The longest eligible free trial or the cheapest introductory offer is automatically applied as per the defined logic.
-
Handling Developer-Determined Offers:
- Offers with the
rc-ignore-offer
tag are not automatically applied, and developer-determined offers are handled according to the set up in the Google Play Console.
- Offers with the
-
Manual Offer Selection:
- The purchase uses the manually selected
SubscriptionOption
, correctly applying the intended offer, such as a specific introductory offer or base plan.
- The purchase uses the manually selected
Pass/Fail Criteria:
-
Pass: Offers are applied according to the expected logic, with correct handling of automatic and manual selections, and developer-determined offers are not unintentionally applied.
-
Fail: If the SDK incorrectly applies offers, fails to respect the
rc-ignore-offer
tag, or does not apply the manually selected offer, the test fails.
Configuration
Anonymous App User ID Configuration
Description: Verify that the user had been successfully configured with the SDK with the anonymous App User ID
Preconditions: App installed, Sandbox environment enabled, RevenueCat debug logs enabled and RevenueCat configure()
called without App User ID.
Example Code:
- Swift
- Obj-C
- Kotlin
- Kotlin Multiplatform
- Java
- Flutter
- React Native
- Cordova
- Capacitor
- Unity
Purchases.configure(withAPIKey: <my_api_key>)
[RCPurchases configureWithAPIKey:@<my_api_key>];
Purchases.configure(PurchasesConfiguration.Builder(this, <api_key>).build())
Purchases.configure(apiKey = "<api_key>")
Purchases.configure(new PurchasesConfiguration.Builder(context, <api_key>).build());
await Purchases.configure(PurchasesConfiguration(<public_sdk_key>));
Purchases.configure({apiKey: <public_sdk_key>});
Purchases.configureWith({ apiKey: <public_sdk_key> });
Purchases.configure({ apiKey: <public_sdk_key> });
// The SDK can be configured through the Unity Editor.
// See Unity installation instructions https://docs.revenuecat.com/docs/unity
// If you'd like to do it programmatically instead,
// make sure to check "Use runtime setup" in the Editor and then:
Purchases.PurchasesConfiguration.Builder builder = Purchases.PurchasesConfiguration.Builder.Init("api_key");
Purchases.PurchasesConfiguration purchasesConfiguration = builder.Build();
purchases.Configure(purchasesConfiguration);
Steps:
- Open the App.
- Open your RevenueCat debug logs.
- You should see [Purchases] - DEBUG: 👤 Initial App User ID - $RCAnonymousID:9be80d6558664c649fc0be8d00c5113a
- In the CustomerInfo Object you should see the anonymous ID under Original App User ID
Expected Results: An Anonymous ID is successfully attributed to the customer
Pass/Fail Criteria: Anonymous User is seen on the RevenueCat dashboard, debug logs and CustomerInfo Object.
Identified App User ID Configuration
Description: Verify that the user had been successfully configured with the SDK with the Identified App User ID
Related Docs Identifying Users
Preconditions: App installed, Sandbox environment enabled, RevenueCat debug logs enabled and RevenueCat configure()
called without App User ID.
Example Code:
- Swift
- Obj-C
- Kotlin
- Kotlin Multiplatform
- Java
- Flutter
- React Native
- Cordova
- Capacitor
- Unity
Purchases.configure(withAPIKey: <my_api_key>, appUserID: <my_app_user_id>)
[RCPurchases configureWithAPIKey:@<my_api_key> appUserID:@<my_app_user_id>];
Purchases.configure(PurchasesConfiguration.Builder(this, <api_key>).appUserID(<my_app_user_id>).build())
Purchases.configure(apiKey = "<api_key>") {
appUserId = "<app_user_id>"
}
Purchases.configure(new PurchasesConfiguration.Builder(context, <api_key>).appUserID(<my_app_user_id>).build());
await Purchases.configure(
PurchasesConfiguration(<public_sdk_key>)
..appUserID = <my_app_user_id>
);
Purchases.configure({apiKey: <public_sdk_key>, appUserID: <my_app_user_id>});
Purchases.configureWith({ apiKey: <public_sdk_key>, appUserID: <my_app_user_id> });
await Purchases.configure({ apiKey: <public_sdk_key>, appUserID: <my_app_user_id> });
// The appUserID can be set through the Unity Editor.
// See Unity installation instructions https://docs.revenuecat.com/docs/unity
// If you'd like to do it programmatically instead,
// make sure to check "Use runtime setup" in the Editor and then:
Purchases.PurchasesConfiguration.Builder builder = Purchases.PurchasesConfiguration.Builder.Init("api_key");
Purchases.PurchasesConfiguration purchasesConfiguration =
builder.SetUserDefaultsSuiteName("user_default")
.SetDangerousSettings(new Purchases.DangerousSettings(false))
.SetObserverMode(true)
.SetUseAmazon(false)
.SetAppUserId(appUserId)
.Build();
purchases.Configure(purchasesConfiguration);
Steps:
- Open the App.
- Open your RevenueCat debug logs.
- You should see [Purchases] - DEBUG: 👤 Initial App User ID - [my_app_user_id]
- In the CustomerInfo Object you should see the Identified ID under Original App User ID
Expected Results: An Identified ID is successfully attributed to the customer
Pass/Fail Criteria: Identified User is seen on the RevenueCat dashboard, debug logs, and CustomerInfo Object.
Display Offering Flow
Description: Test the functionality of displaying products and offerings using the RevenueCat SDK, including fetching offerings, handling placements, and displaying packages based on various configurations. This ensures that products are dynamically presented to users without requiring app updates and that the SDK's offerings configuration works as expected.
Related Docs
Preconditions:
- The RevenueCat SDK is integrated into the app.
- Offerings are configured in the RevenueCat dashboard. * The app's paywalls are set up to display offerings and packages.
Example Code:
// Fetching Offerings
Purchases.shared.getOfferings { (offerings, error) in
if let packages = offerings?.current?.availablePackages {
self.display(packages)
}
}
// Fetching Offerings by Placement
Purchases.shared.getOfferings { offerings, error in
if let offering = offerings?.currentOffering(forPlacement: "your-placement-identifier") {
// TODO: Show paywall
} else {
// TODO: Do nothing or continue on to next view
}
}
// Fetching Custom Offering by Identifier
Purchases.shared.getOfferings { (offerings, error) in
if let packages = offerings?.offering(identifier: "experiment_group")?.availablePackages {
self.display(packages)
}
}
Steps:
-
Launch the app and configure the SDK
- Start by launching the app and configuring the SDK.
-
Fetch Offerings
- Use the
getOfferings()
method to fetch the current offerings configured in the RevenueCat dashboard. - Verify that the default offering and its available packages are displayed correctly.
- Use the
-
Fetch Offerings by Placement
- Use
getCurrentOffering(forPlacement: "your-placement-identifier")
to fetch offerings based on a specific placement. - Check that the correct offering is displayed based on the placement identifier if user fulfills your targeting rules.
- Use
-
Fetch Custom Offering by Identifier
- Fetch a specific offering using its identifier (e.g.,
"experiment_group"
). - Verify that the correct packages associated with the custom offering are displayed.
- Fetch a specific offering using its identifier (e.g.,
-
Display Packages
- Use the
.availablePackages
property on an offering to display the available packages. - Verify that the packages are grouped correctly according to type (e.g., monthly, annual).
- Use the
Expected Results:
-
Fetch Offerings:
- The SDK fetches the current offerings correctly, and the associated packages are displayed to the user.
-
Fetch Offerings by Placement:
- The correct offering is fetched and displayed based on the specified placement identifier.
-
Fetch Custom Offering by Identifier:
- The SDK correctly retrieves and displays the custom offering identified by its unique identifier.
-
Display Packages:
- Packages are displayed accurately, reflecting the appropriate grouping and type (monthly, annual, etc.).
Pass/Fail Criteria:
-
Pass: Each scenario behaves as expected, with correct updates to the SDK and no unintended behavior.
-
Fail: If any scenario does not behave as expected—such as incorrect fetching, failure to display offerings, or incorrect handling of empty states—the test fails.
Login/Logout Flow
Description: Test the login behavior in the RevenueCat SDK to ensure that custom and anonymous App User IDs are handled correctly. This includes verifying the merging and switching of IDs and ensuring correct behavior when logging out and logging back in.
Related Docs
Preconditions:
- The RevenueCat SDK is integrated into the app.
- A unique custom App User ID is available for testing.
- The app's authentication system manages App User IDs.
Example Code:
// Log In with Custom App User ID:
// Configure Purchases on app launch
Purchases.configure(withAPIKey: <my_api_key>)
// Log in with a custom App User ID
Purchases.shared.logIn("<my_app_user_id>") { (customerInfo, created, error) in
// customerInfo updated for my_app_user_id
}
// Log Out:
// Log out the current user
Purchases.shared.logOut()
// Log In with Another Custom App User ID:
// Log in with another custom App User ID
Purchases.shared.logIn("<another_app_user_id>") { (customerInfo, created, error) in
// customerInfo updated for another_app_user_id
}
Steps:
-
Launch the app and configure the SDK
- Start by configuring the SDK without providing an App User ID to generate an anonymous ID.
-
Log in with a custom App User ID
- Use the
.logIn("<my_app_user_id>")
method to log in with a custom App User ID. This should also result in the new app user ID being aliased with the anonymous app user ID. - Verify that the
customerInfo
object reflects the custom App User ID.
- Use the
-
Log out of the current user
- Call the
.logOut()
method to log out. - Confirm that a new anonymous App User ID is generated.
- Call the
-
Log in again with a different custom App User ID
- Use the
.logIn("<another_app_user_id>")
method. - Check that the
customerInfo
updates to the new custom App User ID without merging data from the previous session.
- Use the
-
Switch accounts without logging out
- Directly call the
.logIn()
method with another App User ID without first logging out. - Ensure the
customerInfo
correctly switches to the new App User ID without unintended merging.
- Directly call the
Expected Results:
-
Initial Log In with Custom App User ID:
- The
customerInfo
object should correctly reflect the custom App User ID (<my_app_user_id>
), showing the associated subscription status and purchase history.
- The
-
Log Out:
- A new anonymous App User ID should be generated, and the
customerInfo
should no longer be associated with the previous custom App User ID.
- A new anonymous App User ID should be generated, and the
-
Log In After Log Out:
- Logging in with a different custom App User ID (
<another_app_user_id>
) should update thecustomerInfo
object to reflect this new ID, with no data merged from the previous session unless necessary for a restore or similar operation.
- Logging in with a different custom App User ID (
-
Switching Accounts:
- When switching from one custom App User ID to another, the
customerInfo
should update to reflect the new custom App User ID without merging.
- When switching from one custom App User ID to another, the
-
Anonymous to Custom App User ID:
- When logging in from an anonymous ID to a custom App User ID, the SDK should merge or transfer
customerInfo
correctly, depending on the presence of existing aliases or prior configurations. If the custom ID already exists, ensure the correct merging logic is applied.
- When logging in from an anonymous ID to a custom App User ID, the SDK should merge or transfer
Pass/Fail Criteria:
- Pass: Each scenario behaves as expected, with correct updates to the
customerInfo
object and no unintended merges or data loss. - Fail: If any scenario does not behave as expected—such as incorrect merging, failure to update
customerInfo
, or retention of previous IDs—the test fails.
Restoring Flow
syncpurchase() or purchase under different account
Description: To ensure that you are syncing purchases correctly and that a transfer event happens, follow this test guide.
Related docs:
Preconditions: App installed, two App User IDs, The first App User ID has a current subscription, and the other App User ID has no subscription.
Steps:
- Open the app with the currently subscribed App User ID.
- Close the app, and create a new App User ID.
- Open the app with the new App User ID that previously didn't have a subscription.
- If you are calling
syncPurchases()
on app launch, this user should have gotten the subscription and entitlements transferred on app launch. - Test to see if you can access your paid content.
- Verify that the transfer happened by checking the new App User ID's customer history and looking for a
TRANSFER
event.
Expected Results: Subscription and entitlements are transferred to the new App User ID.
Pass/Fail Criteria: Fresh App User ID is able to access paid content without paying for a new subscription.
Restoring Purchases (Transfer to new App User ID)
Description: To ensure that your transfer behavior is working correctly, follow this test guide.
Related docs:
Preconditions: App installed, Two App User IDs, The first App User ID has a current subscription, and the other App User ID has no subscription.
Steps:
- Open the app with the currently subscribed app user ID and verify this user has access to paid content.
- Close the app, and create a new app user ID.
- Open the app with the new app user ID that previously did not have a subscription.
- Navigate to your payment screen and hit your "Restore Purchases" button.
- If this works, you should now gain access to paid content that was previously attached to the other app user ID.
- Verify that the transfer happened by checking the new app user ID's customer history and looking for a
TRANSFER
event.
Expected Results: Subscription and entitlements are transferred to the new app user ID.
Pass/Fail Criteria: Fresh app user ID is able to access paid content without paying for a new subscription.
Restoring Purchases (Transfer if there are no active subscriptions)
Description: To ensure that your transfer behavior is working correctly, follow this test guide.
Related docs:
Preconditions: App installed, three App User IDs, first App User ID has a current subscription, second App User ID has no subscription, and the third App User ID has a subscription to the same product.
Steps:
- Open the app with the currently subscribed app user ID and verify this user has access to paid content.
- Open the app with the second app user ID that previously did not have a subscription.
- Navigate to your payment screen and hit your "Restore Purchases" button.
- If this works, you should now gain access to paid content that was previously attached to the other app user ID.
- Verify that the transfer happened by checking the new app user ID's customer history and looking for a
TRANSFER
event. - Open the app again
- Login to your app user ID which already has an active subscription.
- Navigate to your payment screen and hit your "Restore Purchases" button.
- You should now see an error message stating that we can't restore this purchase.
- Verify that no
TRANSFER
event happened on the third app user ID's customer history.
Expected Results: Subscription and entitlements are transferred to the second app user ID. The third app user ID is not able to restore purchases as they already previously have a subscription.
Pass/Fail Criteria: Transfer events are sent and the allowing/blocking of transfers works as intended.
Restoring Purchases (Keep with original App User ID)
Description: To ensure that your transfer behavior is working correctly, follow this test guide.
Related docs:
Preconditions: App installed, two app user IDs, the first app user ID has a subscription, the second one does not.
Steps:
- Open the app. login with the first app user ID and verify this user has access to paid content.
- Close the app and reopen the app.
- Login with the second app user ID. Make sure you are logged into the same store account.
- Navigate to the purchase page in your app and try to restore purchases.
- You should now see an error message when restoring because this purchase belongs to the other app user ID.
- Attempt to start a subscription on that same app user ID.
- You should now see an error message when restoring because this purchase belongs to the other app user ID.
- Verify that no
TRANSFER
event happened on the second app user ID's customer history.
Expected Results: Subscription and entitlements are not transferred to the second app user ID. This user is also not able to make a purchase while logged in with the same store account.
Pass/Fail Criteria: Purchases stay with the original user that made them and do not transfer to other users.
Restoring Purchases (Share between App User IDs (legacy))
Description: To ensure that your transfer behavior is working correctly, follow this test guide.
Related docs:
Preconditions: App installed, two app user IDs, the first app user ID has a subscription, the second one does not.
Steps:
- Open the app with the first app user ID.
- Ensure that this user has access to entitlements and paid content.
- Close the app and reopen the app.
- Login with the second app user ID.
- Verify that you currently don't have any access to paid content or entitlements.
- Navigate to the purchase page in your app and try to restore purchases.
- Once the restore happens, verify that you now have access to paid content/entitlements.
- Open the RevenueCat dashboard of the new app user ID.
- Check the bottom right of the customer history and ensure that you see the first app user ID under the "App User ID" section.
Expected Results: First and second app user IDs are aliased and both share the same customer history, purchases, and entitlements.
Pass/Fail Criteria: The user is correctly aliased in the customer history and the new user has the entitlements of the old user.
Paywalls
Displaying Paywalls and making purchases
Description: To ensure that your Paywall is opening properly and functioning properly, follow this test guide.
Related docs:
Preconditions: App installed, Paywall set up in RevenueCat, and a fresh App User ID with no purchases.
Steps:
- Open the app.
- Navigate to your paywall and ensure that the paywall is showing in fullscreen with the proper packages that you have chosen as well as details and any images.
- Select a package from the selection available on your paywall.
- Trigger the purchase.
- Ensure that the purchase went through by checking your app for paid content/entitlements.
- Verify that the purchase went through by checking the customer history of the app user ID and verifying that a new purchase event has been created.
Expected Results: The user is shown the correct paywall and the purchase flow works as intended.
Pass/Fail Criteria: Users purchase is seen on customer history and the paywall displayed to the user was correct.
Localization
Description: To ensure that your Paywall localization's are set up correctly, follow this test guide.
Related docs:
Preconditions: App installed, Paywall set up in RevenueCat, fresh App User ID, device and store account is set to the country that localization is to be tested.
Steps:
- Open the app with the app user ID.
- Navigate to your paywall screen.
- Ensure that the paywall is being shown in the proper language as well as that the paywall has the correct conversions for values in your packages.
Expected Results: Users are shown the paywall in the correct language based on their localization.
Pass/Fail Criteria: Customers paywall changes based on their localization settings.
Test Values coming through properly (Intro offer eligibility)
Description: To ensure that your Paywalls test values are being loaded correctly and users are being offered their correct introductory offers, use this test guide.
Related docs:
Preconditions: App installed, Paywall set up in RevenueCat, and fresh App User ID.
Steps:
- Open the app using your fresh app user ID with no subscription.
- Navigate to your paywall screen.
- Ensure that your intro offer is being shown on your paywall as well as the discount between different packages.
- Purchase a package that has an intro offer attached.
- Check the RevenueCat dashboard customer history for that app user ID and ensure that an
INITAL_PURCHASE
event was made with the Intro offer attached to it. This event should look like the intro offers discussed above in the test guide.
Expected Results: User is shown the paywall with their intro offer attached and the user is able to make the purchase with the intro offer attached.
Pass/Fail Criteria: Customers are able to start an intro offer directly from purchasing through the RevenueCat created paywall.
RC Billing
Purchase Flow
Description: Test the purchase flow using the RevenueCat SDK to ensure that subscriptions are correctly initiated when the purchase process is completed. This includes verifying the handling of purchase initiation, completion, and failure scenarios.
Related Docs:
Preconditions:
- The RevenueCat SDK is integrated and configured correctly in the app.
- Products are set up in the RevenueCat dashboard.
Example Code:
try {
const { customerInfo } = await Purchases.getSharedInstance().purchase({
rcPackage: pkg,
});
if (Object.keys(customerInfo.entitlements.active).includes("pro")) {
// Unlock "pro" content
}
} catch (e) {
if (
e instanceof PurchasesError &&
e.errorCode == ErrorCode.UserCancelledError
) {
// User canceled the purchase
} else {
// Handle other errors
}
}
Steps:
- Initialize the SDK and ensure it’s correctly configured.
- Trigger a purchase for a subscription using the SDK.
- Complete the purchase flow and verify that an
INITIAL_PURCHASE
event is generated. - If the purchase is successful, ensure that the customer receives access to the appropriate entitlements.
- In the case of purchase failure or cancellation, verify that no subscription is created and no events are generated.
Expected Results:
- A subscription is created only when the purchase is successfully completed, generating an
INITIAL_PURCHASE
event. - If the purchase is canceled or fails, no subscription is created and no events are generated.
Pass/Fail Criteria:
- Pass: The purchase flow behaves as expected with correct event generation and entitlement access.
- Fail: If the purchase flow does not correctly handle successful or failed purchases, the test fails.
Free Trials
Description: Test the application and eligibility of free trials for subscriptions through RevenueCat Billing, ensuring that the correct trial period is applied based on the customer's eligibility criteria.
Related Docs:
Preconditions:
- Products with free trials are configured in the RevenueCat dashboard.
- The RevenueCat SDK is integrated and set up correctly.
Example Code:
// Example: Checking trial eligibility
const customerInfo = await Purchases.getSharedInstance().getCustomerInfo();
if ("gold_entitlement" in customerInfo.entitlements.active) {
grantEntitlementAccess();
}
Steps:
- Configure a product with a free trial in the RevenueCat dashboard.
- Set different trial eligibility criteria (e.g., "Everyone", "Has never made any purchase").
- Attempt to start a subscription for a customer and verify that the correct trial eligibility is applied.
- Ensure that the trial automatically converts to a paid subscription unless canceled before expiration.
Expected Results:
- The correct free trial is applied based on the configured eligibility criteria.
- The trial period starts without charging the customer and automatically converts to a paid subscription if not canceled.
Pass/Fail Criteria:
- Pass: The free trial is correctly applied and transitions to a paid subscription as expected.
- Fail: If the trial eligibility is incorrect or fails to convert properly, the test fails.
Expiration
Description: Test the expiration of subscriptions to ensure that the subscription ends appropriately when canceled, when the billing period ends, or when a grace period expires.
Preconditions:
- A subscription is active and has been configured with or without a grace period.
- The RevenueCat SDK is integrated and configured.
Example Code:
// Example: Checking for subscription expiration
const customerInfo = await Purchases.getSharedInstance().getCustomerInfo();
if (!("gold_entitlement" in customerInfo.entitlements.active)) {
revokeEntitlementAccess();
}
Steps:
- Start a subscription and verify that it is active.
- Cancel the subscription or allow the billing period to end without payment.
- If applicable, wait for the grace period to expire.
- Verify that an EXPIRATION event is generated.
- Ensure that the customer loses access to the entitlements associated with the expired subscription.
Expected Results:
- The subscription expires as expected, generating an EXPIRATION event.
- The customer loses access to any entitlements associated with the subscription.
Pass/Fail Criteria:
- Pass: The subscription expires correctly, and access to entitlements is revoked.
- Fail: If the subscription does not expire as expected or entitlements are not revoked, the test fails.