Selling software, subscriptions and in-app purchases
Set a product's type, billing period and its own price on the web, the App Store and Google Play, then bring each customer's plans and purchases onto their profile, from the stores or from your own system, so agents and the AI assistant answer right.
Updated on
On this page
If you sell an app or software, one plan often has three prices: on the web, on the App Store and on Google Play, each store with its own product id. Ha Tang keeps all three on one product: customers writing from your iOS app see the App Store price, from your Android app the Google Play price, on the web the web price. Each customer's plans (active, trial, won't renew, expired, refunded) and one-time purchases then show on their profile.
There are two ways to bring purchases into Ha Tang, and you can use both:
- Connect the App Store and Google Play. Ha Tang checks each purchase with Apple or Google and receives every renewal, cancellation and refund from the stores. Your app passes the customer's account token when buying. Suits apps whose own servers do not check store purchases yet.
- Send them from your own system. Your server, which already checks purchases with the stores or takes payments on your website, sends each plan and purchase to Ha Tang. Nothing to connect in the stores. Suits apps that already have a backend for in-app purchases, and anything you sell on the web.
The same purchase sent both ways stays one record.
You need Work access to Products to edit products, and Manage access to Customer Support to connect the stores.
Create a subscription
- Go to Products → Catalog and click Add product (or open an existing one).
- Under Type, choose:
- Subscription for a plan paid per period; then pick the Billing period (weekly, monthly, every 3 or 6 months, yearly) and Free trial (days) if any;
- In-app purchase, consumable for something used up and bought again (coins, credits);
- In-app purchase, one-time for something bought once and kept (unlocking a feature);
- Digital product for software sold once on the web.
- Web price (₫) and the Product page URL are the price and checkout page for customers on the web.
- Open Prices on the App Store and Google Play and fill in each store:
- the product ID you created in App Store Connect or the Play Console;
- the Price and Currency you set in that store, for example
4.99USDon the App Store and219000VNDon Google Play; - for a Google Play subscription: the Base plan ID, and the Offer ID if there is an offer such as a free trial.
- If a variant has its own ids (a yearly plan, say), add it under Prices per variant, one per line:
ios | Yearly | 49.99 | USD | com.app.pro.yearly. - Fill in SKU with your own code for the plan (for example
PRO-1M). Purchases your system sends, above all those made on your website where there is no store product id, find their product by this SKU, so the customer's profile shows the plan's name. - Click Save.
Import many plans at once from a CSV file with the columns kind, billing_period, trial_days, ios_product_id, ios_price, ios_currency, android_product_id, android_price, android_currency, android_base_plan_id (see Your product catalog).
What customers and the AI assistant see
- Product cards sent to a customer carry the price on the platform they are using, with the billing period and free trial. Inside your app a card carries only that store's id, so Buy starts Apple's or Google's purchase; on the web it carries the checkout page.
- The AI assistant quotes the platform's price ("$4.99/month on the App Store, 7-day free trial"). For in-app products it never offers a bank transfer or a draft order, since Apple and Google require their own checkout.
- Cards an agent sends from the reply box (Product) are priced for the customer's platform too.
Connect the App Store and Google Play
Connect so every purchase, renewal, cancellation and refund from the stores reaches Ha Tang. Your developers add one step in the app: pass the customer's account token when buying (see the SDK guides), so each transaction lands on the right customer.
If your own server already receives the stores' notifications, you do not need this section: Apple allows one notification URL per environment, so keep it on your server and send purchases from your own system instead.
App Store
- Go to Customer Support → Channels and open your iOS app.
- Under Subscriptions from the App Store and Google Play, enter the app's Bundle ID and click Connect.
- Copy the Notification URL.
- In App Store Connect, open the app → App Information → App Store Server Notifications, paste the URL for Production and Sandbox, and choose Version 2.
- Click Request a Test Notification. The app page in Ha Tang shows "Last notification" with the time.
App Store Server API key (optional). With this key Ha Tang can ask Apple at any time instead of only waiting for notifications: the Refresh link on each plan, a daily check of plans due to renew (in case a notification got lost), and importing customers who bought before you connected.
- In App Store Connect → Users and Access → Integrations → In-App Purchase, generate a key. Note the Issuer ID and Key ID and download the
.p8file (Apple lets you download it only once). - In Ha Tang, open App Store Server API key in the same card, enter both ids, choose the
.p8file and click Save.
Google Play
- In Google Cloud, create a service account, then in Play Console → Users and permissions invite its email with View financial data and Manage orders and subscriptions (so Ha Tang can acknowledge purchases with Google). Download the service account's JSON key.
- In Ha Tang, open your Android app under Channels, enter the Package name, upload the JSON key and click Connect.
- Copy the Push URL.
- In Google Cloud, create a Pub/Sub topic, grant Publisher to
[email protected], and add a Push subscription with the URL you copied. - In Play Console → Monetization setup, enter the topic and click Send test notification.
If a notification is refused (wrong bundle ID or package, a key without access), the app page shows Last error with the reason.
The customer's plans on their profile
Plans shows in the conversation's side panel and on the customer page: the plan, the store, the status and the renewal or end date.
| Status | Means |
|---|---|
| Trial | In the free trial |
| Active | Paid, renews automatically |
| Grace period | The last payment failed and the store is retrying; the customer keeps access |
| On hold (payment failed) | The store stopped access until the customer fixes their payment method |
| Paused | The customer paused the plan (Google Play) |
| Won't renew | The customer canceled; access lasts until the period ends |
| Expired | The last period ended |
| Refunded / Revoked | The store refunded or revoked the transaction |
The AI assistant reads this too, so it can answer "which plan am I on?" and "when does it renew?". For App Store and Google Play plans it sends customers to Apple or Google for refunds and payment methods, and never promises a refund.
When the stores are connected, right after each purchase the app sends the store's proof of the transaction (SDK reportPurchase). Ha Tang checks it with Apple or Google before recording the plan; fake transactions are refused. For Google Play, Ha Tang also acknowledges the purchase, so Google does not refund it automatically after three days. The open conversation also gets an internal note.
Customers who buy before signing in to the app keep their plan: when the app identifies them, the purchases made on that phone move to their profile.
One-time purchases
One-time purchases (coin packs, lifetime unlocks, non-renewing plans, courses) show under the plans, with their type (Consumable, One-time purchase, Non-renewing plan), where they were bought (App Store, Google Play or Web) and the purchase date. A refund from the store or from your own system shows Refunded.
Refresh and import existing customers
- Refresh next to an App Store or Google Play plan asks the store again right away. It works only when the stores are connected, and needs the App Store Server API key (iOS) or the service account (Android).
- To import customers who bought before you connected, your developers send Apple transaction ids or Google Play purchase tokens through the API (
POST /chat/subscriptions/import, up to 500 per call).
Send plans and purchases from your own system
Your developers send Ha Tang what your system already knows, right after each change: a purchase, a renewal, an expiry, a refund. This covers:
- Plans paid on your website (bank transfer, your own payment provider);
- App Store and Google Play plans and purchases that your server already checks with Apple or Google;
- One-time purchases: coin packs, unlocks, courses, on the web or in the stores, and their refunds.
How it works:
- Each record carries the user id your app and website use to identify the customer in the chat, so it lands on their profile. Records for someone who has never opened the chat appear as soon as they do.
- Plans and purchases find their product by its SKU or its App Store / Google Play product id, so set those on your products.
- Sending the same plan or purchase again only updates it, so your system can resend everything after each change, and send the history once to fill in customers who bought before.
- Your developers use the Node.js SDK (
@hatang/sdk0.6.0 or later), the Python SDK (hatang) or the REST API with an API key that has the CRM write scope. See Send purchases from your backend, the Node.js SDK and the Python SDK.
Was this article helpful?
Related articles
- Your product catalogAdd your products by hand or import them from a CSV file, a Google Sheet or your website, so agents can send them in chat and the AI can quote them.
- Send product cards in chatSend up to four products from your catalog as cards with photo, price and a Buy button, on the website chat, your app, Zalo, Messenger and every other channel.
- How the AI assistant worksWhat the AI assistant answers, what it knows, when it hands a conversation to your team, and what it costs.
Not finding what you are looking for?
Our team answers in the chat, in English or Vietnamese.