Webhook Notifications

When a relevant event occurs such as payment or refund transaction being made (i.e. moved into a ‘completed’ state), CentraPay issues an HTTP POST notification message to your application at a merchant-supplied webhook.


Enabling webhook notifications is done by supplying the notifyUrl argument to the requests.create API call.

curl -d "notifyUrl=http://localhost:8080/api/service.notify&asset=NZD&amount=1020&merchantId=merchant1234&description=My+request+description&externalReference=request1234" -X POST

As any malicious party may theoretically POST an HTTPS payload to your application, CentraPay digitally signs the notification messages and sends them over HTTPS to your application.

The JSON-formatted POST notification contains a payload representing the relevant event information. If the webhook endpoint is unavailable or takes too long to respond for whatever reason, CentraPay will attempt to resend the notification message up to a total of 8 times over the course of 25 hours until a successful response is received (HTTP status code 200 OK).

Attempt # Delay
1 Immediate
2 2 Minutes
3 10 Minutes
4 15 Minutes
5 1 Hour
6 2 Hours
7 6 Hours
8 11 Hours

Notification contents

All notifications are wrapped in a JSON Web Token (JWT) structure thereby allowing integrating developers to utilise existing software libraries to parse and validate the authenticity of the contents. Resources further describing the JWT structure are available here.

The payload of the JWT will contain the following attributes defined within the JWT schema in addition to the event data itself.

Name Description
iss The issuer claim identifies the principal (i.e. CentraPay) that issued the JWT
iat Identifies the time at which the JWT was issued
jti Provides a unique identifier for the JWT and can be used to prevent the JWT from being replayed by an attacker

The transactionType and state parameters in the notification message indicate which event triggered the notification message:

    "iss": "b4d5d7a3-38bf-4c41-8e38-e33d96ddb169",
    "iat": 1538440151,
    "jti": "fff41104-8a22-493a-a9d2-f6d94e7b901e",
    "transaction": {
        "transactionId": "aba4b07d-fd12-43bc-bbb1-12fda46d9937",
        "transactionType": "PURCHASE",
        "ledger": "g.crypto.cennznet.testnet.centrapay.assets.models.Account.NZDOFFRAMP",
        "state": "completed",
        "amount": 2000,
        "request": {
        "requestId": "1b23d1f9-8a3e-414d-ac94-f4b331095197",
        "merchantId": "0b1100be-6a76-45b0-adb8-bfe7db5ae720",
        "externalReference": "12345sixseveneightnineten",
        "denomination": { "asset": "NZD", "amount": 2000 }
        "createdAt": "2018-10-02T00:29:09.307Z",
        "updatedAt": "2018-10-02T00:29:11.383Z",
        "type": "CENNZNET_TESTNET",
        "timestamp": "2018-10-02T00:29:08.761Z",
        "account": "1Fy8xwtT8csbVwVCw2NMkpTjXx7AURY7fp",
        "responseCode": "00",
        "settlementDate": "2018-10-02T00:29:08.760Z",
        "authCode": "961241"

The authentication algorithm uses an asymmetric signature algorithm, ECDSA using P-256 curve and SHA-256 hash algorithm to generate the verify signature section of the JWT. This enables CentraPay to use a private key to create the signature and enables merchants to use the public key published by CentraPay to verify that the message has in fact been generated by CentraPay and arrived to the merchant application in an untampered. Please contact a CentraPay representative to obtain the CentraPay public key to be verified.

Verifying a signature using jsonwebtoken

Install jsonwebtoken npm package:

$ npm install jsonwebtoken

NodeJS pseudo code to validate webhook:

 module.exports = {
     verify: (payload, publicKey) => {
         try {
             const jwt = require('jsonwebtoken');
             jwt.verify(payload, publicKey, { algorithms: ['ES256'] });
         } catch {
             return false;
         return true;