Skip to content

Commit a028ed8

Browse files
Add EventNotificationHandler example (#2129)
1 parent 87b5e98 commit a028ed8

File tree

2 files changed

+108
-0
lines changed

2 files changed

+108
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
This release changes the pinned API version to `2025-12-15.preview`.
55

66
* [#2104](https://github.com/stripe/stripe-java/pull/2104) Add EventNotificationHandler
7+
* This is a new, simplified way to handle event notifications (AKA thin event webhooks). Learn more in the docs: https://docs.stripe.com/webhooks/event-notification-handlers
78
* [#2117](https://github.com/stripe/stripe-java/pull/2117) Update generated code for beta
89
* Add support for new resources `reserve.Hold`, `reserve.Plan`, and `reserve.Release`
910
* Add support for `list` and `retrieve` methods on resources `reserve.Hold` and `reserve.Release`
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package com.stripe.examples;
2+
3+
import com.stripe.StripeClient;
4+
import com.stripe.StripeEventNotificationHandler;
5+
import com.stripe.StripeEventNotificationHandler.UnhandledNotificationDetails;
6+
import com.stripe.events.V1BillingMeterErrorReportTriggeredEventNotification;
7+
import com.stripe.exception.StripeException;
8+
import com.stripe.model.billing.Meter;
9+
import com.stripe.model.v2.core.EventNotification;
10+
import com.sun.net.httpserver.HttpExchange;
11+
import com.sun.net.httpserver.HttpHandler;
12+
import com.sun.net.httpserver.HttpServer;
13+
import java.io.ByteArrayOutputStream;
14+
import java.io.IOException;
15+
import java.io.InputStream;
16+
import java.net.InetSocketAddress;
17+
import java.nio.charset.StandardCharsets;
18+
19+
/**
20+
* Receive and process event notifications (AKA thin events) like
21+
* "v1.billing.meter.error_report_triggered" using EventNotificationHandler.
22+
*
23+
* <p>In this example, we:
24+
*
25+
* <ul>
26+
* <li>write a fallback callback to handle unrecognized event notifications
27+
* <li>create a StripeClient called client
28+
* <li>Initialize an EventNotificationHandler with the client, webhook secret, and fallback
29+
* callback
30+
* <li>register a specific handler for the "v1.billing.meter.error_report_triggered" event
31+
* notification type
32+
* <li>use handler.handle() to process the received notification webhook body
33+
* </ul>
34+
*/
35+
public class EventNotificationHandlerEndpoint {
36+
private static final String API_KEY = System.getenv("STRIPE_API_KEY");
37+
private static final String WEBHOOK_SECRET = System.getenv("WEBHOOK_SECRET");
38+
39+
private static final StripeClient client = new StripeClient(API_KEY);
40+
private static final StripeEventNotificationHandler handler =
41+
client.notificationHandler(
42+
WEBHOOK_SECRET, EventNotificationHandlerEndpoint::fallbackCallback);
43+
44+
public static void main(String[] args) throws IOException {
45+
handler.onV1BillingMeterErrorReportTriggered(
46+
EventNotificationHandlerEndpoint::handleMeterErrors);
47+
48+
HttpServer server = HttpServer.create(new InetSocketAddress(4242), 0);
49+
server.createContext("/webhook", new WebhookHandler());
50+
server.setExecutor(null);
51+
server.start();
52+
}
53+
54+
private static void fallbackCallback(
55+
EventNotification notif, StripeClient client, UnhandledNotificationDetails details) {
56+
System.out.println("Received unhandled event notification type: " + notif.getType());
57+
}
58+
59+
private static void handleMeterErrors(
60+
V1BillingMeterErrorReportTriggeredEventNotification notif, StripeClient client) {
61+
Meter meter;
62+
try {
63+
meter = notif.fetchRelatedObject();
64+
} catch (StripeException e) {
65+
// TODO Auto-generated catch block
66+
e.printStackTrace();
67+
return;
68+
}
69+
System.out.println("Handling meter error for meter: " + meter.getDisplayName());
70+
}
71+
72+
static class WebhookHandler implements HttpHandler {
73+
// For Java 1.8 compatibility
74+
public static byte[] readAllBytes(InputStream inputStream) throws IOException {
75+
final int bufLen = 1024;
76+
byte[] buf = new byte[bufLen];
77+
int readLen;
78+
79+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
80+
81+
while ((readLen = inputStream.read(buf, 0, bufLen)) != -1)
82+
outputStream.write(buf, 0, readLen);
83+
84+
return outputStream.toByteArray();
85+
}
86+
87+
@Override
88+
public void handle(HttpExchange exchange) throws IOException {
89+
if ("POST".equals(exchange.getRequestMethod())) {
90+
InputStream requestBody = exchange.getRequestBody();
91+
String webhookBody = new String(readAllBytes(requestBody), StandardCharsets.UTF_8);
92+
String sigHeader = exchange.getRequestHeaders().getFirst("Stripe-Signature");
93+
94+
try {
95+
handler.handle(webhookBody, sigHeader);
96+
97+
exchange.sendResponseHeaders(200, -1);
98+
} catch (StripeException e) {
99+
exchange.sendResponseHeaders(400, -1);
100+
}
101+
} else {
102+
exchange.sendResponseHeaders(405, -1);
103+
}
104+
exchange.close();
105+
}
106+
}
107+
}

0 commit comments

Comments
 (0)