Nextbase Docs
Payments

Stripe Configuration

Stripe is implemented using an Abstract payment provider. It has the following shape.

import { DBTable } from "@/types";
import { Dictionary } from "lodash";

export interface PaginationOptions {
  limit?: number;
  startingAfter?: string;
  endingBefore?: string;
}

export interface PaginatedResponse<T> {
  data: T[];
  hasMore: boolean;
  totalCount?: number;
}

export type CustomerData = {
  id?: string;
  email: string;
  metadata?: { [key: string]: any };
};

export type SubscriptionData = DBTable<"billing_subscriptions"> & {
  billing_prices: DBTable<"billing_prices"> | null;
  billing_products: DBTable<"billing_products"> | null;
};

export type ProductData = DBTable<"billing_products"> & {
  billing_prices: DBTable<"billing_prices">[];
};

export type ProductAndPrice = {
  product: DBTable<"billing_products">;
  price: DBTable<"billing_prices">;
};

export type InvoiceData = DBTable<"billing_invoices"> & {
  billing_products: DBTable<"billing_products"> | null;
  billing_prices: DBTable<"billing_prices"> | null;
};

export type OneTimePaymentData = DBTable<"billing_one_time_payments"> & {
  billing_products: DBTable<"billing_products"> | null;
  billing_prices: DBTable<"billing_prices"> | null;
  billing_invoices: DBTable<"billing_invoices"> | null;
};

export interface CheckoutSessionData {
  id: string;
  url: string;
}

export interface CustomerPortalData {
  url: string;
}

export interface PaymentMethodData {
  id: string;
  customerId: string;
  type: "card" | "bank_account" | "other";
  last4: string;
  expiryMonth?: number;
  expiryYear?: number;
}

export type CheckoutSessionOptions = {
  freeTrialDays?: number;
};

export abstract class PaymentGateway {
  abstract getName(): string;

  /**
   * These are methods which perform operations on the database.
   */
  abstract db: {
    createCustomer(
      customerData: Partial<DBTable<"billing_customers">>,
      workspaceId: string,
    ): Promise<DBTable<"billing_customers">>;
    getCustomerByCustomerId(
      customerId: string,
    ): Promise<DBTable<"billing_customers">>;
    getCustomerByWorkspaceId(
      workspaceId: string,
    ): Promise<DBTable<"billing_customers"> | null>;
    hasCustomer(customerId: string): Promise<boolean>;
    updateCustomer(
      customerId: string,
      updateData: Partial<DBTable<"billing_customers">>,
    ): Promise<DBTable<"billing_customers">>;
    deleteCustomer(customerId: string): Promise<void>;
    listCustomers(
      options?: PaginationOptions,
    ): Promise<PaginatedResponse<DBTable<"billing_customers">>>;
    // Subscription methods
    getSubscriptionsByCustomerId(
      customerId: string,
    ): Promise<SubscriptionData[]>;
    getSubscriptionsByWorkspaceId(
      workspaceId: string,
    ): Promise<SubscriptionData[]>;
    getSubscription(subscriptionId: string): Promise<SubscriptionData>;
    listSubscriptions(
      customerId: string,
      options?: PaginationOptions,
    ): Promise<PaginatedResponse<SubscriptionData>>;
    // Invoice methods
    getInvoice(invoiceId: string): Promise<InvoiceData>;
    listInvoicesByCustomerId(
      customerId: string,
      options?: PaginationOptions,
    ): Promise<PaginatedResponse<InvoiceData>>;
    listInvoicesByWorkspaceId(
      workspaceId: string,
      options?: PaginationOptions,
    ): Promise<PaginatedResponse<InvoiceData>>;
    // Product methods
    getProduct(productId: string): Promise<ProductData>;
    listProducts(options?: PaginationOptions): Promise<Array<ProductData>>;
  };

  abstract util: {
    createCustomerForWorkspace(
      workspaceId: string,
    ): Promise<DBTable<"billing_customers">>;
    getCustomerByWorkspaceId(
      workspaceId: string,
    ): Promise<DBTable<"billing_customers"> | null>;
    supportsFeature(featureName: string): boolean;
    isTestMode(): boolean;
  };

  /**
   * These are methods which perform operations on the payment gateway.
   */
  abstract gateway: {
    createGatewayCustomer(
      userData: Partial<CustomerData>,
    ): Promise<CustomerData>;
    // Webhook methods
    handleGatewayWebhook(body: any, signature: string): Promise<void>;
  };
  abstract anonScope: {
    listAllProducts(): Promise<ProductAndPrice[]>;
    /**
     * List all subscription products that are visible to the user.
     */
    listAllSubscriptionProducts(): Promise<Dictionary<ProductAndPrice[]>>;
    /**
     * List all one-time products that are visible to the user.
     */
    listAllOneTimeProducts(): Promise<ProductAndPrice[]>;
  };
  abstract userScope: {
    getWorkspaceDatabaseSubscriptions(
      workspaceId: string,
    ): Promise<DBTable<"billing_subscriptions">[]>;
    getWorkspaceDatabaseOneTimePurchases(
      workspaceId: string,
    ): Promise<OneTimePaymentData[]>;
    getWorkspaceDatabaseInvoices(
      workspaceId: string,
    ): Promise<PaginatedResponse<InvoiceData>>;
    getWorkspaceDatabasePaymentMethods(
      workspaceId: string,
    ): Promise<DBTable<"billing_payment_methods">[]>;
    getWorkspaceDatabaseCustomer(
      workspaceId: string,
    ): Promise<DBTable<"billing_customers">>;
    // Checkout methods
    createGatewayCheckoutSession({
      productId,
      priceId,
      options,
      workspaceId,
    }: {
      workspaceId: string;
      productId: string;
      priceId: string;
      options?: CheckoutSessionOptions;
    }): Promise<CheckoutSessionData>;
    // Customer portal methods
    createGatewayCustomerPortalSession(
      workspaceId: string,
      returnUrl: string,
    ): Promise<CustomerPortalData>;
  };
  abstract superAdminScope: {
    syncProducts(): Promise<void>;
    syncCustomers(): Promise<void>;
    toggleProductVisibility(
      productId: string,
      isVisible: boolean,
    ): Promise<void>;
    listAllProducts(): Promise<ProductData[]>;
    getCurrentMRR(): Promise<number>;
    getSubscriptionsByMonthBetween(
      startDate: Date,
      endDate: Date,
    ): Promise<{ month: Date; subscriptions: number }[]>;
    getCurrentRevenueByProduct(): Promise<
      { productId: string; revenue: number }[]
    >;
    getCurrentMonthRevenue(): Promise<number>;
    getLastMonthRevenue(): Promise<number>;
    listCurrentMonthInvoices(): Promise<InvoiceData[]>;
    listCurrentMonthSubscriptions(): Promise<SubscriptionData[]>;
    listCustomers(): Promise<DBTable<"billing_customers">[]>;
  };
}
Stripe Configuration | Nextbase v3 Starter Kits Documentation