Zebble
  • About Zebble
  • Compare
  • Documentation
  • Themes
  • Plug-ins
  • Contact Us

    • What is Zebble?
    • Structure of a Zebble solution
    • Zebble Designer (UWP)
    • Installing - Introduction
    • Introduction
    • ViewModel development
    • VM.EXE
    • View development
    • Dialogs
    • Lists and Collections
    • Tips and shortcuts
    • List views
    • ViewModel testing
    • Automatic Views
    • View development process
    • Hello World - Core Concepts
    • Layout: Sizing & Positioning
    • Event handling
    • Navigation
    • Alerts, Dialog, Prompt and toast
    • View lifecycle
    • Managing Files & Resources
    • Config & Debugging
    • Forms
    • Page templates
    • Device API
    • Animations
    • Web Api - Part 1 (reading data)
    • Web Api - Part 2 (post and delete)
    • Web Api - Part 3 (server vs client domain model)
    • Gesture events
    • View class
    • Zebble Markup (.zbl files)
    • Data Binding and MVVM
    • Stack class
    • Sizing and positioning
    • Layout examples
    • ScrollView class
    • Page class
    • Styling in Zebble
    • CSS property mapping to Zebble
    • Supported selectors
    • Zebble CSS: Under the hood
    • Inline styling
    • CSS real-time updates
    • Dynamic expressions in CSS
    • Gradient background colours
    • CSS Pseudo-classes support
    • Using Bold and Light Fonts in Zebble
    • Rotation in Zebble
    • Using custom fonts in Zebble
    • Flashing on tap using AutoFlash
    • Button
    • Carousel class
    • Checkbox class
    • DatePicker
    • Drawing class
    • FilePicker class
    • Grid class
    • IconButton class
    • ImageView
    • ItemPicker class
    • ListView & Grid classes
    • OptionsList
    • SearchInput class
    • Slider class
    • Switch class
    • Tabs Class
    • TextInput class
    • TextView
    • TimePicker
    • TreeView
    • Waiting Indicator
    • WebView class (displaying html)
    • C# Methods and Properties Of UI Components
    • Nav.Forward() vs Nav.Go()
    • Passing parameters to the destination page
    • Going Back
    • Showing Popup pages
    • Waiting class
    • Hardware Back button (e.g. Android)
    • NavigationBar class
    • Tabs class
    • Caching (pages)
    • Navigation without event handler
    • Use the Windows version
    • Logging messages for Debugging
    • Debugging Zebble/Plugin
    • Exception handling in Zebble
    • Debugging layout and styles
    • Zebble Device API
    • Device.Screen and orientation (landscape | portrait)
    • Code that should run on a specific platform
    • Using Lamp (aka Flash, LED and Torch)
    • Using Compass (Smooth compass)
    • Using Accelerometer (device angle)
    • Using Gyroscope (device motion speed)
    • How to Vibrate the device?
    • Launching the device browser
    • Finding device model and manufacturer
    • Responding to System events
    • Handling device shake event
    • Permissions
    • Permissions declaration (manifest files)
    • Sharing
    • Prompt for rating the app
    • Finding if Internet connection is available
    • Device messaging (Make a phone call, send SMS or Email)
    • Showing a local notification
    • Copying to Clipboard
    • Accessing device contacts
    • Reading and writing into Gallery (albums)
    • Playing & Recording Audio
    • Cache and temp files and folders
    • C# async / await
    • Understanding Zebble Threading
    • Debugging - the StackTrace problem
    • Not awaiting (running in parallel)
    • Timer (interval / scheduled running)
    • Post-render changes to the UI (dynamic)
    • Introduction of Geo location
    • Map & Location Services
    • Launch directions to a location (external)
    • Getting current Location
    • Tracking user location
    • Device.Media: Taking and picking photos
    • Playing an audio file
    • VideoPlayer class
    • Augmented reality
    • Recording audio
    • Virtual Reality
    • Speech Recognition
    • Recording or picking video
    • Playing remote videos in iOS
    • Text to speech
    • Introduction to the importance of Mobile Testing
    • Why and what to test
    • Testing mobile apps on different devices
    • Testing mobile apps
    • Xamarin Profiler
    • Performance optimization
    • Moving a view to another container at run-time
    • Attaching custom data (tag) to objects
    • Saving a view as image
    • Naming best practices
    • Fastest way to update your nuget package
    • Tips for Clean and Brief code
    • Splash screen and icon generation
    • Advice for passing Approval
    • Options for iOS app distribution
    • Test Release (internal and UAT)
    • Application Icons in IOS
    • Submitting to App Store
    • Releasing to App Store
    • Crash reporting
    • Optimized Release Build
    • Android - Generating an APK for manual installation
    • Payment (subscriptions & in-app purchases)
    • Introduction to push notifications
    • Registration process (App)
    • Push notification setup - iOS
    • Push notification setup - Android
    • Push notification setup - Windows
    • Sending a push message from the web app
    • Introduction
    • Connecting Zebble to Web API
    • Installation
    • Creating an API class
    • GET APIs
    • Calling a GET API (in the mobile app)
    • POST, PUT, PATCH and DELETE APIs
    • Domain Model
    • Web API and Authentication
    • Versioning
    • Uniquely identifying installations (token)
    • Settings file: config.xml
    • Standard Zebble settings
    • Login/Register with Facebook
    • Creating a composite component / plugin
    • Creating a Zebble component using Html and Javascript
    • CustomRenderedView: Third-party native components / plugins
    • Mapbox
    • Naming considerations
    • Random problems?
    • Display Keyboard for Visual Studio Android Emulator
    • iOS goes mad?
    • Configuring a Windows phone for ad-hoc testing
    • Fixing Error DEP0001 : Unexpected Error: -2147009287 while deploying Windows UWP app on device
    • Fixing Error DEP0001 : Unexpected Error: -1988945906 while deploying Windows UWP app on device
    • Unable tp Connect to the Mac agent from Visual Studio
    • Can't connect to the Mac agent from Visual Studio?
    • Choosing the CPU architecture
    • How to debug Zebble.Exe?
    • How to add a Device API to Zebble source?
    • About Automated UI testing
    • What should we test in mobile applications?
    • Creating an Automated UI Test in Zebble



Payment (subscriptions & in-app purchases)


To accept payments in your mobile app, you will need to do a number of actions.

Payments need to be taken through the built-in mechanism by Apple (App Store), Google (Play Store), etc. These app distribution marketplaces typically forbid charging the users outside of their platforms, so they can take a commission (often 30%, but sometimes 15%). There are exceptions to this rule, but they are outside of the scope of this tutorial.

Generally, your payments are either related to a subscription (a recurring payment schedule that can be cancelled by the user at any time) or an in-app purchase (one-off payment for a digital product, which can be used for a non-recurring subscription also (such as lifetime).

Product setup

You should set up your buyable products and subscriptions directly in the iTunes Connect (for iOS) or Google Play Console (for Android). That's a straight forward web-based step-by-step process which you can do once logged into those web app consoles.

For each product or subscription option you should choose a unique product ID which should be in the format of my_product_id (lower case, alphanumeric characters and underlines). It's recommended to use the same name on both App Store and Google Play store accounts to prevent confusion. Be very careful when setting them up, because once you use a product id, you cannot delete and reuse it. 

The price and availability will be set also directly in the store. Try to keep the Apple and Google Play store prices as close to each other as you can to avoid having angry users later on.

App integration

Once your products are set up, add the nuget package Plugin.InAppBilling to your iOS, Android and UWP projects.
It's also recommended to read this guide for better understanding of how it works.

You will need to apply the linker skip settings in your iOS and Android projects in Release configuration. Otherwise you will get runtime errors when publishing the app!

Payment UI

In your app, implement the subscription or shopping page as per your requirements and design. The products you publish in the app, must match the same product IDs as the ones you set up in the previous step.

It is recommended that in your app domain project, you have the necessary classes to represent your products. For example a class named SubscriptionProduct, to include all product Ids, and other descriptions, stored in a Json file in your app can be a good idea.

Getting the product prices in the app

The prices may change, and are in fact different on each app store and each user location. This means that you need to dynamically fetch the latest price information for the products in your app to ensure the prices you show in the app are the same as ones set up in the App stores' web console. Once you have the correct price, for performance, you can cache it locally, but still it's recommneded to fetch the updated prices regularly, (e.g. daily).

You can obtain the latest prices for all your products and subscriptions by making a single call for each type.

async Task<bool> FetchPrices(ItemType type, string[] productIds)
{
     try
     {
            var connected = await Billing.ConnectAsync(type);
            if (!connected) return false;

            var items = await Billing.GetProductInfoAsync(type, productIds);
            if (items == null) return false;

            foreach (var item in items)
                 SubscriptionProduct.Update(item.ProductId, item.LocalizedPrice, item.MicrosPrice / 1000000m);

            SubscriptionProduct.SavePrices();
            return true;
     }    
     finally
     {
          try { await Billing.DisconnectAsync(); }
          catch { Zebble.Device.Log.Error("Failed to disconnect from billing!"); }
     }
}

await FetchPrices(ItemType.Subscription, new [] { "my_product_id1", "my_product_id2", "..." });

// if needed, have a similar call for in-app purchases.
The above example, assumes that you have a SubscriptionProducts.json file with the description of the products in your app. Each one will have a product Id, name, and other visual information.

// TODO: Implement a full store implementation as Zebble.Billing with client and server components.

The Store class needs an initialization routine which loads the product json (overridable) manages the price updates, purchase event calls, server components, ...

 

 

 



‹
Zebble is a product of Geeks Ltd , a software house based in London, UK. All rights are reserved.

Telephone: +44 (0)845 643 6229

Email: hello@zebble.net

Address: 66a London Road, Morden

Greater London, United Kingdom, SM4 5BE

Privacy Statement
Terms & Conditions
Contact Us