Setting up Webhooks

Webhooks allow you to receive real-time HTTPS notifications of events on the Paxful marketplace. For example, we could send you a notification when a new trade starts or whenever 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 bitcoin
  • Trade was cancelled or has expired
  • Bitcoin sold successfully
  • Bitcoin purchased
  • Bitcoin deposit confirmed
  • Incoming bitcoin deposit is pending
  • Feedback received from a trade partner
  • New feedback reply received

Setting up Webhooks

Note: Make sure your service is ready for receiving Webhooks. During the URL saving process, 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):

RequestHeader.png

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.
ClickSettings.png

The Settings page appears.

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

The Developer page appears.

3. In case 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. 
AddAPIKey.png

Your new API key appears on the Developer page alongside with 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.

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


ClickSave.png

A request header is sent to your app.

Note: We have a timeout of 10 seconds. In case 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.
Events.png

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. 
  • 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.
    ClickRetry.png
     

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

WebhookexampleEvent.png

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.

On each HTTPS request sent, we add an "X-Paxful-Signature" HTTPS header. 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 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 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}`));

Reach out to our Support in case of any additional questions. You can also learn more about our API services in our developers' documentation.

Articles in this section