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

@repitoo/sdk

v0.1.2

Published

Repitoo inside your system: turn loyalty on per business, add stamps from the till (with an offline queue), verify webhooks and open <repitoo-modal>.

Readme

@repitoo/sdk

Repitoo inside your system: turn loyalty on per business, add stamps from the till (even offline), verify webhooks and open the Repitoo window in your POS.

npm install @repitoo/sdk

Works in Node 20+ and in the browser (only @repitoo/sdk/modal), with no AWS or framework dependency.

Your system isn't JavaScript? You don't need the SDK: Repitoo is an HTTP API with JSON and works from any language (PHP, Python, Java, C#, Go, Ruby, Delphi…) and any till, web or desktop. AGENTS.md describes every call, the webhook signature and how to open the window; the full reference is https://api.repitoo.com/openapi.json. See the examples at the end.

The two keys

| Key | Who uses it | For | | ------------------------------ | ------------------------------- | ------------------------------------------------------------------------------- | | rpt_partner_… / rpt_test_… | Your server | Turning businesses on and off, getting new keys and opening the Repitoo window. | | rpt_live_… | The server of a business's till | Adding stamps, finding cards and handing out rewards in that business. |

No key ever goes to the browser. Where you store them is up to you (environment variables, Secrets Manager, Parameter Store): Repitoo never touches your AWS. keyFromEnv, secretsManagerKeys and parameterStoreKeys read them using your own client.

With an rpt_test_ key everything works the same, but the businesses are test ones: they don't count toward your invoice and don't notify anyone.

1. Turn loyalty on for a business

Only when the business signs up for it, never when the POS is installed.

import { RepitooPartner } from "@repitoo/sdk";

const partner = new RepitooPartner(process.env.REPITOO_PARTNER_KEY!);
const { business, apiKey, created } = await partner.activateBusiness({
  externalId: "store-123", // your id: repeating it returns the same business
  name: "Corner Coffee",
  ownerEmail: "[email protected]",
  program: { rewardDescription: "A free coffee", stampsRequired: 8 },
});
// apiKey (rpt_live_…) only comes back when created is true: store it right away.

deactivateBusiness(business.id) when it stops paying for it (its customers keep their stamps and it no longer counts as an active location) and reactivateBusiness(business.id) to bring it back.

2. Add stamps from the till

import { RepitooTill } from "@repitoo/sdk";

const till = new RepitooTill(businessKey);
const { card, stampsAdded, rewardEarned } = await till.recordSale(
  { customer: { phone: "+584141234567" }, amount: 25.5, reference: "F-1001" },
  "F-1001", // the idempotency key: the invoice number works
);
  • Send phone numbers with their country code (+58…): an 8-digit number without one is read as Costa Rican.
  • amount for by-amount programs; stamps for by-visit programs (1 by default).
  • A customer who doesn't exist yet is enrolled with that sale.
  • findCard, redeemReward and reverseStamps (a voided sale) round out the till.

Offline

import { OfflineQueue } from "@repitoo/sdk";

const queue = new OfflineQueue(till, yourStore); // in memory if you don't pass one
await queue.record(sale, invoice); // answers now, or { queued: true }
await queue.flush(); // when the connection is back

Each sale keeps the time it happened (occurredAt), so the stamps count on that day, and it is always resent with the same key: it never adds stamps twice. Repitoo accepts sales up to 7 days old. What Repitoo refuses for good (a reused invoice, a customer with no details) ends up in rejected for a person to review.

3. The Repitoo window in your POS

Your server asks for the address (valid for 30 minutes) and the page opens it:

const { url } = await partner.openWindow(business.id); // on your server
<repitoo-modal label="Stamps"></repitoo-modal>
<script type="module">
  import "@repitoo/sdk/modal";
  const modal = document.querySelector("repitoo-modal");
  modal.addEventListener("repitoo-stamped", (event) => console.log(event.detail.card));
  modal.open(urlFromYourServer);
</script>

There the cashier finds the customer, gives them their card, adds stamps and hands out the reward. Events: repitoo-stamped, repitoo-redeemed and repitoo-close. Your domain must be among your partner account's allowed origins (Repitoo sets them up for you); otherwise the window won't show.

<repitoo-modal> is a standard HTML element: it works the same with or without a framework (in Angular, with CUSTOM_ELEMENTS_SCHEMA; in React, with a ref). Without the SDK, an <iframe> and a postMessage listener are enough (examples/html/till.html). In a desktop till or an app (WPF, Electron, Android, iOS), open the address in a WebView: it works the same, and webhooks tell you what changed.

4. Webhooks

Create them in your partner portal (Keys → Notifications to your system). Each delivery carries Repitoo-Signature: t=…,v1=… (HMAC-SHA256 of the body with your whsec_…):

import { verifyWebhook } from "@repitoo/sdk";

const event = verifyWebhook(secret, request.headers.get("repitoo-signature"), rawBody);

In another language: v1 is the hex HMAC-SHA256 of "<t>.<body>" with your whsec_… as the key; compare it in constant time and reject a t more than 5 minutes old.

Answer 2xx within 10 s. Otherwise Repitoo retries after 1 min, 5 min, 30 min, 2 h, 12 h and 24 h. A retry carries the same event.id: ignore what you already processed.

Errors

Every non-2xx response is a RepitooError with status, error (the code) and retryable (no connection, 408, 429 or 5xx: worth retrying). 402 payment_required: your partner account or the business is paused.

Examples

| Language or stack | Example | | -------------------- | --------------------------------------------------------------------------------- | | Any (HTTP) | examples/http/curl.sh: activate, sell and open the window | | Node, no framework | examples/node/server.mjs (with the SDK) and examples/node/fetch.mjs (without) | | Node with the queue | examples/offline-till.ts: offline sales | | React | examples/react/LoyaltyButton.tsx: the till's button | | React Router / Remix | examples/react-router/loyalty.tsx: server action and useFetcher | | Next.js | examples/nextjs: server and webhook | | Angular | examples/angular: the till's button | | Plain HTML | examples/html/till.html: the window in an <iframe> | | Python | examples/python/webhook.py (Flask) | | PHP | examples/php/webhook.php | | C# / .NET | examples/csharp/RepitooWebhook.cs: webhook and sale | | Java | examples/java/RepitooTill.java: sale with HttpClient | | Go | examples/go/webhook.go |

For your coding assistant: AGENTS.md, llms.txt and the skills/repitoo-partner skill.