diff --git a/openapi.json b/openapi.json index 89e9550..7b95b9e 100644 --- a/openapi.json +++ b/openapi.json @@ -11455,6 +11455,221 @@ } }, "webhooks": { + "checkouts.created": { + "post": { + "operationId": "CheckoutCreatedWebhook", + "tags": [ + "Checkouts" + ], + "summary": "Checkout created", + "description": "Sent once when a checkout is first observed in the checkout snapshot stream, even if it is already paid, failed, or expired. The event timestamp is the original checkout creation time.", + "x-object": { + "$ref": "#/components/schemas/Checkout" + }, + "x-object-type": "checkout", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Event" + }, + "examples": { + "created": { + "value": { + "id": "event_01ARZ3NDEKTSV4RRFFQ69G5FAV", + "type": "checkouts.created", + "created_at": "2026-10-15T12:00:00Z", + "object": { + "id": "e552de3b-1777-4c91-bdb8-756967678572", + "type": "checkout", + "url": "https://api.sumup.com/v0.1/checkouts/e552de3b-1777-4c91-bdb8-756967678572" + } + } + } + } + } + } + }, + "responses": { + "2XX": { + "description": "Return any 2xx response to acknowledge successful delivery." + } + } + } + }, + "checkouts.failed": { + "post": { + "operationId": "CheckoutFailedWebhook", + "tags": [ + "Checkouts" + ], + "summary": "Checkout failed", + "description": "Sent once when a checkout is first observed with status FAILED. A failed checkout can subsequently be retried and paid. Later FAILED snapshots do not emit another failed event.", + "x-object": { + "$ref": "#/components/schemas/Checkout" + }, + "x-object-type": "checkout", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Event" + }, + "examples": { + "failed": { + "value": { + "id": "event_01ARZ3NDEKTSV4RRFFQ69G5FAV", + "type": "checkouts.failed", + "created_at": "2026-10-15T12:00:00Z", + "object": { + "id": "e552de3b-1777-4c91-bdb8-756967678572", + "type": "checkout", + "url": "https://api.sumup.com/v0.1/checkouts/e552de3b-1777-4c91-bdb8-756967678572" + } + } + } + } + } + } + }, + "responses": { + "2XX": { + "description": "Return any 2xx response to acknowledge successful delivery." + } + } + } + }, + "checkouts.expired": { + "post": { + "operationId": "CheckoutExpiredWebhook", + "tags": [ + "Checkouts" + ], + "summary": "Checkout expired", + "description": "Sent once when a checkout is first observed with status EXPIRED. Expiry or deactivation without an upstream snapshot cannot produce this event. Later EXPIRED snapshots do not emit another expired event.", + "x-object": { + "$ref": "#/components/schemas/Checkout" + }, + "x-object-type": "checkout", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Event" + }, + "examples": { + "expired": { + "value": { + "id": "event_01ARZ3NDEKTSV4RRFFQ69G5FAV", + "type": "checkouts.expired", + "created_at": "2026-10-15T12:00:00Z", + "object": { + "id": "e552de3b-1777-4c91-bdb8-756967678572", + "type": "checkout", + "url": "https://api.sumup.com/v0.1/checkouts/e552de3b-1777-4c91-bdb8-756967678572" + } + } + } + } + } + } + }, + "responses": { + "2XX": { + "description": "Return any 2xx response to acknowledge successful delivery." + } + } + } + }, + "checkouts.updated": { + "post": { + "operationId": "CheckoutUpdatedWebhook", + "tags": [ + "Checkouts" + ], + "summary": "Checkout updated", + "description": "Sent when a checkout snapshot is published, including creation and payment status updates. Fetch the checkout to inspect its current status. This is not a guarantee that every checkout mutation produces a notification.", + "x-object": { + "$ref": "#/components/schemas/Checkout" + }, + "x-object-type": "checkout", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Event" + }, + "examples": { + "updated": { + "value": { + "id": "event_01ARZ3NDEKTSV4RRFFQ69G5FAV", + "type": "checkouts.updated", + "created_at": "2026-10-15T12:00:00Z", + "object": { + "id": "e552de3b-1777-4c91-bdb8-756967678572", + "type": "checkout", + "url": "https://api.sumup.com/v0.1/checkouts/e552de3b-1777-4c91-bdb8-756967678572" + } + } + } + } + } + } + }, + "responses": { + "2XX": { + "description": "Return any 2xx response to acknowledge successful delivery." + } + } + } + }, + "checkouts.paid": { + "post": { + "operationId": "CheckoutPaidWebhook", + "tags": [ + "Checkouts" + ], + "summary": "Checkout paid", + "description": "Sent once when a checkout is first observed with status PAID. Later PAID snapshots do not emit another paid event. The timestamp is the snapshot update time, not necessarily the payment completion time.", + "x-object": { + "$ref": "#/components/schemas/Checkout" + }, + "x-object-type": "checkout", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Event" + }, + "examples": { + "paid": { + "value": { + "id": "event_01ARZ3NDEKTSV4RRFFQ69G5FAV", + "type": "checkouts.paid", + "created_at": "2026-10-15T12:00:00Z", + "object": { + "id": "e552de3b-1777-4c91-bdb8-756967678572", + "type": "checkout", + "url": "https://api.sumup.com/v0.1/checkouts/e552de3b-1777-4c91-bdb8-756967678572" + } + } + } + } + } + } + }, + "responses": { + "2XX": { + "description": "Return any 2xx response to acknowledge successful delivery." + } + } + } + }, "readers.created": { "post": { "operationId": "ReaderCreatedWebhook", diff --git a/src/main/java/com/sumup/sdk/events/AsyncEventsHandler.java b/src/main/java/com/sumup/sdk/events/AsyncEventsHandler.java index d2d7fad..2ac53cb 100644 --- a/src/main/java/com/sumup/sdk/events/AsyncEventsHandler.java +++ b/src/main/java/com/sumup/sdk/events/AsyncEventsHandler.java @@ -48,6 +48,66 @@ public EventNotification parse(byte[] body, String signature) { return EventNotification.parse(client, body, signature, secret); } + /** + * Registers the callback for {@code "checkouts.created"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public AsyncEventsHandler onCheckoutCreated(AsyncEventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put("checkouts.created", event -> callback.handle((CheckoutCreatedEvent) event)); + return this; + } + + /** + * Registers the callback for {@code "checkouts.expired"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public AsyncEventsHandler onCheckoutExpired(AsyncEventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put("checkouts.expired", event -> callback.handle((CheckoutExpiredEvent) event)); + return this; + } + + /** + * Registers the callback for {@code "checkouts.failed"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public AsyncEventsHandler onCheckoutFailed(AsyncEventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put("checkouts.failed", event -> callback.handle((CheckoutFailedEvent) event)); + return this; + } + + /** + * Registers the callback for {@code "checkouts.paid"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public AsyncEventsHandler onCheckoutPaid(AsyncEventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put("checkouts.paid", event -> callback.handle((CheckoutPaidEvent) event)); + return this; + } + + /** + * Registers the callback for {@code "checkouts.updated"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public AsyncEventsHandler onCheckoutUpdated(AsyncEventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put("checkouts.updated", event -> callback.handle((CheckoutUpdatedEvent) event)); + return this; + } + /** * Registers the callback for {@code "members.created"}, replacing any previous registration. * diff --git a/src/main/java/com/sumup/sdk/events/CheckoutCreatedEvent.java b/src/main/java/com/sumup/sdk/events/CheckoutCreatedEvent.java new file mode 100644 index 0000000..e827ab2 --- /dev/null +++ b/src/main/java/com/sumup/sdk/events/CheckoutCreatedEvent.java @@ -0,0 +1,16 @@ +// Code generated by sumup-java/codegen. DO NOT EDIT. +package com.sumup.sdk.events; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.sumup.sdk.models.Checkout; + +/** + * Sent once when a checkout is first observed in the checkout snapshot stream, even if it is + * already paid, failed, or expired. The event timestamp is the original checkout creation time. + */ +public final class CheckoutCreatedEvent extends FetchableEvent { + @Override + TypeReference resourceType() { + return new TypeReference<>() {}; + } +} diff --git a/src/main/java/com/sumup/sdk/events/CheckoutExpiredEvent.java b/src/main/java/com/sumup/sdk/events/CheckoutExpiredEvent.java new file mode 100644 index 0000000..15b8b6a --- /dev/null +++ b/src/main/java/com/sumup/sdk/events/CheckoutExpiredEvent.java @@ -0,0 +1,17 @@ +// Code generated by sumup-java/codegen. DO NOT EDIT. +package com.sumup.sdk.events; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.sumup.sdk.models.Checkout; + +/** + * Sent once when a checkout is first observed with status EXPIRED. Expiry or deactivation without + * an upstream snapshot cannot produce this event. Later EXPIRED snapshots do not emit another + * expired event. + */ +public final class CheckoutExpiredEvent extends FetchableEvent { + @Override + TypeReference resourceType() { + return new TypeReference<>() {}; + } +} diff --git a/src/main/java/com/sumup/sdk/events/CheckoutFailedEvent.java b/src/main/java/com/sumup/sdk/events/CheckoutFailedEvent.java new file mode 100644 index 0000000..1b5be62 --- /dev/null +++ b/src/main/java/com/sumup/sdk/events/CheckoutFailedEvent.java @@ -0,0 +1,16 @@ +// Code generated by sumup-java/codegen. DO NOT EDIT. +package com.sumup.sdk.events; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.sumup.sdk.models.Checkout; + +/** + * Sent once when a checkout is first observed with status FAILED. A failed checkout can + * subsequently be retried and paid. Later FAILED snapshots do not emit another failed event. + */ +public final class CheckoutFailedEvent extends FetchableEvent { + @Override + TypeReference resourceType() { + return new TypeReference<>() {}; + } +} diff --git a/src/main/java/com/sumup/sdk/events/CheckoutPaidEvent.java b/src/main/java/com/sumup/sdk/events/CheckoutPaidEvent.java new file mode 100644 index 0000000..0e91067 --- /dev/null +++ b/src/main/java/com/sumup/sdk/events/CheckoutPaidEvent.java @@ -0,0 +1,17 @@ +// Code generated by sumup-java/codegen. DO NOT EDIT. +package com.sumup.sdk.events; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.sumup.sdk.models.Checkout; + +/** + * Sent once when a checkout is first observed with status PAID. Later PAID snapshots do not emit + * another paid event. The timestamp is the snapshot update time, not necessarily the payment + * completion time. + */ +public final class CheckoutPaidEvent extends FetchableEvent { + @Override + TypeReference resourceType() { + return new TypeReference<>() {}; + } +} diff --git a/src/main/java/com/sumup/sdk/events/CheckoutUpdatedEvent.java b/src/main/java/com/sumup/sdk/events/CheckoutUpdatedEvent.java new file mode 100644 index 0000000..2eaa1ab --- /dev/null +++ b/src/main/java/com/sumup/sdk/events/CheckoutUpdatedEvent.java @@ -0,0 +1,17 @@ +// Code generated by sumup-java/codegen. DO NOT EDIT. +package com.sumup.sdk.events; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.sumup.sdk.models.Checkout; + +/** + * Sent when a checkout snapshot is published, including creation and payment status updates. Fetch + * the checkout to inspect its current status. This is not a guarantee that every checkout mutation + * produces a notification. + */ +public final class CheckoutUpdatedEvent extends FetchableEvent { + @Override + TypeReference resourceType() { + return new TypeReference<>() {}; + } +} diff --git a/src/main/java/com/sumup/sdk/events/EventNotification.java b/src/main/java/com/sumup/sdk/events/EventNotification.java index fbed34f..6ddae3b 100644 --- a/src/main/java/com/sumup/sdk/events/EventNotification.java +++ b/src/main/java/com/sumup/sdk/events/EventNotification.java @@ -98,6 +98,11 @@ private static EventNotification parseBody(ApiClient client, byte[] body) { throw new EventPayloadException("Expected a JSON object."); Class type = switch (root.path("type").asText("")) { + case "checkouts.created" -> CheckoutCreatedEvent.class; + case "checkouts.expired" -> CheckoutExpiredEvent.class; + case "checkouts.failed" -> CheckoutFailedEvent.class; + case "checkouts.paid" -> CheckoutPaidEvent.class; + case "checkouts.updated" -> CheckoutUpdatedEvent.class; case "members.created" -> MemberCreatedEvent.class; case "members.deleted" -> MemberDeletedEvent.class; case "members.updated" -> MemberUpdatedEvent.class; diff --git a/src/main/java/com/sumup/sdk/events/EventsHandler.java b/src/main/java/com/sumup/sdk/events/EventsHandler.java index 89016cf..9d713ed 100644 --- a/src/main/java/com/sumup/sdk/events/EventsHandler.java +++ b/src/main/java/com/sumup/sdk/events/EventsHandler.java @@ -45,6 +45,86 @@ public EventNotification parse(byte[] body, String signature) { return EventNotification.parse(client, body, signature, secret); } + /** + * Registers the callback for {@code "checkouts.created"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public EventsHandler onCheckoutCreated(EventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put( + "checkouts.created", + event -> { + callback.handle((CheckoutCreatedEvent) event); + }); + return this; + } + + /** + * Registers the callback for {@code "checkouts.expired"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public EventsHandler onCheckoutExpired(EventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put( + "checkouts.expired", + event -> { + callback.handle((CheckoutExpiredEvent) event); + }); + return this; + } + + /** + * Registers the callback for {@code "checkouts.failed"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public EventsHandler onCheckoutFailed(EventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put( + "checkouts.failed", + event -> { + callback.handle((CheckoutFailedEvent) event); + }); + return this; + } + + /** + * Registers the callback for {@code "checkouts.paid"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public EventsHandler onCheckoutPaid(EventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put( + "checkouts.paid", + event -> { + callback.handle((CheckoutPaidEvent) event); + }); + return this; + } + + /** + * Registers the callback for {@code "checkouts.updated"}, replacing any previous registration. + * + * @param callback callback to complete before acknowledging delivery + * @return this handler for chaining + */ + public EventsHandler onCheckoutUpdated(EventCallback callback) { + Objects.requireNonNull(callback); + callbacks.put( + "checkouts.updated", + event -> { + callback.handle((CheckoutUpdatedEvent) event); + }); + return this; + } + /** * Registers the callback for {@code "members.created"}, replacing any previous registration. *