Initial Node.js SDK v1.0.0

This commit is contained in:
garfieldheron
2026-02-19 12:07:39 -05:00
commit 6c252b7495
24 changed files with 1837 additions and 0 deletions

31
dist/api/ledger.d.ts vendored Normal file
View File

@@ -0,0 +1,31 @@
import { AxiosInstance } from 'axios';
import { LedgerAccount, LedgerEntry, ListResponse, PaginationParams } from '../types';
/**
* Ledger API client
*/
export declare class LedgerClient {
private http;
constructor(http: AxiosInstance);
/**
* List all ledger accounts
*/
listAccounts(params?: PaginationParams & {
type?: string;
}): Promise<ListResponse<LedgerAccount>>;
/**
* Retrieve a ledger account by ID
*/
retrieveAccount(accountId: string): Promise<LedgerAccount>;
/**
* List all ledger entries
*/
listEntries(params?: PaginationParams & {
account_id?: string;
payment_id?: string;
entry_type?: string;
}): Promise<ListResponse<LedgerEntry>>;
/**
* Retrieve a ledger entry by ID
*/
retrieveEntry(entryId: string): Promise<LedgerEntry>;
}

27
dist/api/payment-methods.d.ts vendored Normal file
View File

@@ -0,0 +1,27 @@
import { AxiosInstance } from 'axios';
import { PaymentMethod, CreatePaymentMethodRequest, ListResponse, PaginationParams } from '../types';
/**
* Payment Methods API client
*/
export declare class PaymentMethodsClient {
private http;
constructor(http: AxiosInstance);
/**
* Create a new payment method
*/
create(params: CreatePaymentMethodRequest, idempotencyKey?: string): Promise<PaymentMethod>;
/**
* Retrieve a payment method by ID
*/
retrieve(paymentMethodId: string): Promise<PaymentMethod>;
/**
* List all payment methods
*/
list(params?: PaginationParams & {
type?: string;
}): Promise<ListResponse<PaymentMethod>>;
/**
* Delete a payment method
*/
delete(paymentMethodId: string): Promise<void>;
}

35
dist/api/payments.d.ts vendored Normal file
View File

@@ -0,0 +1,35 @@
import { AxiosInstance } from 'axios';
import { Payment, CreatePaymentRequest, ListResponse, PaginationParams, FilterParams } from '../types';
/**
* Payments API client
*/
export declare class PaymentsClient {
private http;
constructor(http: AxiosInstance);
/**
* Create a new payment
*/
create(params: CreatePaymentRequest, idempotencyKey?: string): Promise<Payment>;
/**
* Retrieve a payment by ID
*/
retrieve(paymentId: string): Promise<Payment>;
/**
* List all payments
*/
list(params?: PaginationParams & FilterParams & {
status?: string;
rail?: string;
}): Promise<ListResponse<Payment>>;
/**
* Cancel a pending payment
*/
cancel(paymentId: string, reason?: string, idempotencyKey?: string): Promise<Payment>;
/**
* Refund a settled payment
*/
refund(paymentId: string, params?: {
amount?: number;
reason?: string;
}, idempotencyKey?: string): Promise<Payment>;
}

29
dist/api/webhooks.d.ts vendored Normal file
View File

@@ -0,0 +1,29 @@
import { AxiosInstance } from 'axios';
import { WebhookEndpoint, CreateWebhookRequest, ListResponse, PaginationParams } from '../types';
/**
* Webhooks API client
*/
export declare class WebhooksClient {
private http;
constructor(http: AxiosInstance);
/**
* Create a new webhook endpoint
*/
create(params: CreateWebhookRequest, idempotencyKey?: string): Promise<WebhookEndpoint>;
/**
* Retrieve a webhook endpoint by ID
*/
retrieve(webhookId: string): Promise<WebhookEndpoint>;
/**
* List all webhook endpoints
*/
list(params?: PaginationParams): Promise<ListResponse<WebhookEndpoint>>;
/**
* Update a webhook endpoint
*/
update(webhookId: string, params: Partial<CreateWebhookRequest>): Promise<WebhookEndpoint>;
/**
* Delete a webhook endpoint
*/
delete(webhookId: string): Promise<void>;
}

21
dist/client.d.ts vendored Normal file
View File

@@ -0,0 +1,21 @@
import { FetcherPayConfig } from './types';
import { PaymentsClient } from './api/payments';
import { LedgerClient } from './api/ledger';
import { PaymentMethodsClient } from './api/payment-methods';
import { WebhooksClient } from './api/webhooks';
/**
* Main FetcherPay client
*/
export declare class FetcherPay {
private http;
payments: PaymentsClient;
ledger: LedgerClient;
paymentMethods: PaymentMethodsClient;
webhooks: WebhooksClient;
constructor(config: FetcherPayConfig);
/**
* Verify webhook signature
*/
verifyWebhookSignature(payload: string, signature: string, secret: string): boolean;
}
export default FetcherPay;

27
dist/index.d.ts vendored Normal file
View File

@@ -0,0 +1,27 @@
/**
* FetcherPay Node.js SDK
* One API. Every Rail.
*
* @example
* ```typescript
* import { FetcherPay } from '@fetcherpay/node';
*
* const client = new FetcherPay({
* apiKey: 'fp_test_your_key',
* environment: 'sandbox'
* });
*
* const payment = await client.payments.create({
* amount: 10000,
* currency: 'USD',
* source: { payment_method_id: 'pm_123' },
* destination: { payment_method_id: 'pm_456' }
* });
* ```
*/
export { FetcherPay } from './client';
export { PaymentsClient } from './api/payments';
export { LedgerClient } from './api/ledger';
export { PaymentMethodsClient } from './api/payment-methods';
export { WebhooksClient } from './api/webhooks';
export * from './types';

271
dist/index.esm.js vendored Normal file
View File

@@ -0,0 +1,271 @@
import axios from 'axios';
/**
* FetcherPay SDK Types
*/
class FetcherPayError extends Error {
constructor(message, type, statusCode, param, code) {
super(message);
this.type = type;
this.statusCode = statusCode;
this.param = param;
this.code = code;
this.name = 'FetcherPayError';
}
}
class AuthenticationError extends FetcherPayError {
constructor(message) {
super(message, 'authentication_error', 401);
}
}
class ValidationError extends FetcherPayError {
constructor(message, param) {
super(message, 'validation_error', 422, param);
}
}
class NotFoundError extends FetcherPayError {
constructor(message) {
super(message, 'not_found', 404);
}
}
/**
* Payments API client
*/
class PaymentsClient {
constructor(http) {
this.http = http;
}
/**
* Create a new payment
*/
async create(params, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post('/payments', params, { headers });
return response.data;
}
/**
* Retrieve a payment by ID
*/
async retrieve(paymentId) {
const response = await this.http.get(`/payments/${paymentId}`);
return response.data;
}
/**
* List all payments
*/
async list(params) {
const response = await this.http.get('/payments', { params });
return response.data;
}
/**
* Cancel a pending payment
*/
async cancel(paymentId, reason, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post(`/payments/${paymentId}/cancel`, reason ? { reason } : {}, { headers });
return response.data;
}
/**
* Refund a settled payment
*/
async refund(paymentId, params, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post(`/payments/${paymentId}/refund`, params || {}, { headers });
return response.data;
}
}
/**
* Ledger API client
*/
class LedgerClient {
constructor(http) {
this.http = http;
}
/**
* List all ledger accounts
*/
async listAccounts(params) {
const response = await this.http.get('/ledger/accounts', { params });
return response.data;
}
/**
* Retrieve a ledger account by ID
*/
async retrieveAccount(accountId) {
const response = await this.http.get(`/ledger/accounts/${accountId}`);
return response.data;
}
/**
* List all ledger entries
*/
async listEntries(params) {
const response = await this.http.get('/ledger/entries', { params });
return response.data;
}
/**
* Retrieve a ledger entry by ID
*/
async retrieveEntry(entryId) {
const response = await this.http.get(`/ledger/entries/${entryId}`);
return response.data;
}
}
/**
* Payment Methods API client
*/
class PaymentMethodsClient {
constructor(http) {
this.http = http;
}
/**
* Create a new payment method
*/
async create(params, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post('/payment-methods', params, { headers });
return response.data;
}
/**
* Retrieve a payment method by ID
*/
async retrieve(paymentMethodId) {
const response = await this.http.get(`/payment-methods/${paymentMethodId}`);
return response.data;
}
/**
* List all payment methods
*/
async list(params) {
const response = await this.http.get('/payment-methods', { params });
return response.data;
}
/**
* Delete a payment method
*/
async delete(paymentMethodId) {
await this.http.delete(`/payment-methods/${paymentMethodId}`);
}
}
/**
* Webhooks API client
*/
class WebhooksClient {
constructor(http) {
this.http = http;
}
/**
* Create a new webhook endpoint
*/
async create(params, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post('/webhooks', params, { headers });
return response.data;
}
/**
* Retrieve a webhook endpoint by ID
*/
async retrieve(webhookId) {
const response = await this.http.get(`/webhooks/${webhookId}`);
return response.data;
}
/**
* List all webhook endpoints
*/
async list(params) {
const response = await this.http.get('/webhooks', { params });
return response.data;
}
/**
* Update a webhook endpoint
*/
async update(webhookId, params) {
const response = await this.http.put(`/webhooks/${webhookId}`, params);
return response.data;
}
/**
* Delete a webhook endpoint
*/
async delete(webhookId) {
await this.http.delete(`/webhooks/${webhookId}`);
}
}
/**
* Main FetcherPay client
*/
class FetcherPay {
constructor(config) {
const baseUrl = config.baseUrl || (config.environment === 'production'
? 'https://api.fetcherpay.com/v1'
: 'https://sandbox.fetcherpay.com/v1');
this.http = axios.create({
baseURL: baseUrl,
timeout: config.timeout || 30000,
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'Content-Type': 'application/json',
},
});
// Response interceptor for error handling
this.http.interceptors.response.use((response) => response, (error) => {
if (error.response) {
const { status, data } = error.response;
const errorData = data?.error || {};
switch (status) {
case 401:
throw new AuthenticationError(errorData.message || 'Authentication failed');
case 404:
throw new NotFoundError(errorData.message || 'Resource not found');
case 422:
throw new ValidationError(errorData.message || 'Validation failed', errorData.param);
default:
throw new FetcherPayError(errorData.message || 'An error occurred', errorData.type || 'api_error', status, errorData.param, errorData.code);
}
}
throw error;
});
// Initialize API clients
this.payments = new PaymentsClient(this.http);
this.ledger = new LedgerClient(this.http);
this.paymentMethods = new PaymentMethodsClient(this.http);
this.webhooks = new WebhooksClient(this.http);
}
/**
* Verify webhook signature
*/
verifyWebhookSignature(payload, signature, secret) {
const crypto = require('crypto');
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
try {
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
catch {
return false;
}
}
}
export { AuthenticationError, FetcherPay, FetcherPayError, LedgerClient, NotFoundError, PaymentMethodsClient, PaymentsClient, ValidationError, WebhooksClient };
//# sourceMappingURL=index.esm.js.map

1
dist/index.esm.js.map vendored Normal file

File diff suppressed because one or more lines are too long

281
dist/index.js vendored Normal file
View File

@@ -0,0 +1,281 @@
'use strict';
var axios = require('axios');
/**
* FetcherPay SDK Types
*/
class FetcherPayError extends Error {
constructor(message, type, statusCode, param, code) {
super(message);
this.type = type;
this.statusCode = statusCode;
this.param = param;
this.code = code;
this.name = 'FetcherPayError';
}
}
class AuthenticationError extends FetcherPayError {
constructor(message) {
super(message, 'authentication_error', 401);
}
}
class ValidationError extends FetcherPayError {
constructor(message, param) {
super(message, 'validation_error', 422, param);
}
}
class NotFoundError extends FetcherPayError {
constructor(message) {
super(message, 'not_found', 404);
}
}
/**
* Payments API client
*/
class PaymentsClient {
constructor(http) {
this.http = http;
}
/**
* Create a new payment
*/
async create(params, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post('/payments', params, { headers });
return response.data;
}
/**
* Retrieve a payment by ID
*/
async retrieve(paymentId) {
const response = await this.http.get(`/payments/${paymentId}`);
return response.data;
}
/**
* List all payments
*/
async list(params) {
const response = await this.http.get('/payments', { params });
return response.data;
}
/**
* Cancel a pending payment
*/
async cancel(paymentId, reason, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post(`/payments/${paymentId}/cancel`, reason ? { reason } : {}, { headers });
return response.data;
}
/**
* Refund a settled payment
*/
async refund(paymentId, params, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post(`/payments/${paymentId}/refund`, params || {}, { headers });
return response.data;
}
}
/**
* Ledger API client
*/
class LedgerClient {
constructor(http) {
this.http = http;
}
/**
* List all ledger accounts
*/
async listAccounts(params) {
const response = await this.http.get('/ledger/accounts', { params });
return response.data;
}
/**
* Retrieve a ledger account by ID
*/
async retrieveAccount(accountId) {
const response = await this.http.get(`/ledger/accounts/${accountId}`);
return response.data;
}
/**
* List all ledger entries
*/
async listEntries(params) {
const response = await this.http.get('/ledger/entries', { params });
return response.data;
}
/**
* Retrieve a ledger entry by ID
*/
async retrieveEntry(entryId) {
const response = await this.http.get(`/ledger/entries/${entryId}`);
return response.data;
}
}
/**
* Payment Methods API client
*/
class PaymentMethodsClient {
constructor(http) {
this.http = http;
}
/**
* Create a new payment method
*/
async create(params, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post('/payment-methods', params, { headers });
return response.data;
}
/**
* Retrieve a payment method by ID
*/
async retrieve(paymentMethodId) {
const response = await this.http.get(`/payment-methods/${paymentMethodId}`);
return response.data;
}
/**
* List all payment methods
*/
async list(params) {
const response = await this.http.get('/payment-methods', { params });
return response.data;
}
/**
* Delete a payment method
*/
async delete(paymentMethodId) {
await this.http.delete(`/payment-methods/${paymentMethodId}`);
}
}
/**
* Webhooks API client
*/
class WebhooksClient {
constructor(http) {
this.http = http;
}
/**
* Create a new webhook endpoint
*/
async create(params, idempotencyKey) {
const headers = {};
if (idempotencyKey) {
headers['Idempotency-Key'] = idempotencyKey;
}
const response = await this.http.post('/webhooks', params, { headers });
return response.data;
}
/**
* Retrieve a webhook endpoint by ID
*/
async retrieve(webhookId) {
const response = await this.http.get(`/webhooks/${webhookId}`);
return response.data;
}
/**
* List all webhook endpoints
*/
async list(params) {
const response = await this.http.get('/webhooks', { params });
return response.data;
}
/**
* Update a webhook endpoint
*/
async update(webhookId, params) {
const response = await this.http.put(`/webhooks/${webhookId}`, params);
return response.data;
}
/**
* Delete a webhook endpoint
*/
async delete(webhookId) {
await this.http.delete(`/webhooks/${webhookId}`);
}
}
/**
* Main FetcherPay client
*/
class FetcherPay {
constructor(config) {
const baseUrl = config.baseUrl || (config.environment === 'production'
? 'https://api.fetcherpay.com/v1'
: 'https://sandbox.fetcherpay.com/v1');
this.http = axios.create({
baseURL: baseUrl,
timeout: config.timeout || 30000,
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'Content-Type': 'application/json',
},
});
// Response interceptor for error handling
this.http.interceptors.response.use((response) => response, (error) => {
if (error.response) {
const { status, data } = error.response;
const errorData = data?.error || {};
switch (status) {
case 401:
throw new AuthenticationError(errorData.message || 'Authentication failed');
case 404:
throw new NotFoundError(errorData.message || 'Resource not found');
case 422:
throw new ValidationError(errorData.message || 'Validation failed', errorData.param);
default:
throw new FetcherPayError(errorData.message || 'An error occurred', errorData.type || 'api_error', status, errorData.param, errorData.code);
}
}
throw error;
});
// Initialize API clients
this.payments = new PaymentsClient(this.http);
this.ledger = new LedgerClient(this.http);
this.paymentMethods = new PaymentMethodsClient(this.http);
this.webhooks = new WebhooksClient(this.http);
}
/**
* Verify webhook signature
*/
verifyWebhookSignature(payload, signature, secret) {
const crypto = require('crypto');
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
try {
return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}
catch {
return false;
}
}
}
exports.AuthenticationError = AuthenticationError;
exports.FetcherPay = FetcherPay;
exports.FetcherPayError = FetcherPayError;
exports.LedgerClient = LedgerClient;
exports.NotFoundError = NotFoundError;
exports.PaymentMethodsClient = PaymentMethodsClient;
exports.PaymentsClient = PaymentsClient;
exports.ValidationError = ValidationError;
exports.WebhooksClient = WebhooksClient;
//# sourceMappingURL=index.js.map

1
dist/index.js.map vendored Normal file

File diff suppressed because one or more lines are too long

192
dist/types/index.d.ts vendored Normal file
View File

@@ -0,0 +1,192 @@
/**
* FetcherPay SDK Types
*/
export interface FetcherPayConfig {
apiKey: string;
environment?: 'sandbox' | 'production';
baseUrl?: string;
timeout?: number;
}
export interface Payment {
id: string;
object: 'payment';
status: 'pending' | 'authorized' | 'processing' | 'settled' | 'failed' | 'cancelled' | 'refunded' | 'partially_refunded';
amount: number;
currency: string;
rail: string;
rail_selected: string;
description?: string;
source: PaymentSource;
destination: PaymentDestination;
fee?: Fee;
timeline: TimelineEvent[];
ledger_entry_ids: string[];
refunds: Refund[];
idempotency_key?: string;
metadata: Record<string, any>;
created_at: string;
updated_at: string;
}
export interface PaymentSource {
payment_method_id: string;
name?: string | null;
type?: string;
}
export interface PaymentDestination {
payment_method_id: string;
name?: string | null;
type?: string;
}
export interface Fee {
amount: number;
rate: string;
}
export interface TimelineEvent {
status: string;
timestamp: string;
detail: string;
}
export interface Refund {
id: string;
payment_id: string;
amount: number;
reason?: string | null;
status: string;
created_at: string;
}
export interface CreatePaymentRequest {
amount: number;
currency?: string;
rail?: 'auto' | 'ach' | 'rtp' | 'card' | 'crypto';
rail_fallback_order?: string[];
description?: string;
source: PaymentSource;
destination: PaymentDestination;
metadata?: Record<string, any>;
}
export interface PaymentMethod {
id: string;
object: 'payment_method';
type: 'bank_account' | 'card' | 'usdc_wallet';
status: 'active' | 'inactive' | 'verification_required';
bank_account?: BankAccount;
card?: Card;
usdc_wallet?: UsdcWallet;
metadata: Record<string, any>;
created_at: string;
}
export interface BankAccount {
account_type: 'checking' | 'savings';
bank_name?: string;
routing_number_last4: string;
account_number_last4: string;
}
export interface Card {
brand: string;
last4: string;
exp_month: number;
exp_year: number;
}
export interface UsdcWallet {
address: string;
network: 'ethereum' | 'polygon';
}
export interface CreatePaymentMethodRequest {
type: 'bank_account' | 'card' | 'usdc_wallet';
bank_account?: {
account_number: string;
routing_number: string;
account_type: 'checking' | 'savings';
};
card?: {
number: string;
exp_month: number;
exp_year: number;
cvc: string;
};
usdc_wallet?: {
address: string;
network: string;
};
metadata?: Record<string, any>;
}
export interface LedgerAccount {
id: string;
object: 'ledger_account';
name: string;
type: 'asset' | 'liability' | 'revenue' | 'expense' | 'equity';
currency: string;
balance: {
pending: number;
posted: number;
available: number;
};
metadata: Record<string, any>;
created_at: string;
updated_at: string;
}
export interface LedgerEntry {
id: string;
object: 'ledger_entry';
journal_id: string;
account_id: string;
payment_id?: string;
entry_type: 'debit' | 'credit';
amount: number;
currency: string;
status: 'pending' | 'posted';
description?: string;
metadata: Record<string, any>;
created_at: string;
}
export interface WebhookEndpoint {
id: string;
object: 'webhook_endpoint';
url: string;
events: string[];
status: 'active' | 'disabled';
secret: string;
metadata: Record<string, any>;
created_at: string;
}
export interface CreateWebhookRequest {
url: string;
events?: string[];
metadata?: Record<string, any>;
}
export interface WebhookEvent {
id: string;
object: 'event';
type: string;
created_at: string;
data: any;
}
export interface ListResponse<T> {
data: T[];
has_more: boolean;
next_cursor: string | null;
}
export interface PaginationParams {
cursor?: string;
limit?: number;
}
export interface FilterParams {
created_after?: string;
created_before?: string;
}
export declare class FetcherPayError extends Error {
type: string;
statusCode?: number | undefined;
param?: string | null | undefined;
code?: string | null | undefined;
constructor(message: string, type: string, statusCode?: number | undefined, param?: string | null | undefined, code?: string | null | undefined);
}
export declare class AuthenticationError extends FetcherPayError {
constructor(message: string);
}
export declare class ValidationError extends FetcherPayError {
constructor(message: string, param?: string);
}
export declare class NotFoundError extends FetcherPayError {
constructor(message: string);
}