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'>[]>;
  };
}

On this page

No Headings