Other payment providers

For Paddle, Lemon Squeezy, Paystack or your own billing. UsageGate doesn't connect to them directly: when your provider tells your app that someone paid or cancelled, your app passes it on with one call.

1. Copy the plan id

In Access rules, click the id under the plan name (for example plan_pro). That is what you send, not your provider's own plan code.

2. Call reportSubscription from your webhook

In the route that already receives your provider's webhooks, after checking its signature:

app/api/webhooks/billing/route.ts
export async function POST(req: Request) {
  const event = await verifyWebhook(req); // your provider's signature check

  await gate.reportSubscription({
    eventId: event.id,            // repeats of the same event are ignored
    userId: event.customer_id,    // the id you use with consume / canAccess
    planId: "plan_pro",           // from Access rules
    status: "active",             // or "canceled"
    periodEnd: event.period_end,  // end of the paid period (required when active)
    occurredAt: event.created_at, // optional: older events are ignored
  });

  return new Response("ok");
}

Rename the event.… fields to whatever your provider sends.

Upgrades, cancellations, renewals

One call covers every change
WhenSend
Someone pays or renewsstatus: "active", the plan, and the new periodEnd
Someone upgrades or downgradesstatus: "active" with the new planId (no cancel for the old plan)
Someone cancelsstatus: "canceled" and the plan they leave. They go back to Free and keep at most what they had left.

If no renewal arrives within 3 days after periodEnd, the user goes back to Free on their next request.

The first call switches your workspace's payment provider to “Other” automatically. If you had connected Stripe, the call is refused (HTTP 409) until you choose Other in Payment gateway.