🌍 Public Module
📖 Overview
The Public module provides public-facing API endpoints that can be accessed without standard authentication. These endpoints are typically used for embedded widgets, public payment processing, and external integrations where full authentication is not feasible.
File Path: internal/api/v1/public/
Key Features
- No Auth Required: Endpoints accessible without JWT tokens
- Stripe Integration: Public Stripe key access for checkout widgets
- Payment Methods: Tokenized payment method creation
- Product Catalog: Public product listings for embedded stores
- Checkout Processing: Stripe checkout session creation
- Funnel Support: Multi-funnel Stripe account routing
� Directory Structure
public/
├── 📄 index.js - Module router
├── 📂 controllers/
│ └── billing.controller.js - Public billing endpoints
├── 📂 services/
│ └── billing.service.js - Stripe API integration logic
├── 📂 routes/
│ └── index.js - Route definitions
├── 📂 middlewares/
│ └── (auth middlewares) - Custom funnel authentication
├── 📂 validations/
│ └── (validation schemas)
└── 📂 tests/
└── (test files)
�🔧 Core Endpoints
Get Stripe Public Key
Endpoint: GET /api/v1/public/billing/public-key
Purpose: Retrieve Stripe publishable key for frontend payment forms.
Authentication: Custom stripe_funnel authentication (not JWT)
Response:
{
"success": true,
"data": {
"public_key": "pk_live_51J..."
}
}
Use Case: Embedded payment widgets need Stripe public key to initialize payment forms.
Get Products
Endpoint: GET /api/v1/public/billing/products
Purpose: Retrieve product catalog for public-facing stores/widgets.
Query Parameters:
status(String) - Product status filtersearch(String) - Search termlimit(Number) - Results per pagelast_product_id(String) - Pagination cursorfirst_product_id(String) - Pagination cursor (reverse)next_page(Boolean) - Pagination directiontype(String) - Product type filtercurrency(String) - Currency filter
Response:
{
"success": true,
"data": {
"products": [
{
"id": "prod_...",
"name": "Pro Plan",
"description": "...",
"prices": [...],
"metadata": {...}
}
],
"has_more": true
}
}
Get Payment Methods
Endpoint: GET /api/v1/public/billing/payment-methods
Purpose: List payment methods for a customer (by email).
Query Parameters:
email(String) - Customer emailstart_date(Date) - Filter from dateend_date(Date) - Filter to datelimit(Number) - Results limitfirst_payment_method_id(String) - Pagination cursorlast_payment_method_id(String) - Pagination cursor
Use Case: Show existing payment methods in embedded checkout.
Add Payment Method
Endpoint: POST /api/v1/public/billing/payment-method
Purpose: Create tokenized payment method for checkout.
Request Body:
{
"email": "customer@example.com",
"payment_method": "pm_1J...",
"billing_details": {
"name": "John Doe",
"address": {...}
}
}
Response:
{
"success": true,
"data": {
"payment_method_id": "pm_1J...",
"customer_id": "cus_..."
}
}
Create Checkout
Endpoint: POST /api/v1/public/billing/checkout
Purpose: Create Stripe checkout session for payment processing.
Query Parameters:
preview(Boolean) - Preview mode (calculate totals without creating session)
Request Body:
{
"customer_email": "customer@example.com",
"line_items": [
{
"price": "price_1J...",
"quantity": 1
}
],
"success_url": "https://...",
"cancel_url": "https://...",
"mode": "subscription"
}
Response:
{
"success": true,
"data": {
"session_id": "cs_test_...",
"url": "https://checkout.stripe.com/pay/cs_test_..."
}
}
🔀 Integration Points
Stripe Funnel System
Multi-Account Support: DashClicks uses multiple Stripe accounts ("funnels") for different business units or clients.
Funnel Authentication:
- Custom middleware identifies which Stripe account to use
stripe_funnelandstripe_configinjected intoreq.auth- Each funnel has its own:
- Stripe API keys
- Product catalog
- Customer base
- Webhooks
Example Middleware:
// Custom authentication for public endpoints
const identifyStripeFunnel = async (req, res, next) => {
const funnelId = req.header('X-Stripe-Funnel') || 'default';
const stripeConfig = await StripeConfig.findOne({ funnel_id: funnelId });
req.auth = {
stripe_funnel: funnelId,
stripe_config: stripeConfig,
};
next();
};
Embedded Widgets
Use Case: White-label checkout forms embedded on partner websites.
Flow:
- Partner site loads DashClicks widget script
- Widget fetches products via
GET /public/billing/products - User selects product, widget calls
GET /public/billing/public-key - Stripe.js tokenizes payment method
- Widget calls
POST /public/billing/checkoutwith token - User redirects to Stripe checkout page
Webhook Processing
Stripe Events: After successful checkout, Stripe sends webhooks to complete order processing.
Integration: Public module creates checkout sessions, but order fulfillment happens via webhook handlers in billing module.
⚠️ Important Notes
- 🔓 Public Access: Endpoints are public but require custom funnel authentication
- 💳 Stripe Only: All billing operations use Stripe API
- 🎯 Funnel Isolation: Each funnel operates with separate Stripe accounts
- 📊 Preview Mode: Checkout endpoint supports preview for price calculation
- 🔐 Token-Based: Payment methods are tokenized (no raw card data)
- 🌐 CORS Enabled: Endpoints allow cross-origin requests for embedded widgets
🛡️ Security Considerations
Public Key Exposure
- Safe: Stripe publishable keys (
pk_live_*orpk_test_*) are designed to be public - Client-Side: Used in browser to tokenize payment methods
- Secret Keys: Never exposed (stored securely in
stripe_config)
Rate Limiting
- Recommendation: Apply rate limiting to prevent abuse
- No Built-In: Current implementation has no rate limiting
- Endpoints at Risk: Product listing, checkout creation
Input Validation
- Validation Middleware: Uses
validations/folder for request validation - Stripe Validation: Stripe API validates payment method tokens
- Email Validation: Important for payment method lookups
📈 Performance Considerations
Caching Opportunities:
- Product catalog (15-minute TTL)
- Stripe public keys (1-hour TTL)
- Funnel configurations (6-hour TTL)
External API Calls:
- Every request calls Stripe API
- Consider caching frequently accessed products
- Use Stripe's pagination efficiently
Last Updated: 2025-01-08
Module Path:internal/api/v1/public/
Main Routes:
GET /api/v1/public/billing/public-keyGET /api/v1/public/billing/productsPOST /api/v1/public/billing/checkout> Authentication: Custom funnel-based (not JWT)