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

@birtalanrobert/commerce

v4.4.0

Published

Taking money on a business's behalf: payout onboarding, payments, refunds and the record of both

Readme

@birtalanrobert/commerce

Taking money on a business's behalf: payout onboarding, card payments, manually recorded takings, refunds, and the record of all of it.

We never hold anybody's funds. The customer pays the business directly and our cut is taken on top as an application fee. This is an architectural rule rather than a preference — holding third-party money turns a software company into a regulated payments business — and everything here follows from it.

Not to be confused with @birtalanrobert/billing, which is the other direction: the business paying us for a subscription. They differ in who pays whom, in which provider account, and in what happens when one fails.

What is decided without a provider

The root entry point is pure, because a console shows these numbers while somebody drags a slider:

import { depositFor, canTakeMoney } from '@birtalanrobert/commerce';

depositFor(15_000, { kind: 'percentage', value: 30 }); // 4_500
canTakeMoney('pending'); // false — the provider has not verified them yet

Using it in a NestJS application

import { StripeConnect } from '@birtalanrobert/commerce/stripe';
import {
  COMMERCE_PROVIDER,
  CommerceService,
  commerceEntities,
  commerceMigrations,
} from '@birtalanrobert/commerce/nestjs';

@Module({
  providers: [
    {
      provide: COMMERCE_PROVIDER,
      useFactory: (config: AppConfig) =>
        new StripeConnect({
          secretKey: config.STRIPE_SECRET_KEY,
          webhookSecret: config.STRIPE_WEBHOOK_SECRET,
        }),
      inject: [ConfigModule.token()],
    },
    CommerceService,
  ],
})
export class PaymentsModule {}

Register commerceEntities and commerceMigrations with the data source, as with every other package here.

Where a deployment takes no card payments — which is most of them in some categories — provide NoPayments instead of StripeConnect. It reports none and refuses every operation, so every gate that already asks whether a business can be paid out answers no. Do not construct the vendor client with an empty key: it throws inside its own constructor and the application does not start.

Three entry points, and the split is deliberate. The root is pure — what a deposit comes to, whether a business may sell yet, whether a payment can still be refunded — because a console decides all three while somebody drags a slider. /nestjs holds the service, the entities and the migrations. /stripe holds the vendor's client on its own, because importing it pulls in the whole SDK, and a barrel that re-exported it once put a payments SDK into a booking console's first load.

The parts worth knowing before using it

  • A business cannot be charged for until the provider says it may be paid out. take refuses before the provider is called. A charge that succeeded into an account with no destination would leave the customer debited and the money nowhere anybody can see it.
  • authorized is not captured. A card held against a no-show fee is authorised and charged only if the fee is actually applied — and that decision is a human one. This package offers the mechanism and never the trigger, because charging a customer automatically is how a business loses them permanently.
  • Cash, terminal, voucher and transfer payments are recorded, not processed — and recording them is not a lesser feature. A salon is mostly cash, a restaurant takes meal vouchers, a box office takes notes. A report counting only what a provider processed tells a business a fraction of its own takings while looking complete.
  • The record outlives the provider. Amounts, dates, what it was for and who decided are stored in full rather than as identifiers to fetch, because a business must be able to produce its own takings after the account is closed.
  • A webhook carries the provider's delivery id, and deduplicating is the caller's job. settle is safe to run twice — it assigns a state rather than performing an act — but what a product does around it usually is not: a buyer can be sent two tickets. ProviderEvent.id is the identifier to keep, and not externalId, which names the payment and repeats across the several events one payment produces.
  • A dispute is reported and not recorded. settle understands the event and returns nothing: the money has already moved, and what a dispute needs is evidence assembled from what was bought — the product's rows, not the payment's. The deadline arrives with the first event, because missing it loses the money whatever the evidence would have said.
  • There is no foreign key to whatever was paid for. One product takes a deposit against an appointment, another against a seat, a third against a table's tab; a key to any one of them is what would stop this being shared.