MagiaPay· Events

Events

Every merchant-visible webhook delivery is backed by an event. Fetch them for reconciliation when a webhook was missed, replay-checked, or when you need the canonical copy of a past state change.

Why events?

Webhooks are asynchronous — your endpoint could be down when one fires. Instead of trusting that every delivery arrived, poll GET /v1/events on a schedule (every 5–15 minutes for high-volume, or after a suspicious gap in webhooks) and catch up on anything you missed.

The event id you receive in a webhook payload (id: evt_…) matches exactly what GET /v1/events/{id} returns. Use this to verify a delivery you're not sure about.

List events

curl "https://magiapay.innoserver.cloud/v1/events?limit=10&type=payment.succeeded" \
  -H "Authorization: Bearer sk_live_..."

Event types

TypeWhen
payment.pendingPayment created, awaiting customer action.
payment.processingProvider acknowledged customer paid; funds settling.
payment.succeededFunds captured. Ledger credited.
payment.failedProvider rejected the payment.
payment.expiredCheckout window elapsed without payment.
payment.refundedFull refund applied; payment is settled.
refund.succeededRefund processed successfully.
refund.failedRefund attempt failed.
payout.succeededPayout to destination succeeded.
payout.failedPayout failed; ledger debit auto-reversed.

Reconciliation pattern

Store the highest id you've processed. On each poll, request events with starting_after=<your-highest-id> and work through the returned list.

Reconciliation cron
let lastSeenId = await db.get('magiapay_last_event_id');

while (true) {
  const url = new URL('https://magiapay.innoserver.cloud/v1/events');
  url.searchParams.set('limit', '100');
  if (lastSeenId) url.searchParams.set('starting_after', lastSeenId);

  const res = await fetch(url, { headers: { Authorization: `Bearer ${SECRET}` } });
  const { data, has_more } = await res.json();
  if (data.length === 0) break;

  for (const evt of data.reverse()) {
    await applyEvent(evt);       // your idempotent handler
    lastSeenId = evt.id;
  }
  if (!has_more) break;
}
await db.set('magiapay_last_event_id', lastSeenId);

Event retention

Events are retained indefinitely — you can replay months-old events if needed. Individual webhook delivery attempts (which endpoint received what, when) are retained 90 days.