API Documentation

Integraciones

Notifications

A small receiver that verifies the signature and relays events into Slack. The same shape works for Discord, Teams, Telegram or an SMS gateway — only the last few lines change.

Warning
Your receiver is a public URL that anyone can post to. Nothing proves a payload came from your store except a valid signature, so verify it and reject stale timestamps before doing anything with the contents — and escape those contents like any other external input when you pass them on.
<?php
// webhook-receiver.php
$secret = getenv( 'WCUSAGE_WEBHOOK_SECRET' );
$body   = file_get_contents( 'php://input' );
$header = $_SERVER['HTTP_X_WCUSAGE_SIGNATURE'] ?? '';

$parts = [];
foreach ( explode( ',', $header ) as $pair ) {
    [ $k, $v ] = array_pad( explode( '=', $pair, 2 ), 2, '' );
    $parts[ trim( $k ) ] = trim( $v );
}

$expected = hash_hmac( 'sha256', ( $parts['t'] ?? '' ) . '.' . $body, $secret );

if ( ! hash_equals( $expected, $parts['v1'] ?? '' ) || abs( time() - (int) ( $parts['t'] ?? 0 ) ) > 300 ) {
    http_response_code( 401 );
    exit;
}

// Acknowledge immediately - the sender allows 8 seconds and retries on anything else.
http_response_code( 200 );
fastcgi_finish_request();

$payload = json_decode( $body, true );
$data    = $payload['data'] ?? [];

switch ( $payload['event'] ) {
    case 'payout.requested':
        $text = sprintf( ':moneybag: Payout requested: %s asked for %.2f via %s (payout #%d)',
            get_display_name( $data['user_id'] ), $data['amount'], $data['method'], $data['payout_id'] );
        break;

    case 'registration.created':
        $text = sprintf( ':wave: New affiliate application for code *%s*', $data['coupon_code'] );
        break;

    case 'affiliate.payout_details_updated':
        $text = sprintf( ':warning: Affiliate %d changed their payout details (%s)',
            $data['user_id'], $data['method_type'] ?: 'none set' );
        break;

    default:
        return; // not interested
}

$ch = curl_init( getenv( 'SLACK_WEBHOOK_URL' ) );
curl_setopt_array( $ch, [
    CURLOPT_POST       => true,
    CURLOPT_HTTPHEADER => [ 'Content-Type: application/json' ],
    CURLOPT_POSTFIELDS => json_encode( [ 'text' => $text ] ),
    CURLOPT_RETURNTRANSFER => true,
] );
curl_exec( $ch );

Two details worth copying:

  • Acknowledge before working. fastcgi_finish_request() (or a queue) returns the 2xx immediately, so a slow Slack call never turns into a retry storm.
  • Ignore unknown events. New event types appear in later releases; a receiver that throws on them will disable itself after 25 failures.
Tip
Subscribing to * and filtering in your receiver is easier to maintain than editing the subscription list every time you want another event — as long as your handler ignores what it does not recognise.