From b5f6346dbf36aaa844c8e1145cae405b7cca4c66 Mon Sep 17 00:00:00 2001 From: David Brownman Date: Tue, 5 May 2026 11:46:23 -0700 Subject: [PATCH] generate / tweak EventNotificationHandler code for private preview --- src/main/java/com/stripe/StripeClient.java | 64 + src/main/java/com/stripe/StripeContext.java | 4 +- .../StripeEventNotificationHandler.java | 2960 +++++++++++++++++ .../events/UnknownEventNotification.java | 1 + .../EventNotificationHandlerEndpoint.java | 108 + .../EventNotificationWebhookHandler.java | 1 + .../model/v2/core/EventNotification.java | 1 + .../stripe/net/LiveStripeResponseGetter.java | 21 + .../StripeEventNotificationHandlerTest.java | 518 +++ 9 files changed, 3676 insertions(+), 2 deletions(-) create mode 100644 src/main/java/com/stripe/StripeEventNotificationHandler.java create mode 100644 src/main/java/com/stripe/examples/EventNotificationHandlerEndpoint.java create mode 100644 src/test/java/com/stripe/StripeEventNotificationHandlerTest.java diff --git a/src/main/java/com/stripe/StripeClient.java b/src/main/java/com/stripe/StripeClient.java index c17b6823a3f..52e20811091 100644 --- a/src/main/java/com/stripe/StripeClient.java +++ b/src/main/java/com/stripe/StripeClient.java @@ -8,6 +8,7 @@ import com.stripe.net.Webhook.Signature; import java.net.PasswordAuthentication; import java.net.Proxy; +import lombok.Builder; import lombok.Getter; /** @@ -41,6 +42,62 @@ protected StripeResponseGetter getResponseGetter() { return responseGetter; } + /** Gets the current StripeContext from the client's configuration. Used in unit testing. */ + protected String getContext() { + // TODO(major): add getOptions to the StripeResponseGetter interface? that would simplify this + if (!(responseGetter instanceof LiveStripeResponseGetter)) { + return null; + } + + LiveStripeResponseGetter liveGetter = (LiveStripeResponseGetter) responseGetter; + StripeResponseGetterOptions options = liveGetter.getOptions(); + + return options.getStripeContext(); + } + + /** + * Creates a new StripeClient with the same configuration as this client but with a custom + * StripeContext. This method is useful for creating thread-safe clients with different contexts, + * such as when processing webhooks in parallel where each webhook has its own context. + * + *

The new client will share the same configuration (API key, timeouts, proxy settings, etc.) + * and HTTP client as this client, but will have the specified context. This allows for efficient + * parallel processing without reinitializing HTTP connections. + * + * @param context the custom stripe_context to use for the new client + * @return a new StripeClient with the custom context + * @throws IllegalStateException if this client doesn't use a LiveStripeResponseGetter + */ + public StripeClient withStripeContext(StripeContext context) { + // Convert StripeContext to String + String contextString = (context == null) ? null : context.toString(); + + StripeResponseGetter responseGetter = this.getResponseGetter(); + + // We can only create a new client for LiveStripeResponseGetter because it's the only class with + // `getOptions()`. If we add that method to the interface in a later major, we could remove this + // check. + if (!(responseGetter instanceof LiveStripeResponseGetter)) { + throw new IllegalStateException( + "Cannot create a client with custom context for non-Live response getters"); + } + + LiveStripeResponseGetter liveGetter = (LiveStripeResponseGetter) responseGetter; + + // Create a new LiveStripeResponseGetter with updated context, reusing the HTTP client + LiveStripeResponseGetter newResponseGetter = + liveGetter.withNewOptions( + options -> { + ClientStripeResponseGetterOptions existingOptions = + (ClientStripeResponseGetterOptions) options; + + return existingOptions.toBuilder().stripeContext(contextString).build(); + }); + + // Create and return a new StripeClient with the new response getter + return new StripeClient(newResponseGetter); + } + /** * Returns an StripeEvent instance using the provided JSON payload. Throws a JsonSyntaxException * if the payload is not valid JSON, and a SignatureVerificationException if the signature @@ -1116,6 +1173,8 @@ public com.stripe.service.WebhookEndpointService webhookEndpoints() { } // The end of the section generated from our OpenAPI spec + @SuppressWarnings("ObjectToString") + @Builder(toBuilder = true) static class ClientStripeResponseGetterOptions extends StripeResponseGetterOptions { // When adding setting here keep them in sync with settings in RequestOptions and // in the RequestOptions.merge method @@ -1521,4 +1580,9 @@ public StripeResponse rawRequest( public StripeObject deserialize(String rawJson, ApiMode apiMode) throws StripeException { return StripeObject.deserializeStripeObject(rawJson, this.getResponseGetter(), apiMode); } + + public StripeEventNotificationHandler notificationHandler( + String webhookSecret, StripeEventNotificationHandler.FallbackCallback fallbackCallback) { + return new StripeEventNotificationHandler(webhookSecret, this, fallbackCallback); + } } diff --git a/src/main/java/com/stripe/StripeContext.java b/src/main/java/com/stripe/StripeContext.java index cd7b15b19e8..a86572595ed 100644 --- a/src/main/java/com/stripe/StripeContext.java +++ b/src/main/java/com/stripe/StripeContext.java @@ -64,8 +64,8 @@ public StripeContext pop() { /** * Converts the context to a string by joining segments with '/'. * - * @return string representation of the context segments joined by '/', `null` if there are no - * segments (useful for clearing context) + * @return string representation of the context segments joined by '/'. If there are no segments, + * returns an empty string (useful for clearing context). */ @Override public String toString() { diff --git a/src/main/java/com/stripe/StripeEventNotificationHandler.java b/src/main/java/com/stripe/StripeEventNotificationHandler.java new file mode 100644 index 00000000000..bbf671f0729 --- /dev/null +++ b/src/main/java/com/stripe/StripeEventNotificationHandler.java @@ -0,0 +1,2960 @@ +// File copied from our code generator; changes here will be overwritten. +package com.stripe; + +// event-notification-class-imports: The beginning of the section generated from our OpenAPI spec +// - hack because we can't format java files whose imports aren't a single contiguous block +// - so _any_ imports in this file have to come from codegen +// - as do these comments, explaining the whole thing +import com.stripe.events.V1AccountApplicationAuthorizedEventNotification; +import com.stripe.events.V1AccountApplicationDeauthorizedEventNotification; +import com.stripe.events.V1AccountExternalAccountCreatedEventNotification; +import com.stripe.events.V1AccountExternalAccountDeletedEventNotification; +import com.stripe.events.V1AccountExternalAccountUpdatedEventNotification; +import com.stripe.events.V1AccountSignalsIncludingDelinquencyCreatedEventNotification; +import com.stripe.events.V1AccountUpdatedEventNotification; +import com.stripe.events.V1ApplicationFeeCreatedEventNotification; +import com.stripe.events.V1ApplicationFeeRefundUpdatedEventNotification; +import com.stripe.events.V1ApplicationFeeRefundedEventNotification; +import com.stripe.events.V1BalanceAvailableEventNotification; +import com.stripe.events.V1BillingAlertTriggeredEventNotification; +import com.stripe.events.V1BillingMeterErrorReportTriggeredEventNotification; +import com.stripe.events.V1BillingMeterNoMeterFoundEventNotification; +import com.stripe.events.V1BillingPortalConfigurationCreatedEventNotification; +import com.stripe.events.V1BillingPortalConfigurationUpdatedEventNotification; +import com.stripe.events.V1BillingPortalSessionCreatedEventNotification; +import com.stripe.events.V1CapabilityUpdatedEventNotification; +import com.stripe.events.V1CashBalanceFundsAvailableEventNotification; +import com.stripe.events.V1ChargeCapturedEventNotification; +import com.stripe.events.V1ChargeDisputeClosedEventNotification; +import com.stripe.events.V1ChargeDisputeCreatedEventNotification; +import com.stripe.events.V1ChargeDisputeFundsReinstatedEventNotification; +import com.stripe.events.V1ChargeDisputeFundsWithdrawnEventNotification; +import com.stripe.events.V1ChargeDisputeUpdatedEventNotification; +import com.stripe.events.V1ChargeExpiredEventNotification; +import com.stripe.events.V1ChargeFailedEventNotification; +import com.stripe.events.V1ChargePendingEventNotification; +import com.stripe.events.V1ChargeRefundUpdatedEventNotification; +import com.stripe.events.V1ChargeRefundedEventNotification; +import com.stripe.events.V1ChargeSucceededEventNotification; +import com.stripe.events.V1ChargeUpdatedEventNotification; +import com.stripe.events.V1CheckoutSessionAsyncPaymentFailedEventNotification; +import com.stripe.events.V1CheckoutSessionAsyncPaymentSucceededEventNotification; +import com.stripe.events.V1CheckoutSessionCompletedEventNotification; +import com.stripe.events.V1CheckoutSessionExpiredEventNotification; +import com.stripe.events.V1ClimateOrderCanceledEventNotification; +import com.stripe.events.V1ClimateOrderCreatedEventNotification; +import com.stripe.events.V1ClimateOrderDelayedEventNotification; +import com.stripe.events.V1ClimateOrderDeliveredEventNotification; +import com.stripe.events.V1ClimateOrderProductSubstitutedEventNotification; +import com.stripe.events.V1ClimateProductCreatedEventNotification; +import com.stripe.events.V1ClimateProductPricingUpdatedEventNotification; +import com.stripe.events.V1CouponCreatedEventNotification; +import com.stripe.events.V1CouponDeletedEventNotification; +import com.stripe.events.V1CouponUpdatedEventNotification; +import com.stripe.events.V1CreditNoteCreatedEventNotification; +import com.stripe.events.V1CreditNoteUpdatedEventNotification; +import com.stripe.events.V1CreditNoteVoidedEventNotification; +import com.stripe.events.V1CustomerCashBalanceTransactionCreatedEventNotification; +import com.stripe.events.V1CustomerCreatedEventNotification; +import com.stripe.events.V1CustomerDeletedEventNotification; +import com.stripe.events.V1CustomerSubscriptionCreatedEventNotification; +import com.stripe.events.V1CustomerSubscriptionDeletedEventNotification; +import com.stripe.events.V1CustomerSubscriptionPausedEventNotification; +import com.stripe.events.V1CustomerSubscriptionPendingUpdateAppliedEventNotification; +import com.stripe.events.V1CustomerSubscriptionPendingUpdateExpiredEventNotification; +import com.stripe.events.V1CustomerSubscriptionResumedEventNotification; +import com.stripe.events.V1CustomerSubscriptionTrialWillEndEventNotification; +import com.stripe.events.V1CustomerSubscriptionUpdatedEventNotification; +import com.stripe.events.V1CustomerTaxIdCreatedEventNotification; +import com.stripe.events.V1CustomerTaxIdDeletedEventNotification; +import com.stripe.events.V1CustomerTaxIdUpdatedEventNotification; +import com.stripe.events.V1CustomerUpdatedEventNotification; +import com.stripe.events.V1EntitlementsActiveEntitlementSummaryUpdatedEventNotification; +import com.stripe.events.V1FileCreatedEventNotification; +import com.stripe.events.V1FinancialConnectionsAccountCreatedEventNotification; +import com.stripe.events.V1FinancialConnectionsAccountDeactivatedEventNotification; +import com.stripe.events.V1FinancialConnectionsAccountDisconnectedEventNotification; +import com.stripe.events.V1FinancialConnectionsAccountReactivatedEventNotification; +import com.stripe.events.V1FinancialConnectionsAccountRefreshedBalanceEventNotification; +import com.stripe.events.V1FinancialConnectionsAccountRefreshedOwnershipEventNotification; +import com.stripe.events.V1FinancialConnectionsAccountRefreshedTransactionsEventNotification; +import com.stripe.events.V1IdentityVerificationSessionCanceledEventNotification; +import com.stripe.events.V1IdentityVerificationSessionCreatedEventNotification; +import com.stripe.events.V1IdentityVerificationSessionProcessingEventNotification; +import com.stripe.events.V1IdentityVerificationSessionRedactedEventNotification; +import com.stripe.events.V1IdentityVerificationSessionRequiresInputEventNotification; +import com.stripe.events.V1IdentityVerificationSessionVerifiedEventNotification; +import com.stripe.events.V1InvoiceCreatedEventNotification; +import com.stripe.events.V1InvoiceDeletedEventNotification; +import com.stripe.events.V1InvoiceFinalizationFailedEventNotification; +import com.stripe.events.V1InvoiceFinalizedEventNotification; +import com.stripe.events.V1InvoiceMarkedUncollectibleEventNotification; +import com.stripe.events.V1InvoiceOverdueEventNotification; +import com.stripe.events.V1InvoiceOverpaidEventNotification; +import com.stripe.events.V1InvoicePaidEventNotification; +import com.stripe.events.V1InvoicePaymentActionRequiredEventNotification; +import com.stripe.events.V1InvoicePaymentFailedEventNotification; +import com.stripe.events.V1InvoicePaymentPaidEventNotification; +import com.stripe.events.V1InvoicePaymentSucceededEventNotification; +import com.stripe.events.V1InvoiceSentEventNotification; +import com.stripe.events.V1InvoiceUpcomingEventNotification; +import com.stripe.events.V1InvoiceUpdatedEventNotification; +import com.stripe.events.V1InvoiceVoidedEventNotification; +import com.stripe.events.V1InvoiceWillBeDueEventNotification; +import com.stripe.events.V1InvoiceitemCreatedEventNotification; +import com.stripe.events.V1InvoiceitemDeletedEventNotification; +import com.stripe.events.V1IssuingAuthorizationCreatedEventNotification; +import com.stripe.events.V1IssuingAuthorizationRequestEventNotification; +import com.stripe.events.V1IssuingAuthorizationUpdatedEventNotification; +import com.stripe.events.V1IssuingCardCreatedEventNotification; +import com.stripe.events.V1IssuingCardUpdatedEventNotification; +import com.stripe.events.V1IssuingCardholderCreatedEventNotification; +import com.stripe.events.V1IssuingCardholderUpdatedEventNotification; +import com.stripe.events.V1IssuingDisputeClosedEventNotification; +import com.stripe.events.V1IssuingDisputeCreatedEventNotification; +import com.stripe.events.V1IssuingDisputeFundsReinstatedEventNotification; +import com.stripe.events.V1IssuingDisputeFundsRescindedEventNotification; +import com.stripe.events.V1IssuingDisputeSubmittedEventNotification; +import com.stripe.events.V1IssuingDisputeUpdatedEventNotification; +import com.stripe.events.V1IssuingPersonalizationDesignActivatedEventNotification; +import com.stripe.events.V1IssuingPersonalizationDesignDeactivatedEventNotification; +import com.stripe.events.V1IssuingPersonalizationDesignRejectedEventNotification; +import com.stripe.events.V1IssuingPersonalizationDesignUpdatedEventNotification; +import com.stripe.events.V1IssuingTokenCreatedEventNotification; +import com.stripe.events.V1IssuingTokenUpdatedEventNotification; +import com.stripe.events.V1IssuingTransactionCreatedEventNotification; +import com.stripe.events.V1IssuingTransactionPurchaseDetailsReceiptUpdatedEventNotification; +import com.stripe.events.V1IssuingTransactionUpdatedEventNotification; +import com.stripe.events.V1MandateUpdatedEventNotification; +import com.stripe.events.V1PaymentIntentAmountCapturableUpdatedEventNotification; +import com.stripe.events.V1PaymentIntentCanceledEventNotification; +import com.stripe.events.V1PaymentIntentCreatedEventNotification; +import com.stripe.events.V1PaymentIntentPartiallyFundedEventNotification; +import com.stripe.events.V1PaymentIntentPaymentFailedEventNotification; +import com.stripe.events.V1PaymentIntentProcessingEventNotification; +import com.stripe.events.V1PaymentIntentRequiresActionEventNotification; +import com.stripe.events.V1PaymentIntentSucceededEventNotification; +import com.stripe.events.V1PaymentLinkCreatedEventNotification; +import com.stripe.events.V1PaymentLinkUpdatedEventNotification; +import com.stripe.events.V1PaymentMethodAttachedEventNotification; +import com.stripe.events.V1PaymentMethodAutomaticallyUpdatedEventNotification; +import com.stripe.events.V1PaymentMethodDetachedEventNotification; +import com.stripe.events.V1PaymentMethodUpdatedEventNotification; +import com.stripe.events.V1PayoutCanceledEventNotification; +import com.stripe.events.V1PayoutCreatedEventNotification; +import com.stripe.events.V1PayoutFailedEventNotification; +import com.stripe.events.V1PayoutPaidEventNotification; +import com.stripe.events.V1PayoutReconciliationCompletedEventNotification; +import com.stripe.events.V1PayoutUpdatedEventNotification; +import com.stripe.events.V1PersonCreatedEventNotification; +import com.stripe.events.V1PersonDeletedEventNotification; +import com.stripe.events.V1PersonUpdatedEventNotification; +import com.stripe.events.V1PlanCreatedEventNotification; +import com.stripe.events.V1PlanDeletedEventNotification; +import com.stripe.events.V1PlanUpdatedEventNotification; +import com.stripe.events.V1PriceCreatedEventNotification; +import com.stripe.events.V1PriceDeletedEventNotification; +import com.stripe.events.V1PriceUpdatedEventNotification; +import com.stripe.events.V1ProductCreatedEventNotification; +import com.stripe.events.V1ProductDeletedEventNotification; +import com.stripe.events.V1ProductUpdatedEventNotification; +import com.stripe.events.V1PromotionCodeCreatedEventNotification; +import com.stripe.events.V1PromotionCodeUpdatedEventNotification; +import com.stripe.events.V1QuoteAcceptedEventNotification; +import com.stripe.events.V1QuoteCanceledEventNotification; +import com.stripe.events.V1QuoteCreatedEventNotification; +import com.stripe.events.V1QuoteFinalizedEventNotification; +import com.stripe.events.V1RadarEarlyFraudWarningCreatedEventNotification; +import com.stripe.events.V1RadarEarlyFraudWarningUpdatedEventNotification; +import com.stripe.events.V1RefundCreatedEventNotification; +import com.stripe.events.V1RefundFailedEventNotification; +import com.stripe.events.V1RefundUpdatedEventNotification; +import com.stripe.events.V1ReviewClosedEventNotification; +import com.stripe.events.V1ReviewOpenedEventNotification; +import com.stripe.events.V1SetupIntentCanceledEventNotification; +import com.stripe.events.V1SetupIntentCreatedEventNotification; +import com.stripe.events.V1SetupIntentRequiresActionEventNotification; +import com.stripe.events.V1SetupIntentSetupFailedEventNotification; +import com.stripe.events.V1SetupIntentSucceededEventNotification; +import com.stripe.events.V1SigmaScheduledQueryRunCreatedEventNotification; +import com.stripe.events.V1SourceCanceledEventNotification; +import com.stripe.events.V1SourceChargeableEventNotification; +import com.stripe.events.V1SourceFailedEventNotification; +import com.stripe.events.V1SourceRefundAttributesRequiredEventNotification; +import com.stripe.events.V1SubscriptionScheduleAbortedEventNotification; +import com.stripe.events.V1SubscriptionScheduleCanceledEventNotification; +import com.stripe.events.V1SubscriptionScheduleCompletedEventNotification; +import com.stripe.events.V1SubscriptionScheduleCreatedEventNotification; +import com.stripe.events.V1SubscriptionScheduleExpiringEventNotification; +import com.stripe.events.V1SubscriptionScheduleReleasedEventNotification; +import com.stripe.events.V1SubscriptionScheduleUpdatedEventNotification; +import com.stripe.events.V1TaxRateCreatedEventNotification; +import com.stripe.events.V1TaxRateUpdatedEventNotification; +import com.stripe.events.V1TaxSettingsUpdatedEventNotification; +import com.stripe.events.V1TerminalReaderActionFailedEventNotification; +import com.stripe.events.V1TerminalReaderActionSucceededEventNotification; +import com.stripe.events.V1TerminalReaderActionUpdatedEventNotification; +import com.stripe.events.V1TestHelpersTestClockAdvancingEventNotification; +import com.stripe.events.V1TestHelpersTestClockCreatedEventNotification; +import com.stripe.events.V1TestHelpersTestClockDeletedEventNotification; +import com.stripe.events.V1TestHelpersTestClockInternalFailureEventNotification; +import com.stripe.events.V1TestHelpersTestClockReadyEventNotification; +import com.stripe.events.V1TopupCanceledEventNotification; +import com.stripe.events.V1TopupCreatedEventNotification; +import com.stripe.events.V1TopupFailedEventNotification; +import com.stripe.events.V1TopupReversedEventNotification; +import com.stripe.events.V1TopupSucceededEventNotification; +import com.stripe.events.V1TransferCreatedEventNotification; +import com.stripe.events.V1TransferReversedEventNotification; +import com.stripe.events.V1TransferUpdatedEventNotification; +import com.stripe.events.V2BillingCadenceBilledEventNotification; +import com.stripe.events.V2BillingCadenceCanceledEventNotification; +import com.stripe.events.V2BillingCadenceCreatedEventNotification; +import com.stripe.events.V2BillingLicenseFeeCreatedEventNotification; +import com.stripe.events.V2BillingLicenseFeeUpdatedEventNotification; +import com.stripe.events.V2BillingLicenseFeeVersionCreatedEventNotification; +import com.stripe.events.V2BillingLicensedItemCreatedEventNotification; +import com.stripe.events.V2BillingLicensedItemUpdatedEventNotification; +import com.stripe.events.V2BillingMeteredItemCreatedEventNotification; +import com.stripe.events.V2BillingMeteredItemUpdatedEventNotification; +import com.stripe.events.V2BillingPricingPlanComponentCreatedEventNotification; +import com.stripe.events.V2BillingPricingPlanComponentUpdatedEventNotification; +import com.stripe.events.V2BillingPricingPlanCreatedEventNotification; +import com.stripe.events.V2BillingPricingPlanSubscriptionCollectionAwaitingCustomerActionEventNotification; +import com.stripe.events.V2BillingPricingPlanSubscriptionCollectionCurrentEventNotification; +import com.stripe.events.V2BillingPricingPlanSubscriptionCollectionPastDueEventNotification; +import com.stripe.events.V2BillingPricingPlanSubscriptionCollectionPausedEventNotification; +import com.stripe.events.V2BillingPricingPlanSubscriptionCollectionUnpaidEventNotification; +import com.stripe.events.V2BillingPricingPlanSubscriptionServicingActivatedEventNotification; +import com.stripe.events.V2BillingPricingPlanSubscriptionServicingCanceledEventNotification; +import com.stripe.events.V2BillingPricingPlanSubscriptionServicingPausedEventNotification; +import com.stripe.events.V2BillingPricingPlanUpdatedEventNotification; +import com.stripe.events.V2BillingPricingPlanVersionCreatedEventNotification; +import com.stripe.events.V2BillingRateCardCreatedEventNotification; +import com.stripe.events.V2BillingRateCardCustomPricingUnitOverageRateCreatedEventNotification; +import com.stripe.events.V2BillingRateCardRateCreatedEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionActivatedEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionCanceledEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionCollectionAwaitingCustomerActionEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionCollectionCurrentEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionCollectionPastDueEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionCollectionPausedEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionCollectionUnpaidEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionServicingActivatedEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionServicingCanceledEventNotification; +import com.stripe.events.V2BillingRateCardSubscriptionServicingPausedEventNotification; +import com.stripe.events.V2BillingRateCardUpdatedEventNotification; +import com.stripe.events.V2BillingRateCardVersionCreatedEventNotification; +import com.stripe.events.V2CommerceProductCatalogImportsFailedEventNotification; +import com.stripe.events.V2CommerceProductCatalogImportsProcessingEventNotification; +import com.stripe.events.V2CommerceProductCatalogImportsSucceededEventNotification; +import com.stripe.events.V2CommerceProductCatalogImportsSucceededWithErrorsEventNotification; +import com.stripe.events.V2CoreAccountClosedEventNotification; +import com.stripe.events.V2CoreAccountCreatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationCardCreatorCapabilityStatusUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationCardCreatorUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationCustomerCapabilityStatusUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationCustomerUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationMerchantCapabilityStatusUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationMerchantUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationRecipientCapabilityStatusUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationRecipientUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationStorerCapabilityStatusUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingConfigurationStorerUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingDefaultsUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingFutureRequirementsUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingIdentityUpdatedEventNotification; +import com.stripe.events.V2CoreAccountIncludingRequirementsUpdatedEventNotification; +import com.stripe.events.V2CoreAccountLinkReturnedEventNotification; +import com.stripe.events.V2CoreAccountPersonCreatedEventNotification; +import com.stripe.events.V2CoreAccountPersonDeletedEventNotification; +import com.stripe.events.V2CoreAccountPersonUpdatedEventNotification; +import com.stripe.events.V2CoreAccountSignalsFraudulentWebsiteReadyEventNotification; +import com.stripe.events.V2CoreAccountUpdatedEventNotification; +import com.stripe.events.V2CoreApprovalRequestApprovedEventNotification; +import com.stripe.events.V2CoreApprovalRequestCanceledEventNotification; +import com.stripe.events.V2CoreApprovalRequestCreatedEventNotification; +import com.stripe.events.V2CoreApprovalRequestExpiredEventNotification; +import com.stripe.events.V2CoreApprovalRequestFailedEventNotification; +import com.stripe.events.V2CoreApprovalRequestRejectedEventNotification; +import com.stripe.events.V2CoreApprovalRequestSucceededEventNotification; +import com.stripe.events.V2CoreBatchJobBatchFailedEventNotification; +import com.stripe.events.V2CoreBatchJobCanceledEventNotification; +import com.stripe.events.V2CoreBatchJobCompletedEventNotification; +import com.stripe.events.V2CoreBatchJobCreatedEventNotification; +import com.stripe.events.V2CoreBatchJobReadyForUploadEventNotification; +import com.stripe.events.V2CoreBatchJobTimeoutEventNotification; +import com.stripe.events.V2CoreBatchJobUpdatedEventNotification; +import com.stripe.events.V2CoreBatchJobUploadTimeoutEventNotification; +import com.stripe.events.V2CoreBatchJobValidatingEventNotification; +import com.stripe.events.V2CoreBatchJobValidationFailedEventNotification; +import com.stripe.events.V2CoreClaimableSandboxClaimedEventNotification; +import com.stripe.events.V2CoreClaimableSandboxCreatedEventNotification; +import com.stripe.events.V2CoreClaimableSandboxExpiredEventNotification; +import com.stripe.events.V2CoreClaimableSandboxExpiringEventNotification; +import com.stripe.events.V2CoreClaimableSandboxUpdatedEventNotification; +import com.stripe.events.V2CoreEventDestinationPingEventNotification; +import com.stripe.events.V2CoreHealthApiErrorFiringEventNotification; +import com.stripe.events.V2CoreHealthApiErrorResolvedEventNotification; +import com.stripe.events.V2CoreHealthApiLatencyFiringEventNotification; +import com.stripe.events.V2CoreHealthApiLatencyResolvedEventNotification; +import com.stripe.events.V2CoreHealthAuthorizationRateDropFiringEventNotification; +import com.stripe.events.V2CoreHealthAuthorizationRateDropResolvedEventNotification; +import com.stripe.events.V2CoreHealthEventGenerationFailureResolvedEventNotification; +import com.stripe.events.V2CoreHealthFraudRateIncreasedEventNotification; +import com.stripe.events.V2CoreHealthIssuingAuthorizationRequestErrorsFiringEventNotification; +import com.stripe.events.V2CoreHealthIssuingAuthorizationRequestErrorsResolvedEventNotification; +import com.stripe.events.V2CoreHealthIssuingAuthorizationRequestTimeoutFiringEventNotification; +import com.stripe.events.V2CoreHealthIssuingAuthorizationRequestTimeoutResolvedEventNotification; +import com.stripe.events.V2CoreHealthMeterEventSummariesDelayedFiringEventNotification; +import com.stripe.events.V2CoreHealthMeterEventSummariesDelayedResolvedEventNotification; +import com.stripe.events.V2CoreHealthPaymentMethodErrorFiringEventNotification; +import com.stripe.events.V2CoreHealthPaymentMethodErrorResolvedEventNotification; +import com.stripe.events.V2CoreHealthSepaDebitDelayedFiringEventNotification; +import com.stripe.events.V2CoreHealthSepaDebitDelayedResolvedEventNotification; +import com.stripe.events.V2CoreHealthTrafficVolumeDropFiringEventNotification; +import com.stripe.events.V2CoreHealthTrafficVolumeDropResolvedEventNotification; +import com.stripe.events.V2CoreHealthWebhookLatencyFiringEventNotification; +import com.stripe.events.V2CoreHealthWebhookLatencyResolvedEventNotification; +import com.stripe.events.V2DataReportingQueryRunCreatedEventNotification; +import com.stripe.events.V2DataReportingQueryRunFailedEventNotification; +import com.stripe.events.V2DataReportingQueryRunSucceededEventNotification; +import com.stripe.events.V2DataReportingQueryRunUpdatedEventNotification; +import com.stripe.events.V2ExtendExtensionRunFailedEventNotification; +import com.stripe.events.V2ExtendWorkflowRunFailedEventNotification; +import com.stripe.events.V2ExtendWorkflowRunStartedEventNotification; +import com.stripe.events.V2ExtendWorkflowRunSucceededEventNotification; +import com.stripe.events.V2IamApiKeyCreatedEventNotification; +import com.stripe.events.V2IamApiKeyDefaultSecretRevealedEventNotification; +import com.stripe.events.V2IamApiKeyExpiredEventNotification; +import com.stripe.events.V2IamApiKeyPermissionsUpdatedEventNotification; +import com.stripe.events.V2IamApiKeyRotatedEventNotification; +import com.stripe.events.V2IamApiKeyUpdatedEventNotification; +import com.stripe.events.V2IamStripeAccessGrantApprovedEventNotification; +import com.stripe.events.V2IamStripeAccessGrantCanceledEventNotification; +import com.stripe.events.V2IamStripeAccessGrantDeniedEventNotification; +import com.stripe.events.V2IamStripeAccessGrantRemovedEventNotification; +import com.stripe.events.V2IamStripeAccessGrantRequestedEventNotification; +import com.stripe.events.V2IamStripeAccessGrantUpdatedEventNotification; +import com.stripe.events.V2MoneyManagementAdjustmentCreatedEventNotification; +import com.stripe.events.V2MoneyManagementFinancialAccountCreatedEventNotification; +import com.stripe.events.V2MoneyManagementFinancialAccountUpdatedEventNotification; +import com.stripe.events.V2MoneyManagementFinancialAddressActivatedEventNotification; +import com.stripe.events.V2MoneyManagementFinancialAddressFailedEventNotification; +import com.stripe.events.V2MoneyManagementInboundTransferAvailableEventNotification; +import com.stripe.events.V2MoneyManagementInboundTransferBankDebitFailedEventNotification; +import com.stripe.events.V2MoneyManagementInboundTransferBankDebitProcessingEventNotification; +import com.stripe.events.V2MoneyManagementInboundTransferBankDebitQueuedEventNotification; +import com.stripe.events.V2MoneyManagementInboundTransferBankDebitReturnedEventNotification; +import com.stripe.events.V2MoneyManagementInboundTransferBankDebitSucceededEventNotification; +import com.stripe.events.V2MoneyManagementOutboundPaymentCanceledEventNotification; +import com.stripe.events.V2MoneyManagementOutboundPaymentCreatedEventNotification; +import com.stripe.events.V2MoneyManagementOutboundPaymentFailedEventNotification; +import com.stripe.events.V2MoneyManagementOutboundPaymentPostedEventNotification; +import com.stripe.events.V2MoneyManagementOutboundPaymentReturnedEventNotification; +import com.stripe.events.V2MoneyManagementOutboundPaymentUpdatedEventNotification; +import com.stripe.events.V2MoneyManagementOutboundTransferCanceledEventNotification; +import com.stripe.events.V2MoneyManagementOutboundTransferCreatedEventNotification; +import com.stripe.events.V2MoneyManagementOutboundTransferFailedEventNotification; +import com.stripe.events.V2MoneyManagementOutboundTransferPostedEventNotification; +import com.stripe.events.V2MoneyManagementOutboundTransferReturnedEventNotification; +import com.stripe.events.V2MoneyManagementOutboundTransferUpdatedEventNotification; +import com.stripe.events.V2MoneyManagementPayoutMethodCreatedEventNotification; +import com.stripe.events.V2MoneyManagementPayoutMethodUpdatedEventNotification; +import com.stripe.events.V2MoneyManagementReceivedCreditAvailableEventNotification; +import com.stripe.events.V2MoneyManagementReceivedCreditFailedEventNotification; +import com.stripe.events.V2MoneyManagementReceivedCreditReturnedEventNotification; +import com.stripe.events.V2MoneyManagementReceivedCreditSucceededEventNotification; +import com.stripe.events.V2MoneyManagementReceivedDebitCanceledEventNotification; +import com.stripe.events.V2MoneyManagementReceivedDebitFailedEventNotification; +import com.stripe.events.V2MoneyManagementReceivedDebitPendingEventNotification; +import com.stripe.events.V2MoneyManagementReceivedDebitSucceededEventNotification; +import com.stripe.events.V2MoneyManagementReceivedDebitUpdatedEventNotification; +import com.stripe.events.V2MoneyManagementRecipientVerificationCreatedEventNotification; +import com.stripe.events.V2MoneyManagementRecipientVerificationUpdatedEventNotification; +import com.stripe.events.V2MoneyManagementTransactionCreatedEventNotification; +import com.stripe.events.V2MoneyManagementTransactionUpdatedEventNotification; +import com.stripe.events.V2OrchestratedCommerceAgreementConfirmedEventNotification; +import com.stripe.events.V2OrchestratedCommerceAgreementCreatedEventNotification; +import com.stripe.events.V2OrchestratedCommerceAgreementPartiallyConfirmedEventNotification; +import com.stripe.events.V2OrchestratedCommerceAgreementTerminatedEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentAttemptFailedEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentAttemptStartedEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentAuthorizationAttemptFailedEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentAuthorizationAttemptStartedEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentCanceledEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentCreatedEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentFailedEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentPausedEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentRequiresCaptureEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentResumedEventNotification; +import com.stripe.events.V2PaymentsOffSessionPaymentSucceededEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentCanceledEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentCreatedEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentErroredEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentFundsNotReceivedEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentMatchedEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentNotFoundEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentSettledEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentSplitCanceledEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentSplitCreatedEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentSplitSettledEventNotification; +import com.stripe.events.V2PaymentsSettlementAllocationIntentSubmittedEventNotification; +import com.stripe.events.V2ReportingReportRunCreatedEventNotification; +import com.stripe.events.V2ReportingReportRunFailedEventNotification; +import com.stripe.events.V2ReportingReportRunSucceededEventNotification; +import com.stripe.events.V2ReportingReportRunUpdatedEventNotification; +import com.stripe.events.V2SignalsAccountSignalFraudulentMerchantReadyEventNotification; +import com.stripe.exception.SignatureVerificationException; +import com.stripe.model.v2.core.EventNotification; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; + +// event-notification-class-imports: The end of the section generated from our OpenAPI spec + +public class StripeEventNotificationHandler { + /** + * Functional interface for callback functions. It describes the signature of the functions you'll + * register on the StripeEventRouter to process incoming event notifications. + */ + @FunctionalInterface + public interface Callback { + // this is an internal-facing method name that dictates how we call the stored method + void process(T event, StripeClient client); + } + + /** + * Functional interface for handling otherwise unhandled events. It's similar to {@link Callback}, + * but includes additional information about the unhandled event to help debug it. + */ + @FunctionalInterface + public interface FallbackCallback { + // this is an internal-facing method name that dictates how we call the stored method + void process( + EventNotification event, StripeClient client, UnhandledNotificationDetails details); + } + + /** + * Information about an unhandled event notification to make it easier to respond (and potentially + * update your integration). + */ + public static class UnhandledNotificationDetails { + private boolean isKnownEventType; + + private UnhandledNotificationDetails(boolean isKnownEventType) { + this.isKnownEventType = isKnownEventType; + } + + /** + * If true, the unhandled event's type is known to the SDK (i.e., it was successfully + * deserialized into a specific `EventNotification` subclass). + */ + public boolean isKnownEventType() { + return isKnownEventType; + } + } + + // this is intentionally naiive to avoid the performance cost of interacting with `volatile`. We + // expect that registrations are done synchronously at startup time and handling will happen + // async, so thread-safe reads aren't important here. + private boolean hasHandledEvent = false; + + private final String webhookSecret; + private final StripeClient client; + private final FallbackCallback fallbackCallback; + private final HashMap> registeredHandlers = + new HashMap<>(); + + public StripeEventNotificationHandler( + String webhookSecret, StripeClient client, FallbackCallback fallbackCallback) { + this.webhookSecret = webhookSecret; + this.client = client; + this.fallbackCallback = fallbackCallback; + } + + private StripeEventNotificationHandler register( + String eventType, Callback handler) { + if (hasHandledEvent) { + throw new IllegalStateException("Cannot register handlers after handling an event"); + } + + if (this.registeredHandlers.containsKey(eventType)) { + throw new IllegalArgumentException("Handler already registered for event type: " + eventType); + } + this.registeredHandlers.put(eventType, handler); + return this; + } + + /** + * Handle an incoming webhook event notification. + * + * @param webhookBody the incoming webhook body + * @param sigHeader the incoming webhook signature header + * @throws SignatureVerificationException if the validation of the webhook signature fails + * @throws IllegalArgumentException if no handler is registered for the event type + */ + @SuppressWarnings("unchecked") + public void handle(String webhookBody, String sigHeader) throws SignatureVerificationException { + // setting this naiively isn't technically thread-safe, but we expect the all callbacks to be + // registered syncronously on startup, so this should be fine + hasHandledEvent = true; + + EventNotification eventNotification = + this.client.parseEventNotification(webhookBody, sigHeader, this.webhookSecret); + + Callback handler = + registeredHandlers.get(eventNotification.getType()); + + // Create a new client with the event's context for thread-safe processing + StripeClient eventClient = this.client.withStripeContext(eventNotification.context); + + if (handler == null) { + boolean isKnownEventType = + !(eventNotification instanceof com.stripe.events.UnknownEventNotification); + UnhandledNotificationDetails details = new UnhandledNotificationDetails(isKnownEventType); + + this.fallbackCallback.process(eventNotification, eventClient, details); + } else { + // this is technically unsafe but we control the registration API so should be ok + ((Callback) handler).process(eventNotification, eventClient); + } + } + + // notification-handler-methods: The beginning of the section generated from our OpenAPI spec + public StripeEventNotificationHandler onV1AccountApplicationAuthorized( + Callback callback) { + this.register("v1.account.application.authorized", callback); + return this; + } + + public StripeEventNotificationHandler onV1AccountApplicationDeauthorized( + Callback callback) { + this.register("v1.account.application.deauthorized", callback); + return this; + } + + public StripeEventNotificationHandler onV1AccountExternalAccountCreated( + Callback callback) { + this.register("v1.account.external_account.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1AccountExternalAccountDeleted( + Callback callback) { + this.register("v1.account.external_account.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1AccountExternalAccountUpdated( + Callback callback) { + this.register("v1.account.external_account.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1AccountUpdated( + Callback callback) { + this.register("v1.account.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1AccountSignalsIncludingDelinquencyCreated( + Callback callback) { + this.register("v1.account_signals[delinquency].created", callback); + return this; + } + + public StripeEventNotificationHandler onV1ApplicationFeeCreated( + Callback callback) { + this.register("v1.application_fee.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1ApplicationFeeRefundUpdated( + Callback callback) { + this.register("v1.application_fee.refund.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1ApplicationFeeRefunded( + Callback callback) { + this.register("v1.application_fee.refunded", callback); + return this; + } + + public StripeEventNotificationHandler onV1BalanceAvailable( + Callback callback) { + this.register("v1.balance.available", callback); + return this; + } + + public StripeEventNotificationHandler onV1BillingAlertTriggered( + Callback callback) { + this.register("v1.billing.alert.triggered", callback); + return this; + } + + public StripeEventNotificationHandler onV1BillingMeterErrorReportTriggered( + Callback callback) { + this.register("v1.billing.meter.error_report_triggered", callback); + return this; + } + + public StripeEventNotificationHandler onV1BillingMeterNoMeterFound( + Callback callback) { + this.register("v1.billing.meter.no_meter_found", callback); + return this; + } + + public StripeEventNotificationHandler onV1BillingPortalConfigurationCreated( + Callback callback) { + this.register("v1.billing_portal.configuration.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1BillingPortalConfigurationUpdated( + Callback callback) { + this.register("v1.billing_portal.configuration.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1BillingPortalSessionCreated( + Callback callback) { + this.register("v1.billing_portal.session.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1CapabilityUpdated( + Callback callback) { + this.register("v1.capability.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1CashBalanceFundsAvailable( + Callback callback) { + this.register("v1.cash_balance.funds_available", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeCaptured( + Callback callback) { + this.register("v1.charge.captured", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeDisputeClosed( + Callback callback) { + this.register("v1.charge.dispute.closed", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeDisputeCreated( + Callback callback) { + this.register("v1.charge.dispute.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeDisputeFundsReinstated( + Callback callback) { + this.register("v1.charge.dispute.funds_reinstated", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeDisputeFundsWithdrawn( + Callback callback) { + this.register("v1.charge.dispute.funds_withdrawn", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeDisputeUpdated( + Callback callback) { + this.register("v1.charge.dispute.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeExpired( + Callback callback) { + this.register("v1.charge.expired", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeFailed( + Callback callback) { + this.register("v1.charge.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargePending( + Callback callback) { + this.register("v1.charge.pending", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeRefundUpdated( + Callback callback) { + this.register("v1.charge.refund.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeRefunded( + Callback callback) { + this.register("v1.charge.refunded", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeSucceeded( + Callback callback) { + this.register("v1.charge.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV1ChargeUpdated( + Callback callback) { + this.register("v1.charge.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1CheckoutSessionAsyncPaymentFailed( + Callback callback) { + this.register("v1.checkout.session.async_payment_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1CheckoutSessionAsyncPaymentSucceeded( + Callback callback) { + this.register("v1.checkout.session.async_payment_succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV1CheckoutSessionCompleted( + Callback callback) { + this.register("v1.checkout.session.completed", callback); + return this; + } + + public StripeEventNotificationHandler onV1CheckoutSessionExpired( + Callback callback) { + this.register("v1.checkout.session.expired", callback); + return this; + } + + public StripeEventNotificationHandler onV1ClimateOrderCanceled( + Callback callback) { + this.register("v1.climate.order.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV1ClimateOrderCreated( + Callback callback) { + this.register("v1.climate.order.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1ClimateOrderDelayed( + Callback callback) { + this.register("v1.climate.order.delayed", callback); + return this; + } + + public StripeEventNotificationHandler onV1ClimateOrderDelivered( + Callback callback) { + this.register("v1.climate.order.delivered", callback); + return this; + } + + public StripeEventNotificationHandler onV1ClimateOrderProductSubstituted( + Callback callback) { + this.register("v1.climate.order.product_substituted", callback); + return this; + } + + public StripeEventNotificationHandler onV1ClimateProductCreated( + Callback callback) { + this.register("v1.climate.product.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1ClimateProductPricingUpdated( + Callback callback) { + this.register("v1.climate.product.pricing_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1CouponCreated( + Callback callback) { + this.register("v1.coupon.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1CouponDeleted( + Callback callback) { + this.register("v1.coupon.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1CouponUpdated( + Callback callback) { + this.register("v1.coupon.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1CreditNoteCreated( + Callback callback) { + this.register("v1.credit_note.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1CreditNoteUpdated( + Callback callback) { + this.register("v1.credit_note.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1CreditNoteVoided( + Callback callback) { + this.register("v1.credit_note.voided", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerCreated( + Callback callback) { + this.register("v1.customer.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerDeleted( + Callback callback) { + this.register("v1.customer.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerSubscriptionCreated( + Callback callback) { + this.register("v1.customer.subscription.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerSubscriptionDeleted( + Callback callback) { + this.register("v1.customer.subscription.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerSubscriptionPaused( + Callback callback) { + this.register("v1.customer.subscription.paused", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerSubscriptionPendingUpdateApplied( + Callback callback) { + this.register("v1.customer.subscription.pending_update_applied", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerSubscriptionPendingUpdateExpired( + Callback callback) { + this.register("v1.customer.subscription.pending_update_expired", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerSubscriptionResumed( + Callback callback) { + this.register("v1.customer.subscription.resumed", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerSubscriptionTrialWillEnd( + Callback callback) { + this.register("v1.customer.subscription.trial_will_end", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerSubscriptionUpdated( + Callback callback) { + this.register("v1.customer.subscription.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerTaxIdCreated( + Callback callback) { + this.register("v1.customer.tax_id.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerTaxIdDeleted( + Callback callback) { + this.register("v1.customer.tax_id.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerTaxIdUpdated( + Callback callback) { + this.register("v1.customer.tax_id.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerUpdated( + Callback callback) { + this.register("v1.customer.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1CustomerCashBalanceTransactionCreated( + Callback callback) { + this.register("v1.customer_cash_balance_transaction.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1EntitlementsActiveEntitlementSummaryUpdated( + Callback callback) { + this.register("v1.entitlements.active_entitlement_summary.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1FileCreated( + Callback callback) { + this.register("v1.file.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1FinancialConnectionsAccountCreated( + Callback callback) { + this.register("v1.financial_connections.account.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1FinancialConnectionsAccountDeactivated( + Callback callback) { + this.register("v1.financial_connections.account.deactivated", callback); + return this; + } + + public StripeEventNotificationHandler onV1FinancialConnectionsAccountDisconnected( + Callback callback) { + this.register("v1.financial_connections.account.disconnected", callback); + return this; + } + + public StripeEventNotificationHandler onV1FinancialConnectionsAccountReactivated( + Callback callback) { + this.register("v1.financial_connections.account.reactivated", callback); + return this; + } + + public StripeEventNotificationHandler onV1FinancialConnectionsAccountRefreshedBalance( + Callback callback) { + this.register("v1.financial_connections.account.refreshed_balance", callback); + return this; + } + + public StripeEventNotificationHandler onV1FinancialConnectionsAccountRefreshedOwnership( + Callback callback) { + this.register("v1.financial_connections.account.refreshed_ownership", callback); + return this; + } + + public StripeEventNotificationHandler onV1FinancialConnectionsAccountRefreshedTransactions( + Callback callback) { + this.register("v1.financial_connections.account.refreshed_transactions", callback); + return this; + } + + public StripeEventNotificationHandler onV1IdentityVerificationSessionCanceled( + Callback callback) { + this.register("v1.identity.verification_session.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV1IdentityVerificationSessionCreated( + Callback callback) { + this.register("v1.identity.verification_session.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1IdentityVerificationSessionProcessing( + Callback callback) { + this.register("v1.identity.verification_session.processing", callback); + return this; + } + + public StripeEventNotificationHandler onV1IdentityVerificationSessionRedacted( + Callback callback) { + this.register("v1.identity.verification_session.redacted", callback); + return this; + } + + public StripeEventNotificationHandler onV1IdentityVerificationSessionRequiresInput( + Callback callback) { + this.register("v1.identity.verification_session.requires_input", callback); + return this; + } + + public StripeEventNotificationHandler onV1IdentityVerificationSessionVerified( + Callback callback) { + this.register("v1.identity.verification_session.verified", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceCreated( + Callback callback) { + this.register("v1.invoice.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceDeleted( + Callback callback) { + this.register("v1.invoice.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceFinalizationFailed( + Callback callback) { + this.register("v1.invoice.finalization_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceFinalized( + Callback callback) { + this.register("v1.invoice.finalized", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceMarkedUncollectible( + Callback callback) { + this.register("v1.invoice.marked_uncollectible", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceOverdue( + Callback callback) { + this.register("v1.invoice.overdue", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceOverpaid( + Callback callback) { + this.register("v1.invoice.overpaid", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoicePaid( + Callback callback) { + this.register("v1.invoice.paid", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoicePaymentActionRequired( + Callback callback) { + this.register("v1.invoice.payment_action_required", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoicePaymentFailed( + Callback callback) { + this.register("v1.invoice.payment_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoicePaymentSucceeded( + Callback callback) { + this.register("v1.invoice.payment_succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceSent( + Callback callback) { + this.register("v1.invoice.sent", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceUpcoming( + Callback callback) { + this.register("v1.invoice.upcoming", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceUpdated( + Callback callback) { + this.register("v1.invoice.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceVoided( + Callback callback) { + this.register("v1.invoice.voided", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceWillBeDue( + Callback callback) { + this.register("v1.invoice.will_be_due", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoicePaymentPaid( + Callback callback) { + this.register("v1.invoice_payment.paid", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceitemCreated( + Callback callback) { + this.register("v1.invoiceitem.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1InvoiceitemDeleted( + Callback callback) { + this.register("v1.invoiceitem.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingAuthorizationCreated( + Callback callback) { + this.register("v1.issuing_authorization.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingAuthorizationRequest( + Callback callback) { + this.register("v1.issuing_authorization.request", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingAuthorizationUpdated( + Callback callback) { + this.register("v1.issuing_authorization.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingCardCreated( + Callback callback) { + this.register("v1.issuing_card.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingCardUpdated( + Callback callback) { + this.register("v1.issuing_card.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingCardholderCreated( + Callback callback) { + this.register("v1.issuing_cardholder.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingCardholderUpdated( + Callback callback) { + this.register("v1.issuing_cardholder.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingDisputeClosed( + Callback callback) { + this.register("v1.issuing_dispute.closed", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingDisputeCreated( + Callback callback) { + this.register("v1.issuing_dispute.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingDisputeFundsReinstated( + Callback callback) { + this.register("v1.issuing_dispute.funds_reinstated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingDisputeFundsRescinded( + Callback callback) { + this.register("v1.issuing_dispute.funds_rescinded", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingDisputeSubmitted( + Callback callback) { + this.register("v1.issuing_dispute.submitted", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingDisputeUpdated( + Callback callback) { + this.register("v1.issuing_dispute.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingPersonalizationDesignActivated( + Callback callback) { + this.register("v1.issuing_personalization_design.activated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingPersonalizationDesignDeactivated( + Callback callback) { + this.register("v1.issuing_personalization_design.deactivated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingPersonalizationDesignRejected( + Callback callback) { + this.register("v1.issuing_personalization_design.rejected", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingPersonalizationDesignUpdated( + Callback callback) { + this.register("v1.issuing_personalization_design.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingTokenCreated( + Callback callback) { + this.register("v1.issuing_token.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingTokenUpdated( + Callback callback) { + this.register("v1.issuing_token.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingTransactionCreated( + Callback callback) { + this.register("v1.issuing_transaction.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingTransactionPurchaseDetailsReceiptUpdated( + Callback callback) { + this.register("v1.issuing_transaction.purchase_details_receipt_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1IssuingTransactionUpdated( + Callback callback) { + this.register("v1.issuing_transaction.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1MandateUpdated( + Callback callback) { + this.register("v1.mandate.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentIntentAmountCapturableUpdated( + Callback callback) { + this.register("v1.payment_intent.amount_capturable_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentIntentCanceled( + Callback callback) { + this.register("v1.payment_intent.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentIntentCreated( + Callback callback) { + this.register("v1.payment_intent.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentIntentPartiallyFunded( + Callback callback) { + this.register("v1.payment_intent.partially_funded", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentIntentPaymentFailed( + Callback callback) { + this.register("v1.payment_intent.payment_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentIntentProcessing( + Callback callback) { + this.register("v1.payment_intent.processing", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentIntentRequiresAction( + Callback callback) { + this.register("v1.payment_intent.requires_action", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentIntentSucceeded( + Callback callback) { + this.register("v1.payment_intent.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentLinkCreated( + Callback callback) { + this.register("v1.payment_link.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentLinkUpdated( + Callback callback) { + this.register("v1.payment_link.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentMethodAttached( + Callback callback) { + this.register("v1.payment_method.attached", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentMethodAutomaticallyUpdated( + Callback callback) { + this.register("v1.payment_method.automatically_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentMethodDetached( + Callback callback) { + this.register("v1.payment_method.detached", callback); + return this; + } + + public StripeEventNotificationHandler onV1PaymentMethodUpdated( + Callback callback) { + this.register("v1.payment_method.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1PayoutCanceled( + Callback callback) { + this.register("v1.payout.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV1PayoutCreated( + Callback callback) { + this.register("v1.payout.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1PayoutFailed( + Callback callback) { + this.register("v1.payout.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1PayoutPaid( + Callback callback) { + this.register("v1.payout.paid", callback); + return this; + } + + public StripeEventNotificationHandler onV1PayoutReconciliationCompleted( + Callback callback) { + this.register("v1.payout.reconciliation_completed", callback); + return this; + } + + public StripeEventNotificationHandler onV1PayoutUpdated( + Callback callback) { + this.register("v1.payout.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1PersonCreated( + Callback callback) { + this.register("v1.person.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1PersonDeleted( + Callback callback) { + this.register("v1.person.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1PersonUpdated( + Callback callback) { + this.register("v1.person.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1PlanCreated( + Callback callback) { + this.register("v1.plan.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1PlanDeleted( + Callback callback) { + this.register("v1.plan.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1PlanUpdated( + Callback callback) { + this.register("v1.plan.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1PriceCreated( + Callback callback) { + this.register("v1.price.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1PriceDeleted( + Callback callback) { + this.register("v1.price.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1PriceUpdated( + Callback callback) { + this.register("v1.price.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1ProductCreated( + Callback callback) { + this.register("v1.product.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1ProductDeleted( + Callback callback) { + this.register("v1.product.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1ProductUpdated( + Callback callback) { + this.register("v1.product.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1PromotionCodeCreated( + Callback callback) { + this.register("v1.promotion_code.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1PromotionCodeUpdated( + Callback callback) { + this.register("v1.promotion_code.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1QuoteAccepted( + Callback callback) { + this.register("v1.quote.accepted", callback); + return this; + } + + public StripeEventNotificationHandler onV1QuoteCanceled( + Callback callback) { + this.register("v1.quote.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV1QuoteCreated( + Callback callback) { + this.register("v1.quote.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1QuoteFinalized( + Callback callback) { + this.register("v1.quote.finalized", callback); + return this; + } + + public StripeEventNotificationHandler onV1RadarEarlyFraudWarningCreated( + Callback callback) { + this.register("v1.radar.early_fraud_warning.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1RadarEarlyFraudWarningUpdated( + Callback callback) { + this.register("v1.radar.early_fraud_warning.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1RefundCreated( + Callback callback) { + this.register("v1.refund.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1RefundFailed( + Callback callback) { + this.register("v1.refund.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1RefundUpdated( + Callback callback) { + this.register("v1.refund.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1ReviewClosed( + Callback callback) { + this.register("v1.review.closed", callback); + return this; + } + + public StripeEventNotificationHandler onV1ReviewOpened( + Callback callback) { + this.register("v1.review.opened", callback); + return this; + } + + public StripeEventNotificationHandler onV1SetupIntentCanceled( + Callback callback) { + this.register("v1.setup_intent.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV1SetupIntentCreated( + Callback callback) { + this.register("v1.setup_intent.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1SetupIntentRequiresAction( + Callback callback) { + this.register("v1.setup_intent.requires_action", callback); + return this; + } + + public StripeEventNotificationHandler onV1SetupIntentSetupFailed( + Callback callback) { + this.register("v1.setup_intent.setup_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1SetupIntentSucceeded( + Callback callback) { + this.register("v1.setup_intent.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV1SigmaScheduledQueryRunCreated( + Callback callback) { + this.register("v1.sigma.scheduled_query_run.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1SourceCanceled( + Callback callback) { + this.register("v1.source.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV1SourceChargeable( + Callback callback) { + this.register("v1.source.chargeable", callback); + return this; + } + + public StripeEventNotificationHandler onV1SourceFailed( + Callback callback) { + this.register("v1.source.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1SourceRefundAttributesRequired( + Callback callback) { + this.register("v1.source.refund_attributes_required", callback); + return this; + } + + public StripeEventNotificationHandler onV1SubscriptionScheduleAborted( + Callback callback) { + this.register("v1.subscription_schedule.aborted", callback); + return this; + } + + public StripeEventNotificationHandler onV1SubscriptionScheduleCanceled( + Callback callback) { + this.register("v1.subscription_schedule.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV1SubscriptionScheduleCompleted( + Callback callback) { + this.register("v1.subscription_schedule.completed", callback); + return this; + } + + public StripeEventNotificationHandler onV1SubscriptionScheduleCreated( + Callback callback) { + this.register("v1.subscription_schedule.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1SubscriptionScheduleExpiring( + Callback callback) { + this.register("v1.subscription_schedule.expiring", callback); + return this; + } + + public StripeEventNotificationHandler onV1SubscriptionScheduleReleased( + Callback callback) { + this.register("v1.subscription_schedule.released", callback); + return this; + } + + public StripeEventNotificationHandler onV1SubscriptionScheduleUpdated( + Callback callback) { + this.register("v1.subscription_schedule.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1TaxSettingsUpdated( + Callback callback) { + this.register("v1.tax.settings.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1TaxRateCreated( + Callback callback) { + this.register("v1.tax_rate.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1TaxRateUpdated( + Callback callback) { + this.register("v1.tax_rate.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1TerminalReaderActionFailed( + Callback callback) { + this.register("v1.terminal.reader.action_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1TerminalReaderActionSucceeded( + Callback callback) { + this.register("v1.terminal.reader.action_succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV1TerminalReaderActionUpdated( + Callback callback) { + this.register("v1.terminal.reader.action_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV1TestHelpersTestClockAdvancing( + Callback callback) { + this.register("v1.test_helpers.test_clock.advancing", callback); + return this; + } + + public StripeEventNotificationHandler onV1TestHelpersTestClockCreated( + Callback callback) { + this.register("v1.test_helpers.test_clock.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1TestHelpersTestClockDeleted( + Callback callback) { + this.register("v1.test_helpers.test_clock.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV1TestHelpersTestClockInternalFailure( + Callback callback) { + this.register("v1.test_helpers.test_clock.internal_failure", callback); + return this; + } + + public StripeEventNotificationHandler onV1TestHelpersTestClockReady( + Callback callback) { + this.register("v1.test_helpers.test_clock.ready", callback); + return this; + } + + public StripeEventNotificationHandler onV1TopupCanceled( + Callback callback) { + this.register("v1.topup.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV1TopupCreated( + Callback callback) { + this.register("v1.topup.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1TopupFailed( + Callback callback) { + this.register("v1.topup.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV1TopupReversed( + Callback callback) { + this.register("v1.topup.reversed", callback); + return this; + } + + public StripeEventNotificationHandler onV1TopupSucceeded( + Callback callback) { + this.register("v1.topup.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV1TransferCreated( + Callback callback) { + this.register("v1.transfer.created", callback); + return this; + } + + public StripeEventNotificationHandler onV1TransferReversed( + Callback callback) { + this.register("v1.transfer.reversed", callback); + return this; + } + + public StripeEventNotificationHandler onV1TransferUpdated( + Callback callback) { + this.register("v1.transfer.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingCadenceBilled( + Callback callback) { + this.register("v2.billing.cadence.billed", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingCadenceCanceled( + Callback callback) { + this.register("v2.billing.cadence.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingCadenceCreated( + Callback callback) { + this.register("v2.billing.cadence.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingLicenseFeeCreated( + Callback callback) { + this.register("v2.billing.license_fee.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingLicenseFeeUpdated( + Callback callback) { + this.register("v2.billing.license_fee.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingLicenseFeeVersionCreated( + Callback callback) { + this.register("v2.billing.license_fee_version.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingLicensedItemCreated( + Callback callback) { + this.register("v2.billing.licensed_item.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingLicensedItemUpdated( + Callback callback) { + this.register("v2.billing.licensed_item.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingMeteredItemCreated( + Callback callback) { + this.register("v2.billing.metered_item.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingMeteredItemUpdated( + Callback callback) { + this.register("v2.billing.metered_item.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanCreated( + Callback callback) { + this.register("v2.billing.pricing_plan.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanUpdated( + Callback callback) { + this.register("v2.billing.pricing_plan.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanComponentCreated( + Callback callback) { + this.register("v2.billing.pricing_plan_component.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanComponentUpdated( + Callback callback) { + this.register("v2.billing.pricing_plan_component.updated", callback); + return this; + } + + public StripeEventNotificationHandler + onV2BillingPricingPlanSubscriptionCollectionAwaitingCustomerAction( + Callback< + V2BillingPricingPlanSubscriptionCollectionAwaitingCustomerActionEventNotification> + callback) { + this.register( + "v2.billing.pricing_plan_subscription.collection_awaiting_customer_action", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanSubscriptionCollectionCurrent( + Callback callback) { + this.register("v2.billing.pricing_plan_subscription.collection_current", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanSubscriptionCollectionPastDue( + Callback callback) { + this.register("v2.billing.pricing_plan_subscription.collection_past_due", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanSubscriptionCollectionPaused( + Callback callback) { + this.register("v2.billing.pricing_plan_subscription.collection_paused", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanSubscriptionCollectionUnpaid( + Callback callback) { + this.register("v2.billing.pricing_plan_subscription.collection_unpaid", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanSubscriptionServicingActivated( + Callback callback) { + this.register("v2.billing.pricing_plan_subscription.servicing_activated", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanSubscriptionServicingCanceled( + Callback callback) { + this.register("v2.billing.pricing_plan_subscription.servicing_canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanSubscriptionServicingPaused( + Callback callback) { + this.register("v2.billing.pricing_plan_subscription.servicing_paused", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingPricingPlanVersionCreated( + Callback callback) { + this.register("v2.billing.pricing_plan_version.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardCreated( + Callback callback) { + this.register("v2.billing.rate_card.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardUpdated( + Callback callback) { + this.register("v2.billing.rate_card.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardCustomPricingUnitOverageRateCreated( + Callback callback) { + this.register("v2.billing.rate_card_custom_pricing_unit_overage_rate.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardRateCreated( + Callback callback) { + this.register("v2.billing.rate_card_rate.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardSubscriptionActivated( + Callback callback) { + this.register("v2.billing.rate_card_subscription.activated", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardSubscriptionCanceled( + Callback callback) { + this.register("v2.billing.rate_card_subscription.canceled", callback); + return this; + } + + public StripeEventNotificationHandler + onV2BillingRateCardSubscriptionCollectionAwaitingCustomerAction( + Callback + callback) { + this.register( + "v2.billing.rate_card_subscription.collection_awaiting_customer_action", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardSubscriptionCollectionCurrent( + Callback callback) { + this.register("v2.billing.rate_card_subscription.collection_current", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardSubscriptionCollectionPastDue( + Callback callback) { + this.register("v2.billing.rate_card_subscription.collection_past_due", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardSubscriptionCollectionPaused( + Callback callback) { + this.register("v2.billing.rate_card_subscription.collection_paused", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardSubscriptionCollectionUnpaid( + Callback callback) { + this.register("v2.billing.rate_card_subscription.collection_unpaid", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardSubscriptionServicingActivated( + Callback callback) { + this.register("v2.billing.rate_card_subscription.servicing_activated", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardSubscriptionServicingCanceled( + Callback callback) { + this.register("v2.billing.rate_card_subscription.servicing_canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardSubscriptionServicingPaused( + Callback callback) { + this.register("v2.billing.rate_card_subscription.servicing_paused", callback); + return this; + } + + public StripeEventNotificationHandler onV2BillingRateCardVersionCreated( + Callback callback) { + this.register("v2.billing.rate_card_version.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2CommerceProductCatalogImportsFailed( + Callback callback) { + this.register("v2.commerce.product_catalog.imports.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2CommerceProductCatalogImportsProcessing( + Callback callback) { + this.register("v2.commerce.product_catalog.imports.processing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CommerceProductCatalogImportsSucceeded( + Callback callback) { + this.register("v2.commerce.product_catalog.imports.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV2CommerceProductCatalogImportsSucceededWithErrors( + Callback callback) { + this.register("v2.commerce.product_catalog.imports.succeeded_with_errors", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountClosed( + Callback callback) { + this.register("v2.core.account.closed", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountCreated( + Callback callback) { + this.register("v2.core.account.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountUpdated( + Callback callback) { + this.register("v2.core.account.updated", callback); + return this; + } + + public StripeEventNotificationHandler + onV2CoreAccountIncludingConfigurationCardCreatorCapabilityStatusUpdated( + Callback< + V2CoreAccountIncludingConfigurationCardCreatorCapabilityStatusUpdatedEventNotification> + callback) { + this.register( + "v2.core.account[configuration.card_creator].capability_status_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountIncludingConfigurationCardCreatorUpdated( + Callback callback) { + this.register("v2.core.account[configuration.card_creator].updated", callback); + return this; + } + + public StripeEventNotificationHandler + onV2CoreAccountIncludingConfigurationCustomerCapabilityStatusUpdated( + Callback< + V2CoreAccountIncludingConfigurationCustomerCapabilityStatusUpdatedEventNotification> + callback) { + this.register("v2.core.account[configuration.customer].capability_status_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountIncludingConfigurationCustomerUpdated( + Callback callback) { + this.register("v2.core.account[configuration.customer].updated", callback); + return this; + } + + public StripeEventNotificationHandler + onV2CoreAccountIncludingConfigurationMerchantCapabilityStatusUpdated( + Callback< + V2CoreAccountIncludingConfigurationMerchantCapabilityStatusUpdatedEventNotification> + callback) { + this.register("v2.core.account[configuration.merchant].capability_status_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountIncludingConfigurationMerchantUpdated( + Callback callback) { + this.register("v2.core.account[configuration.merchant].updated", callback); + return this; + } + + public StripeEventNotificationHandler + onV2CoreAccountIncludingConfigurationRecipientCapabilityStatusUpdated( + Callback< + V2CoreAccountIncludingConfigurationRecipientCapabilityStatusUpdatedEventNotification> + callback) { + this.register("v2.core.account[configuration.recipient].capability_status_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountIncludingConfigurationRecipientUpdated( + Callback callback) { + this.register("v2.core.account[configuration.recipient].updated", callback); + return this; + } + + public StripeEventNotificationHandler + onV2CoreAccountIncludingConfigurationStorerCapabilityStatusUpdated( + Callback< + V2CoreAccountIncludingConfigurationStorerCapabilityStatusUpdatedEventNotification> + callback) { + this.register("v2.core.account[configuration.storer].capability_status_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountIncludingConfigurationStorerUpdated( + Callback callback) { + this.register("v2.core.account[configuration.storer].updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountIncludingDefaultsUpdated( + Callback callback) { + this.register("v2.core.account[defaults].updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountIncludingFutureRequirementsUpdated( + Callback callback) { + this.register("v2.core.account[future_requirements].updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountIncludingIdentityUpdated( + Callback callback) { + this.register("v2.core.account[identity].updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountIncludingRequirementsUpdated( + Callback callback) { + this.register("v2.core.account[requirements].updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountLinkReturned( + Callback callback) { + this.register("v2.core.account_link.returned", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountPersonCreated( + Callback callback) { + this.register("v2.core.account_person.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountPersonDeleted( + Callback callback) { + this.register("v2.core.account_person.deleted", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountPersonUpdated( + Callback callback) { + this.register("v2.core.account_person.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreAccountSignalsFraudulentWebsiteReady( + Callback callback) { + this.register("v2.core.account_signals.fraudulent_website_ready", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreApprovalRequestApproved( + Callback callback) { + this.register("v2.core.approval_request.approved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreApprovalRequestCanceled( + Callback callback) { + this.register("v2.core.approval_request.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreApprovalRequestCreated( + Callback callback) { + this.register("v2.core.approval_request.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreApprovalRequestExpired( + Callback callback) { + this.register("v2.core.approval_request.expired", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreApprovalRequestFailed( + Callback callback) { + this.register("v2.core.approval_request.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreApprovalRequestRejected( + Callback callback) { + this.register("v2.core.approval_request.rejected", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreApprovalRequestSucceeded( + Callback callback) { + this.register("v2.core.approval_request.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobBatchFailed( + Callback callback) { + this.register("v2.core.batch_job.batch_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobCanceled( + Callback callback) { + this.register("v2.core.batch_job.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobCompleted( + Callback callback) { + this.register("v2.core.batch_job.completed", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobCreated( + Callback callback) { + this.register("v2.core.batch_job.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobReadyForUpload( + Callback callback) { + this.register("v2.core.batch_job.ready_for_upload", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobTimeout( + Callback callback) { + this.register("v2.core.batch_job.timeout", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobUpdated( + Callback callback) { + this.register("v2.core.batch_job.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobUploadTimeout( + Callback callback) { + this.register("v2.core.batch_job.upload_timeout", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobValidating( + Callback callback) { + this.register("v2.core.batch_job.validating", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreBatchJobValidationFailed( + Callback callback) { + this.register("v2.core.batch_job.validation_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreClaimableSandboxClaimed( + Callback callback) { + this.register("v2.core.claimable_sandbox.claimed", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreClaimableSandboxCreated( + Callback callback) { + this.register("v2.core.claimable_sandbox.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreClaimableSandboxExpired( + Callback callback) { + this.register("v2.core.claimable_sandbox.expired", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreClaimableSandboxExpiring( + Callback callback) { + this.register("v2.core.claimable_sandbox.expiring", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreClaimableSandboxUpdated( + Callback callback) { + this.register("v2.core.claimable_sandbox.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreEventDestinationPing( + Callback callback) { + this.register("v2.core.event_destination.ping", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthApiErrorFiring( + Callback callback) { + this.register("v2.core.health.api_error.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthApiErrorResolved( + Callback callback) { + this.register("v2.core.health.api_error.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthApiLatencyFiring( + Callback callback) { + this.register("v2.core.health.api_latency.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthApiLatencyResolved( + Callback callback) { + this.register("v2.core.health.api_latency.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthAuthorizationRateDropFiring( + Callback callback) { + this.register("v2.core.health.authorization_rate_drop.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthAuthorizationRateDropResolved( + Callback callback) { + this.register("v2.core.health.authorization_rate_drop.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthEventGenerationFailureResolved( + Callback callback) { + this.register("v2.core.health.event_generation_failure.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthFraudRateIncreased( + Callback callback) { + this.register("v2.core.health.fraud_rate.increased", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthIssuingAuthorizationRequestErrorsFiring( + Callback callback) { + this.register("v2.core.health.issuing_authorization_request_errors.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthIssuingAuthorizationRequestErrorsResolved( + Callback callback) { + this.register("v2.core.health.issuing_authorization_request_errors.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthIssuingAuthorizationRequestTimeoutFiring( + Callback callback) { + this.register("v2.core.health.issuing_authorization_request_timeout.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthIssuingAuthorizationRequestTimeoutResolved( + Callback callback) { + this.register("v2.core.health.issuing_authorization_request_timeout.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthMeterEventSummariesDelayedFiring( + Callback callback) { + this.register("v2.core.health.meter_event_summaries_delayed.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthMeterEventSummariesDelayedResolved( + Callback callback) { + this.register("v2.core.health.meter_event_summaries_delayed.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthPaymentMethodErrorFiring( + Callback callback) { + this.register("v2.core.health.payment_method_error.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthPaymentMethodErrorResolved( + Callback callback) { + this.register("v2.core.health.payment_method_error.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthSepaDebitDelayedFiring( + Callback callback) { + this.register("v2.core.health.sepa_debit_delayed.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthSepaDebitDelayedResolved( + Callback callback) { + this.register("v2.core.health.sepa_debit_delayed.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthTrafficVolumeDropFiring( + Callback callback) { + this.register("v2.core.health.traffic_volume_drop.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthTrafficVolumeDropResolved( + Callback callback) { + this.register("v2.core.health.traffic_volume_drop.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthWebhookLatencyFiring( + Callback callback) { + this.register("v2.core.health.webhook_latency.firing", callback); + return this; + } + + public StripeEventNotificationHandler onV2CoreHealthWebhookLatencyResolved( + Callback callback) { + this.register("v2.core.health.webhook_latency.resolved", callback); + return this; + } + + public StripeEventNotificationHandler onV2DataReportingQueryRunCreated( + Callback callback) { + this.register("v2.data.reporting.query_run.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2DataReportingQueryRunFailed( + Callback callback) { + this.register("v2.data.reporting.query_run.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2DataReportingQueryRunSucceeded( + Callback callback) { + this.register("v2.data.reporting.query_run.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV2DataReportingQueryRunUpdated( + Callback callback) { + this.register("v2.data.reporting.query_run.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2ExtendExtensionRunFailed( + Callback callback) { + this.register("v2.extend.extension_run.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2ExtendWorkflowRunFailed( + Callback callback) { + this.register("v2.extend.workflow_run.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2ExtendWorkflowRunStarted( + Callback callback) { + this.register("v2.extend.workflow_run.started", callback); + return this; + } + + public StripeEventNotificationHandler onV2ExtendWorkflowRunSucceeded( + Callback callback) { + this.register("v2.extend.workflow_run.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamApiKeyCreated( + Callback callback) { + this.register("v2.iam.api_key.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamApiKeyDefaultSecretRevealed( + Callback callback) { + this.register("v2.iam.api_key.default_secret_revealed", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamApiKeyExpired( + Callback callback) { + this.register("v2.iam.api_key.expired", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamApiKeyPermissionsUpdated( + Callback callback) { + this.register("v2.iam.api_key.permissions_updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamApiKeyRotated( + Callback callback) { + this.register("v2.iam.api_key.rotated", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamApiKeyUpdated( + Callback callback) { + this.register("v2.iam.api_key.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamStripeAccessGrantApproved( + Callback callback) { + this.register("v2.iam.stripe_access_grant.approved", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamStripeAccessGrantCanceled( + Callback callback) { + this.register("v2.iam.stripe_access_grant.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamStripeAccessGrantDenied( + Callback callback) { + this.register("v2.iam.stripe_access_grant.denied", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamStripeAccessGrantRemoved( + Callback callback) { + this.register("v2.iam.stripe_access_grant.removed", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamStripeAccessGrantRequested( + Callback callback) { + this.register("v2.iam.stripe_access_grant.requested", callback); + return this; + } + + public StripeEventNotificationHandler onV2IamStripeAccessGrantUpdated( + Callback callback) { + this.register("v2.iam.stripe_access_grant.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementAdjustmentCreated( + Callback callback) { + this.register("v2.money_management.adjustment.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementFinancialAccountCreated( + Callback callback) { + this.register("v2.money_management.financial_account.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementFinancialAccountUpdated( + Callback callback) { + this.register("v2.money_management.financial_account.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementFinancialAddressActivated( + Callback callback) { + this.register("v2.money_management.financial_address.activated", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementFinancialAddressFailed( + Callback callback) { + this.register("v2.money_management.financial_address.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementInboundTransferAvailable( + Callback callback) { + this.register("v2.money_management.inbound_transfer.available", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementInboundTransferBankDebitFailed( + Callback callback) { + this.register("v2.money_management.inbound_transfer.bank_debit_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementInboundTransferBankDebitProcessing( + Callback callback) { + this.register("v2.money_management.inbound_transfer.bank_debit_processing", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementInboundTransferBankDebitQueued( + Callback callback) { + this.register("v2.money_management.inbound_transfer.bank_debit_queued", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementInboundTransferBankDebitReturned( + Callback callback) { + this.register("v2.money_management.inbound_transfer.bank_debit_returned", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementInboundTransferBankDebitSucceeded( + Callback callback) { + this.register("v2.money_management.inbound_transfer.bank_debit_succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundPaymentCanceled( + Callback callback) { + this.register("v2.money_management.outbound_payment.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundPaymentCreated( + Callback callback) { + this.register("v2.money_management.outbound_payment.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundPaymentFailed( + Callback callback) { + this.register("v2.money_management.outbound_payment.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundPaymentPosted( + Callback callback) { + this.register("v2.money_management.outbound_payment.posted", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundPaymentReturned( + Callback callback) { + this.register("v2.money_management.outbound_payment.returned", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundPaymentUpdated( + Callback callback) { + this.register("v2.money_management.outbound_payment.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundTransferCanceled( + Callback callback) { + this.register("v2.money_management.outbound_transfer.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundTransferCreated( + Callback callback) { + this.register("v2.money_management.outbound_transfer.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundTransferFailed( + Callback callback) { + this.register("v2.money_management.outbound_transfer.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundTransferPosted( + Callback callback) { + this.register("v2.money_management.outbound_transfer.posted", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundTransferReturned( + Callback callback) { + this.register("v2.money_management.outbound_transfer.returned", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementOutboundTransferUpdated( + Callback callback) { + this.register("v2.money_management.outbound_transfer.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementPayoutMethodCreated( + Callback callback) { + this.register("v2.money_management.payout_method.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementPayoutMethodUpdated( + Callback callback) { + this.register("v2.money_management.payout_method.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementReceivedCreditAvailable( + Callback callback) { + this.register("v2.money_management.received_credit.available", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementReceivedCreditFailed( + Callback callback) { + this.register("v2.money_management.received_credit.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementReceivedCreditReturned( + Callback callback) { + this.register("v2.money_management.received_credit.returned", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementReceivedCreditSucceeded( + Callback callback) { + this.register("v2.money_management.received_credit.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementReceivedDebitCanceled( + Callback callback) { + this.register("v2.money_management.received_debit.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementReceivedDebitFailed( + Callback callback) { + this.register("v2.money_management.received_debit.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementReceivedDebitPending( + Callback callback) { + this.register("v2.money_management.received_debit.pending", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementReceivedDebitSucceeded( + Callback callback) { + this.register("v2.money_management.received_debit.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementReceivedDebitUpdated( + Callback callback) { + this.register("v2.money_management.received_debit.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementRecipientVerificationCreated( + Callback callback) { + this.register("v2.money_management.recipient_verification.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementRecipientVerificationUpdated( + Callback callback) { + this.register("v2.money_management.recipient_verification.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementTransactionCreated( + Callback callback) { + this.register("v2.money_management.transaction.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2MoneyManagementTransactionUpdated( + Callback callback) { + this.register("v2.money_management.transaction.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2OrchestratedCommerceAgreementConfirmed( + Callback callback) { + this.register("v2.orchestrated_commerce.agreement.confirmed", callback); + return this; + } + + public StripeEventNotificationHandler onV2OrchestratedCommerceAgreementCreated( + Callback callback) { + this.register("v2.orchestrated_commerce.agreement.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2OrchestratedCommerceAgreementPartiallyConfirmed( + Callback callback) { + this.register("v2.orchestrated_commerce.agreement.partially_confirmed", callback); + return this; + } + + public StripeEventNotificationHandler onV2OrchestratedCommerceAgreementTerminated( + Callback callback) { + this.register("v2.orchestrated_commerce.agreement.terminated", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentAttemptFailed( + Callback callback) { + this.register("v2.payments.off_session_payment.attempt_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentAttemptStarted( + Callback callback) { + this.register("v2.payments.off_session_payment.attempt_started", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentAuthorizationAttemptFailed( + Callback callback) { + this.register("v2.payments.off_session_payment.authorization_attempt_failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentAuthorizationAttemptStarted( + Callback callback) { + this.register("v2.payments.off_session_payment.authorization_attempt_started", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentCanceled( + Callback callback) { + this.register("v2.payments.off_session_payment.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentCreated( + Callback callback) { + this.register("v2.payments.off_session_payment.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentFailed( + Callback callback) { + this.register("v2.payments.off_session_payment.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentPaused( + Callback callback) { + this.register("v2.payments.off_session_payment.paused", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentRequiresCapture( + Callback callback) { + this.register("v2.payments.off_session_payment.requires_capture", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentResumed( + Callback callback) { + this.register("v2.payments.off_session_payment.resumed", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsOffSessionPaymentSucceeded( + Callback callback) { + this.register("v2.payments.off_session_payment.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentCanceled( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentCreated( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentErrored( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent.errored", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentFundsNotReceived( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent.funds_not_received", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentMatched( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent.matched", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentNotFound( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent.not_found", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentSettled( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent.settled", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentSubmitted( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent.submitted", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentSplitCanceled( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent_split.canceled", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentSplitCreated( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent_split.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2PaymentsSettlementAllocationIntentSplitSettled( + Callback callback) { + this.register("v2.payments.settlement_allocation_intent_split.settled", callback); + return this; + } + + public StripeEventNotificationHandler onV2ReportingReportRunCreated( + Callback callback) { + this.register("v2.reporting.report_run.created", callback); + return this; + } + + public StripeEventNotificationHandler onV2ReportingReportRunFailed( + Callback callback) { + this.register("v2.reporting.report_run.failed", callback); + return this; + } + + public StripeEventNotificationHandler onV2ReportingReportRunSucceeded( + Callback callback) { + this.register("v2.reporting.report_run.succeeded", callback); + return this; + } + + public StripeEventNotificationHandler onV2ReportingReportRunUpdated( + Callback callback) { + this.register("v2.reporting.report_run.updated", callback); + return this; + } + + public StripeEventNotificationHandler onV2SignalsAccountSignalFraudulentMerchantReady( + Callback callback) { + this.register("v2.signals.account_signal.fraudulent_merchant_ready", callback); + return this; + } + // notification-handler-methods: The end of the section generated from our OpenAPI spec + + /** + * Get a sorted list of all registered event types. + * + * @return A sorted list of event type strings + */ + public List getRegisteredEventTypes() { + List eventTypes = new ArrayList<>(this.registeredHandlers.keySet()); + Collections.sort(eventTypes); + return eventTypes; + } +} diff --git a/src/main/java/com/stripe/events/UnknownEventNotification.java b/src/main/java/com/stripe/events/UnknownEventNotification.java index c70a4cca034..a91141b59fc 100644 --- a/src/main/java/com/stripe/events/UnknownEventNotification.java +++ b/src/main/java/com/stripe/events/UnknownEventNotification.java @@ -1,3 +1,4 @@ +// File copied from our code generator; changes here will be overwritten. package com.stripe.events; import com.google.gson.annotations.SerializedName; diff --git a/src/main/java/com/stripe/examples/EventNotificationHandlerEndpoint.java b/src/main/java/com/stripe/examples/EventNotificationHandlerEndpoint.java new file mode 100644 index 00000000000..6a0288f4098 --- /dev/null +++ b/src/main/java/com/stripe/examples/EventNotificationHandlerEndpoint.java @@ -0,0 +1,108 @@ +// File copied from our code generator; changes here will be overwritten. +package com.stripe.examples; + +import com.stripe.StripeClient; +import com.stripe.StripeEventNotificationHandler; +import com.stripe.StripeEventNotificationHandler.UnhandledNotificationDetails; +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 event notifications (AKA thin events) like + * "v1.billing.meter.error_report_triggered" using EventNotificationHandler. + * + *

In this example, we: + * + *

+ */ +public class EventNotificationHandlerEndpoint { + 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); + private static final StripeEventNotificationHandler handler = + client.notificationHandler( + WEBHOOK_SECRET, EventNotificationHandlerEndpoint::fallbackCallback); + + public static void main(String[] args) throws IOException { + handler.onV1BillingMeterErrorReportTriggered( + EventNotificationHandlerEndpoint::handleMeterErrors); + + HttpServer server = HttpServer.create(new InetSocketAddress(4242), 0); + server.createContext("/webhook", new WebhookHandler()); + server.setExecutor(null); + server.start(); + } + + private static void fallbackCallback( + EventNotification notif, StripeClient client, UnhandledNotificationDetails details) { + System.out.println("Received unhandled event notification type: " + notif.getType()); + } + + private static void handleMeterErrors( + V1BillingMeterErrorReportTriggeredEventNotification notif, StripeClient client) { + Meter meter; + try { + meter = notif.fetchRelatedObject(); + } catch (StripeException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return; + } + System.out.println("Handling meter error for meter: " + meter.getDisplayName()); + } + + 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 { + handler.handle(webhookBody, sigHeader); + + 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/EventNotificationWebhookHandler.java b/src/main/java/com/stripe/examples/EventNotificationWebhookHandler.java index 728b786d83f..82829cb1901 100644 --- a/src/main/java/com/stripe/examples/EventNotificationWebhookHandler.java +++ b/src/main/java/com/stripe/examples/EventNotificationWebhookHandler.java @@ -1,3 +1,4 @@ +// File copied from our code generator; changes here will be overwritten. package com.stripe.examples; import com.stripe.StripeClient; diff --git a/src/main/java/com/stripe/model/v2/core/EventNotification.java b/src/main/java/com/stripe/model/v2/core/EventNotification.java index 374abbb60f8..a56742d3a4a 100644 --- a/src/main/java/com/stripe/model/v2/core/EventNotification.java +++ b/src/main/java/com/stripe/model/v2/core/EventNotification.java @@ -1,3 +1,4 @@ +// File copied from our code generator; changes here will be overwritten. package com.stripe.model.v2.core; import com.google.gson.JsonObject; diff --git a/src/main/java/com/stripe/net/LiveStripeResponseGetter.java b/src/main/java/com/stripe/net/LiveStripeResponseGetter.java index 763f8cdb82a..fda88ce18f3 100644 --- a/src/main/java/com/stripe/net/LiveStripeResponseGetter.java +++ b/src/main/java/com/stripe/net/LiveStripeResponseGetter.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.function.Function; public class LiveStripeResponseGetter implements StripeResponseGetter { private final HttpClient httpClient; @@ -76,6 +77,26 @@ public LiveStripeResponseGetter(StripeResponseGetterOptions options, HttpClient this.httpClient = (httpClient != null) ? httpClient : buildDefaultHttpClient(); } + /** + * Creates a new LiveStripeResponseGetter with the same configuration and HTTP client as this + * instance, but with a different stripe_context. This allows for efficient cloning when you need + * to make requests with different contexts (e.g., webhook processing) without reinitializing HTTP + * connections. + * + * @param contextCreator a function that takes the existing options and returns new options with + * the desired context + * @return a new LiveStripeResponseGetter with the updated options and the same HTTP client + */ + public LiveStripeResponseGetter withNewOptions( + Function contextCreator) { + StripeResponseGetterOptions newOptions = contextCreator.apply(this.options); + return new LiveStripeResponseGetter(newOptions, this.httpClient); + } + + public StripeResponseGetterOptions getOptions() { + return this.options; + } + private StripeRequest toStripeRequest(ApiRequest apiRequest, RequestOptions mergedOptions) throws StripeException { String fullUrl = fullUrl(apiRequest); diff --git a/src/test/java/com/stripe/StripeEventNotificationHandlerTest.java b/src/test/java/com/stripe/StripeEventNotificationHandlerTest.java new file mode 100644 index 00000000000..31c567d6468 --- /dev/null +++ b/src/test/java/com/stripe/StripeEventNotificationHandlerTest.java @@ -0,0 +1,518 @@ +// File copied from our code generator; changes here will be overwritten. +package com.stripe; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import com.stripe.events.UnknownEventNotification; +import com.stripe.events.V1BillingMeterErrorReportTriggeredEventNotification; +import com.stripe.events.V2CoreAccountCreatedEventNotification; +import com.stripe.exception.SignatureVerificationException; +import com.stripe.model.v2.core.EventNotification; +import com.stripe.net.Webhook; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class StripeEventNotificationHandlerTest { + private static final String DUMMY_WEBHOOK_SECRET = "whsec_test_secret"; + + private StripeClient stripeClient; + private StripeEventNotificationHandler.FallbackCallback fallbackCallback; + private StripeEventNotificationHandler eventNotificationHandler; + + private String v1BillingMeterPayload; + private String v2AccountCreatedPayload; + private String unknownEventPayload; + + @BeforeEach + public void setUp() { + // Create a StripeClient with context + stripeClient = + StripeClient.builder() + .setApiKey("sk_test_1234") + .setStripeContext("original_context_123") + .build(); + + // Create mock handler for unhandled events + fallbackCallback = mock(StripeEventNotificationHandler.FallbackCallback.class); + + // Create event router + eventNotificationHandler = + new StripeEventNotificationHandler(DUMMY_WEBHOOK_SECRET, stripeClient, fallbackCallback); + + // Set up test payloads + v1BillingMeterPayload = + "{" + + "\"id\": \"evt_123\"," + + "\"object\": \"v2.core.event\"," + + "\"type\": \"v1.billing.meter.error_report_triggered\"," + + "\"livemode\": false," + + "\"created\": \"2022-02-15T00:27:45.330Z\"," + + "\"context\": \"event_context_456\"," + + "\"related_object\": {" + + "\"id\": \"mtr_123\"," + + "\"type\": \"billing.meter\"," + + "\"url\": \"/v1/billing/meters/mtr_123\"" + + "}" + + "}"; + + v2AccountCreatedPayload = + "{" + + "\"id\": \"evt_789\"," + + "\"object\": \"v2.core.event\"," + + "\"type\": \"v2.core.account.created\"," + + "\"livemode\": false," + + "\"created\": \"2022-02-15T00:27:45.330Z\"," + + "\"context\": null," + + "\"related_object\": {" + + "\"id\": \"acct_abc\"," + + "\"type\": \"account\"," + + "\"url\": \"/v2/core/accounts/acct_abc\"" + + "}" + + "}"; + + unknownEventPayload = + "{" + + "\"id\": \"evt_unknown\"," + + "\"object\": \"v2.core.event\"," + + "\"type\": \"llama.created\"," + + "\"livemode\": false," + + "\"created\": \"2022-02-15T00:27:45.330Z\"," + + "\"context\": \"event_context_unknown\"," + + "\"related_object\": {" + + "\"id\": \"llama_123\"," + + "\"type\": \"llama\"," + + "\"url\": \"/v1/llamas/llama_123\"" + + "}" + + "}"; + } + + private String generateSigHeader(String payload) + throws NoSuchAlgorithmException, InvalidKeyException { + Map options = new HashMap<>(); + options.put("payload", payload); + options.put("secret", DUMMY_WEBHOOK_SECRET); + return generateSigHeader(options); + } + + private String generateSigHeader(Map options) + throws NoSuchAlgorithmException, InvalidKeyException { + final long timestamp = + (options.get("timestamp") != null) + ? ((Long) options.get("timestamp")).longValue() + : Webhook.Util.getTimeNow(); + final String payload = (String) options.get("payload"); + final String secret = (String) options.get("secret"); + final String scheme = + (options.get("scheme") != null) + ? (String) options.get("scheme") + : Webhook.Signature.EXPECTED_SCHEME; + String signature = (String) options.get("signature"); + + if (signature == null) { + final String payloadToSign = String.format("%d.%s", timestamp, payload); + signature = Webhook.Util.computeHmacSha256(secret, payloadToSign); + } + + return String.format("t=%d,%s=%s", timestamp, scheme, signature); + } + + @Test + public void testRoutesEventToRegisteredHandler() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that a registered event type is routed to the correct handler + @SuppressWarnings("unchecked") + StripeEventNotificationHandler.Callback + handler = mock(StripeEventNotificationHandler.Callback.class); + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler); + + String sigHeader = generateSigHeader(v1BillingMeterPayload); + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader); + + verify(handler, times(1)) + .process(org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()); + verify(fallbackCallback, never()) + .process( + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any()); + } + + @SuppressWarnings("unchecked") + @Test + public void testRoutesDifferentEventsToCorrectHandlers() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that different event types route to their respective handlers + StripeEventNotificationHandler.Callback + billingHandler = mock(StripeEventNotificationHandler.Callback.class); + StripeEventNotificationHandler.Callback accountHandler = + mock(StripeEventNotificationHandler.Callback.class); + + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(billingHandler); + eventNotificationHandler.onV2CoreAccountCreated(accountHandler); + + String sigHeader1 = generateSigHeader(v1BillingMeterPayload); + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader1); + + String sigHeader2 = generateSigHeader(v2AccountCreatedPayload); + eventNotificationHandler.handle(v2AccountCreatedPayload, sigHeader2); + + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader1); + + verify(billingHandler, times(2)) + .process(org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()); + verify(accountHandler, times(1)) + .process(org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()); + verify(fallbackCallback, never()) + .process( + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any()); + } + + @Test + public void testHandlerReceivesCorrectRuntimeType() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that handlers receive the correctly typed event notification + AtomicReference receivedEvent = new AtomicReference<>(); + AtomicReference receivedClient = new AtomicReference<>(); + + StripeEventNotificationHandler.Callback + handler = + (event, client) -> { + receivedEvent.set(event); + receivedClient.set(client); + }; + + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler); + + String sigHeader = generateSigHeader(v1BillingMeterPayload); + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader); + + assertInstanceOf( + V1BillingMeterErrorReportTriggeredEventNotification.class, receivedEvent.get()); + V1BillingMeterErrorReportTriggeredEventNotification notification = + (V1BillingMeterErrorReportTriggeredEventNotification) receivedEvent.get(); + assertEquals("v1.billing.meter.error_report_triggered", notification.getType()); + assertEquals("evt_123", notification.getId()); + assertEquals("mtr_123", notification.getRelatedObject().getId()); + assertNotNull(receivedClient.get()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCannotRegisterHandlerAfterHandling() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that registering handlers after handle() raises IllegalStateException + StripeEventNotificationHandler.Callback + handler = mock(StripeEventNotificationHandler.Callback.class); + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler); + + String sigHeader = generateSigHeader(v1BillingMeterPayload); + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader); + + IllegalStateException exception = + assertThrows( + IllegalStateException.class, + () -> + eventNotificationHandler.onV2CoreAccountCreated( + mock(StripeEventNotificationHandler.Callback.class))); + + assertTrue(exception.getMessage().contains("Cannot register handlers after handling an event")); + } + + @SuppressWarnings("unchecked") + @Test + public void testCannotRegisterDuplicateHandler() { + // Test that registering the same event type twice raises IllegalArgumentException + StripeEventNotificationHandler.Callback + handler1 = mock(StripeEventNotificationHandler.Callback.class); + StripeEventNotificationHandler.Callback + handler2 = mock(StripeEventNotificationHandler.Callback.class); + + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler1); + + IllegalArgumentException exception = + assertThrows( + IllegalArgumentException.class, + () -> eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler2)); + + assertTrue( + exception + .getMessage() + .contains( + "Handler already registered for event type: v1.billing.meter.error_report_triggered")); + } + + @Test + public void testHandlerUsesEventStripeContext() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that the handler receives a client with stripe_context from the event + AtomicReference receivedContext = new AtomicReference<>(); + + StripeEventNotificationHandler.Callback + handler = + (event, client) -> { + receivedContext.set(client.getContext()); + }; + + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler); + + assertEquals("original_context_123", stripeClient.getContext()); + + String sigHeader = generateSigHeader(v1BillingMeterPayload); + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader); + + assertEquals("event_context_456", receivedContext.get()); + } + + @Test + public void testStripeContextRestoredAfterHandlerSuccess() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that the original stripe_context is restored after successful handler execution + StripeEventNotificationHandler.Callback + handler = + (event, client) -> { + assertEquals("event_context_456", client.getContext()); + }; + + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler); + + assertEquals("original_context_123", stripeClient.getContext()); + + String sigHeader = generateSigHeader(v1BillingMeterPayload); + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader); + + assertEquals("original_context_123", stripeClient.getContext()); + } + + @Test + public void testStripeContextRestoredAfterHandlerError() + throws NoSuchAlgorithmException, InvalidKeyException { + // Test that the original stripe_context is restored even when handler raises an exception + StripeEventNotificationHandler.Callback + handler = + (event, client) -> { + assertEquals("event_context_456", client.getContext()); + throw new RuntimeException("Handler error!"); + }; + + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler); + + assertEquals("original_context_123", stripeClient.getContext()); + + String sigHeader = generateSigHeader(v1BillingMeterPayload); + + RuntimeException exception = + assertThrows( + RuntimeException.class, + () -> eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader)); + assertEquals("Handler error!", exception.getMessage()); + + assertEquals("original_context_123", stripeClient.getContext()); + } + + @Test + public void testStripeContextSetToNullWhenEventHasNoContext() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that stripe_context is set to null when event context is null + AtomicReference receivedContext = new AtomicReference<>(); + + StripeEventNotificationHandler.Callback handler = + (event, client) -> { + receivedContext.set(client.getContext()); + }; + + eventNotificationHandler.onV2CoreAccountCreated(handler); + + assertEquals("original_context_123", stripeClient.getContext()); + + String sigHeader = generateSigHeader(v2AccountCreatedPayload); + eventNotificationHandler.handle(v2AccountCreatedPayload, sigHeader); + + assertNull(receivedContext.get()); + assertEquals("original_context_123", stripeClient.getContext()); + } + + @Test + public void testUnknownEventRoutesToOnUnhandled() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that events without SDK types rout handler + String sigHeader = generateSigHeader(unknownEventPayload); + eventNotificationHandler.handle(unknownEventPayload, sigHeader); + + verify(fallbackCallback, times(1)) + .process( + org.mockito.ArgumentMatchers.argThat( + event -> + event instanceof UnknownEventNotification + && event.getType().equals("llama.created")), + org.mockito.ArgumentMatchers.any(StripeClient.class), + org.mockito.ArgumentMatchers.argThat(info -> info.isKnownEventType() == false)); + } + + @Test + public void testKnownUnregisteredEventRoutesToOnUnhandled() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that known event types without a registered handler rout + String sigHeader = generateSigHeader(v1BillingMeterPayload); + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader); + + verify(fallbackCallback, times(1)) + .process( + org.mockito.ArgumentMatchers.argThat( + event -> + event instanceof V1BillingMeterErrorReportTriggeredEventNotification + && event.getType().equals("v1.billing.meter.error_report_triggered")), + org.mockito.ArgumentMatchers.any(StripeClient.class), + org.mockito.ArgumentMatchers.argThat(info -> info.isKnownEventType() == true)); + } + + @SuppressWarnings("unchecked") + @Test + public void testRegisteredEventDoesNotCallOnUnhandled() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that registered events don't tri + StripeEventNotificationHandler.Callback + handler = mock(StripeEventNotificationHandler.Callback.class); + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler); + + String sigHeader = generateSigHeader(v1BillingMeterPayload); + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader); + + verify(handler, times(1)) + .process(org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any()); + verify(fallbackCallback, never()) + .process( + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any(), + org.mockito.ArgumentMatchers.any()); + } + + @Test + public void testHandlerClientRetainsConfiguration() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test that the client passed to handlers retains all configuration except stripe_context + String originalContext = "original_context_xyz"; + + StripeClient customClient = + StripeClient.builder() + .setApiKey("sk_test_custom_key") + .setStripeContext(originalContext) + .build(); + + StripeEventNotificationHandler customRouter = + new StripeEventNotificationHandler(DUMMY_WEBHOOK_SECRET, customClient, fallbackCallback); + + AtomicReference receivedContext = new AtomicReference<>(); + + StripeEventNotificationHandler.Callback + handler = + (event, client) -> { + receivedContext.set(client.getContext()); + }; + + customRouter.onV1BillingMeterErrorReportTriggered(handler); + + String sigHeader = generateSigHeader(v1BillingMeterPayload); + customRouter.handle(v1BillingMeterPayload, sigHeader); + + assertEquals("event_context_456", receivedContext.get()); + assertEquals(originalContext, customClient.getContext()); + } + + @Test + public void testOnUnhandledReceivesCorrectInfoForUnknown() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test receives correct UnhandledNotificationDetails for unknown events + String sigHeader = generateSigHeader(unknownEventPayload); + eventNotificationHandler.handle(unknownEventPayload, sigHeader); + + verify(fallbackCallback, times(1)) + .process( + org.mockito.ArgumentMatchers.any(EventNotification.class), + org.mockito.ArgumentMatchers.any(StripeClient.class), + org.mockito.ArgumentMatchers.argThat(info -> info.isKnownEventType() == false)); + } + + @Test + public void testOnUnhandledReceivesCorrectInfoForKnownUnregistered() + throws SignatureVerificationException, NoSuchAlgorithmException, InvalidKeyException { + // Test receives correct UnhandledNotificationDetails for known unregistered + // events + String sigHeader = generateSigHeader(v1BillingMeterPayload); + eventNotificationHandler.handle(v1BillingMeterPayload, sigHeader); + + verify(fallbackCallback, times(1)) + .process( + org.mockito.ArgumentMatchers.any(EventNotification.class), + org.mockito.ArgumentMatchers.any(StripeClient.class), + org.mockito.ArgumentMatchers.argThat(info -> info.isKnownEventType() == true)); + } + + @Test + public void testValidatesWebhookSignature() { + // Test that invalid webhook signatures are rejected + assertThrows( + SignatureVerificationException.class, + () -> eventNotificationHandler.handle(v1BillingMeterPayload, "invalid_signature")); + } + + @Test + public void testRegisteredEventTypesEmpty() { + // Test that registered_event_types returns empty list when no handlers are registered + List eventTypes = eventNotificationHandler.getRegisteredEventTypes(); + assertNotNull(eventTypes); + assertTrue(eventTypes.isEmpty()); + } + + @SuppressWarnings("unchecked") + @Test + public void testRegisteredEventTypesSingle() { + // Test that registered_event_types returns a single event type + StripeEventNotificationHandler.Callback + handler = mock(StripeEventNotificationHandler.Callback.class); + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler); + + List eventTypes = eventNotificationHandler.getRegisteredEventTypes(); + assertEquals(1, eventTypes.size()); + assertEquals("v1.billing.meter.error_report_triggered", eventTypes.get(0)); + } + + @SuppressWarnings({"rawtypes", "unchecked"}) + @Test + public void testRegisteredEventTypesMultipleAlphabetized() { + // Test that registered_event_types returns multiple event types in alphabetical order + StripeEventNotificationHandler.Callback handler = + mock(StripeEventNotificationHandler.Callback.class); + + // Register in non-alphabetical order + eventNotificationHandler.onV2CoreAccountUpdated(handler); + eventNotificationHandler.onV1BillingMeterErrorReportTriggered(handler); + eventNotificationHandler.onV2CoreAccountCreated(handler); + + List expected = + Arrays.asList( + "v1.billing.meter.error_report_triggered", + "v2.core.account.created", + "v2.core.account.updated"); + + List eventTypes = eventNotificationHandler.getRegisteredEventTypes(); + assertEquals(expected, eventTypes); + } +}