Helpers
Helper Utilities
Exported utility functions for working with Stripe event and object data inside webhook handlers or anywhere in your application.
Import
import {
formatAmount,
getPlanName,
isActiveSubscription,
isInTrial,
getDaysUntilTrialEnd,
isRenewal,
calculateMRR,
getSubscriptionStatusText,
getEventDescription,
getCustomerEmail,
isTestEvent,
getMetadata,
getPaymentMethodType,
getInvoiceLineItems,
isSubscriptionInvoice,
getNextBillingDate,
formatDate,
} from "@xenterprises/fastify-xstripe";
Formatting
formatAmount(cents, currency?)
Converts a Stripe amount (in cents) to a formatted currency string.
formatAmount(cents: number, currency?: string): string
| Param | Type | Default | Description |
|---|---|---|---|
cents | number | — | Amount in cents (e.g. 2000). |
currency | string | "USD" | ISO 4217 currency code. |
formatAmount(2000) // "$20.00"
formatAmount(150050, "EUR") // "€1,500.50"
formatDate(unixTimestamp, locale?)
Converts a Stripe Unix timestamp to a human-readable date string.
formatDate(unixTimestamp: number, locale?: string): string | null
formatDate(1735689600) // "January 1, 2025"
formatDate(1735689600, "fr-FR") // "1 janvier 2025"
formatDate(null) // null
Subscription Helpers
isActiveSubscription(subscription)
Returns true if the subscription status is "active" or "trialing".
isActiveSubscription(sub) // boolean
isInTrial(subscription)
Returns true if the subscription is "trialing" and the trial has not yet ended.
isInTrial(sub) // boolean
getDaysUntilTrialEnd(subscription)
Returns the number of days remaining in the trial, or null if no trial end date.
getDaysUntilTrialEnd(sub) // number | null
getPlanName(subscription)
Returns the plan name from price.nickname, price.product.name, or price.id (in that order).
getPlanName(sub) // string
getSubscriptionStatusText(status)
Returns a human-readable label for a Stripe subscription status string.
| Input | Output |
|---|---|
"active" | "Active" |
"trialing" | "Trial" |
"past_due" | "Past Due" |
"canceled" | "Canceled" |
"paused" | "Paused" |
getSubscriptionStatusText("past_due") // "Past Due"
calculateMRR(subscription)
Calculates monthly recurring revenue in cents, normalizing yearly/weekly/daily intervals to monthly.
calculateMRR(sub) // number (cents)
getNextBillingDate(subscription)
Returns a Date for the next billing date (current_period_end), or null if unavailable.
getNextBillingDate(sub) // Date | null
Invoice Helpers
isRenewal(event)
Returns true if the invoice.paid event is a subscription renewal (not a first charge).
isRenewal(event) // boolean
isSubscriptionInvoice(invoice)
Returns true if the invoice is associated with a subscription.
isSubscriptionInvoice(invoice) // boolean
getInvoiceLineItems(invoice)
Extracts line items from an invoice as a simplified array.
getInvoiceLineItems(invoice): Array<{
description: string,
amount: number,
quantity: number,
priceId: string
}>
Event & Customer Helpers
getCustomerEmail(event, stripe)
Resolves the customer email from the event object or by fetching the customer if needed.
getCustomerEmail(event: Stripe.Event, stripe: Stripe): Promise<string | null>
getEventDescription(event)
Returns a short human-readable description for common event types.
getEventDescription({ type: "invoice.paid" }) // "Payment received"
getEventDescription({ type: "checkout.session.completed" }) // "Checkout completed"
getMetadata(event)
Returns the metadata object from the event's data object, or {} if none.
getMetadata(event) // object
isTestEvent(event)
Returns true if the event was fired from Stripe test mode (livemode === false).
isTestEvent(event) // boolean
getPaymentMethodType(paymentMethod)
Returns a human-readable payment method type.
| Input | Output |
|---|---|
{ type: "card" } | "Card" |
{ type: "us_bank_account" } | "US Bank Account" |
{ type: "sepa_debit" } | "SEPA Direct Debit" |
Examples
// Full handler using multiple helpers
"invoice.paid": async (event, fastify, stripe) => {
const invoice = event.data.object;
if (isTestEvent(event)) {
fastify.log.debug("Test invoice — skipping fulfillment");
return;
}
const email = await getCustomerEmail(event, stripe);
const lineItems = getInvoiceLineItems(invoice);
const amount = formatAmount(invoice.amount_paid, invoice.currency);
const renewal = isRenewal(event);
await sendEmail(email, renewal ? "Payment received" : "Welcome!", {
amount,
lineItems,
});
},
// Compute MRR across all active subscriptions
async function computeTotalMRR(fastify) {
const subscriptions = await fastify.stripe.subscriptions.list({ status: "active" });
return subscriptions.data.reduce((sum, sub) => sum + calculateMRR(sub), 0);
}
See Also
- Webhook Route — How to use handlers with the webhook route.
AI Context
package: "@xenterprises/fastify-xstripe"
import: from "@xenterprises/fastify-xstripe/helpers" or { helpers } from "@xenterprises/fastify-xstripe"
use-when: Utility functions for working with Stripe objects — formatting, subscription state, invoice parsing
key-helpers: formatAmount, getPlanName, isActiveSubscription, isInTrial, getDaysUntilTrialEnd, calculateMRR, getSubscriptionStatusText, getEventDescription, getCustomerEmail, isTestEvent, getNextBillingDate, formatDate
fastify-xstripe
Fastify plugin for Stripe webhook handling with signature verification, 23 default subscription event handlers, and the Stripe SDK client decorated on the instance.
fastify.stripe
The Stripe SDK client decorated on the Fastify instance — make any Stripe API call from handlers, plugins, or lifecycle hooks.
