Offres et abonnements
Faites payer votre application sans écrire de code de paiement. Vous définissez des offres, votre application demande au SDK qui a accès, et dg.run s’occupe du paiement : depuis le portefeuille de l’utilisateur ou par carte avec Stripe. Tout est en dollars américains.
Les types d’offres
| Type | Ce que l’utilisateur obtient | Prix |
|---|---|---|
| Essai gratuit | Un accès de N jours (1 à 90). Une seule fois par utilisateur et par application. | Gratuit |
| Abonnement | Un accès pour une période (toutes les N semaines, mois ou années). Se renouvelle seul depuis le portefeuille jusqu’à ce que l’utilisateur l’arrête. | 1 $ à 1 000 $, ou 100 000 à 5 000 000 000 rials |
| Achat unique | Un accès de N jours, ou à vie (0 jour). Ne se renouvelle jamais. | 1 $ à 1 000 $, ou 100 000 à 5 000 000 000 rials |
Créez vos offres dans Mes applications → Offres. Chacune a une clé (par exemple monthly) que votre application utilise pour la désigner, un nom, une courte description et une liste d’avantages. Une application peut avoir jusqu’à 10 offres.
Le type, le prix et la durée d’une offre ne peuvent plus changer une fois créée, car les abonnés les ont acceptés. Pour changer un prix, créez une nouvelle offre et archivez l’ancienne : elle disparaît pour les nouveaux acheteurs et les abonnés actuels gardent ce qu’ils ont acheté. Vous ne pouvez supprimer qu’une offre que personne n’a jamais prise.
Dans votre application
import { createDg } from '@dgrun/sdk'
const dg = createDg()
const plans = await dg.billing.plans() // ce que vous proposez (sans connexion)
const sub = await dg.billing.status() // null, ou l’abonnement de l’utilisateur connecté
if (sub?.active) { /* débloquer les fonctions payantes */ }
await dg.billing.subscribe('monthly') // envoie l’utilisateur payer sur dg.run, puis revient ici
await dg.billing.cancel() // arrête le renouvellement (l’accès dure jusqu’à la fin de la période)
status() renvoie { active, plan, startedAt, currentPeriodEnd, autoRenew, trial, renewalError }. currentPeriodEnd vaut null pour un accès à vie. Un essai ou un abonnement terminé est quand même renvoyé, avec active: false.
Au retour du paiement, le SDK nettoie l’adresse et résout dg.billing.checkout avec { result: 'ok' | 'cancel', plan } (ou null sur tout autre chargement). Il ne dit pas si l’utilisateur a payé : appelez status().
L’exemple Pro Notes du dépôt (examples/pro-notes) est une application complète.
Comment se passe le paiement
- Votre application appelle
subscribe('monthly'). Le navigateur va sur dg.run/subscribe, qui affiche votre application, l’offre, le prix et le solde du portefeuille. - L’utilisateur confirme sur dg.run, avec sa propre session, et choisit de payer avec le portefeuille ou par carte (Stripe). Un essai gratuit demande un seul clic.
- Le navigateur revient dans votre application, qui appelle
status().
Votre page ne voit jamais de carte et ne déplace jamais d’argent. Une application peut seulement lire les offres et le statut, arrêter le renouvellement et demander à l’utilisateur d’aller payer ; elle ne peut débiter personne.
Portefeuille et renouvellements
Chaque utilisateur a un portefeuille dans son Profil : il l’alimente par carte, et il règle les offres de toutes les applications et les renouvellements. Chaque paiement apparaît dans son historique de transactions.
- Un abonnement se renouvelle automatiquement depuis le portefeuille à la fin de sa période. Si le solde est insuffisant, le renouvellement échoue et l’abonnement expire (
renewalErrorvautinsufficient_funds). - Payer un abonnement par carte achète une période ; les renouvellements suivants viennent du portefeuille.
- Passer à une autre offre remplace immédiatement l’actuelle, sans remboursement du temps restant.
- C’est le serveur qui décide : les renouvellements et les expirations sont appliqués chaque fois que quelqu’un lit un abonnement, et une tâche quotidienne traite le reste.
Dans Mes applications → Données et utilisateurs → Utilisateurs, vous voyez l’offre de chaque utilisateur, le temps qu’il lui reste (ou À vie) et si elle se renouvelle automatiquement.
Argent et tests
- Les clients paient dg.run. Votre page Offres affiche ce que les clients ont payé et ce que vous recevez après taxe, frais et part de la plateforme ; la plateforme vous verse l'argent manuellement (voir plus haut).
- Dans un aperçu administrateur, seuls les essais gratuits peuvent être testés.
- Sans clé Stripe, les paiements par carte sont simulés en développement.
Vérifier l’accès hors ligne (preuve signée)
status() interroge toujours le serveur. Pour une application qui doit aussi fonctionner hors ligne, utilisez entitlement() :
const e = await dg.billing.entitlement() // null, ou { plan, trial, periodEnd, validUntil, source }
if (e) { /* déverrouiller */ }
Tant qu’un abonnement est actif, le serveur remet au SDK une preuve signée (Ed25519). Le SDK l’enregistre dans IndexedDB et la vérifie sur l’appareil avec la clé publique de dg.run : elle fonctionne donc hors ligne jusqu’à 15 jours (jamais au-delà de la fin de l’abonnement), et modifier les données enregistrées casse la signature. Elle est liée à votre application et à cet utilisateur. En ligne, le SDK remplace une preuve de plus d’un jour (modifiable avec createDg({ proofRefreshAfterMs })) et la supprime dès que l’abonnement disparaît, que l’utilisateur se déconnecte ou déconnecte l’application. Pour ne faire confiance qu’à une clé que vous détenez, copiez-la depuis https://<dg.run>/api/jwks et passez createDg({ publicKeys }). Les navigateurs sans Ed25519 dans WebCrypto reçoivent null hors ligne (échec fermé).
Devises
Chaque offre est tarifée dans une seule devise, USD ou IRR (rial iranien, sans décimales), que vous choisissez à la création. Elle ne peut plus changer dès que quelqu'un a utilisé l'offre. Rien n'est jamais converti : une offre en rials se paie depuis le solde en rials du client, une offre en dollars depuis son solde en dollars. Les deux sont dans le même portefeuille. Les cartes (Stripe) ne fonctionnent qu'en dollars ; les soldes en rials sont ajoutés par la plateforme. Une application peut proposer des offres dans les deux devises.
Ce que vous gagnez et comment vous êtes payé
Les clients paient le prix complet du forfait. Votre revenu est ce qui reste après la taxe de vente comprise dans le prix, les frais de paiement par carte et la part de la plateforme. Les taux sont affichés sur la page de vos forfaits, avec un graphique de vos revenus et, pour chaque forfait, la répartition de chaque vente. En fixant un prix, vous voyez à peu près ce que vous recevrez par vente. Les taux peuvent changer, mais une vente garde toujours la répartition qu'elle avait au moment de l'achat.
Pour être payé, ajoutez sur votre page Paiements (section Développeur) un moyen de paiement pour chaque devise dans laquelle vous vendez : PayPal, virement Interac, virement bancaire ou autre pour les dollars ; votre numéro SHEBA, le titulaire du compte et le nom de la banque pour les rials. La plateforme décide des options disponibles pour chaque devise. Quand votre solde atteint le minimum, la plateforme envoie l'argent et enregistre le paiement ; vous le voyez sur la même page.
À savoir
status().activeest calculé par le serveur à chaque appel. Ce que fait votre page de cette valeur n’est aussi solide que votre page : utilisez-la pour décider de ce qu’on affiche, et protégez ce qui compte côté serveur.- Erreurs :
plan_not_found,not_recurring,unauthorized. - Supprimer votre application supprime ses offres et ses abonnements ; l’historique des paiements reste.
dg.run