Skip to main content
The SDK API sends notifications to your game server when events occur.

Event Types

EventDescription
coupon.redeemedCoupon redeemed
payment.createdPayment registered
sponsor.createdSponsor created

Webhook Format

Headers
Content-Type: application/json
X-Webhook-Batch: true
X-Webhook-Signature: {HMAC-SHA256 signature}
Payload
{
  "events": [
    {
      "event": "payment.created",
      "timestamp": "2024-01-15T10:30:00.000Z",
      "data": {
        "transactionId": "txn_abc123",
        "userId": "user_12345",
        "amount": 9900,
        "currency": "KRW",
        "creatorKey": "ABC12"
      }
    }
  ]
}

Signature Verification

Verify that webhook requests actually come from PlayCamp.
The SDK provides a verifyWebhook() utility that handles signature verification, timestamp validation, and payload parsing:
import { verifyWebhook } from '@playcamp/node-sdk';

app.post('/webhooks/playcamp', (req, res) => {
  const result = verifyWebhook({
    payload: req.rawBody,
    signature: req.headers['x-webhook-signature'],
    secret: process.env.WEBHOOK_SECRET,
    tolerance: 300,  // Max age in seconds (default: 300)
  });

  if (!result.valid) {
    return res.status(401).json({ error: result.error });
  }

  for (const event of result.payload.events) {
    switch (event.event) {
      case 'coupon.redeemed':
        console.log('Coupon redeemed:', event.data.couponCode);
        break;
      case 'payment.created':
        console.log('Payment created:', event.data.transactionId);
        break;
      case 'sponsor.created':
        console.log('Sponsor created:', event.data.userId);
        break;
    }
  }

  res.status(200).json({ received: true });
});

Reception Example (Express)

import { verifyWebhook } from '@playcamp/node-sdk';

app.post('/webhooks/playcamp', express.raw({ type: 'application/json' }), (req, res) => {
  const payload = Buffer.isBuffer(req.body) ? req.body.toString() : req.body;

  const result = verifyWebhook({
    payload,
    signature: req.headers['x-webhook-signature'] as string,
    secret: process.env.WEBHOOK_SECRET!,
  });

  if (!result.valid) {
    return res.status(401).json({ error: result.error });
  }

  for (const event of result.payload.events) {
    switch (event.event) {
      case 'coupon.redeemed':
        console.log('Coupon redeemed:', event.data);
        break;
      case 'payment.created':
        console.log('Payment created:', event.data);
        break;
    }
  }

  res.json({ received: true });
});
Use express.raw({ type: 'application/json' }) instead of express.json() to enable signature verification with the raw body.

Testing Webhooks

Generate test signatures for local development:
import { constructWebhookSignature } from '@playcamp/node-sdk';

const payload = JSON.stringify({
  events: [{
    event: 'coupon.redeemed',
    timestamp: new Date().toISOString(),
    data: { couponCode: 'TEST', userId: 'user_123', usageId: 1, reward: [] },
  }]
});

const signature = constructWebhookSignature(payload, 'your_webhook_secret');

Webhook Management

FunctionMethodEndpoint
List webhooksGET/v1/server/webhooks
Create webhookPOST/v1/server/webhooks
Update webhookPUT/v1/server/webhooks/:id
Delete webhookDELETE/v1/server/webhooks/:id
Get webhook logsGET/v1/server/webhooks/:id/logs
Test webhookPOST/v1/server/webhooks/:id/test