Stripe Payment Integration: Error Handling, Idempotent Retries and Payment Storage
Company: Mercor
Role: Software Engineer
Category: Software Engineering Fundamentals
Difficulty: medium
Interview Round: Technical Screen
Your backend service needs to start charging customers through Stripe, a third-party payments API. The interviewer asks you to add a Stripe integration, then probes how you would make it robust. Assume each charge pays for one order that already exists in your system, for a known amount and currency.
### Clarifying Questions
- Is the payment completed while the user waits on the checkout page, or can it finish asynchronously?
- Do card details ever reach your servers, or does the provider's client-side form collect them?
- Are refunds and recurring payments in scope, or only one-time charges?
- What should the user see while the outcome of a payment is still unknown?
### Part 1 — Error handling
Walk through what can go wrong when your service calls Stripe to charge a customer, and how your code handles each case, so that a customer is never charged twice and a successful payment is never lost.
```hint Know versus not know
Separate the failures in which you know the charge did not happen from the failures in which you cannot tell. The second kind drives the design.
```
#### What This Part Should Cover
- Which failures are safe to retry and which are not
- How retries are made safe when the outcome of a request is unknown
- The retry policy, and what happens when retries are exhausted
- How outcomes that arrive later, or out of order, are applied
### Part 2 — What to store, and in which database
What payment data must your service persist, and which database would you choose for it? Justify the choice in terms of ACID transactions and availability.
```hint Think a month ahead
List the questions that support, accounting and your own retry logic will need to answer about a payment weeks later. Then decide which records must change together, atomically.
```
#### What This Part Should Cover
- The payment records and fields, how they link to your orders and to the provider's identifiers, and what must never be stored
- Database constraints that enforce idempotency and valid state changes
- A justified database choice, with a clear position on consistency versus availability for payment data
### What a Strong Answer Covers
- No double charge and no lost payment across timeouts, retries, crashes and duplicate notifications
- A payment state machine that is persisted before and after every external call
- A concrete schema in which unique keys and conditional updates enforce correctness
- The trade-off between strong consistency and availability, argued for payment data specifically
- Reconciliation with the provider's records, and the metrics and alerts that catch drift
### Follow-up Questions
- Your service crashes after Stripe confirms the charge but before you save the result. How does the system recover?
- How would you support full and partial refunds with the same guarantees?
- The payments database is down. Do you reject checkouts, or accept them and charge later? What are the risks of each?
Overview: Explain how to add a Stripe payment integration to a backend service: how to handle errors and retries without charging a customer twice, what payment data to store, and which database to use given ACID and availability needs. Tests idempotency, failure handling, and data modeling for payments.
Read the full Mercor Software Engineer interview experience this question came from