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
  • Consuming the IAP
  • Check for Unconsumed Purchases
  • Taking Additional Actions When Consuming a Purchase
  1. Subscription Management
  2. Advanced Use Cases

Working with Consumable IAPs

When working with consumable purchases, there are a couple of extra steps you need to take in your app code.

  1. You need to let the SDK know that you have processed (or consumed) the consumable so that it is eligible to be purchased again.

  2. Check for purchases that have not been consumed when the app launches and make sure they are consumed.

  3. Optionally take an action on the successful purchase, such as incrementing a credit or coin count granted by purchasing the consumable IAP or displaying a message with the account balance after the transaction.

Consuming the IAP

The Nami platform tracks all purchases that have been made as do the stores themselves and in both places you'll be prevented from making that same purchase a second time.

However, in the case of a consumable IAP, you actually want to let your customers purchase this SKU multiple times.

In order to allow for this, you simply need to Consume the SKU. Once this is done, your customers will be able to purchase it again. This can be done with the following SDK call

NamiPurchaseManager.consumePurchasedSku(skuId: StoreId)

where StoreId is the SKU ID defined in the Control Center.

👍 Nami Best Practice

We recommend calling the consumePurchasedSku method immediately after a successful purchase has happened. See the code sample below.

🚧 App with Consumable and Non-Consumable SKUs

If your app sells a mixture of consumable and non-consumable SKUs (such as subscriptions), be sure to check the SKU ID before you consume the SKU.

NamiPurchaseManager.registerPurchasesChangedHandler { (purchases, state, error) in
	if state == .purchased {
  	if let purchase = purchases.first {
    	// if you have non-consumable SKUs check the sku_id
      if purchase.skuId == "consumable_sku_id" {
      	NamiPurchaseManager.consumePurchasedSku(skuId: purchase.skuId)
        print("Consumed purchase for \(purchase.skuId).")
    	}
  	}
	}
}

🚧 Android vs Apple

Note that on Android a successful consumable purchase that has not yet been consumed will have a NamiPurchaseState of PENDING.

On iOS the purchase state will be PURCHASED when it is ready to be processed and consumed.

Check for Unconsumed Purchases

👍 Nami Best Practice

It is a good idea to check for any unconsumed purchases when your app starts.

If the app were killed during the purchase process or a purchase was made outside of the app, the purchase change listener would not properly consume the purchase and update the user's credit balance.

In order to check for purchases that have not been consumed, add a listener for purchase changes to the applicationDidFinishLaunching method in your iOS app.

We'll modify the code above slightly to track the SKU ID of purchases that are started and go into a pending state as well as purchases that complete with a state of purchased.

As before, if you have non-consumable SKUs in your app, be sure to check the SKU ID to make sure this is a SKU you want to consume.

// Place at class level
 var pendingSkuId : String? = .none

...

// Place inside applicationDidFinishLaunching
NamiPurchaseManager.registerPurchasesChangedHandler { (purchases, state, error) in
	if state == .pending {
  	self.pendingSkuId = purchases.first?.skuId
  }
                                      
  if state == .purchased {
  	for purchase in purchases {
    	// Make sure the purchase is one we want to consume, vs something like a subscription
      if purchase.skuId == "consumable_sku_id" && purchase.skuId == self.pendingSkuId  {
      	NamiPurchaseManager.consumePurchasedSku(skuId: purchase.skuId)
      	print("Consumed \(purchase.skuId).")
  		}
  	}
	}
}

Taking Additional Actions When Consuming a Purchase

Finally, we may want to take some additional actions after consuming a purchase, such as:

  • Adding credits to a balance

  • Granting access to an entitlement

  • Displaying a message that states the user's total credit balance

We can accomplish this by adding a little extra code to the last example. Here we see examples of both incrementing a credit count and displaying a message to the user after the purchase completes.

// Place at class level
var pendingSkuId : String? = .none

...

// Place inside applicationDidFinishLaunching
NamiPurchaseManager.registerPurchasesChangedHandler { (purchases, state, error) in
	if state == .pending {
  	self.pendingSkuId = purchases.first?.skuId
  }
                                      
  if state == .purchased {
    for purchase in purchases {
    	// Make sure the purchase is one we want to consume, vs something like a subscription
      if purchase.skuId == "consumable_sku_id" && purchase.skuId == self.pendingSkuId  {

      	increaseCreditBalance(10);
        NamiPurchaseManager.consumePurchasedSku(skuId: purchase.skuId)
        print("Consumed \(purchase.skuId) and increased credit balance.")
      }
    }
                        
    // Take further action after paywall is closed
    NamiPaywallManager.dismiss(animated: true) {
    	self.showMessageWithCreditBalance();
    }
  }
}

Last updated 11 months ago