
Let payment events update the application
Bring provider payment activity back into customer billing state. Wildo verifies incoming events, identifies the billing account and updates the corresponding subscription, invoice or completed purchase.
Example — Confirm a purchase after checkout
The provider sends a checkout-completed event. Wildo checks its account and purchase metadata before applying the purchase, then the application can refresh its billing view.
For engineers
Enable the billing provider on the backend with both BILLING_PROVIDER and WEBHOOK_ORIGINATOR. Supply the provider signing secret and run wildo config sync. The provider module registers POST /api/v1/webhooks/stripe/billing; configure the provider or a local event forwarder to reach it. Keep the raw request body available for signature verification.
The billing adapter verifies the request through the selected provider implementation:
The following selected excerpt is from billing-webhook-adapter.backend.service.ts; the surrounding module and explanatory source comments are omitted.
verifySignature(
rawBody: string | Buffer,
signatureHeader: string,
secret: string,
): boolean {
return this.billingProvider.verifyWebhookSignature(
typeof rawBody === 'string' ? rawBody : rawBody.toString('utf-8'),
signatureHeader,
secret,
);
}
After verification, the adapter normalizes the event and retains its native event type and payload for scope resolution. The Stripe module matches data.object.customer against the account’s providerCustomerId across the enabled billing variants. A browser-supplied organization ID is not that authority.
Let each event perform its own work
Subscription events reconcile status and period bounds; invoice events upsert totals and status. Checkout completion checks reserved metadata against the resolved account before granting products or credits. The settlement path uses a persisted claim keyed by completion identity to avoid granting the same purchase again; it refuses a grant without a deduplication identity.
Do not translate that into a promise that every arbitrary side effect is exactly-once. Custom work must preserve its own failure and replay semantics. Provider-only fields are written through the trusted backend update path, so identifiers needed by subsequent events survive schema filtering. Inspect event delivery and the resulting resource state when integrating: reaching the endpoint is not proof that a purchase was reconciled.