@volverjs/satispay-node-sdk
v0.0.4
Published
(Unofficial) Satispay GBusiness Node.js API SDK
Maintainers
Readme
(Unofficial) Satispay GBusiness Node.js API SDK
Universal (but unofficial) TypeScript SDK for Satispay GBusiness API integration. Zero external dependencies, compatible with Node.js, Deno, and Bun.
Features
- Zero dependencies - Uses only native standard APIs (fetch, crypto)
- Multi-runtime - Works with Node.js 18+, Deno 1.30+, and Bun 1.0+
- Lightweight - Only 268KB bundle size
- Type-safe - Complete TypeScript definitions
- Modern - Fetch API, async/await, ES Modules
- Secure - Native RSA-SHA256 encryption
- Developer-friendly - Intuitive API with automatic conversions:
- 💶 Use
amount(euros) instead ofamount_unit(cents) - 📅 Use
Dateobjects instead of timestamp strings
- 💶 Use
Installation
Node.js
npm install @volverjs/satispay-node-sdkDeno
import { Api, Payment } from "npm:@volverjs/satispay-node-sdk";Or use deno.json:
{
"imports": {
"satispay": "npm:@volverjs/satispay-node-sdk"
}
}Bun
bun add @volverjs/satispay-node-sdkQuick Start
Authentication
Get your credentials using the CLI tool with an activation token:
npx @volverjs/satispay-node-sdk YOUR_ACTIVATION_TOKENThis will generate:
- Public Key - RSA public key
- Private Key - RSA private key (keep this secure!)
- Key ID - Your authentication key ID
Where to get the activation token:
- Production: Satispay Business Dashboard → Developers → Generate Activation Code
- Sandbox: Request from Satispay Developer Support
Options:
npx @volverjs/satispay-node-sdk YOUR_TOKEN # Sandbox (default)
npx @volverjs/satispay-node-sdk YOUR_TOKEN --production # Production
npx @volverjs/satispay-node-sdk YOUR_TOKEN --sandbox # Sandbox (explicit)⚠️ Important: The activation token is single-use. Save the generated credentials securely!
Configure the SDK
Use the generated credentials to configure the SDK:
import { Api } from '@volverjs/satispay-node-sdk';
Api.setSandbox(true); // or false for production
Api.setPublicKey(process.env.SATISPAY_PUBLIC_KEY!);
Api.setPrivateKey(process.env.SATISPAY_PRIVATE_KEY!);
Api.setKeyId(process.env.SATISPAY_KEY_ID!);Store credentials in .env:
SATISPAY_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----\n..."
SATISPAY_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n..."
SATISPAY_KEY_ID="your-key-id"API Reference
Payment Operations
Create Payment
// Using amount in euros (recommended)
const payment = await Payment.create({
flow: 'MATCH_CODE',
amount: 1.00, // Automatically converted to 100 cents
currency: 'EUR',
callback_url: 'https://your-site.com/callback',
external_code: 'ORDER-123',
metadata: { order_id: '12345' },
});
// Or using amount_unit in cents (still supported)
const payment2 = await Payment.create({
flow: 'MATCH_CODE',
amount_unit: 100, // Amount in cents
currency: 'EUR',
callback_url: 'https://your-site.com/callback',
external_code: 'ORDER-123',
metadata: { order_id: '12345' },
});💡 Tip: Use amount (euros) for more intuitive code. The SDK automatically converts it to cents.
See examples/create-payment-with-amount.ts for more examples.
Get Payment
const payment = await Payment.get('PAYMENT_ID');
console.log('Status:', payment.status);List Payments
const result = await Payment.all({
limit: 20,
status: 'ACCEPTED',
from_date: '2024-01-01',
});
result.data.forEach(payment => {
console.log(`${payment.id}: ${payment.status}`);
});Filter by Date
You can filter payments using Date objects or timestamp strings:
// Using Date objects (recommended)
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const recentPayments = await Payment.all({
starting_after_timestamp: yesterday, // Date is automatically converted to milliseconds
limit: 10,
});
// Or using timestamp string (milliseconds)
const timestampString = new Date('2024-01-01').getTime().toString();
const paymentsFromDate = await Payment.all({
starting_after_timestamp: timestampString,
limit: 10,
});See examples/payment-date-filtering.ts for more examples.
Update Payment
// Using amount in euros
const payment = await Payment.update('PAYMENT_ID', {
action: 'ACCEPT',
amount: 5.50, // Automatically converted to 550 cents
});
// Or using amount_unit in cents
const payment2 = await Payment.update('PAYMENT_ID', {
action: 'ACCEPT',
amount_unit: 550,
});Consumer Operations
import { Consumer } from '@volverjs/satispay-node-sdk';
const consumer = await Consumer.get('+393331234567');
console.log('Consumer:', consumer.name);Daily Closure
import { DailyClosure } from '@volverjs/satispay-node-sdk';
// Today's closure
const closure = await DailyClosure.get();
// Specific date using Date object (recommended)
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const closureByDate = await DailyClosure.get(yesterday);
// Or using YYYYMMDD string format
const closureByString = await DailyClosure.get('20240115');
console.log('Date:', closure.shop_daily_closure.id);
console.log('Total:', closure.shop_daily_closure.amount_unit / 100, closure.shop_daily_closure.currency);
console.log('Gross:', closure.shop_daily_closure.gross_amount_unit / 100);
console.log('Refunds:', closure.shop_daily_closure.refund_amount_unit / 100);Pre-Authorized Payment Tokens
Pre-Authorized Payment Tokens allow consumers to authorize payments in advance:
import { PreAuthorizedPaymentToken } from '@volverjs/satispay-node-sdk';
// Create a pre-authorized payment token
const token = await PreAuthorizedPaymentToken.create({
reason: 'Subscription payment',
callback_url: 'https://your-site.com/callback',
redirect_url: 'https://your-site.com/success',
});
console.log('Token ID:', token.id);
console.log('Token:', token.token);
console.log('Status:', token.status); // PENDING
// Get token details
const retrievedToken = await PreAuthorizedPaymentToken.get(token.id);
// Update token (e.g., cancel it)
const updatedToken = await PreAuthorizedPaymentToken.update(token.id, {
status: 'CANCELED',
});
// Once the consumer accepts the token, you can use it to create payments:
const payment = await Payment.create({
flow: 'PRE_AUTHORIZED',
token: token.token,
amount: 9.99,
currency: 'EUR',
});Important Notes:
- The consumer must accept the token before it can be used for payments
- Token status can be:
PENDING,ACCEPTED, orCANCELED - Use the
tokenfield (not theid) when creating pre-authorized payments
Reports
⚠️ Special Authentication Required: Report APIs require special authentication keys. Contact [email protected] to enable access.
import { Report } from '@volverjs/satispay-node-sdk';
// Create a new report
const report = await Report.create({
type: 'PAYMENT_FEE',
format: 'CSV', // or 'PDF', 'XLSX'
from_date: '2025-11-01',
to_date: '2025-11-30',
columns: ['transaction_id', 'transaction_date', 'total_amount'], // Optional
});
// Get list of reports
const reports = await Report.all({
limit: 10,
starting_after: 'report-123',
});
// Get specific report
const reportDetails = await Report.get('report-123');
if (reportDetails.status === 'READY' && reportDetails.download_url) {
console.log('Download URL:', reportDetails.download_url);
}Important Notes:
- Reports are extracted at merchant level (includes all shops)
- Reports for the previous day should be generated at least 4 hours after midnight
- Report status:
PENDING,READY, orFAILED
Sessions (POS Integration)
Sessions are used for POS/device integration to manage fund lock payments incrementally:
import { Session } from '@volverjs/satispay-node-sdk';
// Open a session from a fund lock
const session = await Session.open({
fund_lock_id: 'payment-fund-lock-123',
});
console.log('Session ID:', session.id);
console.log('Available amount:', session.residual_amount_unit);
// Add items to the session
await Session.createEvent(session.id, {
operation: 'ADD',
amount_unit: 500,
currency: 'EUR',
description: 'Coffee',
metadata: { sku: 'COFFEE-001' },
});
// Remove items (e.g., discount)
await Session.createEvent(session.id, {
operation: 'REMOVE',
amount_unit: 200,
currency: 'EUR',
description: 'Discount',
});
// Get session details
const details = await Session.get(session.id);
console.log('Residual amount:', details.residual_amount_unit);
// Close the session
const closedSession = await Session.update(session.id, {
status: 'CLOSE',
});Meal Voucher & Fringe Benefits
Meal Voucher and Fringe Benefits payments use the same Payment API with additional parameters:
import { Payment } from '@volverjs/satispay-node-sdk';
// Create payment with Meal Voucher limits
const payment = await Payment.create({
flow: 'MATCH_CODE',
amount: 50.00,
currency: 'EUR',
meal_voucher_max_amount_unit: 4000, // Max 40 EUR with meal vouchers
meal_voucher_max_quantity: 8, // Max 8 vouchers
});
// Update payment with Meal Voucher limits
const updated = await Payment.update(payment.id, {
action: 'ACCEPT',
meal_voucher_max_amount_unit: 3000,
meal_voucher_max_quantity: 6,
});Important Notes:
- Meal Vouchers and Fringe Benefits are mutually exclusive
- Meal Voucher refunds: Only on the same day, full amount only
- Fringe Benefits refunds: Only within the same month, full amount only
- Default limit: 8 meal vouchers per payment if not specified
Runtime-Specific Examples
Node.js Server
import express from 'express';
import { Api, Payment } from '@volverjs/satispay-node-sdk';
Api.setSandbox(true);
Api.setPublicKey(process.env.SATISPAY_PUBLIC_KEY);
Api.setPrivateKey(process.env.SATISPAY_PRIVATE_KEY);
Api.setKeyId(process.env.SATISPAY_KEY_ID);
const app = express();
app.use(express.json());
app.post('/create-payment', async (req, res) => {
const payment = await Payment.create({
flow: 'MATCH_CODE',
amount_unit: req.body.amount,
currency: 'EUR',
});
res.json(payment);
});
app.listen(3000);Deno Server
import { serve } from "https://deno.land/[email protected]/http/server.ts";
import { Api, Payment } from "npm:@volverjs/satispay-node-sdk";
Api.setSandbox(true);
Api.setPublicKey(Deno.env.get("SATISPAY_PUBLIC_KEY")!);
Api.setPrivateKey(Deno.env.get("SATISPAY_PRIVATE_KEY")!);
Api.setKeyId(Deno.env.get("SATISPAY_KEY_ID")!);
serve(async (req) => {
const url = new URL(req.url);
if (url.pathname === "/create-payment" && req.method === "POST") {
const body = await req.json();
const payment = await Payment.create({
flow: "MATCH_CODE",
amount_unit: body.amount,
currency: "EUR",
});
return Response.json(payment);
}
return Response.json({ error: "Not found" }, { status: 404 });
});Bun Server
import { Api, Payment } from "@volverjs/satispay-node-sdk";
Api.setSandbox(true);
Api.setPublicKey(process.env.SATISPAY_PUBLIC_KEY!);
Api.setPrivateKey(process.env.SATISPAY_PRIVATE_KEY!);
Api.setKeyId(process.env.SATISPAY_KEY_ID!);
Bun.serve({
port: 3000,
async fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/create-payment" && req.method === "POST") {
const body = await req.json();
const payment = await Payment.create({
flow: "MATCH_CODE",
amount_unit: body.amount,
currency: "EUR",
});
return Response.json(payment);
}
return Response.json({ error: "Not found" }, { status: 404 });
},
});Custom Headers
import { Api, Request } from '@volverjs/satispay-node-sdk';
// Global headers
Api.setPlatformHeader('MyApp');
Api.setPlatformVersionHeader('1.0.0');
Api.setPluginNameHeader('my-plugin');
Api.setPluginVersionHeader('2.0.0');
Api.setTypeHeader('ONLINE_SHOP');
Api.setTrackingHeader('tracking-code-123');
// Per-request headers
const payment = await Payment.create(
{
flow: 'MATCH_CODE',
amount_unit: 100,
currency: 'EUR',
},
{
[Request.HEADER_TRACKING_CODE]: 'custom-tracking-code',
[Request.HEADER_IDEMPOTENCY_KEY]: 'unique-key-123',
}
);Environment Configuration
Sandbox Mode
Api.setSandbox(true); // Test environment
Api.setSandbox(false); // Production environmentEnvironment Variables
Store your credentials securely:
# .env
SATISPAY_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----..."
SATISPAY_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----..."
SATISPAY_KEY_ID="your-key-id"Development
# Install dependencies
pnpm install
# Build
pnpm build
# Watch mode
pnpm build:watch
# Run tests
pnpm test
# Watch tests
pnpm test:watch
# Test with UI
pnpm test:ui
# Coverage report
pnpm test:coverage
# Lint
pnpm lint
# Format
pnpm formatTesting
This project uses Vitest for testing. The test suite includes:
- Unit tests for all core modules (Api, Payment, Consumer, DailyClosure, etc.)
- RSA Service tests for cryptographic operations
- Mock-based tests for API interactions
Current test coverage: 94.82% (Statements: 93.83%, Branches: 89.65%, Functions: 100%, Lines: 95.8%)
Run tests:
pnpm test # Run all tests
pnpm test:watch # Watch mode for development
pnpm test:ui # Interactive UI
pnpm test:coverage # Generate coverage reportExamples
See the examples/ directory for complete examples:
auth-with-token.ts- Authentication with tokencreate-payment.ts- Create a paymentget-payment.ts- Get payment detailsget-payments.ts- List paymentsget-consumer.ts- Get consumer informationget-daily-closure.ts- Get daily closure
To run examples:
npm install
npm run build
cd examples
npx tsc
node dist/auth-with-token.jsRequirements
| Runtime | Minimum Version | Native fetch Support | |---------|----------------|---------------------| | Node.js | 18.0.0 | Yes | | Deno | 1.30.0 | Yes | | Bun | 1.0.0 | Yes |
No external dependencies required.
Technical Details
This SDK uses Web Standard APIs:
- fetch API for HTTP requests (native in all supported runtimes)
- crypto module for RSA-SHA256 signatures (Node.js crypto with compatibility layers for Deno/Bun)
Benefits:
- Same code works across all runtimes
- No polyfills needed
- Native performance
- Future-proof
Why Zero Dependencies?
- No third-party vulnerability risks
- Minimal bundle size (268KB)
- Fast installation
- No dependency conflicts
- Uses only standard APIs
Error Handling
try {
const payment = await Payment.create({
flow: 'MATCH_CODE',
amount_unit: 100,
currency: 'EUR',
});
} catch (error) {
console.error('Payment creation failed:', error.message);
}TypeScript Support
Full TypeScript support with complete type definitions included:
import type {
PaymentCreate,
PaymentResponse,
ConsumerResponse,
DailyClosureResponse,
} from '@volverjs/satispay-node-sdk';License
MIT
