Aller au contenu principal

S'abonner à du contenu

Contrôle l'accès au contenu par abonnement : vérifie si l'utilisateur a un abonnement actif et lui donne accès au contenu premium ou l'invite à s'abonner.

Ce que fait cet exemple :

  • Affiche le contenu premium uniquement aux utilisateurs ayant un abonnement actif
  • La vérification s'appuie sur Orders et Users.
  • Les utilisateurs connectés sans abonnement actif reçoivent une commande et une session de paiement pour s'abonner.

Prérequis :

  • Un PROJECT_URL et un APP_TOKEN valides pour l'API OneEntry.
  • Un formulaire de commande (type "Order form") avec le marqueur subscription et les attributs expired_date (date) et subscription_time (liste avec une option dont la valeur est 1)
  • Un stockage des commandes avec le marqueur subscriptions lié à ce formulaire, avec le compte de paiement cash
  • Un produit à vendre comme abonnement (l'exemple utilise productId: 15 ; remplacez-le par l'id de votre produit)
  • Une page avec l'URL premium_page
  • Un utilisateur inscrit

Remarques :

  • Les exemples gèrent les erreurs de façon minimale : ils lèvent une exception lorsqu'un appel renvoie un objet d'erreur.
  • Par défaut (isShell: true), le SDK renvoie un objet d'erreur au lieu de lever une exception : vérifiez donc le résultat, par ex. 'statusCode' in result. Avec isShell: false, il lève une exception, et vous gérez les erreurs avec try/catch. Voir Errors.
  • L'accès n'est ouvert qu'une fois la session de paiement terminée (isCompleted: true). Avec le compte de paiement cash, cela n'arrive que lorsque le paiement est confirmé côté plateforme.
  • La vérification de l'abonnement s'exécute dans votre application : elle ne contrôle donc que ce qu'affiche votre interface. La page elle-même reste accessible via la Content API à toute personne dont le groupe d'utilisateurs peut la lire. Pour vraiment en restreindre l'accès, autorisez la page uniquement pour un groupe d'utilisateurs auquel appartiennent les abonnés (autorisations des groupes d'utilisateurs dans le panneau d'administration), et appelez l'API au nom de l'utilisateur connecté.

Documentation de la plateforme :

Référence du SDK :

Essayer en direct​

Exécutez cet exemple dans le bac à sable JS SDK. Lors de la première visite, connectez l'URL de votre projet et votre App Token, puis ouvrez :

Scénario​

1. Importer defineOneEntry et définir PROJECT_URL et APP_TOKEN​

import { defineOneEntry } from 'oneentry';

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

2. Créer un client API avec defineOneEntry()​

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

3. Obtenir le formulaire d'abonnement avec Forms.getFormByMarker()​

const form = await Forms.getFormByMarker('subscription');
console.log(form);
// expired_date - Date
// subscription_time - list
Résultat :
{
"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. Préparer les données pour authentifier l'utilisateur​

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

5. Connecter l'utilisateur avec AuthProvider.auth() et obtenir l'utilisateur avec 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() renvoie :

Résultat :
{
"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. Obtenir les commandes de l'utilisateur avec Orders.getAllOrdersByMarker()​

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

if ('statusCode' in orders) {
throw new Error(orders.message);
}
Résultat :
{
"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. Vérifier l'existence d'un abonnement actif​

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. Si l'abonnement est actif, donner l'accès ; sinon, créer une commande et un paiement​

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);
}

Exemple final​

// 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);
}