Customer Management
Overview
The Customer Management controller provides read-only access to Stripe customer information for both platform and connected accounts. It retrieves full customer details including payment sources for billing and payment method management.
Source File: internal/api/v1/store/Controllers/customer.js (43 lines)
Key Capabilities
- Customer Retrieval: Get full Stripe customer object
- Source Expansion: Includes all payment sources in response
- Multi-Tenant Support: Platform and connected account handling
- Read-Only Operations: Focused on data retrieval (modifications via other controllers)
🗄️ MongoDB Collections
| Collection | Operations | Purpose |
|---|---|---|
stripe.keys | Query | Load connected account Stripe credentials |
_accounts | Read | Get stripe_customer from req.auth.account |
Note: Primary data source is Stripe API, not MongoDB.
🎯 Core Methods
getCustomerInfo() - Retrieve Customer Details
Purpose: Fetch complete Stripe customer object with expanded sources.
Business Logic
flowchart TD
A[Get Customer Request] --> B{stripe_customer Exists?}
B -->|No| C[Error: STRIPE_CUSTOMER_NOT_FOUND]
B -->|Yes| D{Main Account?}
D -->|Yes| E[Use Platform Stripe Key]
D -->|No| F[Load Parent Stripe Key]
F --> G{Parent Key Exists?}
G -->|No| H[Error: Parent Key Missing]
G -->|Yes| I[Retrieve Customer from Stripe]
E --> I
I --> J[Expand Sources]
J --> K[Return Customer Object]
Key Operations
1. Stripe Instance Creation
let stripe;
if (req.auth.account.main) {
stripe = Stripe(process.env.STRIPE_SECRET_KEY);
} else {
const stripe_keys = await StripeKey.findOne({
account_id: new mongoose.Types.ObjectId(
req.auth.account.parent_account?.id || req.auth.account.parent_account,
),
});
const key = stripe_keys?._doc?.token?.access_token;
if (!key) {
throw notFound('Parent account stripe key does not exist.');
}
stripe = Stripe(key);
}
2. Customer Retrieval with Expansion
if (!req.auth.account.stripe_customer) {
let error = new Error('STRIPE_CUSTOMER_NOT_FOUND');
return next(error);
}
stripeCustomer = await stripe.customers.retrieve(req.auth.account.stripe_customer, {
expand: ['sources'], // Include all payment sources
});
Response
{
"success": true,
"message": "SUCCESS",
"data": {
"id": "cus_ABC123",
"object": "customer",
"email": "customer@example.com",
"name": "John Doe",
"default_source": "card_XYZ789",
"sources": {
"object": "list",
"data": [
{
"id": "card_XYZ789",
"object": "card",
"brand": "Visa",
"last4": "4242",
"exp_month": 12,
"exp_year": 2025
}
]
},
"subscriptions": {...},
"invoice_settings": {
"default_payment_method": "pm_ABC123"
}
}
}
Important Notes
- Sources Expanded: Response includes full payment source objects, not just IDs
- Read-Only: This controller only retrieves data; use PaymentMethods controller for modifications
- Multi-Tenant: Automatically determines correct Stripe account (platform vs connected)
- No Caching: Always fetches fresh data from Stripe API
- Complete Customer Data: Includes subscriptions, invoice settings, and metadata
🔐 Configuration
Environment Variables
| Variable | Description | Required |
|---|---|---|
STRIPE_SECRET_KEY | Platform Stripe secret key | ✅ |
Authentication Requirements
- Authenticated Account: Requires valid JWT token
- Stripe Customer: Account must have
stripe_customerfield populated
⚠️ Important Notes
Critical Business Rules
- Stripe Customer Required: Account must have
stripe_customerpopulated - Connected Account Keys: Sub-accounts use parent's Stripe access token
- Source Expansion: All payment sources included automatically
- Read-Only Controller: Modifications handled by PaymentMethods controller
- No Caching: Always returns real-time data from Stripe
Error Messages
| Error | Cause | Resolution |
|---|---|---|
STRIPE_CUSTOMER_NOT_FOUND | Account has no stripe_customer | Create Stripe customer first via checkout |
Parent account stripe key does not exist | Missing StripeKey for parent | Configure parent Stripe Connect |
Use Cases
1. Payment Method Display
- Show customer's saved cards
- Display default payment method
- List all available payment sources
2. Billing Information
- Get customer email and name
- View invoice preferences
- Check default payment settings
3. Account Status
- Verify customer exists in Stripe
- Check delinquent status
- View balance and currency
Integration Points
Related Controllers:
- PaymentMethods: Modify payment sources (add, update, delete)
- Subscriptions: Use customer for subscription creation
- Invoice: Retrieve customer invoices
- Charge: Process charges for customer
Typical Flow:
// 1. Get customer info to display billing page
const customer = await getCustomerInfo();
// 2. Show payment methods from sources
customer.sources.data.forEach(source => {
renderPaymentMethod(source);
});
// 3. Highlight default payment method
if (customer.default_source) {
highlightDefault(customer.default_source);
}
🔗 Related Documentation
- Payment Methods - Add, update, delete payment methods
- Payment Intent - Process payments
- Subscriptions - Manage customer subscriptions
- Invoice - Customer invoice management
Last Updated: October 8, 2025
Status: Production-Ready ✅