@ninjapay/sdk
v0.1.0
Published
Official NinjaPay TypeScript SDK — borderless and confidential commerce on Solana
Maintainers
Readme
@ninjapay/sdk
Official TypeScript SDK for NinjaPay — borderless and confidential commerce on Solana. Stripe-portable merchant API + private x402 facilitator for AI agents + multi-recipient stablecoin payroll, with privacy-by-default via the Umbra Privacy SDK.
Install
npm install @ninjapay/sdk
# or
pnpm add @ninjapay/sdk
# or
yarn add @ninjapay/sdkRequires Node.js ≥ 20.
Quick start
import { NinjaPayClient } from '@ninjapay/sdk';
const ninjapay = new NinjaPayClient({
apiKey: process.env.NINJAPAY_API_KEY!, // nk_live_…
baseUrl: 'https://api.ninjapay.finance', // omit for default
});
// Create a payment link
const link = await ninjapay.paymentLinks.create({
amount: '49.99',
currency: 'USDC',
description: 'Pro plan — annual',
});
console.log(link.url); // https://checkout.ninjapay.finance/pay/<id>
// List recent payment intents
const { data } = await ninjapay.paymentIntents.list({ limit: 25 });Resources
The client exposes a Stripe-style resource surface:
client.paymentIntents— intent lifecycle (create, retrieve, list, cancel)client.paymentLinks— hosted-checkout link managementclient.refunds— full + partial refundsclient.customers— customer CRUD + summariesclient.subscriptions— recurring billingclient.invoices— invoice generation + filingclient.webhooks— webhook endpoint registrationclient.disputes— dispute lifecycleclient.connectedAccounts— Stripe-Connect-portableclient.transfers— direct on-chain transfersclient.payroll.{employees,batches,taxFilings}— multi-recipient payrollclient.x402Endpoints/client.x402Attestations— x402 facilitatorclient.accountClaims— recipient claim flow
See the API reference for full method signatures, request/response shapes, and error codes.
Webhook signature verification
Webhook verification helpers ship at the @ninjapay/sdk/webhooks subpath
(separate from the main client) because they statically import node:crypto
— which is unavailable in browser bundles. Server-side handlers use:
import { verifyWebhookSignature } from '@ninjapay/sdk/webhooks';
app.post('/webhooks/ninjapay', (req, res) => {
const result = verifyWebhookSignature({
body: req.rawBody, // Buffer or string of the raw request body
header: req.headers['x-ninjapay-signature']!,
secret: process.env.NINJAPAY_WEBHOOK_SECRET!,
});
if (!result.ok) {
return res.status(400).json({ error: result.reason });
}
const event = result.event; // typed WebhookEvent
switch (event.type) {
case 'payment_intent.succeeded':
// handle settlement
break;
case 'refund.succeeded':
// handle refund
break;
}
res.json({ received: true });
});The verifier:
- Parses the
X-NinjaPay-Signatureheader (t=<unix-secs>,v1=<hex-hmac>) - Asserts the timestamp is within the tolerance window (default ±5 min)
- Recomputes HMAC-SHA256 over
<t>.<body>keyed by your webhook secret - Constant-time compares — returns a discriminated
{ ok, reason? }
Mirrors packages/webhook-delivery/src/signature.ts byte-for-byte.
Errors
All resource methods throw one of three branded errors:
NinjaPayApiError— API returned 4xx/5xx with a structured bodyNinjaPayNetworkError— fetch failed (DNS, connection, timeout)NinjaPayResponseShapeError— response didn't match Zod schema
import {
NinjaPayApiError,
NinjaPayNetworkError,
NinjaPayResponseShapeError,
} from '@ninjapay/sdk';
try {
await ninjapay.paymentIntents.create({ /* ... */ });
} catch (err) {
if (err instanceof NinjaPayApiError) {
// err.status, err.body, err.requestId
} else if (err instanceof NinjaPayNetworkError) {
// retryable
}
}Idempotency
All mutating endpoints accept an Idempotency-Key header — pass it via the
optional second arg:
await ninjapay.refunds.create(
{ paymentIntentId: 'pi_…', amount: '12.50' },
{ idempotencyKey: 'refund-2026-05-22-001' },
);Same key + same body within the TTL window returns the cached result. Same key + different body returns 422.
Versioning
This SDK follows semver:
- Patch (
0.1.x) — bug fixes, internal-only refactors - Minor (
0.x.0) — new resources, new methods, additive type fields - Major (
x.0.0) — breaking changes to public API surface
Pre-1.0, minor versions may include breaking changes — pin to an exact
version ("@ninjapay/sdk": "0.1.0") for production use until 1.0.
The API surface (/v1/) is versioned independently. Breaking API changes
will land at /v2/ with a deprecation window — the SDK supports the
latest two API versions.
Telemetry
The SDK does not collect telemetry. All observability is server-side via OpenTelemetry on the NinjaPay platform itself.
Development
# from the monorepo root
pnpm install
pnpm -F @ninjapay/sdk build
pnpm -F @ninjapay/sdk testTo publish (maintainers only):
cd packages/sdk
npm login
pnpm publish --access public