License Operator NATS Events

The License Operator publishes a single JetStream subject whenever a paid license is created through the Stripe webhook pipeline. The publisher automatically creates the stream (work-queue retention, 30‑day max age) and writes one JSON message per issuance. Subscribe with durable consumers if you need guaranteed processing.

SubjectPublisherTriggerPayload
licenseoperator.license.issuedStripe webhook managercheckout.session.completed or invoice.payment_succeeded produces a new paid licenseSigned license envelope plus Stripe identifiers
subject.stripe.webhook.eventHTTP webhook controllerEvery Stripe webhook POST requestRaw payload + signature for asynchronous replay

licenseoperator.license.issued

The name of the subject can be configured in config.yaml under nats.subject_license_issued. It is recommended to keep the default value unless you have a naming convention to follow.

  • When it fires – After a Stripe webhook event is validated, the payment record is persisted, and the license service has produced a signed envelope. Manual API issues (/authlance/license/internal/issue) do not emit this event; it is exclusive to automated purchases.
  • Delivery semantics – Uses JetStream with a dedicated stream per subject (name derived by replacing dots with underscores). Messages remain available for 30 days. Acks are handled by your consumer; the operator simply publishes.
  • Payload
{
  "licenseId": "L-0d7fc1b1",
  "email": "owner@example.com",
  "payloadB64": "LS0tLUVYQU1QTEUtTElDRU5TRS0tLS0K...",
  "signatureB64": "hQEMA5fakeSig==",
  "exp": "2026-01-01T00:00:00Z",
  "plan": "alpha",
  "domain": "example.com",
  "group": "acme",
  "stripe": {
    "customerId": "cus_FAKE123",
    "checkoutSessionId": "cs_test_a1b2",
    "invoiceId": "in_test_987"
  }
}

Field reference

FieldDescription
licenseIdIdentifier returned by the issuance service (L- prefix or UUID).
emailPrimary contact used during checkout or manual issuance.
payloadB64Base64-encoded license payload (PEM body) that downstream services can persist or email.
signatureB64Base64-encoded RSA signature that pairs with payloadB64.
expRFC3339 expiration timestamp that matches the stored license record.
planPlan name resolved after applying coupon overrides and defaults.
domainDomain claim embedded in the license payload.
groupAuthlance group that owns the license (matches Stripe metadata group_name).
stripe.customerIdStripe customer ID tied to the purchase (may be empty for manual inserts).
stripe.checkoutSessionIdSession identifier for the hosted checkout that produced the event.
stripe.invoiceIdInvoice ID associated with the payment.

Consuming the event

  1. Create a durable consumer on the stream the license-operator subject name is configured on the config.yaml nats.subject_license_issued. This is where you could hook your email service or provisioning automation.
  2. Acknowledge messages after you persist or deliver the license artifact to avoid redelivery.
  3. Optinally validate the signature using the public key that corresponds to the product key indicated in your configuration.

subject.stripe.webhook.event

Incoming Stripe webhook requests are persisted onto a dedicated JetStream work queue before any business logic executes. This shields the pipeline from transient HTTP failures—events are processed by an internal worker that validates the signature and issues licenses asynchronously. The subject can be changed via nats.subject_stripe_webhook_event, but most deployments can keep the default value.

  • When it fires – Immediately upon receiving the webhook request, before verification. Duplicate deliveries are possible if Stripe retries.
  • Delivery semantics – Work-queue JetStream stream with 30-day retention. The built-in worker acks only after processing succeeds; signature or metadata errors are acked to avoid infinite retries.
  • Payload – JSON envelope containing the base64-encoded HTTP body, the Stripe-Signature header, and a timestamp when it was enqueued. It is primarily for internal use, but you can subscribe for diagnostics if desired.