Skip to Content

Get Trial Info

Get information about the current trial state for regular paywalls, including time-based and action-based trials.

Version Requirement: Available in paywall script version 1.0.3 and later.

Regular Paywalls Only: If you have a tokenized paywall, skip this section — it’s only relevant for regular paywalls. To get remaining tokens for tokenized paywalls, use paywall.getUser() instead.

Overview

The paywall.getTrialInfo() method retrieves information about trials that are set before displaying the paywall:

  • Time-based trials - Trials with duration in hours/days
  • Action-based trials - Trials with limited number of actions/opens
  • No trial - When no trial is configured

Before Paywall Trials: This API returns information about trials set before the paywall opens. For subscription-based trials (activated after entering card details), use paywall.getUser().

API Reference

Method Signature

paywall.getTrialInfo(): Promise<TrialInfo>

Return Types

interface TimeBasedTrial { /** Timestamp when trial period started (in milliseconds) */ expirationStart: number; /** Timestamp when trial period ends (in milliseconds) */ expirationEnd: number; /** Total duration of trial period (in milliseconds) */ expirationTime: number; /** Whether the trial period has expired */ expired: boolean; }

Basic Usage

Checking Trial Status

try { const trialInfo = await paywall.getTrialInfo(); if (trialInfo === 'no trial') { console.log('No trial available'); } else if ('expirationTime' in trialInfo) { // Time-based trial console.log(`Trial expires in ${trialInfo.expirationTime} ms`); } else { // Action-based trial console.log(`${trialInfo.remainingActions} actions remaining`); } } catch (error) { console.error('Failed to get trial info:', error); }

Practical Examples

Time-Based Trial Handler

const handleTimeBasedTrial = async () => { try { const trialInfo = await paywall.getTrialInfo(); if (trialInfo !== 'no trial' && 'expirationTime' in trialInfo) { const now = Date.now(); const timeRemaining = trialInfo.expirationEnd - now; if (trialInfo.expired) { console.log('Trial has expired'); showUpgradePrompt(); } else { const hoursRemaining = Math.floor(timeRemaining / (1000 * 60 * 60)); console.log(`Trial expires in ${hoursRemaining} hours`); showTrialStatus(hoursRemaining); } } } catch (error) { console.error('Error checking trial:', error); } };

Action-Based Trial Handler

const handleActionBasedTrial = async () => { try { const trialInfo = await paywall.getTrialInfo(); if (trialInfo !== 'no trial' && 'remainingActions' in trialInfo) { if (trialInfo.expired) { console.log('All trial actions used'); showUpgradePrompt(); } else { const percentage = (trialInfo.remainingActions / trialInfo.totalActions) * 100; console.log(`${trialInfo.remainingActions} actions remaining (${percentage.toFixed(1)}%)`); showActionProgress(trialInfo.remainingActions, trialInfo.totalActions); } } } catch (error) { console.error('Error checking trial:', error); } };

React Component

import { useState, useEffect } from 'react'; function TrialStatus() { const [trialInfo, setTrialInfo] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { const fetchTrialInfo = async () => { try { const info = await paywall.getTrialInfo(); setTrialInfo(info); } catch (error) { console.error('Failed to fetch trial info:', error); } finally { setLoading(false); } }; fetchTrialInfo(); }, []); if (loading) { return <div>Loading trial information...</div>; } if (trialInfo === 'no trial') { return ( <div> <p>No trial available</p> <button onClick={() => paywall.open()}> Get Premium Access </button> </div> ); } if ('expirationTime' in trialInfo) { // Time-based trial const timeRemaining = trialInfo.expirationEnd - Date.now(); const hoursRemaining = Math.floor(timeRemaining / (1000 * 60 * 60)); return ( <div> <h3>Trial Status</h3> {trialInfo.expired ? ( <p>Your trial has expired</p> ) : ( <p>Trial expires in {hoursRemaining} hours</p> )} <button onClick={() => paywall.open()}> Upgrade Now </button> </div> ); } if ('remainingActions' in trialInfo) { // Action-based trial return ( <div> <h3>Trial Actions</h3> {trialInfo.expired ? ( <p>No trial actions remaining</p> ) : ( <> <p>{trialInfo.remainingActions} of {trialInfo.totalActions} actions remaining</p> <div style={{ width: '100%', backgroundColor: '#f0f0f0', borderRadius: '4px', height: '8px' }}> <div style={{ width: `${(trialInfo.remainingActions / trialInfo.totalActions) * 100}%`, backgroundColor: '#007bff', height: '100%', borderRadius: '4px' }} /> </div> </> )} <button onClick={() => paywall.open()}> Get More Actions </button> </div> ); } return null; }

Error Handling

const safeGetTrialInfo = async () => { try { const trialInfo = await paywall.getTrialInfo(); return trialInfo; } catch (error) { if (error.message.includes('not initialized')) { console.error('Paywall not initialized yet'); } else if (error.message.includes('version')) { console.error('Paywall version too old - upgrade to 1.0.3+'); } else { console.error('Failed to get trial info:', error); } // Return safe default return 'no trial'; } };

Data Examples

Time-Based Trial

{ expirationStart: 1703001600000, // December 19, 2023 12:00:00 PM expirationEnd: 1703174400000, // December 21, 2023 12:00:00 PM expirationTime: 172800000, // 48 hours in milliseconds expired: false }

Action-Based Trial

{ remainingActions: 3, // 3 actions left totalActions: 5, // 5 actions total expired: false // Still has actions }

Next Steps

Last updated on