# BillingService

**Kind:** Service

**Source:** [`atloria-monorepo/apps/api/src/billing/billing.service.ts`](https://github.com/sherkety/atloria/blob/main/atloria-monorepo/apps/api/src/billing/billing.service.ts#L23)

`BillingService` encapsulates backend billing operations for the API, including creating hosted checkout and customer portal sessions, processing payment-provider webhooks, and returning billing summaries. It acts as the application boundary between billing-related API endpoints and the external payment provider.

## Methods

| Method | Signature | Returns | Description |
|---|---|---|---|
| `createCheckoutSession` | `createCheckoutSession(user: JwtPayload, plan: BillingPlanKey)` | `Promise<{ url: string }>` | Create a Stripe Checkout Session for a subscription to 'pro'|'business'. |
| `createPortalSession` | `createPortalSession(user: JwtPayload)` | `Promise<{ url: string }>` | Create a Stripe Billing Portal session so customers can manage/cancel. |
| `handleWebhook` | `handleWebhook(rawBody: Buffer, signature: string)` | `Promise<{ received: boolean }>` | Handle Stripe webhook events (signature-verified against the raw body). |
| `getSummary` | `getSummary(user: JwtPayload)` | `unknown` | Plan + credits + usage summary for the billing settings page. |

## Dependencies

- `PrismaService`
- `ConfigService`
- `AIUsageService`
- `Stripe`

## Where it refuses work

- `BillingService` stops the work with `NotFoundException` when `!org` — “Organization not found”, in 3 places.
- `BillingService` stops the work with `BadRequestException` when `!envVar`.
- `BillingService` stops the work with `BadRequestException` when `!priceId`.
- `BillingService` stops the work with `BadRequestException` when `!session.url` — “Stripe did not return a checkout URL”.
- `BillingService` stops the work with `BadRequestException` when `!org.stripeCustomerId` — “No billing account yet — subscribe to a plan first.”.
- `BillingService` stops the work with `BadRequestException` when `!webhookSecret` — “STRIPE_WEBHOOK_SECRET is not configured”.

## When something fails

- `BillingService` handles failure in 1 place: it lets it reach the caller in all 1.

## Diagram

```mermaid
sequenceDiagram
  participant Client
  participant API as Billing Controller
  participant Service as BillingService
  participant Provider as Payment Provider

  Client->>API: Request checkout or portal session
  API->>Service: createCheckoutSession() / createPortalSession()
  Service->>Provider: Create hosted session
  Provider-->>Service: Session URL
  Service-->>API: { url }
  API-->>Client: Redirect URL

  Provider->>API: Webhook event
  API->>Service: handleWebhook()
  Service->>Provider: Validate/process event
  Service-->>API: { received: true }
```

## Usage

```ts
import { Controller, Get, Post } from '@nestjs/common';
import { BillingService } from './billing.service';

@Controller('billing')
export class BillingController {
  constructor(private readonly billingService: BillingService) {}

  @Post('checkout')
  createCheckout() {
    return this.billingService.createCheckoutSession();
  }

  @Post('portal')
  createPortal() {
    return this.billingService.createPortalSession();
  }

  @Get('summary')
  getSummary() {
    return this.billingService.getSummary();
  }
}
```

## AI Coding Instructions

- Keep payment-provider calls inside `BillingService`; controllers should only validate requests and delegate to the service.
- Return hosted session URLs using the established `{ url: string }` response shape for checkout and portal flows.
- Treat `handleWebhook()` as a security-sensitive integration point: preserve raw payload handling and signature verification requirements.
- Make webhook processing idempotent so repeated provider events do not create duplicate billing state changes.
- Update `getSummary()` when billing state, subscription fields, or provider response mappings change.

## Relationships

- DEPENDS_ON → `PrismaService`
- DEPENDS_ON → `configservice`
- DEPENDS_ON → `AIUsageService`
- DEPENDS_ON → `stripe`

## Referenced By

- `BillingController` (DEPENDS_ON)
- `BillingModule` (MODULE_PROVIDES)
- `BillingModule` (MODULE_EXPORTS)
