# Billing

Stripe's advanced billing namespace provides sophisticated usage metering, credit management, and billing alerting capabilities. These features enable complex billing scenarios including usage-based pricing, prepaid credits, and automated billing monitoring.

## Usage Metering

### Billing.Meters

Define and manage usage meters for tracking billable events:

```typescript { .api }
interface BillingMeter {
  id: string;
  object: 'billing.meter';
  created: number;
  display_name: string;
  event_name: string;
  status: 'active' | 'inactive';
  customer_mapping: {
    event_payload_key: string;
    type: 'by_id';
  };
  default_aggregation: {
    formula: 'count' | 'sum';
  };
  value_settings?: {
    event_payload_key?: string;
  };
}

// Create usage meter
const meter = await stripe.billing.meters.create({
  display_name: 'API Requests',
  event_name: 'api_request',
  customer_mapping: {
    event_payload_key: 'customer_id',
    type: 'by_id'
  },
  default_aggregation: {
    formula: 'count'
  }
});

// Create value-based meter
const valueMeter = await stripe.billing.meters.create({
  display_name: 'Storage Usage (GB)',
  event_name: 'storage_used',
  customer_mapping: {
    event_payload_key: 'stripe_customer_id',
    type: 'by_id'
  },
  default_aggregation: {
    formula: 'sum'
  },
  value_settings: {
    event_payload_key: 'gb_used'
  }
});

// Retrieve meter
const retrieved = await stripe.billing.meters.retrieve('mtr_123');

// Update meter
const updated = await stripe.billing.meters.update('mtr_123', {
  display_name: 'Updated API Request Meter'
});

// List meters
const meters = await stripe.billing.meters.list({
  status: 'active',
  limit: 10
});

// Deactivate meter
const deactivated = await stripe.billing.meters.deactivate('mtr_123');

// Reactivate meter
const reactivated = await stripe.billing.meters.reactivate('mtr_123');

// List event summaries
const eventSummaries = await stripe.billing.meters.listEventSummaries(
  'mtr_123',
  {
    customer: 'cus_123',
    start_time: Math.floor(Date.now() / 1000) - 86400 * 30, // Last 30 days
    end_time: Math.floor(Date.now() / 1000)
  }
);
```

### Billing.MeterEvents

Record usage events for billing:

```typescript { .api }
interface BillingMeterEvent {
  object: 'billing.meter_event';
  created: number;
  event_name: string;
  identifier: string;
  payload: {
    [key: string]: string;
  };
}

// Create meter event
const meterEvent = await stripe.billing.meterEvents.create({
  event_name: 'api_request',
  payload: {
    customer_id: 'cus_123',
    endpoint: '/api/users',
    method: 'GET'
  }
});

// Create value-based meter event
const valueMeterEvent = await stripe.billing.meterEvents.create({
  event_name: 'storage_used',
  payload: {
    stripe_customer_id: 'cus_123',
    gb_used: '2.5',
    timestamp: Math.floor(Date.now() / 1000).toString()
  }
});

// Batch meter events (recommended for high volume)
const events = [
  {
    event_name: 'api_request',
    payload: { customer_id: 'cus_123', endpoint: '/api/data' }
  },
  {
    event_name: 'api_request', 
    payload: { customer_id: 'cus_456', endpoint: '/api/users' }
  }
];

for (const event of events) {
  await stripe.billing.meterEvents.create(event);
}
```

### Billing.MeterEventAdjustments

Adjust previously recorded usage events:

```typescript { .api }
// Create meter event adjustment (correction)
const adjustment = await stripe.billing.meterEventAdjustments.create({
  event_name: 'api_request',
  type: 'cancel',
  original_event_id: 'mevt_123'
});

// Create value adjustment
const valueAdjustment = await stripe.billing.meterEventAdjustments.create({
  event_name: 'storage_used',
  type: 'cancel',
  original_event_id: 'mevt_456'
});
```

## V2 Billing API (Latest)

### V2.Billing.MeterEvents

Enhanced meter events with improved performance:

```typescript { .api }
// Create V2 meter event
const v2MeterEvent = await stripe.v2.billing.meterEvents.create({
  event_name: 'api_call',
  payload: {
    stripe_customer_id: 'cus_123',
    value: '1'
  }
});

// Create V2 meter event adjustment
const v2Adjustment = await stripe.v2.billing.meterEventAdjustments.create({
  event_name: 'api_call',
  type: 'cancel',
  original_event_id: 'mevt_789'
});
```

### V2.Billing.MeterEventSession

Batch meter events for improved performance:

```typescript { .api }
// Create meter event session for batch operations
const session = await stripe.v2.billing.meterEventSession.create({
  meter_event_session: {
    // Session configuration
  }
});
```

### V2.Billing.MeterEventStream

Stream meter events for real-time processing:

```typescript { .api }
// Create meter event stream
const stream = await stripe.v2.billing.meterEventStream.create({
  // Stream configuration
});
```

## Credit Management

### Billing.CreditGrants

Issue and manage customer credit grants:

```typescript { .api }
interface BillingCreditGrant {
  id: string;
  object: 'billing.credit_grant';
  customer: string;
  amount: {
    monetary?: {
      currency: string;
      value: number;
    };
    type: 'monetary';
  };
  applicability_config: {
    scope: {
      price_type: 'metered';
    };
  };
  category: 'paid' | 'promotional';
  effective_at: number;
  expires_at?: number;
}

// Create monetary credit grant
const creditGrant = await stripe.billing.creditGrants.create({
  customer: 'cus_123',
  amount: {
    monetary: {
      currency: 'usd',
      value: 1000 // $10.00 in cents
    },
    type: 'monetary'
  },
  applicability_config: {
    scope: {
      price_type: 'metered'
    }
  },
  category: 'promotional',
  effective_at: Math.floor(Date.now() / 1000),
  expires_at: Math.floor(Date.now() / 1000) + 86400 * 90, // 90 days
  name: 'Welcome Bonus Credit'
});

// Create credit grant for specific products
const productCredit = await stripe.billing.creditGrants.create({
  customer: 'cus_123',
  amount: {
    monetary: {
      currency: 'usd', 
      value: 2000
    },
    type: 'monetary'
  },
  applicability_config: {
    scope: {
      price_type: 'metered',
      filters: [
        {
          prices: ['price_api_calls', 'price_storage']
        }
      ]
    }
  },
  category: 'paid'
});

// Retrieve credit grant
const retrieved = await stripe.billing.creditGrants.retrieve('cg_123');

// Update credit grant
const updated = await stripe.billing.creditGrants.update('cg_123', {
  name: 'Updated Credit Grant',
  metadata: { campaign: 'spring_2024' }
});

// List credit grants
const creditGrants = await stripe.billing.creditGrants.list({
  customer: 'cus_123',
  limit: 10
});

// Expire credit grant
const expired = await stripe.billing.creditGrants.expire('cg_123');

// Void credit grant
const voided = await stripe.billing.creditGrants.voidGrant('cg_123');
```

### Billing.CreditBalanceSummary

View customer's current credit balance:

```typescript { .api }
interface BillingCreditBalanceSummary {
  object: 'billing.credit_balance_summary';
  customer: string;
  balance: {
    monetary: Array<{
      currency: string;
      available_balance: {
        currency: string;
        value: number;
      };
      ledger_balance: {
        currency: string;
        value: number;
      };
    }>;
  };
}

// Retrieve credit balance summary
const balanceSummary = await stripe.billing.creditBalanceSummary.retrieve({
  customer: 'cus_123'
});

console.log('Available USD credit:', 
  balanceSummary.balance.monetary.find(b => b.currency === 'usd')?.available_balance.value
);
```

### Billing.CreditBalanceTransactions

Track credit balance changes:

```typescript { .api }
interface BillingCreditBalanceTransaction {
  id: string;
  object: 'billing.credit_balance_transaction';
  customer: string;
  type: 'credit_grant' | 'credit_grant_adjustment' | 'credit_reversal' | 'invoice_applied_credit' | 'invoice_voided_credit';
  amount: {
    monetary: {
      currency: string;
      value: number;
    };
    type: 'monetary';
  };
  created: number;
}

// Retrieve credit balance transaction
const transaction = await stripe.billing.creditBalanceTransactions.retrieve('cbt_123');

// List credit balance transactions
const transactions = await stripe.billing.creditBalanceTransactions.list({
  customer: 'cus_123',
  limit: 20,
  type: 'credit_grant'
});

// List transactions by date range
const recentTransactions = await stripe.billing.creditBalanceTransactions.list({
  customer: 'cus_123',
  created: {
    gte: Math.floor(Date.now() / 1000) - 86400 * 30 // Last 30 days
  }
});
```

## Billing Alerts

### Billing.Alerts

Monitor and alert on billing events:

```typescript { .api }
interface BillingAlert {
  id: string;
  object: 'billing.alert';
  alert_type: 'usage_threshold';
  filter?: {
    customer?: string;
  };
  status: 'active' | 'archived';
  title: string;
  usage_threshold_config?: {
    gte: number;
    meter: string;
    recurrence: 'one_time' | 'daily' | 'monthly';
  };
}

// Create usage threshold alert
const usageAlert = await stripe.billing.alerts.create({
  alert_type: 'usage_threshold',
  title: 'High API Usage Alert',
  usage_threshold_config: {
    gte: 1000, // Alert when usage >= 1000
    meter: 'mtr_api_requests',
    recurrence: 'daily'
  }
});

// Create customer-specific alert
const customerAlert = await stripe.billing.alerts.create({
  alert_type: 'usage_threshold',
  title: 'Enterprise Customer Alert',
  filter: {
    customer: 'cus_enterprise_123'
  },
  usage_threshold_config: {
    gte: 10000,
    meter: 'mtr_api_requests',
    recurrence: 'monthly'
  }
});

// Retrieve alert
const retrieved = await stripe.billing.alerts.retrieve('ba_123');

// List alerts
const alerts = await stripe.billing.alerts.list({
  alert_type: 'usage_threshold',
  limit: 10
});

// Activate alert
const activated = await stripe.billing.alerts.activate('ba_123');

// Deactivate alert
const deactivated = await stripe.billing.alerts.deactivate('ba_123');

// Archive alert
const archived = await stripe.billing.alerts.archive('ba_123');
```

## Usage-Based Pricing Integration

Combine billing features with pricing for complete usage-based billing:

```typescript { .api }
// Create metered price
const meteredPrice = await stripe.prices.create({
  product: 'prod_api_service',
  currency: 'usd',
  recurring: {
    interval: 'month',
    usage_type: 'metered'
  },
  billing_scheme: 'per_unit',
  unit_amount: 10, // $0.10 per unit
  transform_usage: {
    divide_by: 1,
    round: 'up'
  }
});

// Create tiered usage pricing
const tieredPrice = await stripe.prices.create({
  product: 'prod_api_service',
  currency: 'usd',
  recurring: {
    interval: 'month',
    usage_type: 'metered'
  },
  billing_scheme: 'tiered',
  tiers_mode: 'graduated',
  tiers: [
    {
      up_to: 1000,
      unit_amount: 10 // $0.10 for first 1000
    },
    {
      up_to: 5000,
      unit_amount: 8 // $0.08 for next 4000
    },
    {
      up_to: 'inf',
      unit_amount: 5 // $0.05 for everything above
    }
  ]
});

// Create subscription with usage-based pricing
const usageSubscription = await stripe.subscriptions.create({
  customer: 'cus_123',
  items: [{
    price: meteredPrice.id
  }],
  billing_thresholds: {
    amount_gte: 5000, // Generate invoice when amount >= $50
    reset_billing_cycle_anchor: false
  }
});

// Record usage events
await stripe.billing.meterEvents.create({
  event_name: 'api_request',
  payload: {
    customer_id: 'cus_123',
    units: '10' // 10 API calls
  }
});

// Apply promotional credit
const promoCredit = await stripe.billing.creditGrants.create({
  customer: 'cus_123',
  amount: {
    monetary: {
      currency: 'usd',
      value: 500 // $5.00 credit
    },
    type: 'monetary'
  },
  applicability_config: {
    scope: {
      price_type: 'metered'
    }
  },
  category: 'promotional',
  effective_at: Math.floor(Date.now() / 1000),
  name: 'First Month Free Credit'
});
```

## Best Practices

### Event Recording
```typescript { .api }
// Use idempotency for reliable event recording
const eventId = `api_call_${customerId}_${timestamp}_${uniqueId}`;
await stripe.billing.meterEvents.create({
  event_name: 'api_request',
  payload: {
    customer_id: 'cus_123'
  }
}, {
  idempotencyKey: eventId
});

// Batch events for better performance
const events = collectUsageEvents(); // Your event collection logic
for (const event of events) {
  await stripe.billing.meterEvents.create(event, {
    idempotencyKey: event.unique_id
  });
}
```

### Credit Management
```typescript { .api }
// Check credit balance before charging
const balance = await stripe.billing.creditBalanceSummary.retrieve({
  customer: 'cus_123'
});

const usdCredit = balance.balance.monetary.find(b => b.currency === 'usd');
if (usdCredit && usdCredit.available_balance.value > 0) {
  console.log(`Customer has $${usdCredit.available_balance.value / 100} in credits`);
}
```

### Alert Configuration
```typescript { .api }
// Set up graduated alerts for different usage levels
const alerts = [
  { threshold: 1000, title: 'Usage Warning - 1K API calls' },
  { threshold: 5000, title: 'High Usage Alert - 5K API calls' },
  { threshold: 10000, title: 'Critical Usage - 10K API calls' }
];

for (const alert of alerts) {
  await stripe.billing.alerts.create({
    alert_type: 'usage_threshold',
    title: alert.title,
    usage_threshold_config: {
      gte: alert.threshold,
      meter: 'mtr_api_requests',
      recurrence: 'daily'
    }
  });
}
```

The billing namespace provides enterprise-grade usage metering and credit management capabilities, enabling sophisticated pricing models and proactive billing monitoring for usage-based businesses.