Aller au contenu

Ce contenu n’est pas encore disponible dans votre langue.

The purchase webhooks allow your application to validate purchase events and automatically trigger the PurchaseCompleted interaction, which could potentially lead to user rewards based on active campaigns. The webhooks also update the on-chain purchase oracle for your merchant, allowing you to know whether a purchase has been finalized. All purchase data is anonymized, and the oracle is updated with a Merkle tree root where each leaf contains a hashed purchaseId, userId, and the purchase finality status.

We provide three types of webhooks to handle purchase tracking:

  1. Shopify Webhook
  2. WooCommerce Webhook
  3. Custom Webhook

The Shopify webhook should be set up to trigger on order updates, allowing the backend to validate purchases and update the oracle. It is provisioned automatically by the official Frak Shopify app during onboarding — see the Shopify Integration Guide for details.

Similar to the Shopify webhook, the WooCommerce webhook is provisioned automatically by the Frak WordPress plugin once the webhook secret is pasted in. Follow the WordPress integration guide to properly set it up.

The Custom webhook is designed for applications that use a custom eCommerce solution or need more flexibility. This webhook requires specific headers and a payload to register the purchase event.

The specific endpoint URL for each webhook type is visible in the business dashboard under the Purchase Tracker section of your merchant.

  • x-hmac-sha256: A HMAC SHA-256 digest of the entire request body. The HMAC is computed using the secret available in your business dashboard.
  • x-test: Indicates if the webhook call is for a test order. This is useful for development environments.

The body of the Custom webhook should be a JSON object that follows the CustomWebhookDto type:

type CustomWebhookDto = Readonly<{
/**
* Id of the order on your side (external order id)
*/
id: string;
/**
* Id of the customer on your side (external customer id)
*/
customerId: string;
/**
* Status of the order
*/
status: "pending" | "confirmed" | "cancelled" | "refunded";
/**
* Custom token for this order
* - Should be the same one as the one exposed to the end user and submitted through the `listenForPurchase` API method
*/
token: string;
/**
* Currency code (ISO 4217)
* - Optional, could be empty
* - Recommended for the UX in the members space
*/
currency?: string;
/**
* The total price of the order, in the currency provided
* - Optional, could be empty
* - Recommended for the UX in the members space
*/
totalPrice?: string;
/**
* All the items in the order
* - Optional
* - Will be used in the wallet members space, to display additional data to the end user, e.g. which product they referee bought the most
*/
items?: {
/**
* The product id on your side
*/
productId: string;
/**
* The quantity of the product in the order
*/
quantity: number;
/**
* The price of the product
*/
price: string;
/**
* An internal name for the product, used in url slug
*/
name: string;
/**
* The displayable title of the product
*/
title: string;
/**
* A potential image URL for the product
*/
image?: string;
}[];
}>;

Here is a few custom webhook calls in different languages:

import crypto from 'crypto';
type Purchase = {
id: string;
customerId: string;
status: "pending" | "confirmed" | "cancelled" | "refunded";
token: string;
currency?: string;
totalPrice?: string;
items?: {
productId: string;
quantity: number;
price: string;
name: string;
title: string;
image?: string;
}[];
}
async function sendPurchaseWebhook(
purchase: Purchase
): Promise<void> {
const body = JSON.stringify(purchase);
const hmac = await crypto
.createHmac('sha256', process.env.FRAK_PURCHASE_WEBHOOK_SECRET)
.update(body)
.digest('hex');
await fetch(process.env.FRAK_PURCHASE_WEBHOOK, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-hmac-sha256': hmac,
'x-test': process.env.NODE_ENV === 'production' ? 'false' : 'true'
},
body
});
}
// Usage example
const purchase = {
id: 'order_123',
customerId: 'cust_456',
status: 'confirmed',
token: 'purchase_token_789',
currency: 'USD',
totalPrice: '99.99',
items: [{
productId: 'prod_001',
quantity: 1,
price: '99.99',
name: 'premium-subscription',
title: 'Premium Subscription'
}]
};
sendPurchaseWebhook(purchase)
.then(response => console.log('Webhook sent successfully:', response))
.catch(error => console.error('Error sending webhook:', error));

Each webhook request should include a valid HMAC signature of the entire body payload, ensuring the request’s integrity and authenticity. The secret used to generate this HMAC signature is available in your business dashboard.

All webhook types expect a JSON response indicating whether the request was successfully processed.

  • Ensure that the id, customerId, status, and token fields are consistent between the client and the server to ensure successful tracking.
  • The webhooks automatically update the on-chain purchase oracle, which anonymously tracks the purchase finality status.
  • You can find the specific webhook URL for your merchant in the business dashboard, under the Purchase Tracker section of your merchant.