Self-managed currency
Set up Tapjoy Offerwall with a self-managed virtual currency by configuring reward callbacks and handling transactions on your server.
Read time 6 minutesLast updated a day ago
Use self-managed currency to manage your users' virtual currency directly on your own servers. This approach provides greater control compared to Tapjoy-managed currency, but it also requires you to handle all back-end processes, including storing and updating currency balances. Unlike Tapjoy-managed currency, self-managed currency doesn't support functions such as
getCurrencyBalanceawardCurrencyspendCurrency- Delayed Rewards: Tapjoy aims to reward users as quickly as possible but can't guarantee instant delivery. To ensure accurate balance updates, check for changes at regular intervals, such as during app launch, resume events, level transitions, video ad completion, and before store interactions. Inform your users that completing an offer might take some time before the reward appears.
- Platform-Specific Currency: Each platform (iOS, Android, etc.) requires its own distinct currency setup, even when self-managed.
Callback URL
When a user earns currency through an offer, Tapjoy sends an HTTP GET request to your specified callback URL. The request includes the following parameters:- : The user ID.
snuid - : The amount of currency to add to the user's account.
currency - : The user's Wi-Fi MAC address (if available).
mac_address
<callback_url>?snuid=<user_id>¤cy=<currency>&mac_address=<mac_address>// Examplehttp://www.sampledoman.com/payments/offers/tapjoy?&snuid=42&currency=50&mac_address=00-16-41-34-2C-A6
Server response requirements
Your server must respond with one of the following HTTP status codes:Status code | Cause |
|---|---|
| The user received their currency. |
|
|
- If Tapjoy doesn't receive a or
200response, it retries the request every five mins for up to four days.403 - If your server takes longer than 5 s to respond, Tapjoy treats the request as failed and retries the request.
- Responses must be UTF-8 encoded; otherwise, Tapjoy will retry even if the server returns a .
200
Fraud detection or prevention parameters
Use a virtual currency secret key to enhance security. Go to Monetize > Virtual Currency > Create/Edit in the Tapjoy Dashboard to configure your secret key. This key differs from the Application SDK Key and signs the callback. Currencies with a birtual currency secret key have the following additional security parameters:- ID: A unique identifier for the reward request (distinct from )
currency_id - Verifier: An MD5 hash of ID, snuid, currency, and the secret key.
Fraud scenarios to monitor
Consider the following fraud scenarios when you manage your currencies:- If you encounter a reused ID or the verifier is incorrect, the callback URL might not originate from Tapjoy and you can consider it fraudulent.
- If your user IDs only contain integers, validate the snuid to prevent manipulation. For example, Tapjoy considers and
001234as two separate user IDs. However, your back end server logic might not.1234
Verifier calculation
The verifier is an MD5 hash with the following format:Your server must recompute the verifier and returns aDigest::MD5.hexdigest("#{id}:#{snuid}:#{currency}:#{secret_key}")
403 ForbiddenImproved callback URL
A more secure callback format is available through Tapjoy Support. This version uses a POST request with a JSON payload and SHA256 Hash-Based Message Authentication Code (HMAC) verification. Contact your account manager or support team to enable this feature. When a user earns currency, Tapjoy sends a POST request to your provided URL. Tapjoy generates the verifier from the request body and your shared secret key (found in the Tapjoy Dashboard), and includes it in the request headers. Tapjoy signs the request by using a structure similar to the following example:{ "cp": "some_string", "currency": { "currency_sale": "1.0", "id": "reward_id", "reward": 100 }, "id": "some_id", "offer": { "advertiser_app_name": "a_cool_app", "currency": { "max_reward_value": 1360 }, "expires_at": 1768175428, "icon_url": "some_URL/icon.jpg", "name": "eye_catching_headline", "task":{ "is_iap": false, "name": "event_name" }, "type": "" }, "placement":{ "content_type": "offerwall", "name": "placement_name" }, "rev": 100, "timestamp": 1762993750, "user": { "id": "user_id" }}
Parameter
Type
Description
idrevcpcurrency.idcurrency.rewardcurrency.currency_salecurrency.max_reward_valueoffer.nameoffer.typeoffer.icon_urloffer.advertiser_app_nameoffer.task.nameoffer.task.is_iapoffer.expires_atplacement.nameplacement.content_typeuser.idtimestampThe following example demonstrates the Tapjoy header with signature:HMAC_SHA-256(<Request-Body>,<Secret-Key>)
X-Tapjoy-Signature => 7205ccfdfa1fe28cd05a1b56a9508d898cc938aa555a6c18848097fe4ee0975b
Setting the User ID
For self-managed currency, setting a uniqueuser_iduser_iduser_id- Use a unique, numeric ID (up to 190 characters).
- Avoid identifiable information (for example: usernames, real names, emails) for GDPR compliance.
- Keep the ID consistent for each user's lifetime to support security and fraud detection.
// Recommended approach using connect flagNSDictionary *connectFlags = @{TJC_OPTION_USER_ID : @"<USER_ID_HERE>"};[Tapjoy connect:@"SDK_KEY_GOES_HERE" options:connectFlags];// Setting the user id directly[Tapjoy setUserIDWithCompletion:@"<USER_ID_HERE>" completion:^(BOOL success, NSError *error) {}];
Setting the user balance
Update Tapjoy with the user's current balance each time you request a placement, before loading content. This ensures accurate tracking for self-managed currency.TJPlacement *placement = [TJPlacement placementWithName:@"placementName" delegate:nil];[placement setBalance:100 forCurrencyId:@"1234" withCompletion:^(NSError * _Nullable error) { if (error != nil) { //Failure NSString *message = error.localizedDescription; } else { //Success }}];
Required amount
If you set the balance, you can also set the required amount value on a placement.TJPlacement* placement = [TJPlacement placementWithName:@"placementName" delegate:nil];placement setRequiredAmount:100 forCurrencyId:@"1234" withCompletion:^(NSError * _Nullable error) { if (error != nil) { //Failure NSString *message = error.localizedDescription; } else { //Success }}
Reward Callback IP allowlisting
If your callback server restricts access, allowlist the following Tapjoy IP addresses:18.215.207.8918.235.142.16523.20.255.11323.23.134.1653.210.188.323.215.42.1403.217.209.1773.218.95.353.219.236.533.231.137.161
Troubleshooting
If you receive an unexpected snuid in the callback URL, ensure that you callsetUserIDsetUserID