Bank of Advance app icon

Community bank · Banno Mobile tenant · Stoddard County, MO

How Bank of Advance's accounts and Zelle traffic come off Banno Mobile

The Android package com.bankofadvance.grip sits in the same .grip namespace as com.profitstars.grip — the canonical Banno Mobile reference build under Jack Henry's ProfitStars division — and the same suffix shows up on other US community-bank tenants (com.linkbank.grip, bank.cfg.grip, com.cbna.grip, com.tompkinstrust.grip). Treat the page on that basis: Bank of Advance is a Banno Mobile white-label deployment for The Bank of Advance (Miles Bancshares, Inc., Advance, Missouri), the data lives behind the Banno Consumer API, and the integration is mostly about consuming a paginated, cursored transaction stream plus a handful of event channels — not unwrapping an unknown protocol.

What we would actually ship for this bank is a Python or Node module that handles the PKCE auth dance, persists a per-account cursor, replays the transaction stream against a warehouse table, and emits typed events for Zelle send/receive, mobile deposit status changes and card-state changes. The footprint is small because Banno does the heavy lifting; the value sits in handling the bank-specific quirks — pending posting behaviour, rate budget on this tenant, and the bank's current aggregator-program posture — correctly enough that the integration is still running unattended on month 18.

The data domains we read off this Banno tenant

DomainWhere it lives in the Banno surfaceGranularityWhat an integrator does with it
Accounts Consumer API /users/me/accounts — checking, savings, club, CDs, money markets, loans, lines of credit (account-type list per the bank's own services page). Current and available balances, last-statement balance, account type, masked number, status. Aggregation widgets, sweep automation, balance-threshold automations.
Transactions Consumer API /users/me/accounts/{id}/transactions, cursor-paginated, with a status field that flips pending → posted in place. Date, posted date, amount, description, merchant, type, check images for mRDC items. Categorisation, expense feeds, reconciliation against an external ledger, anomaly alerts.
Transfers Internal own-account transfers and external A2A; the bank also markets "Rapid Transfer" that funds external accounts via debit-card rails. Initiation, schedule, status (scheduled, in-flight, posted, failed), reference id. Treasury automation, scheduled funding, refund pipelines.
Zelle P2P Banno P2P module wrapping the Early Warning Services (Zelle) network — confirmed Zelle page on the bank's site. Send / receive, recipient identifier (phone, email, Z-Tag), memo, real-time status. Real-time disbursement to retail customers, refunds without an ACH return window.
Mobile Remote Deposit mRDC endpoint — front / back check images, MICR line, deposit amount, hold rules. Per-deposit status (queued, accepted, posted, returned) with check-image links. Embedded check intake in a third-party app, automated hold reconciliation.
Card controls Debit-card endpoints: pause / unpause, travel notice, alert rules. Card state, threshold settings, alert subscriptions. Fraud-response workflows, kiosk-side card management.
Bill Pay ProfitStars / iPay back-end as exposed through Banno — payee directory, one-time and recurring schedules. Payee, payment date, amount, delivery method (electronic or paper draft). AP automation, scheduled outgoing payments.
eDocs / statements Monthly statement PDFs and year-end tax documents, addressable by period and account. Document type, period, account reference, PDF binary. Statement ingestion for accounting and tax pipelines.

The three authorized routes into this stream

Three routes are realistic for a Banno tenant of this size. We name what each one reaches, the typical effort to stand it up, and how durable the route is across Banno or core changes.

1. Aggregator-permissioned access (Banno's native partner channel)

Banno publishes a Data Aggregators program covering Plaid, MX, Finicity, Akoya and Yodlee. When the bank has enrolled, third parties authenticate the consumer through an OAuth handshake and receive a tokenized read view of accounts and transactions without holding the customer's online-banking password. Reach: accounts, transactions, statement balances, in some configurations card and bill-pay status. Effort: low — primarily configuration on the aggregator side plus the bank's own enrolment. Durability: high; this is the route Banno explicitly steers toward.

2. Direct Consumer API integration under tenant credentials

For data flows the aggregator route does not cover (Zelle event streams, card-control writes, mRDC binary submission, embedded-fintech plugin surfaces), we set up an OAuth2 + PKCE client against the bank's Banno tenant subdomain and call the Consumer API directly with scoped tokens. Reach: every endpoint the Banno mobile build itself uses. Effort: moderate — the studio handles the client registration, redirect URIs, scope mapping and the on-device PKCE flow during onboarding; access is arranged with the bank, not assumed. Durability: high while the bank remains on Banno; the auth layer becomes the only thing to revisit if the bank moves cores behind Banno.

3. Consenting-customer credential bridge under FFIEC 2021 expectations

Where neither aggregator enrolment nor a tenant client is in place, the legal basis is the customer's own authorization and the technical bridge runs through a credential-handling channel built to the controls FFIEC named in its 2021 interagency guidance — MFA on the consumer's session, the studio's environment hardened, every fetch logged, credentials not retained beyond the consented purpose. Reach: whatever a consumer can see in the app. Effort: higher operationally because of the consent and control plumbing. Durability: moderate; we treat this as a transitional route until the bank lights up an aggregator or tenant channel.

The build we usually recommend for a Banno tenant this size is route 2 with route 1 as a fall-back when the data the customer wants is fully covered by aggregator scopes — code that runs against the same API the mobile app does, with a documented downgrade path if the bank moves to a partner-only posture.

Wiring the Consumer API and replaying the transaction stream

The snippet below is illustrative — exact parameter names and field shapes are confirmed against the bank's tenant during onboarding, not asserted here. It reflects the Banno-documented OAuth2 + PKCE + OIDC pattern and the cursor replay shape consistent with the marketed feature set.

# Illustrative — exact shapes confirmed during the build.
# Banno Consumer API on com.bankofadvance.grip; client_id, scopes and the
# tenant subdomain are issued during onboarding with the bank.
import httpx, hashlib, secrets, base64, time

BANNO_BASE = "https://<tenant>.banno.com/a/consumer/api/v0"
CLIENT_ID  = "<issued during onboarding>"

# --- 1. OAuth2 Authorization Code + PKCE (native client, no secret on device)
verifier  = base64.urlsafe_b64encode(secrets.token_bytes(64)).rstrip(b"=").decode()
challenge = base64.urlsafe_b64encode(
    hashlib.sha256(verifier.encode()).digest()
).rstrip(b"=").decode()
# user is redirected through <tenant>.banno.com, returns ?code=...
# POST /oauth2/token { grant_type, code, code_verifier, client_id, redirect_uri }
# Response: { access_token, refresh_token, id_token (OIDC), expires_in, scope }

# --- 2. Account list, then cursor-replay each account's transaction stream.
def replay_transactions(access_token, account_id, since_cursor=None):
    cursor = since_cursor
    while True:
        params = {"limit": 200}
        if cursor: params["cursor"] = cursor
        r = httpx.get(
            f"{BANNO_BASE}/users/me/accounts/{account_id}/transactions",
            headers={"Authorization": f"Bearer {access_token}"},
            params=params, timeout=15.0,
        )
        if r.status_code == 401:
            access_token = oidc_refresh(access_token)   # rotate via /oauth2/token
            continue
        if r.status_code == 429:
            time.sleep(int(r.headers.get("Retry-After", "5")))
            continue
        r.raise_for_status()
        page = r.json()
        for txn in page["transactions"]:
            # Pending rows can be rewritten by a later posted row for the same
            # logical txn. The warehouse key is (account_id, txn_id, posted_at);
            # a posted row supersedes a prior pending row that matches on
            # (merchant, amount, business_date), captured as a failing-test
            # fixture during onboarding using the bank's own posting behaviour.
            yield txn
        cursor = page.get("nextCursor")
        if not cursor:
            return page.get("currentCursor")   # persist for tomorrow's replay

The same pattern carries over to the Zelle event channel and the mRDC status stream — replay-by-cursor with idempotent upserts keyed on the bank's identifiers, so a paused job can be resumed cold and a re-run on the same window converges on the same warehouse state.

What lands in your repo

For a Banno-style tenant the deliverables are concrete and weighted toward code that runs.

  • Runnable source. A Python module (and a Node.js port on request) that handles the PKCE auth dance, OIDC refresh rotation, cursor-paginated transaction replay with pending/posted reconciliation, Zelle event ingestion, mRDC submission, card-control writes, and bill-pay scheduling. Imported into your service, it is the integration.
  • Webhook / event-handler scaffolding. A small fan-out service that turns the Banno cursor stream and the Zelle / mRDC channels into a queue of typed events your code subscribes to — useful when the consuming side is a workflow engine or a downstream analytics pipeline rather than a single batch job.
  • Automated test fixtures. Recorded responses from a consenting dry-run account, a fake Banno transport for unit tests, and contract tests pinned to the bank's specific pending → posted behaviour. If the Banno surface drifts, CI breaks before reconciliation does.
  • Sync-design notes. Recommended cursor cadence, retry / back-off windows tuned to this tenant's observed rate budget, and an idempotency rule the warehouse loader applies on every write.
  • OpenAPI / auth-flow document. A spec describing the surface the integration calls — endpoints, scopes, request and response shapes, error semantics, OIDC flow — usable as the reference your own team works from after the engagement ends.
  • Compliance & retention guidance. A short document on consent capture, log retention, data minimization and the FFIEC 2021 control map, written for your auditor rather than as marketing.

Three end-to-end builds the studio would routinely run for this bank

  1. Nightly accounting export. Pull balances and posted transactions for each enrolled customer overnight, push the deltas into Xero or QuickBooks Online, mark pending entries explicitly so the bookkeeper does not double-enter them. The cursor replay survives a missed night without re-pulling history.
  2. Treasury sweep. Subscribe to balance-threshold events; when a checking account crosses a configured floor, kick off a Banno internal transfer or a Rapid Transfer to top it up. Each sweep carries a deterministic client-side request key, so the same event hitting the worker twice resolves to the same single transfer at the bank.
  3. Refund-by-Zelle. A merchant-side refund engine that issues a Zelle P2P transfer to a customer's email or phone for refund amounts under the merchant's threshold, with mRDC fall-back when the customer's identifier is not Zelle-resolvable.

Where the rule actually sits for a Missouri community bank

Because Bank of Advance is a Missouri state-chartered, Federal Reserve member bank, two things narrow the regulation problem: Missouri has no general consumer-data-privacy statute and no state open-banking rule, and a state-chartered FDIC bank's prudential supervisor (not the FTC) enforces the interagency Safeguards standard at 12 CFR Part 364 Appendix B. The would-be federal data-rights rule for retail bank data, 12 CFR Part 1033, is not a present-tense obligation for this bank — it is back in agency reconsideration and a federal court has enjoined enforcement, which is why aggregators are still riding the pre-existing tokenized arrangements. The integration is therefore written on the basis that actually exists today: the customer's own express authorization, captured and logged.

Operationally that means, for this bank: a user-permissioned, tokenized aggregator handshake (Plaid, MX, Finicity, Yodlee or Akoya) when Banno's Data Aggregators program is enrolled for the tenant; or a consenting-customer credential bridge built to the controls in FFIEC's August 2021 interagency guidance on Authentication and Access to Financial Institution Services and Systems when it is not. Data handling is documented against GLBA Title V, Reg P and Part 364 App. B. The build keeps a §1033 alignment as a configuration switch rather than a rewrite, so when the rewrite lands the integration adopts whatever the final framework requires without redoing the core code.

Things this build has to account for at this specific bank

The interesting engineering judgments are at the edges, not the centre. Three call-outs for a Banno tenant the size of Bank of Advance:

  • Pending → posted transaction flips. Banno surfaces pending and posted transactions on the same endpoint with a status field, and the same logical transaction can rewrite as it clears (sometimes with a different transaction id). The warehouse loader keys on (account_id, transaction_id, posted_date) and applies an upgrade rule that lets a posted row supersede a matching pending row on (merchant, amount, business_date). We map this once on a consenting account during onboarding using the bank's own posting behaviour, and the rule lives in the test suite as failing fixtures so a future change in posting timing fails CI before it fails reconciliation.
  • Per-tenant rate budget on the Banno cloud. Banno serves each FI on a per-tenant subdomain and tracks rate limits per tenant, not per consumer. A noisy reconciliation job at 9am can crowd retail customers off their banking session. We measure the bank's observed budget during the dry-run window, set the polling cadence and the retry envelope around that measurement, and document the budget so your platform team can see when an unrelated job is starting to eat into the headroom.
  • Aggregator-program posture, confirmed not guessed. Whether Bank of Advance is enrolled in Banno's Data Aggregators program (Plaid, MX, Finicity, Akoya, Yodlee) is a configuration question the bank answers, not one we infer from the package id. We confirm enrolment with the bank on the first call, route the build to the aggregator channel if it is on, and stand up a tenant-direct OAuth client if it is not. The deliverable code paths cover both so a later enrolment change is a switch flip, not a re-build.
  • Statement document retention. The bank's eDocs and tax documents are PDF binaries served from short-lived URLs; a download pipeline has to store the binary as it lands, not lazily fetch the URL six months later when the link has expired. Our ingestion stores on first sight and the storage layout is documented so a later GLBA Safeguards audit has a clean retention story.

Pricing for a Banno-style integration like this one

Source-code delivery for a Banno tenant the size of Bank of Advance starts at $300 and is paid only after the build is in your repository and verifiably working against a consenting account — typical cycle is one to two weeks for a first delivery covering accounts, transactions, transfers, Zelle and mRDC. The hosted alternative is the same surface exposed on our endpoints, billed per call with no upfront fee; you ship traffic, you pay, and the integration can move to source-delivery later without redoing the modelling. To start, send the app name and what the integration has to do — open a brief on /contact.html and we will come back with a short scope and the route we would take for this bank. Access, sandbox routing and any aggregator-program coordination are arranged with the bank as part of the engagement.

Interface evidence — what the live app surfaces look like

Screenshots from the public Play listing, useful for cross-referencing UI elements against API responses during the build.

Bank of Advance app screen 1 Bank of Advance app screen 2 Bank of Advance app screen 3 Bank of Advance app screen 4 Bank of Advance app screen 5 Bank of Advance app screen 6 Bank of Advance app screen 7
Bank of Advance app screen 1 large
Bank of Advance app screen 2 large
Bank of Advance app screen 3 large
Bank of Advance app screen 4 large
Bank of Advance app screen 5 large
Bank of Advance app screen 6 large
Bank of Advance app screen 7 large

Sources opened to put this together

The brief is built from the bank's own product pages, the Banno / Jack Henry developer documentation, the CFPB's reconsideration page and 2026 industry reporting on it, and a cross-check against other community-bank apps in the same .grip namespace. Specific deep links:

Reviewed 31 May 2026 by OpenFinance Lab — engineering notes for the Banno Mobile build at com.bankofadvance.grip.

Peers in the community-bank cluster

Apps an integrator usually evaluates alongside Bank of Advance, either because they sit in the same Missouri / Arkansas community-bank tier or because they show up in the same shopping list when a customer asks "reach my bank" without naming the institution. Each peer holds broadly the same data — balances, transactions, transfers, P2P, mobile deposit, statements — and a unified integration over a few of them is usually one project, not several.

  • Community State Bank of Missouri — same-state small bank app holding balances, transactions, internal transfers and bill pay; close institutional peer.
  • Community Bank of Missouri (CBOM Mobile) — another in-state community-bank app with balances, transfer history and bill-pay payees.
  • CSB Arkansas Mobile — Community State Bank, Arkansas; the closest neighbouring-state peer, with mobile deposit and bill pay on the same shape.
  • First State Community Bank (FSCB Banking) — Missouri-headquartered, holds balances, activity, mRDC images and internal / external transfers.
  • Community Bank N.A. (CBNA Mobile Banking) — another .grip tenant build under com.cbna.grip, useful as a like-for-like reference when designing the integration.
  • Tompkins Community Bankcom.tompkinstrust.grip; another Banno white-label, the same Consumer API shape applies.
  • CFG Bankbank.cfg.grip; same Banno codebase, larger-bank deployment patterns visible in the Play listing.
  • United Community Mobile — community-bank app holding balances, transfers and deposit history; close in tier and scope.
  • CFSB Mobile Banking — Community Financial Services Bank; balances, mRDC images and secure-messaging threads with the same feature outline.
  • Chime, Ally Bank, Varo Bank — mobile-first national peers that are not community banks but usually appear in the same comparison shortlists; useful when a buyer wants "like my Bank of Advance app but national".

Common questions an integrator asks first

Is com.bankofadvance.grip really a Banno Mobile build, and does that change the integration plan?

The .grip Android namespace is the historical Banno suffix; the canonical reference build sits at com.profitstars.grip (Jack Henry's ProfitStars division) and the same suffix is used by other Banno tenants such as com.linkbank.grip, bank.cfg.grip and com.cbna.grip. We treat Bank of Advance as a Banno Mobile white-label on Jack Henry — meaning the integration targets the Banno Consumer API (REST/JSON, OAuth2 + PKCE + OIDC) rather than a hand-rolled per-bank protocol, which shortens the build and makes the test fixtures portable. The hosted tenant subdomain, rate budget and any aggregator-program enrolment are confirmed with the bank during onboarding.

Since CFPB §1033 isn't in force right now, what's the actual legal basis we'd use?

For Bank of Advance the operative basis is the customer's own express authorization, not 12 CFR Part 1033 — the §1033 rule is currently under CFPB reconsideration and enforcement has been enjoined, so there is no §1033 compliance obligation in effect to build against. We implement that authorization as a user-permissioned, tokenized aggregator handshake (Plaid, MX, Finicity, Yodlee or Akoya) when Banno's Data Aggregators program is enrolled for this tenant, or as a consenting-customer credential bridge under FFIEC's 2021 interagency guidance when it is not. Data handling follows GLBA, Reg P, and the interagency Safeguards standard for FDIC-insured banks at 12 CFR Part 364 Appendix B. The build is structured so a §1033 alignment slots in as configuration when the CFPB rewrite finalizes.

How do you handle pending-to-posted transaction flips when replaying the stream?

Banno surfaces pending and posted transactions on the same endpoint with a status field; the same logical transaction will appear first with a pending status (estimated posted date) and later with a posted status (cleared date), and the transaction id can also change in some edge cases. The cursor replay keys warehouse rows on (account_id, transaction_id, posted_date) plus an upgrade rule that lets a posted record overwrite an earlier pending record for the same merchant-amount-date triple. We map this once on a consenting account during onboarding so the rule reflects how Bank of Advance's actual core posts, not a generic assumption, and the rule is captured as failing test fixtures in the suite.

What gets touched if the bank moves between Jack Henry's cores or onto the new platform?

Banno Mobile sits in front of one of Jack Henry's cores (most commonly SilverLake, CIF 20/20 or Symitar) and abstracts that core through the Consumer API. From the integration's perspective the surface is the Consumer API — a core migration may change throughput, posting cut-offs and which embedded fintech modules are present, but the resource shapes (accounts, transactions, transfers, bill pay, P2P, mRDC, cards, alerts, statements) stay the same. The build's risk is therefore concentrated at the auth layer (tenant subdomain, OAuth client) and at the rate budget, both of which are configuration in our deployment, not code.

Bank profile — collapsed reference

Institution. The Bank of Advance, 105 E Gabriel St, Advance, Missouri 63730 — a state-chartered Missouri community bank, Federal Reserve member, FDIC-insured (FDIC certificate 9369 per the search-snippet of the FDIC BankFind page; not independently re-verified by direct page load).

Holding company. Miles Bancshares, Inc. — Advance, MO — the developer named on the Google Play listing.

Founded. 1902, per the bank's own About page; family-owned per the same source.

Routing number. 081506523 as the primary routing per third-party routing-number databases; a secondary number 081519361 also appears in those databases with unverified current status.

Financials. Approximately $317.4M in assets, $275.3M in deposits, $41.7M in equity per a third-party bank-locations search snippet; the as-of date is not stated in the snippet and these are not asserted as current.

Mobile. Android com.bankofadvance.grip (developer "MILES BANCSHARES, INC."); iOS title "Bank of Advance Mobile Banking" (App Store id 858023120). App version as reported by a Play search snippet at the time of writing was 3.30.0, not independently re-verified.

Feature surface (per the bank's own services page). View balances and transaction history; mobile remote deposit; internal and external transfers, including "Rapid Transfer" via external debit card; Zelle P2P; Bill Pay (one-time and recurring); debit-card alerts and pause / unpause; travel notices; eDocs (electronic statements); dashboard customization; 2FA via SMS, voice or authenticator; biometric or 4-digit passcode re-auth.

Open a brief on /contact.html

Last checked 2026-05-31.