Skip to main content

Subscribe to content

Controls access to content by subscription: it checks whether a user has an active subscription and either grants access to premium content or prompts them to subscribe.

What this example does:

  • Shows premium content only to users with an active subscription
  • The check is based on Orders and Users.
  • Signed-in users without an active subscription get an order and a payment session to subscribe.

Prerequisites:

  • A valid PROJECT_URL and APP_TOKEN for the OneEntry API.
  • An order form (type "Order form") with marker subscription and attributes expired_date (date) and subscription_time (list with an option whose value is 1)
  • An order storage with marker subscriptions linked to that form, with payment account cash
  • A product to sell as the subscription (the example uses productId: 15; replace it with your product's id)
  • A page with URL premium_page
  • A registered user

Notes:

  • The examples handle errors minimally: they throw when a call returns an error object.
  • By default (isShell: true) the SDK returns an error object instead of throwing, so check the result, e.g. 'statusCode' in result. With isShell: false it throws, and you handle errors with try/catch. See Errors.
  • Access opens only after the payment session is completed (isCompleted: true). With the cash payment account, this happens only when the payment is confirmed on the platform side.
  • The subscription check runs in your app, so it only controls what your UI shows. The page itself stays available through the Content API to anyone whose user group can read it. To actually restrict it, allow access to the page only for a user group that subscribers belong to (user-group permissions in the admin panel), and call the API on behalf of the signed-in user.

Platform docs:

SDK reference:

Try it live​

Run this example in the JS SDK sandbox. Connect your Project URL and App Token on first visit, then open:

Scenario​

1. Import defineOneEntry and define PROJECT_URL and APP_TOKEN​

import { defineOneEntry } from 'oneentry';

const PROJECT_URL = 'https://your-project.oneentry.cloud';
const APP_TOKEN = 'your-app-token';

2. Create an API client with defineOneEntry()​

const { Users, Orders, Pages, Payments, AuthProvider, Forms } = defineOneEntry(
PROJECT_URL,
{
token: APP_TOKEN,
},
);

3. Get the subscription form with Forms.getFormByMarker()​

const form = await Forms.getFormByMarker('subscription');
console.log(form);
// expired_date - Date
// subscription_time - list
Result:
{
"id": 6,
"attributeSetId": 8,
"type": "order",
"localizeInfos": {
"title": "Subscription",
"titleForSite": "Subscription",
"successMessage": "Message about successful data processing",
"unsuccessMessage": "Message about unsuccessful data processing",
"urlAddress": "",
"database": "0",
"script": "0"
},
"version": 21,
"position": 1,
"identifier": "subscription",
"processingType": "script",
"templateId": null,
"attributes": [
{
"type": "date",
"marker": "expired_date",
"position": 2,
"settings": {},
"isVisible": true,
"listTitles": [],
"validators": {},
"initialValue": null,
"localizeInfos": {
"title": "Expired date"
},
"additionalFields": {}
},
{
"type": "list",
"marker": "subscription_time",
"position": 5,
"settings": {},
"isVisible": true,
"listTitles": [
{
"title": "1 month",
"value": "1",
"extended": {
"type": "real",
"value": "100"
},
"position": 1
},
{
"title": "6 months",
"value": "6",
"extended": {
"type": "real",
"value": "500"
},
"position": 2
},
{
"title": "1 year",
"value": "12",
"extended": {
"type": "real",
"value": "999"
},
"position": 3
}
],
"validators": {},
"initialValue": null,
"localizeInfos": {
"title": "Subscription time"
},
"additionalFields": {}
}
],
"total": "1",
"moduleFormConfigs": []
}

4. Prepare the data to authenticate the user​

const authData = [
{ marker: 'email_reg', value: 'your-email' },
{ marker: 'password_reg', value: 'your-password' },
];
Result:
[
{
"marker": "email_reg",
"value": "john@example.com"
},
{
"marker": "password_reg",
"value": "123456"
}
]

5. Sign in with AuthProvider.auth() and get the user with Users.getUser()​

const authResponse = await AuthProvider.auth('email', { authData });

if ('statusCode' in authResponse) {
throw new Error(authResponse.message);
}

console.log(authResponse);

const user = await Users.getUser();
console.log(user);

Users.getUser() returns:

Result:
{
"id": 39,
"total": "1",
"identifier": "john@example.com",
"authProviderIdentifier": "email",
"formData": [
{
"marker": "name_reg",
"type": "string",
"value": "John"
},
{
"marker": "phone_reg",
"type": "string",
"value": "+12025550147"
},
{
"marker": "email_notification_reg",
"type": "string",
"value": "john@example.com"
}
],
"formIdentifier": "reg",
"groups": [
1
],
"state": {},
"rating": {},
"moduleFormConfigs": []
}

6. Get the user's orders with Orders.getAllOrdersByMarker()​

const orders = await Orders.getAllOrdersByMarker('subscriptions');

if ('statusCode' in orders) {
throw new Error(orders.message);
}
Result:
{
"items": [
{
"id": 119,
"storageId": 2,
"createdDate": "2026-06-06T11:50:12.995Z",
"statusIdentifier": "active",
"statusLocalizeInfos": {
"title": "Active"
},
"formIdentifier": "subscription",
"formData": [
{
"type": "date",
"marker": "expired_date",
"value": {
"fullDate": "2026-05-07T00:00:00.000Z",
"formattedValue": "07-05-2026 00:00",
"formatString": "DD-MM-YYYY HH:mm"
}
},
{
"type": "list",
"marker": "subscription_time",
"value": [
"1"
]
}
],
"attributeSetIdentifier": "subscriptions",
"paymentStrategy": "once",
"totalSum": "400",
"totalSumRaw": "400",
"currency": "USD",
"paymentAccountIdentifier": "cash",
"paymentAccountLocalizeInfos": {
"title": "Cash"
},
"products": [
{
"id": 15,
"title": "Orange ball",
"sku": null,
"previewImage": "[]",
"price": 400,
"quantity": 1,
"isGift": false
}
],
"paymentUrl": null,
"discountConfig": {
"orderDiscounts": [],
"productDiscounts": [],
"coupon": null,
"settings": {
"allowStacking": false,
"maxDiscountValue": null,
"allowGiftStacking": false,
"maxBonusPaymentPercent": null,
"minBonusAmount": null,
"minOrderAmountForBonus": null,
"giftRefundPolicy": "KEEP_GIFT"
},
"additionalDiscountsMarkers": [],
"totalRaw": 400,
"totalSumWithDiscount": 400,
"excludedGiftProductIds": [],
"bonus": {
"availableBalance": 0,
"maxBonusDiscount": 0,
"minBonusAmount": null,
"minOrderAmountForBonus": null,
"bonusApplied": 0
},
"bonusApplied": 0,
"totalDue": 400
},
"isPartial": false,
"isCompleted": false
}
],
"total": 1
}

7. Check for an active subscription​

const now = new Date();
const hasActiveSubscription = (orders.items ?? []).some((order) => {
// isCompleted: true = payment completed; null = no payment session
if (!order.isCompleted) return false;
const expiry = order.formData.find((d) => d.marker === 'expired_date')
?.value as { fullDate?: string } | undefined;
return !!expiry?.fullDate && new Date(expiry.fullDate) > now;
});

8. If the subscription is active, grant access; otherwise create an order and a payment​

let content = null;
if (hasActiveSubscription) {
// Active subscription: show the content
content = await Pages.getPageByUrl('premium_page');
console.log('Access granted:', content);
} else {
// No active subscription: create an order and a payment session
const months = 1;
const expires = new Date();
expires.setMonth(expires.getMonth() + months);
const pad = (n: number) => String(n).padStart(2, '0');
const formatted = `${pad(expires.getDate())}-${pad(expires.getMonth() + 1)}-${expires.getFullYear()} ${pad(expires.getHours())}:${pad(expires.getMinutes())}`;
const body = {
formIdentifier: 'subscription',
paymentAccountIdentifier: 'cash',
formData: [
{
type: 'date',
marker: 'expired_date',
value: {
fullDate: expires.toISOString(),
formattedValue: formatted,
formatString: 'DD-MM-YYYY HH:mm',
},
},
{
// A `list` field takes an array of the selected option values
// (plain strings), not option objects. '1' = the "1 month" option.
type: 'list',
marker: 'subscription_time',
value: [String(months)],
},
],
products: [
{
productId: 15,
quantity: 1,
},
],
};
const order = await Orders.createOrder('subscriptions', body);

if ('statusCode' in order) {
throw new Error(order.message);
}

const payment = await Payments.createSession(order.id, 'session', false);

if ('statusCode' in payment) {
throw new Error(payment.message);
}

console.log('Payment session:', payment);
}

Final example​

// 1. Import defineOneEntry and define PROJECT_URL and APP_TOKEN
import { defineOneEntry } from 'oneentry';

const PROJECT_URL = 'https://your-project.oneentry.cloud';
const APP_TOKEN = 'your-app-token';

// 2. Create an API client
const { Users, Orders, Pages, Payments, AuthProvider, Forms } = defineOneEntry(
PROJECT_URL,
{
token: APP_TOKEN,
},
);

// 3. Get the subscription form
const form = await Forms.getFormByMarker('subscription');
console.log(form);
// expired_date - Date
// subscription_time - list

// 4. Prepare the data to authenticate the user
const authData = [
{ marker: 'email_reg', value: 'your-email' },
{ marker: 'password_reg', value: 'your-password' },
];

// 5. Sign in and get the user
const authResponse = await AuthProvider.auth('email', { authData });

if ('statusCode' in authResponse) {
throw new Error(authResponse.message);
}

console.log(authResponse);

const user = await Users.getUser();
console.log(user);

// 6. Get the user's orders
const orders = await Orders.getAllOrdersByMarker('subscriptions');

if ('statusCode' in orders) {
throw new Error(orders.message);
}

// 7. Check for an active subscription
const now = new Date();
const hasActiveSubscription = (orders.items ?? []).some((order) => {
// isCompleted: true = payment completed; null = no payment session
if (!order.isCompleted) return false;
const expiry = order.formData.find((d) => d.marker === 'expired_date')
?.value as { fullDate?: string } | undefined;
return !!expiry?.fullDate && new Date(expiry.fullDate) > now;
});

// 8. If the subscription is active, grant access; otherwise create an order and a payment
let content = null;
if (hasActiveSubscription) {
// Active subscription: show the content
content = await Pages.getPageByUrl('premium_page');
console.log('Access granted:', content);
} else {
// No active subscription: create an order and a payment session
const months = 1;
const expires = new Date();
expires.setMonth(expires.getMonth() + months);
const pad = (n: number) => String(n).padStart(2, '0');
const formatted = `${pad(expires.getDate())}-${pad(expires.getMonth() + 1)}-${expires.getFullYear()} ${pad(expires.getHours())}:${pad(expires.getMinutes())}`;
const body = {
formIdentifier: 'subscription',
paymentAccountIdentifier: 'cash',
formData: [
{
type: 'date',
marker: 'expired_date',
value: {
fullDate: expires.toISOString(),
formattedValue: formatted,
formatString: 'DD-MM-YYYY HH:mm',
},
},
{
// A `list` field takes an array of the selected option values
// (plain strings), not option objects. '1' = the "1 month" option.
type: 'list',
marker: 'subscription_time',
value: [String(months)],
},
],
products: [
{
productId: 15,
quantity: 1,
},
],
};
const order = await Orders.createOrder('subscriptions', body);

if ('statusCode' in order) {
throw new Error(order.message);
}

const payment = await Payments.createSession(order.id, 'session', false);

if ('statusCode' in payment) {
throw new Error(payment.message);
}

console.log('Payment session:', payment);
}