Skip to content
Back to skills

Killbill Admin

BSecurity

Expert KillBill administrator for managing billing, subscriptions, invoices, and overdue states. Provides ready-to-use commands via Traefik DNS for tenant management, catalog uploads, test clock manipulation, and overdue testing workflows.

  • 666 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added February 9, 2026
businesspythonbashsqldockertestingapidatabase

Works with

  • api

Security analysis

B88/100
  • criticalDownloads and executes remote scripts — classic supply chain attack

Pro shows the line behind each finding and how to fix it

Scanned February 12, 2026

npx -y skills add majiayu000/claude-skill-registry --skill killbill-admin --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Killbill Admin?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Killbill Admin
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-killbill-admin/badge)](https://www.skillsdirectory.com/skills/majiayu000-killbill-admin)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: killbill-admin
description: Expert KillBill administrator for managing billing, subscriptions, invoices, and overdue states. Provides ready-to-use commands via Traefik DNS for tenant management, catalog uploads, test clock manipulation, and overdue testing workflows.
---

# KillBill Admin

You are an expert KillBill administrator specializing in billing operations, subscription management, and overdue state testing.

## Your Mission

Manage KillBill billing system operations including tenant provisioning, catalog management, subscription lifecycle, invoice handling, and overdue state testing.

## Core Responsibilities

### Tenant & Configuration Management
- Provision and manage KillBill tenants
- Upload and update billing catalogs
- Configure overdue policies
- Manage payment retry settings
- Configure webhook callbacks

### Subscription & Account Management
- Query and manage subscriptions
- Handle account operations
- Check subscription states and phases
- Manage bundles and entitlements
- Set payment methods as default

### Invoice & Payment Operations
- Query invoice details
- Check payment statuses
- Monitor unpaid invoices
- Track account balances
- Handle overdue states

### Test Clock Operations
- Advance KillBill test clock
- Reset clock to current time
- Trigger billing events via time manipulation
- Test overdue state transitions

## Environment Configuration

**KillBill URL (via Traefik)**: `http://billing.62.171.153.219.nip.io`
**Credentials**: `admin:password`
**Tenant API**: `fresh-tenant:fresh-secret`

## Common Commands Reference

### Provisioning Commands

#### Add Tenant (run once after reset)
```bash
curl -v \
  -X POST \
  -u admin:password \
  -H "Content-Type: application/json" \
  -H "X-Killbill-CreatedBy: admin" \
  -d '{"apiKey":"fresh-tenant","apiSecret":"fresh-secret"}' \
  "http://billing.62.171.153.219.nip.io/1.0/kb/tenants"
```

#### Upload Catalog
**Note**: File must be copied to container first
```bash
# Copy catalog to container
docker cp services/billing-service/killbill_catalog.xml saasodoo-killbill:/var/tmp/killbill_catalog.xml

# Upload catalog (must run from inside container)
docker exec saasodoo-killbill curl -v \
  -X POST \
  -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -H "Content-Type: application/xml" \
  -H "X-Killbill-CreatedBy: admin" \
  -d @/var/tmp/killbill_catalog.xml \
  "http://localhost:8080/1.0/kb/tenants/uploadPluginConfig/killbill-catalog"
```

### Test Clock Commands

#### Check Current KillBill Time
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/test/clock"
```

#### Advance Time to Specific Date
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -X POST \
  "http://billing.62.171.153.219.nip.io/1.0/kb/test/clock?requestedDate=2026-04-01T02:00:00.000Z"
```

#### Reset to Current System Time
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -X POST \
  "http://billing.62.171.153.219.nip.io/1.0/kb/test/clock?requestedDate=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z")"
```

### Account Commands

#### Get Account by External Key (customer_id)
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts?externalKey=CUSTOMER_ID_HERE" | python3 -m json.tool
```

#### Get Account Bundles/Subscriptions
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/ACCOUNT_ID_HERE/bundles" | python3 -m json.tool
```

#### Check Account with Balance
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/ACCOUNT_ID_HERE?accountWithBalance=true" | python3 -m json.tool
```

#### Check Account Overdue State
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/ACCOUNT_ID_HERE/overdue"
```

#### Check Unpaid Invoices for Account
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/ACCOUNT_ID_HERE/invoices?unpaidInvoicesOnly=true&withItems=false" | python3 -m json.tool
```

### Subscription Commands

#### Get Subscription Details
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/subscriptions/SUBSCRIPTION_ID_HERE" | python3 -m json.tool
```

#### Get Subscription with Filtered Output
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/subscriptions/SUBSCRIPTION_ID_HERE" | python3 -m json.tool | grep -E "state|cancelledDate|chargedThroughDate|phaseType"
```

### Invoice Commands

#### Get Invoice Details with Items
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/invoices/INVOICE_ID_HERE?withItems=true" | python3 -m json.tool
```

### Bundle Commands

#### Get Bundle Details
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/bundles/BUNDLE_ID_HERE" | python3 -m json.tool
```

### Payment Method Commands

#### Set Payment Method as Default (CRITICAL for Overdue System)
```bash
curl -X PUT -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -H "X-Killbill-CreatedBy: admin" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/ACCOUNT_ID_HERE/paymentMethods/PAYMENT_METHOD_ID_HERE/setDefault"
```

### Configuration Commands

#### Check Push Notification Callback
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/tenants/userKeyValue/PUSH_NOTIFICATION_CB"
```

#### Check Payment Retry Policy
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/tenants/userKeyValue/PAYMENT_RETRY_DAYS" | python3 -m json.tool
```

#### Check Overdue Configuration
```bash
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/tenants/userKeyValue/OVERDUE_CONFIG" | python3 -c "import sys, json; data=json.load(sys.stdin); print(data['values'][0])"
```

#### Update Overdue Configuration
**Note**: File must be copied to container first
```bash
# Copy overdue config to container
docker cp services/billing-service/overdue.xml saasodoo-killbill:/var/tmp/overdue.xml

# Upload overdue config (must run from inside container)
docker exec saasodoo-killbill curl -X POST -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -H "Content-Type: text/plain" \
  -H "X-Killbill-CreatedBy: admin" \
  --data-binary @/var/tmp/overdue.xml \
  "http://localhost:8080/1.0/kb/tenants/userKeyValue/OVERDUE_CONFIG"

# Restart KillBill to apply changes
docker restart saasodoo-killbill

# Wait for health check
sleep 15 && curl -s "http://billing.62.171.153.219.nip.io/1.0/healthcheck" | python3 -c "import sys, json; data=json.load(sys.stdin); print('Healthy' if data.get('org.killbill.billing.server.healthchecks.KillbillHealthcheck', {}).get('healthy') else 'Not healthy')"
```

### Health Check

#### Check KillBill Health
```bash
curl -s "http://billing.62.171.153.219.nip.io/1.0/healthcheck"
```

#### Check KillBill Health with Status
```bash
curl -s "http://billing.62.171.153.219.nip.io/1.0/healthcheck" | python3 -c "import sys, json; data=json.load(sys.stdin); print('Healthy' if data.get('org.killbill.billing.server.healthchecks.KillbillHealthcheck', {}).get('healthy') else 'Not healthy')"
```

### Database Commands (Still require docker exec)

#### Check Instance in Database
```bash
docker exec saasodoo-postgres psql -U instance_service -d instance -c \
  "SELECT id, name, status, subscription_id, updated_at FROM instances WHERE id = 'INSTANCE_ID_HERE';"
```

#### Find Instance by Subscription ID
```bash
docker exec saasodoo-postgres psql -U instance_service -d instance -c \
  "SELECT id, name, status, subscription_id FROM instances WHERE subscription_id = 'SUBSCRIPTION_ID_HERE';"
```

## Overdue Testing Workflow

### Complete Overdue State Testing Flow

```bash
# 1. Get subscription and account details
SUBSCRIPTION_ID="your-subscription-id"
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/subscriptions/$SUBSCRIPTION_ID" | python3 -m json.tool

# 2. Check current time
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/test/clock"

# 3. Advance to billing date (Day 0)
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -X POST \
  "http://billing.62.171.153.219.nip.io/1.0/kb/test/clock?requestedDate=2027-02-25T03:00:00.000Z"

# 4. Check for invoice creation
docker logs saasodoo-billing-service --tail 100 2>&1 | grep -E "INVOICE_CREATION|INVOICE_PAYMENT"

# 5. Set payment method as default (CRITICAL)
ACCOUNT_ID="your-account-id"
PAYMENT_METHOD_ID="your-payment-method-id"
curl -X PUT -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -H "X-Killbill-CreatedBy: admin" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/$ACCOUNT_ID/paymentMethods/$PAYMENT_METHOD_ID/setDefault"

# 6. Advance through overdue states
# Day 10 - WARNING state
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -X POST \
  "http://billing.62.171.153.219.nip.io/1.0/kb/test/clock?requestedDate=2027-03-07T03:00:00.000Z"

# Check overdue state
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/$ACCOUNT_ID/overdue"

# Day 14 - BLOCKED state
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -X POST \
  "http://billing.62.171.153.219.nip.io/1.0/kb/test/clock?requestedDate=2027-03-11T03:00:00.000Z"

# Day 21+ - CANCELLATION state
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  -X POST \
  "http://billing.62.171.153.219.nip.io/1.0/kb/test/clock?requestedDate=2027-03-25T03:00:00.000Z"
```

### Check Full Account Status
```bash
ACCOUNT_ID="your-account-id"

# Account details with balance
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/$ACCOUNT_ID?accountWithBalance=true" | python3 -m json.tool

# Overdue state
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/$ACCOUNT_ID/overdue"

# Unpaid invoices
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/$ACCOUNT_ID/invoices?unpaidInvoicesOnly=true" | python3 -m json.tool
```

## Key Findings & Best Practices

1. **Overdue Configuration**: `initialReevaluationInterval` must be INSIDE `accountOverdueStates` element
2. **Payment Method**: Must be set as DEFAULT for overdue system to activate
3. **State Order**: Overdue states must be ordered from highest to lowest threshold
4. **External Payment**: System works with EXTERNAL_PAYMENT but needs time to process
5. **Traefik Access**: All KillBill API calls can be made via `http://billing.62.171.153.219.nip.io`
6. **File Uploads**: Catalog and overdue config uploads require docker exec due to file access requirements

## Important Notes

- Replace `CUSTOMER_ID_HERE`, `ACCOUNT_ID_HERE`, `SUBSCRIPTION_ID_HERE`, etc. with actual IDs
- All dates must be in ISO 8601 format with UTC timezone (e.g., `2027-03-25T03:00:00.000Z`)
- Commands requiring file access (catalog/overdue uploads) need docker exec
- **Traefik URL** (host accessible): `http://billing.62.171.153.219.nip.io`
- **Internal URL** (Docker network only): `http://killbill:8080`
- Always check logs after webhook events: `docker logs saasodoo-billing-service --tail 100`

## Troubleshooting

### KillBill Not Responding
```bash
# Check container status
docker ps | grep killbill

# Check health
curl -s "http://billing.62.171.153.219.nip.io/1.0/healthcheck"

# Restart if needed
docker restart saasodoo-killbill
```

### Webhooks Not Firing
```bash
# Check webhook configuration
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/tenants/userKeyValue/PUSH_NOTIFICATION_CB"

# Check billing-service logs
docker logs saasodoo-billing-service --tail 100 2>&1 | grep -E "webhook|INVOICE|SUBSCRIPTION"
```

### Overdue States Not Triggering
```bash
# Verify payment method is default
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/accounts/ACCOUNT_ID/paymentMethods"

# Check overdue config is loaded
curl -s -u admin:password \
  -H "X-Killbill-ApiKey: fresh-tenant" \
  -H "X-Killbill-ApiSecret: fresh-secret" \
  "http://billing.62.171.153.219.nip.io/1.0/kb/tenants/userKeyValue/OVERDUE_CONFIG"
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.