Installation
@pulsora/revenue is a server-side package for tracking revenue events with full attribution to customer journeys.
⚠️ Important: This package is for server-side use only. Never use it in the browser as it requires your secret API token.
Prerequisites
- Node.js 14 or higher
- A Pulsora account with API access
- Access to your payment webhook endpoints
NPM Installation
1. Install the Package
npm install @pulsora/revenue
Or using Yarn:
yarn add @pulsora/revenue
Or using pnpm:
pnpm add @pulsora/revenue
2. Import and Initialize
// CommonJS
const { Revenue } = require('@pulsora/revenue');
// ES Modules
import { Revenue } from '@pulsora/revenue';
// Initialize with your secret API token
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN,
});
3. TypeScript Support
TypeScript definitions are included:
import { Revenue, RevenueConfig, RevenueData } from '@pulsora/revenue';
const config: RevenueConfig = {
apiToken: process.env.PULSORA_SECRET_TOKEN!,
debug: process.env.NODE_ENV === 'development',
};
const revenue = new Revenue(config);
Environment Setup
1. Environment Variables
Create a .env file in your project root:
# Production
PULSORA_SECRET_TOKEN=sec_your_secret_token_here
# Development
PULSORA_SECRET_TOKEN=sec_your_test_token_here
PULSORA_DEBUG=true
2. Load Environment Variables
// Using dotenv
require('dotenv').config();
// Or in ES modules
import dotenv from 'dotenv';
dotenv.config();
// Initialize with env vars
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN,
debug: process.env.PULSORA_DEBUG === 'true',
});
Configuration Options
interface RevenueConfig {
apiToken: string; // Required: Your secret API token
endpoint?: string; // Optional: Custom API endpoint
debug?: boolean; // Optional: Enable debug logging
maxRetries?: number; // Optional: Max retry attempts (default: 3)
retryBackoff?: number; // Optional: Initial retry delay in ms (default: 1000)
}
Basic Configuration
const revenue = new Revenue({
apiToken: 'sec_your_secret_token',
});
Advanced Configuration
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN,
endpoint: 'https://custom.pulsora.co/api/ingest',
debug: true,
maxRetries: 5,
retryBackoff: 2000,
});
Framework Integration
Express.js
const express = require('express');
const { Revenue } = require('@pulsora/revenue');
const app = express();
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN,
});
// Webhook endpoint
app.post('/webhooks/stripe', express.json(), async (req, res) => {
const event = req.body;
if (event.type === 'checkout.session.completed') {
await revenue.track({
visitor_fingerprint: event.data.object.metadata.visitor_fingerprint,
session_id: event.data.object.metadata.session_id,
customer_id: event.data.object.customer,
amount: event.data.object.amount_total / 100,
currency: event.data.object.currency,
transaction_id: event.data.object.id,
payment_processor: 'stripe',
event_type: 'purchase',
});
}
res.json({ received: true });
});
Next.js API Routes
// pages/api/webhooks/stripe.ts (Pages Router)
// app/api/webhooks/stripe/route.ts (App Router)
import { NextRequest, NextResponse } from 'next/server';
import { Revenue } from '@pulsora/revenue';
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN!,
});
export async function POST(request: NextRequest) {
const event = await request.json();
try {
await revenue.track({
// ... revenue data
});
return NextResponse.json({ success: true });
} catch (error) {
console.error('Revenue tracking error:', error);
return NextResponse.json(
{ error: 'Failed to track revenue' },
{ status: 500 },
);
}
}
Fastify
const fastify = require('fastify')();
const { Revenue } = require('@pulsora/revenue');
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN,
});
fastify.post('/webhooks/paddle', async (request, reply) => {
const event = request.body;
if (event.event_type === 'transaction.completed') {
await revenue.track({
visitor_fingerprint: event.custom_data.visitor_fingerprint,
session_id: event.custom_data.session_id,
customer_id: event.customer_id,
amount: parseFloat(event.amount),
currency: event.currency_code,
transaction_id: event.id,
payment_processor: 'paddle',
event_type: 'purchase',
});
}
return { success: true };
});
AWS Lambda
const { Revenue } = require('@pulsora/revenue');
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN,
});
exports.handler = async (event) => {
const body = JSON.parse(event.body);
try {
await revenue.track({
visitor_fingerprint: body.metadata.visitor_fingerprint,
session_id: body.metadata.session_id,
customer_id: body.customer_id,
amount: body.amount,
currency: body.currency,
transaction_id: body.transaction_id,
payment_processor: 'custom',
event_type: 'purchase',
});
return {
statusCode: 200,
body: JSON.stringify({ success: true }),
};
} catch (error) {
console.error('Revenue tracking error:', error);
return {
statusCode: 500,
body: JSON.stringify({ error: 'Failed to track revenue' }),
};
}
};
Vercel Edge Functions
import { Revenue } from '@pulsora/revenue';
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN!,
});
export const config = {
runtime: 'edge',
};
export default async function handler(request: Request) {
const event = await request.json();
await revenue.track({
// ... revenue data
});
return new Response(JSON.stringify({ success: true }), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
}
Security Best Practices
1. Never Expose Secret Tokens
// ❌ WRONG - Never hardcode secret tokens
const revenue = new Revenue({
apiToken: 'sec_abc123...',
});
// ✅ CORRECT - Use environment variables
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN,
});
2. Validate Webhook Signatures
Always verify webhook signatures from payment providers:
// Stripe example
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
app.post(
'/webhooks/stripe',
express.raw({ type: 'application/json' }),
async (req, res) => {
const sig = req.headers['stripe-signature'];
try {
// Verify webhook signature
const event = stripe.webhooks.constructEvent(
req.body,
sig,
process.env.STRIPE_WEBHOOK_SECRET,
);
// Now safe to process
if (event.type === 'checkout.session.completed') {
await revenue.track({
// ... revenue data
});
}
res.json({ received: true });
} catch (err) {
console.error('Webhook signature verification failed:', err);
res.status(400).send(`Webhook Error: ${err.message}`);
}
},
);
3. Use HTTPS Only
Ensure all webhook endpoints use HTTPS:
// Force HTTPS in production
if (process.env.NODE_ENV === 'production') {
app.use((req, res, next) => {
if (req.header('x-forwarded-proto') !== 'https') {
res.redirect(`https://${req.header('host')}${req.url}`);
} else {
next();
}
});
}
Verification
1. Test Installation
// test-revenue.js
const { Revenue } = require('@pulsora/revenue');
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN,
debug: true,
});
// Test tracking
async function test() {
try {
await revenue.track({
visitor_fingerprint: 'test_fp_123',
session_id: 'test_session_123',
customer_id: 'test_customer',
amount: 9.99,
currency: 'USD',
transaction_id: 'test_tx_' + Date.now(),
payment_processor: 'test',
event_type: 'purchase',
});
console.log('✅ Revenue tracking successful');
} catch (error) {
console.error('❌ Revenue tracking failed:', error);
}
}
test();
2. Debug Mode
Enable debug mode to see detailed logs:
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET_TOKEN,
debug: true,
});
// All API calls will be logged
// [Pulsora Revenue] Tracking revenue event...
// [Pulsora Revenue] Request: POST https://pulsora.co/api/ingest
// [Pulsora Revenue] Response: 200 OK
3. Check Dashboard
After successful tracking:
- Log in to your Pulsora dashboard
- Navigate to Revenue Analytics
- Verify test events appear
- Check attribution data
Troubleshooting
Common Issues
"Invalid API token"
- Ensure you're using a secret token (starts with
sec_) - Check for typos or extra spaces
- Verify token in Pulsora dashboard
"Module not found"
# Ensure package is installed
npm list @pulsora/revenue
# Reinstall if needed
npm install @pulsora/revenue
"Network error"
- Check your server has internet access
- Verify firewall allows outbound HTTPS
- Test endpoint connectivity:
curl -X POST https://pulsora.co/api/ingest \
-H "Authorization: Bearer your_token" \
-H "Content-Type: application/json" \
-d '{"test": true}'
Environment Checklist
- Secret API token in environment variables
- Token starts with
sec_ - Package installed correctly
- Server has internet access
- Webhook endpoint accessible
- Error handling implemented
Next Steps
Now that you have the revenue package installed:
- Basic Usage - Track your first revenue event
- Webhook Integration - Set up payment webhooks
- Attribution - Understand visitor attribution
- API Reference - Complete method documentation
Need Help?
- 📚 Check the API Reference
- 💬 Join our Discord Community
- 📧 Email support@pulsora.co