bankbuddy.
Explore demoConsole

Bank transaction APIs in South Africa: an integration checklist.

To choose a bank transaction API in South Africa, check which banks and account types work today, how fresh the data is, whether transaction IDs stay stable, how customers grant and withdraw access, and what you are billed for. Test failure cases before committing. Payment APIs and transaction-data APIs are different products.

For a South African software team, start from a concrete workflow: whose accounts need to connect, which data your application needs, and how quickly it needs to react. Turn those answers into acceptance tests, then ask every provider to pass the same tests.

Start with the capability you need

Reading transactions, verifying an account and initiating a payment are separate capabilities. An API that lets a customer pay a merchant does not, by itself, give you that customer's transaction history. If you are importing transactions into a ledger, you need read access to history and balances, not payment initiation.

Ask the provider to demonstrate your exact workflow. Can an authorised user connect a business account, retrieve earlier transactions and receive later updates? Which parts of the demonstration run in a sandbox, and which run in production?

Write the answer down as a test, not as a general promise of “bank connectivity”.

Check each bank and account product

A row of bank logos does not tell you which accounts can connect. Support often varies by account product: a bank may work for personal cheque accounts but not business accounts, or for transactions but not credit cards. Ask for coverage as a dated table, one row per bank and account type:

BankAccount typeEnvironmentStatusKnown limits
Bank ABusiness chequeProductionAvailable90 days of history
Bank ACredit cardProductionNot supported—
Bank BBusiness chequeSandbox onlyPilotNo balances yet

The table above is an illustration, not a statement about any real bank. Its value is that “available”, “pilot” and “planned” are kept apart. A roadmap is not coverage.

Developers often search bank by bank, for example for an “FNB API” or a “Capitec API”. Some banks run their own developer programmes. Check who can join them and whether they cover your customers' accounts, or only accounts held by your own business. A single integration that reaches several banks is a different product from one bank's API.

Finally, decide what happens when an account cannot connect. Your application needs a clear message and a fallback, such as an authorised statement upload. Don't promise customers universal coverage until you have checked your own list of banks and account types.

Define what “fresh” means

Separate three times: when the activity happens, when the bank makes it available, and when your application receives it. A webhook can notify you quickly once the provider sees a transaction. That doesn't make the underlying bank data instant.

Ask for documented refresh behaviour and timestamps. Ask how pending, posted, corrected and reversed records are handled. Store the time your system first saw each update alongside the source dates, so you can explain a delay without rewriting the transaction date.

A daily schedule is not a promise of daily data. A scheduled refresh can run, fail, or succeed without finding anything new. Your users need to see the difference.

Test identifiers, balances and history

Get sample data and examine every field you will rely on: account identifier, transaction identifier, amount, currency, description, status and dates. Confirm which fields stay the same across refreshes and which can change.

Here is why it matters. An account has two separate R150 purchases at the same shop on the same day. If your duplicate check uses only date, amount and description, one real purchase disappears. A documented, stable transaction ID avoids that guess.

Balances need their own question. A feed can return transactions without a balance, and a current balance is different from a running balance after each transaction. Don't try to rebuild an authoritative balance by adding up a partial history.

Also check:

  • how far back history goes on the first pull, and whether that varies by bank;
  • pagination, and recovery when a fetch is interrupted;
  • how amounts are represented. Use exact values, and don't guess units from a sample.

Plan to connect, re-approve and disconnect

Map the whole life of a connection before you build the first screen:

  1. Connect. How does the account holder authorise access, and where does that happen? With hosted linking, the customer authenticates on a page your application doesn't control. Find out what your app receives when they finish, cancel or fail.
  2. Stay connected. How long can updates continue unattended before the customer must approve again? Does that differ by bank?
  3. Disconnect. How does a customer stop future refreshes and revoke access? What happens to stored credentials or tokens, and to data already collected?

Each stage needs a visible state in your app, so customers can tell an account with no new activity from a connection that needs attention. Accounting practices that connect their clients' accounts will ask these questions too, because they answer to those clients.

Find out what you are billed for

Bank-data pricing is easy to misread because providers count different things. Before comparing prices, find out which unit applies:

  • Linked account: a fee per connected account, often monthly.
  • Refresh or request: a charge each time data is fetched, including fetches that find nothing new.
  • Transaction: a charge per record returned.
  • Setup and minimums: onboarding fees, monthly floors or contract terms.

Then model your real usage. As a worked example, 200 businesses with 2 accounts each, refreshed daily, means 400 linked accounts and about 12,000 refreshes in a 30-day month. Those figures give very different bills under per-account and per-refresh pricing. Also ask whether pulling the same history again is charged twice.

Test failure, not just success

A sandbox proves your code can call the API. It doesn't prove production coverage, customer authorisation, real-world freshness or recovery. Treat the move to production as its own checklist.

For ongoing updates, test duplicate notifications, missed deliveries and events arriving out of order. Run an outage-and-recovery exercise as well as a successful connection. When something fails, find out what the provider's support needs from you and how quickly they respond.

If periodic uploads would meet the need, compare that option too. Our guide to bank feeds versus CSV imports covers the trade-offs.

Questions to send each provider

Send every provider the same list and compare the written answers:

  • Which banks and account types are available in production today, and as of what date?
  • How much history is returned on first connection, per bank?
  • How often can data refresh, and how long until a customer must re-approve?
  • Are transaction IDs stable across refreshes and reconnections?
  • Are current balances included? Running balances?
  • What does my application receive when linking succeeds, is cancelled or fails?
  • How does a customer disconnect, and what happens to their stored data?
  • What exactly is billable: linked accounts, refreshes, transactions or setup?
  • Where is data stored, for how long, and who are the subprocessors?
  • What separates sandbox testing from production approval?
  • How do I report a failed connection, and what response time should I expect?

Where bankbuddy stands. bankbuddy is building a bank-transaction feed and developer console. Today the interactive demo runs on sample transactions. Live bank connections and production webhook delivery are not available yet. Use the demo to judge the workflow, not as evidence of bank coverage.

Frequently asked questions

Does a payment API also provide bank transaction history?

Not necessarily. Payment initiation and access to account history are different capabilities. Ask the provider to demonstrate the exact data workflow you need: authorisation, history retrieval and later updates. Don't assume access to a customer's other transactions because an API can initiate payments.

Are bank transaction feeds always real time?

No. Update speed depends on when the bank makes activity available and how the provider retrieves and delivers it. A fast webhook does not remove upstream delays. Ask for documented refresh behaviour and timestamps, then test whether the delay you actually observe suits your application.

If a provider lists my bank, will all my customers' accounts connect?

Not always. Support can depend on the account type, such as business versus personal accounts or credit cards, and on whether the bank is in production or still in a pilot. Ask for coverage per bank and account type, with a date, and test your own accounts.

Which South African banks does bankbuddy support?

None in production yet. bankbuddy's public demo uses sample transactions, and live bank connections are still in development. Use the demo to assess the intended interface. Before planning a production integration, check bankbuddy's current status and supported account types.

Examples, figures and bank names in this guide are illustrations. They are not statements about any provider's coverage, pricing or legal status.