diff --git a/src/main/java/com/stripe/examples/NewExample.java b/src/main/java/com/stripe/examples/ExampleTemplate.java similarity index 51% rename from src/main/java/com/stripe/examples/NewExample.java rename to src/main/java/com/stripe/examples/ExampleTemplate.java index 908307b1601..b014e775f0b 100644 --- a/src/main/java/com/stripe/examples/NewExample.java +++ b/src/main/java/com/stripe/examples/ExampleTemplate.java @@ -1,17 +1,27 @@ package com.stripe.examples; /** - * To create a new example, clone this file and implement your example. + * This is a template for defining new examples. It is not intended to be used directly. * - *

To run from VS Code: 1. make sure the recommended extensions are installed 2. right click on - * your new file in the Explorer 3. click Run Java or Debug Java 4. witness greatness. + *

describe what this example does + * + *

In this example, we: + * + *

+ * + *

describe assumptions about the user's stripe account, environment, or configuration; or things + * to watch out for when running */ -public class NewExample { +public class ExampleTemplate { @SuppressWarnings("unused") private String apiKey; - public NewExample(String apiKey) { + public ExampleTemplate(String apiKey) { this.apiKey = apiKey; } @@ -30,7 +40,7 @@ public void doSomethingGreat() { public static void main(String[] args) { String apiKey = "{{API_KEY}}"; - NewExample example = new NewExample(apiKey); + ExampleTemplate example = new ExampleTemplate(apiKey); example.doSomethingGreat(); } } diff --git a/src/main/java/com/stripe/examples/MeterEventManager.java b/src/main/java/com/stripe/examples/MeterEventStream.java similarity index 73% rename from src/main/java/com/stripe/examples/MeterEventManager.java rename to src/main/java/com/stripe/examples/MeterEventStream.java index 9f9e142bf33..8fab8e575dd 100644 --- a/src/main/java/com/stripe/examples/MeterEventManager.java +++ b/src/main/java/com/stripe/examples/MeterEventStream.java @@ -5,12 +5,26 @@ import com.stripe.param.v2.billing.MeterEventStreamCreateParams; import java.time.Instant; -public class MeterEventManager { +/** + * Use the high-throughput meter event stream API to report create billing meter events. + * + *

In this example, we: + * + *

+ * + *

This example expects a billing meter with an event_name of 'alpaca_ai_tokens'. If you have a + * different meter event name, you can change it before running this example. + */ +public class MeterEventStream { private String apiKey; private MeterEventSession meterEventSession; - public MeterEventManager(String apiKey) { + public MeterEventStream(String apiKey) { this.apiKey = apiKey; } @@ -55,7 +69,7 @@ public static void main(String[] args) { String apiKey = "{{API_KEY}}"; String customerId = "{{CUSTOMER_ID}}"; // Replace with actual customer ID - MeterEventManager manager = new MeterEventManager(apiKey); + MeterEventStream manager = new MeterEventStream(apiKey); manager.sendMeterEvent("alpaca_ai_tokens", customerId, "28"); } } diff --git a/src/main/java/com/stripe/examples/StripeWebhookHandler.java b/src/main/java/com/stripe/examples/StripeWebhookHandler.java deleted file mode 100644 index bf91afd1e9e..00000000000 --- a/src/main/java/com/stripe/examples/StripeWebhookHandler.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.stripe.examples; - -public class StripeWebhookHandler { - // 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 { - // @Override - // public void handle(HttpExchange exchange) throws IOException { - // if ("POST".equals(exchange.getRequestMethod())) { - // InputStream requestBody = exchange.getRequestBody(); - // String webhookBody = new String(requestBody.readAllBytes(), StandardCharsets.UTF_8); - // String sigHeader = exchange.getRequestHeaders().getFirst("Stripe-Signature"); - - // try { - // ThinEvent thinEvent = client.parseThinEvent(webhookBody, sigHeader, WEBHOOK_SECRET); - - // // Fetch the event data to understand the failure - // Event baseEvent = client.v2().core().events().retrieve(thinEvent.getId()); - // if (baseEvent instanceof V1BillingMeterErrorReportTriggeredEvent) { - // V1BillingMeterErrorReportTriggeredEvent event = - // (V1BillingMeterErrorReportTriggeredEvent) baseEvent; - // Meter meter = event.fetchRelatedObject(); - - // String meterId = meter.getId(); - // System.out.println(meterId); - - // // Record the failures and alert your team - // // Add your logic here - // } - - // exchange.sendResponseHeaders(200, -1); - // } catch (StripeException e) { - // exchange.sendResponseHeaders(400, -1); - // } - // } else { - // exchange.sendResponseHeaders(405, -1); - // } - // exchange.close(); - // } - // } -} diff --git a/src/main/java/com/stripe/examples/ThinEventWebhookHandler.java b/src/main/java/com/stripe/examples/ThinEventWebhookHandler.java new file mode 100644 index 00000000000..f26cdf99bae --- /dev/null +++ b/src/main/java/com/stripe/examples/ThinEventWebhookHandler.java @@ -0,0 +1,94 @@ +package com.stripe.examples; + +import com.stripe.StripeClient; +import com.stripe.events.V1BillingMeterErrorReportTriggeredEvent; +import com.stripe.exception.StripeException; +import com.stripe.model.ThinEvent; +import com.stripe.model.billing.Meter; +import com.stripe.model.v2.Event; +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 thin events like the v1.billing.meter.error_report_triggered event. + * + *

In this example, we: + * + *

+ */ +public class ThinEventWebhookHandler { + 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 { + ThinEvent thinEvent = client.parseThinEvent(webhookBody, sigHeader, WEBHOOK_SECRET); + + // Fetch the event data to understand the failure + Event baseEvent = client.v2().core().events().retrieve(thinEvent.getId()); + if (baseEvent instanceof V1BillingMeterErrorReportTriggeredEvent) { + V1BillingMeterErrorReportTriggeredEvent event = + (V1BillingMeterErrorReportTriggeredEvent) baseEvent; + Meter meter = event.fetchRelatedObject(); + + String meterId = meter.getId(); + System.out.println(meterId); + + // Record the failures and alert your team + // Add your logic here + } + + exchange.sendResponseHeaders(200, -1); + } catch (StripeException e) { + exchange.sendResponseHeaders(400, -1); + } + } else { + exchange.sendResponseHeaders(405, -1); + } + exchange.close(); + } + } +}