PlexySDK DOCS

Handle Webhook Events

Process webhook payloads in your application

Handle Webhook Events

Learn how to receive and process webhook events from Plexy.

Webhook payload structure

Every webhook event has a consistent structure:

{
  "id": "evt_1234567890",
  "type": "payment.succeeded",
  "created": 1679529600,
  "data": {
    "id": "pay_abc123",
    "amount": 5000,
    "currency": "USD",
    "status": "succeeded"
  }
}
FieldDescription
idUnique event identifier
typeEvent type (e.g., payment.succeeded)
createdUnix timestamp when event occurred
dataEvent-specific payload

Basic webhook handler

const express = require('express');
const app = express();

app.post('/webhooks/plexy', express.json(), (req, res) => {
  const event = req.body;

  switch (event.type) {
    case 'payment.succeeded':
      const payment = event.data;
      console.log(`Payment ${payment.id} succeeded`);
      // Update order status, send confirmation email, etc.
      break;

    case 'payment.failed':
      const failedPayment = event.data;
      console.log(`Payment ${failedPayment.id} failed`);
      // Notify customer, retry payment, etc.
      break;

    case 'refund.succeeded':
      const refund = event.data;
      console.log(`Refund ${refund.id} processed`);
      // Update inventory, notify customer, etc.
      break;

    default:
      console.log(`Unhandled event type: ${event.type}`);
  }

  res.status(200).json({ received: true });
});
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/webhooks/plexy', methods=['POST'])
def handle_webhook():
    event = request.json

    if event['type'] == 'payment.succeeded':
        payment = event['data']
        print(f"Payment {payment['id']} succeeded")
        # Update order status, send confirmation email, etc.

    elif event['type'] == 'payment.failed':
        payment = event['data']
        print(f"Payment {payment['id']} failed")
        # Notify customer, retry payment, etc.

    elif event['type'] == 'refund.succeeded':
        refund = event['data']
        print(f"Refund {refund['id']} processed")
        # Update inventory, notify customer, etc.

    return jsonify({'received': True}), 200
func handleWebhook(w http.ResponseWriter, r *http.Request) {
    var event map[string]interface{}
    json.NewDecoder(r.Body).Decode(&event)

    eventType := event["type"].(string)
    data := event["data"].(map[string]interface{})

    switch eventType {
    case "payment.succeeded":
        log.Printf("Payment %s succeeded", data["id"])
        // Update order status, send confirmation email, etc.

    case "payment.failed":
        log.Printf("Payment %s failed", data["id"])
        // Notify customer, retry payment, etc.

    case "refund.succeeded":
        log.Printf("Refund %s processed", data["id"])
        // Update inventory, notify customer, etc.
    }

    w.WriteHeader(http.StatusOK)
    json.NewEncoder(w).Encode(map[string]bool{"received": true})
}

Best practices

Return quickly

Return a 200 response immediately, then process the event asynchronously:

app.post('/webhooks/plexy', (req, res) => {
  // Acknowledge receipt immediately
  res.status(200).send('OK');

  // Process asynchronously
  processEventAsync(req.body);
});

Handle duplicates

Events may be delivered more than once. Use the event id to ensure idempotency:

async function processEvent(event) {
  // Check if already processed
  const existing = await db.events.findOne({ eventId: event.id });
  if (existing) {
    return; // Already processed
  }

  // Process and record
  await handleEvent(event);
  await db.events.insert({ eventId: event.id, processedAt: new Date() });
}

Log all events

Log every webhook for debugging and auditing:

app.post('/webhooks/plexy', (req, res) => {
  console.log('Webhook received:', JSON.stringify(req.body));
  // ... handle event
});

See also

Осы бетте