Skip to content

Webhooks

The webhook endpoint receives purchase and subscription events from cglounge and automatically creates, extends, or revokes licenses.


Endpoint

POST /cgloungeWebhook


Authentication

Pass the webhook secret in either location:

x-webhook-secret: YOUR_WEBHOOK_SECRET
{
  "webhookSecret": "YOUR_WEBHOOK_SECRET",
  "type": "purchase.completed",
  ...
}

Request Fields

Field Type Required Description
type string yes Event type. See Events table below.
email string yes Purchaser or subscriber email
productId string yes Product the event applies to
variant string no Variant name (e.g. indie, studio)
purchaseId string no Unique purchase ID for deduplication
licenseType string no per-machine, floating, or site. Falls back to variant default.
maxMachines integer no Override max machine activations
discountCode string no Discount code applied at checkout
trialDays integer no Override trial duration
durationDays integer no Subscription period in days
amount number no Transaction amount
currency string no ISO 4217 currency code (e.g. USD)

Events

Event Type Action
purchase.completed Creates a new license for the buyer
purchase.refunded Revokes the license tied to this purchase. Sets threatLevel: 4 and disputeReason: "refund".
purchase.disputed Revokes the license. Sets threatLevel: 4 and disputeReason: "chargeback".
subscription.renewed Extends the existing license by durationDays
subscription.cancelled Received but does NOT modify the license. The license continues until its existing expiresAt. No automated cancellation is performed.

License Expiry Priority

When multiple expiry signals are present, the server resolves them in this order:

  1. durationDays on the webhook request (highest priority)
  2. trialDays on the webhook request
  3. Trial days from a redeemed discount code
  4. Perpetual (no expiry) if none of the above are set

Chargeback Flow

When a purchase.disputed event arrives:

  1. Webhook receives the event.
  2. License is immediately revoked.
  3. The license record is flagged with threatLevel: 4 and disputeReason: "chargeback".
  4. The license cannot be reinstated without an explicit admin action via /reinstateLicense.

Webhook Deduplication

Deduplication applies only to purchase.completed events. Before creating a new license, the server checks whether a license with the same purchaseId already exists. If one is found, the existing license key is returned and no new license is created.

Renewal, refund, and chargeback events are NOT deduplicated. Sending the same refund or chargeback event twice will apply the action twice.


Example Payloads

{
  "type": "purchase.completed",
  "email": "artist@example.com",
  "productId": "abc123",
  "variant": "indie",
  "purchaseId": "stripe_pi_abc",
  "licenseType": "per-machine",
  "maxMachines": 2,
  "amount": 4900,
  "currency": "USD"
}
{
  "type": "subscription.renewed",
  "email": "artist@example.com",
  "productId": "abc123",
  "purchaseId": "stripe_sub_abc",
  "durationDays": 365
}
{
  "type": "purchase.disputed",
  "email": "artist@example.com",
  "productId": "abc123",
  "purchaseId": "stripe_pi_abc"
}
{
  "type": "subscription.cancelled",
  "email": "artist@example.com",
  "productId": "abc123",
  "purchaseId": "stripe_sub_abc",
  "durationDays": 30
}

curl Example

curl -X POST https://us-central1-cg-license-server.cloudfunctions.net/cgloungeWebhook \
  -H "Content-Type: application/json" \
  -H "x-webhook-secret: YOUR_WEBHOOK_SECRET" \
  -d '{
    "type": "purchase.completed",
    "email": "artist@example.com",
    "productId": "abc123",
    "variant": "studio",
    "purchaseId": "stripe_pi_xyz789",
    "licenseType": "per-machine",
    "maxMachines": 5,
    "amount": 14900,
    "currency": "USD"
  }'