@orangecheck/me-client / WebhookPayload
Interface: WebhookPayload
Defined in: me-client/src/types.ts:244
The exact JSON body delivered to a registered webhook endpoint when a billable event fires. Imported by integrator backends so the receive handler is type-checked end-to-end without re-declaring the shape.
import type { WebhookPayload } from '@orangecheck/me-client';
export async function POST(req: Request) { const payload = (await req.json()) as WebhookPayload; if (payload.subtype === 'payment_authorization') { creditUser(payload.sub, payload.user_earned_sats); } }
Headers carry the signature and metadata (see WebhookHeaders below).
Verify the signature with oc.webhook.verify({ body, headers, jwks }).
Privacy contract · the master oc identity is NEVER in the payload.
Integrators see sub (per-integrator anonymous id) plus any
scopes the user explicitly granted. See PRIVACY-ARCHITECTURE.md.
Extends
Properties
| Property | Type | Description | Inherited from | Defined in |
|---|---|---|---|---|
<a id="property-class"></a> class | EventClass | - | BillableEvent.class | me-client/src/types.ts:203 |
<a id="property-gross_fee_sats"></a> gross_fee_sats | number | - | BillableEvent.gross_fee_sats | me-client/src/types.ts:206 |
<a id="property-id"></a> id | string | - | BillableEvent.id | me-client/src/types.ts:201 |
<a id="property-is_agent"></a> is_agent? | boolean | Per OCHK-V3-PLAN §7 phase-1 · true when the event was fired by an oc-agent delegation rather than a human session. The integrator's IntegratorEventConfig.agent block may price these differently or refuse them. Optional · canonical encoder branches to v=3 only when present, so legacy human-fired events keep their v=2 hash + signature. | BillableEvent.is_agent | me-client/src/types.ts:217 |
<a id="property-kind"></a> kind | "oc-billable-event" | Discriminator · identifies the payload kind for routing on the integrator's side. Always 'oc-billable-event' today; future webhook payload kinds (refunds, charters, etc) will use distinct discriminator values. | - | me-client/src/types.ts:249 |
<a id="property-occurred_at"></a> occurred_at | string | - | BillableEvent.occurred_at | me-client/src/types.ts:202 |
<a id="property-platform_fee_sats"></a> platform_fee_sats | number | - | BillableEvent.platform_fee_sats | me-client/src/types.ts:207 |
<a id="property-scopes"></a> scopes? | Partial<Record< | "bitcoin_address" | "email" | "attest_tier" | "display_name" | "cross_integrator_event_count" | "cross_integrator_human_event_count" | "trust_attestation_count" | "trust_attestations_bundle", string>> | Resolved scoped fields · only present for scopes the user has granted to this project. Wire format is string-keyed (every value is stringified · ints stringified, addresses as-is). | - | me-client/src/types.ts:258 |
<a id="property-site"></a> site | { display_name: string; domain: string; } | - | BillableEvent.site | me-client/src/types.ts:205 |
site.display_name | string | - | - | me-client/src/types.ts:205 |
site.domain | string | - | - | me-client/src/types.ts:205 |
<a id="property-site_rebate_sats"></a> site_rebate_sats | number | - | BillableEvent.site_rebate_sats | me-client/src/types.ts:209 |
<a id="property-sub"></a> sub | string | Per-integrator anonymous subject id · stable across events for the same (oc_identity, project_key) pair. Key your user records on this; OC will never give you the master address unless the user explicitly grants bitcoin_address or email scope. | - | me-client/src/types.ts:254 |
<a id="property-subtype"></a> subtype | EventSubtype | - | BillableEvent.subtype | me-client/src/types.ts:204 |
<a id="property-user_earned_sats"></a> user_earned_sats | number | - | BillableEvent.user_earned_sats | me-client/src/types.ts:208 |
<a id="property-verify_url"></a> verify_url | string | - | BillableEvent.verify_url | me-client/src/types.ts:210 |