# Introduction

Welcome to the Playtime SDK documentation, your comprehensive guide to integrating ad-based monetization solutions into your Android applications. Playtime offers Android app developers an innovative platform designed for seamless and effective app monetization through ads.

## What is Playtime SDK?

Playtime SDK empowers Android developers to effortlessly integrate ad-based monetization features into their applications. It provides tools to implement offerwall and rewarded advertising, enhancing user engagement and maximizing app revenue potential.<br>

Here "Playtime" is a unique advertising format, which rewards users for installing and continuously using apps from our advertising partners. Clicking on any ad displayed in the Playtime offerwall will bring the user to the Play Store. By playing this advertised app, users receive rewards in your app - the more they play, the more they earn! And, of course, you also earn money for every install generated through users of your app.


# Our Features

## Key Features

* **Rewarded Advertising:** Incentivize users with rewards like in-app currency or premium content for interacting with ads.
* **Easy Integration:** Easily monetize your app with straightforward integration using Playtime SDK.
* **Offerwall:** Encourage user engagement and earn revenue through completed offers.

## Why Choose Playtime SDK?

* **Optimized Monetization**: Maximize revenue with a range of ad-based monetization solutions.
* **Enhanced User Engagement:** Increase user retention by integrating offerwalls and rewarded advertising.
* **Simple Integration:** Quick and straightforward integration process supported by detailed documentation and code examples.


# Create Publisher Account

1. #### Create an account with Playtime through the👉 [`Publisher Dashboard`](https://publisher.playtimeads.com/)

<figure><img src="/files/3oL4UOA5jZCqNzsxTW8F" alt="" width="563"><figcaption></figcaption></figure>

2. After Register You will have to request your account manager to approve your account after you have signed up on the dashboard

<figure><img src="/files/vgwLf3gTEPxmSaT2K3b0" alt="" width="563"><figcaption><p>Fill all information then click on Register for approval.</p></figcaption></figure>

Once you have the dashboard access, you can proceed with creating your first app and the integration flow.


# Create Your App

Once your account is approved, you can access `manage apps` from the side bar.

1. Click on the `manage apps` item on the side bar.

<figure><img src="/files/UeGEpNIbiLTna6dG5pDF" alt="" width="563"><figcaption></figcaption></figure>

2. Next, Provide us all necessary assets for the app by clicking on the `Add App` button.

<figure><img src="/files/BYZuDD2IiaH39VCoalrK" alt="" width="563"><figcaption></figcaption></figure>

3. Additionally, Submit us your S2S Url for postback👉 [( GUIDE )](/sdk-integration/setup-s2s-postback)

<figure><img src="/files/1uKMywatxg4WnjNbW2Ry" alt="" width="563"><figcaption></figcaption></figure>


# Android Integration

## Add Dependency

* Add the Playtime dependency to your app's build.gradle (module level)

{% tabs %}
{% tab title="Java" %}

```java
dependencies {
    implementation 'com.playtimeads:offerwall:2.0.6'
}
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
dependencies {
    implementation ("com.playtimeads:offerwall:2.0.6")
}
```

{% endtab %}
{% endtabs %}


# Initialize SDK

To make all of the features of the Playtime SDK available, you need to initialize it first. This initialization happens asynchronously in the background, with its completion indicated by a callback method. Make sure to initialize the SDK immediately after the app launches and after the user login in the app.

### Best practices for the SDK initialization:

* **Initialize early:** Initialize the SDK as soon as possible after your app starts. This ensures all SDK features are ready for use right away.
* **Initialize after your app authentication:** Once a user signs up or logs in in your app, initialize the SDK again with the latest user details. This updates the userID within the SDK and ensures reward will be delivered to the user. If a user is not login in your app, you can pass blank or 0.
* **Initialization triggers:** Call the init method at the app start and after login

### Initialization

The initialization will run in the main application process asynchronously in the background and notify you when it is finished by invoking the OfferWallInitListener's onInitSuccess or onAlreadyInitializing or onInitFailed method

**Important:** Initialization must happen on the main thread since it's a UI-related action. Calling any of the init methods off the main thread could lead to app disruptions.

{% tabs %}
{% tab title="Java" %}

```java
PlaytimeAds.getInstance().init(context, applicationKey, userID, new OfferWallInitListener() {
     @Override public void onInitSuccess() {
      Log.e("TAG", "onInitSuccess");
      }
     @Override public void onAlreadyInitializing() {
      Log.e("TAG", "onAlreadyInitializing");
      }
     @Override public void onInitFailed(String error) {
      Log.e("TAG", "onInitFailed: " + error);
      }
  });
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
PlaytimeAds.getInstance().destroy()// clears your previous session
PlaytimeAds.getInstance().init(context, applicationKey, userID,object : OfferWallInitListener {
      override fun onInitSuccess() {
      Log.e("TAG", "onInitSuccess");
      }
      override fun onAlreadyInitializing() {
      Log.e("TAG", "onAlreadyInitializing");
      }
      override fun onInitFailed(error: String?) {
      Log.e("TAG", "onInitFailed: " + error);
      }
  })
```

{% endtab %}
{% endtabs %}

### Parameters:

| Parameter      | Type   | Explanation                                                                                                                                                                                                      |
| -------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| UserID         | String | A custom that will be used to identify your user uniquely. This will be sent back in the postback. If user is not logged-in in your app, please pass 0 or blank in UserId. Max character limit is 50 characters. |
| applicationKey | String | Application key provided in publisher panel for your application                                                                                                                                                 |

{% hint style="danger" %}
Re-initialize Playtime SDK after user login. Otherwise rewarding the user is not guaranteed

Note: If SDK is already initialized, You need to destroy previous session first in order to initialize it again for new UserId.
{% endhint %}

### Clear Session on Logout

Don't miss to clear Playtime session when users logout from the app.

{% tabs %}
{% tab title="Java" %}

```java
PlaytimeAds.getInstance().destroy(); // clears your previous session
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
PlaytimeAds.getInstance().destroy()// clears your previous session
```

{% endtab %}
{% endtabs %}


# Launch Offerwall

The primary function of the Playtime SDK is showing the offerwall to the users. The offerwall lists various campaigns that the users can complete to receive a reward in the app's virtual in-app currency.

Offerwall shows Event based campaigns, Target based campaigns and playtime campaigns.

<details>

<summary>Event-Based</summary>

Rewards users based on events. Users are rewarded after completing defined tasks. For example: Register into the app, in-app purchases, Make online purchases etc.

</details>

<details>

<summary>Playtime</summary>

Which rewards users for achieving a designated combination of events within advertised apps and also rewards users for the time they spend in the advertised app, e.g. Earn 50 points per minute for playing a game.

</details>

<details>

<summary>Level-Based</summary>

Playtime tab also has level based offers. Which rewards users for achieving a designated combination of events within advertised apps, e.g. in-app purchases, and/or reaching specified game levels. Users are rewarded after completing each task. Example: "Up to 5 points per level" or "Complete Level 10" etc.

</details>

We recommend triggering the offerwall via a button or UI element. Use the code below to launch the Playtime OfferWall Activity and display the Playtime Offerwall tab.

{% tabs %}
{% tab title="Java" %}

```java
if (PlaytimeAds.getInstance().isInitialized()) {
       PlaytimeAds.getInstance().open(context);
} else {
       setToast(context, "PlaytimeAds is not initialized");
       // Initialize Playtime SDK
 }
```

{% endtab %}

{% tab title="Kotlin" %}

```kotlin
if (PlaytimeAds.getInstance().isInitialized) {
       PlaytimeAds.getInstance().open(context)
} else {
       Toast.makeText(context, "PlaytimeAds is not initialized",Toast.LENGTH_SHORT).show()
       // Initialize Playtime Ads SDK
}
```

{% endtab %}
{% endtabs %}

### Access to Advertising Info

We also ask the user to accept the App Usage Permissions. This allows us to monitor the time spent in each game or app. Without accepting these permissions, users won't be eligible to participate in such campaigns which requires app usage access information to reward users.


# Unity Integration

## 🧩Prerequisites

* Unity version 2022.3.38f1 or later
* Unity Android Build Support installed
* Basic familiarity with Unity C# scripts
* Your application key from Playtime SDK
* Targeting Android platform only

### Navigate to: `Assets → Plugins → Android → mainTemplate.gradle`

Add the following line inside the dependencies block:

```csharp
implementation 'com.playtimeads:offerwall:2.0.6'
```

***

### Create a C# Wrapper Class With a Listener Proxy Class

This wrapper bridges Unity and the native Android library.

```csharp
using System;
using UnityEngine;

public class PlaytimeAds
{
    private AndroidJavaObject objPlaytimeAds;
    private AndroidJavaObject unityActivity;
    public static Action OnInitSuccess;
    public static Action OnInitFailed;
    public PlaytimeAds()
    {
        using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            unityActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
        }
        using (AndroidJavaClass javaClass = new AndroidJavaClass("com.playtimeads.PlaytimeAds"))
        {
            objPlaytimeAds = javaClass.CallStatic<AndroidJavaObject>("getInstance");
        }
    }
    public void DestroyPlaytimeAds()
    {
         if (objPlaytimeAds != null)
         {
             // Call the method in the Java class without expecting a return value
             Debug.LogError("destroyPlaytimeAds method is getting called");
             objPlaytimeAds.Call("destroy");
         }
         else
         {
             Debug.LogError("Failed to create Android class instance destroyPlaytimeAds.");
         }
    }
    public void Init(string applicationId, string userId)
    {
        if (objPlaytimeAds != null)
        {
            var listenerProxy = new Proxy.Listener();
            Debug.Log("init method is getting called" + userId);
            objPlaytimeAds.Call("init",unityActivity, applicationId, userId,listenerProxy);
        }
        else
        {
            Debug.LogError("Failed to create Android class instance. isInitPlaytimeAds1");
        }
    }

    public void OpenOfferWall()
    {
        if (objPlaytimeAds != null)
        {
            // Call the method in the Java class without expecting a return value
            Debug.LogError("open Offerwall method is getting called");
            // objPlaytimeAds.Call("isInitialized");
            objPlaytimeAds.Call("open",unityActivity);
        }
        else
        {
            Debug.LogError("Failed to create Android class instance. isInitPlaytimeAds1");
        }
    }
}
namespace Proxy
{
    public class Listener : AndroidJavaProxy
    {
        public Listener() : base("com.playtimeads.listeners.OfferWallInitListener") { }

        // Implement the onSuccess method
        public void onInitSuccess()
        {
            PlaytimeAds.OnInitSuccess?.Invoke();
            Debug.Log("onInitSuccess is called");
        }

        public void onAlreadyInitializing()
        {
            Debug.Log("onAlreadyInitializing is called");
        }

        // Implement the onFailure method
        public void onInitFailed(string error)
        {
            PlaytimeAds.OnInitFailed?.Invoke();
            Debug.LogError("onInitFailed is called: " + error);
        }
    }
}

```

***

### Create a Manager Class

This manager centralizes all interactions with the wrapper class.

```csharp

public class PlaytimeAdsManager : Manager<PlaytimeAdsManager>
{
    private PlaytimeAds _playtimeAds;
    public PlaytimeAds PlaytimeAds => _playtimeAds ??= new PlaytimeAds();

    public void InitializeWithUserId(string userId)
    {
#if !UNITY_ANDROID || UNITY_EDITOR
        Debug.Log("PlaytimeAds Initialization Skipped in Editor");
        return;
#endif
        Debug.Log("Initializing PlaytimeAds...");
        PlaytimeAds.OnInitSuccess += OnInitSuccess;
        PlaytimeAds.OnInitFailed += OnInitFailed;
        PlaytimeAds.Init(userId);
    }

    private void OnInitSuccess()
    {
        Debug.Log("PlaytimeAds Initialized Successfully");
    }

    private void OnInitFailed()
    {
        Debug.Log("PlaytimeAds Initialization Failed");
    }

    public void DestroyPlaytimeAds()
    {
#if !UNITY_ANDROID || UNITY_EDITOR
        Debug.Log("Destroy Skipped in Editor");
        return;
#endif
        PlaytimeAds.DestroyPlaytimeAds();
    }

    public void OpenOfferWall()
    {
#if !UNITY_ANDROID || UNITY_EDITOR
        Debug.Log("Open Offerwall Skipped in Editor");
        return;
#endif
        PlaytimeAds.OpenOfferWall();
    }
}
```


# Initialize SDK

### Use the Manager in Unity Scripts

Integrate Playtime Ads SDK into your app by following these simple steps. Ensure proper initialization, offer wall access, and optional SDK cleanup for best results.

Now you can use `PlaytimeAdsManager.Instance` to call SDK functions anywhere in your Unity project:

## Initialize the SDK with User ID&#x20;

Use your **Application Key** and a unique **User ID** from your system to initialize the SDK.

```csharp
// Initialize with user ID
PlaytimeAdsManager.Instance.InitializeWithUserId(<YOUR_APPLICATION_KEY>,<USER_ID>);
```

{% hint style="warning" %}
Replace `"<YOUR_APPLICATION_KEY>"` and `“<USER_ID>”` with your actual app key provided by Playtime SDK and logged-in user id.
{% endhint %}


# Launch Offerwall

## Open the Offerwall

Call this function after initialization to show users the Playtime Offerwall.

```csharp
// Open OfferWall
PlaytimeAdsManager.Instance.OpenOfferWall();
```

This allows users to interact with offers and earn rewards within your app.

***

## Clear Session on Logout

Don't miss to clear Playtime session when users logout from the app.

```csharp
// Optionally destroy SDK
PlaytimeAdsManager.Instance.DestroyPlaytimeAds();
```

***

### ✅ Best Practices

* Make sure you initialize SDK using `InitializeWithUserId` before opening the Offerwall.
* Use consistent User IDs to ensure proper user tracking.
* Call `DestroyPlaytimeAds` when SDK usage is complete.


# Setup S2S Postback

You can configure the S2S postback for the application in the dashboard while adding new app inside manage app section.

## Setting Up Postback URL

We fire an HTTP GET request to the provided postback URL. The following query parameters will be consider.

```url
//Example URL

https://www.example.com/postbacks/postback_file_name.php
```

<table><thead><tr><th width="206">Query Params	</th><th>Description</th></tr></thead><tbody><tr><td><code>user_id</code></td><td>Unique identifier of the user from your app.</td></tr><tr><td><code>offer_id</code></td><td>The identifier of the offer for which the user receives a postback.</td></tr><tr><td><code>offer_name</code></td><td>The name of the offer for which the user receives a postback.</td></tr><tr><td><code>payout</code></td><td>The amount earned per completed milestone by publisher.</td></tr><tr><td><code>amount</code></td><td>The value of the reward earned by the end user.</td></tr><tr><td><code>signature</code></td><td>Hash of the above values to verify the request</td></tr><tr><td><code>task_name</code></td><td>The name of task for which user receives reward (for level or playtime offers)</td></tr><tr><td><code>task_id</code></td><td>The id of task for which user receives reward (for level or playtime offers)</td></tr><tr><td><code>currency_name</code></td><td>The currency name you have set will be sent to you in this variable in the postback.</td></tr></tbody></table>

**Example**

user\_id = `123`

offer\_id = `123`&#x20;

offer\_name = `Test_game`&#x20;

payout = `500`

amount= `250`

signature = `45786sdg458-sdg465-659s465sdg-465ery98bm`

task\_name = `Complete_level_X`

task\_id = `162657`&#x20;

currency\_name = `Coin`

PostbackURL ->  `https://www.example.com/postbacks/postback_file_name.php?user_id=123&offer_id=123&offer_name=Test_game&payout=500&amount=250&signature=45786sdg458-sdg465-659s465sdg-465ery98bm&task_name=Complete_level_X&task_id=162657&currency_name=Coin`&#x20;

### Sample code to validate request

{% tabs %}
{% tab title="PHP" %}

<pre class="language-php"><code class="lang-php"> // Signature Authentication
 
 $userId = $_REQUEST['user_id'];
 $offer_id = $_REQUEST['offer_id'];
 $coin_amount = (int)$_REQUEST['amount'];
 $signature = $_REQUEST['signature'];
 $task_id = $_REQUEST['task_id'];
 $task_name = $_REQUEST['task_name'];
 $currency_name = $_REQUEST['currency_name '];

 $calculated_signature = sha1($<a data-footnote-ref href="#user-content-fn-1">userId</a>.$<a data-footnote-ref href="#user-content-fn-2">offer_id</a>.$<a data-footnote-ref href="#user-content-fn-3">coin_amount</a>."<a data-footnote-ref href="#user-content-fn-4">YOUR_APPLICATION_KEY</a>"."<a data-footnote-ref href="#user-content-fn-5">YOUR_APPLICATION_SECRET_KEY</a>");
 
 if($signature === $calculated_signature){
 // Request is valid
 }
</code></pre>

{% endtab %}
{% endtabs %}

## Test Callback Tool

We provide a dedicated **Test Callback Tool** so you can safely verify your callback configuration before going live.

<figure><img src="/files/earaKcSwTsiKVBUUbBVU" alt=""><figcaption></figcaption></figure>

#### Key Features:

* Safely test your callback URL without affecting live data.
* Instantly simulate user actions and reward payouts.
* Debug and validate parameters directly from the dashboard.

#### Input Fields:

* **User ID** → Simulates a user session.

<figure><img src="/files/1kA2fWN8bM5ytB6S8Wyo" alt=""><figcaption></figcaption></figure>

#### How It Works:

1. Enter the **User ID** (this must match the User ID used in your SDK initialization).
2. Click **Send** **Test Postback**.

ℹ️ **Note**: Make sure the callback endpoint is correctly configured to receive and validate all required parameters.

#### **Points to keep in mind while setting up postback URL**

* All parameters are append from our side publisher has to give only path to their postback file.
* Value of amount passed in postback is converted in your given app currency at your given currency rate in exchange of 1$.

[^1]: Your application `unique_id` set while initializing the SDK.

[^2]: The identifier of the offer for which the user receives a postback.

[^3]: The value of the reward earned by the end user.

[^4]: Your Unique Application ID, which you get from manage App section in publisher panel.

[^5]: Your Application Secret Key, which you get from manage App section in your publisher panel. **This key is diffrent for all applications.**


# Introduction

This API allows you to retrieve a curated list of offers available for monetization. These offers can be filtered and integrated into your mobile apps, websites, or platforms to drive user engagement and revenue.

The Offers API allows publishers to fetch available campaigns in real time, along with targeting rules, payout details, and tracking URLs.


# Authentication

All requests must include your unique <mark style="background-color:orange;">App Key</mark> & <mark style="background-color:orange;">Secret Key</mark>, Which you will find in Offer Api section of your Dashboard. As shown in below image.

<figure><img src="/files/FMmCV2s0Q5zVcNQpYNjp" alt=""><figcaption></figcaption></figure>

## How to access the API

```php
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.playtimeads.com/Api/Offers',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'GET',
  CURLOPT_HTTPHEADER => array(
    'AppKey: <YOUR_APP_KEY>',
    'AppSecretKey: <YOUR_SECRET_KEY>'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;
```

{% hint style="warning" %}
Replace `“<YOUR_APP_KEY>”` and `"<YOUR_SECRET_KEY>"` with your actual keys provided in your dashboard as shown in above image.
{% endhint %}

## Example Response

```json
{
    "total_offers": 1,
    "total_page": 1,
    "page": 1,
    "limit": 1000,
    "Offers": [
        {
            "campaignId": "XXXXXX01",
            "totalPayout": 9.999,
            "status": "active",
            "campaignName": "Sample Game Campaign",
            "description": "<p>Step 1: Tap Play Now and install the app.<br />\r\nStep 2: Open the app to start.<br />\r\nStep 3: Complete the first level.<br />\r\nStep 4: Keep playing to earn more rewards!</p>\r\n",
            "model": "CPL",
            "app": {
                "title": "Sample Game",
                "packageName": "com.example.samplegame",
                "previewUrl": "https://play.google.com/store/apps/details?id=com.example.samplegame",
                "logo": "https://example.com/images/sample_logo.jpg",
                "bannerImage": "https://example.com/images/sample_thumbnail.jpg"
            },
            "currency": {
                "name": "USD",
                "symbol": "$"
            },
            "payoutEvents": [
                {
                    "event": "level_1_complete",
                    "eventTitle": "Complete Level 1",
                    "eventDesc": "",
                    "payoutAmount": 0.010,
                    "targetCaps": "0"
                },
                {
                    "event": "level_5_complete",
                    "eventTitle": "Complete Level 5",
                    "eventDesc": "",
                    "payoutAmount": 0.050,
                    "targetCaps": "0"
                },
                {
                    "event": "level_10_complete",
                    "eventTitle": "Complete Level 10",
                    "eventDesc": "",
                    "payoutAmount": 0.500,
                    "targetCaps": "0"
                },
                {
                    "event": "boss_level_complete",
                    "eventTitle": "Defeat Final Boss",
                    "eventDesc": "",
                    "payoutAmount": 1.000,
                    "targetCaps": "0"
                },
                {
                    "event": "game_completed",
                    "eventTitle": "Finish the Game",
                    "eventDesc": "",
                    "payoutAmount": 5.000,
                    "targetCaps": "0"
                }
            ],
            "targeting": {
                "os": "android",
                "countries": [
                    {
                        "iso": "US"
                    }
                ]
            },
            "tracking": {
                "clickUrl": "http://tracking.example.com/track/oa/XXXXXXX/XXXXXX01/?clickId={clickId}&gaid={gaid}&sub1={sub1}...&sub10={sub10}",
                "impressionUrl": "https://tracking.example.com/i/XXXXXX01/{publisher_id}"
            }
        }
    ]
}

```

{% hint style="success" %}
**status** – Indicates whether the offer is currently available. Value can be `active` (offer is live) or `paused` (offer is temporarily unavailable, usually due to cap being reached).
{% endhint %}

## Click Url Tracking Parameters&#x20;

| Parameter          | Description                                                                                                                                                                      |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| {clickId}          | Pass the unique user ID from your platform that distinctly identifies each user.                                                                                                 |
| {gaid}             | Pass the user’s Google Advertising ID in this parameter to enable accurate tracking and attribution.                                                                             |
| {sub1}  to {sub10} | These are optional parameters that allow the publisher to send custom user information, which will be returned in same parameter in postback to help identify or track the user. |


# Setup Postback

## Postback URL Structure

{% code overflow="wrap" %}

```html
//Example Postback URL

https://www.example.com/postbacks/postback_file_name.php?user_id={user_id}&offer_id={offer_id}&offer_name={offer_name}&payout={payout}&signature={signature}&event={event}&sub1={sub1}&sub2={sub2}&sub3={sub3}&sub4={sub4}&sub5={sub5}&sub6={sub6}&sub7={sub7}&sub8={sub8}&sub9={sub9}&sub10={sub10}&gaid={users_advertising_id}&clickIp={clickIpaddress}&clickDatetime={clickDatetime}&conversionDatetime={conversionDatetime}&timeZone={timeZone}&callback_type={callback_type}
```

{% endcode %}

## **Available Macros (Placeholders)**

| Macro                  | Description                                                                                |
| ---------------------- | ------------------------------------------------------------------------------------------ |
| `{user_id}`            | Unique identifier of the user from your app (sent in click URL).                           |
| `{offer_id}`           | Unique identifier assigned to the offer in our system.                                     |
| `{offer_name}`         | The name/title of the offer that generated the conversion.                                 |
| `{payout}`             | Total revenue earned from the event.                                                       |
| `{sig}`                | A secure hash signature generated for verifying the authenticity of the postback data.     |
| `{event}`              | Name of the event or goal triggered (e.g., registration, level\_completed).                |
| `{sub1}` - `{sub10}`   | Custom parameters you passed in the click URL to help identify the user or campaign.       |
| `{clickDatetime}`      | Date and time when the user clicked the offer link.                                        |
| `{conversionDatetime}` | Date and time when the conversion (e.g., purchase, install) happened.                      |
| `{timeZone}`           | Time zone in which the click and conversion timestamps are recorded.                       |
| `{callback_type}`      | Type of callback (e.g., 1 = Api Callback, 2 = Direct offer Callback, 3 = iFrame Callback). |

**Example**

`clickId`= `123`

`offer_id`= `123`

`offer_name`= `Test_game`

`payout`= `500`

`signature`= `45786sdg458-sdg465-659s465sdg-465ery98bm-65fb798sdg32dv`

`event`= `Complete_level_X`

`clickDatetime`= `202X-0X-0X XX:XX:XX`  &#x20;

`conversionDatetime`= `202X-0X-0X XX:XX:XX`

`timeZone`= `IST`

`callback_type`= `1`

PostbackURL -> `https://www.example.com/postbacks/postback_file_name.php?clickId =123&`offer\_id`=123&`offer\_name`=Test_game&payout=500&signature=45786sdg458-sdg465-659s465sdg-465ery98bm-65fb798sdg32dv&event=Complete_level_X&clickDatetime=202X-0X-0X XX:XX:XX&conversionDatetime=202X-0X-0X XX:XX:XX&timeZone=IST&callback_type=1`

## Test Callback Tool

We provide a dedicated **Test Callback Tool** so you can safely verify your callback configuration before going live.

<figure><img src="/files/g8LV84cGq5UkZ3W9HNkW" alt=""><figcaption></figcaption></figure>

#### Key Features:

* Safely test your callback URL without affecting live data.
* Instantly simulate user actions and reward payouts.
* Debug and validate parameters directly from the dashboard.

#### Input Fields:

* **User ID** → Simulates a user session.
* **Custom Parameters** → sub1=abc\&sub2=123\&sub5=xyz

<figure><img src="/files/XjcTK7KnvoCUSvBpJYRE" alt=""><figcaption></figcaption></figure>

#### How It Works:

1. Enter the **User ID** (this must match the User ID used in your SDK initialization).
2. Enter the **Custom Parameters** ( This is extra params which you can use to track conversions )&#x20;
3. Click **Send** **Test Postback**.

ℹ️ **Note**: Make sure the callback endpoint is correctly configured to receive and validate all required parameters.


# Introduction

Welcome to the **Playtime SDK iFrame Integration** guide.\
This integration allows you to embed our Offerwall directly into your app or website using a simple iFrame — no SDK required.

## Why iFrame Integration?

* Quick & easy setup.
* Lightweight (no extra dependencies).
* Seamless user experience inside your app.
* Rewards are automatically tracked and delivered via postback.


# iFrame Setup

Basic Setup

## Insert the following iFrame code into your app’s **WebView** or website:

```html
<iframe 
    src="https://web.playtimeads.com/index.php?app_id=YOUR_APP_ID&user_id=USER_UNIQUE_ID" 
    frameborder="0" 
    scrolling="yes">
</iframe>
```

* `app_id` → Your Unique iFrame App Key .
* `user_id` → Unique identifier of the user from your system.
* `sub1-sub10`  → Custom parameter for additions tracking information.
* `gaid` → Users Google Advertiser Id (optional).

## How to get your Unique iFrame App Key ?

<figure><img src="/files/0Wkb9G6RkBoFO02MMpwk" alt=""><figcaption></figcaption></figure>

1. From the left-hand menu, navigate to the **`Manage iFrame`** tab.
2. Click on the **`Create Web App`** button to add a new web app.
3. Once created, your **`App Key`** will be displayed in the App Key column (see image above).


# Setup Postback

When a user successfully completes an offer, Playtime SDK will send a **postback** to your server with the reward details.\
This ensures that rewards are delivered securely and accurately.

{% code overflow="wrap" %}

```
// Example Postback 

https://www.example.com/postbacks/postback_file_name.php?user_id={user_id}&offer_id={offer_id}&offer_name={offer_name}&payout={payout}&signature={signature}&event={event}&sub1={sub1}&sub2={sub2}&sub3={sub3}&sub4={sub4}&sub5={sub5}&sub6={sub6}&sub7={sub7}&sub8={sub8}&sub9={sub9}&sub10={sub10}&gaid={users_advertising_id}&clickIp={clickIpaddress}&clickDatetime={clickDatetime}&conversionDatetime={conversionDatetime}&timeZone={timeZone}&callback_type={callback_type}&currency_name={currency_name}&appKey={appKey}&amount={amount}
```

{% endcode %}

## Postback Parameters

| Parameter            | Description                                                                                      |
| -------------------- | ------------------------------------------------------------------------------------------------ |
| `user_id`            | Unique identifier of the user from your app (mentioned in iFrame url).                           |
| `offer_id`           | Unique ID of the campaign/offer.                                                                 |
| `offer_name`         | Name of the campaign (URL encoded).                                                              |
| `payout`             | Publisher payout amount in USD.                                                                  |
| `signature`          | Security hash to validate authenticity.                                                          |
| `event`              | Event Name (e.g., `install`, `signup`, `complete_level_2`).                                      |
| `sub1` - `sub10`     | Custom tracking parameters (optional).                                                           |
| `gaid`               | Google Advertising ID of the user (if available).                                                |
| `clickIp`            | IP address of the user when clicking the offer.                                                  |
| `clickDatetime`      | Timestamp of the click (in `YYYY_MM_DD HH:MM:SS` format).                                        |
| `conversionDatetime` | Timestamp when conversion occurred.                                                              |
| `timeZone`           | Time zone of conversion (e.g., IST).                                                             |
| `callback_type`      | Type of callback (e.g., `1 = Api Callback`, `2 = Direct offer Callback`, `3 = iFrame Callback`). |
| `amount`             | Reward coins/points to be credited to the user in your app.                                      |
| `appKey`             | Unique App Key assigned to your app.                                                             |
| `currency_name`      | Name of your inapp currency which you have set.                                                  |

### Sample code to validate signature

{% tabs %}
{% tab title="PHP" %}

<pre class="language-php"><code class="lang-php"> // Signature Authentication
 
 $userId = $_REQUEST['user_id'];
 $offer_id = $_REQUEST['offer_id'];
 $coin_amount = (int)$_REQUEST['amount'];
 $signature = $_REQUEST['signature'];
 $event= $_REQUEST['event'];

 $calculated_signature = sha1($<a data-footnote-ref href="#user-content-fn-1">userId</a>.$<a data-footnote-ref href="#user-content-fn-2">offer_id</a>.$event."<a data-footnote-ref href="#user-content-fn-3">YOUR_APPLICATION_KEY</a>"."<a data-footnote-ref href="#user-content-fn-4">YOUR_APPLICATION_SECRET_KEY</a>");
 
 if($signature === $calculated_signature){
 // Request is valid
 }
</code></pre>

{% endtab %}
{% endtabs %}

## Test Callback Tool

We provide a dedicated **Test Callback Tool** so you can safely verify your callback configuration before going live.

<figure><img src="/files/alOFvfyFJZI1aqd1pVum" alt=""><figcaption></figcaption></figure>

**Key Features:**

* Safely test your callback URL without affecting live data.
* Instantly simulate user actions and reward payouts.
* Debug and validate parameters directly from the dashboard.

#### Input Fields:

* **User ID** → Simulates a user session.
* **Custom Parameters** → sub1=abc\&sub2=123\&sub5=xyz

<figure><img src="/files/CQ6ovAFiMmcqfWUMyPbQ" alt=""><figcaption></figcaption></figure>

#### How It Works:

1. Enter the **User ID** (this must match the User ID used in your SDK initialization).
2. Enter the **Custom Parameters** ( This is extra params which you can use to track conversions )&#x20;
3. Click **Send** **Test Postback**.

ℹ️ **Note**: Make sure the callback endpoint is correctly configured to receive and validate all required parameters.

[^1]: Your application `unique_id` set while initializing the SDK.

[^2]: The identifier of the offer for which the user receives a postback.

[^3]: Your Unique Application ID, which you get from manage App section in publisher panel.

[^4]: Your Application Secret Key, which you get from manage App section in your publisher panel. **This key is diffrent for all applications.**


# FAQs

<details>

<summary>Is it necessary to provide the userId at app start-up with the init method?</summary>

No. Since the init method should happen at app start-up, there are circumstances where you don’t yet have this data. For example, if the user hasn’t signed in yet. In these cases, it’s still critical to init at the app start up, but you can pass a blank or 0 value in UserId. After login, re-initialize the SDK with proper userId.&#x20;

Remember that the userId is critical for doing S2S payouts, without it your users will not be able to get their rewards. It is also important to note that whatever the last supplied userId was is what will be sent in the S2S payout URL. Therefore, the last supplied UserId was what will be sent in the S2S payout URL.

</details>

<details>

<summary>Do I need to do anything with the Playtime SDK after the user logs out?</summary>

You should clear the previous session by using PlaytimeAds.getInstance().destroy() code to ensure SDK will reinitialize properly with new user details when user login the app again.

</details>

<details>

<summary>What is the size of SDK?</summary>

SDK size depends on the wrapper, but it is roughly <0.5MB.

</details>

<details>

<summary>How often is the SDK updated?</summary>

The SDK is updated every couple of months. Please keep an eye out on our&#x20;

Add the Playtime 👉 [`SDK Dependency`](broken://pages/a5wlqVZ0lqkf6PMYF7gV) section.&#x20;

Where you can see the latest SDK version to download.

</details>

<details>

<summary>What kind of data does the SDK track? I need to share this information with the Google Play Store.</summary>

All of the data that we collect can be found in the AndroidManifest.xml of the SDK

</details>

<details>

<summary>How do users know that they are able to receive a reward?</summary>

For Android users, we send a postback for rewards. Please generate a push notification to notify users &#x20;

while receiving postback from us.

</details>

<details>

<summary>I'm not seeing campaigns/games in the offerwall?</summary>

The most common reason is if you have started the same campaigns/games previously on your device, so it will not be visible to you.

</details>

<details>

<summary>After playing some time-based reward games (Playtime), I stopped receiving rewards after some time. Why?</summary>

It can happen because you stopped progressing through the game. To fix this, please keep playing and progressing through the game.

</details>

<details>

<summary>What's the difference between Event-Based, Playtime, and Level-Based Campaigns?</summary>

We have more information about this in our docs. Please refer to them 👉[`here`](broken://pages/qJJRhKagrBhSmc4zS3H6) .

</details>

<details>

<summary>What is the use of the GAID?</summary>

We use GAID to identify users. We provide these data to our advertising partners so they can count attribution.

</details>

<details>

<summary>Why does the user need to accept Access to Advertising Info? </summary>

We also ask the user to accept the App Usage Permissions. This allows us to monitor the time spent in each game or app. Without accepting these permissions, users won't be eligible to participate in such campaigns which requires app usage access information to reward users.

</details>

<details>

<summary>Why does the user need to accept TOS?</summary>

We have more information about this in our docs. Please refer to them👉 [`here`](/other/terms-of-service) . This is what the users sees in the TOS page:&#x20;

*<mark style="background-color:yellow;">We hereby inform you that Playtime processes the following personal data within the framework of the use of offers:</mark>*

### *<mark style="background-color:yellow;">- Installed apps (including the use duration and use history)</mark>*

<mark style="background-color:yellow;">- We read Google service configuration to get your device level information. We also collect device-specific information (such as your hardware model, operating system version, unique device identifiers, ip address, GAID and mobile network information). We primarily use this information to detect fraud & unauthorized usage of Playtime services. Your device level information is also used in tracking your activity on Playtime for various actions & tasks to give you the best possible experience.</mark>

<mark style="background-color:yellow;">- The data will be connected to your end device via the device ID and sent, encrypted, to our servers. In order for app providers to finance our app suggestions, we must send them the device ID for billing purposes.</mark>

The processing of the above data is necessary to be able to recommend, via system messages, the installation of apps available in Playtime that match your interests, and calculate the bonuses acquired as a result of your use of the corresponding apps and to prevent fraudulent activity.

### *<mark style="background-color:yellow;">Consent</mark>*&#x20;

<mark style="background-color:yellow;">By clicking on “I Accept”, I give Playtime my consent to process my above-mentioned personal data and transmit it to other app providers so that I can use Playtime as described.</mark>

<mark style="background-color:yellow;">I am aware that a profile of interests will be generated using the above data, and depending on the types of apps I use, this may contain particularly sensitive personal data (e.g. health-related data or data about my sexual orientation, and any other data in special categories).</mark>

<mark style="background-color:yellow;">For that reason my consent also applies explicitly to the processing of this data.</mark>

*<mark style="background-color:yellow;">Please refer to the links to our ✒️</mark>* [*<mark style="background-color:yellow;">Privacy Policy</mark>*](https://playtimeads.com/PrivacyPolicy.html) *<mark style="background-color:yellow;">and 📝</mark>* [*<mark style="background-color:yellow;">Terms and Conditions</mark>*](https://playtimeads.com/TermsConditions.html) *<mark style="background-color:yellow;">before using our services.</mark>*

</details>

###


# Terms of Service

Users need to accept Playtime Terms of Service to use Playtime and access offers. Agreeing to the TOS is mandatory before installing any partner apps. After users accept the TOS, we can identify the types of apps/games they have installed, allowing our algorithm to tailor game suggestions on the offerwall based on their preferences.&#x20;

If the user rejects TOS, they will not be able to see offerwall campaigns

### Access to Advertising Info & Device Specific Information&#x20;

We collect device specific information from users to detect fraud & unauthorized usage of Playtime services. Your device level information is also used in tracking your activity on Playtime for various actions & tasks to give you the best possible experience.

### Access to App Usage

We also ask the user to accept the App Usage Permissions. This allows us to monitor the time spent in each game or app. Without accepting these permissions, users won't be eligible to participate in Playtime campaigns and will be limited to only Event-Based & Level-Based offers


