Skip to main content
This guide will walk you through setting up Flex as a Stripe custom payment method in your application.

Prerequisites

Before you begin, ensure you have:
  • A Stripe account with access to the Dashboard
  • A Flex account with API credentials
  • Node.js 18.17.1 or higher (for JavaScript/TypeScript implementations)
  • An existing web application or checkout flow

Step 1: Create Custom Payment Method in Stripe

1

Navigate to the Stripe Dashboard

Log in to your Stripe Dashboard and navigate to Settings → Payments → Custom Payment Methods.
2

Create a new custom payment method

Click Add custom payment method and configure:
  • Display Name: Enter “Flex”
  • Logo: Upload the Flex logo
    • Ensure the logo is visible against light and dark backgrounds
    • Recommended size: At least 32x32 pixels
    • Include rounded corners if using a filled background
    • For transparent backgrounds, consider the background color for visibility
3

Save and copy the Custom Payment Method ID

After creating the custom payment method, Stripe will generate a unique ID starting with cpmt_. Copy this ID - you’ll need it for your integration.Example ID format: cpmt_1RFYhqIVh7O1TOu8IP4pAWbm
The custom payment method ID is different from your Stripe API keys. Store it as a constant in your application code.

Step 2: Install Required Dependencies

For JavaScript/TypeScript Projects

Install the Stripe client libraries:
npm install @stripe/stripe-js @stripe/react-stripe-js stripe
Or using yarn:
yarn add @stripe/stripe-js @stripe/react-stripe-js stripe
Or using pnpm:
pnpm add @stripe/stripe-js @stripe/react-stripe-js stripe

Additional Dependencies (Optional)

For form validation and schema management:
npm install react-hook-form zod @hookform/resolvers
For UUID generation (used in order tracking):
npm install uuid

Step 3: Configure Environment Variables

Create or update your environment configuration file (.env.local for Next.js or .env for other frameworks):
.env.local
# Stripe Configuration
STRIPE_SECRET_KEY=sk_test_... # Your Stripe secret key (server-side only)
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_... # Your Stripe publishable key

# Flex Configuration
FLEX_SECRET_KEY=your_flex_secret_key # Your Flex API secret key (server-side only)

# Application Configuration
NEXT_PUBLIC_BASE_URL=http://localhost:3000 # Your application base URL
Security Best Practice: Never expose secret keys to the client side. Only keys prefixed with NEXT_PUBLIC_ (or your framework’s equivalent) should be accessible in the browser.

Step 4: Create Constants File

Create a file to store your custom payment method ID and other constants:
lib/constants.ts
export const CURRENCY = "usd";
export const FLEX_CUSTOM_PAYMENT_METHOD_ID = "cpmt_1RFYhqIVh7O1TOu8IP4pAWbm"; // Replace with your ID
Replace the FLEX_CUSTOM_PAYMENT_METHOD_ID with the ID you copied from the Stripe Dashboard in Step 1.

Step 5: Configure Product and Pricing Data

Example structure - This shows one way to organize product data. Your structure may differ based on your needs:
data.json
{
  "plans": [
    {
      "name": "monthly",
      "price": 2999,
      "plan_id": "plan_monthly_001",
      "flex_price_id": "fprice_01js70gpb0m40qd316gwp9e6g0"
    },
    {
      "name": "annual",
      "price": 29900,
      "plan_id": "plan_annual_001",
      "flex_price_id": "fprice_01js70j4gqjqbgre2r08xb7j1n"
    }
  ]
}
What you actually need: Data to create Flex checkout sessions. This requires Flex price IDs (from your Flex Dashboard) and product information. Structure this data however works best for your application - JSON file, database, CMS, etc. Flex supports both one-time and recurring payments.

Step 6: Set Up Stripe Server Instance

Create a server-side Stripe instance for backend operations:
lib/stripe.ts
import "server-only"; // Prevents accidental client-side imports
import Stripe from "stripe";

export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY as string, {
  appInfo: {
    name: "your-app-name",
  },
});
The "server-only" import ensures this module can never be accidentally imported in client-side code, protecting your secret keys.

Step 7: Set Up Stripe.js Client Instance

Create a client-side Stripe.js instance:
lib/get-stripejs.ts
import { loadStripe, Stripe } from "@stripe/stripe-js";

let stripePromise: Promise<Stripe | null>;

export default function getStripe(): Promise<Stripe | null> {
  if (!stripePromise) {
    stripePromise = loadStripe(
      process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY as string
    );
  }
  return stripePromise;
}
This singleton pattern ensures Stripe.js is only loaded once, improving performance.

Verification

After completing these steps, verify your setup:
  • Custom payment method created in Stripe Dashboard
  • Custom payment method ID saved in constants file
  • Dependencies installed
  • Environment variables configured
  • Stripe server and client instances created
  • Product/pricing data configured

Next Steps

With your environment configured, you’re ready to implement the payment flow. Continue to the Custom Payment Methods guide for detailed implementation instructions.

Troubleshooting

Custom payment method not showing in Payment Element

  • Verify the custom payment method ID is correct
  • Ensure the ID is properly passed to the Elements configuration
  • Check that the custom payment method is enabled in your Stripe Dashboard

Environment variables not loading

  • Restart your development server after adding environment variables
  • Verify the variable names match exactly (including prefixes)
  • For Next.js, ensure .env.local is in your project root

Stripe.js not loading

  • Check your browser console for errors
  • Verify your publishable key is correct
  • Ensure you’re using the correct environment key (test vs. production)