npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@anybill/sdk

v0.14.1

Published

TypeScript SDK for the AnyBill billing platform — query subscriptions, subscribers and invoices, or build custom payment provider plugins

Downloads

3,905

Readme

@anybill/sdk

TypeScript SDK for the AnyBill billing platform.

Two use cases:

  1. Client SDK — query subscriptions, subscribers, and invoices from your backend
  2. Provider API — build custom payment provider plugins

Installation

npm install @anybill/sdk

Client SDK

import { AnybillSDK } from "@anybill/sdk";

const client = new AnybillSDK({
  baseUrl: "https://billing.example.com",
  apiKey: "ak_...",
});

// List active plans
const plans = await client.getSubscriptions();

// Check if a user has an active subscription (including trial status)
const subscribers = await client.getSubscriberByUid("user_123");
const isActive = subscribers.some(
  (s) => s.status === "active" || s.status === "trialing",
);

// Start a free trial for a user
const trial = await client.startTrial("user_123");
// trial.status → "trialing"
// trial.trialEnd → Date string (ISO 8601)

// Create a secure checkout link
const link = await client.createCheckoutLink("plan-uuid", "user_123");
// link.url → redirect user here

// With custom success redirect (overrides account setting)
const link2 = await client.createCheckoutLink("plan-uuid", "user_123", {
  successUrl: "https://myapp.com/thanks",
});

// Create a portal link for subscriber self-service
const portal = await client.createPortalLink("user_123");
// portal.url → redirect user to manage their subscription

// Grant a subscription without payment (admin/promo)
const grant = await client.grantSubscription("plan-uuid", "user_123");
// grant.status → "active"

// Grant for 90 days starting from a specific date
const grant2 = await client.grantSubscription("plan-uuid", "user_123", {
  days: 90,
  startDate: "2025-02-01T00:00:00Z",
});
// --- Squads (group subscriptions) ---

// Check access (covers both direct subscribers and squad members)
const access = await client.checkAccess("user-123");
if (access.hasAccess) {
  console.log(access.accessType); // "direct" or "squad"
}

// Squad is auto-created when purchasing a squad-enabled plan.
// To manage members:
const members = await client.squads.getMembers("squad-id");
await client.squads.addMember("squad-id", "friend-uid");
await client.squads.removeMember("squad-id", "friend-uid");
// --- Real-time Event Streaming (SSE) ---

const stream = client.events.subscribe([
  "payment.confirmed",
  "subscription.renewed",
]);

stream.on("payment.confirmed", (data) => {
  // data is fully typed: invoiceId, amount, currency, provider, paidAt, ...
  console.log(`Payment ${data.invoiceId}: ${data.amount} ${data.currency}`);
});

stream.on("subscription.renewed", (data) => {
  console.log(`Renewed until ${data.currentPeriodEnd}`);
});

// Lifecycle events
stream.on("connected", () => console.log("SSE connected"));
stream.on("error", (err) => console.error(err));

// Subscribe to ALL events
const allStream = client.events.subscribe();

// Clean up when done
stream.close();

Methods

| Method | Description | | ------------------------------------------------ | ------------------------------------------------------------- | | getSubscriptions() | List all active subscription plans | | getSubscriberByUid(uid) | Find subscribers by external user ID | | getSubscriber(id) | Get a subscriber by AnyBill ID | | getInvoice(id) | Get an invoice by ID | | createCheckoutLink(planId, uid, opts?) | Create a secure checkout URL (opts: ttl, couponCode, successUrl) | | createPortalLink(uid, ttl?) | Create a time-limited subscriber portal URL | | checkAccess(uid, subscriptionId?) | Check if user has access (direct or squad) | | startTrial(uid, subscriptionId?) | Start a free trial for a user (auto-resolves plan if omitted) | | grantSubscription(planId, uid, opts?) | Grant a subscription without payment (opts: days, startDate) | | cancelSubscriber(subscriberId) | Cancel subscription (access until period end) | | revokeSubscriber(subscriberId) | Immediately revoke access (no grace period) | | deleteSubscriber(subscriberId) | Permanently delete subscriber and all related data | | squads.create(subscriberId) | Create a squad for a subscriber | | squads.get(squadId) | Get squad by ID | | squads.getByOwnerUid(uid) | Find squad by owner's uid | | squads.dissolve(squadId) | Dissolve a squad | | squads.addMember(squadId, uid) | Add member to squad | | squads.removeMember(squadId, uid) | Remove member from squad | | squads.getMembers(squadId) | List active squad members | | squads.invites.create(squadId, uid) | Create an invite for a user | | squads.invites.list(squadId) | List squad invites | | squads.invites.accept(squadId, inviteId, uid) | Accept an invite | | squads.invites.decline(squadId, inviteId, uid) | Decline an invite | | squads.invites.cancel(squadId, inviteId) | Cancel an invite (owner) | | squads.invites.incoming(uid) | Get incoming invites for a user | | events.subscribe(events?) | Open SSE stream for real-time events |

Event Streaming

events.subscribe() returns an EventStream with typed .on() handlers. Supports auto-reconnect and Last-Event-ID replay.

Available events: payment.confirmed, payment.failed, payment.refunded, payment.cancelled, subscription.renewed, subscription.expired, subscription.cancelled, squad.created, squad.dissolved, squad.member_added, squad.member_removed, squad.invite_created, squad.invite_accepted, squad.invite_declined, squad.invite_cancelled, coupon.redeemed, trial.started, trial.expired.

Provider API

Build custom payment providers using the decorator-based plugin system.

import {
  AnybillProvider,
  ProviderCapability,
  CreatePaymentLink,
  ValidateWebhook,
  IncomingWebhook,
  PaymentLink,
  Payment,
} from "@anybill/sdk";

class StripeProvider extends AnybillProvider {
  get displayName() { return "Stripe"; }
  get capabilities(): ProviderCapability[] { return ["one_time", "recurring"]; }

  @CreatePaymentLink()
  async createLink(ctx) {
    const session = await stripe.checkout.sessions.create({ ... });
    return PaymentLink.url(session.url!).id(session.id);
  }

  @ValidateWebhook()
  verify(ctx) {
    return stripe.webhooks.constructEvent(ctx.body, ctx.headers["stripe-signature"], secret);
  }

  @IncomingWebhook()
  async webhook(ctx) {
    const event = JSON.parse(ctx.body);
    if (event.type === "checkout.session.completed") {
      return Payment.id(event.data.object.id).confirm();
    }
    return Payment.ignore();
  }
}

export default { name: "stripe", provider: new StripeProvider() };

Decorators

| Decorator | Purpose | | ---------------------- | --------------------------------- | | @CreatePaymentLink() | Generate a payment URL | | @ValidateWebhook() | Verify incoming webhook signature | | @IncomingWebhook() | Process webhook payload | | @RefundPayment() | Issue a refund | | @CancelPayment() | Cancel a pending payment |

Builders

| Builder | Usage | | ----------------------------- | ---------------------------- | | PaymentLink.url(url).id(id) | Build a payment link result | | Payment.id(id).confirm() | Confirm a payment | | Payment.id(id).failure() | Mark payment as failed | | Payment.id(id).renew() | Provider-managed renewal | | Payment.ignore() | Ignore an irrelevant webhook |

Note: Provider plugins require experimentalDecorators in their tsconfig.json. See the example provider for a complete setup.

License

MIT