Skip to main content
Providers report what happens after checkout through webhooks: a subscription cancelled, a renewal that failed, an asynchronous payment that finally settled. Aikeedo routes them to your gateway automatically.

The endpoint

Every gateway shares one route:
The request handler resolves your gateway from its key, asks for getWebhookHandler(), and calls handle(). Return the URL from Helper::generateWebhookUrl(), and show it on your settings page so administrators can paste it into the provider’s dashboard.
The webhook route runs with error handling only. There’s no session, no authentication and no CSRF protection, because the caller is a machine. Your signature check is the authentication.

A handler

src/WebhookHandler.php

Verify every request

1

Read the raw body

Compute the signature over (string) $request->getBody(), not over a re-encoded array. Re-encoding changes key order and escaping, and the signature won’t match.
2

Compare in constant time

Use hash_equals(), never ==.
3

Fail closed

If the secret isn’t configured, reject the request. Skipping verification “until it’s set up” means anyone can cancel subscriptions or mark orders paid.
4

Check what the payload claims

Confirm the event refers to an object you know, and that the amount and currency match the order before you treat it as payment.

Responses

Acting on events

Fulfilling from a webhook must mirror what the callback does. If the workspace had a previous subscription, cancel it as well, or the customer ends up with two active subscriptions.

Idempotency

Providers retry, deliver out of order, and sometimes deliver twice.
Look up state before you change it, and make repeated deliveries a no-op.
Rely on the exceptions: AlreadyPaidException and AlreadyFulfilledException tell you the work is already done.
Never grant credits directly from a webhook. Go through the order commands, which enforce the state machine.
Log the provider’s event ID so duplicates are visible while debugging.

Testing

  • Use the provider’s dashboard to replay events at your installation.
  • For local development, expose your machine with a tunnel, and set the site URL so the generated webhook URL is reachable.
  • Send a request with a wrong signature and confirm you get a 400.
  • Send an unknown event type and confirm you get a 200.
  • Watch var/log/app-*.log while testing.