Used to check for browser translation.
用于检测浏览器翻译。
ブラウザの翻訳を検出する
Usage Guides

Credit Billing


PaymentKit provides a flexible system for implementing credit-based or prepaid billing. This model allows you to charge customers based on their consumption of services, such as API calls, data storage, or compute time. This guide will walk you through the entire workflow, from defining what to measure to tracking usage and managing customer balances.

The credit billing system is built on four core resources:

Credit Billing Workflow#

The following diagram illustrates the typical lifecycle of credit-based billing in PaymentKit:

Developer creates a Meter

PaymentKit System

Developer grants credits to a Customer

Customer credit balance is updated

User action triggers usage

Your Application

App reports usage with a Meter Event

PaymentKit processes the event

Finds the applicable credit grant

Consumes credits and creates a transaction

Customer balance is reduced

Developer monitors balance and history


1. Define Usage with Meters#

A Meter is a resource that defines how you measure usage for a specific service. You create a meter for each distinct type of usage you want to track.

Use the payment.meters.create() method to create a new meter.

Parameters

Name

Type

Description

name

string

A human-readable name for the meter (e.g., 'API Calls').

event_name

string

A unique identifier for the event that this meter tracks (e.g., 'api_calls'). This is used when reporting usage.

aggregation_method

string

How to aggregate usage events. Can be sum (adds up all values), count (counts the number of events), or last (uses the value of the most recent event). Defaults to sum.

unit

string

The unit of measurement for the usage (e.g., 'calls', 'bytes').

description

string

An optional description of what the meter tracks.

Example

import payment from '@blocklet/payment-js';

async function createMeter() {
try {
const meter = await payment.meters.create({
name: 'API Calls',
event_name: 'api_calls',
aggregation_method: 'sum',
unit: 'calls',
description: 'Tracks the number of API calls made by a user.'
});
console.log('Meter created:', meter);
} catch (error) {
console.error('Error creating meter:', error.message);
}
}

createMeter();

Example Response

{
"id": "mtr_xxxxxxxxxxxxxx",
"object": "meter",
"name": "API Calls",
"event_name": "api_calls",
"aggregation_method": "sum",
"status": "active",
"unit": "calls",
"description": "Tracks the number of API calls made by a user.",
"livemode": false,
"metadata": {},
"created_at": "2023-10-27T10:00:00.000Z",
"updated_at": "2023-10-27T10:00:00.000Z"
}

2. Issue Credits with Credit Grants#

Once you have a meter, you can grant credits to your customers. A Credit Grant represents a specific amount of credit added to a customer's balance. Credits can be categorized as paid (purchased by the customer) or promotional (given for free).

Use payment.creditGrants.create() to issue credits.

Parameters

Name

Type

Description

customer_id

string

The ID of the customer receiving the credits.

amount

string

The number of credits to grant.

currency_id

string

The currency of the credits. This must match a currency supported by your system.

category

string

The category of the grant. Must be paid or promotional.

name

string

A name for the credit grant, for internal reference (e.g., 'New User Bonus').

expires_at

number

Optional. A Unix timestamp indicating when the credits expire.

Example

import payment from '@blocklet/payment-js';

async function grantCredits() {
try {
const thirtyDaysFromNow = Math.floor(Date.now() / 1000) + (30 * 24 * 60 * 60);
const creditGrant = await payment.creditGrants.create({
customer_id: 'cus_xxx',
amount: '1000',
currency_id: 'pc_xxx',
category: 'promotional',
name: 'New user bonus credits',
expires_at: thirtyDaysFromNow
});
console.log('Credit Grant created:', creditGrant);
} catch (error) {
console.error('Error creating credit grant:', error.message);
}
}

grantCredits();

Example Response

{
"id": "cg_xxxxxxxxxxxxxx",
"object": "credit_grant",
"amount": "1000",
"currency_id": "pc_xxx",
"customer_id": "cus_xxx",
"category": "promotional",
"status": "granted",
"remaining_amount": "1000",
"expires_at": 1729852800,
"livemode": false,
"metadata": {},
"created_at": "2023-10-27T10:05:00.000Z",
"updated_at": "2023-10-27T10:05:00.000Z"
}

3. Report Usage with Meter Events#

As your customers use your service, you report their usage by creating Meter Events. PaymentKit automatically deducts the corresponding amount from the customer's credit balance.

Use payment.meterEvents.create() to report usage. It is crucial to provide a unique identifier for each event to prevent duplicate reporting (idempotency).

Parameters

Name

Type

Description

event_name

string

The event_name of the meter this usage corresponds to.

payload

object

An object containing the usage details.

payload.customer_id

string

The ID of the customer who consumed the service.

payload.value

string

The amount of usage to report.

identifier

string

A unique string to identify this specific usage event and prevent duplicates.

timestamp

number

Optional. A Unix timestamp for when the usage occurred. Defaults to the current time.

Example

import payment from '@blocklet/payment-js';

async function reportUsage() {
try {
const meterEvent = await payment.meterEvents.create({
event_name: 'api_calls',
payload: {
customer_id: 'cus_xxx',
value: '10'
},
identifier: `unique_event_${Date.now()}`,
timestamp: Math.floor(Date.now() / 1000)
});
console.log('Meter Event created:', meterEvent);
} catch (error) {
console.error('Error creating meter event:', error.message);
}
}

reportUsage();

Example Response

{
"id": "mevt_xxxxxxxxxxxxxx",
"event_name": "api_calls",
"payload": {
"customer_id": "cus_xxx",
"value": "10"
},
"identifier": "unique_event_1698372300000",
"timestamp": 1698372300,
"livemode": false,
"status": "completed",
"credit_consumed": "10",
"created_at": "2023-10-27T10:10:00.000Z",
"updated_at": "2023-10-27T10:10:00.000Z"
}

4. Monitor Balances and History#

You can monitor a customer's credit balance and view their transaction history to understand their usage patterns.

Check Credit Balance

Use payment.creditGrants.summary() to get a summary of a customer's available and pending credits, grouped by currency.

import payment from '@blocklet/payment-js';

async function checkBalance() {
try {
const creditSummary = await payment.creditGrants.summary({
customer_id: 'cus_xxx'
});
console.log('Credit Summary:', creditSummary);
} catch (error) {
console.error('Error fetching credit summary:', error.message);
}
}

checkBalance();

Example Response

{
"customer_id": "cus_xxx",
"total_balance": {
"pc_xxx": {
"currency_id": "pc_xxx",
"total_amount": "1000",
"available_amount": "990",
"pending_amount": "0",
"currency": {
"id": "pc_xxx",
"symbol": "CRDT",
"decimal": 18
}
}
}
}

View Transaction History

Use payment.creditTransactions.list() to retrieve a paginated list of all credit transactions for a customer, including grants, consumptions, and expirations.

import payment from '@blocklet/payment-js';

async function listTransactions() {
try {
const transactions = await payment.creditTransactions.list({
customer_id: 'cus_xxx',
pageSize: 10
});
console.log('Credit Transactions:', transactions.list);
} catch (error) {
console.error('Error listing credit transactions:', error.message);
}
}

listTransactions();

Example Response

{
"count": 2,
"list": [
{
"id": "ctxn_xxxxxxxxxxxxxx",
"type": "consumption",
"amount": "-10",
"running_balance": "990",
"description": "Usage of API Calls",
"created_at": "2023-10-27T10:10:00.000Z"
},
{
"id": "ctxn_yyyyyyyyyyyyyy",
"type": "grant",
"amount": "1000",
"running_balance": "1000",
"description": "New user bonus credits",
"created_at": "2023-10-27T10:05:00.000Z"
}
]
}


By following these steps, you can successfully implement a complete credit-based billing system. To explore all available options for each function, refer to the detailed API Reference. To receive real-time notifications for credit-related events, such as a low balance, see the Webhooks guide.