While writing the official TypeScript SDK against the OpenAPI spec, I cross-checked docs/Webhooks.md against the actual PHP code and found four mismatches. The DTOs in src/API/ are correct against the spec; the docs describe a shape that no class in this repo models.
1. Webhook payload shape
docs/Webhooks.md describes the payload as:
{ id, type, data, createdAt }
The actual DTO in src/API/Resources/WebhookEvent.php is:
{ id, resource, eventName, entityType, entityId, object, links }
This also matches the OpenAPI spec's WebhookEvent schema and the fixture in tests/Endpoints/WebhookEventEndpointTest.php. The docs' field names (type, data, createdAt) don't exist anywhere in the codebase.
2. Event name list
The docs list event names like checkout.paid, checkout.failed, subscription.created, subscription.renewed, subscription.ended, refund.created, chargeback.created, chargeback.won, chargeback.lost. None of these are constants in src/API/Types/WebhookEvent.php.
The actual constants are: order.paid, order.canceled, order.chargeback_received, order.chargeback_reversed, refund.completed, refund.failed, refund.canceled, subscription.started, subscription.canceled_immediately, subscription.canceled_with_grace_period, subscription.cancellation_grace_period_completed, checkout.expired.
Only order.paid, refund.completed, and checkout.expired overlap.
3. Webhook::parse() doesn't exist
Both the standalone PHP example and the Laravel example reference:
use Vatly\API\Webhook;
$event = Webhook::parse($payload, $signature, $secret);
No Vatly\API\Webhook class exists in src/. The only verifier is src/API/Webhooks/WebhookSignatureValidator.php, which exposes verify($payload, $signature) / isValid(...) / calculateSignature(...). Either Webhook::parse() needs to be added, or the examples should be rewritten against the existing validator.
4. Header name — can you confirm?
The docs read $_SERVER['HTTP_VATLY_SIGNATURE'] and $request->header('Vatly-Signature'), both of which correspond to the HTTP header Vatly-Signature (no X- prefix). I've separately seen X-Vatly-Signature cited as the canonical name. The PHP code itself doesn't read the header (the validator takes the signature as a string param), so the docs are currently the only source of truth — and there's no test exercising a real delivery.
Could you confirm which one Vatly actually sends on the wire? Whichever it is, the docs should match.
Suggested fix
Happy to PR a rewrite of docs/Webhooks.md against the real DTOs and an inferred Webhook::parse() convenience (or just route the examples through WebhookSignatureValidator + manual json_decode). Let me know which direction you'd prefer.
While writing the official TypeScript SDK against the OpenAPI spec, I cross-checked
docs/Webhooks.mdagainst the actual PHP code and found four mismatches. The DTOs insrc/API/are correct against the spec; the docs describe a shape that no class in this repo models.1. Webhook payload shape
docs/Webhooks.mddescribes the payload as:The actual DTO in
src/API/Resources/WebhookEvent.phpis:This also matches the OpenAPI spec's
WebhookEventschema and the fixture intests/Endpoints/WebhookEventEndpointTest.php. The docs' field names (type,data,createdAt) don't exist anywhere in the codebase.2. Event name list
The docs list event names like
checkout.paid,checkout.failed,subscription.created,subscription.renewed,subscription.ended,refund.created,chargeback.created,chargeback.won,chargeback.lost. None of these are constants insrc/API/Types/WebhookEvent.php.The actual constants are:
order.paid,order.canceled,order.chargeback_received,order.chargeback_reversed,refund.completed,refund.failed,refund.canceled,subscription.started,subscription.canceled_immediately,subscription.canceled_with_grace_period,subscription.cancellation_grace_period_completed,checkout.expired.Only
order.paid,refund.completed, andcheckout.expiredoverlap.3.
Webhook::parse()doesn't existBoth the standalone PHP example and the Laravel example reference:
No
Vatly\API\Webhookclass exists insrc/. The only verifier issrc/API/Webhooks/WebhookSignatureValidator.php, which exposesverify($payload, $signature)/isValid(...)/calculateSignature(...). EitherWebhook::parse()needs to be added, or the examples should be rewritten against the existing validator.4. Header name — can you confirm?
The docs read
$_SERVER['HTTP_VATLY_SIGNATURE']and$request->header('Vatly-Signature'), both of which correspond to the HTTP headerVatly-Signature(noX-prefix). I've separately seenX-Vatly-Signaturecited as the canonical name. The PHP code itself doesn't read the header (the validator takes the signature as a string param), so the docs are currently the only source of truth — and there's no test exercising a real delivery.Could you confirm which one Vatly actually sends on the wire? Whichever it is, the docs should match.
Suggested fix
Happy to PR a rewrite of
docs/Webhooks.mdagainst the real DTOs and an inferredWebhook::parse()convenience (or just route the examples throughWebhookSignatureValidator+ manualjson_decode). Let me know which direction you'd prefer.