Skip to main content

S2S Rewarded Callbacks

Server-to-Server (S2S) rewarded callbacks enable server-side reward verification.

NAM SDK has supported S2S rewarded callback functionality since version 8.5.0.

This guide explains how to integrate S2S rewarded callbacks.

Before You Begin

  • S2S rewarded callback functionality is supported from NAM SDK 8.5.0 and later.
  • S2S callback-related settings must be completed in NAM Admin.

[Step 1] NAM SDK Integration Complete

To use S2S rewarded callback functionality, you need NAM SDK 8.5.0 or later.

Please refer to Rewarded Ads Getting Started.

The following content assumes that NAM SDK integration has been completed.


[Step 2] S2S Rewarded Callback Parameter Configuration (Optional)

If you want to pass additional information during S2S rewarded callbacks, you can configure the following parameters. For detailed ad request information, please refer to the Ad Parameters page.

User Token Configuration

You can set a user token for rewarded callbacks using the setUserToken method.

val adParam = AdParam.Builder()
.setAdUnitId("YOUR_AD_UNIT_ID")
// Set user token for rewarded callback
.setUserToken("your_user_token_here")
.build()

Adding Custom Parameters

You can add custom parameters for rewarded callbacks using the addRewardCustomParam method.

caution

Please contact NAM administrator before using this feature.

val adParam = AdParam.Builder()
.setAdUnitId("YOUR_AD_UNIT_ID")
.setUserToken("your_user_token_here")
// Add custom parameters for rewarded callback
.addRewardCustomParam("level", "5")
.addRewardCustomParam("stage", "boss_battle")
.build()

[Step 3] RewardedAdListener Configuration

The RewardedAdListener interface has been enhanced to support S2S rewarded callbacks. It has been changed to an interface with Kotlin implementation, and new callback methods have been added.

New Callback Methods

  • onFailedServerRewardVerification: Reward verification has failed, and retrying is futile.
  • onReceiveErrorServerRewardVerification: An error occurred during the verification process (such as timeout), and retrying may be needed according to service policy.
  • onSuccessServerRewardVerification: The user is eligible to receive the reward.
rewardedAdManager.setAdListener(
object : RewardedAdListener {
override fun onAdLoaded(ad: GfpRewardedAd) {
// Ad loaded successfully - ready to show ad
}

override fun onAdStarted(ad: GfpRewardedAd) {
// Ad started
}

override fun onAdClicked(ad: GfpRewardedAd) {
// Ad clicked
}

override fun onAdClosed(ad: GfpRewardedAd) {
// Ad closed
}

override fun onAdCompleted(ad: GfpRewardedAd) {
// Ad viewing completed
}

override fun onError(ad: GfpRewardedAd, error: GfpError) {
// Error occurred while loading or showing ad
}

override fun onFailedServerRewardVerification(ad: GfpRewardedAd, error: GfpError) {
// Reward verification denied by server - retrying is useless
// Inform user that reward cannot be granted
}

override fun onReceiveErrorServerRewardVerification(ad: GfpRewardedAd) {
// Error occurred during reward verification - retry may be needed according to service policy
// Ask user for retry or perform automatic retry
}

override fun onSuccessServerRewardVerification(ad: GfpRewardedAd) {
// Server reward verification successful - user can receive reward
// Grant reward to user
}
}
)

[Step 4] Checking Server Verification Availability

After the ad is loaded, you can use the isUseServerVerification method to check if server-side verification is enabled for that ad.

override fun onAdLoaded(ad: GfpRewardedAd) {
// Check if server verification is enabled
val isServerVerificationEnabled = rewardedAdManager.isUseServerVerification()

if (isServerVerificationEnabled) {
logTextView.append("Server-side verification is enabled.\n")
// Logic for using S2S rewarded callbacks
} else {
logTextView.append("Using client-side verification.\n")
// Logic for using existing onAdCompleted callback
}

showButton.isEnabled = true
}

[Step 5] Using Retry API

When the onReceiveErrorServerRewardVerification callback occurs and a retry is needed, you can use the requestServerVerification() method of GfpRewardedAdManager.

override fun onReceiveErrorServerRewardVerification(ad: GfpRewardedAd) {
// Perform retry according to service policy
// Example: Retry after user confirmation
showRetryDialog { shouldRetry ->
if (shouldRetry) {
rewardedAdManager.requestServerVerification()
} else {
// Close ad
rewardedAdManager.close()
}
}
}

[Step 6] Using Close Ad API

When retrying is not possible or meaningless, you can close the ad using the close() method of GfpRewardedAdManager.

override fun onFailedServerRewardVerification(ad: GfpRewardedAd, error: GfpError) {
// Verification failed - retry not possible
// Inform user and close ad
showRewardFailureMessage()

rewardedAdManager.close()
}

[Optional] Implementing Dialog-based Retry Popup

If you want to implement a retry popup in the form of a dialog Activity, you can use the provided NdaRewardCallbackBroadcastReceiver example.

Complete Implementation Example

class RewardedFragment : Fragment() {
private var rewardedAdManager: GfpRewardedAdManager? = null
private lateinit var binding: FragmentRewardedBinding
private lateinit var logTextView: TextView
private lateinit var showButton: Button
private var ndaRewardCallbackBroadcastReceiver: NdaRewardCallbackBroadcastReceiver? = null

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
binding = FragmentRewardedBinding.inflate(inflater)
logTextView = binding.logTextView
showButton = binding.showButton.apply {
isEnabled = false
setOnClickListener {
if (rewardedAdManager?.isAdInvalidated != false) {
logTextView.append("AD is not valid.\n")
return@setOnClickListener
}
rewardedAdManager?.showAd(requireActivity())
}
}

val adParam = AdParam.Builder()
.setAdUnitId(AD_UNIT_ID)
.build()
rewardedAdManager = GfpRewardedAdManager(requireActivity(), adParam)

rewardedAdManager?.setAdListener(
object : RewardedAdListener {
override fun onAdLoaded(ad: GfpRewardedAd) {
showButton.isEnabled = true
logTextView.append("Ad loaded\n")
}

override fun onAdStarted(ad: GfpRewardedAd) {
logTextView.append("Ad started\n")
}

override fun onAdCompleted(ad: GfpRewardedAd) {
logTextView.append("Ad completed\n")
}

override fun onAdClosed(ad: GfpRewardedAd) {
logTextView.append("Ad closed\n")
showButton.isEnabled = false
}

override fun onError(ad: GfpRewardedAd, error: GfpError) {
logTextView.append("Error: ${error.message}\n")
showButton.isEnabled = false
}

override fun onFailedServerRewardVerification(ad: GfpRewardedAd, error: GfpError) {
logTextView.append("Reward verification failed\n")
// Retrying is useless
}

override fun onReceiveErrorServerRewardVerification(ad: GfpRewardedAd) {
logTextView.append("Reward verification error - showing retry dialog\n")
registerReceiver()
val intent = Intent(requireActivity(), RewardCallbackDialogActivity::class.java)
startActivity(intent)
}

override fun onSuccessServerRewardVerification(ad: GfpRewardedAd) {
logTextView.append("Reward verification success\n")
// Grant reward to user
}
}
)
rewardedAdManager?.loadAd()
return binding.root
}

override fun onDestroyView() {
super.onDestroyView()
rewardedAdManager?.destroy()
}

override fun onDestroy() {
super.onDestroy()
ndaRewardCallbackBroadcastReceiver?.let {
requireActivity().unregisterReceiver(it)
}
}

private fun registerReceiver() {
if (ndaRewardCallbackBroadcastReceiver == null) {
ndaRewardCallbackBroadcastReceiver =
NdaRewardCallbackBroadcastReceiver(
object : NdaRewardCallbackListener {
override fun onNdaRewardCallbackRetry() {
logTextView.append("Retry reward verification\n")
rewardedAdManager?.requestServerVerification()
}

override fun onNdaRewardCallbackCancel() {
logTextView.append("Close rewarded ad\n")
rewardedAdManager?.close()
}
},
RESULT_KEY
).apply {
registerReceiver(requireActivity(), this)
}
}
}

companion object {
private const val AD_UNIT_ID = "YOUR_AD_UNIT_ID"
private const val RESULT_KEY = "reward_result_key"
}
}

Broadcast Receiver Actions

The RewardCallbackDialogActivity used in the sample assumes sending these two actions:

  • NdaRewardCallbackBroadcastReceiver.ACTION_NDA_REWARD_CALLBACK_RETRY: Retry
  • NdaRewardCallbackBroadcastReceiver.ACTION_NDA_REWARD_CALLBACK_CANCEL: Cancel

Important Notes

Server Configuration Required

To use S2S rewarded callbacks, callback URL configuration must be completed in NAM Admin. Please contact your NAM administrator for related settings.

Network Connection

Since S2S reward verification is performed through network communication, the onReceiveErrorServerRewardVerification callback may occur when network connection is unstable.

Retry Policy

To prevent infinite retries when onReceiveErrorServerRewardVerification occurs, it is recommended to set appropriate retry count limits.