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

@mostajs/payment

v0.5.3

Published

Payment module for @mostajs — Multi-provider (Stripe, Satim/CIB, Chargily, PayPal), multi-method, multi-currency

Readme

@mostajs/payment

Payment module for @mostajs — Stripe checkout, multi-method (card, transfer, cash), multi-currency.

Install

npm install @mostajs/payment stripe

Usage

Schema

import { createPaymentSchema } from '@mostajs/payment'

// Default (no relation, USD)
const schema = createPaymentSchema()

// With relation to Reservation, DZD currency
const schema = createPaymentSchema({
  currency: 'DZD',
  relationTarget: 'Reservation',
  relationRequired: true,
})

Stripe Checkout (server-side)

import { createCheckoutHandler } from '@mostajs/payment/server'

const config = {
  currency: 'EUR',
  stripeSecretKey: process.env.STRIPE_SECRET_KEY,
  successUrlTemplate: '/confirmation/{orderId}?paid=true',
  cancelUrlTemplate: '/payment/{orderId}?cancelled=true',
}

// Next.js App Router
export const POST = createCheckoutHandler(config)

Payment Page (React)

import { PaymentPage } from '@mostajs/payment'

<PaymentPage
  orderId="12345"
  orderSummary={{
    title: 'Commande #12345',
    lines: [{ label: 'Article', value: '2x Widget' }],
    amount: 99.99,
    currency: 'EUR',
  }}
  config={{
    currency: 'EUR',
    stripePublicKey: process.env.NEXT_PUBLIC_STRIPE_KEY,
    successUrlTemplate: '/confirmation/{orderId}',
    cancelUrlTemplate: '/payment/{orderId}',
    methods: ['card', 'transfer'],
    bankInfo: { rib: 'FR76...', bankName: 'BNP', holder: 'SARL Example' },
  }}
  onSuccess={(method) => console.log('Paid via', method)}
/>

API

| Export | Entry | Description | |---|---|---| | PaymentSchema | . | Default schema (no relation) | | createPaymentSchema(opts) | . | Schema factory with options | | PaymentPage | . | React payment UI component | | createStripeClient(config) | ./server | Stripe SDK wrapper | | createCheckoutSession(stripe, req, config) | ./server | Create Stripe session | | handleWebhook(stripe, body, sig, secret) | ./server | Verify webhook | | createCheckoutHandler(config) | ./server | Next.js checkout route | | createPaymentHandlers(dialect) | ./server | CRUD route handlers | | getPaymentRepo(dialect) | ./server | Payment repository |

Environment

All provider factories read their secrets from environment variables as a fallback when no explicit config is passed. This is the recommended setup in production.

# Stripe
STRIPE_SECRET_KEY=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...

# PayPal (REST v2)
PAYPAL_CLIENT_ID=...
PAYPAL_SECRET=...
PAYPAL_TEST_MODE=false           # default: true unless literally 'false'
PAYPAL_RETURN_URL=/payment/success
PAYPAL_CANCEL_URL=/payment/canceled
PAYPAL_WEBHOOK_ID=...

# Chargily Pay V2 — Algeria (CIB + EDAHABIA)
CHARGILY_API_KEY=...
CHARGILY_TEST_MODE=false         # default: true unless literally 'false'
CHARGILY_SUCCESS_URL=/payment/success
CHARGILY_FAILURE_URL=/payment/failed
CHARGILY_WEBHOOK_URL=...

# Satim — Algeria (CIB, GIE Monetique)
SATIM_MERCHANT_ID=...
SATIM_PASSWORD=...
SATIM_TEST_MODE=true             # default: false unless literally 'true'
SATIM_RETURN_URL=/payment/callback
SATIM_FAIL_URL=/payment/failed

Profile cascade with MOSTA_ENV (v0.4+)

Powered by @mostajs/config. Keep one .env with profile-prefixed overrides à la Spring Boot profiles (spring.profiles.active=test) :

MOSTA_ENV=TEST

# Base defaults (used when no profile, or as fallback)
STRIPE_SECRET_KEY=sk_test_default
CHARGILY_API_KEY=test_default

# Profile overrides
TEST_STRIPE_SECRET_KEY=sk_test_xxx
TEST_CHARGILY_API_KEY=test_xxx

DEV_STRIPE_SECRET_KEY=sk_test_dev

PROD_STRIPE_SECRET_KEY=${VAULT_STRIPE}    # injected at runtime
PROD_CHARGILY_API_KEY=${VAULT_CHARGILY}

Resolution cascade (first non-empty value wins) :

  1. Explicit config argument passed to createStripeProvider(config) / etc.
  2. ${MOSTA_ENV}_${KEY} — profile-prefixed env var
  3. ${KEY} — plain env var
  4. Provider-specific default (empty string for required keys — the provider will raise a clear error at call time)

Missing profile overrides silently fall back to the plain variable — no crash if the profiled key is absent. Empty strings are treated as "not set" so they don't silently leak a blank secret to the provider SDK.

Why this matters for payments

Provider secrets move through orchestrators (Vault, Scaleway Secrets, Kubernetes Secrets, Doppler) in production. The cascade lets you keep one committed .env with safe test defaults and have PROD_* values injected at container startup. No more .env.production living in a separate private repo. Users already using plain STRIPE_SECRET_KEY etc. keep working unchanged — the cascade is fully backward-compatible.

Changelog

v0.4.1 — 2026-05-04 — Découplage @mostajs/orm via façade data-plug + WeakMap repo

Étape 3 du chantier « system dialect séparé » — applique deux fix qui se combinent.

1. Migration @mostajs/orm@mostajs/data-plug (façade)

Conformément au principe « les modules @mostajs passent par data-plug, jamais hardcoder un dialect ou importer @mostajs/orm directement », payment ne dépend plus de @mostajs/orm en peerDependency. Tous les imports de production passent désormais par @mostajs/data-plug v1.2.4 (qui ré-exporte BaseRepository, IDialect, EntitySchema, …).

4 fichiers migrés :

| Fichier | Symboles | |---------|----------| | src/api/payments.route.ts | IDialect | | src/lib/module-info.ts | EntitySchema | | src/lib/payment-factory.ts | BaseRepository + IDialect | | src/schemas/payment.schema.ts | EntitySchema | | package.json | peerDep ormdata-plug |

@mostajs/orm reste en devDependency uniquement (cohérence avec le test-unit qui pourrait l'instancier — sera revu plus tard).

2. WeakMap dans payment-factory.ts

// Avant — capture la référence du PREMIER dialect, ignore les suivants
let cachedRepo: BaseRepository<PaymentDTO> | null = null

// Après — keyed par identité du dialect
const cache = new WeakMap<IDialect, BaseRepository<PaymentDTO>>()

Évite que le repo capture la référence du PREMIER dialect passé et ignore tous les suivants. Lorsque /api/change-dialect (ou rotation système ↔ métier) modifie le dialect courant, le cache miss force la reconstruction du repo avec la nouvelle instance dialect — au lieu de réutiliser un repo pointant vers une connexion morte.

resetPaymentRepo() conservé en no-op pour rétro-compat (la WeakMap auto-libère naturellement les entrées dont le dialect n'est plus référencé).

Bump

0.4.0 → 0.4.1 (patch — découplage interne, signatures publiques inchangées).


v0.4.0 — 2026-04-21

Added : all four provider factories (createStripeProvider, createPayPalProvider, createChargilyProvider, createSatimProvider) now resolve environment variables through @mostajs/config. This enables profile-based override cascade (MOSTA_ENV=TESTTEST_STRIPE_SECRET_KEY priority over plain STRIPE_SECRET_KEY), with silent fallback when the profiled variant is absent. Matches Spring Boot profile semantics (spring.profiles.active=test).

  • src/providers/stripe.provider.ts : STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET
  • src/providers/paypal.provider.ts : PAYPAL_CLIENT_ID, PAYPAL_SECRET, PAYPAL_TEST_MODE, PAYPAL_RETURN_URL, PAYPAL_CANCEL_URL, PAYPAL_WEBHOOK_ID
  • src/providers/chargily.provider.ts : CHARGILY_API_KEY, CHARGILY_TEST_MODE, CHARGILY_SUCCESS_URL, CHARGILY_FAILURE_URL, CHARGILY_WEBHOOK_URL
  • src/providers/satim.provider.ts : SATIM_MERCHANT_ID, SATIM_PASSWORD, SATIM_TEST_MODE, SATIM_RETURN_URL, SATIM_FAIL_URL
  • package.json : add @mostajs/config ^1.0.0 dependency, bump to 0.4.0

Semantics preserved exactly : CHARGILY_TEST_MODE !== 'false' and SATIM_TEST_MODE === 'true' defaults are unchanged (Chargily defaults to test-on, Satim defaults to test-off).

License

AGPL-3.0-or-later — (c) 2026 Dr Hamid MADANI [email protected]

Commercial license available : [email protected]