Nami Public Documentation
Sign In
Nami Documentation
Nami Documentation
  • Get Started
    • Overview
      • Key Concepts
      • Data Collection
      • Built for Privacy
    • Evaluating Nami
    • SDKs
      • Apple Native SDK
      • Android Native SDK
      • Amazon Native SDK
      • Roku Native SDK
      • React Native Cross-Platform SDK
      • Flutter Cross-Platform SDK
      • Unity Cross-Platform SDK
      • Release Notes
        • Find Nami SDK Version
    • Quickstart Guide
  • Subscription Management
    • Overview
    • Products
      • Archive Products
      • Sync Products
    • Entitlements
    • Customer Screen
    • Accounts and Login/Logout
    • Advanced Use Cases
      • Upgrades and Downgrades
      • Supported Purchase Change States by Platform
      • Restoring Purchases
      • Working with Consumable IAPs
  • No Code Paywalls
    • Overview
    • Paywall Creator
      • Using the Creator
      • Paywall Layout
      • Components
        • Editing, Deleting, Reordering
        • Hiding Components
        • Video
        • Collapse
      • Editable Properties
        • Focused Styling
        • Safe Area
      • Conditions
        • Notched Devices
        • Product Entitlements
      • Adding Products
      • Repeating Product Group
      • Product Fields
      • Capabilities
        • Featured Styling
        • Selected Styling
        • Custom Brand Fonts
        • Carousel
        • Trial Eligibility
        • Deeplink Button
        • Introductory Offer Eligibility
        • Login Check
        • Product Groups
        • Conditional Product Groups
        • Offer Eligibility and Purchasing
        • Screenreader Text
        • Personalization Tokens
        • Custom Variables
        • Multipage
        • Custom Data Source
        • Advanced Video Features
        • Product Error States
      • ❓FAQs
        • Designing Paywalls in Figma
        • Guide to Building a Paywall from Scratch
      • 🎁Releases
        • Roadmap
    • Paywall Templates
      • Pacific
      • Pacific Premium
      • Trident
      • Starfish
      • Mantis
      • Venice
      • Venice Premium
      • Honest
      • Catalina
      • Oyster
      • Puffin
      • Marina
      • Beluga
      • Driftwood
      • Lagoon
      • Pisces
      • Aquarius
      • Conch
      • Lionfish
      • Moray
      • Tetra
      • Lighthouse
      • Puffin Tablet
    • Managing Paywalls
      • Archiving a Paywall
      • Duplicate a Paywall
    • Paywall Smart Text
    • Pricing Eligibility States
    • Pricing Eligibility by Platform
    • Nami Paywalls in Different Languages
    • Legacy Paywalls
  • Campaigns
    • Placements
      • Create a Placement
      • Deeplink Placements
      • Archiving a Placement
      • Managing Lots of Placements
      • Export Placements
    • Campaigns
      • Campaign Filters
        • Campaign Use Cases
      • Archiving a Campaign
      • Scheduling a Campaign
      • Campaign Conversion Events
      • Managing Lots of Campaigns
      • Campaign Troubleshooting
    • A/B and Multivariate Testing
      • Selecting an A/B test winner
      • A/B Test Allocation
  • Integrations
    • All Integrations
    • Billing Platforms
      • Apple Integration
        • App Store Setup
          • Privacy Details
        • Platform Integration
        • App Store Server Notifications
        • Store Credentials
          • App Store Connect Shared Secret
          • Apple App Store Connect API
          • Apple In App Purchase
        • Add a Product
        • Platform Sync
        • SDK Integration
        • Troubleshooting
        • Testing and Development
          • Apple Testing Environments
          • Setting up Device Sandbox Test Environment
          • Setting up StoreKit config in Xcode
      • Google Integration
        • Google Play Store Setup
        • Platform Integration
        • Service Account
        • Real-time Developer Notifications
        • Add a Product
        • Platform Sync
        • SDK Setup
        • Troubleshooting
          • Supporting Android minSdkVersion 25 or lower
          • Requested product is not available for purchase
          • Unsupported Version of Play Billing
      • Amazon Appstore Integration
        • Create Amazon Android App
        • Platform Integration
        • Shared Key
        • Real-time Event Notifications
        • Add a Product
        • SDK Integration
        • Testing
      • Roku Integration
        • Platform Integration
        • API Key
        • Transaction Notifications
        • Add a Product
        • SDK Integration
      • Web Integration
    • Analytics Tools
      • Adobe Analytics
      • Amplitude
      • Google Analytics
      • mParticle
      • 3rd-Party Analytics
    • Subscription Management
      • Nami Subscription Management
      • Bring your Own Payment Code
    • CDP Integrations
      • Adobe CDP Integration
      • Amplitude CDP Integration
      • Custom CDP Integration
      • Generic CDP Integration
    • Other Integrations
      • Wicket Labs
      • Webhooks
        • Introduction to the Nami ML Event System
        • Event Types
          • Purchase Status Updates
          • Events for Upgrades, Downgrades, and Crossgrades
        • Event Subscriptions
        • Understanding Transferred Events and Accounts
      • API Access
    • Events Feed
  • Analytics
    • Using Charts
    • Paywall Analytics
      • Impressions
      • Paywall Conversion Rate
      • Sessions
      • Active Devices
    • Subscription Analytics
      • Revenue
      • MRR
      • Purchases
      • Trial Starts
  • Nami Account
    • Manage your Apps
      • Find your Nami App Platform ID
      • Setting up Legal Text for your Apps
    • Organization
      • Configuring Organization Security Policies
      • Billing
    • Invite your Team
      • Roles
    • Manage your Account
      • Two-Factor Authentication (2FA)
Powered by GitBook
On this page
  1. Integrations
  2. Billing Platforms
  3. Apple Integration

Testing and Development

Tips and tricks for testing Apple purchases

Last updated 1 year ago

In order to simplify testing, Apple's App Store uses accelerated time in their sandbox environments. In the Nami platform, this will affect the following aspects of the platform:

  • Time for subscription purchases to expire

You will encounter these accelerated time periods in simulator testing, device testing, and on TestFlight.

These rules apply to auto-renewable subscriptions. In addition to the accelerated time, test subscriptions only auto-renew a maximum of six times.

For the latest on how Apple handles this, . We've included the rules here as well for reference.

Real Duration
Accelerated Duration

1 week

3 minutes

1 month

5 minutes

2 months

10 minutes

3 months

15 minutes

6 months

30 minutes

1 year

1 hour

Testing payments with Nami

Testing payment flows in the App Store for your application can be made easier with Nami.

In addition to the normal StoreKit test flows which all work as expected with the Nami SDK, you can also choose to enable a bypassStore mode, which lets you test payment flows without calling StoreKit under the hood. This lets you test how payments affect your application in the simulator using the real callbacks (such as registering a purchases changed handler) or purchase checks (like checking if a product ID or set of product IDs has been purchased) that would be used for reacting to store purchases.

Because StoreKit is not available for use in testing when in the iOS simulator, byPassStore mode is enabled by default in the simulator.

To enable on device, set bypassStore to be true in the NamiConfiguration object when you initialize the SDK.

let namiConfig = NamiConfiguration(appPlatformID: "YOUR_APP_ID")
namiConfig.logLevel = .info
namiConfig.bypassStore = true
Nami.configure(namiConfig: namiConfig)
NamiConfiguration *namiConfig = [NamiConfiguration configurationForAppPlatformID: @"YOUR_APP_ID"];
[namiConfig setLogLevel:NamiLogLevelInfo];
[namiConfig setBypassStore:true];
    
[Nami configureWithNamiConfig:namiConfig];
var configDict = {
  "appPlatformID-google": "YOUR_GOOGLE_PLATFORM_ID",
  "appPlatformID-apple": "YOUR_APPLE_PLATFORM_ID",
  "logLevel": "INFO",
  "bypassStore": true
};

NativeModules.NamiBridge.configure(configDict);

After that, purchases will route through Nami internally instead of StoreKit. This lets you avoid having to enter a password every time you want to test a purchase, and to test first-time purchases vs. re-subscriptions.

StoreKit Best Practice

StoreKit has no way of clearing out previous purchases. For this reason, it is usually recommended that you make a new testing account for each pass through a complete purchase test.

This takes effect for both local device testing, and for TestFlight builds so carefully consider which way you want TestFlight users testing purchases before including bypassStore in a TestFlight build.

Enabling this flag also lets you include purchases into XCUITests or unit tests, which may not be possible depending on how or where you do automated testing.

The byPassStore flag is disabled automatically when in a production app on the App Store.

Once you have byPassStore enabled, you can add the code as you normally would handle purchases and will get the same kinds of call flows from Nami that you would from a real StoreKit purchase - it will give you a pending, then purchased signal if you have a purchase handler set up.

Like a real purchase, byPassStore purchases will remain for products that are permanent purchases. In order to clear out test purchases, you can call:

NamiPurchaseManager.clearBypassStorePurchases()
[NamiPurchaseManager clearBypassStorePurchases];
NativeModules.NamiPurchaseManager.clearBypassStorePurchases();

This call will clear purchases made by this bypass mechanism - note that it will not clear out Apple sandbox purchases when running on a device.

Nami Best Practice

We recommend you add a call to clearBypassStorePurchases on app open any time you are using byPassStore. This will ensure that each app run gets a clean test environment.

Note that if you want to test purchase behavior over multiple app runs, you should not include clearBypassStorePurchases.

You can also use clearBypassStorePurchases in conjunction with XCUITests or unit tests to help clear testing purchases made.

For subscription products that can expire, bypassStore uses the same shortened expiration for subscriptions - see the previous chart for times. The time period of the subscription closest to one of those durations determines how much time a subscription expiration takes. The Apple sandbox will automatically renew a subscription five times before expiring. Currently, the Nami framework will just expire without renewal when the subscription is over, at the accelerated rate.

Note that the bypassStore makes testing purchases much easier, but you should always still do some testing with the Apple Sandbox on device - the Nami SDK is a simplification of real-world response from StoreKit, but StoreKit timing of purchases and messaging flows can be different in more complex situations.

head over to their documentation