X Enterprises
fastify-xstripe

Helpers

Utility functions for parsing and working with Stripe event data — amounts, subscriptions, invoices, dates, and metadata.

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
ParamTypeDefaultDescription
centsnumberAmount in cents (e.g. 2000).
currencystring"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.

InputOutput
"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.

InputOutput
{ 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

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
Copyright © 2026