Cloud manual invoices and accounting export
Mockarty Cloud supports B2B payment by bank transfer without pretending that a payment provider processed the money. An Owner, Admin, or Billing Manager can choose Request invoice for a paid plan. Cloud freezes the exact seller, plan, price version, policy bundle, currency, quantity, tax, and total in a durable order and creates an open invoice. The subscription and entitlements do not change at this stage.
The Cloud API must use PostgreSQL and start with CLOUD_API_BILLING_MODE=manual_invoice or CLOUD_API_BILLING_MODE=provider. The first mode offers bank-transfer invoices only; the second can offer both hosted provider checkout and manual invoices. The default free mode exposes neither paid path. Payment-provider credentials are not required for a manual invoice.
Customer flow
Open Subscription, select a plan, and choose Request invoice. The request requires a recent step-up confirmation and an Idempotency-Key that identifies that exact request. Reusing the same key after a lost response returns the same frozen order; changing the plan, Space, or quantity with that key is rejected.
The manual-invoice panel shows one of these durable states:
- Awaiting transfer: the invoice is open and no bank evidence has been recorded.
- Awaiting finance approval: billing support recorded one-way evidence digests; access is still unchanged.
- Approved: an independent finance operator approved the transfer and the frozen subscription became active.
- Rejected or Canceled: the order and invoice are closed without granting access.
An unpaid request can be canceled from the same panel. A transfer that has already entered finance review cannot be canceled by the customer; contact support so the payment is reconciled instead of creating a second invoice.
Two-person operator approval
Open Operator console → Manual invoice queue. Billing support records the bank transaction reference and the SHA-256 digest of the reviewed statement. Do not paste the statement or payment details into the queue.
A different finance operator reviews and approves or rejects the case. The person who recorded the transfer cannot approve it. Approval marks the invoice paid and activates the subscription. It does not change the agreed price or claim that an online payment succeeded.
Rejected evidence uses a bounded non-personal reason code. Do not put names, account numbers, payment details, or free-form comments in reason fields.
Settle with a bonus
An invoice can be settled by a grant rather than by money: beta access, a promotional campaign, or a term of a partner agreement. The invoice queue offers Settle with bonus next to recording a transfer.
Enter the grant reference (for example, a promo code or agreement), select the reason shown in the form, and add the requested evidence digest. Do not enter customer payment details here.
As with a bank transfer, a second finance operator must approve the case. Once approved, the subscription activates. The accounting record distinguishes a grant from an incoming payment.
Settling with a bonus takes the approving finance role, not billing support: giving the product away is a commercial decision.
Operator MCP
An operator token with the read scope sees the same queues over MCP: cloud_manual_invoices_list (filter by status; evidence_pending is the state that waits for a second finance operator) and cloud_billing_credits_list (proposed waits for a finance decision). Both appear in the first-look cloud_operator_attention answer as manual_invoices_evidence_pending and billing_credits_proposed. Decisions themselves stay in the console: the MCP surface is read-only.
Accounting export
An operator with accounting authority can open Operator console → Accounting export and select a range of at most one year. The returned immutable projection includes stable entity IDs, seller code, currency, price and policy versions, net, tax, gross, provider and refund provenance when applicable, and an export digest. It deliberately excludes customer workload content, email addresses, bank references, raw statements, connector secrets, and provider response bodies.
The export is an accounting input, not proof that a provider settlement or fiscal receipt was delivered. Compare it with Commerce reconciliation and the bank or provider record before closing a discrepancy.
Billing credits and subscription repair
The operator console also contains Credits and subscription repair for bounded corrections:
- Billing support can propose a credit only against an already settled order. The proposed amount plus successful refunds and all other proposed or issued credits cannot exceed that order’s paid total.
- A different finance operator approves or rejects the exact case generation. An approved credit is an immutable compensating-accounting fact and appears in the customer’s Subscription page. The customer is told about it by e-mail and in the cabinet, with the amount and the reason. The operator who proposed the credit cannot decide it; the console refuses with
money_adjustment_self_decision. - An issued credit is not cash, a payment-provider operation, or an automatically spendable wallet balance. Its tax effect is not guessed at issuance; future invoice application is a separate pricing and accounting operation.
- A finance operator can repair a subscription projection only from an exact paid order and paid invoice. Cloud derives the plan, billing period, seats, and frozen commercial references from those facts; the request cannot supply replacement values.
Before a repair, enter the subscription ID and choose Load current fence. The returned generation must be sent unchanged with the command. A repair is rejected if the paid period already ended, the source is refunded or disputed, the seat count no longer fits, the projection is already correct, or another repair advanced the generation. Each refusal names its reason (repair_period_ended, repair_source_not_settled, repair_seats_exceed, repair_not_needed, money_adjustment_conflict). A subscription that was canceled or expired cannot be repaired: its commercial selection is closed and the ledger never reopens one (repair_selection_closed); the customer checks out again, and support can issue a credit for the unused period. Every accepted repair dirties entitlement heads and reconciles membership economics in the same audited transaction.
Recovery rules
- Repeat a lost request with the same
Idempotency-Key; do not invent a second business operation. - Reload a case after
409because another operator may have advanced its generation. - Never approve from a screenshot or a customer message alone. Reconcile against the bank record and the stored document digest.
- If approval outcome is uncertain, read the case and accounting export before retrying. A successful atomic transaction is returned by exact replay; a conflicting retry is rejected.
- Never use subscription repair to extend an expired period, override a price, or replace provider/fiscal reconciliation. Fix the authoritative source fact first; repair only a demonstrably stale projection.