Skip to main content
Customers are people who have completed orders through your moneydevkit checkout. The customers page helps you manage customer relationships, issue refunds, and track purchase history.

What are Customers?

Customers let you collect information on people who complete orders so you can:
  • Contact them later - Reach out for support, updates, or marketing
  • Issue refunds - Process refunds to their refund address
  • Track purchases - View their complete order history

Customers Dashboard

The customers page in your moneydevkit dashboard displays:
  • Customer list - All customers with name and email
  • Search - Find customers by name or email
  • Customer details - View individual customer information and order history

Customer Information

Each customer record includes:
  • Name - Customer’s name (if provided)
  • Email - Customer’s email address
  • Refund Address - Lightning address for processing refunds
  • Order Count - Number of completed orders
  • Checkout Count - Number of checkout sessions
  • Order History - List of recent orders with amounts and dates
  • Subscriptions - Active and past subscriptions

Collecting Customer Information

Customer information can be collected in two ways: by passing it programmatically when creating a checkout, or by requiring customers to fill out a form during checkout.

Option 1: Pass Customer Data Directly

If you already know the customer’s information (e.g., from your authentication system), pass it when creating the checkout:
const result = await createCheckout({
  type: 'AMOUNT',
  title: 'Product Name',
  amount: 500,
  currency: 'USD',
  successUrl: '/checkout/success',
  customer: {
    email: 'customer@example.com',
    name: 'Jane Doe',
    externalId: 'user-123' // Your system's user ID
  }
})

Option 2: Require Customer Data Entry

Use requireCustomerData to display a form that collects customer information before payment. This is useful when you don’t have the customer’s details upfront:
const result = await createCheckout({
  type: 'AMOUNT',
  title: 'Product Name',
  amount: 500,
  currency: 'USD',
  successUrl: '/checkout/success',
  requireCustomerData: ['email', 'name']
})
The checkout will display a form requiring the specified fields before the customer can proceed to payment.

Available Fields

FieldDescription
emailCustomer’s email address
nameCustomer’s full name
Custom fieldsAny additional field name (e.g., 'company', 'phone')
Field names are case-sensitive and must match exactly (e.g., taxId in requireCustomerData requires taxId in customer, not tax_id).

Combining Both Approaches

You can combine pre-filled data with required fields. The form will only show fields that aren’t already provided:
const result = await createCheckout({
  type: 'AMOUNT',
  title: 'Product Name',
  amount: 500,
  currency: 'USD',
  successUrl: '/checkout/success',
  customer: {
    externalId: 'user-123', // Known from your auth system
    name: 'Jane Doe'        // Already known
  },
  requireCustomerData: ['email', 'name', 'company']
  // Form will only ask for email and company since name is already provided
})
If you pass an externalId for an existing customer, moneydevkit will automatically backfill any fields they’ve previously provided. This means returning customers may not need to fill out the form at all.

Using externalId for Authenticated Users

When your user is already authenticated in your app, pass externalId to link checkouts to their account:
const result = await createCheckout({
  type: 'AMOUNT',
  title: "Premium Plan",
  description: 'Monthly subscription',
  amount: 1000,
  currency: 'USD',
  successUrl: '/checkout/success',
  customer: {
    externalId: user.id,  // Your app's user ID
    name: user.name,
    email: user.email,
  },
  requireCustomerData: ['name', 'email'],
})
When externalId is provided:
  • The system assumes the user is authenticated
  • If the customer already exists (matched by externalId), their stored name and email are used
  • Only fields missing from the customer record are requested
  • This prevents authenticated users from being asked for data you already have

Customer Matching

Customers are matched and deduplicated using:
  1. External ID - If you provide an externalId, existing customers with that ID are found and updated with new email/name/metadata from the checkout
  2. Email - If no external ID match, customers are matched by email and linked without updating (existing data is preserved)
This ensures you don’t create duplicate customer records when the same person makes multiple purchases.
Email is required to create a customer record. Without an email, customer data is attached to the checkout but no customer record is created.
When using externalId for authenticated users, be aware that checkout data will overwrite existing customer fields. If you want to preserve existing data, omit fields you don’t want to change.

Managing Customers

Editing Customers

Click the edit button to update customer information:
  • Name
  • Email
  • Refund address
  • Custom metadata

Refunds

To issue a refund:
  1. Find the customer in the customers list
  2. View their order history
  3. Use the refund address to send funds back
Refunds are processed manually by sending to the customer’s refund address. Ensure the refund address is valid before sending funds.

Customer Metadata

You can store additional information in customer metadata:
const result = await createCheckout({
  type: 'AMOUNT',
  title: 'Product Name',
  amount: 500,
  currency: 'USD',
  successUrl: '/checkout/success',
  customer: {
    email: 'customer@example.com',
    name: 'Jane Doe',
    // Custom fields are stored in userMetadata
    shippingAddress: '123 Main St',
    phoneNumber: '+1-555-0123'
  }
})
Custom fields beyond name, email, and externalId are stored in the customer’s metadata and visible in the dashboard.

Fetching Customer Data

Use the useCustomer hook to fetch customer data in your application, including subscription status:
import { useCustomer } from '@moneydevkit/nextjs'

function CustomerProfile() {
  const { customer, isLoading, error, refetch } = useCustomer({ externalId: user.id })

  if (isLoading) return <p>Loading...</p>
  if (error) return <p>Error: {error.message}</p>
  if (!customer) return <p>Customer not found</p>

  return (
    <div>
      <p>Email: {customer.email}</p>
      <p>Name: {customer.name}</p>
      <p>Has active subscription: {customer.hasActiveSubscription ? 'Yes' : 'No'}</p>
    </div>
  )
}

CustomerIdentifier Types

You can identify customers using any of these options:
IdentifierDescriptionExample
externalIdYour app’s user ID{ externalId: user.id }
emailCustomer’s email address{ email: 'user@example.com' }
customerIdmoneydevkit customer ID{ customerId: 'cus_abc123' }
Use externalId when you have authenticated users. This links moneydevkit customers to your user accounts and enables features like checking subscription status.
See the Subscriptions guide for more details on managing recurring payments.