Setting Up Webhooks

Modified on Wed, Jan 3 at 3:12 PM

Webhooks allow you to receive real-time HTTPS notifications of events on the Paxful marketplace. For example, we could notify you when a new trade starts or when your trade partner sends a message in a trade chat. This prevents you from having to query the API for changes to objects that may or may not have happened and helps you avoid reaching your rate limit. This guide will describe how exactly you can set up Webhooks with Paxful.


We support Webhooks for the following events:

  • New incoming trade on Paxful
  • Message received in trade chat
  • Attachment received in trade chat
  • Someone has viewed your Paxful profile
  • Someone has viewed your offer
  • Trade partner has paid for their crypto
  • Trade was canceled or has expired
  • Crypto sold successfully
  • Crypto purchased
  • Crypto deposit confirmed
  • The incoming crypto deposit is pending
  • Feedback received from a trade partner
  • New feedback reply received


Setting up Webhooks
Verifying requests from Paxful
Example in JavaScript


Setting up Webhooks


Note: Make sure your service is ready for receiving Webhooks. During the URL saving, your service should take the "X-Paxful-Request-Challenge" request header and put it into the response as-is.


Here is how our request header should appear in your payload (this is a Webhooks service example in Node.js):

1. Log in to your Paxful account, hover over your username on the top right of the page, and click Settings from the context menu that appears.

The Settings page appears.


2. On the menu on the left side of the page, click Developer.


The Developer page appears.


3. If you don’t have an API key, insert the two-factor code in the field below and click Add new API key. If you already have an API key, you can skip this step. 

Your new API key appears on the Developer page alongside additional sections.


4. Copy the URL from your app.
Go to the 
Webhooks section on the Paxful Developer page. Paste the link into the Request URL field and click Save.


WarningOur Webhooks are supported by HTTPS address types only. HTTP addresses will not work for this purpose.


A request header is sent to your app.


Note: We have a timeout of 10 seconds. If we do not receive a response from your app, the URL will not be saved, and a Webhook will not be created.


5. In case of success, a list of events available for subscription appears below. Tick a box to select an event from the Subscribe to Events list.


Note:

  • Once selected, events are saved automatically.
  • In the case of three failed attempts to send event information to your app, Webhook (URL) becomes disabled. The timeout for calling a Webhook is 3 seconds.
  • To insert a new link, replace the current URL with the new one and click Change
  • To deactivate your Webhooks completely, click Delete.
  • To reactivate a disabled URL, click Retry.


In case if request URL is saved successfully, this is how our events will appear in your app:



Verifying requests from Paxful

Paxful creates a unique string for your app and shares it with you. Verify requests from Paxful with confidence by verifying signatures using your signing secret.


We add an "X-Paxful-Signature" HTTPS header on each HTTPS request sent. The signature is created by combining the signing secret with the body of the request we're sending using a standard HMAC-SHA256 keyed hash.


Note: The resulting signature is unique to each request and doesn't directly contain any secret information. That keeps your app secure, preventing bad actors from causing mischief.


Example in JavaScript


const crypto = require('crypto');
const express = require('express');
const app = express();
const port = 3000;
const bodyParser = require('body-parser');


Your API secret from the https://paxful.com/account/developer page:


const apiSecret = 'maE5KV16FV0nDyh7XPm2F8f8FZTdtb5p';

app.use(bodyParser.json());


When you receive a service address verification request, you should take the "X-Paxful-Request-Challenge" header from the request and then put it into the response.


app.use((req, res, next) => {


The address verification request doesn't contain the payload and request signature.


  if (!Object.keys(req.body).length && !req.get('X-Paxful-Signature')) {
        console.log('Address verification request received.');
        const challengeHeader = 'X-Paxful-Request-Challenge';
        res.set(challengeHeader, req.get(challengeHeader));
        res.end();
    } else {
        next();
    }
});


When you receive an event notification, you should verify the "X-Paxful-Signature" header. In case the request contains the wrong signature, do not process it.


  app.use((req, res, next) => {
    const providedSignature = req.get('X-Paxful-Signature');
    const calculatedSignature = crypto.createHmac('sha256', apiSecret).update(JSON.stringify(req.body)).digest('hex');
    if (providedSignature !== calculatedSignature) {
        console.log('Request signature verification failed.');
        res.status(403).end();
    } else {
        next();
    }
});


Now you can process an event.


  app.post('*', async (req, res) => {
    console.log('New event received:');
    console.log(req.body);
    res.end();
});

app.listen(port, () => console.log(`Example app listening at http://localhost:${port}`));


Please feel free to reach out to our Support team with any additional questions. You can also learn more about API services in our developers' documentation.