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

@cuenca-mx/cep

v1.0.0

Published

TypeScript SDK for the Banxico CEP (Comprobante Electrónico de Pago) portal.

Readme

@cuenca-mx/cep

TypeScript SDK for the Banxico CEP portal — the public service that issues Comprobante Electrónico de Pago receipts for SPEI transfers.

This package is the JavaScript counterpart to cep-python. The two share the same protocol expectations and error semantics so consumers can switch languages without surprises.

Install

npm install @cuenca-mx/cep

Requires Node.js >= 20.

Usage

import Cep, {
  CepError,
  CepNotAvailableError,
  FileFormat,
  InvalidInstitutionError,
  MaxRequestError,
  TransferNotFoundError,
} from '@cuenca-mx/cep'

const cep = new Cep()

try {
  const transfer = await cep.transfers.validate({
    fecha: '08-11-2024', // dd-mm-yyyy
    claveRastreo: 'BiB202411081016248360',
    emisor: '37166', // 5-digit Banxico code
    receptor: '90723', // 5-digit Banxico code
    cuenta: '723969000011000077',
    monto: 341495, // amount in cents (integer), same as cep-python
  })
  void transfer.ordenante.nombre // parsed from Banxico XML after validate

  const pdf = await cep.transfers.download(FileFormat.Pdf)
  // pdf is a Buffer with the %PDF magic bytes already verified.
} catch (err: unknown) {
  if (err instanceof TransferNotFoundError) {
    /* 404 */
  } else if (err instanceof InvalidInstitutionError) {
    /* 422 — emisor/receptor are not Banxico 5-digit codes */
  } else if (err instanceof MaxRequestError) {
    /* 429 */
  } else if (err instanceof CepNotAvailableError) {
    /* 202 / retry later */
  } else if (err instanceof CepError) {
    /* other SDK errors */
  } else {
    throw err
  }
}

For server contexts that pipe the PDF straight into an HTTP response you can use downloadStream, which yields a Readable whose payload has already been validated as PDF/XML/ZIP:

import Cep, { FileFormat } from '@cuenca-mx/cep'
import { NextApiRequest, NextApiResponse } from 'next'

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const cep = new Cep() // fresh instance per request — see "Concurrency" below
  await cep.transfers.validate(req.query as any)
  const stream = await cep.transfers.downloadStream(FileFormat.Pdf)

  res.setHeader('Content-Type', 'application/pdf')
  stream.pipe(res)
}

Concurrency

Every new Cep() owns its own Client, which in turn owns its own axios session and cookie jar. Two concurrent CEP lookups in the same Node process never share a JSESSIONID. Always allocate a Cep instance per inbound request — do not cache one in module scope.

Errors

All errors thrown by the SDK extend CepError, so consumers can catch (err: unknown) and narrow with err instanceof CepError (and specific subclasses):

| Error | When Banxico says… | | ------------------------- | ------------------------------------------------------------------------------- | | TransferNotFoundError | "No se encontró ningún pago…" / "El SPEI no ha recibido…" | | CepNotAvailableError | "Con la información proporcionada se identificó el siguiente pago" (no CEP yet) | | InvalidInstitutionError | "No existe un emisor válido" / "…receptor válido" | | MaxRequestError | "Lo sentimos, pero ha excedido el número máximo de consultas" | | InvalidDownloadError | descarga.do returned non-PDF/XML/ZIP bytes | | CepRequestError | Network failure, 5xx, timeouts |

CepException and CepResponseException are kept as aliases for backwards compatibility with the 0.x line.

Configuration

Pass options when constructing Cep (or Client). There is no global base URL — each instance is isolated (better for tests and concurrent requests).

import Cep from '@cuenca-mx/cep'

new Cep({ beta: true }) // https://www.banxico.org.mx/cep-beta
new Cep() // production https://www.banxico.org.mx/cep
new Cep({ baseURL: 'https://internal-mock/cep' }) // tests / fixtures

Migrating from 0.x

  • validate throws a typed error if Banxico says the transfer does not exist / CEP is not available / emisor is invalid / rate limit was hit. On success it resolves to a Transfer parsed from Banxico XML (fields such as ordenante, beneficiario, concepto, sello, …).
  • download(...) now returns a verified Buffer (with PDF magic bytes already checked). Callers that need the previous "Readable stream" behavior should switch to downloadStream(...).
  • Client.getInstance() is gone — each new Cep() instantiates a fresh client. This fixes a session/cookie leak across concurrent requests in server runtimes (Next.js API, Vercel, Lambda).
  • set-cookie handling no longer joins entries with , — Banxico rejects the malformed header and the next call lost its session.
  • POST /valida.do now sends application/x-www-form-urlencoded body instead of a query string.

Development

npm install
npm run lint
npm test
npm run build

License

MIT — see LICENSE.