Skip to content

Usage-based API

import { Access, Billing, Offer, Purchase } from "@byfungsi/sapa";
import { Effect } from "effect";
export const meteredApi = Effect.gen(function* () {
const access = yield* Access.entitlements({
entitlements: ["api.use"],
duration: "purchased_period",
});
const purchase = yield* Purchase.parse({
key: "api.metered.access",
revision: 1,
provides: [access],
});
const billing = yield* Billing.meteredSubscription({
family: "api",
interval: "month",
meter: { key: "api.request", revision: 1 },
rate: {
currency: "IDR",
amount: 25n,
perUnits: 10n,
rounding: "trunc",
},
accessPolicy: { key: "api.postpaid_access", revision: 1 },
});
return yield* Offer.parse({
key: "api.metered",
revision: 1,
purchase,
billing,
});
});

This charges IDR 25 per ten requests after period aggregation. For 99 accepted units, the line amount is trunc(99 × 25 / 10) = 247 IDR.

The composition root must install:

  • meter api.request revision 1;
  • merchant access policy api.postpaid_access revision 1;
  • a provider for invoice checkout;
  • storage supporting enrollment, usage, invoice, and payment history.

The access policy has an explicit grace period. Zero means immediate suspension when payment becomes overdue. Full refunds create debt at refund time; payment can reinstate access according to retained policy history.

Follow the complete operation order in metered billing.