Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,25 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.0.4] - 2025-12-03

### Changed
- **BREAKING:** `Session` API aligned with official Satispay documentation
- Changed `type` field to `operation` in session events
- Changed `SessionEventType` enum to `SessionEventOperation`
- Replaced `'ADD_ITEM' | 'REMOVE_ITEM' | 'UPDATE_TOTAL'` with `'ADD' | 'REMOVE'`
- Removed `UPDATE_TOTAL` operation (not supported by Satispay API)
- Made `currency` field mandatory in `SessionEventCreateBody`

### Added
- E2E tests for fund lock payment creation

### Fixed
- `Session` types and operations now match official Satispay API specification
- Corrected Session examples in README and `examples/pos-session.ts`
- Corrected Pre-Authorized Payment Tokens documentation in README
- Removed duplicate "Create a Payment" section from README

## [0.0.3] - 2025-12-03

### Changed
Expand Down Expand Up @@ -66,6 +85,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Example files for all major operations (payments, reports, sessions, webhooks, etc.)
- Runtime-specific examples for Node.js, Deno, and Bun

[0.0.3]: https://github.com/volverjs/zod-vue-i18n/compare/v0.0.2...v0.0.3
[0.0.2]: https://github.com/volverjs/zod-vue-i18n/compare/v0.0.1...v0.0.2
[0.0.4]: https://github.com/volverjs/satispay-node-sdk/compare/v0.0.3...v0.0.4
[0.0.3]: https://github.com/volverjs/satispay-node-sdk/compare/v0.0.2...v0.0.3
[0.0.2]: https://github.com/volverjs/satispay-node-sdk/compare/v0.0.1...v0.0.2
[0.0.1]: https://github.com/volverjs/satispay-node-sdk/releases/tag/v0.0.1
73 changes: 33 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Universal (but unofficial) TypeScript SDK for Satispay GBusiness API integration

- **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 156KB bundle size
- **Lightweight** - Only 268KB bundle size
- **Type-safe** - Complete TypeScript definitions
- **Modern** - Fetch API, async/await, ES Modules
- **Secure** - Native RSA-SHA256 encryption
Expand Down Expand Up @@ -98,29 +98,6 @@ SATISPAY_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----\n..."
SATISPAY_KEY_ID="your-key-id"
```

### Create a Payment

```typescript
import { Payment } from '@volverjs/satispay-node-sdk';

// Using amount in euros (recommended)
const payment = await Payment.create({
flow: 'MATCH_CODE',
amount: 1.99, // Amount in euros (automatically converted to cents)
currency: 'EUR',
});

// Or using amount_unit in cents (still supported)
const payment2 = await Payment.create({
flow: 'MATCH_CODE',
amount_unit: 199, // Amount in cents (1.99 EUR)
currency: 'EUR',
});

console.log('Payment ID:', payment.id);
console.log('Code:', payment.code_identifier);
```

## API Reference

### Payment Operations
Expand Down Expand Up @@ -247,24 +224,44 @@ 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:

```typescript
import { PreAuthorizedPaymentToken } from '@volverjs/satispay-node-sdk';

// Create token
// Create a pre-authorized payment token
const token = await PreAuthorizedPaymentToken.create({
flow: 'MATCH_CODE',
consumer_uid: 'CONSUMER_UID',
reason: 'Subscription payment',
callback_url: 'https://your-site.com/callback',
redirect_url: 'https://your-site.com/success',
});

// Get token
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
// 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`, or `CANCELED`
- Use the `token` field (not the `id`) when creating pre-authorized payments

### Reports

> **⚠️ Special Authentication Required**: Report APIs require special authentication keys. Contact tech@satispay.com to enable access.
Expand Down Expand Up @@ -317,25 +314,21 @@ console.log('Available amount:', session.residual_amount_unit);

// Add items to the session
await Session.createEvent(session.id, {
type: 'ADD_ITEM',
operation: 'ADD',
amount_unit: 500,
currency: 'EUR',
description: 'Coffee',
metadata: { sku: 'COFFEE-001' },
});

// Remove items
// Remove items (e.g., discount)
await Session.createEvent(session.id, {
type: 'REMOVE_ITEM',
operation: 'REMOVE',
amount_unit: 200,
currency: 'EUR',
description: 'Discount',
});

// Update total
await Session.createEvent(session.id, {
type: 'UPDATE_TOTAL',
amount_unit: 300,
});

// Get session details
const details = await Session.get(session.id);
console.log('Residual amount:', details.residual_amount_unit);
Expand Down Expand Up @@ -548,7 +541,7 @@ This project uses [Vitest](https://vitest.dev/) for testing. The test suite incl
- **RSA Service tests** for cryptographic operations
- **Mock-based tests** for API interactions

Current test coverage: **79.45%**
Current test coverage: **94.82%** (Statements: 93.83%, Branches: 89.65%, Functions: 100%, Lines: 95.8%)

Run tests:
```bash
Expand Down Expand Up @@ -605,7 +598,7 @@ Benefits:
## Why Zero Dependencies?

- No third-party vulnerability risks
- Minimal bundle size (156KB)
- Minimal bundle size (268KB)
- Fast installation
- No dependency conflicts
- Uses only standard APIs
Expand Down
80 changes: 41 additions & 39 deletions examples/pos-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,46 +67,48 @@ async function main() {
console.log('Residual amount:', session.residual_amount_unit / 100, 'EUR')
console.log('Status:', session.status)

// Step 3: Add items to the session
console.log('\n3️⃣ Adding items to session...\n')

// Add coffee
await Session.createEvent(session.id, {
type: 'ADD_ITEM',
amount_unit: 300, // 3.00 EUR
description: 'Espresso',
metadata: { sku: 'COFFEE-001', category: 'beverages' },
})
console.log('✅ Added: Espresso (3.00 EUR)')

// Add croissant
await Session.createEvent(session.id, {
type: 'ADD_ITEM',
amount_unit: 250, // 2.50 EUR
description: 'Croissant',
metadata: { sku: 'PASTRY-042', category: 'food' },
})
console.log('✅ Added: Croissant (2.50 EUR)')

// Add water
await Session.createEvent(session.id, {
type: 'ADD_ITEM',
amount_unit: 150, // 1.50 EUR
description: 'Water',
metadata: { sku: 'DRINK-010', category: 'beverages' },
})
console.log('✅ Added: Water (1.50 EUR)')

// Apply discount
console.log('\n4️⃣ Applying discount...\n')
await Session.createEvent(session.id, {
type: 'REMOVE_ITEM',
amount_unit: 100, // -1.00 EUR discount
description: 'Happy Hour Discount',
})
console.log('✅ Applied discount: -1.00 EUR')
// Step 3: Add items to the session
console.log('\n3️⃣ Adding items to session...\n')

// Check session status
// Add coffee
await Session.createEvent(session.id, {
operation: 'ADD',
amount_unit: 300, // 3.00 EUR
currency: 'EUR',
description: 'Espresso',
metadata: { sku: 'COFFEE-001', category: 'beverages' },
})
console.log('✅ Added: Espresso (3.00 EUR)')

// Add croissant
await Session.createEvent(session.id, {
operation: 'ADD',
amount_unit: 250, // 2.50 EUR
currency: 'EUR',
description: 'Croissant',
metadata: { sku: 'PASTRY-042', category: 'food' },
})
console.log('✅ Added: Croissant (2.50 EUR)')

// Add water
await Session.createEvent(session.id, {
operation: 'ADD',
amount_unit: 150, // 1.50 EUR
currency: 'EUR',
description: 'Water',
metadata: { sku: 'DRINK-010', category: 'beverages' },
})
console.log('✅ Added: Water (1.50 EUR)')

// Apply discount
console.log('\n4️⃣ Applying discount...\n')
await Session.createEvent(session.id, {
operation: 'REMOVE',
amount_unit: 100, // -1.00 EUR discount
currency: 'EUR',
description: 'Happy Hour Discount',
})
console.log('✅ Applied discount: -1.00 EUR') // Check session status
console.log('\n5️⃣ Checking session status...\n')
const sessionDetails = await Session.get(session.id)
console.log('Total amount:', sessionDetails.amount_unit / 100, 'EUR')
Expand Down
9 changes: 6 additions & 3 deletions src/Session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ import type {
*
* // Add items to the session
* await Session.createEvent(session.id, {
* type: 'ADD_ITEM',
* operation: 'ADD',
* amount_unit: 500,
* currency: 'EUR',
* description: 'Product A'
* });
*
Expand Down Expand Up @@ -140,16 +141,18 @@ export class Session {
* ```typescript
* // Add an item to the session
* await Session.createEvent('session-123', {
* type: 'ADD_ITEM',
* operation: 'ADD',
* amount_unit: 1000,
* currency: 'EUR',
* description: 'Coffee',
* metadata: { sku: 'COFFEE-001' }
* });
*
* // Remove an item
* await Session.createEvent('session-123', {
* type: 'REMOVE_ITEM',
* operation: 'REMOVE',
* amount_unit: 500,
* currency: 'EUR',
* description: 'Discount applied'
* });
* ```
Expand Down
9 changes: 5 additions & 4 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ export type ReportStatus = 'PENDING' | 'READY' | 'FAILED'
export type SessionStatus = 'OPEN' | 'CLOSE'

/**
* Session event type
* Session event operation
*/
export type SessionEventType = 'ADD_ITEM' | 'REMOVE_ITEM' | 'UPDATE_TOTAL'
export type SessionEventOperation = 'ADD' | 'REMOVE'

/**
* Payment action
Expand Down Expand Up @@ -315,8 +315,9 @@ export type SessionUpdateBody = {
* Session event creation body
*/
export type SessionEventCreateBody = {
type: SessionEventType
amount_unit?: number
operation: SessionEventOperation
amount_unit: number
currency: string
description?: string
metadata?: Record<string, unknown>
}
Loading