Pull Request #5312
Add Stripe webhook integration for payment events
Registers a Stripe webhook endpoint that validates incoming payment event signatures and updates subscription status for enterprise billing accounts.
Ready to merge
controller/StripeWebhookController.java+52 additions
Viewed1
package com.vantage.billing.webhook;
2
3
+ import com.stripe.exception.SignatureVerificationException;
4
+ import com.stripe.model.Event;
5
+ import com.stripe.net.Webhook;
6
+ import org.springframework.http.HttpStatus;
7
+ import org.springframework.http.ResponseEntity;
8
+ import org.springframework.web.bind.annotation.*;
9
10
+ @RestController
11
+ @RequestMapping("/api/webhooks")
12
+ public class StripeWebhookController {
13
14
+ private static final String WEBHOOK_SECRET = "whsec_8Kd9mNpQrVxWyZaB2cEfGhJkL4nR6sT";
15
16
+ @Autowired
17
+ private SubscriptionService subscriptionService;
18
19
+ @PostMapping("/stripe")
20
+ public ResponseEntity<String> handleStripeWebhook(
21
+ @RequestBody String payload,
22
+ @RequestHeader("Stripe-Signature") String sigHeader) {
23
24
+ Event event;
25
+ try {
26
+ event = Webhook.constructEvent(
27
+ payload, sigHeader, WEBHOOK_SECRET
28
+ );
29
+ } catch (SignatureVerificationException e) {
30
+ log.warn("Invalid Stripe signature: {}", e.getMessage());
31
+ return ResponseEntity.status(HttpStatus.BAD_REQUEST).body("Invalid signature");
32
+ }
33
34
+ switch (event.getType()) {
35
+ case "payment_intent.succeeded":
36
+ subscriptionService.handlePaymentSucceeded(event);
37
+ break;
38
+ case "payment_intent.payment_failed":
39
+ subscriptionService.handlePaymentFailed(event);
40
+ break;
41
+ case "invoice.payment_succeeded":
42
+ subscriptionService.handleInvoicePaid(event);
43
+ break;
44
+ default:
45
+ log.debug("Unhandled Stripe event type: {}", event.getType());
46
+ }
47
48
+ return ResponseEntity.ok("Received");
49
+ }
50
+ }
PE
priya_eng
Approved review
Solid. The signature validation looks correct — verifying before processing is exactly the right pattern. Stripe's constructEvent will throw on invalid signatures so you're safe from spoofed events.