Mintcash
ConceptsWebhooks

Event types

Every webhook MintCash emits, when it fires, and whether it's terminal.

Every webhook's event field follows the pattern <entity>.<status>. The type field tells you what's inside data. The event field tells you which state transition fired.

Payment events (type: "payment")

EventWhen it firesTerminal
payment.pendingPSP accepted the charge, awaiting capture or 3DS completionNo
payment.authorizedFunds authorized but not yet capturedNo
payment.succeededCharge captured — fulfil the order on this eventNo¹
payment.failedCharge declined or PSP returned an errorYes
payment.partially_refundedA partial refund succeeded; further refunds are still possibleNo
payment.voidedAuthorization voided before captureYes

No webhook fires when the payment row is first created — the synchronous POST /payments response covers that state. Refund transitions (payment.partially_refunded, payment.refunded, payment.refund_failed) keep the payment. event prefix but are delivered with type: "refund" — see Refund events below.

¹ succeeded is not strictly terminal because the payment can still be refunded (delivered as a type: "refund" event). Once you receive a terminal event for a paymentId, no further events fire for it.

Subscription events (type: "subscription")

Subscription events mirror payment events for the underlying invoice charges, plus the lifecycle transitions of the subscription itself.

EventWhen it fires
subscription.pendingA subscription charge was accepted by the PSP, awaiting capture or 3DS
subscription.succeededFirst charge or a renewal charge succeeded
subscription.failedA subscription charge attempt failed (first charge, renewal, or retry)
subscription.cancelledThe subscription terminated — merchant cancel via DELETE /subscriptions/{id}, retries exhausted, or a non-recoverable decline (terminal)

Treat subscription.succeeded after the first one as "renewal — extend the customer's access by another billingIntervalDays." The event string is the same for the first charge and every renewal, but each cycle is a distinct event with its own eventId — dedupe on eventId and count each subscription.succeeded as one cycle. data.currentPeriodStart / data.currentPeriodEnd tell you which period that charge paid for.

Refund events (type: "refund")

EventWhen it fires
payment.partially_refundedA partial refund succeeded; further refunds still possible
payment.refundedThe payment is now fully refunded
payment.refund_failedA refund attempt couldn't be processed

What "terminal" means in practice

When a payment hits failed or refunded, no further events will fire for that paymentId. Same for a subscription that hits failed or cancelled.

Use this to safely clean up state: archive the order record, close the dunning ticket, mark the customer record. You won't get any more updates about that resource.