Monetization Provider API

Version: 1.0.0

Introduction

The monetization provider client API lets you integrate your own monetization solution with Privacy & messaging in Ad Manager. Today, this API is only available to publishers participating in the Offerwall closed beta.

To integrate your own monetization solution with the Offerwall, follow these Custom Choice setup steps. In summary:

  • Enable the "Custom Choice" option for the Offerwall from within the Privacy & messaging tab in Ad Manager.

  • Add custom JavaScript on the site that the Offerwall is published to. Implementation details can be found in sections below.

  • This JavaScript should instantiate a custom monetization provider as defined below and register the provider with Privacy & messaging on the window with registration key: 'publisherCustom'.

Glossary

Term Definition
Monetization Provider A native JavaScript object that provides your custom monetization solution. For example, you could supply a subscription service, micropayments service, and more. The Offerwall invokes your provider's methods to monetize your content with your custom solution.
Entitlement A reward that is granted to users by your monetization solution for completing some monetization action. In scope of this API, an entitlement grants users access to your website's content without seeing the Offerwall. You determine the number of free page loads or duration of time granted to users that select your custom monetization choice.
Monetization Portal An entry point into a monetization flow. Portals define the separate flows offered by your monetization solution. For instance, one portal may be for "monetization", where the user can subscribe to your service. Another portal may be for "sign in", where the user can sign in to access an existing subscription.
Registration Key A monetization provider's identifier, which is used to register your provider implementation with Google Privacy & messaging at page load time.

Sample API Implementation

Here is an example of an implementation that defines a monetization provider, instantiates it, and registers it with Google Privacy & messaging.

// This class defines a monetization provider by implementing four core functions that every provider
// must support: initialize, getUserEntitlementState, monetize, and destroy.
class CustomMonetizationProvider {
  userEntitlementState;

  async initialize(initializeParams) {
    // Replace this function's code with your implementation of the initialize function.
    this.userEntitlementState = googlefc.monetization.UserEntitlementStateEnum.ENTITLED_NO;
    return {initializeSuccess: true, apiVersionInUse: "1.0.0", signInMonetizationPortalSupported: false};
  }

  async getUserEntitlementState() {
    // Replace this function's code with your implementation of the getUserEntitlementState function.
    return this.userEntitlementState;
  }

  async monetize(monetizeParams) {
    // Replace this function's code with your implementation of the monetize function.
    if (monetizeParams.monetizationPortal == googlefc.monetization.MonetizationPortalEnum.PORTAL_PRIMARY_ACCESS) {
      return await this.showSubscriptionPrompt();
    } else {
      console.log('Unsupported monetization portal.');
    }
  }

  async destroy(destructionParams) {
    // Replace this function's code with your implementation of the destroy function.
    console.log('Custom provider is no longer initialized.');
  }

  // ==== The helper functions in this section are only used for this demo, and should be omitted from your actual implementation. ===
  async showSubscriptionPrompt() {
    return new Promise(resolve => {
      const sharedStyles = 'border: 2px solid #6b6e7666; border-radius: 8px; padding: 10px; background: white;';
      const modalStyles =  'width: 500px; z-index: 100; top: 50%; left: 50%; position: absolute; transform: translate(-50%, -50%);';
      const overlayStyles = 'height: 100%; width: 100%; background: black; opacity: 0.6; z-index: 99; position: absolute; top: 0;';

      const modal = this.createElement("div", modalStyles + sharedStyles);
      const overlay = this.createElement("div", overlayStyles);
      const header = this.createElement("h1", 'text-align: center; color: black;', "Subscribe for access.");
      const subscribeButton = this.createElement("button", sharedStyles + 'color: #5499C7; margin-left: 40%;', "Subscribe");
      const backButton = this.createElement("button", sharedStyles + 'color: #5499C7;', "Back");

      this.exitSubscriptionPromptOnButtonClick(subscribeButton, resolve, googlefc.monetization.UserEntitlementStateEnum.ENTITLED_YES, modal, overlay);
      this.exitSubscriptionPromptOnButtonClick(backButton, resolve, googlefc.monetization.UserEntitlementStateEnum.ENTITLED_NO,modal, overlay);

      modal.append(backButton, header, subscribeButton);
      document.body.append(overlay, modal);
    });
  }

  createElement(tag, styles = '', textContent ='') {
    const element = document.createElement(tag);
    element.style.cssText = styles;
    element.textContent = textContent;
    return element;
  }

  exitSubscriptionPromptOnButtonClick(button, resolve, userEntitlementStateEnum, modal, overlay) {
    button.addEventListener("click", () => {
      document.body.removeChild(modal);
      document.body.removeChild(overlay);
      this.userEntitlementState = userEntitlementStateEnum;
      resolve({userEntitlementState: userEntitlementStateEnum});
    });
  }
  // =============================================================================================================================
};

// Important: code to register a custom monetization provider with Google Privacy & messaging.
window.googlefc = window.googlefc || {};
window.googlefc.monetization = window.googlefc.monetization || {};
window.googlefc.monetization.providerRegistry =
  window.googlefc.monetization.providerRegistry || new Map();

window.googlefc.monetization.providerRegistry.set(
  'publisherCustom', new CustomMonetizationProvider());

The snippet of code above is a skeleton implementation that includes everything that is required to integrate a monetization provider with Privacy & messaging. Note that for each provider function, example code was added that you are responsible for replacing with your own implementation.

Method Summary

A monetization provider is an object that provides monetization functionality on web pages by exposing a core set of functions. These functions are further described below.

Method Summary
initialize Initialize the monetization provider, along with any resources required to perform monetization actions.
getUserEntitlementState Get the user's entitlement state at the moment of invocation.
monetize Render your custom monetization solution on the web page. Your monetization solution can take any form, with some examples being a rewarded ad, subscription service dialog, and more.
destroy Destroy the provider, along with any resources or jobs that were running upon initialization. Upon destruction, the Offerwall no longer invokes any provider methods.

Method Definitions

The definition of each monetization provider method is further described below.

initialize

initialize(initializeParams:InitializeParams): Promise<InitializeResponse>

Initialize the monetization provider. Once initialized, the provider should be ready to respond to any other provider functions. This function is guaranteed to be invoked before any other provider function, and can be expected to be invoked at most once on a given page load.

Example:

  async initialize(initializeParams: InitializeParams): Promise<InitializeResponse> {
    const isInitializationSuccessful = await this.initializeMyProvider(initializeParams);
    const initializeResponse = {initializeSuccess: isInitializationSuccessful,
                                                   apiVersionInUse: "1.0.0",
                                                   signInMonetizationPortalSupported: true};
    resolve(initializeResponse);
  }

getUserEntitlementState

getUserEntitlementState(): Promise<UserEntitlementStateEnum>

Get the user's entitlement state at the moment of invocation. The Offerwall is hidden if the user is entitled since the user should receive free access to the website.

Example:

  async getUserEntitlementState(): Promise<googlefc.monetization.UserEntitlementStateEnum> {
      resolve(this.isUserLoggedIn() ? this.isUserEntitledOnThisPage()
        : googlefc.monetization.UserEntitlementStateEnum.ENTITLED_NO);
  }

monetize

monetize(monetizeParams:MonetizeParams): Promise<MonetizeResponse>

Render your monetization solution and handle the user's monetization actions. Monetization can take any form, whether it be a rewarded ad, subscription service, and more. Once this method is invoked by the Offerwall, the Offerwall is hidden until the promise is resolved. Therefore, it is the provider's responsibility to gate page content until the promise is resolved. Once the promise is resolved, the provider must also be sure to no longer be visible on the web page.

It is highly encouraged for you to use the suggested language code and styles provided in the InitializeParams within your monetization solution. This ensures a seamless visual experience between the Offerwall and the provider.

The Offerwall sets the monetization portal parameter to indicate which portal it wants to access. The two portal types that are available include PORTAL_PRIMARY_ACCESS which is not optional, and PORTAL_SIGN_IN which is optional. You can indicate whether you support the optional portal PORTAL_SIGN_IN in your response to the initialize function.

Upon resolving the monetize function promise, you must:

  • Hide your rendered monetization solution.

  • Return whether or not the user is entitled to page content. This determines whether the Offerwall continues to show or is hidden.

  • Return any additional data on the user interaction if applicable such as the paid amount, entitlement type & value, and monetization recurrence.

Example:

  async monetize(monetizeParams: MonetizeParams): Promise<MonetizeResponse> {
    const result;
    if (monetizeParams.monetizationPortal == googlefc.monetization.MonetizationPortalEnum.PORTAL_PRIMARY_ACCESS) {
      result = await this.showMyBuyFlow();
    } else if (monetizeParams.monetizationPortal == googlefc.monetization.MonetizationPortalEnum.PORTAL_SIGN_IN) {
      result = await this.showMySignInFlow();
    }

    if (!result.monetized) {
      resolve({userEntitlementState: googlefc.monetization.UserEntitlementStateEnum.ENTITLED_NO});
    }

    const monetizeResponse = {
      userEntitlementState: googlefc.monetization.UserEntitlementStateEnum.ENTITLED_YES,
      newlyGrantedUserEntitlementType: googlefc.monetization.EntitlementTypeEnum.TYPE_PAGEVIEW_COUNT,
      newlyGrantedUserEntitlementValue: 4,
      newlyPaidAmountByUser: {currencyCode: "USD", units: 5, nanos: 0},
      // This monetization event does not auto-recur, so leaving property
      // recurrenceOfNewMonetizationEvent undefined.
    }
    resolve(monetizeResponse);
  }

destroy

destroy(destroyParams:DestroyParams): void

Destroy the provider. This function is guaranteed to be invoked last in the provider's lifecycle, and you should expect it to be invoked at most once on a given page load.

Example:

  destroy(destroyParams: DestroyParams): void {
    this.recordDestroyReason(destroyParams.destroyReason);
    this.destroyAllOfMyResourcesOnPage();
  }

Type Definitions

The definition of each data type in the API is further described below.

Object Definitions

This section lists out all object definitions in the API.

InitializeParams

The parameter type for the initialize function.

interface InitializeParams {
  // The loaded monetization provider API version. i.e. "1.0.0"
  currentApiVersion: string;
  // The language code suggested for the provider to use, as defined by BCP 47.
  suggestedLanguageCode?: string;
  // The styles suggested for the provider to use.
  suggestedStyles?: Styles;
  // The publisher's logo url.
  publisherLogoUrl?: string;
}

Styles

The type for defining styles.

interface Styles {
  // The primary color of the Offerwall.
  primaryColor?: string;
  // The background color of the Offerwall.
  backgroundColor?: string;
}

InitializeResponse

The response type for the initialize function.

interface InitializeResponse {
  // Whether or not initialization was successful. If initialization is
  // unsuccessful, the Offerwall does not proceed to call other provider methods
  // except for destroy.
  initializeSuccess: boolean;
  // The monetization provider API version that the provider is using. If the
  // indicated major version is not equal to the major version of the API
  // currently on the page, provider execution is halted.
  apiVersionInUse: string;
  // Whether or not the optional sign-in monetization portal is supported. If
  // you indicate that it is supported, the Offerwall renders a sign-in link
  // that will invoke your sign-in portal upon user click.
  signInMonetizationPortalSupported: boolean;
}

MonetizeParams

The parameter type for the monetize function.

interface MonetizeParams {
  // The monetization portal that the Offerwall wants to invoke. You can
  // indicate whether you support any optional portals in your
  // InitializeResponse; the only portal that isn't optional is
  // MonetizationPortalEnum.PORTAL_PRIMARY_ACCESS. The Offerwall provides the
  // portal enum for the flow requested by the user.
  monetizationPortal: googlefc.monetization.MonetizationPortalEnum;
}

MonetizeResponse

The response type for the monetize function.

interface MonetizeResponse {
  // The user's current entitlement state.
  userEntitlementState: googlefc.monetization.UserEntitlementStateEnum;
  // The user's granted entitlement type, only populated if an entitlement was
  // granted within the scope of the current MonetizationProvider.monetize
  // invocation.
  newlyGrantedUserEntitlementType?: googlefc.monetization.EntitlementTypeEnum;
  // The user's granted entitlement value, only populated if an entitlement was
  // granted within the scope of the current MonetizationProvider.monetize
  // invocation.
  newlyGrantedUserEntitlementValue?: number;
  // The amount paid by the user, only populated if a payment occurred within
  // the scope of the current MonetizationProvider.monetize invocation.
  newlyPaidAmountByUser?: Money;
  // The recurrence of the monetization event, populated only if the
  // monetization event occurred within the scope of the current
  // MonetizationProvider.monetize invocation & the monetization event is
  // expected to auto-recur without further action from the user (e.g.
  // registering for a monthly subscription)
  recurrenceOfNewMonetizationEvent?: googlefc.monetization.MonetizationRecurrenceEnum;
}

Money

The type for defining an amount of money in a specific currency. See original money.proto definition.

interface Money {
  // The three-letter currency code defined in ISO 4217.
  currencyCode: string;
  // The whole units of the amount.
  // For example if `currencyCode` is `"USD"`, then 1 unit is one US dollar.
  units?: number;
  // Number of nano (10^-9) units of the amount.
  // The value must be between -999,999,999 and +999,999,999 inclusive.
  // If `units` is positive, `nanos` must be positive or zero.
  // If `units` is zero, `nanos` can be positive, zero, or negative.
  // If `units` is negative, `nanos` must be negative or zero.
  // For example $-1.75 is represented as `units`=-1 and `nanos`=-750,000,000.
  nanos?: number;
}

DestroyParams

The parameter type for the destroy function.

interface DestroyParams {
  // The reason for destroying the provider.
  destroyReason: googlefc.monetization.DestroyReasonEnum;
}

Enum Definitions

This section lists out all enum definitions in the API.

googlefc.monetization.UserEntitlementStateEnum

Enumeration of the entitlement states that a user can be in for a monetization provider.

googlefc.monetization.UserEntitlementStateEnum {
  ENTITLED_UNKNOWN = 0,
  // The user is currently entitled to access page content.
  ENTITLED_YES = 1,
  // The user is not currently entitled to access page content.
  ENTITLED_NO = 2,
}

googlefc.monetization.MonetizationPortalEnum

Enumeration of the different monetization portals, or monetization entry points, that a provider can possibly support. See glossary for more on monetization portals.

googlefc.monetization.MonetizationPortalEnum {
  PORTAL_UNKNOWN = 0,
  // The primary access portal represents a provider's main entry point into a
  // monetization flow, and must always be supported.
  PORTAL_PRIMARY_ACCESS = 1,
  // The sign in portal represents a provider's monetization entry point that
  // usually begins with the user performing some sign-in or registration
  // action. Provider support for this monetization portal type is optional.
  PORTAL_SIGN_IN = 2,
}

googlefc.monetization.EntitlementTypeEnum

Enumeration of the different entitlement types that a monetization provider can grant a user.

googlefc.monetization.EntitlementTypeEnum {
  TYPE_UNKNOWN = 0,
  // This type is used if the user is awarded a positive integer value of
  // Offerwall-free pageviews.
  TYPE_PAGEVIEW_COUNT = 1,
  // This type is used if the user is awarded a positive integer value of
  // seconds (duration) in which they can access Offerwall-free page content any
  // number of times.
  TYPE_DURATION_SECONDS = 2,
}

googlefc.monetization.DestroyReasonEnum

Enumeration of reasons for which a monetization provider can be destroyed.

googlefc.monetization.DestroyReasonEnum {
  REASON_UNKNOWN = 0,
  // The Offerwall no longer needs to invoke the monetization provider on the
  // pageview.
  REASON_CALLER_FINISHED = 1,
  // The Offerwall encountered an erroneous state with the monetization provider
  // in the midst of the provider's lifecycle.
  REASON_ERROR_STATE = 2,
  // The API version that the monetization provider is currently using is no
  // longer supported.
  REASON_UNSUPPORTED_API_VERSION = 3,
}

googlefc.monetization.MonetizationRecurrenceEnum

Enumeration of the different monetization recurrence cadences that can be started upon some user action.

googlefc.monetization.MonetizationRecurrenceEnum {
  MONETIZATION_RECURRENCE_UNKNOWN = 0,
  MONETIZATION_RECURRENCE_WEEKLY = 1,
  MONETIZATION_RECURRENCE_MONTHLY = 2,
  MONETIZATION_RECURRENCE_ANNUALLY = 3,
}

Provider Registration

googlefc.monetization.providerRegistry?: Map<string, Object>

The window-level JavaScript object used to register monetization providers. Registration includes passing your instantiated provider object keyed by a static registration key to a registry that lives under the window namespace: window.googlefc.monetization

// Register a custom monetization provider with Google Privacy & messaging.
window.googlefc = window.googlefc || {};
window.googlefc.monetization = window.googlefc.monetization || {};
window.googlefc.monetization.providerRegistry =
                            window.googlefc.monetization.providerRegistry || new Map();

window.googlefc.monetization.providerRegistry.set(
                            'publisherCustom', new CustomMonetizationProvider());

Version History

Version Release Date Summary
1.0.0 07/24/2023 Initial release of the monetization provider API.