How we ensure a fast response time for card authorization

Image for post
Image for post

Service design at Qonto

At Qonto, we provide a bank account and credit cards to SMEs and entrepreneurs. Having a world-class card authorization system is a top priority: we face tens of thousands of card transactions every day and growing!

TL;DR

Your Qonto card is crazy fast and rock solid.

The recipe: from needs to plan

The ingredients

Starting from a blank page. What do we need? What are the problems to solve? Where could our new Core Banking System (CBS) bring something better to the table?

Image for post
Image for post
Image for post
Image for post
Image for post
Image for post
  • Be accurate: We must not allow any false positive nor false negative authorization. When you have money, you can use it. When you don’t, you can’t. This might seem obvious, but better said than not.
  • Be maintainable from the start: What we build must last long and be easily re-usable.
  • Ship on time. Keeping that in mind helps us simplify things.

The recipe

We have those starting elements, the ingredients for our CBS authorization service. Let’s plan out the recipe to put everything together.

  • An authorization handler: We must be able to answer any authorization request.
  1. An ISO8583 decoder and encoder,
  2. A client for the authorization service,
Image for post
Image for post
  1. A database (DB) client that will contain and execute DB queries,
  2. An error handler that would provide feedback on authorization choices.
Image for post
Image for post

Cooking the starter: parsing ISO8583

A complex format

Let’s follow up on the credit example from earlier: a credit request arrives at Qonto. We receive an ISO8583 TCP frame looking very much like this:

ISO85853 TCP Packet

Being fast

Here is the actual challenge of the protocol handler: parse this messy format and transform it into intelligible JSON. And if possible, read it only once: because we need all information from the frame, O(n) is the optimal parsing complexity.

Field structures
Message structure
Algorithm pseudo-code

Handling quartets

Given that the output of the protocol handler is pure JSON (a string), we decide to drop the quartet to ints tuple conversion (we would have done it with a few bitwise operations). Instead, we create three functions:

  • One from a byte of text (in EBCDIC) to an ASCII character;
  • A nop converter that only copies the byte as is.
Conversion maps

The main dish: How we use Postgres to its fullest capabilities

Treating your card payment does not end with parsing the card network request! Let’s dig into the authorization service: how we decide to accept your payments.

Designing the database

Let’s write down all the information we need to store:

  • Card information and options
  • Balance
  • Requested amount and balance delta (as partial authorizations might be allowed)
  • Insertion, validity and authorization date
  • Operation type
Table create

Forging fast queries

With this one table, the next focus for each payload received by the authorization service is to only trigger one query execution. This query has to:

  1. Get the account status,
  2. Get the rolling limits of the card on the last month,
  3. Get the last status of the card as well as its options,
  4. Get the possible previous transaction (if multiple linked transactions such as in the first case at a fuel dispenser),
  5. Compute authorizable amount (the balance delta),
  6. Decide whether to authorize, partially authorize or refuse the transaction,
  7. Insert a new transaction or (in case of idempotency conflict) return the previous transaction.
Account CTE
Last month CTE
Idempotency CTEs

The dessert: what we learned, how to improve

Be fast: Not everything has to be improved

There are a few indicators to monitor in order to be fast and in time:

  • How much resource does it consume?
  • How long does it take us to write it?
  • At which cost will we maintain it in the future?

Software metrics

The two first ones are easy: using the go tools, running a benchmark and profiling an application is straightforward.

Team metrics

When you develop, you easily lose yourself in small details. To stay focused on our objectives, we use several good practices:

  • Use visual feedback: with Kanban (看板), we constantly keep track of what is done, on review, in progress, or in backlog. Discussing it on a daily basis helps us select the right priorities.
  • Continuous peer review: having split the tasks into small units, we are able to ship many times a day. Each time a developer creates a merge request, they look at those still open, reviewing what the others have done.

Ready to serve? There is always room to improve

Can we say “the end?” The system is already in use by beta testers. It handles all of our expected use-cases. It interfaces with the card network seamlessly. It is fast. It is accurate. It is resilient. It is a strong ground for all payment methods you throw at it.

The Qonto Way

Learning while scaling

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store