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

paygenix-sdk

v0.0.2

Published

Thin JavaScript SDK for collecting card payments via Paygenix. Wraps VGS Collect.js — merchants mount secure card fields and receive a tokn_xxx token without raw card data ever touching their server.

Readme

paygenix-sdk

CDN: https://cdn.jsdelivr.net/npm/[email protected]/dist/paygenix-sdk.umd.js

Collect card payments without raw card data ever touching your server.
The SDK mounts secure hosted fields (powered by VGS) into your page and returns a tokn_xxx token you send to your backend.


Who should read what

| I want to… | Go to | |------------|-------| | Add Paygenix payments to my app | Merchant Integration | | Run the HTML demo locally | Running the Demo | | Contribute to this package | Development |


Merchant Integration

You only need: a publishable key and your checkout page.
No .env file, no demo server, no local setup beyond npm install.

Step 0 — Get your publishable key

Log in to the Paygenix dashboard and copy your key:

| Environment | Key format | Use for | |-------------|------------|---------| | Sandbox | pk_test_… | Development, QA, CI | | Production | pk_live_… | Real payments |

Never commit keys to source control. Use environment variables (process.env, import.meta.env, etc.)

Step 1 — Install

CDN (recommended — no bundler required):

<!-- Pin the version. Replace 0.0.2 with the latest version from npm. -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/paygenix-sdk.umd.js"></script>

npm (optional, for bundler users):

npm install paygenix-sdk

Step 2 — Add a mount point to your HTML

<!-- Any empty element works — the SDK injects hosted iframes here -->
<div id="card-form"></div>
<button id="pay">Pay now</button>

Step 3 — Initialise and mount

// CDN: Paygenix is on window.Paygenix after the <script> tag loads.
// npm: import { Paygenix } from 'paygenix-sdk';

const pg = await Paygenix.init({ publishableKey: 'pk_test_xxx' });

pg.mountCardForm('#card-form');
// Three hosted fields (card number, expiry, CVV) now render inside #card-form.
// Raw card data is captured only inside VGS iframes — never in your JS.

Step 4 — Tokenise on submit

const { token, error } = await pg.createToken({
  cardholderName: 'Somchai Prasert', // from a name input in your UI
  country: 'TH',                     // ISO 3166-1 alpha-2
});

if (error) {
  // Always resolves — never throws
  alert(error.message); // e.g. "Card number is invalid"
} else {
  // Send token.id to YOUR backend — the only card identifier you ever handle
  await fetch('/api/charge', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ token: token.id }),
  });
}

The token contains:

token.id        // 'tokn_xxx'  — send this to your server
token.card.brand      // 'visa'
token.card.last4      // '4242'
token.card.exp_month  // 3
token.card.exp_year   // 2029

React example

import { Paygenix } from 'paygenix-sdk';
import type { PaygenixInstance } from 'paygenix-sdk';

const PUBLISHABLE_KEY = import.meta.env.VITE_PAYGENIX_PUBLISHABLE_KEY;

useEffect(() => {
  Paygenix.init({ publishableKey: PUBLISHABLE_KEY }).then((pg) => {
    pgRef.current = pg;
    pg.mountCardForm('#card-form');
  });
}, []);

// On form submit:
const { token, error } = await pgRef.current.createToken({
  cardholderName: `${firstName} ${lastName}`.trim(),
  country,
});

See examples/react/CheckoutForm.tsx for the full component with loading state, error handling, and styling.

Plain HTML example (no bundler)

<div id="card-form"></div>
<button id="pay">Pay now</button>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/paygenix-sdk.umd.js"></script>
<script>
  Paygenix.init({ publishableKey: 'pk_test_xxx' }).then(function (pg) {
    pg.mountCardForm('#card-form');

    document.getElementById('pay').addEventListener('click', async function () {
      var result = await pg.createToken({
        cardholderName: document.getElementById('name').value,
        country: 'TH',
      });
      if (result.error) {
        alert(result.error.message);
      } else {
        console.log('Token:', result.token.id); // send to your server
      }
    });
  });
</script>

Styling

The SDK injects this structure inside your mount node:

<div class="pg-card-fields">
  <div class="pg-field-group">          <!-- card number row -->
    <label>Card number</label>
    <div class="vgs-input-wrap">        <!-- style border/background here -->
      <div id="pg-card-number" class="vgs-mount"></div>
    </div>
  </div>
  <div class="pg-row2">                 <!-- expiry + CVV side by side -->
    ...
  </div>
</div>

Key CSS targets: .vgs-input-wrap (border, background), .pg-row2 (two-column grid), .pg-field-group label (field labels).

CORS — what you need to do

The SDK makes two requests from the customer's browser to the Paygenix API:

GET  /v2/external/checkout-config   (on init)
POST /v2/tokens                     (on createToken)

Because these are cross-origin requests from the customer's browser, your checkout domain must be registered in Paygenix.

| Your page is on… | What to do | |-----------------|-----------| | https://checkout.yourstore.com | Register this origin in the Paygenix dashboard (or contact support) | | http://localhost:* (local dev) | Register your localhost origin in the sandbox dashboard, or point apiBase at a same-origin proxy you control |

The demo server (npm run demo) uses a built-in proxy so it does not need CORS registration — see Running the Demo.

API reference

Paygenix.version

Semver string baked into the build (e.g. 0.0.2). On Paygenix.init(), the SDK fetches the latest version from npm via jsDelivr and logs a one-time console.warn with an updated script URL if yours is behind — init is never blocked.

Paygenix.init(options)

| Option | Type | Required | Description | |--------|------|:--------:|-------------| | publishableKey | string | ✅ | pk_test_… or pk_live_… from the dashboard | | apiBase | string | — | Override the API origin. Omit this in production — the correct URL is already in the package. |

Returns Promise<PaygenixInstance>. Throws PaygenixError on failure.

pg.mountCardForm(selector)

Injects three hosted fields (card number, expiry, CVV) into the element matched by selector. Idempotent — safe to call again on re-mount.

pg.createToken(options?)

| Option | Type | Description | |--------|------|-------------| | cardholderName | string | Full name on the card. Stored in the token record. | | country | string | ISO 3166-1 alpha-2 (e.g. TH). Stored in the token record. |

Returns Promise<CreateTokenResult> — never throws:

{ token: { id: 'tokn_xxx', card: { brand, last4, exp_month, exp_year } } }
// or
{ error: { code, message } }

Error codes

| Code | Meaning | |------|---------| | invalid_card | Card number / expiry / CVV failed VGS validation | | submit_failed | Network error or Paygenix API rejected the request | | config_fetch_failed | Could not reach Paygenix API (wrong key, CORS not set up, network) | | vgs_load_failed | VGS Collect.js <script> failed to load | | mount_failed | selector matched no element in the DOM | | init_failed | publishableKey was empty or missing |

Security notes

  • Raw PAN and CVV never enter your JavaScript — VGS hosted iframes own that data.
  • token.id (tokn_xxx) is the only card-related value your code handles.
  • Never log or persist error.cause in production — it may contain upstream API payloads.
  • Use pk_test_… everywhere outside production. Never commit keys to source control.

Running the Demo

This section is for Paygenix team members and contributors who want to run examples/html/index.html against a local gupay-api.
Merchants do not need any of this.

How the demo avoids CORS

The demo server proxies API calls server-side so the browser never talks cross-origin:

Browser  →  http://localhost:3002/v2/tokens   (same origin — no CORS check)
                    ↓  Node.js proxy
demo-server  →  http://localhost:3000/v2/tokens   (server-to-server — CORS not applied)
                    ↓
               gupay-api responds

No CORS registration is needed anywhere for the demo.

Prerequisites

| Requirement | Details | |-------------|---------| | Paygenix API | Dev default: https://dev-api.paygenix.co (or local gupay-api on :3000) | | Publishable key | A pk_test_… key valid for the API environment you target | | Built SDK | dist/paygenix-sdk.umd.js must exist (npm run build) |

Start the demo

# 1. Copy and edit env
cp .env.example .env
# Set GUPAY_API_BASE to the API you want the demo proxy to target:
#   https://dev-api.paygenix.co    ← dev (default in .env.example)
#   https://uat-api.paygenix.co    ← UAT
#   http://localhost:3000          ← local gupay-api
#   https://api.paygenix.co        ← production (use real pk_live_ key, be careful)

# 2. Build the SDK
npm install && npm run build

# 3. Start gupay-api (if pointing at local), then:
npm run demo

Open http://localhost:3002/examples/html/index.html

| Port | Role | |------|------| | 3002 | Demo page + /v2/* reverse proxy | | GUPAY_API_BASE | Actual API target (proxied server-side) |

Point the demo at production or sandbox

Just change .env and restart — no rebuild required for the proxy target:

# .env
GUPAY_API_BASE=https://dev-api.paygenix.co      # dev
# GUPAY_API_BASE=https://uat-api.paygenix.co    # UAT
# GUPAY_API_BASE=https://api.paygenix.co        # production (real charges possible!)

Update the PUBLISHABLE_KEY constant in examples/html/index.html to match the environment.

⚠️ Pointing at production with pk_live_… uses your live VGS vault. Real card aliases will be created. Only do this for deliberate live-vault testing.


Releasing (maintainers)

Use this checklist when shipping a new version (CDN-first; npm is optional).

Prerequisites

| Tool | Version | |------|---------| | Node.js | ≥ 18 | | npm | ≥ 9 | | git | configured with access to github.com/paygenix/paygenix-sdk | | npm account | only if you publish to the public registry |

1 — One-time git setup

cd paygenix-sdk   # or your local clone path

# Initialise (skip if already a repo)
git init
git remote add origin https://github.com/paygenix/paygenix-sdk.git

# Never commit secrets
# .env is already in .gitignore

Rename the GitHub repository to paygenix-sdk if it is still paygenix-cards-js (Settings → Repository name).

2 — Build and verify locally

npm install
cp .env.example .env          # set GUPAY_API_BASE for the target API
npm run lint
npm test
npm run build

Confirm the UMD bundle exists and contains the right version:

ls -la dist/paygenix-sdk.umd.js
# Should embed version 0.0.1 in the built file

Optional smoke test:

npm run demo
# Open http://localhost:3002/examples/html/index.html

3 — Commit the CDN artifact

Only dist/paygenix-sdk.umd.js (+ .map) are tracked for jsDelivr; other dist/ files are gitignored.

git add package.json package-lock.json src/ tests/ README.md
git add dist/paygenix-sdk.umd.js dist/paygenix-sdk.umd.js.map
git commit -m "build: release v0.0.2"

4 — Tag v0.0.2 and push (optional GitHub mirror)

git tag v0.0.2
git push origin main
git push origin v0.0.2

Primary CDN is npm via jsDelivr (no GitHub tag required):

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/paygenix-sdk.umd.js"></script>

Optional: commit dist/paygenix-sdk.umd.js and use GitHub jsDelivr only if you maintain that mirror. After git push + tag, the GitHub CDN URL is live (may take a few minutes):

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/paygenix-sdk.umd.js"></script>

Latest (always points at the newest tag):

<script src="https://cdn.jsdelivr.net/npm/paygenix-sdk@latest/dist/paygenix-sdk.umd.js"></script>

Pin @0.0.2 in production; use @latest only for experiments.

5 — npm publish (optional)

CDN is the primary distribution. Publish to npm only if bundler users need npm install paygenix-sdk:

npm login
npm publish --access public

prepublishOnly runs lint, test, and build automatically.

6 — Version check (built into the SDK)

Merchants do not configure this. On every Paygenix.init():

  1. The bundled version is read from Paygenix.version (e.g. "0.0.1").
  2. The SDK fetches https://cdn.jsdelivr.net/npm/paygenix-sdk/package.json (latest on npm).
  3. If the published version is newer, a one-time console.warn prints the upgrade script URL. Init is never blocked.

Verify after release:

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/paygenix-sdk.umd.js"></script>
<script>
  Paygenix.init({ publishableKey: 'pk_test_xxx' }).then(() => {
    console.log('Loaded SDK version:', Paygenix.version); // e.g. "0.0.2"
  });
</script>

Open DevTools → Console. If a newer tag exists on GitHub, you will see the upgrade warning.

7 — Ship a patch release (example 0.0.2)

# Bump version in package.json → "0.0.2"
npm run build
git add package.json package-lock.json dist/paygenix-sdk.umd.js dist/paygenix-sdk.umd.js.map
git commit -m "build: release v0.0.2"
git tag v0.0.2
git push origin main --tags
# optional: npm publish

Update CDN examples in this README from @0.0.2 to the new tag.


Development (this package)

npm install
cp .env.example .env      # GUPAY_API_BASE bakes into the bundle at build time
npm run build             # ESM + CJS + UMD → dist/
npm test                  # vitest
npm run lint              # tsc --noEmit

GUPAY_API_BASE in .env is substituted at build time — change it and rebuild for the bundle default to update. See .env.example for all variables.


License

MIT