Charge
๐ Overviewโ
internal/api/v1/billing/services/charge.service.js powers marketplace-style purchases that bill the connected account immediately and optionally start new subscriptions on the parent account. It supports previewing pricing, executing charges with either legacy sources or modern payment methods, provisioning add-ons, and logging OneBalance usage.
Primary Controller: charge.controller.js
๐๏ธ Collections & Modelsโ
shared/models/account.js(_account) โ Validates parent/sub-account eligibility and Yext status.shared/models/onebalance.js(onebalance) โ Fetches rebill config to determine internal cost.shared/models/onebalance-usage_logs.jsโ Records cost events for both sub-account and parent.shared/models/queues.js(queue) โ Queues post-purchase automation jobs.shared/models/store-price.js/store-subscription.js/store-cart.jsโ Resolve pricing metadata and persist cart state.shared/models/user.jsโ Locates parent owner for queue attribution.shared/models/stripe-key.jsโ Supplies connected account access tokens.
๐ Full schema references live under
../../database/collections.
๐ External Servicesโ
- Stripe โ Charges API, Payment Intents API, Subscriptions API, Invoices API.
- DashClicks Router (
API_BASE_URL) โ Proxy for Twilio number pricing and customer creation. - Twilio Search Endpoint โ Determines tiered pricing for phone number purchases.
๐ Data Flowโ
flowchart TD
UI[Marketplace UI] -->|POST /checkout| Controller
Controller --> Service
Service -->|Connected token| Stripe[Stripe API]
Service --> Onebalance[(OneBalance)]
Service --> StorePrice
Service --> QueueManager
Stripe --> WebhookService
๐ง Core Behavioursโ
- Calculates internal cost based on OneBalance rebill settings before charging the customer.
- Supports
type=previewto upsert a single-item cart and return a formatted quote without billing. - Distinguishes between legacy card sources and PaymentMethod IDs, calling the appropriate Stripe API.
- Automatically creates a parent-account subscription mirroring the sub-account purchase for internal accounting.
- Enqueues downstream provisioning jobs (phone number activation, listing enablement) via Queue Manager.
๐งฉ Functionsโ
checkout({ account, account_id, product_type, type, external_action, card, price, uid })โ
Handles both preview (type="preview") and purchase paths.
Preview Pathโ
- Upserts a single-item cart with proration time, metadata, and
external_actionpayload. - Augments price data with phone-number quantity overrides when applicable.
- Returns
formatPriceDTO for UI display.
Purchase Pathโ
- Validates Stripe connectivity and resolves payment source (default source fallback).
- Computes
costusing OneBalance rebill values or price unit amount. - Executes Payment Intent (for
pm_IDs) or Charge (for legacy sources). - Creates parent subscription via
createMainAccountSubscription. - Logs OneBalance debits for sub-account and parent contexts.
- Enqueues
subaccount-chargequeue item with transaction metadata. - Returns formatted payload for receipt display.
Guards & Edge Casesโ
- Blocks duplicate listing purchases when Yext already active.
- Rejects Instasite/Site add-ons (unsupported via direct checkout).
- Requires payment source or default card; surfaces 3DS requirements for Payment Intents.
phoneNumQuantity({ account_id, parent_account, uid, external_action, price_id })โ
- Generates a scoped JWT to query Twilio inventory via Router.
- Matches returned pricing tiers to determine per-account costs.
- Returns
{ mainaccount, subaccount }integer amounts for rebill calculations.
formatPrice(item, product_type)โ
- Normalises cart or invoice data into
{ buyer, item }DTO consumed by frontend. - Handles setup fee vs recurring fee extraction and discount adjustments.
- Provides human-readable product name and interval metadata.
createMainAccountSubscription({ account, parent_account, price, charge_id, external_action, quantity })โ
- Uses platform API key (
STRIPE_SECRET_KEY) to create a subscription on the parent account. - Upserts
store-subscriptionrecord, enriches with latest invoice, and triggersnewOrderutility. - Annotates subscription metadata with sub-account identifiers for reporting.
additionalAction({ external_action, parent_account_id, account_id, subscription_id, uid })โ
- Derives follow-up queue payloads (phone provisioning, listings sync).
- Sets
yext_statuswhen listings purchased. - Queues
subscription-activatejob targeting Queue Manager.
๐งช Testing Notesโ
- Fixtures:
tests/fixtures/customer.jsinclude sample checkout payloads; extend for new product types. - Integration tests:
tests/customer.test.jscovers OneBalance entries and queue side-effects.
โ ๏ธ Operational Considerationsโ
- Ensure
APP_SECRET,API_BASE_URL,SETUP_PRODUCT, andSTRIPE_SECRET_KEYenvironment variables are configured. - Rate limiting: Twilio search + Stripe calls can stack; controllers throttle repeated previews.
- Phone number pricing relies on Twilio response structure (
pricing.pricearray).