-
Notifications
You must be signed in to change notification settings - Fork 400
Expand file tree
/
Copy pathEventNotificationWebhookHandler.java
More file actions
115 lines (98 loc) · 4.71 KB
/
Copy pathEventNotificationWebhookHandler.java
File metadata and controls
115 lines (98 loc) · 4.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package com.stripe.examples;
import com.stripe.StripeClient;
import com.stripe.events.UnknownEventNotification;
import com.stripe.events.V1BillingMeterErrorReportTriggeredEvent;
import com.stripe.events.V1BillingMeterErrorReportTriggeredEventNotification;
import com.stripe.exception.StripeException;
import com.stripe.model.billing.Meter;
import com.stripe.model.v2.core.EventNotification;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
/**
* Receive and process EventNotifications like the v1.billing.meter.error_report_triggered event.
*
* <p>In this example, we:
*
* <ul>
* <li>use parseEventNotification to parse the received event notification webhook body
* <li>call StripeClient.v2.core.events.retrieve to retrieve the full event object
* <li>if it is a V1BillingMeterErrorReportTriggeredEvent event type, call fetchRelatedObject to
* retrieve the Billing Meter object associated with the event.
* </ul>
*/
public class EventNotificationWebhookHandler {
private static final String API_KEY = System.getenv("STRIPE_API_KEY");
private static final String WEBHOOK_SECRET = System.getenv("WEBHOOK_SECRET");
private static final StripeClient client = new StripeClient(API_KEY);
public static void main(String[] args) throws IOException {
HttpServer server = HttpServer.create(new InetSocketAddress(4242), 0);
server.createContext("/webhook", new WebhookHandler());
server.setExecutor(null);
server.start();
}
static class WebhookHandler implements HttpHandler {
// For Java 1.8 compatibility
public static byte[] readAllBytes(InputStream inputStream) throws IOException {
final int bufLen = 1024;
byte[] buf = new byte[bufLen];
int readLen;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
while ((readLen = inputStream.read(buf, 0, bufLen)) != -1)
outputStream.write(buf, 0, readLen);
return outputStream.toByteArray();
}
@Override
public void handle(HttpExchange exchange) throws IOException {
if ("POST".equals(exchange.getRequestMethod())) {
InputStream requestBody = exchange.getRequestBody();
String webhookBody = new String(readAllBytes(requestBody), StandardCharsets.UTF_8);
String sigHeader = exchange.getRequestHeaders().getFirst("Stripe-Signature");
try {
EventNotification notif =
client.parseEventNotification(webhookBody, sigHeader, WEBHOOK_SECRET);
if (notif instanceof V1BillingMeterErrorReportTriggeredEventNotification) {
V1BillingMeterErrorReportTriggeredEventNotification eventNotification =
(V1BillingMeterErrorReportTriggeredEventNotification) notif;
// there's basic info about the related object in the notification
System.out.println(
"Meter w/ id " + eventNotification.getRelatedObject().getId() + " had a problem");
// or you can fetch the full object form the API for more details
Meter meter = eventNotification.fetchRelatedObject();
StringBuilder sb = new StringBuilder();
sb.append("Meter ")
.append(meter.getDisplayName())
.append(" (")
.append(meter.getId())
.append(") had a problem");
System.out.println(sb.toString());
// And you can always fetch the full event:
V1BillingMeterErrorReportTriggeredEvent event = eventNotification.fetchEvent();
System.out.println("More info: " + event.getData().getDeveloperMessageSummary());
} else if (notif instanceof UnknownEventNotification) {
// Events that were introduced after this SDK version release are
// represented as `UnknownEventNotification`s.
// They're valid, the SDK just doesn't have corresponding classes for them.
// You must match on the "type" property instead.
UnknownEventNotification unknownEvent = (UnknownEventNotification) notif;
if (unknownEvent.getType().equals("some.new.event")) {
// you can still `.fetchEvent()` and `.fetchRelatedObject()`, but the latter may
// return `null` if that event type doesn't have a related object.
}
}
exchange.sendResponseHeaders(200, -1);
} catch (StripeException e) {
exchange.sendResponseHeaders(400, -1);
}
} else {
exchange.sendResponseHeaders(405, -1);
}
exchange.close();
}
}
}