All files / src/lib/integrations stripe.ts

76.38% Statements 55/72
92.3% Branches 12/13
100% Functions 4/4
76.38% Lines 55/72

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 731x 1x 1x 1x 1x 1x 1x 1x 8x 8x 7x 7x 2x 2x 5x 5x 5x 6x 6x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 38x 38x 38x 1x 1x 1x 1x 30x 30x 30x 1x 1x 1x 1x 18x 18x                                   18x 18x 13x 13x 5x 5x 5x  
import Stripe from "stripe";
 
/**
 * Stripe client - lazily initialized
 * This prevents errors during build when env vars aren't available
 */
let stripeClient: Stripe | null = null;
 
export function getStripeClient(): Stripe {
  if (!stripeClient) {
    const key = process.env.STRIPE_SECRET_KEY;
    if (!key) {
      throw new Error("STRIPE_SECRET_KEY is not configured");
    }
    stripeClient = new Stripe(key, {
      typescript: true});
  }
  return stripeClient;
}
 
/**
 * Stripe configuration
 */
export const STRIPE_CONFIG = {
  currency: "usd" as const,
  paymentMethods: ["card"] as const,
  successUrl: `${process.env.NEXTAUTH_URL || ""}/order-confirmation?session_id={CHECKOUT_SESSION_ID}`,
  cancelUrl: `${process.env.NEXTAUTH_URL || ""}/checkout?canceled=true`} as const;
 
/**
 * Convert amount to cents for Stripe
 */
export function toStripeCents(amount: number): number {
  return Math.round(amount * 100);
}
 
/**
 * Convert cents from Stripe to dollars
 */
export function fromStripeCents(cents: number): number {
  return cents / 100;
}
 
/**
 * Format Stripe error messages for display
 */
export function formatStripeError(error: unknown): string {
  if (error instanceof Stripe.errors.StripeError) {
    switch (error.type) {
      case "StripeCardError":
        return error.message || "Your card was declined";
      case "StripeRateLimitError":
        return "Too many requests. Please try again later.";
      case "StripeInvalidRequestError":
        return "Invalid payment request. Please try again.";
      case "StripeAPIError":
        return "Payment service temporarily unavailable.";
      case "StripeConnectionError":
        return "Could not connect to payment service. Please try again.";
      case "StripeAuthenticationError":
        return "Payment authentication failed.";
      default:
        return "Payment failed. Please try again.";
    }
  }
 
  if (error instanceof Error) {
    return error.message;
  }
 
  return "An unexpected error occurred";
}