Manual Billing Workflow Execution
This guide provides information for manually executing billing workflows using Temporal CLI or other workflow execution tools.
Prerequisites
- Access to Temporal cluster
- Proper authentication and permissions
- Understanding of workspace IDs and billing periods
Common Parameters
All billing workflows use the following task queue:
- Task Queue:
BILLING_TASK_QUEUE
Workflows
BillingListWorkspaceBalanceWorkflow
Retrieves invoice line items and balance information for a specific workspace and billing period.
Workflow Details:
- Task Queue:
BILLING_TASK_QUEUE - Workflow Type:
BillingListWorkspaceBalanceWorkflow
Payload Example:
{
"workspace_id": "123e4567-e89b-12d3-a456-426614174000",
"billing_period": "2024-01",
"billing_period_start": "2024-01-01T00:00:00Z",
"billing_period_end": "2024-01-31T23:59:59.999Z"
}
Parameters:
workspace_id(string): UUID of the workspacebilling_period(string): Billing period in YYYY-MM formatbilling_period_start(time): Start of billing period (ISO 8601)billing_period_end(time): End of billing period (ISO 8601)
Expected Result:
{
"line_items": [
{
"description": "Runner Usage - tenki-standard-autoscale",
"runner_label": "tenki-standard-autoscale",
"quantity": 120,
"unit_price": 0.01,
"amount": 1.2
}
],
"total_amount": 1.2,
"timestamp": "2024-01-31T23:59:59Z"
}
BillingCycleScheduleWorkflow
Parent workflow that orchestrates billing cycles for all workspaces. Typically triggered by a scheduled cron job.
Workflow Details:
- Task Queue:
BILLING_TASK_QUEUE - Workflow Type:
BillingCycleScheduleWorkflow
Payload Example:
{
"luxor_only": false,
"exclude_workspaces": ["123e4567-e89b-12d3-a456-426614174000", "987fcdeb-51a2-43d1-b567-123456789abc"]
}
Parameters:
luxor_only(boolean, optional): Filter to process only Luxor customers (is_luxor = true)exclude_workspaces(array of UUIDs, optional): List of workspace IDs to exclude from billing cycle
Behavior:
- Queries all active workspaces with billing accounts
- Spawns individual
BillingCycleWorkflowchild workflows for each workspace - Handles the current billing period automatically
BillingCycleWorkflow
Individual workspace billing processing workflow. Handles invoice generation, charging, and payment processing for a single workspace.
Workflow Details:
- Task Queue:
BILLING_TASK_QUEUE - Workflow Type:
BillingCycleWorkflow
Payload Example:
{
"workspace_id": "123e4567-e89b-12d3-a456-426614174000",
"billing_period": "2024-01",
"billing_period_start": "2024-01-01T00:00:00Z",
"billing_period_end": "2024-01-31T23:59:59.999Z"
}
Parameters:
workspace_id(UUID): The workspace to process billing forbilling_period(string): Billing period in YYYY-MM formatbilling_period_start(time): Start of billing period (ISO 8601)billing_period_end(time): End of billing period (ISO 8601)
Workflow Steps:
- Generate Stripe invoice with line items
- Process invoice and attempt payment
- Handle TigerBeetle accounting transfers
- Create billing payment records
- Process promotional credit adjustments
- Reset monthly free credits
BillingPaymentReversalWorkflow
Reverses a payment by creating a reversal transfer in TigerBeetle and updating the payment status to ‘reversed’. Used for refunds, chargebacks, or administrative corrections.
Workflow Details:
- Task Queue:
BILLING_TASK_QUEUE - Workflow Type:
BillingPaymentReversalWorkflow
Payload Example:
{
"payment_id": "123e4567-e89b-12d3-a456-426614174000",
"workspace_id": "987fcdeb-51a2-43d1-b567-123456789abc",
"reason": "Customer requested refund",
"initiated_by_email": "admin@tenki.cloud"
}
Parameters:
payment_id(UUID): The payment ID to reverseworkspace_id(UUID): The workspace that owns the paymentreason(string): Reason for the reversal (required)initiated_by_email(string): Email of the person initiating the reversal (required)
Expected Result:
{
"success": true,
"reversal_transfer_id": "base64-encoded-transfer-id",
"original_amount": "12.50",
"reversed_at": "2024-01-31T15:30:00Z"
}
Workflow Steps:
- Validate required parameters (payment_id, workspace_id, reason, initiated_by_email)
- Lookup payment details from database and TigerBeetle
- Create reversal transfer in TigerBeetle using original transfer details
- Update payment status to ‘reversed’ with reversal details
BillingUsageReversalWorkflow
Reverses a usage event by creating a reversal transfer in TigerBeetle and deleting the usage event record. Used for correcting erroneous charges or administrative adjustments to usage records.
Workflow Details:
- Task Queue:
BILLING_TASK_QUEUE - Workflow Type:
BillingUsageReversalWorkflow
Payload Example:
{
"usage_event_id": "123e4567-e89b-12d3-a456-426614174000",
"workspace_id": "987fcdeb-51a2-43d1-b567-123456789abc",
"reason": "Incorrect runner charge - job failed",
"initiated_by_email": "admin@tenki.cloud"
}
Parameters:
usage_event_id(UUID): The usage event ID to reverse (required)workspace_id(UUID): The workspace that owns the usage event (required)reason(string): Reason for the reversal (required)initiated_by_email(string): Email of the person initiating the reversal (required)
Expected Result:
{
"success": true,
"reversal_transfer_id": "base64-encoded-transfer-id",
"original_amount": "0.50",
"reversed_at": "2024-01-31T15:30:00Z"
}
Workflow Steps:
- Validate required parameters (usage_event_id, workspace_id, reason, initiated_by_email)
- Fetch usage event details from database
- Verify workspace ownership matches provided workspace_id
- Lookup actual transfer details from TigerBeetle
- Create reversal transfer in TigerBeetle using original transfer amounts
- Delete the usage event record from database
Important Notes:
- Unlike payment reversals, usage event reversals permanently delete the record (no audit trail in the usage_events table)
- The reversal transfer in TigerBeetle maintains the financial audit trail
- Workspace ID validation ensures the usage event belongs to the specified workspace
Temporal CLI Examples
Execute BillingListWorkspaceBalanceWorkflow
temporal workflow start \
--task-queue BILLING_TASK_QUEUE \
--type BillingListWorkspaceBalanceWorkflow \
--input '{
"workspace_id": "123e4567-e89b-12d3-a456-426614174000",
"billing_period": "2024-01",
"billing_period_start": "2024-01-01T00:00:00Z",
"billing_period_end": "2024-01-31T23:59:59.999Z"
}'
Execute BillingCycleScheduleWorkflow
temporal workflow start \
--task-queue BILLING_TASK_QUEUE \
--type BillingCycleScheduleWorkflow \
--input '{
"luxor_only": false,
"exclude_workspaces": []
}'
Execute BillingCycleWorkflow
temporal workflow start \
--task-queue BILLING_TASK_QUEUE \
--type BillingCycleWorkflow \
--input '{
"workspace_id": "123e4567-e89b-12d3-a456-426614174000",
"billing_period": "2024-01",
"billing_period_start": "2024-01-01T00:00:00Z",
"billing_period_end": "2024-01-31T23:59:59.999Z"
}'
Execute BillingPaymentReversalWorkflow
temporal workflow start \
--task-queue BILLING_TASK_QUEUE \
--type BillingPaymentReversalWorkflow \
--input '{
"payment_id": "123e4567-e89b-12d3-a456-426614174000",
"workspace_id": "987fcdeb-51a2-43d1-b567-123456789abc",
"reason": "Customer requested refund",
"initiated_by_email": "admin@tenki.cloud"
}'
Execute BillingUsageReversalWorkflow
temporal workflow start \
--task-queue BILLING_TASK_QUEUE \
--type BillingUsageReversalWorkflow \
--input '{
"usage_event_id": "123e4567-e89b-12d3-a456-426614174000",
"workspace_id": "987fcdeb-51a2-43d1-b567-123456789abc",
"reason": "Incorrect runner charge - job failed",
"initiated_by_email": "admin@tenki.cloud"
}'
Notes
- All timestamps should be in UTC
- Workspace IDs must be valid UUIDs
- Billing periods follow YYYY-MM format
- The
BillingCycleScheduleWorkflowis typically run automatically via Temporal schedules - Individual
BillingCycleWorkflowexecutions can be run manually for specific workspaces - Use
BillingListWorkspaceBalanceWorkflowto preview billing information before processing