Webhooks

This guide is an overview of webhooks V2, which are available through the Developers Portal. If you are looking for the deprecated V1, please use this article . For the difference between V1 and V2 and why V2 is the improved version, visit the “Why should I use V2?” section below. If you’re looking to migrate from V1 to V2, check out migrating to webhooks version 2 .

Webhooks allows you to receive real-time HTTPS notifications of events that occur within Paxful products. For example, you could receive a notification when a new trade starts or when your trade partner sends you a message in a trade chat. This prevents you from having to poll the API for changes that could have happened and helps you to avoid hitting your API rate limit.

Depending on what kind of application you are developing, you can use webhooks for both direct and delegated access modes. If you’re using direct access, you can subscribe to notifications that happen within your own Paxful account. If you’re using delegated access when you develop an application, you can subscribe to notifications that happen within a users’ account that start using your application.

Getting started with webhooks

On a high level, the configuration process looks like:

  • Application is deployed on a publicly accessible URL.
  • Create a webhook by specifying a URL from the previous step and choose the events you want the URL to be invoked by Paxful when the events occur.
  • Once the webhook is saved, Paxful will send a validation request. The purpose of this request is to ensure the given URL is specifically designed to accept Paxful webhooks.
  • If the validation request is successful, when the chosen events happen, the URL will be called by Paxful.

    URLs you want to use to receive webhook notifications should meet the following criteria:

    1. Must support HTTPS. Paxful won’t send webhooks via plain HTTP.
    2. Must respond within X seconds.
    3. Must always respond with a 200 code.

    If the second or third criteria listed above is not met over 3 invocations of a webhook, it will be automatically disabled.

    Exact configuration steps you need to follow might differ depending on the type of integration flow you use.

    For a list of available webhooks and how samples of their payloads look, please refer to the Available webhooks section.

    Direct access

    Direct access mode allows you to subscribe to events that occur in your own account. Here are the steps you need to follow:

    StepNotes
    Go to developers portal and choose direct access modeDirect access mode
    Create a webhook by specifying a URL and choose the events you wantWebhook creating
    Follow a webhook validation process. For more information, check out handling webhook validation request.

    Once you complete the steps above, if any of the chosen events happen within your account, Paxful will invoke the URL with more information about what happened.

    Delegated access

    We recommend you view the source code of Sign in with Paxful demo application where you can see how a full integration flow with webhooks using delegated access mode looks like.

    Delegated access mode allows you to subscribe to events that happen in other users accounts . When you initiate an authentication flow as explained in the delegated Access authentication guide, you can request access to additional scopes. If a user grants access to your application, your application will be able to use the webhook APIs to configure webhooks on behalf of a user. This way, a user doesn’t need to do anything to have your application fully connect to their account. Once you receive an access token, you can issue a request similar to this one to have a user subscribed to events:

    const events = [
        ‘trade.started’, ‘trade.released’
    ];
    
    await paxful.post(`/webhook/v1/applications/undefined/user/webhooks`,{
        "endpoints": events.map((eventType) => ({
            "event_type": eventType,
            "url": process.env.WEBHOOK_TARGET_URL,
            "enabled": true
        }))
    });
    

    The snippet of code above relies on a few environment variables you’d need to define in your application:

    • PAXFUL_API_ID - this is an ID that you create when you create an application
    • WEBHOOK_TARGET_URL - a publicly accessible URL of controller that will be receiving requests from Paxful, e.g. https://example.com/webhook

    In the snippet, we use POST /webhook/v1/{application_id}/user/webhooks, but webhooks API has many other methods that you can use in your application to manage user’s webhooks. For more information refer to webhooks API documentation.

    Handling webhook validation request

    When you add a new URL to receive notifications for events, Paxful will send a webhook URL validation request (also known as a “challenge request”). The request will have no body but will include a special header named ‘x-paxful-request-challenge’. When you receive this request, your application should return a response with an empty body but should include the same header and value. This is how your controller might look like:

    router.post('/webhook', (req, res) => {
        const isValidationRequest = req.body.type === undefined;
        if (isValidationRequest) {
            res.set("X-Paxful-Request-Challenge", req.headers['x-paxful-request-challenge']);
    
            return;
        }
    }
    

    Available webhooks

    All webhook payloads mirror a structure of related Paxful API response structures:

    WebhookSample payload
    trade.started trade/get
    trade.paid
    trade.released
    rade.cancelled_or_expired
    trade.dispute_started
    trade.dispute_finished
    trade.chat_message_received trade-chat/get
    trade.attachment_uploaded
    trade.bank_account_shared
    trade.online_wallet_shared
    crypto.deposit_pending transactions/all
    crypto.deposit_confirmed
    profile.viewed user/info
    feedback.received feedback/list
    feedback.reply_received
    trade.bank_account_selected bank-account/get
    trade.proof_added trade/add-proof

    Why should I use webhooks version 2?

    If you’re building a new application, there are more advantages to using v2 rather than v1:

    Richer payloads

    Webhooks v1 (in most cases) included only trade_hash/trade_id in their payloads, meaning that once you received a webhook, you’d still need to issue another API request to actually understand what changed. Payloads with webhook v2 mirror the data structure of the public API. This means that once events occur, you’ll most likely receive all relevant information without having to issue a separate API request. For more information, visit the available webhooks section.

    Ability to troubleshoot and rich telemetry (coming soon)

    In webhooks v1, if something happened to your server, your webhook would get disabled with minimal information as to what happened and how you can fix it. With the webhooks v2, you have access to a self service dashboard where you can see and diagnose webhook issues. For more information, visit troubleshooting webhooks section.

    Replay feature (coming soon)

    In webhooks v2, if your server was not accessible and delivery of events was unsuccessful, the webhook events will be saved and you can replay them at a later time in the self-service portal. For more information, visit the troubleshooting webhooks section.

    Lesser latency

    Due to new internal architecture, webhooks v2 have noticeably lesser latency between the moment an event has occurred on Paxful and when the actual webhook is triggered.

    Management API

    Any action you can do through a self service portal you can do through API. This helps you build self contained applications that can be easily distributed and managed. Webhooks API support both direct and delegated access modes. For more information, visit API documentation.

    Migrating to webhooks version 2

    Migrating from webhooks v1 to v2 is an easy process. The migration comes down to two things:

    • Using the new payload structure (required)
    • Validating Paxul signature (optional, but highly recommended)

    Using the new payload structure

    Webhooks v1 has inconsistencies in how the parameter with the hash of a trade is called. For some webhooks, it is trade_id and for others it is trade_hash. In webhooks v2, the hash of a trade is universally called trade_hash. To migrate your application to start accepting new webhooks, start using the trade_hash parameter.

    As previously mentioned, the webhooks v2 has richer payloads. Instead of just trade_hash, you’ll also receive relevant information as to what has happened. If you’d like to, you can update your application and remove some calls to API endpoints because most of the required information is available in webhook payload. For more information, see the available webhooks section.

    Validating Paxful signature

    To make sure a request originates from Paxful, applications accepting webhooks should validate a Paxful signature.

    Paxful uses an asymmetrical signature algorithm provided by NaCl crypto library . The library has bindings for all popular programming languages and platforms.

    To validate a signature, you should take a raw request body (see below for a snippet of code on how to do that) and concatenate it with a URL that is meant to accept webhooks from Paxful’s side using a “:” as a separator. If we use URL “WEBHOOK_TARGET_URL” as an example, a message that needs to be validated will look like this:

    signatureValidationPayload = WEBHOOK_TARGET_URL + “:” + rawRequestBody
    

    Then, use the result string “signatureValidationPayload” to validate the signature obtained from X-Paxful-Signature request header.

    In NodeJs payload signature validation logic may look like:

    const nacl = require('tweetnacl'); // install “tweetnacl” package
    
    const isValidSignature = (signature, host, originalUrl, rawBody) => {
        const signatureValidationPayload = `${process.env.WEBHOOK_TARGET_URL}:${rawBody}`;
        return nacl.sign.detached.verify(
            Buffer.from(signatureValidationPayload, 'utf8'),
            Buffer.from(signature, 'base64'),
            Buffer.from(‘fvcYFZlQl21obFbW5+RK2/foq8JzK/Y5fCEqg+NEy+k=’, 'base64')
        )
    }
    
    In the snippet above the “signature” argument is meant to be a value of “X-Paxful-Signature” request header value.

    It is highly recommended to use this validation for all webhooks you receive. This way, you’ll know that a webhook your application received came from Paxful. Additionally, if a third-party gets to know your application’s webhook URL, they cannot tamper with it.

    If you’re using the Express NodeJs framework, you can cache a raw request body by setting up a middleware similar to this:

    const app = express();
    
    // Savings original raw body, needed for Paxful webhook signature checking
    app.use(function(req, res, next) {
        req.rawBody = '';
    
        req.on('data', function(chunk) {
            req.rawBody += chunk;
        });
    
        next();
    });
    

    Troubleshooting webhooks

    The webhook self service portal will be live in Q1of 2022.

    This website uses cookies to ensure you get the best experience on our website.Learn more