polar icon indicating copy to clipboard operation
polar copied to clipboard

docs: Create a guide for seat based pricing

Open rishi-raj-jain opened this issue 2 months ago • 0 comments
trafficstars

Until we ship a fix for https://github.com/polarsource/polar/issues/4815, we need to inform users how to make this happen today. Write a guide covering the following:

  • Create a meter (say named X) as documented in https://docs.polar.sh/features/usage-based-billing/meters#creating-a-meter with the aggregation as Count and the filter as say new-seat

  • Create a product in Polar as documented in https://docs.polar.sh/features/products#create-a-product and make sure to link the meter X with the price for this meter as you want it per new seat

  • Ingest events to whenever a new person is added to the org using https://docs.polar.sh/api-reference/events/ingest

  • Make sure to have a webhook handler for order.created webhook (https://docs.polar.sh/api-reference/webhooks/order.created) with the billing_reason as subscription_cycle that updates the number of users attached to that workspace (since it's required to do the same per billing period)

With the base code snippets:

import { Polar } from "@polar-sh/sdk";

const polar = new Polar({ accessToken: process.env.POLAR_ACCESS_TOKEN });

// When a new user is added
async function trackNewUser(customerId: string) {
  // Each event call (like below) represents 1 new user
  await polar.events.ingest({
    events: [
      {
        // note that this field value is equal to the one that was entered in the `name` field in the `Condition` in the meter group
        name: "new-user",
        // Your user ID
        external_customer_id: customerId,
      },
    ],
  });
}

and

// At the start of each billing cycle, check no. of current users
async function billCurrentUsers(customerId: string) {
  const customers = await getNumberOfCustomersFromYourDB(customerId);
  const currentCustomers = customer.length;
    // Send events for each additional workspace
    for (let i = 0; i < currentCustomers; i++) {
      await polar.events.ingest({
        events: [{
          name: "new-user",
          external_customer_id: customerId
        }]
      });
  }
}

rishi-raj-jain avatar Sep 02 '25 09:09 rishi-raj-jain