Paywalls

Initializing the Piano javascript meter on your site is as simple as dropping in some javascript code. The meter can be used for the classic use case of metered paywall, or you can use it to simply track how many pageviews a user has seen over a designated period.

tp.push(["init", function() {
    tp.meter.init({
        paywallId: "1234567",
        trackPageview: true,
        meterSelector: function() {},
        loginRequired: function(params) {},
        customEvent: function(params) {},
        close: function() {},
        onMeterActive: function(meter) {},
        onMeterExpired: function(meter) {},
        onAccessGranted: function(meter) {},
        onShowOffer: function(meter) {},
        onCheckoutSuccess: function() {}
    });
}]);

Response

Every paywall callback with have a meter object passed in as its first parameter that contains these properties.

{
    "paywall_id" : 1234567,
    "views" : 3,
    "views_left" : 2,
    "max_views" : 5,
    "show_reminder" : true,
    "track_page_view" : true,
    "state" : "ok",
    "country_code" : "US",
    "region" : "North America",
    "meter_name" : ""
}

You can use these properties to perform additional logic based off of certain criteria that you may need.

Multi-meter

If users need to have different meter heights based on certain criteria - for example, anonymous users should get 5 views while registered users should get 10 views - read the full documentation here on how to implement a multi-meter.

GeoIP Tracking and Targeting

If you need to only track users from certain countries or geographic regions, read the full documentation here on how to implement a geoIP tracking and targeting.

Metering Only

If you are using Piano for metering only and handling transaction processing yourself - or not at all - you can disable showing the Piano curtain and reminders by returning false from the onShowOffer callback in all cases.

tp.push(["init", function() {
    tp.meter.init({
        paywallId: "1234567",
        onMeterActive: function(meter) {
            // perform any metering-only actions
        },
        onMeterExpired: function(meter) {
            // perform any metering-only actions
        },
        onShowOffer: function(meter) {
            // do not show the curtain or reminders.
            return false;
        }
    });
}]);

Callbacks

There are several callbacks you can listen for to implement custom or advanced functionality.

loginRequired

This callback is executed when a user attempts to checkout and isn't logged in. You can leverage this callback to have the user login before proceeding with checkout. You can find more information about how to implement logic here.

tp.push(["init", function() {
    tp.meter.init({
        paywallId: "12345",
        trackPageview: true,
        loginRequired: function(params) {
            // this is a reference implementation only
            // your own custom login/registration implementation would
            // need to return the tinypass-compatible userRef inside the callback
            mysite.showLoginRegistration(function(tinypassUserRef) {
                tp.push(["setUserRef", tinypassUserRef]);
                tp.offer.startCheckout(params);
            });
 
            // this prevents the tinypass error message from displaying
            return false;
        }
    });
}]);

customEvent

This callback is executed when a user clicks a link that has implemented the external-event directive in the template. You can find more information about how to implement logic here.

close

This callback is executed when a user closes the curtain. You can find more information about how to implement logic here.

onMeterActive

This callback is executed when a user's meter is active. The user has not made a purchase yet and access is not yet denied. You can use this callback to perform any additional logic you need.

tp.push(["init", function() {
    tp.meter.init({
        paywallId: "1234567",
        onMeterActive: function(meter) {
            _gaq.push(["_trackEvent", "Paywall", "Active Meter State", meter.views]);
        }
    });
}]);

onMeterExpired

This callback is executed when a user's meter is expired. This state will typically be accompanied by an onShowOffer callback as well to show the curtain.

onAccessGranted

This callback is executed when a user has access to the content protected by the paywall. This callback fires on every page, not just immediately after purchase. To control what happens only after purchase, use the onCheckoutSuccess callback.

onShowOffer

This callback is executed when the page is about to show the end-user the curtain or reminder offer. You can prevent the offer from showing by returning false from this method. A return value of false will prevent the Piano code from showing the offer and instead this responsibility will be with your code.

tp.push(["init", function() {
    tp.meter.init({
        paywallId: "1234567",
        onMeterExpired: function(meter) {
            if (specialCriteria) {
                tp.offer.show({
                    offerId: "O12345",      // the special criteria offer
                    templateId: "OTABCDEF", // the special criteria template
                });
            }
            else {
                tp.offer.show({
                    offerId: "O23456",      // the regular offer
                    templateId: "OTBCDEFG", // the regular template
                });
            }
        },
        onShowOffer: function(meter) {
            // this selectively returns false only at the "end" of
            // the meter; this would allow you to have the reminder
            // controlled in the dashboard, but show custom curtains
            // based on some special criteria
            if (meter.views_left == 0) {
                return false;
            }
        }
    });
});

onCheckoutSuccess

This callback is executed after someone successfully completes checkout. You can hook into this event to, for example, make calls off to 3rd-party analytics to track conversions.

tp.push(["init", function() {
    tp.meter.init({
        paywallId: "1234567",
        onCheckoutSuccess: function(conversionDetails) {
            _gaq.push(['_trackEvent', 'Paywall', 'Conversion', conversionDetails.uid]);
        }
    });
});

The conversionDetails object will contain certain information about the conversion that took just place.

{
    "rid": "RID",
    "chargeAmount": 1.99,
    "chargeCurrency": "USD",
    "termConversionId": "TCTRYTG6FF9F",
    "termId": "TMWJ2JIOB2M8",
    "expires": 1434979751,
    "uid": "[email protected]",
    "token_list": "{jax}fCJKadfDsHdSjElYA09lYkGFCdXk0HuO3k0zX4aPoVmBGaPhhWFd28W-7cCVIBKll40Kgpl4FGpNxmG8bA1IOEynE2bbYdfahk7dWkFUGcrNPzTpRS9l5XQr2Jx5Y1ILRWa6n8Exu8RwKq_lZyanChBev8VGrXBOLB3CQMih_3UW0ygEu7bpqkTQrNpgCSdM4/F3IavKvZ"
}

The token_list property is the updated Access Token List. Piano will, by default, set the __tac cookie with the updated token_list after all conversions.