McTaba Labs logo
Bonaventure OgetoBy Bonaventure Ogeto|

Accept Payments with Paystack in Spring Boot

To accept Paystack payments in Spring Boot, create a PaystackService that uses RestTemplate to call the Paystack API. Build a controller with endpoints for initialization and verification. Store your secret key in application.properties and inject it with @Value.

Setup

Add your key to application.properties:

paystack.secret-key=sk_test_xxxxxxxxxxxxxxxxxxxxx

PaystackService

// src/main/java/com/example/payment/PaystackService.java
@Service
public class PaystackService {
    @Value("${paystack.secret-key}")
    private String secretKey;

    private final RestTemplate restTemplate = new RestTemplate();

    public Map<String, Object> initializeTransaction(String email, int amountKobo, String reference, String callbackUrl) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + secretKey);
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, Object> body = Map.of(
            "email", email,
            "amount", amountKobo,
            "reference", reference,
            "callback_url", callbackUrl
        );

        HttpEntity<Map<String, Object>> request = new HttpEntity<>(body, headers);
        ResponseEntity<Map> response = restTemplate.postForEntity(
            "https://api.paystack.co/transaction/initialize", request, Map.class);

        return response.getBody();
    }

    public Map<String, Object> verifyTransaction(String reference) {
        HttpHeaders headers = new HttpHeaders();
        headers.set("Authorization", "Bearer " + secretKey);

        HttpEntity<?> request = new HttpEntity<>(headers);
        ResponseEntity<Map> response = restTemplate.exchange(
            "https://api.paystack.co/transaction/verify/" + reference,
            HttpMethod.GET, request, Map.class);

        return response.getBody();
    }
}

Get weekly developer tips

Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.

No spam. Unsubscribe anytime.

Payment Controller

@RestController
@RequestMapping("/api/payment")
public class PaymentController {
    @Autowired
    private PaystackService paystackService;

    @PostMapping("/initialize")
    public ResponseEntity<?> initialize(@RequestBody Map<String, Object> payload) {
        String email = (String) payload.get("email");
        double amount = ((Number) payload.get("amount")).doubleValue();
        String reference = "order_" + UUID.randomUUID().toString().substring(0, 12);

        Map<String, Object> result = paystackService.initializeTransaction(
            email, (int)(amount * 100), reference, "http://localhost:8080/api/payment/callback");

        if (Boolean.TRUE.equals(result.get("status"))) {
            Map<String, Object> data = (Map<String, Object>) result.get("data");
            return ResponseEntity.ok(Map.of(
                "authorization_url", data.get("authorization_url"),
                "reference", data.get("reference")
            ));
        }
        return ResponseEntity.badRequest().body(Map.of("error", result.get("message")));
    }

    @GetMapping("/callback")
    public ResponseEntity<?> callback(@RequestParam String reference) {
        Map<String, Object> result = paystackService.verifyTransaction(reference);

        if (Boolean.TRUE.equals(result.get("status"))) {
            Map<String, Object> data = (Map<String, Object>) result.get("data");
            if ("success".equals(data.get("status"))) {
                // TODO: Verify amount, mark order as paid
                return ResponseEntity.ok(Map.of("success", true));
            }
        }
        return ResponseEntity.badRequest().body(Map.of("success", false));
    }
}

Production Checklist

  1. Use profiles. Spring profiles for dev/prod keys: application-dev.properties vs application-prod.properties.
  2. Set up webhooks. See Handle Paystack Webhooks in Spring Boot.
  3. HTTPS. Required for callbacks and webhooks.
  4. Validate amounts. Check against your JPA entity, not request params.

Ship Payments Faster

Key Takeaways

  • Spring Boot RestTemplate or WebClient handles all Paystack REST API calls.
  • Store your Paystack secret key in application.properties. Inject with @Value.
  • Use @Service for the PaystackService and @RestController for endpoints.
  • Amounts are in kobo (NGN), pesewas (GHS), or cents. Multiply by 100.
  • Always verify transactions server-side after the redirect callback.
  • Spring Boot dependency injection makes PaystackService easily testable.

Frequently Asked Questions

Should I use RestTemplate or WebClient?
RestTemplate is simpler and works for synchronous calls. WebClient is non-blocking and preferred for reactive applications. Both work with Paystack.
Do I need a Paystack Java library?
No. RestTemplate handles all REST API calls. The Paystack API is a standard REST API that works with any HTTP client.
How do I handle CSRF for webhooks?
If using Spring Security, disable CSRF for the webhook endpoint. Add a security configuration that permits the webhook URL without CSRF.

Learn Paystack Integration

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

Not ready? Create Free Account