@pulseroute/sdk
v0.1.0
Published
PulseRoute SDK — intelligent payment routing with automatic failover
Maintainers
Readme
PulseRoute Node.js SDK
Intelligent payment routing with automatic failover. Route transactions to the healthiest processor in real time.
Install
npm install @pulseroute/sdkQuick Start (5 lines)
const PulseRoute = require('@pulseroute/sdk');
const client = PulseRoute.init({ apiKey: 'your-api-key' });
// Before payment: where should I route?
const decision = await client.getRoute({ country: 'US', currency: 'USD', amount: 99.99 });
// After payment: report what happened
client.reportOutcome({ ruleId: 'us_usd_card', processorId: decision.processorId, success: true, latencyMs: 120 });Integration with Stripe + Adyen
const PulseRoute = require('@pulseroute/sdk');
const Stripe = require('stripe');
const { Client: AdyenClient } = require('@adyen/api-library');
const pulse = PulseRoute.init({
apiKey: process.env.PULSEROUTE_API_KEY,
baseUrl: process.env.PULSEROUTE_URL || 'http://localhost:8080',
});
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY);
const adyen = new AdyenClient({ apiKey: process.env.ADYEN_API_KEY });
async function processPayment(order) {
// 1. Ask PulseRoute where to route
const decision = await pulse.getRoute({
country: order.country,
currency: order.currency,
paymentMethod: 'card',
amount: order.amount,
});
const start = Date.now();
let success = false;
let errorCode = null;
try {
// 2. Route to the recommended processor
if (decision.processorId === 'stripe') {
const intent = await stripe.paymentIntents.create({
amount: Math.round(order.amount * 100),
currency: order.currency.toLowerCase(),
payment_method: order.paymentMethodId,
confirm: true,
});
success = intent.status === 'succeeded';
} else if (decision.processorId === 'adyen') {
const result = await adyen.checkout.payments({
amount: { value: Math.round(order.amount * 100), currency: order.currency },
reference: order.id,
paymentMethod: order.adyenPaymentMethod,
merchantAccount: process.env.ADYEN_MERCHANT,
});
success = result.resultCode === 'Authorised';
if (!success) errorCode = result.resultCode;
}
} catch (err) {
errorCode = err.code || err.message;
}
// 3. Report the outcome (fire-and-forget, non-blocking)
pulse.reportOutcome({
ruleId: `${order.country.toLowerCase()}_${order.currency.toLowerCase()}_card`,
processorId: decision.processorId,
success,
latencyMs: Date.now() - start,
errorCode,
});
return { success, processor: decision.processorId };
}Programmatic Onboarding
Skip the dashboard wizard — set up routing rules from code:
const client = PulseRoute.init({ apiKey: 'your-api-key' });
const result = await client.onboard({
processors: [
{
processorId: 'stripe',
name: 'Stripe',
countries: ['US', 'GB', 'DE'],
currencies: ['USD', 'GBP', 'EUR'],
paymentMethods: ['card', 'wallet'],
priority: 1,
},
{
processorId: 'adyen',
name: 'Adyen',
countries: ['US', 'GB', 'DE', 'FR', 'NL'],
currencies: ['USD', 'GBP', 'EUR'],
paymentMethods: ['card'],
priority: 2,
},
],
primaryWeight: 0.9,
});
console.log(`Created ${result.rulesCreated} routing rules`);
// Created 9 routing rulesExpress Middleware
const express = require('express');
const PulseRoute = require('@pulseroute/sdk');
const app = express();
const pulse = PulseRoute.init({ apiKey: process.env.PULSEROUTE_API_KEY });
app.post('/pay', express.json(), async (req, res) => {
const { country, currency, amount, paymentMethodId } = req.body;
const decision = await pulse.getRoute({ country, currency, amount });
// ... process with decision.processorId ...
res.json({ processor: decision.processorId, fallback: decision.fallbackProcessorId });
});
// Graceful shutdown
process.on('SIGTERM', async () => {
await pulse.shutdown();
process.exit(0);
});API Reference
PulseRoute.init(options)
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| apiKey | string | required | API key |
| baseUrl | string | http://localhost:8080 | PulseRoute API URL |
| timeout | number | 3000 | Request timeout (ms) |
| flushInterval | number | 1000 | Outcome flush interval (ms) |
| maxBufferSize | number | 500 | Max buffered outcomes |
| enableCache | boolean | true | Cache decisions locally |
client.getRoute(transaction) → Promise<RoutingDecision>
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| country | string | yes | ISO country code |
| currency | string | yes | ISO currency code |
| paymentMethod | string | no | card, bank_transfer, wallet, bnpl |
| cardType | string | no | visa, mastercard, amex, etc. |
| amount | number | no | Transaction amount |
Returns: { processorId, weight, fallbackProcessorId, decisionSource, failureProbability }
client.reportOutcome(outcome) → void
Fire-and-forget. Buffers outcomes and flushes periodically.
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| ruleId | string | yes | Rule that matched |
| processorId | string | yes | Processor used |
| success | boolean | yes | Transaction succeeded? |
| latencyMs | number | yes | Response time (ms) |
| errorCode | string | no | Error code if failed |
client.onboard(config) → Promise<OnboardResult>
Bulk setup. See Programmatic Onboarding.
client.flush() → Promise<void>
Flush buffered outcomes immediately.
client.shutdown() → Promise<void>
Flush and stop background timers. Call before process exit.
