Skip to content

[billing-polar] Deliver billable usage events idempotently #1522

Description

@kang-heewon

Parent: #1511
Depends on: #1518, #1520

Priority

P0

Problem

@croco/billing-polar handles checkout, subscription lifecycle, webhooks, and customer portal state, but does not deliver Croco meter events to Polar usage billing.

Desired outcome

Implement the UsageBillingGateway capability for Polar and connect it to the durable billable usage journal without coupling request latency to Polar availability.

Scope

  • Map typed Croco meter bindings to Polar event names and declared dimensions.
  • Use Croco eventId as the stable provider deduplication identity.
  • Support bounded batch delivery with deterministic receipt mapping.
  • Treat provider duplicate acknowledgement as successful delivery.
  • Classify rate limits, 5xx responses, and transport timeout as retryable.
  • Classify schema/meter rejection as terminal and retain actionable diagnostics.
  • Resolve tenant billing accounts to Polar customers without exposing provider IDs to application call sites.
  • Redact provider response details according to existing Problem policies.

Acceptance criteria

  • Replaying one journal event cannot increase accepted Polar usage twice.
  • Partial batch outcomes update each local event correctly.
  • Retryable failures preserve pending events and retry metadata.
  • Terminal rejection remains inspectable and is not retried indefinitely.
  • Missing customer or meter mapping produces a stable Problem/diagnostic with recovery guidance.
  • Batch size and retry behavior are bounded and tested.
  • Unit tests require no live credentials; an opt-in real-provider certification path is documented.
  • API docs, provider maturity/capability metadata, and changesets are updated.

Non-goals

  • Creating or editing Polar meters automatically.
  • Croco-owned price calculation.
  • Synchronous provider calls from MeteringService.record().

Metadata

Metadata

Assignees

Labels

featureProduct feature or roadmap capabilityreliability

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions