Building Scalable Subscription Service

A simple scalable design for building subscription service for one time and recurring renewal SKUs

ADARSH KUMAR
8 min readJan 29, 2022

What is subscription

  • Subscription is collection of premium benefits given to set/segment of users who buy a plan from a company and pay its fee periodically.
Sample Group 1: (ex: plan group for taxi vouchers)
com.samplegroup1.medium.pro (Highest tier)
com.samplegroup1.medium.lite (Mid Level tier)
com.samplegroup1.medium.starer (Lowest tier)
Sample Group 2: (ex: plan group for food delivery vouchers)
com.samplegroup2.medium.pro (Highest tier)
com.samplegroup2.medium.lite (Mid Level tier)
com.samplegroup2.medium.starer (Lowest tier)
These 2 groups could be targetted to different or same set of users. User can opt/purchase 1 plan per group.

What to expect

  • High level design (HLD)of subscription service (or subscription platform) and associated components

Requirements

Before we talk about design, let’s set some clear requirements seen in common subscription platform.

  • Organisation can define their SKUs (purchasable products) with per billing cycles length/ cost/ group (such as user can switch between 1 SKU per group)/ rank (order in which this SKU will be shown in UI). With other metadata such as tax/ user segment targeting / discounted price in terms of billing cycle.
  • User can choose their payment type to pay from the available payment methods.
  • User should be able use benefit when paid for the billing cycle.
  • Benefits should be paused/ on-hold when billing failed for fixed duration. And eventually cancel the plan.
  • User should get notification on every successful/ failed transaction for the subscription.
  • Other DA services should be consistent with the subscription (eventually) revenue.

What is the role of subscription platform

It is a light weight service which abstracts the subscription life cycle out of fulfilment services such as SKU_Service1 (and more). It takes cycles of payment and triggering fulfilment events during the entire lifecycle of the user’s purchase. It primarily require following components to work.

  • Maintain record of SKU with metadata (such as SKU_ID, Billing Duration, Fee , Renewal Duration, Start Date, End Date) .
  • Expose API for fulfilment services to plug into subscription platform seamlessly.
  • All users to buy and auto-renew their subscription and inform fulfilment services to fulfil benefits via events.
  • Subscription platform should take care of the lifecycle of subscription and integrated fulfilment services should take care of benefits.
  • Cron : Cron can be considered as a small module within subscription (or any other mechanism which can trigger subscription api to do timely operations on the defined time)
  • Events : Event’s determine various lifecycle of the subscription (such as purchase/ renewal / expiry and so on). Each event will contain, unique subscriptionID (such as ABC123),billingID ( such as ABC123.1)and eventType (such as PURCHASED/ RENEWED etc) along with a token (string which fulfilment service can use to call subscription and get entire details of the subscription lifecycle)
  • Payment : This service is abstraction of all the payment related api for single and recurrent charges from sync to async. For async payment we will assume payment service will publish a message in queue which will be consumed by subscription.
  • Notification : Notification (push or email) can be handled with these events directly by notification service or fulfilment services has handle it by them selves as they might want to add more personalised details for the users

Components or modules

These components can be seen as bird eye view of entire ecosystem for subscription service.

  • Orchestration : Service that aggregates the in/out traffic for user and CMS team to manage new/existing SKUs. Any new SKU services need to be plugged here to make use of this ecosystem. Some apps has subscriptions owned by different teams, here orchestration service unify them in 1 place.
  • SKU services: This service manage the SKUs and its associated benefits and counters such as used benefits or remaining benefits. There could be multiple SKU services which can plug to subscription to manage the cycle.
  • Subscription (or subscription platform): This is a light weight service which holds/manage user’s subscription cycles(including payment) / refund/ cancellation/ retries. This service does not understand end to end details of SKU ( It just understand SKU id, SKU billing period, SKU cost and these information are saved via API provides for subscription for SKU services). Other SKU services (or fulfilment services) will receive token (or purchase token) to get details about a subscription by passing token to subscription api.
  • Payment : Subscription service here will interact with payment to deduct/ charge for next billing cycle.
  • Web hook gateway: Subscription service will call web hook gateway for finite times which will handle scenario where downstream services are down.
  • Notification : This service can consume from webhook gateway queues and send notification to end user using firebase/ Apn or any 3rd party services.

High level design

  • Admin create a SKU
Fig 1. Admin create a SKU in a GROUP
  • User purchase a SKU (First time)
Fig 2. User purchasing a SKU in GROUP
  • Auto renewal of user’s subscription SKU (First or any successful renewal)
Fig 3. Cron Taking care of auto renewal with recurrent charge
  • Failed auto renewal of user’s subscription SKU
Fig 4. Holding/ Pause SKU benefit when payment fail due to payment issues
  • User cancels a SKU for next billing cycle
Fig 5. User cancels his subscription (SKU). He will continue to have benefits for current billing cycle
  • User resubscribe after cancellation
Fig 6. User resubscribe to same SKU after cancellation within the active billing cycle. Auto renew will happen as usual
  • User’s subscription expiry
Fig 7. If user cancels his SKU, then his benefits will expire at the end of billing cycle
  • User’s subscription plan change (upgrade or downgrade) : Organisation can choose if plan change has to be immediate or deferred at the end of billing cycle
Fig 8.1. Deferred Upgrade/ Downgrade SKU in a GROUP
Fig 8.2. Complete Upgrade/ Downgrade SKU in a GROUP

Events from subscription platform

  • PURCHASED : This event is pushed when user purchase his first SKU in group. If user purchase another SKU in the group (which another is still active, SWITCH INIT is triggered). Fulfilment services can choose to handle this event (for async fulfilment of benefits) or their api call (for sync fulfilment of benefits).
  • RENEWED : This event is pushed when a user’s subscription is at the end of billing cycle and user (or company ) has not canceled (or stopped) the SKU which was purchased (auto renewal is on). Subscription service call the recurrent charge api of payment and after successful sync or async acknowledgment from payment service, status is updated in subscription and message is pushed.
  • SWITCH_INIT : As user may like to upgrade or downgrade a plan. Companies can choose to fulfil such upgrade or downgrade immediately or deferred at the end of billing cycle. In case of deferred with first SWITCH_INIT so that subscription and fulfilment services are aware of this planned change of SKU in a group.
  • SWITCH_COMPLETED : This event is pushed when user’s subscription is at the end of billing cycle and auto renewal is still on. Subscription service check if it is normal renewal or user had planned for switch to another SKU in the group. If there was a SWITCH_INIT, then SWITCH_COMPLETED is pushed to let fulfilment service know that they need to cancel SKU_OLD and fulfil SKU_NEW in the group.
  • CANCELED: When user is not happy with the SKU, then can cancel it anytime (auto renew will become off) but subscription will be active till the end of current billing cycle. Save this information in subscription and make auto renew off and then push CANCEL event for fulfilment service. There will be a follow up expiry event at the end of billing cycle.
  • REFUNDED: Upon user’s genuine complaint, admin can refund the amount for a particular billing cycle to the user (partial or full). Depending upon the use case then can also opt to expire the subscription immediately. When admin does it, this information is save and then pushed as event for fulfilment service. Fulfilment service should end subscription only in case on EXPIRED event.
  • RESUBSCRIBED: User can choose to continue his canceled plan (still active in his current billing cycle). In such scenario, auto renew is marked ON again and event is pushed.
  • ON_HOLD: When user’s payment failed due to various reason, this event is pushed to fulfilment services to pause the benefits for the users and notify them to fix their payment.
  • EXPIRED: Well, this the break up moment between the user and company, as user choose not to continue with plan and want to leave the SKU.

Subscription lifecycle

  • Active : User is in good standing and has access to the subscription. SKU services will receive PURCHASED event. Then subscription is renewed every billing cycle and RENEWED event is published for SKU services.
  • Cancelled : User has cancelled but still has access until expiration, subscription publish CANCELED event for SKU services, and another EXPIRED event at the end of the billing cycle.
  • On hold : User experienced a payment issue, and no longer has access while Google is retrying the payment method, ON_HOLD is published and SKU services will pause the benefits until next event.
  • Expired : User has cancelled and lost access to the subscription. The user is considered churned at expiration (he/she canceled or plan is discontinued) EXPIRED event is published for SKU services to revoke all the benefits.

Ref : https://developer.android.com/google/play/billing/subscriptions#lifecycle

Subscription platform token’s and order id

  • Token (or Purchase token) : A purchase token is a string that represents a buyer’s entitlement to a product on Subscription platform. It indicates that a user is entitled to a specific product that is represented by a SKU. You can use the purchase token with the Developer API
  • Order ID : An Order ID is a string that represents a financial transaction on Subscription platform. You can use the Order ID to manage refunds in the used in sales and payout reports. Order numbers for subscription renewals contain an additional integer that represents a specific renewal instance. For example, an initial subscription Order ID might be SUBS.1234-5678-9012-34567..0 with subsequent Order IDs being SUBS.1234-5678-9012-34567..1 (first renewal), SUBS.1234-5678-9012-34567..2 (second renewal), and so on

Ref : https://developer.android.com/google/play/billing/integrate#tokens

Developer APIs in subscription platform

--

--

ADARSH KUMAR
ADARSH KUMAR

No responses yet