Payload reference
The JSON shape of every webhook envelope and entity. Use this to write strongly-typed handlers.
Every webhook MintCash sends shares a common envelope. The variable part is data, whose shape is determined by type.
Envelope
| Field | Type | Notes |
|---|---|---|
eventId | string (UUID) | Stable across retries of the same event. Use as your dedupe key. |
event | string | The transition: payment.succeeded, subscription.failed, etc. |
type | string | Determines the shape of data: payment, subscription, or refund. |
apiVersion | string | Webhook schema version (2026-05-01). |
environment | string | live or test. |
createdAt | string (ISO8601) | When the event was emitted. |
data | object | The entity. Shape depends on type. |
Payment payload (type: "payment")
Fires for: payment.created, payment.pending, payment.authorized, payment.succeeded, payment.failed, payment.voided.
{
"eventId": "01HXX...",
"event": "payment.succeeded",
"type": "payment",
"apiVersion": "2026-05-01",
"environment": "live",
"createdAt": "2026-05-22T14:32:08.412Z",
"data": {
"id": "pmt_01HXX...",
"externalId": "order_123",
"status": "succeeded",
"amount": 49.99,
"currency": "USD",
"providerTransactionId": "provider_txn_abc",
"failureCode": null,
"failureMessage": null,
"amountRefunded": 0,
"amountRefundable": 49.99,
"customer": {
"id": "cust_01HXX...",
"externalId": "cust_42",
"email": "buyer@example.com",
"name": "Jane Doe",
"phone": "+15551234567"
},
"billingAddress": {
"country": "US",
"postalCode": "10001",
"name": "Jane Doe",
"line1": "1 Madison Ave",
"line2": null,
"city": "New York",
"state": "NY"
},
"card": {
"brand": "mastercard",
"first6": "555544",
"last4": "0000",
"mask": "555544******0000",
"expMonth": "12",
"expYear": "2030"
}
}
}type Customer = {
id: string;
externalId: string;
email: string;
name: string;
phone: string | null;
};
type Address = {
country: string;
postalCode: string;
name: string | null;
line1: string | null;
line2: string | null;
city: string | null;
state: string | null;
};
type Card = {
brand: string;
first6: string;
last4: string;
mask: string; // already-masked PAN, e.g. 555544******0000
expMonth: string;
expYear: string;
};
type PaymentData = {
id: string;
externalId: string;
status:
| "created"
| "pending"
| "authorized"
| "succeeded"
| "failed"
| "voided";
amount: number; // major units
currency: string;
providerTransactionId: string | null;
failureCode: string | null;
failureMessage: string | null;
amountRefunded: number;
amountRefundable: number;
customer: Customer | null;
billingAddress: Address | null;
card: Card | null; // null until the PSP confirms the charge
};
type PaymentEvent = {
eventId: string;
event:
| "payment.created"
| "payment.pending"
| "payment.authorized"
| "payment.succeeded"
| "payment.failed"
| "payment.voided";
type: "payment";
apiVersion: string;
environment: "live" | "test";
createdAt: string;
data: PaymentData;
};Refund payload (type: "refund")
Fires for: payment.partially_refunded, payment.refunded, payment.refund_failed. The envelope type is "refund": data is the refund, and the payment it was issued against is nested at data.payment (the full payment shape from above).
{
"eventId": "01HXX...",
"event": "payment.refunded",
"type": "refund",
"apiVersion": "2026-05-01",
"environment": "live",
"createdAt": "2026-05-22T16:10:11.000Z",
"data": {
"id": "rfd_01HXX...",
"externalId": "refund_order_123_full",
"status": "succeeded",
"amount": 49.99,
"currency": "USD",
"providerRefundId": "provider_rfn_abc",
"failureCode": null,
"failureMessage": null,
"payment": {
"id": "pmt_01HXX...",
"externalId": "order_123",
"status": "refunded",
"amount": 49.99,
"currency": "USD",
"providerTransactionId": "provider_txn_abc",
"failureCode": null,
"failureMessage": null,
"amountRefunded": 49.99,
"amountRefundable": 0,
"customer": {
"id": "cust_01HXX...",
"externalId": "cust_42",
"email": "buyer@example.com",
"name": "Jane Doe",
"phone": "+15551234567"
},
"billingAddress": {
"country": "US",
"postalCode": "10001",
"name": "Jane Doe",
"line1": "1 Madison Ave",
"line2": null,
"city": "New York",
"state": "NY"
},
"card": {
"brand": "mastercard",
"first6": "555544",
"last4": "0000",
"mask": "555544******0000",
"expMonth": "12",
"expYear": "2030"
}
}
}
}The refund object carries providerRefundId, failureCode, and failureMessage; on a payment.refund_failed event the failure fields describe the refund (the nested payment keeps its own status). There is no reason or createdAt field on the webhook refund object.
Subscription payload (type: "subscription")
Fires for: subscription.succeeded, subscription.failed, subscription.cancelled. The customer, billing address, and card live on the nested payment object — not at the subscription root. The billing schedule (phases) is returned by the REST API, not on the webhook.
{
"eventId": "01HXX...",
"event": "subscription.succeeded",
"type": "subscription",
"apiVersion": "2026-05-01",
"environment": "live",
"createdAt": "2026-05-22T08:00:00.000Z",
"data": {
"id": "sub_01HXX...",
"externalId": "sub_cust42_plan_pro",
"status": "active",
"amount": 19.99,
"currency": "USD",
"billingIntervalDays": 30,
"currentPeriodStart": "2026-05-22T08:00:00.000Z",
"currentPeriodEnd": "2026-06-21T08:00:00.000Z",
"cancelledAt": null,
"payment": {
"id": "pmt_01HXX...",
"externalId": "sub_initial_sub_cust42_plan_pro",
"status": "succeeded",
"amount": 19.99,
"currency": "USD",
"providerTransactionId": "provider_txn_abc",
"failureCode": null,
"failureMessage": null,
"amountRefunded": 0,
"amountRefundable": 19.99,
"customer": {
"id": "cust_01HXX...",
"externalId": "cust_42",
"email": "buyer@example.com",
"name": "Jane Doe",
"phone": "+15551234567"
},
"billingAddress": {
"country": "US",
"postalCode": "10001",
"name": "Jane Doe",
"line1": "1 Madison Ave",
"line2": null,
"city": "New York",
"state": "NY"
},
"card": {
"brand": "mastercard",
"first6": "555544",
"last4": "0000",
"mask": "555544******0000",
"expMonth": "12",
"expYear": "2030"
}
}
}
}cancelledAt is null until the subscription is cancelled, then an ISO 8601 timestamp. status reflects the subscription's own state (active, past_due, cancelled, …), independent of the nested payment's status.