This guide is the high-level map of money movements. It connects the intent builders, templates, balance deltas, and workflows so it is easier to trace a flow end-to-end.
Core Building Blocks
- Intent builders:
internal/moneyflow/intentbuilds acardpipeline.Requestfor each flow. - Templates:
internal/moneyflow/intent/templates/templates.godefines the expected legs for each intent kind. - Balance deltas:
docs/balances.mdandinternal/balances/deltas.godefine how each type/subtype mutates balances. - Execution:
internal/temporal/workflows/cardpipeline/pipeline.gopersists account/card legs and emits hooks. - Entry workflows: provider hooks and API workflows call the intent builders, then execute the pipeline.
ID Glossary (How Legs Tie Together)
LedgerTx: The flow root ID shared by every leg in a movement. This is the canonical flow ID.ReferenceID: Usually equalsLedgerTx. For card follow-ups, it may point at the original auth reference so all legs stay linked.TransactionID: Per-leg ID (derived fromLedgerTxwhen missing).linkedId(card webhooks): Provider-side linkage for auth -> settle -> refund chains. We mirror this on the card transaction feed.Idempotency-Key: Client-supplied key for API-triggered movements; used to seed IDs when present.
Rule of thumb: when tracing a flow, start from referenceId and join card/account/user ledger feeds by that UUID.
Flow Map (Intent -> Ledger Legs)
Legend: account legs are type/subtype. User legs apply only when UseUserFunds is set and a user account exists.
| Intent key | Card tx type | Account legs | Optional user legs | Zero-sum |
|---|---|---|---|---|
| authorization | authorization |
pending/settle_fee (hold) |
lock_user_funds for user-backed holds |
No |
| settlement | settle |
fee/settle_fee (release), deposit/settle_fee (fee credit) |
spend_user_funds when user-backed |
No |
| reversal | cancel |
transfer/settle_fee (release) |
unlock_user_funds |
Yes |
| refund | refund |
none | refund_user_funds |
Yes |
| decline | decline |
fee/decline_fee |
none | No |
| topup | topup |
pending/card_topup_hold, transfer/card_deposit |
Card funding posts to user account if user-backed | Yes |
| withdraw | withdraw |
transfer/card_withdraw |
Card return posts to user account if user-backed | Yes |
| close | close |
transfer/card_closed_refund, withdraw/card_closed_adjustment |
Card return posts to user account if user-backed | Yes |
| issue | issue |
transfer/card_deposit, pending/card_issue, fee/issue_fee, deposit/issue_fee |
User-backed issuance adds user holds + withdraw_user + deposit_user |
No |
| monthly_fee | none | pending/issue_fee, fee/issue_fee |
none | No |
| account_topup | none | deposit/* (wire, sepa, crypto, user, reconcilation), fee/settle_fee (optional) |
none | No |
| account_withdraw | none | withdraw/withdraw_system |
none | No |
User fee reimbursement: when UseUserFunds is on, fee funding is paired as withdraw_user (user) + deposit_user (parent) so the parent account stays whole.
Where Flows Enter the System
- Provider card events:
internal/temporal/workflows/connex,internal/temporal/workflows/monavate,internal/temporal/workflows/reap_transaction.go,internal/temporal/workflows/fank_hook.go - Card lifecycle (issue/topup/withdraw/close):
internal/temporal/workflows/issue.go,internal/temporal/workflows/topup_card.go,internal/temporal/workflows/withdraw.go,internal/temporal/workflows/close.go - User transfers:
internal/temporal/workflows/user_transfers.go(uses account-only intents withdeposit_user/withdraw_user) - Account topup/withdraw:
internal/temporal/workflows/topup_account.go,internal/temporal/workflows/withdraw_account.go
Step-by-Step Trace (Debugging Checklist)
- Start from a webhook or API response and capture
referenceIdandlinkedId. - Pull card transactions by card ID and filter by
referenceIdto get the card leg chain. - Pull account transactions by account ID and filter by the same
referenceIdto see fees, holds, and transfers. - If the card is user-backed, pull user account transactions and join by the same
referenceId. - If there is a mismatch, compare each leg to
docs/balances.mdand the intent template to verify expected subtypes.
For balance deltas and exact subtype rules, see Balance-Only Money Movements.