Revenue Examples
Copy the example that matches your stack to start sending revenue events in minutes.
Stripe Checkout (Node.js + Express)
// server/stripe-webhook.ts
import express from 'express';
import Stripe from 'stripe';
import { Revenue } from '@pulsora/revenue';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
apiVersion: '2023-10-16',
});
const revenue = new Revenue({
apiToken: process.env.PULSORA_SECRET!,
debug: process.env.NODE_ENV !== 'production',
});
const app = express();
app.post(
'/webhooks/stripe',
express.raw({ type: 'application/json' }),
async (req, res) => {
const signature = req.headers['stripe-signature']!;
let event;
try {
event = stripe.webhooks.constructEvent(
req.body,
signature,
process.env.STRIPE_WEBHOOK_SECRET!,
);
} catch (err) {
console.error('Webhook signature verification failed', err);
return res.sendStatus(400);
}
if (event.type === 'checkout.session.completed') {
const session = event.data.object as Stripe.Checkout.Session;
await revenue.track({
visitor_fingerprint: session.metadata?.visitor_fingerprint ?? '',
session_id: session.metadata?.session_id ?? '',
customer_id: session.customer as string,
amount: session.amount_total! / 100,
currency: session.currency!.toUpperCase(),
transaction_id: session.id,
payment_processor: 'stripe',
event_type: 'subscription',
customer_subscription_id: session.subscription as string,
is_recurring: true,
metadata: {
plan: session.metadata?.plan,
},
});
}
res.json({ received: true });
},
);
Stripe Checkout (Laravel)
// app/Http/Controllers/StripeWebhookController.php
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Pulsora\Revenue\Revenue;
class StripeWebhookController extends Controller
{
public function __invoke(Request $request)
{
$payload = $request->all();
if ($payload['type'] !== 'checkout.session.completed') {
return response()->json(['ignored' => true]);
}
$session = $payload['data']['object'];
$revenue = new Revenue([
'apiToken' => config('services.pulsora.secret'),
]);
$revenue->track([
'visitor_fingerprint' => $session['metadata']['visitor_fingerprint'] ?? null,
'session_id' => $session['metadata']['session_id'] ?? null,
'customer_id' => $session['customer'],
'amount' => $session['amount_total'] / 100,
'currency' => strtoupper($session['currency']),
'transaction_id' => $session['id'],
'payment_processor' => 'stripe',
'event_type' => 'purchase',
]);
return response()->json(['success' => true]);
}
}
Paddle Billing
app.post('/webhooks/paddle', express.json(), async (req, res) => {
const event = req.body;
if (event.event_type === 'transaction.completed') {
await revenue.track({
visitor_fingerprint: event.data.custom_data?.visitor_fingerprint,
session_id: event.data.custom_data?.session_id,
customer_id: event.data.customer_id,
amount: parseFloat(event.data.details.totals.total),
currency: event.data.currency_code,
transaction_id: event.data.id,
payment_processor: 'paddle',
event_type: event.data.status === 'refunded' ? 'refund' : 'purchase',
metadata: {
plan: event.data.items[0]?.price?.product?.name,
},
});
}
res.json({ success: true });
});
Manual Invoices
await revenue.track({
visitor_fingerprint: 'fp_manual_import',
session_id: 'sess_manual_import',
customer_id: 'cus_enterprise',
amount: 5000,
currency: 'USD',
transaction_id: 'invoice-2024-05',
payment_processor: 'manual',
event_type: 'purchase',
metadata: {
notes: 'Annual enterprise invoice – recorded manually',
},
});
Handling Errors Gracefully
try {
await revenue.track(payload);
} catch (error) {
// Log to your observability stack
logger.error('Pulsora revenue failed', { error });
// Optionally retry or queue for later
await queue.add('revenue-retry', payload, { delay: 5 * 60 * 1000 });
}
Need a refresher on payload fields? Jump back to the API reference →