Using In-app Subscriptions, you can track subscriptions you sell and service via in-app purchase channels such as Apple's App Store and Google's Play Store. Call this API to notify Chargebee of new subscription purchases. Chargebee responds by creating corresponding subscriptions. You can make the API call directly from the client-side application or from your server. In the case of the Apple App Store integration, you can also configure Chargebee to receive server notifications from Apple to keep subscriptions up-to-date.
In-app subscriptions are read-only
The subscriptions created via the Process Purchase Command API are managed by Apple or Google in response to actions taken by your subscribers via their respective accounts. Chargebee only keeps track of these subscriptions: creating and modifying them in response to events happening against the original subscriptions. Consequently, these subscriptions cannot be modified by you via the Chargebee admin console or the Subscriptions API.
Configure Apple or Google server-side notifications so that subscriptions created using process purchase command API are kept up-to-date using information received via the webhooks.
The following table lists the notification types from App Store and describes how Chargebee responds to each of them.
Notification type |
Description |
DID_CHANGE_RENEWAL_STATUS , INTERACTIVE_RENEWAL |
This notification triggers when a subscription is active or the customer is upgraded to another SKU (stock-keeping unit). Chargebee checks relevant details in the receipt to detect an upgrade event. Once an upgrade event is detected, you can update the subscription with the new product details, and allow the update to take effect immediately. Chargebee webhooks triggered For subscription cancellation, whether immediately or at the end of the term. subscription_changed, subscription_cancellation_scheduled, subscription_cancellation_reminder, and subscription_cancelled. For subscription upgrade with proration. subscription_changed, invoice_generated, payment_succeeded, and invoice_updated. For subscription reactivation. subscription_reactivated, subscription_reactivated_with_backdating, payment_succeeded, and invoice_updated. For regular subscription renewal. subscription_renewed, subscription_changed, invoice_generated, payment_succeeded, and invoice_updated. |
DID_CHANGE_RENEWAL_PREF |
This notification triggers when a subscription is active or the customer is downgraded to another SKU(stock-keeping unit). It indicates that the customer made a change in their subscription plan that takes effect at the next renewal. The currently active plan is not affected. Chargebee schedule downgrades to take effect at the end of the period. At the end of the billing period, confirm the downgrade at Apple’s end before downgrading it in the Chargebee. Chargebee webhooks triggered For subscription upgrade with proration. subscription_changed, invoice_generated, payment_succeeded, and invoice_updated. |
DID_CHANGE_RENEWAL_STATUS |
This notification triggers when a subscription is expired or the customer resubscribes to the same SKU(stock-keeping unit). Chargebee re-activates subscription immediately. Chargebee webhooks triggered For subscription cancellation. subscription_changed, subscription_cancellation_scheduled, subscription_cancellation_reminder, and subscription_cancelled. For subscription upgrade with proration. subscription_changed, invoice_generated, payment_succeeded, and invoice_updated. |
INTERACTIVE_RENEWAL , DID_CHANGE_RENEWAL_STATUS |
This notification triggers when a subscription is expired or the customer resubscribed to another SKU (upgrade or downgrade). Chargebee immediately re-activates the subscription with the new product(plan or item). Chargebee webhooks triggered For subscription upgrade with proration. subscription_changed, invoice_generated, payment_succeeded, and invoice_updated. For subscription cancellation, whether immediately or at the end of the term. subscription_changed, subscription_cancellation_scheduled, subscription_cancellation_reminder, and subscription_cancelled. |
DID_CHANGE_RENEWAL_STATUS |
This notification triggers when the customer canceled the subscription from the App Store Subscriptions settings page. Their subscription will not auto-renew and will expire on the expires_date .Chargebee sets subscription to cancel at expires_date .Chargebee webhooks triggered For subscription cancellation, whether immediately or at the end of the term. subscription_changed, subscription_cancellation_scheduled, subscription_cancellation_reminder, and subscription_cancelled. |
DID_CHANGE_RENEWAL_STATUS |
This notification triggers when the customer previously canceled the subscription but now resubscribed to the same product before the subscription expired. The subscription will auto-renew on the expires_date .Chargebee removes scheduled cancellation of subscription and allows it to auto-renew. If the dates have changed for the term start and end, change the same in the Chargebee subscription. Chargebee webhooks triggered For subscription reactivation. subscription_reactivated, subscription_reactivated_with_backdating, payment_succeeded, and invoice_updated. |
CANCEL , DID_CHANGE_RENEWAL_STATUS |
This notification triggers when AppleCare refunded a subscription.CANCEL indicates that Apple Support cancelled the auto-renewable subscription and the customer received a refund as of the timestamp in cancellation_date_ms .Chargebee cancels the subscription on cancellation_date_ms . Record an offline refund and create a refundable credit note for the full amount. Record cancellation comment on the refund transaction saying canceled by Apple Support .Chargebee webhooks triggered For subscription cancellation, whether immediately or at the end of the term. subscription_changed, subscription_cancellation_scheduled, subscription_cancellation_reminder, and subscription_cancelled. |
DID_FAIL_TO_RENEW |
This notification triggers when the subscription failed to renew because of a billing issue. It Indicates a subscription that failed to renew due to a billing issue. Check is_in_billing_retry_period to know the current retry status of the subscription. Check grace_period_expires_date to know the new service expiration date if the subscription is in a billing grace period.Chargebee takes the following actions. - When we receive this notification before a renewal invoice is created, schedule a cancellation at the end of the current term, if there is no grace period defined in the receipt. - When the notification is received, after the renewal invoice is generated, the subscription remains active while the invoice status becomes not_paid .- If grace_period_expires_date exists, schedule a subscription cancellation on that date.- If there is no recovery until the scheduled cancellation date, then the subscription will get cancelled as scheduled, and the not_paid invoice will get written off.- If grace_period_expires_date does not exist, cancel the subscription and write off the invoice immediately.Chargebee webhooks triggered For subscription cancellation, whether immediately or at the end of the term. subscription_changed, subscription_cancellation_scheduled, subscription_cancellation_reminder, and subscription_cancelled. |
DID_RECOVER |
This notification triggers when expired subscription recovered by App Store through a billing retry. It indicates a successful automatic renewal of an expired subscription that failed to renew in the past. Check expires_date to determine the next renewal date and time.Chargebee resumes the paused subscription with any changes in subscription term dates as per receipt data. Remove scheduled cancellation. If we are syncing dunning information, update it accordingly. Chargebee webhooks triggered For regular subscription renewal. subscription_renewed, subscription_changed, invoice_generated, payment_succeeded, and invoice_updated. |
DID_CHANGE_RENEWAL_STATUS |
This notification triggers when the subscription has churned after failed billing retry attempts. It indicates a change in the subscription renewal status. In the JSON response, check auto_renew_status_change_date_ms to know the date and time of the last status update. Check auto_renew_status to know the current renewal status.Chargebee cancels the subscription at the end of the current term. Chargebee webhooks triggered For subscription cancellation, whether immediately or at the end of the term. subscription_changed, subscription_cancellation_scheduled, subscription_cancellation_reminder, and subscription_cancelled. |
REFUND |
This notification triggers when AppleCare successfully refunded the transaction for a consumable, non-consumable, or non-renewing subscription. Here, the cancellation_date_ms contains the timestamp of the refunded transaction. The original_transaction_id and product_id identify the original transaction and product. The cancellation_reason contains the reason.Chargebee cancels the subscription on a specified date and records an offline refund for the full amount as canceled by Apple Support .Chargebee webhooks triggered subscription_changed, credit_note_created, credit_note_updated, subscription_cancelled, and payment_refunded. |
PRICE_INCREASE_CONSENT |
This notification triggers when the subscription price is increased, and the customer must agree to the increase before the subscription auto-renews. It indicates that App Store has started asking the customer to consent to your app’s subscription price increase. In the unified_receipt.Pending_renewal_info object, the price_consent_status value is 0 , indicating that App Store is asking for the customer’s consent, and hasn’t received it. The subscription won’t auto-renew unless the user agrees to the new price. When the customer agrees to the price increase, the system sets price_consent_status to 1 . Check the receipt using verifyReceipt to view the updated price-consent status.Chargebee updates the subscription overriding subscription price. When consent is not received and renewal date is reached, pause the subscription. If possible, add a comment on the subscription saying “Paused because price increase consent not received from the customer”. |
DID_RENEW |
This notification triggers when a customer’s subscription is successfully auto-renewed for a new transaction period. Chargebee renews the subscription if not already auto-renewed. Chargebee webhooks triggered For regular subscription renewal. subscription_renewed, subscription_changed, invoice_generated, payment_succeeded, and invoice_updated. |
REVOKE |
This notification triggers when a purchaser disabled Family Sharing for a product, the purchaser (or family member) left the family group, or the purchaser asked for and received a refund. Your app will also receive a paymentQueue(_:didRevokeEntitlementsForProductIdentifiers:) call. For more information about Family Sharing, see Supporting Family Sharing in Your App. |
CONSUMPTION_REQUEST |
The customer initiated a refund request for a consumable in-app purchase. Chargebee does not support this notification. |
INITIAL_BUY |
This notification triggers when the customer completes an initial subscription purchase. Chargebee does not support this notification because price and currency information is not present in the receipt. |
When an in-app subscription
is created in Chargebee, the following webhook events get generated in sequence.
plan_created
or item_created
)customer_created
)subscription_created
)subscription_changed
)invoice_generated
)payment_succeeded
)invoice_updated
)Webhooks are asynchronous by nature; therefore not recommended for time-critical applications. Webhooks may reach your application in a different order and become redundant. For time-critical applications, Chargebee recommends using the List events API to poll Chargebee for events.
Since Apple notifications do not provide any price information, processing a webhook fails in the following scenarios:
Issue |
Solution |
A new purchase (INITIAL_BUY ) server notification is received. |
Always use the process purchase command API to record a new purchase. Chargebee requires the amount paid and the currency to create a subscription. |
A notification is received for an SKU (plan) change but the plan-item price is unavailable in Chargebee. | Create the plan-item price in Chargebee via API or admin console, then retry processing the webhook. |
Chargebee acts upon certain notifications from Google. On receiving any of the notifications listed in the table below, Chargebee checks whether the subscription is present. If present, it carries out certain actions as described in the table. The webhooks triggered due to these actions are also listed here for convenience.
Google notification |
Chargebee’s response |
SUBSCRIPTION_RECOVERED |
When the subscription is in the paused state, Chargebee resumes the subscription or schedules it for resumption. Chargebee webhooks triggered For in-term resumption. subscription_resumed For out-of-term resumption. subscription_resumed and invoice_generated For scheduled resumption. subscription_resumption_scheduled |
SUBSCRIPTION_RENEWED |
Chargebee updates the subscription with the next renewal date. After receiving this notification if the subscription is in the canceled state, Chargebee reactivates the subscription. Chargebee webhooks triggered For subscription reactivation. subscription_reactivated , subscription_reactivated_with_backdating , payment_succeeded , and invoice_updated .For regular subscription renewal. subscription_renewed , subscription_changed , invoice_generated , payment_succeeded , and invoice_updated . |
SUBSCRIPTION_RESTARTED |
Chargebee reactivates the canceled subscription. Chargebee webhooks triggered subscription_reactivated , subscription_reactivated_with_backdating , payment_succeeded , and invoice_updated . |
SUBSCRIPTION_IN_GRACE_PERIOD |
Chargebee extends the current subscription term. Chargebee webhooks triggered subscription_changed |
SUBSCRIPTION_ON_HOLD |
Chargebee pauses the subscription and keeps it on hold. Chargebee webhooks triggered subscription_paused |
SUBSCRIPTION_PAUSED |
If the subscription is not already paused, Chargebee pauses the subscription. Chargebee webhooks triggered subscription_paused |
SUBSCRIPTION_PAUSE_SCHEDULE_CHANGED |
If the subscription is not already paused, Chargebee schedules the subscription pause on the pause_date. Chargebee webhooks triggered subscription_pause_scheduled |
SUBSCRIPTION_REVOKED |
Chargebee cancels the subscription immediately. Chargebee webhooks triggered invoice_updated and subscription_cancelled |
SUBSCRIPTION_CANCELED |
Chargebee cancels the subscription or schedules it for cancellation. Chargebee webhooks triggered For subscription cancellation, whether immediately or at the end of the term. subscription_changed , subscription_cancellation_scheduled , subscription_cancellation_reminder , and subscription_cancelled . |
SUBSCRIPTION_EXPIRED |
Chargebee cancels the subscription immediately. Chargebee webhooks triggered subscription_cancelled |
SUBSCRIPTION_PURCHASED |
Chargebee does not support this notification. |
SUBSCRIPTION_PRICE_CHANGE_CONFIRMED |
Chargebee does not support this notification. |
SUBSCRIPTION_DEFERRED |
Chargebee does not support this notification. |
{
"subscription_id": "1000000807994664",
"customer_id": "customer-123",
"plan_id": "app_store_plan_id-USD"
}
Verifies an in-app purchase made by your customer and creates a subscription in Chargebee.
Tip
The recommended approach is to call this endpoint from the client-side app directly. However, if you are using this API to replace an existing direct integration with Apple or Google, then you may choose to call this API from the server-side.
This section provides details of the Process Purchase Command operation when performed for the Apple App Store. This API processes only the latest in-app transaction on the receipt. Sync historical subscriptions into Chargebee using bulk import of In-App Purchase receipts.
Chargebee validates the receipt
with Apple App Store and does the following once validation succeeds:
item_family.id
that matches the value Apple-App-Store, and create such a product family if not found.item.id
that matches product[id]
and if not found, create such a plan-item under the item family described in the previous step.item_price.id
that matches the concatenation of product[id]
and product[currency_code]
, and if not found, create such an item price under the item described in the previous step.id
set to original_transaction_id
start_date
set to responseBody.Latest_receipt_info.purchase_date_ms
current_term_end
set to responseBody.Latest_receipt_info.expires_date_ms
transaction.reference_number
is set to the transaction_id
of the payment.transaction.payment_method
is set to apple_pay
. This section provides details of the Process Purchase Command operation when performed for the Google Play Store. This API processes only the latest in-app transaction using the purchase token.
Chargebee validates the purchase token
with Google Play Store and does the following once validation succeeds:
item_family.id
that matches the value Google-Play-Store
, and create such a product family if not found.item.id
that matches product[id]
and if not found, create such a plan-item under the item family described in the previous step.item_price.id
that matches the concatenation of product[id]
and priceCurrencyCode
, and if not found, create such an item price under the item described in the previous step.id
set to unique identifier generated by Chargebee and mapped to token
of the SubscriptionPurchase
object from Google response.start_date
set to SubscriptionPurchase.startTimeMillis
.current_term_end
set to SubscriptionPurchase.expiryTimeMillis
.transaction.reference_number
is set to the orderId
of the payment.transaction.payment_method
is set to play_store
. {in_app_subscription_app_id}
: The handle created by Chargebee for your Apple App Store or Google Play Store app. It can be obtained from the Chargebee web app.
The following are instructions to obtain the value of the path parameter for the Apple App Store and Google Play Store.
{in_app_subscription_app_id}
, click View Keys within the Sync Overview page of the web app and use the value of generated App ID for this parameter. See detailed steps here.{in_app_subscription_app_id}
, click Set up notifications within the Sync Overview page of the web app and use the value of generated App ID for this parameter. See detailed steps here.# Create an In app subscription for Apple App Store curl https://{site}.chargebee.com/api/v2/in_app_subscriptions/cb-pjp7hcmrcbfmtjhle3smlwicu4/process_purchase_command \ -X POST \ -u {site_api_key}:\ -d receipt="Apple Based64 Encoded Receipt" \ -d product[id]="app_store_plan_id" \ -d product[price]=3399 \ -d product[price_in_decimal]="33.99" \ -d product[currency_code]="USD" \ -d customer[id]="customer-123"
token
taken from the Android device after successful creation of the in-app purchase. productId
/subscriptionId
or sku
received from the Google Play Store
.
product[id]
will be considered as the value of product[name]
.product[price_in_decimal]
.
product[price]
.
optional
parameter. The parameter value is required
if the product(s) are not imported to Chargebee from Apple App Store.
0
represents the day
,1
represents the week
, 2
represents the month
, and 3
represents the year
. This is an optional
parameter. The parameter value is required
if the product(s) are not imported to Chargebee from Apple App Store. Note
Since the Apple App Store receipt does not have the subscription renewal period information for trial subscriptions, product[period]
and product[period_unit]
are needed, to create a subscription in Chargebee with the trial period. If these parameters are not passed and the receipt has trial information then Chargebee will return a validation error.
id
in Chargebee for the customer who made this purchase via Google Play Store. If not provided, subscription_id
(random unique id) will be the customer[id]
. If the customer record is not found in Chargebee, it is created.
id
in Chargebee for the customer who made this purchase. If not provided, the value is considered to be original_transaction_id
(the transaction identifier at Apple, of the original purchase). If the customer record is not found in Chargebee, it is created.
Verifies an Apple App Store or Google Play Store in-app purchase receipt and imports subscriptions for all historical purchases made by the customer.
Tip
Anin_app_subscription
is created for every unique original_transaction_id
. Apple creates original_transaction_id
for every create, upgrade, or downgrade of the subscription. A receipt hardly contains more than 100 original_transaction_id
s. If a receipt contains more than 100 original_transaction_id
s, Chargebee creates all subscription records but this endpoint returns the first 100 records in the response. CSV upload has a file size limitation
that increases the processing time and the number of receipts. This API removes such limitations and allows you to import historical in-app subscription receipts.
This section provides details of the Import Receipt operation performed for the Apple App Store. This API processes only the historical in-app transaction receipts.
Chargebee validates the receipt
with Apple App Store and does the following once validation succeeds:
Subscriptions are imported as follows:
original_transaction_id
in the Apple receipt.original_transaction_id
s for which a subscription already exists in Chargebee.id
set to original_transaction_id
.start_date
set to the earliest purchase_date_ms
.current_term_start
set to latest purchase_date_ms
.current_term_end
set to expires_date_ms
of the same Latest_receipt_info
element with the latest purchase_date_ms
.item_price_id
set to product_id
.status
set to in_trial
if there is only one element of Latest_receipt_info
with the original_transaction_id
and the field is_trial_period
is true
, then consider the subscription is currently in trial. No invoices are created for this subscription.Invoices are imported as follows:
Latest_receipt_info
which has is_trial_period
as false
.subscription_id
set to original_transaction_id
.A transaction is imported for each invoice with the following details:
reference_number
set to the transaction_id
.payment_method
set to apple_store
.This section provides details of the Import Receipt operation performed for the Google Play Store. This API is used to process only the historical in-app purchase subscriptions.
Chargebee validates the purchase token
with Google Play Store and does the following once validation succeeds:
A subscription is imported for every unique purchase token if it is not linked to an existing purchase token
( linkedPurchaseToken
field in SubscriptionsV2.get
API Response).
Each subscription imported has the following attributes set:
id
set to a unique identifier generated by Chargebee and mapped to the token
and latestOrderId
of the SubscriptionPurchaseV2
object from Google response.
start_date
set to the earliest SubscriptionPurchaseV2.startTime
.
current_term_start
set to latest SubscriptionPurchaseV2.startTime
.
current_term_end
set to expiryTime
of the same SubscriptionPurchaseV2
element with the latest purchase.
item_price_id
set to the concatenation of product[id]
and priceCurrencyCode
from Google.
status
set to in_trial
if the free trial configuration is enabled in Google and the monetization.subscriptions.basePlans.offers.State
is Active
with a SubscriptionOfferPhase.duration
, then consider the subscription is currently in trial. No invoices are created for this subscription.
Invoices are imported as follows:
An invoice is imported to Chargebee for every new subscription and renewal of an existing subscription using latestOrderId
.
Each imported invoice has the subscription_id
set to a unique identifier generated by Chargebee and mapped to the token
and latestOrderId
.
A transaction is imported for each invoice with the following details:
transaction.reference_number
is set to the latestOrderId
.
transaction.payment_method
is set to play_store
.
{in_app_subscription_app_id}
: The handle created by Chargebee for your Apple App Store or Google Play Store app. It can be obtained from the Chargebee web app.
The following are instructions to obtain the value of the path parameter for the Apple App Store and Google Play Store.
{in_app_subscription_app_id}
, click View Keys within the Sync Overview page of the web app and use the value of generated App ID for this parameter. See detailed steps here.{in_app_subscription_app_id}
, click Set up notifications within the Sync Overview page of the web app and use the value of generated App ID for this parameter. See detailed steps here.# Import In app subscriptions for Apple App Store curl https://{site}.chargebee.com/api/v2/in_app_subscriptions/cb-pjp7hcmrcbfmtjhle3smlwicu4/import_receipt \ -X POST \ -u {site_api_key}:\ -d receipt="Apple Based64 Encoded Receipt" \ -d product[currency_code]="USD" \ -d customer[id]="customer-123" \ -d customer[email]="customer@test.com"
# Import In app subscriptions for Apple App Store curl https://{site}.chargebee.com/api/v2/in_app_subscriptions/cb-pjp7hcmrcbfmtjhle3smlwicu4/import_receipt \ -X POST \ -u {site_api_key}:\ -d receipt="Apple Based64 Encoded Receipt" \ -d product[currency_code]="USD" \ -d customer[id]="customer-123" \ -d customer[email]="customer@test.com"
Apple App Store: The Base64 encoded App Store in-app purchase receipt taken from the Apple device after successful creation of the in-app purchase subscription.
Google Play Store: The purchase token
taken from the Android device after the successful creation of an in-app purchase subscription.
Apple App Store: The currency code (ISO 4217 format) for the product.
Google Play Store: This parameter is not applicable to the Google Play Store. If the value is passed, it will return a validation error.
Apple App Store: The unique id
in Chargebee for the customer who made this purchase. If not provided, the value is considered to be original_transaction_id
(the transaction identifier at Apple, of the original purchase). If the customer record is not found in Chargebee, it is created.
Google Play Store: The unique id
of the customer who made this purchase via Google Play Store. This unique id
will be used as customer ID within Chargebee. If not provided, subscription_id
(random unique id
) will be the customer ID. If the customer ID already exists in Chargebee then subscription will be associated with this customer ID.