> ## Documentation Index
> Fetch the complete documentation index at: https://support.tapfiliate.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Postback instruction for a CMS

> There's a guide for clients who need to implement the Postback integration on a CMS.

November 9, 2026

Each request must have a header with the user's authentication key.

X-Api-Key: #Your key#

You can find and manage X-Api-Key [in your account settings](https://support.tapfiliate.com/getting-started/essential-account-settings/how-to-find-account-id-and-api-key.md#h_ce8e59730e).\

Your X-Api-Key - has to be saved in secure storage (e.g. database, environment variables).

**Basic concepts**

Postback API endpoints accept both **GET** and **POST** requests.\

When creating a request with the GET method, you need to pass all the necessary parameters in the request URL:

```bash theme={null}
curl -X GET -H 'X-Api-Key: YOUR API KEY HERE' https://api.tapfiliate.com/1.7/pb/con/c/?referral_code=nwjinmy&amount=100&external_id=ORD005
```

When creating a request with the POST method, you need to pass all the necessary parameters in the request body:

```bash theme={null}
curl -X POST -H 'Content-Type: application/json' -H 'X-Api-Key: YOUR API KEY HERE' https://api.tapfiliate.com/1.7/pb/con/c/ -d '
   {
     "referral_code": "nwjinmy",
     "amount": "100",
     "external_id": "ORD005"
   }'
```

**Required parameters:**\

1\. `external id` A unique id for this conversion. It can be anything that is meaningful to you, like an order number, user id, email address etc. This id has to be unique for every conversion.\

2\. You have to also send one of the parameters:\

• `referral code` An affiliate’s referral code. This corresponds to the value of `ref=` in their referral link\

• `coupon` The affiliate’s coupon code.\

• `click id` The click id. Used to add additional reporting information.\

• `asset id` and `source id` A source id or an asset id.\

*If more than one of them is sent, then one will be used, according to priority (from highest to lowest): coupon, click\_id, referral\_code, asset\_id and source\_id.*

**If necessary, you can add additional parameters to the request:**\

• `amount` The conversion amount (number).\

• `currency` The three letter ISO currency code.If not passed, the default program currency will be used.\

• `customer id` The id for this customer in your system. The customer id should be unique for each customer. Depending on your program settings, this can be used for recurring / lifetime commissions. You can read more [about this here](https://developers.tapfiliate.com/tracking/server-to-server).\

• `meta data` Additional data for the conversion (object).\

• `user agent` The client’s user agent string. Used for statistics and fraud detection.\

• `ip` The client’s IP. Used for fraud detection.

**[Implementation for PHP](https://support.tapfiliate.com/integrations/supported-integrations/postback-instruction-for-php.md)**

**Implementation for WordPress and WooCommerce:**

If you use WooCommerce, we recommend the official [Tapfiliate plugin](https://support.tapfiliate.com/integrations/supported-integrations/how-to-integrate-woocommerce-with-tapfiliate.md) instead: it tracks orders without custom code.\

The following code has to be added to the functions.php file of the active theme.

```php theme={null}
<?php
define('TAP_COOKIE_DAYS', 90); // Number of days cookies are stored for
define('TAP_COOKIE_NAME', 'tap_data'); // Cookie name
define('TAP_CONVERSION_POSTBACK_URL', 'https://api.tapfiliate.com/1.7/pb/con/c/'); // Link to the endpoint for working with conversions

function setDataToCookie($data)
{
    setcookie(TAP_COOKIE_NAME, json_encode($data), time() + 60 * 60 * 24 * TAP_COOKIE_DAYS, '/');
}

function parseDataFromUrl()
{
    $resultArray = [];

    if ($assetData = $_GET['aid'] ?? $_GET['asset_id'] ?? $_GET['a'] ?? $_POST['aid'] ?? $_POST['asset_id'] ?? $_POST['a'] ?? null) {
        $resultArray['asset_id'] = $assetData;
    }

    if ($sourceData = $_GET['sid'] ?? $_GET['source_id'] ?? $_GET['s'] ?? $_POST['sid'] ?? $_POST['source_id'] ?? $_POST['s'] ?? null) {
        $resultArray['source_id'] = $sourceData;
    }

    if ($refData = $_GET['refc'] ?? $_GET['referral_code'] ?? $_GET['ref'] ?? $_POST['refc'] ?? $_POST['referral_code'] ?? $_POST['ref'] ?? null) {
        $resultArray['referral_code'] = $refData;
    }

    if (empty(array_filter($resultArray))) {
        return;
    }
    setDataToCookie($resultArray);
}

function sendRequestToPostbackApi($url, $data)
{
    $response = wp_remote_post($url, [
        'method' => 'POST',
        'timeout' => 45,
        'headers' => [
            'X-Api-Key' => getenv('TAPFILIATE_API_KEY'),
            'Content-type' => 'application/json',
            'Accept' => 'application/json',
        ],
        'body' => json_encode($data),
    ]);

    return is_wp_error($response) ? null : wp_remote_retrieve_body($response);
}

// Runs in the customer's browser session when the order is created:
// saves the affiliate data from the cookie to the order.
function saveAffiliateDataToOrder($orderId)
{
    $data = json_decode(wp_unslash($_COOKIE[TAP_COOKIE_NAME] ?? ''), true);
    if (!is_array($data)) {
        return; // The visitor did not come through an affiliate link
    }

    $order = wc_get_order($orderId);
    $order->update_meta_data('_tap_data', $data);
    $order->save_meta_data();
}

// Runs when the order is paid (also from payment gateway callbacks, where there is no cookie).
function createConversionFromOrderId($orderId)
{
    $order = wc_get_order($orderId);
    $data = $order->get_meta('_tap_data') ?: [];

    $requestData = [
        'external_id' => (string) $order->get_id(),
        'referral_code' => $data['referral_code'] ?? null,
        'asset_id' => $data['asset_id'] ?? null,
        'source_id' => $data['source_id'] ?? null,
        'customer_id' => $order->get_billing_email(), // your ID of the customer, used for lifetime/recurring commissions
        'amount' => $order->get_subtotal() - $order->get_total_discount(), // without tax and shipping
        'currency' => $order->get_currency(),
        'ip' => $order->get_customer_ip_address(),
        'user_agent' => $order->get_customer_user_agent(),
    ];

    // Orders without affiliate data are sent too: with lifetime commissions a returning
    // customer is recognised by customer_id. Tapfiliate rejects orders it cannot attribute,
    // and a second call for the same order as a duplicate.
    return sendRequestToPostbackApi(TAP_CONVERSION_POSTBACK_URL, array_filter($requestData));
}

add_action('parse_request', 'parseDataFromUrl');
add_action('woocommerce_new_order', 'saveAffiliateDataToOrder', 10, 1);
add_action('woocommerce_order_status_processing', 'createConversionFromOrderId', 10, 1);
add_action('woocommerce_order_status_completed', 'createConversionFromOrderId', 10, 1);
```

The code saves the affiliate data from the visitor’s cookie to the order when the order is created, and sends the conversion once the order is paid (status Processing or Completed). The amount is the order subtotal after discounts, without tax and shipping.

**Note:** S2S/Postback tracking is an advanced feature. As such, set up of this feature falls outside the scope of our support. You may [need a developer](https://support.tapfiliate.com/advanced-configurations-automation/api-webhooks-automations/need-a-tech-expert-how-to-find-the-right-developer-for-your-program.md) to assist in setting this up.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.