Payment engineering interviews focus on five areas: webhook reliability (how do you guarantee you never miss a payment notification), idempotency (how do you prevent double charges), reconciliation (how do you ensure your records match the payment provider), error handling (what happens when the payment gateway is down), and system design (design a payment service that handles X transactions per second). Interviewers want to see that you understand the financial consequences of bugs, not just the technical implementation.
Payment engineering interviews are different from general software engineering interviews. The technical bar is similar, but the priorities are different.
In a general backend interview, you might be asked to optimize a query, design a social media feed, or implement a sorting algorithm. The focus is on efficiency and scalability.
In a payment engineering interview, the focus is on correctness, reliability, and financial safety. Interviewers want to know: will your code lose money? Will it double-charge a customer? Will it miss a payment? Will it produce incorrect financial records?
They are looking for three things:
Question: "How do you ensure you never miss a webhook from a payment provider?"
Strong answer: "First, the webhook handler must return a 200 response immediately after receiving the event, before doing any heavy processing. This prevents timeouts that cause the provider to retry and potentially send duplicates. The actual processing (updating order status, sending notifications) happens asynchronously after acknowledging receipt.
Second, I implement a verification step that periodically polls the payment provider's API to check for transactions that might have been missed. This is a safety net in case a webhook is lost due to server downtime or network issues.
Third, I verify every webhook signature using the secret key to ensure it genuinely came from the payment provider and not from a malicious actor."
Question: "What happens if you receive the same webhook twice?"
Strong answer: "I use the transaction reference as an idempotency key. Before processing a webhook, I check if a transaction with that reference has already been processed. If it has, I return 200 without doing anything. This is implemented at the database level using a unique constraint on the transaction reference, so even if two webhooks arrive simultaneously, only one will be processed."
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
Question: "Explain idempotency in the context of payments. Why does it matter?"
Strong answer: "An idempotent operation produces the same result whether you execute it once or multiple times. In payments, this means charging a customer once should produce exactly one charge, even if the request is sent multiple times due to network retries, user double-clicks, or webhook replays.
Without idempotency, a network timeout on a payment request might cause the client to retry, resulting in two charges. The customer pays twice for one product. This is the most common and most damaging payment bug.
I implement idempotency by generating a unique idempotency key for each payment intent, storing it before initiating the charge, and checking for it before creating any new charge. If a charge with that key already exists, I return the existing result instead of creating a new charge."
Question: "A customer clicks the pay button and the page hangs. They click again. How do you prevent a double charge?"
Strong answer: "Multiple layers of protection. On the frontend, I disable the button after the first click and show a loading indicator. On the backend, I generate a unique transaction reference when the checkout session is created and use it as an idempotency key. If the backend receives two requests with the same reference, the second one returns the result of the first without creating a new transaction. At the database level, a unique constraint on the transaction reference prevents duplicate records."
Question: "How would you build a reconciliation system for Paystack transactions?"
Strong answer: "Reconciliation means comparing what my system recorded with what Paystack recorded, and identifying discrepancies. I would build it in three steps:
First, a daily job that fetches all transactions from the Paystack API for the previous day and compares them with the transactions in my database. I check for three types of discrepancies: transactions that exist in Paystack but not in my system (missed webhooks), transactions in my system marked as successful but not in Paystack (potential data corruption), and amount mismatches.
Second, a settlement reconciliation that compares Paystack settlement amounts with actual bank deposits. Each settlement should match a bank deposit. Mismatches indicate processing issues.
Third, an alert system that notifies the operations team when discrepancies are found, categorized by severity. A missed transaction needs immediate attention. A small amount discrepancy might be a rounding issue that can be investigated during business hours."
Question: "Your reconciliation report shows 5 transactions in Paystack that are not in your database. What happened and how do you fix it?"
Strong answer: "The most likely cause is missed webhooks. The payment was successful on Paystack's side, but my system never received the notification. This could be due to server downtime, a deployment during the webhook delivery, or a network issue. To fix it: first, process the missing transactions by fetching their details from the Paystack API and updating my database. Second, fulfil any orders that should have been fulfilled. Third, investigate why the webhooks were missed and fix the root cause to prevent recurrence."
Question: "The Paystack API is returning 500 errors. What do you do?"
Strong answer: "First, I check Paystack's status page to confirm whether there is an ongoing incident. If so, I note the expected resolution time.
For my system, I have three response strategies depending on the context. For new payment initiations, I show the user a clear message: 'Our payment provider is experiencing issues. Please try again in a few minutes or use an alternative payment method.' For webhook processing, my system automatically retries failed webhook processing with exponential backoff. For ongoing operations (like scheduled subscription charges), I queue the operations and process them when the API recovers, with alerting so the operations team is aware.
I would not attempt to build a fallback payment provider switch in the moment of the outage. That is a system design decision that should be made and tested in advance, not improvised during an incident."
Question: "A payment succeeds but your database write fails. What state is the system in and how do you recover?"
Strong answer: "The customer has been charged but my system does not know about it. This is the worst type of payment bug. My webhook handler will eventually receive the success notification and can recover, but there is a window where the customer has paid and sees no confirmation.
Prevention is better than recovery: I use database transactions to ensure the payment initiation and the database record creation are atomic. If the database write fails, the transaction is rolled back before the payment is initiated. The webhook handler serves as a second chance: even if the synchronous flow fails, the asynchronous webhook catches the successful payment and updates the database."
Question: "Design a payment service that processes online payments for an e-commerce platform."
This is a broad question. A strong answer covers these components:
For a deeper dive, see our full system design walkthrough.
"Tell me about a time a payment bug affected real users."
If you have real-world experience, share a specific incident. What happened, how you discovered it, how you fixed it, and what you did to prevent it from happening again. Be honest about mistakes. Interviewers respect candour.
If you do not have production experience, describe a scenario from a personal project or a test environment. "During testing, I discovered that my webhook handler was not checking the transaction amount against the order amount. A malicious user could theoretically pay a different amount and the system would accept it. I fixed it by adding amount verification to the webhook handler."
"How do you decide which payment gateway to use for a project?"
Cover these factors: country coverage, supported payment methods, API quality and documentation, pricing, settlement speed, reliability track record, and developer ecosystem. Mention that you have worked with specific gateways and can compare them from experience.
"How do you stay current with payment technology in Africa?"
Mention specific resources: Paystack and Flutterwave engineering blogs, fintech newsletters, developer communities, and conferences. Show that you actively follow the space, not just work in it.
This article is part of the getting paid to build Paystack integrations series.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course