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

@synza/http

v0.1.0-alpha.0

Published

Host-authenticated Web Request and Response handlers for Synza billing

Readme

@synza/http

A framework-independent Web Request/Response adapter for Synza's public Promise billing methods. This experimental 0.1.0-alpha.0 package starts no server and borrows your configured billing instance. Your host verifies callers, registers routes, and supplies CSRF protection for cookie sessions.

Table of contents

Install

Use Node.js >=22.12, ESM, and a framework that supplies Web Request and Response objects. If the host creates its own billing instance, install @synza/stripe explicitly alongside its peers:

pnpm add @synza/http@alpha @synza/stripe@alpha [email protected] stripe@^23.0.0

Effect is an internal runtime dependency. This package has no native Effect entry point. See the Stripe package for schema and database prerequisites.

Configure the handler

The host boundaries below are function parameters, not Synza authentication exports. resolveCaller verifies credentials and returns the admitted Jazz account UUID as Caller.accountId, or null for recognized authentication rejection.

// Register a bearer-authenticated handler using host-owned resources and policy.
import { createSynza, type Caller, type OrganizationAuthorizationPolicy } from '@synza/stripe'
import { createSynzaHttpHandler } from '@synza/http'
import type { Db } from 'jazz-tools'
import Stripe from 'stripe'

export function configureBillingHttp(input: {
  db: () => Db | Promise<Db>
  stripeSecretKey: string
  provider: { stripeAccountId: string; livemode: boolean }
  webhookSecret: string
  priceId: string
  idempotencyNamespace: string
  resolveCaller: (request: Request) => Promise<Caller | null>
  authorizeOrganization: OrganizationAuthorizationPolicy
}) {
  const billing = createSynza({
    db: input.db,
    stripe: new Stripe(input.stripeSecretKey),
    provider: input.provider,
    authorization: { authorizeOrganization: input.authorizeOrganization },
    checkout: {
      offers: {
        team: {
          mode: 'subscription',
          params: {
            success_url: 'https://app.example/billing/success?session_id={CHECKOUT_SESSION_ID}',
            cancel_url: 'https://app.example/billing',
          },
          lineItems: [
            { ref: 'base', price: input.priceId, quantity: { type: 'fixed', quantity: 1 } },
          ],
        },
      },
    },
    portal: { returnUrl: 'https://app.example/billing' },
    webhooks: { secret: input.webhookSecret },
  })
  return createSynzaHttpHandler({
    billing,
    resolveCaller: input.resolveCaller,
    security: { type: 'bearer' },
    idempotencyNamespace: input.idempotencyNamespace,
    basePath: '/api/billing',
  })
}

Choose a stable idempotencyNamespace, distinct across provider account/mode contexts, such as app.primary.sandbox. Keep that namespace unchanged for retries. Register the returned function with your host router. The compiled host fixture demonstrates Jazz bearer resolution and host-derived quantity configuration.

Send requests

All routes are POST under basePath (default /api/billing). Application routes require JSON, verified authentication, and explicit scope such as { "type": "account" } or { "type": "organization", "orgId": "team-id" }.

| Route | Request fields besides scope | | --------------------------- | ------------------------------------------------------------------------------ | | /checkout | Configured offerKey, optional manualQuantities | | /portal | Optional flow selecting Portal or owned subscription cancellation | | /subscriptions/cancel | stripeSubscriptionId, timing: immediate or periodEnd | | /subscriptions/reactivate | stripeSubscriptionId | | /subscriptions/quantity | stripeSubscriptionId, stripeSubscriptionItemId, optional manual quantity | | /checkout/refresh | sessionId |

/checkout calls configured offer Checkout, not raw Stripe Checkout. Prices, destinations, and quantity policy stay on the server. Quantity updates require a configured item policy. There are no Customer creation or billing-read routes. See the HTTP contract for request shapes.

Subscription commands require Idempotency-Key; Checkout accepts it optionally. The adapter derives provider keys using namespace, caller, scope, action, target, and browser key. It retains no attempt ledger and does not freeze resolved parameters. Direct core keys are forwarded unchanged.

Route webhooks

Expose POST /api/billing/webhook to Stripe without host bearer or cookie middleware. This route bypasses resolveCaller and CSRF checks, then verifies stripe-signature through billing's configured webhook secret. Preserve the original body; do not parse, consume, or rewrite it upstream. Configure the Stripe endpoint separately. Successful processing and hooks return empty 204. Hooks repeat on every delivery; the host deduplicates business effects.

Security and failures

Bearer mode checks header shape; the host resolver verifies the token and admitted account. Cookie mode requires { type: 'cookie', allowedOrigins, verifyCsrf }, with exact allowed origins and host CSRF verification returning true. A token header's presence alone is insufficient. The adapter adds no automatic CORS policy. Runtime organization policy uses the central nine-action authorization.authorizeOrganization callback; read and management grants remain independent.

Return null or throw HttpAuthenticationError only for known credential rejection. Unknown resolver failures remain 500. Never derive caller identity from request JSON. Extra fields, raw Stripe parameters, arbitrary URLs, financial options, and replay context are rejected. Responses redact internal failures; successful application calls return JSON 200. Defaults bound application bodies to 64 KiB and webhook bodies to 1 MiB, configurable through maxBodyBytes and maxWebhookBodyBytes.

Validation limits

The ledger records failing full gates. Combined direct Jazz read validation is blocked by Jazz #3981; it is not validated for deployment. HTTP fixtures do not certify host authentication or live Stripe behavior. Synza supplies billing facts, not entitlements or fulfillment. This alpha makes no release-readiness claim.

License

MIT.