Code Review: Partial Failure in a Java Payment Method That Charges Then Records
MercorSoftware Engineer · Technical ScreenLast updated
A Java code-reading question about a payment method that charges an external provider and then inserts a database record, focused on what happens when the client fails in the middle of the call. It tests reasoning about partial failures, retries, idempotency keys, payment states, and reconciliation with the provider.
The interviewer shows the following Java service, which charges a user through an external payment provider and then records the payment in a database. The question: what happens if the client fails in the middle of the call, and how would you change the code? There is no coding in this round; explain the problems and your fix.
import java.util.Map;
public class PaymentService {
private final PaymentProvider provider;
private final Database db;
public Map<String, String> createPayment(String userId, int amountCents) {
// calls external provider (e.g., Stripe-like)
String chargeId = provider.charge(userId, amountCents);
db.insert("payments", Map.of(
"user_id", userId,
"amount", amountCents,
"charge_id", chargeId
));
return Map.of("status", "ok", "charge_id", chargeId);
}
}
Assume provider.charge makes a network call that charges the user and returns the provider's charge ID, throwing an exception on failure, and that db.insert writes one row.
Clarifying Questions
- Who is "the client" here: the caller of
createPayment(an app or another service that retries on timeout), or this service's own connection to the provider? - Does the provider accept an idempotency key, or let us look up a charge by a reference we supply?
- What should the caller be told when the outcome of a charge is unknown?
- Can the caller send a unique ID for each purchase attempt?
Hints
Hint 1
Walk the timeline: List each point at which a process or a network connection could fail during this method, and write down the state of the provider and of the database at each point.
Hint 2
Retries will happen: Assume the caller times out and sends the same request again. Decide what would let the system recognize the second request as the same purchase.
Follow-up questions
- The provider call times out and you do not know whether the user was charged. What does your code do, and what does the caller see?
- The provider does not support idempotency keys. How do you prevent double charges?
- How would you find and repair payments that were charged at the provider but never recorded?
- Why not simply wrap the provider call and the insert in one database transaction?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.