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

@streetjs/plugin-marzpay

v1.1.0

Published

Official StreetJS plugin: MarzPay payments (dependency-free HTTPS client).

Readme

@streetjs/plugin-marzpay

MarzPay for StreetJS applications — payments, billing, webhooks, and verification, without the complexity of a full payment SDK.

Official StreetJS plugin: MarzPay payments.

Dependency-free — request construction is pure and offline-verifiable; the network send uses node:https. Mirrors the official PayPal/Stripe plugins' design.

Every implemented behavior traces to a Verified_Capability recorded in the MarzPay research artifact (verify-don't-invent). Undocumented MarzPay topics (refunds, customer subscriptions, recurring billing, webhook signature scheme) are recorded there as limitations and are not implemented from assumption.

Install

npm install @streetjs/plugin-marzpay
# or: street add marzpay

Configuration

import { MarzPayPlugin } from '@streetjs/plugin-marzpay';

const plugin = MarzPayPlugin({
  apiKey: process.env.MARZPAY_API_KEY,
  secretKey: process.env.MARZPAY_SECRET,
  environment: 'sandbox', // or 'production' (default 'sandbox')
  stateKey: 'marzpay',
});

| Field | Type | Required | Notes | |-------|------|:--------:|-------| | apiKey / secretKey | string | yes | MarzPay API credentials (Basic auth) | | environment | 'sandbox' | 'production' | no | default sandbox | | stateKey | string | no | request-state key (default marzpay) | | timeoutMs | number | no | request timeout, default 30000 |

Status: package skeleton. Configuration, the request builders, the MarzPayClient, and the MarzPayPlugin lifecycle are implemented in subsequent spec tasks.

Capability namespaces

The client injected into application state (default ctx.state.marzpay) exposes six capability-oriented namespaces. Each implemented operation traces to a Verified_Capability in the research artifact; operations whose MarzPay endpoint is not yet documented surface an explicit unsupported-operation error and issue no network request (verify-don't-invent).

| Namespace | Operations | Status | |-----------|------------|--------| | collections | collectMoney(request), getStatus(reference) | Verified — POST /collect-money, GET /transactions/{reference} | | disbursements | sendMoney(request), getStatus(reference) | getStatus verified (GET /transactions/{reference}); sendMoney unverified | | transactions | get(reference) | Verified — GET /transactions/{id} | | accounts | getBalance() | Unverified | | phoneVerification | verify(request), isVerified(request), getUserInfo(request) | Unverified | | utils | formatPhoneNumber(value), isValidPhoneNumber(value) | Local (no network) |

collections

const result = await marzpay.collections.collectMoney({
  amount: 5000,
  country: 'UG',
  reference: 'order-123',
  phone_number: '+256700000000', // or method: 'card'
});
// → { reference, status, redirectUrl? }  (redirectUrl for card flows)

const status = await marzpay.collections.getStatus('order-123');
// → { reference, status }

Argument guards run before any send: a missing/empty amount, country, reference, or payment channel throws a PluginError naming the offending field and issues no network request. A reference that is empty, whitespace-only, or longer than 256 characters (after trimming) is rejected the same way. Non-2xx responses throw an error that includes the returned HTTP status.

transactions

const tx = await marzpay.transactions.get('order-123');
// → { id, reference, amount, currency, status }

Backed by the verified GET /transactions/{id} endpoint with the same reference guard and non-2xx-includes-status mapping as collections.

disbursements

const status = await marzpay.disbursements.getStatus('payout-7'); // verified
await marzpay.disbursements.sendMoney({ /* ... */ });             // unsupported (see below)

getStatus(reference) is fully functional — it reads the verified transactions endpoint. sendMoney(request) validates its required fields first, then surfaces an UnsupportedOperationError: no send-money endpoint is recorded as a Verified_Capability in the research artifact, so the seam stays unbound and no network request is issued.

accounts

await marzpay.accounts.getBalance(); // throws UnsupportedOperationError

getBalance() surfaces an UnsupportedOperationError and issues no network request. The research artifact mentions a Balance API only incidentally and records no concrete balance endpoint, so the seam is left unbound.

phoneVerification

await marzpay.phoneVerification.verify({ phone_number: '+256700000000' });     // unsupported
await marzpay.phoneVerification.isVerified({ phone_number: '+256700000000' }); // unsupported
await marzpay.phoneVerification.getUserInfo({ phone_number: '+256700000000' });// unsupported

Each operation validates its required fields first, then surfaces an UnsupportedOperationError. No phone-verification endpoint is recorded as a Verified_Capability, so all three seams stay unbound and issue no network request.

Note on unverified operations (disbursements.sendMoney, accounts.getBalance, phoneVerification.*): these are intentionally unbound until MarzPay documents the corresponding endpoints. Binding them requires first recording an audited Verified_Capability entry (with a citation) in the research artifact. Until then they fail fast with UnsupportedOperationError and never touch the network.

utils

marzpay.utils.isValidPhoneNumber('0700000000'); // → true / false
marzpay.utils.formatPhoneNumber('0700000000');  // → '+256700000000' (throws PluginError when invalid)

utils exposes only these two helpers. Both delegate to the same single internal normalizer, so formatPhoneNumber output is always accepted by isValidPhoneNumber (round-trip consistency). These are local, offline helpers — they issue no network request.

Flat compatibility methods

For backward compatibility, the flat MarzPayClient methods are retained as thin aliases over the same code paths used by the namespaces, with no behavioral change:

  • initializePayment(request) ≡ collections.collectMoney(request)
  • verifyPayment(reference) ≡ collections.getStatus(reference)
  • getTransaction(id) ≡ transactions.get(id)
  • listTransactions(...) — retained as a flat method
  • refund(...) — unsupported (refunds are a recorded limitation; no endpoint is documented)
  • validateWebhook(rawBody, signature) — unchanged

Security

  • Permissions: net, secrets, middleware. Ed25519-signed manifest verified on install.
  • Credentials are sent only as a Basic-auth header to MarzPay over HTTPS.
  • No third-party runtime dependencies.

License

MIT