Skip to main content

Direct Charge Operations

Source: internal/api/v1/store/Controllers/charge.js

Overview

The Charge controller handles direct Stripe charge operations, primarily for OneBalance wallet reloads. It supports manual balance reloads with currency conversion and payment source resolution.

Key Capabilities

  • Create one-time charges for wallet reloads
  • Automatic payment source resolution (default or provided)
  • Currency conversion for OneBalance credits
  • Manual charge operations (not subscription-based)

MongoDB Collections

CollectionOperationsPurpose
onebalanceUpdateBalance increments
onebalance.usage_logsCreateTransaction logging
stripe.keysReadParent account Stripe key resolution

Service Methods

charge

Creates a Stripe charge and optionally updates OneBalance.

Endpoint: POST /store/charge

Request Body:

{
amount: number, // Dollar amount (will be converted to cents)
currency: string, // Currency code (e.g., 'USD')
payment_source: string // Optional: Stripe source/card ID
}

Query Parameters:

{
onebalance: boolean; // Default true, set to false to skip balance update
}

Response:

{
success: true,
message: "Balance updated"
}

Business Logic:

  1. Resolve Stripe Instance:

    • Main account: Use platform Stripe key
    • Sub-account: Lookup parent account's Stripe key from stripe.keys
  2. Convert Amount: amount * 100 (dollars to cents)

  3. Resolve Payment Source:

    • If not provided, fetch customer's default_source
    • Error if no default source and none provided
  4. Create Charge: stripe.charges.create()

  5. Update OneBalance (if onebalance !== false):

    • Convert charge amount to BASE_CURRENCY using CurrencyUtil
    • Increment balance: $inc: { balance: converted_amount }
    • Log transaction with status 'success'

Currency Conversion:

const currUtil = new CurrencyUtil();
const currData = await currUtil.convert(
account.id,
total_amount, // In cents
currency?.toUpperCase() || BASE_CURRENCY,
BASE_CURRENCY,
);

await Onebalance.updateOne({ account_id: account.id }, { $inc: { balance: currData.amount } });

Edge Cases & Business Rules

1. Parent Account Stripe Key Resolution

Sub-accounts must use parent's Stripe keys:

if (!account.main) {
const stripe_keys = await StripeKey.findOne({
account_id: req.auth.account.parent_account,
});
stripe = Stripe(stripe_keys?.token?.access_token);
}

2. Default Payment Source

If no payment_source provided, uses customer's default:

if (!payment_source) {
const customer = await stripe.customers.retrieve(stripe_customer);
payment_source = customer.default_source;
if (!payment_source) {
throw badRequest('Payment source is not provided.');
}
}

3. OneBalance Optional Update

Can skip balance update by setting onebalance=false:

if (onebalance !== false) {
// Update balance
}

Use Case: Charging without crediting OneBalance (e.g., direct purchases)


💬

Documentation Assistant

Ask me anything about the docs

Hi! I'm your documentation assistant. Ask me anything about the docs!

I can help you with:
- Code examples
- Configuration details
- Troubleshooting
- Best practices

Try asking: How do I configure the API?
09:31 AM