Skip to main content
Outgoing webhooks send HTTP POST requests to your server when specific events occur in your Partnero program.

How It Works

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│   Event     │     │  Partnero   │     │ Your Server │
│   Occurs    │────▶│  Webhook    │────▶│  Endpoint   │
│             │     │  System     │     │             │
└─────────────┘     └─────────────┘     └─────────────┘


                    POST /your-webhook
                    {event, data, timestamp}

Setting Up Outgoing Webhooks

1

Create your endpoint

Create an HTTPS endpoint on your server to receive webhook events:
// Express.js example
app.post('/webhooks/partnero', (req, res) => {
  const { event, data, timestamp } = req.body;
  
  // Process the event
  console.log(`Received ${event} event`);
  
  // Respond quickly with 200
  res.status(200).send('OK');
  
  // Process asynchronously if needed
  processWebhookAsync(event, data);
});
2

Register in Partnero

  1. Go to Program Settings → Webhooks
  2. Click Add Webhook
  3. Enter your endpoint URL
  4. Select which events to receive
  5. Save and copy the signing secret
3

Verify signatures

Verify webhook signatures to ensure requests are from Partnero:
const crypto = require('crypto');

function verifyWebhookSignature(payload, signature, secret) {
  const expectedSignature = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expectedSignature)
  );
}

app.post('/webhooks/partnero', (req, res) => {
  const signature = req.headers['x-partnero-signature'];
  
  if (!verifyWebhookSignature(req.body, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process verified webhook
  res.status(200).send('OK');
});

Available Events

Partner Events

EventDescription
partner.createdNew partner signs up or is created
partner.updatedPartner information is updated
partner.approvedPartner application is approved
partner.rejectedPartner application is rejected
partner.archivedPartner is archived
partner.deletedPartner is deleted

Customer Events

EventDescription
customer.createdNew customer is created
customer.updatedCustomer information is updated
customer.deletedCustomer is deleted

Transaction Events

EventDescription
transaction.createdNew transaction is recorded
transaction.updatedTransaction is updated
transaction.deletedTransaction is deleted (refund)

Reward Events

EventDescription
reward.createdCommission/reward is created
reward.approvedReward is approved for payout
reward.paidReward is marked as paid

Webhook Payload

All webhooks follow this structure:
{
  "event": "partner.created",
  "data": {
    "id": "partner_abc123",
    "email": "[email protected]",
    "name": "John",
    "surname": "Doe",
    "status": "approved",
    "created_at": "2025-01-15T10:30:00.000000Z",
    "metadata": {}
  },
  "program_id": "PROG123",
  "timestamp": "2025-01-15T10:30:00.000000Z"
}

Event-Specific Payloads

{
  "event": "partner.created",
  "data": {
    "id": "partner_abc123",
    "key": "john-doe",
    "email": "[email protected]",
    "name": "John",
    "surname": "Doe",
    "status": "pending",
    "referral_link": "https://yoursite.com?ref=john-doe",
    "created_at": "2025-01-15T10:30:00.000000Z"
  }
}
{
  "event": "transaction.created",
  "data": {
    "key": "txn_123",
    "amount": 99.99,
    "currency": "USD",
    "action": "sale",
    "customer": {
      "id": "cust_456",
      "email": "[email protected]"
    },
    "partner": {
      "id": "partner_abc123",
      "email": "[email protected]"
    },
    "reward": {
      "amount": 19.99,
      "currency": "USD"
    },
    "created_at": "2025-01-15T14:22:00.000000Z"
  }
}
{
  "event": "reward.approved",
  "data": {
    "id": "reward_789",
    "amount": 19.99,
    "currency": "USD",
    "partner": {
      "id": "partner_abc123",
      "email": "[email protected]"
    },
    "transaction_key": "txn_123",
    "approved_at": "2025-01-20T09:00:00.000000Z"
  }
}

Handling Webhooks

Best Practices

Respond Quickly

Return a 2xx status within 5 seconds. Process data asynchronously.

Implement Idempotency

Handle duplicate deliveries by tracking processed event IDs.

Use HTTPS

Always use HTTPS endpoints in production.

Log Everything

Log all received webhooks for debugging and audit trails.

Handling Retries

Partnero retries failed webhooks with exponential backoff:
AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours
After 5 failed attempts, the webhook is marked as failed. Check your webhook logs in the Partnero dashboard.

Example: Processing Partner Signup

app.post('/webhooks/partnero', async (req, res) => {
  const { event, data } = req.body;
  
  // Respond immediately
  res.status(200).send('OK');
  
  // Process asynchronously
  switch (event) {
    case 'partner.created':
      await sendWelcomeEmail(data.email, data.name);
      await addToMailingList(data.email);
      await notifySlack(`New partner: ${data.name} (${data.email})`);
      break;
      
    case 'transaction.created':
      await updateCRM(data);
      await syncToAccounting(data);
      break;
      
    case 'reward.approved':
      await schedulePayoutReminder(data);
      break;
  }
});

Testing Webhooks

Using the Dashboard

  1. Go to Program Settings → Webhooks
  2. Find your webhook and click Test
  3. Select an event type
  4. Click Send Test Webhook

Using ngrok for Local Development

# Start ngrok tunnel
ngrok http 3000

# Use the ngrok URL as your webhook endpoint
# https://abc123.ngrok.io/webhooks/partnero

Troubleshooting

  • Verify your endpoint URL is correct and accessible
  • Check your server logs for incoming requests
  • Ensure your firewall allows requests from Partnero IPs
  • Check the webhook logs in your Partnero dashboard
  • Ensure you’re using the correct signing secret
  • Verify you’re hashing the raw request body
  • Check for any middleware modifying the request body
  • Implement idempotency using event IDs
  • Track processed webhooks in your database
  • Return 200 status quickly to prevent retries

API Reference

For programmatic webhook management, see the Webhooks API.