# Server-Side Rewarding

Server-side rewarding is a mechanism by which you can reward your users for completing Offer Wall offers. Server-side rewarding involves server-to-server interaction via a dedicated endpoint on your rewards server that receives requests from DT Offer Wall servers.

When a DT Advertising partner notifies us that your user has completed an offer, DT creates and sends a reward callback to your dedicated Offer Wall rewards endpoint. In this reward callback, DT includes basic information about the reward, such as the reward amount in virtual currency and the user to be rewarded.

Once you successfully process the callback, send a successful callback response back to DT. If DT receives a response other than successful, we re-send the reward callback up to 10 times until we receive a successful callback response.

The following diagram provides details about the server-side rewarding process.

{% @mermaid/diagram content="sequenceDiagram
box Publisher
participant App as App
participant SSR as Reward Server
end
participant OFW as DT Offer Wall Server
participant Advertiser as Advertiser Partner
autonumber
App ->> Advertiser: User taps Offer URL and completes Offer Requirement (subscribe, sign up, purchase, etc.)
Advertiser ->> OFW: Send offer completion
OFW ->> OFW: Process offer completion
OFW ->> SSR: Send Reward Callback (GET)
alt If callback processed unsuccessfully
loop up to 10 times
SSR ->> OFW: Reward Callback Response 200 OK
OFW ->> SSR: Send Reward Callback (GET)
end
else If callback processed successfully or intentionally not processed
SSR ->> OFW: Reward Callback Response = 200 OK
end
SSR ->> App: Reward User in Virtual Currency" %}

## Implementation of Server-Side Rewarding

{% stepper %}
{% step %}

### [Create reward endpoint](#step-1-create-reward-endpoint)

{% endstep %}

{% step %}

### [Configure reward handling in the DT Console](#step-2-configure-reward-handling-in-the-dt-console)

{% endstep %}

{% step %}

### [Allowlist DT IP addresses](#step-3-allowlist-dt-ip-addresses)

{% endstep %}

{% step %}

### [Implement callback responses](#step-4-implement-callback-response)

{% endstep %}

{% step %}

### [Send test callbacks](#step-5-send-test-callbacks)

{% endstep %}
{% endstepper %}

## Step 1: Create Reward Endpoint

To receive notifications when your user successfully completes an offer, create an endpoint on your reward server where DT can send notifications (reward callbacks). DT sends a reward callback whenever Advertiser Partners confirm that an offer has been completed. Use the information in the reward callback to deliver the reward to your user.

| Method         | `GET`                               |
| -------------- | ----------------------------------- |
| Content-Type   | `application/x-www-form-urlencoded` |
| Authentication | IP Allowlisting                     |

### Default Reward Callback Structure

DT calls your endpoint with a reward callback that includes default parameters, such as user ID and reward amount:

```
https://game.com/ofw?
&uid=rYtXWZPLKgQOPdDe6Yr8g2UV4AB7
&amount=987654
&currency_name=Coin
&currency_id=coin
```

The following table describes the parameters that DT always includes in the reward callback:

| Parameter       | Type   | Description                                                                      |
| --------------- | ------ | -------------------------------------------------------------------------------- |
| `uid`           | String | The user ID for the user account to be credited with virtual currency.           |
| `amount`        | Number | The amount of virtual currency to reward the user account.                       |
| `currency_name` | String | The name of the virtual currency being rewarded as configured in the DT Console. |
| `currency_id`   | String | The ID associated with the virtual currency being rewarded.                      |

### Additional Callback Parameters

In addition to the default parameters for the reward callback, you can have DT include additional parameters for fraud prevention and payout details. To prevent fraudulent rewards, DT highly recommends including security parameters so that each callback is unique. The following sample reward callback includes all optional parameters.

```
https://game.com/ofw?
uid=12345
&amount=10.50
&currency_name=Coins
&currency_id=coins
&_trans_id_=f4a7c2d9-1e6b-4f58-9a23-8d7e45bfc012
&sid=f3c1a97be8d52a61b40798fc3e15d6a42f89c550
&pub0=value0
&pub1=value1
&pub2=value2
&offer_title=Default+Offer
&payout_net=5.00
&net_payout_eur=4.50
&payout_gross=6.00
&payout_currency=EUR
&step_index=2
&lpid=123456
&vcs_enabled=false
&placement_id=default
```

The following table describes the additional parameters that DT can include in the reward callback. To have DT include these parameters in your reward callback, specify them in your **Callback URL** in the DT Console. For more information, see [Setting Up Reward Handling](https://app.gitbook.com/s/LbREhkP3WlLtP6TNVZ2Q/offer-wall/setting-up-an-existing-app/setting-up-reward-handling).

<table><thead><tr><th valign="top">PARAMETER</th><th valign="top">TYPE</th><th valign="top">DESCRIPTION</th></tr></thead><tbody><tr><td valign="top"><code>_trans_id_</code></td><td valign="top">String</td><td valign="top">A Universally Unique Identifier (UUID) for the reward transaction. Use this transaction ID to uniquely identify each transaction between your server and ours so that you don't accidentally reward a user twice. We recommend storing all transaction IDs in your system and comparing your known list of transaction IDs to the ID sent in each reward callback.<br>Due to the universally unique nature of the transaction ID, adding the ID to your callback ensures that the <code>sid</code> parameter is also universally unique. Using these parameters together, you can add in additional security to prevent fraudulent rewards.<br>If you want have DT include a secure ID (<code>SID</code>) in the reward callback, you must also include the transaction ID as it is part of the <code>SID</code> hash.</td></tr><tr><td valign="top"><code>sid</code></td><td valign="top">String</td><td valign="top">The hashed signature for the reward callback.<br>DT includes this signature only when you also include the Transaction ID (<code>_trans_id_</code>) in your reward callback and specify a security token in your Reward Handling settings. For more information about specifying a security token, see <a href="https://app.gitbook.com/s/LbREhkP3WlLtP6TNVZ2Q/offer-wall/setting-up-an-existing-app/setting-up-reward-handling">Setting Up Reward Handling</a>.<br>To ensure the security of reward callbacks, we recommend that you calculate the <code>sid</code> parameter and compare it to the parameter sent in the callback. This allows you to verify that the reward callback originated from DT.<br>Calculate the <code>sid</code> as a SHA1 hash of the following reward callback parameters:<br>- <code>security_token</code><br>- <code>uid</code><br>- <code>amount</code><br>- <code>_trans_id_</code><br>- <code>pub0</code>…<code>pub9</code> (if present)<br>For an example of the hash calculation process, see <a href="#code-example">Code Example</a>.</td></tr><tr><td valign="top"><code>pub0</code>…<code>pub9</code></td><td valign="top">String</td><td valign="top">If you implement custom parameters (<code>pub0…pub9</code>), DT passes these parameters back to you unaltered. For more information about these parameters in SDK implementations, see <a href="../../../dt-offer-wall-sdk/sdk-apis#show-options">Show Options</a>. For more information about these parameters in REST API implementations, see the REST API documentation provided by your DT Account Manager.</td></tr><tr><td valign="top"><code>offer_title</code></td><td valign="top">String</td><td valign="top">Title of the offer that the user completed.</td></tr><tr><td valign="top"><code>payout_net</code></td><td valign="top">Number</td><td valign="top">Amount the publisher earns for completion of the offer after revenue sharing and fee payments.</td></tr><tr><td valign="top"><code>net_payout_eur</code></td><td valign="top">Number</td><td valign="top">Amount in euros that the publisher earns for completion of the offer after revenue sharing and fee payments.</td></tr><tr><td valign="top"><code>payout_gross</code></td><td valign="top">Number</td><td valign="top">Total amount earned for the offer completion before revenue sharing and fee payments.</td></tr><tr><td valign="top"><code>payout_currency</code></td><td valign="top">String</td><td valign="top">The currency set for your Offer Wall account in the DT Console.</td></tr><tr><td valign="top"><code>lpid</code></td><td valign="top">String</td><td valign="top">Advertiser's unique ID for the offer landing page.</td></tr><tr><td valign="top"><code>step_index</code></td><td valign="top">Number</td><td valign="top">For multi-reward offers, this parameter is the index number for the completed step of the offer.</td></tr><tr><td valign="top"><code>vcs_enabled</code></td><td valign="top">Boolean</td><td valign="top">Indicates whether a virtual currency sale was active when the user clicked through to the offer. DT assigns the following values:<br><code>TRUE</code> = Virtual currency sale was active.<br><code>FALSE</code> = Virtual currency sale was not active.</td></tr><tr><td valign="top"><code>placement_id</code></td><td valign="top">String</td><td valign="top">The Offer Wall placement ID for the placement that called up the offer.</td></tr></tbody></table>

## Step 2: Configure Reward Handling in the DT Console

Once you have created your reward callback endpoint and decided which parameters you want DT to include in the reward callback, log in to the DT Console to add the **Callback URL** (endpoint and parameters) along with any security token you want DT to use. For more information, see [Setting Up Reward Handling](https://app.gitbook.com/s/LbREhkP3WlLtP6TNVZ2Q/offer-wall/setting-up-an-existing-app/setting-up-reward-handling).

{% hint style="danger" %}
Never surface the security token you enter in the DT Console in your client-side integration. To prevent fraudulent rewards, keep the token secret between your servers and ours.

If you think your token has been compromised, update your app configuration with a new token, and enter the new token in the DT Console.
{% endhint %}

## Step 3: Allowlist DT IP Addresses

If your server uses restrictive security settings or a firewall, allow traffic to and from the following IP addresses of DT Offer Wall servers:

* `34.23.227.47`
* `34.138.146.173`
* `34.139.143.157`
* `34.139.250.247`
* `34.139.252.26`
* `35.185.30.237`
* `35.196.16.124`
* `35.227.32.40`
* `52.51.229.163`
* `52.208.7.124`
* `52.212.4.99`
* `104.196.100.128`
* `104.196.193.31`

## Step 4: Implement Callback Response

When you receive and process a reward callback, send a response to DT to indicate the status of the reward process.

A blank response with any other status code not listed in the following table indicates an error processing a callback. In response, DT resends the original reward callback up to 10 additional times (with an exponentially increasing delay between each attempt) until we receive a successful response (`HTTP 200`).

<table><thead><tr><th width="178.44921875">Response Status Code</th><th>Description</th></tr></thead><tbody><tr><td><code>200</code></td><td>A blank response with this status indicates you have successfully processed the callback and rewarded the user with virtual currency. You can also use this status code to indicate a duplicate transaction (based on <code>_trans_id_)</code>or to intentionally reject a reward callback.</td></tr><tr><td><code>301</code> or <code>302</code></td><td>You can use redirects; however, all redirect locations must be absolute URLs, as specified in the <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.30">W3C standard</a>.</td></tr></tbody></table>

## Step 5: Send Test Callbacks

Once you have configured your rewards endpoint and callback structure, send a test callback so that you can validate your rewards setup. For more information, see [Sending Test Callbacks](https://app.gitbook.com/s/LbREhkP3WlLtP6TNVZ2Q/offer-wall/setting-up-an-existing-app/setting-up-reward-handling/sending-test-callbacks).

{% hint style="info" %}
If your integration specifies custom parameters (`pub0`…`pub9`), DT includes them in the test callback.
{% endhint %}

## Code Example

The Ruby code example below demonstrates the following aspects of implementing server-side rewarding:

* Gathering parameter values from the reward callback parameters to calculate the sid hash and compare it to the `sid` received in the reward callback.
* Comparing the transaction ID (`_trans_id_`) from the reward callback to previously processed transaction IDs.
* Gathering parameter values from the reward callback parameters to reward the user.
* Setting response status based on processing outcome.

{% code title="Ruby" %}

```ruby
require 'rubygems'
require 'bundler'
require 'sinatra'
require 'digest/sha1'

# For this example we assume that you have another file with the methods necessary to credit the reward to your users.
require File.join(File.dirname(__FILE__), 'reward_processing.rb')

# Your security token should only be present on your server and DT's
$SECURITY_TOKEN = '<YOUR SECURITY TOKEN>'

#### ENDPOINT ####

# Your endpoint for the reward callback should be configured in the DT Console
get '/reward' do
  begin
    #### PARAMETERS ####
    # Gather the parameters that will be used when calculated the sid and for crediting the reward
    user_id = params['uid']
    amount = params['amount']
    # For this example we assume that you have included the transaction id in the DT Console
    # If you have not, you can remove the following line
    trans_id = params['_trans_id_']
    # For this example we assume you are passing custom parameters to assist in rewarding
    # If you are not, you can remove the following two lines
    pub0 = params['pub0']
    pub1 = params['pub1']

    # Gather the additional parameters not used for the sid but still used for rewarding
    currency_name = params['currency_name']
    currency_id = params['currency_id']

    #### SID ####
    # Calculate the sid from the callback parameters
    sid_string = ''
    sid_string += $SECURITY_TOKEN
    sid_string += user_id
    sid_string += amount
    # For this example we assume you have the transaction id, pub0 and pub1 parameters
    # If you do not, you can remove the following three lines
    sid_string += trans_id
    sid_string += pub0
    sid_string += pub1
    sid = Digest::SHA1.hexdigest sid_string

    #### PROCESSING ####
    # Make sure the sid parameter matches what's in the callback
    if (sid == params['sid'])

      # Make sure you have not already processed the transaction
      # For this example we assume that get_transactions returns an array of credited transactions
      if !(get_transactions(uid).include? trans_id)

        # Reward the user
        # For this example we assume that reward_user credits the user with the reward amount
        reward_user(uid, amount, pub0, pub1, currency_name)

        # Set the status to 200 so that DT knows the callback was processed
        status 200
        body 'Callback Successful.'

      else
        # If the transaction was already rewarded, you can safely ignore the callback
        # Set the status to 200 so that DT knows the callback was processed
        status 200
        body 'Duplicate transaction id. Callback rejected.'
      end

    else
      # If the sid is incorrect, you can safely ignore the callback
      # Set the status to 200 so that DT knows the callback was processed
      status 200
      body 'Bad sid. Callback rejected.'
    end

  rescue Exception => e
    # If you ran into any error while processing the callback, you will want DT to try again
    # Set the status to something other than 200 so that DT knows the reward was not processed
    status 500
    body 'Callback failed. Error: ' + e.message
  end
end
```

{% endcode %}
