Integration
TypeScript SDK
The @beinfi/sdk client: payments, checkout, usage and events.
Install and initialize
npm install @beinfi/sdkimport { Infi } from "@beinfi/sdk";
const infi = new Infi({
secretKey: process.env.INFI_SECRET_KEY!
});The key selects the environment. Keep it server-side. Your application's authentication remains yours; pass your own user identifiers when creating customers.
This is Infi's native SDK. The Stripe-compatible SDK is in Early access and is not a claim that this package is a drop-in replacement for every Stripe API.
Payment links
For a product with a published version:
const { url } = await infi.links.create(productId, {
slug: "acme"
});
const links = await infi.links.list(productId, { slug: "acme" });The hosted checkout handles the payment interface. The route is selected when the customer pays. See the quickstart for setup.
Checkout for a known customer
Use a stable key for the purchase intent, such as an order ID:
const { invoiceId, url } = await infi.checkout({
slug: "acme",
productId,
customer: {
externalId: user.id,
email: user.email
},
idempotencyKey: order.id
});Pix and boleto providers may require the customer's tax ID. Pass taxId in
customer when required. Never send raw card details to the Infi API.
Inspect a payment
const payments = await infi.payments.listForInvoice(invoiceId);
const payment = await infi.payments.get(paymentId);
const deliveries = await infi.webhooks.listDeliveries();Payment attempts expose their provider and outcome. Webhook delivery records help you inspect delivery; these calls do not expose a full routing-rule trace.
Idempotency
The SDK generates an idempotency key per mutating call. That protects transport retries of the same call, not a second invocation caused by a double-click.
Pass the same explicit key for the same purchase intent. Reusing a key with a
different request body returns 409 idempotency_key_reused.
Resource methods take the key as a trailing argument. Shortcuts such as
checkout accept idempotencyKey in the options object.
Record usage
First configure a product, a published version and the named meter. Enroll your customer in that product:
const enrollment = await infi.products.enroll(productId, {
externalId: user.id,
email: user.email
});
await infi.track({
customerId: enrollment.id,
productId,
meter: "tokens",
value: "1200",
eventId: usageEvent.id,
timestamp: usageEvent.timestamp
});customerId here is the enrollment ID, not your application's user ID. Always
include productId. For replayed usage, keep both eventId and
timestamp stable: they participate in deduplication.
Recording usage does not by itself create a billing period or a subscription. See the company-as-code guide before enabling usage-based charging.
Receive events
Use the webhook guide to verify signatures, process events idempotently and inspect deliveries.