{% extends "base.html" %} {% import 'components/macros.html' as ui %} {% block title %}App Billing - Server Admin{% endblock %} {% block head_extra %} {% endblock %} {% block content %}

Server App Billing

{% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} {% for category, message in messages %}
{{ message }}
{% endfor %} {% endif %} {% endwith %}

App Usage Pricing And Payments

Set monthly app fees by product count, enable worldwide API-backed payment modes, and monitor subscriptions. Month one is free; shop admins can subscribe or pay early before the due date.

Open Payment Page
Default PriceUSD {{ "{:,.2f}".format(settings.base_price|float) }}
Pricing Tiers{{ tiers|length }}
Payment Modes{{ methods|length }}

Default Billing

Pricing By Product Count

Default structure shown to users in USD: 0-149 products = USD 8; 150-249 = USD 12; 250-349 = USD 16. Add or remove tiers as your billing policy grows.

{% for tier in tiers %} {% endfor %}
TierProductsAmountAction
{{ tier.label or 'Custom tier' }} {{ tier.min_products }} - {{ tier.max_products if tier.max_products is not none else 'No limit' }} USD {{ "{:,.2f}".format(tier.amount|float) }}

Payment Modes For App Usage

Enable the global methods you want shop admins to use. Paybill, Till, cash, and local-only manual modes are removed from app usage billing. The money is routed to the server-owner merchant account/API credentials configured here. Provider payouts to your bank are controlled by your account and payout settings with Stripe, PayPal, Paystack, Flutterwave, Wise, or your bank.

{% for method in methods %}
{{ method.display_name }}
{{ method.category }}
{% if method.is_enabled and method.is_configured %} Live {% elif method.is_enabled %} Needs credentials {% else %} Disabled {% endif %}
{% for field in method.fields %} {% if field != 'instructions' %} {% if field == 'sandbox' %} {% elif field == 'currency' %} {% else %} {% set is_secret = 'secret' in field or 'key' in field or 'passkey' in field or 'credential' in field or 'token' in field %} {% if is_secret %} {% else %} {% endif %} {% endif %} {% endif %} {% endfor %}
{% endfor %}

Shop Charges

{% for shop in shops %} {% else %} {% endfor %}
ShopProductsBilling StageCurrent ChargeSubscriptionNext BillingLatest PaymentPayment Control
{{ shop.name }}
{{ shop.code }}
{{ shop.product_count }} {% if shop.is_billing_exempt %} {{ 'Default shop protected' if shop.is_default_exempt else 'Payments paused' }} {% if shop.exemption_reason %}
{{ shop.exemption_reason }}
{% endif %} {% elif shop.is_free_trial %} First month free
{{ shop.trial_days_left }} day(s) left{% if shop.billing_starts_at %}; billing starts {{ shop.billing_starts_at.strftime('%Y-%m-%d') }}{% endif %}
{% else %} {{ shop.tier_label }} {% endif %}
USD {{ "{:,.2f}".format(shop.app_fee|float) }} {% if shop.is_free_trial and not shop.is_billing_exempt %}
Then USD {{ "{:,.2f}".format(shop.regular_app_fee|float) }}
{% endif %}
{% if shop.is_billing_exempt %} Exempt {% elif shop.subscription_status %} {% if shop.subscription_status == 'active' %} {{ shop.subscription_status|title }} {% else %} {{ shop.subscription_status|title }} {% endif %}
{{ (shop.subscription_method or 'unknown').replace('_', ' ')|title }}{% if shop.subscription_auto_pay %}; auto enabled{% endif %}
{% else %} Not subscribed {% endif %}
{{ '-' if shop.is_billing_exempt else (shop.next_billing_date or '-') }} {% if shop.latest_payment_status %} {% if shop.latest_payment_status == 'paid' %} {{ shop.latest_payment_status }} {% elif shop.latest_payment_status in ['pending', 'initiated'] %} {{ shop.latest_payment_status }} {% else %} {{ shop.latest_payment_status }} {% endif %}
USD {{ shop.latest_payment_amount }} via {{ shop.latest_payment_method }}
{% else %} No payment {% endif %}
{% if shop.is_default_exempt %} Built-in default shop {% elif shop.is_manual_exempt %}
{% else %}
{% endif %} {% if shop.status == 'suspended' and is_server_owner %}
{% endif %}
No shops match that search.

Recent App Usage Payments

{% for payment in payments %} {% else %} {% endfor %}
ShopAmountMethodReferenceStatusDateUpdate
{{ payment.shop_name or ('Shop #' ~ payment.shop_id) }} USD {{ "{:,.2f}".format(payment.amount|float) }} {{ (payment.method_code or 'unknown').replace('_', ' ')|title }} {{ payment.reference or '-' }} {% if payment.status == 'paid' %} {{ payment.status }} {% elif payment.status in ['pending', 'initiated'] %} {{ payment.status }} {% else %} {{ payment.status }} {% endif %} {{ payment.created_at }}
No app usage payments yet.
{% endblock %}