Avo for fintech
Run your fintech's back office from your Rails app
KYC reviews, refunds, flagged transactions, and account limits, worked by your team from a command center inside your Rails app, behind permissions you can prove and an audit trail you own.
250+ paying companies · 2.7M downloads of the avo gem
kyc.approved
transaction.refunded
limit.raised
Written by the actions your team runs, stored in your own tables, and exportable on the day an auditor asks. No vendor to email for a copy.
01 · the stakes
The bar an admin has to clear when money moves through it
When your product moves money, the internal tool is where the risky clicks happen. An admin that was fine for a CRUD app becomes the most scrutinized surface in your stack.
-
01
Every change needs a paper trail
Who raised that limit, who approved that KYC check, who issued that refund and why. When an auditor or a partner bank asks, "we're not sure" is not an answer, and bolting logging onto a hand-built admin after the fact is a project nobody schedules.
-
02
Support touches money, so access has to be narrow
The person answering tickets should be able to issue a refund without also being able to edit balances or see full account numbers. An all-or-nothing admin login is a finding waiting to happen.
-
03
Your data cannot transit someone else's servers
A hosted admin builder puts a vendor between your team and your financial data, and that vendor becomes a line item in every security review. Inside a regulated stack, the tool has to live where the data lives.
-
04
Review queues rot when engineers own them
Pending KYC checks, disputed charges, and flagged accounts pile up when every action needs a developer to run a console command. The queue is an ops job; the tooling for it should not be an engineering backlog.
02 · the Avo version
Your models are already the hard part. Avo is the rest.
Avo mounts inside your Rails app as an engine, so accounts, transactions, and KYC records stay in your database and never sync out to a vendor. You point resources at the models you already have, enforce access with the Pundit policies your app already uses, and turn the money verbs into actions your team runs instead of console commands an engineer runs.
The money verbs become safe, logged actions
Refund a payment, approve a KYC check, freeze an account: each is an Avo action with a confirmation step and a required reason, running one code path you wrote, so support acts in seconds without a console session or a deploy.
Permissions provable down to the field
Avo reads your Pundit policies, so a support agent sees a masked account number while compliance sees the full record, and a field a role should not see simply does not render. The access model is Ruby in your repo, reviewable in a PR.
Review queues as saved views, not consoles
Pending KYC, disputes older than a week, accounts flagged by risk: scopes and dynamic filters turn each queue into a link your ops team opens every morning, worked oldest-first without touching a terminal.
An audit trail in your own database
Pair Avo with model-level auditing and every change records the acting user, in tables you can query and produce when someone asks. Avo's audit logging goes further on Enterprise, down to who viewed a record.
Dashboards on the numbers that matter
Signups, volume, dispute rates, and queue depth on dashboards built from your own queries, so the Monday numbers come from the same database as the product, not an export someone maintains.
A Transaction resource with a refund action and masked fields:
class Avo::Resources::Transaction < Avo::BaseResource
self.includes = [:account]
def fields
field :reference, as: :text, readonly: true
field :amount, as: :number, readonly: true
field :status, as: :select, enum: ::Transaction.statuses
field :card_number, as: :text, visible: -> { current_user.compliance? }
field :account, as: :belongs_to
end
def actions
action Avo::Actions::RefundTransaction
end
end
class Avo::Actions::RefundTransaction < Avo::BaseAction
self.name = "Refund transaction"
self.confirm_button_label = "Issue refund"
def fields
field :reason, as: :textarea, required: true
end
def handle(query:, fields:, current_user:, **)
query.each { |txn| txn.refund!(reason: fields[:reason], by: current_user) }
succeed "Refunded #{query.count} transaction(s)"
end
end
03 · the timeline
From first resource to the team running on it
Generate resources for your existing Account, Transaction, and KycCheck models and you have a navigable back office on real data, with each account's transactions and checks linked from its record.
Put it behind your existing authentication, write Pundit policies so support, risk, and compliance each see their slice, and ship the refund action with a required reason so the first money verb leaves the console.
KYC and dispute queues are saved views your ops team works daily, model auditing records every change with the acting user, and engineers are back on the product.
case study · cybersecurity platform
“It's not like an admin interface, it feels like an app builder. A code-based app builder framework.”
04 · start today
Give your ops team the back office this week
Avo is per app with unlimited users, so the whole team works from it without the bill scaling with headcount. When you hit an edge Avo doesn't cover, you drop to plain Rails instead of filing a feature request.
Things fintech teams build with Avo
Avo by industry
Avo for your team
Frequently asked questions
- Can I run a fintech back office on Ruby on Rails?
- Yes. Accounts, transactions, and KYC checks are ordinary Rails models, and Avo turns them into a working back office on top of your existing tables: resources for the records, actions for the money verbs, policies for who can do what. Because Avo runs inside your Rails app, nothing about your data path changes.
- Is Avo PCI DSS compliant?
- Compliance is a property of your whole system and processes, not of a single library, so no gem can be PCI compliant on its own and we do not claim Avo is. What Avo gives you is a better starting point: it runs inside your app on infrastructure you control, sensitive fields render only for roles your policies allow, and no card or account data transits a third-party service. The compliance work itself, scoping, encryption, and access reviews, remains yours, on code you own.
- Can support issue refunds without database access?
- Yes. A refund becomes an Avo action: a button with a confirmation step and a required reason that calls the same model method your product uses. Support gets a safe, logged way to act, and nobody needs a production console. See the actions docs.
- How do we keep support from seeing full account details?
- Access is enforced with Pundit policies, the same ones your Rails app uses, down to individual fields. A card number or full account field can render only for compliance while support sees a masked value, and the rules live in Ruby you review like any other code. See the authorization docs.
- Does our financial data leave our servers?
- No. Avo is a Rails engine mounted in your application, so every record stays in your database and every request is served by your app. There is no hosted platform between your team and your data, which keeps your vendor list, and your audit scope, unchanged.
- Can we produce an audit trail when a partner bank asks?
- Yes. Pair Avo with model-level auditing and every change is recorded with the acting user in your own database, where you can query and export it. On the Enterprise tier, Avo's audit logging also records who viewed a record, which is the level some partners ask about.