Integrating Supertab with Piano

This guide will walk you through how to use Piano to handle entitlements for single item purchases made with Supertab.

Prerequisites

You will need:

  1. Your Piano aid (Application ID)
  2. Your Piano rid (Resource ID)
  3. The Piano API End point that Supertab will comunicate with and API Key (eg: https://api.piano.io/api/v3/publisher/user/access/grant)
  4. A working Supertab Site and Experience.

Purchase & Entitlement Flow

When a user is presented with the Supertab paywall, they will be given the option to purchase an offering. Once the purchase is successful a webhook will be fired to the Piano /access/grant API end point with the following information:

  • The user's Piano ID (uid)
  • The page URL that the purchase was made (url)
  • The Piano application ID (aid)
  • The Piano resource ID (rid)

The Piano api will then update the users access permission for that application, resource, and page.

Configuring The Supertab Webhook

  1. Login to the Business Portal
  2. Click on "Current Organization", then select "Webhooks"
  3. Click on "Add Endpoint"
  4. For the endpoint URL, use your Piano API URL with the api key appended to the url:

    https://api.piano.io/api/v3/publisher/user/access/grant?api_token=xxxxx

  5. Select the "puchase.completed" event.

  1. Click "Create"

Configuring Webhook Transformation

The Piano API expects data to be in format that is different than the Supertab webhook data.

  1. Click on "Advanced"
  2. Click on "Edit Transformation"
  3. Update the transformation code to the following, ensuring to using the correct Piano aid and rid values.
function handler(webhook) {

  //Get the values we need out of the payload that are required by Piano
  const pianoUID = webhook.payload.data.metadata.pianoUser
  const pageURL = webhook.payload.data.metadata.url
  const aid = "XXXX"
  const rid = "XXXX"
  const send_email = "false"
  
  //Payload sent to Piano api on successful payment
  
  webhook.payload = {aid: aid,
                     rid: rid,
                     send_email: send_email,
                     uid: pianoUID,
                     url: pageURL  
                     }     
  
  // and return it as application/x-www-form-urlencoded
  webhook.payload = Object.entries(webhook.payload)
    .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
    .join('&');

  return webhook
}
  1. Click "Save".

Installing Supertab.js in Composer

Create or edit an existing Experience in Composer for pages you want to display the Supertab paywall on. In this example, we will want to charge for content located at /news

  1. Edit the Page Segment parameters to the following:
    1. Custom Segment
    2. Content and URL parameters: only match /news* URLs

  1. Add a "Segment Users" Branch and specify a Resource (rid) that the user will not have access to unless they pay via Supertab.

  1. Add a "Run JS" Action

The Experience editor in Composer should look something like this:

Supertab/Piano Javascript

We're going to use a slightly modified version of the Supertab.js include code as provided by the Business Portal.

The inclusion of the purchaseMetadata object when creating the Purchase Button:

purchaseMetadata: {pianoUser: tp.pianoId.getUser()?.uid || '0',
					   url: window.location.href},

This will pass the Piano User ID of the currently logged user. Otherwise it will use a uid of 0.

A simple modal dialog box to include the Supertab Purchase button. This box can be styled or customized by adjusting the code as required.

function createModal(options = {}) {
  const {
    title = "Pay to Continue",
    message = "You must pay to view this content",
    buttonText = "",
  } = options;

  // Create overlay
  const overlay = document.createElement("div");
  overlay.style.position = "fixed";
  overlay.style.top = 0;
  overlay.style.left = 0;
  overlay.style.width = "100%";
  overlay.style.height = "100%";
  overlay.style.backgroundColor = "rgba(0, 0, 0, 0.75)";
  overlay.style.display = "flex";
  overlay.style.justifyContent = "center";
  overlay.style.alignItems = "center";
  overlay.style.zIndex = "9999";

  // Create modal box
  const modal = document.createElement("div");
  modal.style.background = "#fff";
  modal.style.padding = "2em";
  modal.style.borderRadius = "8px";
  modal.style.boxShadow = "0 4px 12px rgba(0,0,0,0.2)";
  modal.style.maxWidth = "400px";
  modal.style.textAlign = "center";
  modal.style.fontFamily = "sans-serif";

  // Title
  const h2 = document.createElement("h2");
  h2.textContent = title;

  // Message
  const p = document.createElement("p");
  p.textContent = message;

  // Button
  const button = document.createElement("button");
  button.id = "button";

  // Append children
  modal.appendChild(h2);
  modal.appendChild(p);
  modal.appendChild(button);
  overlay.appendChild(modal);
  document.body.appendChild(overlay);

  // Optional: block scrolling
  document.body.style.overflow = "hidden";
}

createModal({
  onClick: () => {
    tp.offer.show({ offerId: 'your-offer-id', displayMode: 'modal' });
  }
});
  1. Paste the code in its entirety into the "Run JS" action in Composer:
(async () => {
  const module = await import('https://js.supertab.co/v3/supertab.js');
  const { Supertab } = module;

  const supertabClient = new Supertab({ clientId: "test_client.f3cdcfa9-51bb-41e1-a37d-e47e1df75a27" });

  const { initialState, show } = await supertabClient.createPurchaseButton({
    experienceId: "experience.edc7428c-9ca8-460e-bb73-8de958b117da",
    containerElement: document.getElementById("button"),
    purchaseMetadata: {pianoUser: tp.pianoId.getUser()?.uid || '0',
					   url: window.location.href},
    onDone: ({ priorEntitlement, purchase }) => {
          if (priorEntitlement) {
            // Insert your code to handle when user has prior entitlement
            console.log("User has prior entitlement", priorEntitlement);
          } else if (purchase && purchase.status === "completed") {
            // Insert your code to handle when user purchases an offering
            console.log("Purchase completed!", purchase);
          } else {
            // Insert your code to handle when user abandons the flow without purchase or prior entitlement
            console.log("Purchase canceled!");
          }
        }
  });
})();


function createModal(options = {}) {
  const {
    title = "Pay to Continue",
    message = "You must pay to view this content",
    buttonText = "",
  } = options;

  // Create overlay
  const overlay = document.createElement("div");
  overlay.style.position = "fixed";
  overlay.style.top = 0;
  overlay.style.left = 0;
  overlay.style.width = "100%";
  overlay.style.height = "100%";
  overlay.style.backgroundColor = "rgba(0, 0, 0, 0.75)";
  overlay.style.display = "flex";
  overlay.style.justifyContent = "center";
  overlay.style.alignItems = "center";
  overlay.style.zIndex = "9999";

  // Create modal box
  const modal = document.createElement("div");
  modal.style.background = "#fff";
  modal.style.padding = "2em";
  modal.style.borderRadius = "8px";
  modal.style.boxShadow = "0 4px 12px rgba(0,0,0,0.2)";
  modal.style.maxWidth = "400px";
  modal.style.textAlign = "center";
  modal.style.fontFamily = "sans-serif";

  // Title
  const h2 = document.createElement("h2");
  h2.textContent = title;

  // Message
  const p = document.createElement("p");
  p.textContent = message;

  // Button
  const button = document.createElement("button");
  button.id = "button";

  // Append children
  modal.appendChild(h2);
  modal.appendChild(p);
  modal.appendChild(button);
  overlay.appendChild(modal);
  document.body.appendChild(overlay);

  // Optional: block scrolling
  document.body.style.overflow = "hidden";
}

createModal({
  onClick: () => {
    tp.offer.show({ offerId: 'your-offer-id', displayMode: 'modal' });
  }
});
  1. Save the JS Code

  1. Save and publish your experience in Composer.

Testing

  1. On your site, visit a page where the experience we just created in Composer will fire. You should see a new dialog box with the supertab single item purchase button is displayed.
  2. Click on the purchase button and add the item to your tab.
  3. Confirm that the webhook was fired properly from the Business Portal

If you require any additional assistance with setting up this or any other integration of Supertab with Piano, please contact support@supertab.co

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us