Introduction
Overview
The Billing Service is a comprehensive solution for managing all billing-related operations in your Go service. It provides a robust Pricing Engine that allows you to create and manage various pricing plans and features, onboard customers, and handle all billing transactions.
The service is designed to be flexible and scalable, accommodating a wide range of billing scenarios. It supports the creation of features and plans based on a variety of monthly and yearly pricing, and it integrates with popular billing engines like Stripe for seamless payment processing.
Features
Billing Accounts
Billing accounts are the primary entities in the Billing Service. They represent the billing relationship between an organization and a customer. You can create, update, delete, and retrieve billing accounts, as well as list all billing accounts for an organization.
Subscriptions
Subscriptions represent a customer's commitment to pay for a specific plan on a recurring basis. You can create, update, and cancel subscriptions, as well as list all subscriptions for a billing account.
Products and Plans
Products and plans are the building blocks of your pricing model. Features represent individual capabilities or resources that you charge for, while plans are collections of features offered at a specific price. You can create, update, and retrieve features and plans, as well as list all features and plans.
Checkouts
Checkouts represent the process of a customer agreeing to a subscription or purchasing a feature. You can create checkouts and list all checkouts for a billing account.
Billing Balance and Transactions
The Billing Service provides functionality to check the balance of a billing account and list all transactions for a billing account.
API Capabilities:
- Billing Account Management: Create, update, and delete accounts, managing information like name, email, address, and currency.
- Subscription Management: Create, update, cancel, and list subscriptions associated with specific billing accounts, including metadata for custom information.
- Feature Management: Create, update, and list features with configurable pricing models and metadata for custom information.
- Checkout Session Management: Create checkout sessions for users to purchase features or start subscriptions, with support for both types and customizable success and cancellation URLs.
- Billing Usage Reporting: Report platform usage for features with information like feature ID, amount, and timestamp for accurate billing calculations.
- Entitlement Verification: Check user access to specific features based on their account for efficient access control and restriction enforcement.
- Billing Balance Access: View the current balance of a specific billing account, providing insight into outstanding charges and payment requirements.
- Plan Management: Create, update, and list plans that define products and pricing for subscriptions.
Enabling the Billing Service
Here are the steps to enable the billing service on the platform:
- The platform admin creates features using the CreateFeature RPC.
- The platform admin creates plans using the CreatePlan RPC. These plans can be based on a variety of monthly or yearly pricing.
- The platform admin configures the billing engine (like Stripe).
Onboarding a Customer
Here are the steps to onboard a customer on this service:
- Create a billing account for the customer's organization using the CreateBillingAccount RPC.
- The customer subscribes to a plan using the CreateCheckout RPC with a CheckoutSubscriptionBody.
- The customer can also buy virtual credits using the CreateCheckout RPC with a CheckoutFeatureBody.
- The customer can check their balance using the GetBillingBalance RPC.
Onboarding
Create a Billing Account
Endpoint: POST /v1beta1/organizations/{org_id}/billing
RPC: CreateBillingAccount
Request:
{
"org_id": "org123",
"body": {
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+1234567890",
"address": {
"line1": "123 Main St",
"line2": "Apt 4B",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country": "USA"
},
"currency": "usd"
}
}
Response:
{
"billing_account": {
"id": "ba123",
"org_id": "org123",
"name": "John Doe",
"email": "john.doe@example.com",
"phone": "+1234567890",
"address": {
"line1": "123 Main St",
"line2": "Apt 4B",
"city": "New York",
"state": "NY",
"postal_code": "10001",
"country": "USA"
},
"currency": "usd",
"created_at": "2022-01-01T00:00:00Z",
"updated_at": "2022-01-01T00:00:00Z"
}
}
Create a Checkout for a Subscription
Endpoint: POST /v1beta1/organizations/{org_id}/billing/{billing_id}/checkouts
RPC: CreateCheckout
Request:
{
"org_id": "org123",
"billing_id": "ba123",
"success_url": "https://example.com/success",
"cancel_url": "https://example.com/cancel",
"subscription_body": {
"plan": "plan123",
"trail_days": 14
}
}
Response:
{
"checkout_session": {
"id": "cs123",
"checkout_url": "https://checkout.stripe.com/pay/cs_test_123",
"success_url": "https://example.com/success",
"cancel_url": "https://example.com/cancel",
"created_at": "2022-01-01T00:00:00Z",
"updated_at": "2022-01-01T00:00:00Z",
"expire_at": "2022-01-02T00:00:00Z"
}
}
Create a Checkout for a Product
Endpoint: POST /v1beta1/organizations/{org_id}/billing/{billing_id}/checkouts
RPC: CreateCheckout
Request:
{
"org_id": "org123",
"billing_id": "ba123",
"success_url": "https://example.com/success",
"cancel_url": "https://example.com/cancel",
"feature_body": {
"feature": "feature123"
}
}
Response:
{
"checkout_session": {
"id": "cs123",
"checkout_url": "https://checkout.stripe.com/pay/cs_test_123",
"success_url": "https://example.com/success",
"cancel_url": "https://example.com/cancel",
"created_at": "2022-01-01T00:00:00Z",
"updated_at": "2022-01-01T00:00:00Z",
"expire_at": "2022-01-02T00:00:00Z"
}
}
Get Billing Balance
Endpoint: GET /v1beta1/organizations/{org_id}/billing/{id}/balance
RPC: GetBillingBalance
Request:
{
"id": "ba123",
"org_id": "org123"
}
Response:
{
"balance": {
"amount": 10000,
"currency": "usd",
"updated_at": "2022-01-01T00:00:00Z"
}
}
Sample Plan and Product structure
products:
- name: support_credits
title: Support Credits
description: Support for enterprise help
behavior: credits
config:
credit_amount: 100
prices:
- name: default
amount: 20000
currency: inr
- name: basic_access
title: Basic base access
description: Base access to the platform
prices:
- name: monthly
interval: month
amount: 100
currency: inr
- name: starter_access
title: Starter base access
description: Base access to the platform
prices:
- name: monthly
interval: month
amount: 1000
currency: inr
- name: yearly
interval: year
amount: 5000
currency: inr
features:
- name: starter_feature_1
- name: starter_feature_2
- name: starter_per_seat
title: Starter per seat
description: Per seat access cost to the platform
behavior: per_seat
config:
seat_limit: 3
prices:
- name: monthly
interval: month
amount: 20
currency: inr
- name: yearly
interval: year
amount: 15
currency: inr
# - name: enterprise_access
# title: Enterprise base access for year
# description: Base access to the platform
# prices:
# - name: default
# interval: year
# amount: 8000
# currency: inr
plans:
- name: basic_monthly
title: Basic Monthly Plan
description: Basic Monthly Plan
interval: month
products:
- name: basic_access
- name: starter_yearly
title: Starter Plan
description: Starter Plan
interval: year
products:
- name: starter_access
- name: starter_monthly
title: Starter Plan
description: Starter Plan
interval: month
on_start_credits: 50
products:
- name: starter_access
- name: starter_per_seat
# - name: enterprise_yearly
# title: Enterprise Plan
# description: Enterprise Plan
# trial_days: 15
# interval: year
# products:
# - name: enterprise_access
Stripe Test clocks
Stripe allows simulating test clocks to test subscriptions, payments, and invoices. This clock needs to be created from the stripe dashboard and the clock id must be passed as a request header while creating a new billing customer account for the stripe to use this simulated clock. Once the customer is created, there is no need to pass this header and all of its subsequent subscriptions will automatically be part of the simulated clock.
Remember that once the clock expires, all of its resources also expire. Only platform users can use this header to test frontier mechanics.
Example:
X-Stripe-Test-Clock: clk_123
Virtual Credits Management
Virtual credits are a form of currency that can be used to consume services based on usage cost. They are typically used to provide a pay-as-you-go model for services where the user is charged based on the usage of the service. This is apart from subscriptions where the user is charged a fixed amount for allowing access to a set of features.
Virtual Credit Purchase
Virtual credits can be purchased by the user using the CreateCheckout
RPC with a CheckoutProductBody
request body.
Product needs to be defined with a behavior of credits
and a price defined for the product. Product also states how
much credit is provided for the price defined. Once the checkout is successful, the user's account will be credited with the
amount of credits defined in the product.
Virtual Credit Usage
When reporting usage, the user can specify the amount of credits consumed for the usage. The billing service will then
deduct the credits from the user's account balance based on the usage reported. For example, if the user triggers a
machine learning model that runs for 5 mins, the system user can report the usage as 20 units of credits. The billing
service will then deduct 20 credits from the user's account balance. If the user does not have enough credits, the
usage will be rejected. The user can then purchase more credits to continue using the service.
Usage is reported via CreateBillingUsage
RPC(/v1beta1/organizations/{org_id}/billing/{billing_id}/usages
).
Virtual Credit Balance
The user can check their credit balance using the GetBillingBalance
RPC(/v1beta1/organizations/{org_id}/billing/{billing_id}/balance
).
The response will include the amount of credits available in the user's account. The user can then decide to purchase more
credits if needed.
Reverting Virtual Credit Usage
In case of any issues with the usage reported, the user can revert the usage by using the RevertBillingUsage
RPC(/v1beta1/organizations/{org_id}/billing/{billing_id}/usages/{usage_id}/revert
).
This will add the credits back to the user's account balance. The user can then use these credits for future usage.
An example use case is if the machine learning model fails to run due to an error, the usage can be reverted and the credits
can be used for the next run. Revert can be full or partial based on the requirement.
VC Internals
Virtual credits are maintained using a double entry bookkeeping system. When credits are purchased, a credit transaction is created with the amount of credits purchased. When usage is reported, a debit transaction is created with the amount of credits consumed. The balance is calculated by summing up all the credit transactions and subtracting the sum of all the debit transactions. Each entry creates two transactions, one for the credit side and one for the debit side. This ensures that the balance is always accurate and consistent. For example, when user purchases 100 credits, a credit transaction is created with 100 credits to customer account and a debit transaction is created with 100 credits to the system account.