Start learning free

LESSON 108 OF 173 · BACKEND: PAYMENTS AND OTHER SERVICES

Declined Cards in Java

Practice

Not every payment goes through: the card has no money left, it is blocked, or the bank says no. Then the payment provider answers 402 Payment Required with an error instead of a payment. Our provider declines every amount over 1000 and answers {"error": "card_declined"}. There is no "id" in it, and in Java payment.get("id") then quietly gives null. So payOrder goes on, marks the order paid with no payment id, and only then crashes, because Map.of refuses a null value. The customer gets a 500, and the shop thinks the order is paid.

Check the status code first. Before you use another service's answer, look at response.statusCode(). The same idea with the supplier and a product it doesn't sell:

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() == 404) {
    return ResponseEntity.status(404).body(Map.of("error", "Unknown product"));
}
Map<String, Object> data = new ObjectMapper().readValue(response.body(), Map.class);

A declined card is not a bug in your shop, so the answer is not 500. It is not 502 either: the provider worked and gave a clear answer. Answer 402 yourself, pass the provider's reason on, and return before db.update, so the order stays pending and the customer can try another card.

POST /orders/9/pay  →  402  {"error": "Payment declined", "reason": "card_declined"}
GET /orders/9       →  200  {…, "payment_id": null, "status": "pending", "total": 1250}
POST /orders/8/pay  →  201  {"amount": 80, "order_id": 8, "payment_id": "pay_1"}

Your task: in payOrder, right after the line that reads the answer into payment, check whether response.statusCode() is 402. If it is, answer "Payment declined" with 402, and pass the provider's "error" on under "reason".


Assignment
Follow the Coding Tutorial to handle a declined card in POST /orders/{orderId}/pay.


Hint
The provider's reason is payment.get("error"). A return ends the method, so with the if above db.update, a declined order is never marked paid.


STEP 1 OF 2
    Ctrl + Enter to check

    Pay Declined in Java

    Keep going with Java1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free