Log inGet started
Airwallex logo
Home
Online Payments
Treasury
Transactional FX
Payouts
Issuing
Scale
Open Banking
Developer Tools
API Reference
Home
Developer Tools
Postman Collection
Make your first API call with no code
Webhooks
Getting started with webhooksWhitelisting IP addressesEvent typesPayload examplesCode examples
Tips for using webhooksListen for webhook eventsTest webhook event payloadsView webhook eventsRe-trigger webhook events

Code examples

Code example

Java

import org.apache.commons.codec.digest.HmacUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Controller
public class WebhookExampleController {

@PostMapping("/webhook/example")
@ResponseBody
public String receive(HttpServletRequest request, @RequestBody String payload, HttpServletResponse response) {

String responseBody = "";

StringBuilder valueToDigest = new StringBuilder();
// Get the timestamp from header
String timestamp = request.getHeader("x-timestamp");
valueToDigest.append(timestamp);
valueToDigest.append(payload);

// Get the signature from header
String signature = request.getHeader("x-signature");

// Get your secret
String secret = getSecret();

if (HmacUtils.hmacSha256Hex(secret, valueToDigest.toString()).equals(signature)) {

// Do something with event

response.setStatus(HttpServletResponse.SC_OK);
} else {
// Invalid signature
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
responseBody = "failed to verify the signature";
}

return responseBody;
}

}

PHP

<?php
use RingCentral\Psr7\Response;

function getSecret() {
return 'whsec_CEm2XM_JZ1x5FxUUEGcZoRgIz4RZfDE';
}

function handler($request, $context): Response{
$timestamp = $request->getHeaderLine('x-timestamp');
$body = $request->getBody()->getContents();

$secret = getSecret();
$signature = $request->getHeaderLine('x-signature');

if (hash_hmac('sha256', $timestamp.$body, $secret) != $signature) {
return new Response(400, array(), 'failed to verify the signature');
}

// Do something with event
return new Response(200, array(), $body);
}

Node.js

// express.js
const crypto = require('crypto')

const secret = '<CLIENT_API_WEBHOOK_SECRET>'

async webhookController(ctx, next) {
  // webhook is received

  const { headers, body } = ctx.request
  const { name, accountId } = body || {} // payload

  const ts = headers['x-timestamp']

  const policy = `${ts}${body}`

  const signatureHex = crypto.createHmac('sha256', secret).update(policy).digest('hex')

  if (signatureHex === headers['x-signature']) {
    // do business logic after signature is verified

    return next() // http response code = 200: ack the webhook
  } else {
    ctx.status = 500
    ctx.body = 'failed to verify webhook signature'
    return
  }
}