Webhooks and event handling
Gateman is not a universal webhook receiver, event-forwarding service, or event queue for customer applications. Its responsibilities depend on the capability involved:
- Gateman receives and processes Amazon SES/SNS tracking notifications for an SES tracking setup.
- Gateman can provision a Stripe endpoint for a customer callback URL, but Stripe then delivers events to that customer-owned destination.
- The Gateman WordPress plugin receives Stripe payment events directly at a WordPress REST endpoint and completes supported local payments.
- SMS providers can deliver status callbacks directly to customer-supplied destinations when the selected provider request supports them.
- Square, PayPal, and other provider relays do not automatically make Gateman the receiver of later provider events.
A successful provider API relay request therefore does not imply that Gateman will receive the provider's subsequent webhook or callback. The provider, destination owner, and receiver determine the delivery and verification path.
Webhook ownership by capability
| Capability or integration | Who receives the event? | Who verifies and processes it? |
|---|---|---|
| SES tracking | Gateman at POST /webhooks/ses/{app_id} | Gateman verifies the SNS envelope and updates the app's email record |
| Stripe webhook setup | The callback URL supplied by the application | The application at that URL; Gateman only provisions and stores endpoint configuration |
| WordPress Stripe payments | The customer's WordPress site at /wp-json/getgateman/v1/stripe/webhook | The Gateman WordPress plugin verifies and completes supported local payments |
| Twilio SMS status | The StatusCallback URL supplied in the SMS request | The customer's callback application |
| Telnyx SMS status | The webhook_url or failover URL supplied in the SMS request | The customer's callback application |
| AWS SMS callbacks | No Gateman callback receiver is provided by the supported send contract | The customer must use provider-native facilities if needed |
| Square and PayPal events | A customer-configured provider destination | The customer's integration |
Provider callbacks use provider-specific authentication. They are not signed with Gateman application credentials or automatically covered by Contract v1.
Premium application email destinations
Premium applications can keep Gateman tracking enabled and optionally add a second provider-managed HTTPS destination. The provider delivers its native payload independently to both destinations; Gateman does not relay or transform events.
The optional destination is configured from the application console and is never application-only. SES adds an HTTPS subscription to the existing SNS topic and remains pending until the application completes SNS confirmation. Postmark creates a separate webhook for the selected message stream and keeps its provider verification state separate from Gateman's webhook. Resend creates a separate webhook and returns its provider-issued signing secret for the customer application to store and verify natively. Standard applications cannot configure these destinations.
Email tracking entitlement
Provider-event ingestion and Gateman-managed tracking are Premium features. Standard applications may send through SES, Postmark, and Resend, but valid provider events for Standard applications are acknowledged without being written to Gateman's tracking ledger or suppression intelligence. Premium applications retain the event processing, deduplication, suppression, and activity-summary behaviour described below.
This is an additional Gateman protection layer. It does not disable or replace provider-native bounce, complaint, reputation, or sender-policy controls.
Events processed by Gateman
SES delivery and tracking events
When SES tracking is provisioned for an application, SES publishes event notifications to the configured Amazon SNS topic. The SNS subscription points to:
POST /webhooks/ses/{app_id}
The receiver supports these SES event types:
| SES event | Internal Gateman state | Typical effect |
|---|---|---|
Send | accepted | Records that SES accepted the message for sending |
Delivery | delivered | Records successful provider delivery |
Bounce | bounced | Records the bounce and its diagnostics |
Complaint | complained | Records the complaint and its diagnostics |
Reject | rejected | Records provider rejection and its diagnostics |
Provider acceptance is not delivery. A Send event means SES accepted the message; it does not mean the recipient's mailbox accepted it. A later Delivery, Bounce, Complaint, or Reject event supplies the subsequent provider outcome when SES reports one.
Gateman verifies the SNS signature, validates the configured topic and application binding, checks the relevant SES/AWS identity information, and correlates the SES message ID and application tag to an existing email record. Permanent bounces and complaints with recipient evidence can create or update the appropriate suppression state. Suppression is provider- and event-specific; it is not a promise that every provider rejection or temporary bounce creates a suppression entry.
SES tracking is SES-specific: Postmark and Resend email sending do not provide equivalent Gateman SNS event ingestion through this route.
SES acknowledgement, duplicates, and timing
The route returns a successful acknowledgement after a valid notification has been processed, and also treats an already-recorded event as a duplicate rather than applying its side effects again. Invalid notifications are rejected; processing failures return a failure response so SNS may redeliver according to its own delivery rules.
SNS notifications may arrive after a delay or be redelivered by AWS. Gateman validates and processes supported notifications without assuming chronological delivery. Event-level duplicate protection and terminal-status safeguards prevent a duplicate or stale event from inappropriately repeating or replacing an email outcome, but they do not create universal exactly-once delivery or ordering.
Applications are responsible for customer-facing email history, delivery-status tracking, event processing, statistics, and reporting. Gateman retains the internal ledger, provider-event ingestion, correlation, deduplication, suppression, and operational diagnostics described above. See Send email.
Stripe webhook provisioning for customer applications
Gateman can create or reconcile one Stripe webhook endpoint per application and Stripe environment. The authenticated application calls:
POST /stripe/webhook/setup
The request contains the selected environment, an HTTPS callback_url, and a required non-empty events array of Stripe-native event names. The callback URL must be a valid HTTPS destination without embedded credentials. Gateman does not maintain a provider event catalogue: custom applications choose the event names they need, including * where Stripe supports it, and Stripe validates the provider-supported selection.
Gateman removes exact duplicate event names and sorts the list deterministically. It does not expand *. The canonical event list is used for the Stripe request, reconciliation, idempotency key, persisted hash, and response. Repeating setup with the same callback URL and event list does not update the recorded endpoint; changing either updates it. A requested event list is the complete desired selection, so an intentional reduction replaces the endpoint's prior selection.
The setup response identifies the environment, endpoint ID, callback URL, event set, and configured state. It does not return the Stripe signing secret. The endpoint's signing secret is stored in Gateman's encrypted credential store for later retrieval.
The application can retrieve the environment-specific secret through:
POST /stripe/webhook-secret
The request contains only environment, and the successful response contains the configured webhook_secret. These routes are authenticated Gateman API requests and require the exact stripe:webhook:write or stripe:webhook:read capability respectively. See Manage Stripe webhook, Read Stripe webhook secret, and Authentication.
Provisioning does not make Gateman the event receiver. Stripe sends the configured events directly to the customer's HTTPS callback URL. That receiving application must verify the Stripe signature using the secret, correlate the event to its own resource, handle duplicate delivery, process only supported business transitions, return the appropriate acknowledgement, and manage provider retries and failures. Gateman's Stripe relay and webhook setup capabilities do not provide a universal Stripe event ledger or payment-state reconciliation service for arbitrary customer applications.
WordPress Stripe payment webhooks
The canonical Gateman WordPress plugin provisions a Stripe endpoint whose callback is normally:
POST /wp-json/getgateman/v1/stripe/webhook
For its payment workflow, the plugin explicitly requests these events:
checkout.session.completedcheckout.session.async_payment_succeededpayment_intent.succeeded
These are WordPress integration requirements, not Gateman-wide defaults.
Stripe delivers payment events directly to WordPress. The plugin reads the raw request body, verifies the Stripe signature, parses the event, and correlates the provider metadata with a local payment, order, or transaction before completion. It supports WooCommerce, Easy Digital Downloads, and FluentCart. The local payment state and provider payment status are checked before the platform completion callback runs. Repeated delivery therefore does not blindly repeat a completed payment transition. A browser return from Checkout or Payment Element is a separate user-navigation path; it is not a substitute for verified webhook confirmation.
Signing-secret retrieval modes
In GetGateman → Settings → Stripe Webhook, administrators choose how the plugin obtains the environment-specific signing secret.
Retrieve for every webhook — default
- WordPress requests the secret from Gateman for every incoming webhook.
- No local secret cache is maintained.
- Each accepted secret-retrieval request is a billable Gateman operation.
Cache for five minutes — optional
- WordPress retrieves the secret only when no valid matching transient exists.
- The value is stored in a WordPress transient for five minutes.
- Subsequent matching events reuse that cached value during the TTL.
- Cached secrets may reside in the WordPress database or object cache; they are not memory-only.
- Cache entries are isolated by the relevant Gateman application, environment, endpoint, callback configuration, and base URL.
- Gateman application or environment changes, webhook setup changes, endpoint replacement, and retrieval-mode changes invalidate the relevant cache.
The choice is a trade-off between a fresh Gateman retrieval on every event and fewer retrieval operations with short-lived local storage. The plugin does not log or display the secret. It must obtain a valid secret before signature verification; if retrieval fails and no valid cache is available, the request temporarily fails. An invalid Stripe signature is rejected, and the payment handler is not reached.
This WordPress receiver is specific to the canonical plugin. It does not imply that non-WordPress Gateman clients have a hosted Stripe event receiver.
SMS and other provider callbacks
Sending an SMS through Gateman and receiving its later delivery status are separate responsibilities.
- Twilio accepts a caller-supplied
StatusCallbackURL in the SMS request. - Telnyx accepts
webhook_url,webhook_failover_url, and its provider-native webhook options in the SMS request. - The supported AWS SMS send contract does not expose a Gateman-managed inbound callback URL.
When a supported Twilio or Telnyx callback is configured, the provider sends notifications directly to that customer destination. Gateman does not receive, verify, forward, or store those inbound callbacks as a general SMS event service. The customer application must apply the provider's signature and authentication rules, correlate the notification to its message, handle duplicates and retries, and distinguish an accepted send response from later delivery status. Staging and development SMS capture records the outbound request locally; it does not create provider callbacks.
Square and PayPal API relay requests likewise do not automatically subscribe Gateman to later provider events. Customers needing Square or PayPal notifications must configure the provider destination and receiver appropriate to their integration. Stripe's provisioning contract does not apply to these providers.
Authentication and signatures
There are two separate authentication boundaries:
- An application authenticates requests it makes to Gateman with Contract v1, including the application headers and signature rules described in Authentication and Contract v1.
- A provider authenticates event deliveries using its own webhook or SNS contract.
Gateman verifies the SNS envelope for the SES route. A customer endpoint verifies Stripe signatures for a provisioned non-WordPress callback. The WordPress plugin verifies Stripe signatures for its own REST endpoint. Customer Twilio, Telnyx, Square, PayPal, or other provider receivers must implement the verification rules required by those providers. Gateman application credentials must not be used as provider webhook secrets.
Duplicate delivery, ordering, and idempotency
Webhook consumers should expect:
- duplicate delivery;
- delayed delivery;
- out-of-order events;
- provider redelivery after an unsuccessful acknowledgement; and
- uncertainty when processing succeeds but the acknowledgement is lost.
Event deduplication means recognising a provider event that has already been seen. Business-operation idempotency means ensuring that the event cannot complete or mutate the same payment or resource twice. They are related but not identical.
Gateman's implemented protections are capability-specific:
- SES records an event key and applies event-level duplicate protection plus internal email-event safeguards.
- The WordPress plugin relies on local order, payment, and transaction state checks around its supported completion handlers; it does not maintain a universal Stripe event ledger.
- Customer-created webhook receivers must choose and persist the provider event identifiers and business idempotency state appropriate to their application.
See Idempotency for the distinction between request idempotency, provider-native controls, and business effects.
Acknowledgements, retries, and recovery
A successful HTTP acknowledgement tells the provider that the receiver accepted or handled the event according to that receiver's contract. A failed acknowledgement may cause provider redelivery according to provider-specific rules. Gateman does not control those schedules.
A webhook timeout does not prove that processing failed. The receiver should make its business effect safe to retry, record enough provider identity to recognise duplicates, and distinguish delayed processing from an absent event. Neither Gateman's SES route nor the WordPress plugin provides a general replay API, dead-letter queue, outbound delivery queue, or universal reconciliation worker for customer webhooks.
For SES, valid notifications and recognised duplicates receive a successful route response; malformed notifications are rejected and processing failures return a failure response. AWS SNS decides whether and when to redeliver. For WordPress Stripe payments, signature verification and local payment validation occur at the WordPress endpoint before the platform completion handler; failure returns an unsuccessful REST response rather than silently accepting an unverified payment.
Environments
Stripe
Stripe webhook setup and secret retrieval are environment-scoped. Production, staging, and development endpoint state must not be conflated. The callback receiver must use the secret for the same environment that Stripe is delivering from. The WordPress plugin selects the configured Gateman application environment, and its cache isolation includes that environment.
The effective Stripe live or test mode is determined by the configured Stripe credential used for the selected Gateman environment. Confirm the provider account and mode before provisioning an endpoint.
SES
SES tracking is bound to the configured Gateman application, AWS account, region, SES configuration set, and SNS topic. The SES receiver validates that the notification belongs to the configured application/topic binding. It does not treat SES SNS delivery as a generic production/staging/development application request field.
Other providers
Provider callback environments do not automatically follow Gateman's environment and credential-pairing model. Follow each provider's own callback and signing documentation.
Operation accounting
Inbound provider delivery to Gateman is not itself a billable Gateman operation. The following customer-initiated Gateman calls are billable when accepted into their accounting lifecycle:
| Operation | Accounting |
|---|---|
| Stripe webhook setup | One stripe.webhook.setup operation |
| Stripe webhook-secret retrieval | One stripe.webhook_secret.read operation |
| Inbound SES/SNS ingestion | No separate Gateman operation |
| Provider webhook delivered directly to a customer application | No Gateman inbound-event operation |
| WordPress webhook processing | No separate Gateman webhook-processing operation |
| WordPress signing-secret retrieval | One Gateman secret-retrieval operation when the plugin makes the request |
| WordPress verification using a valid five-minute cached secret | No new secret-retrieval operation |
With WordPress's default per-event mode, multiple Stripe deliveries can cause multiple secret-retrieval operations. With the five-minute cache, a new operation is used only when the plugin actually retrieves a new secret; cache reuse does not call Gateman. See Operation Accounting for authoritative accounting and failure semantics.
Event visibility, retention, and limitations
For SES, Gateman retains internally recorded message state, supported event history, provider diagnostics where available, and suppression state. These remain internal operational data; customer-facing history, reporting, and retention decisions belong to the application. See Data retention.
For Stripe endpoints owned by customer applications, delivery logs, event history, replay, retention, and reconciliation remain the responsibility of the receiving application and Stripe. Gateman exposes endpoint configuration and secret retrieval, not a universal customer event history.
For WordPress, payment/order state and any local logs belong to the WordPress installation and its commerce plugins. The Gateman plugin does not expose a universal event ledger.
