Installation
npm install @xpayr/extension-kit
# or copy src/index.js into your extension —
# zero dependencies, no build step, MV3-ready
Vendez une extension de navigateur, un plugin ou une application de bureau en crypto, sans système de comptes. L'acheteur paie depuis son portefeuille, et ce portefeuille est la licence : il débloque n'importe quel autre appareil en signant un message gratuit. Pas d'e-mail, pas de clé de licence à perdre, pas de rétrofacturation.
Les paiements du Chrome Web Store ont fermé en février 2021 : chaque développeur d'extension a donc besoin d'une couche de paiement externe. La solution dominante impose un compte Stripe, ce qui exclut purement et simplement les développeurs de Turquie, du Pakistan, du Nigéria, du Bangladesh, d'Indonésie, d'Égypte et de bien d'autres pays.
Les passerelles de paiement crypto s'arrêtent à « paiement reçu ». Elles vous donnent un webhook, pas une licence : pas de registre de droits, pas de SDK, pas de vérification multi-appareils. Vous finissez par construire vous-même la moitié difficile. Ce kit, c'est cette moitié.
ExtensionPay Paddle / LS Passerelles cryptoXPayr Kit
frais 5% + Stripe 5% + 50c 0.5-1% 2.9% flat
sans Stripe non partiel oui oui
couche licence oui partiel non oui
retrofacturation oui oui aucune aucune
vendeur officiel non oui non non
Nous ne sommes pas vendeur officiel (merchant of record) : vous déclarez vos propres impôts. C'est précisément ce qu'achètent les frais plus élevés de Paddle et Lemon Squeezy — un vrai arbitrage à comprendre avant de choisir.
Créez un produit dans votre tableau de bord marchand pour obtenir un code produit, puis branchez le SDK. Aucune host_permissions n'est nécessaire : l'installation de votre extension n'affiche donc aucun avertissement d'accès aux données.
npm install @xpayr/extension-kit
# or copy src/index.js into your extension —
# zero dependencies, no build step, MV3-ready
{
"manifest_version": 3,
"permissions": ["storage", "alarms"],
"externally_connectable": { "matches": ["https://xpayr.com/*"] }
}
import XPayrKit from '@xpayr/extension-kit';
const xpayr = XPayrKit('prod_my_extension');
xpayr.startBackground(); // required: token delivery + daily refresh
xpayr.onLicenseChanged.addListener(user => {
console.log(user.licensed ? 'unlocked' : 'locked');
});
const user = await xpayr.getUser();
if (user.licensed) {
enableProFeatures();
} else {
showUpgradeButton(() => xpayr.openCheckout());
}
Voilà toute l'intégration. Le parcours acheteur — choisir un réseau, payer, signer, déverrouiller — est hébergé chez nous sur xpayr.com/buy/{product_code}.
| Champ | Catégorie | Signification |
|---|---|---|
licensed |
boolean |
Conditionnez vos fonctionnalités à ce champ. La réponse vient d'un jeton vérifié localement : instantané et hors ligne. |
plan |
'lifetime' | 'prepaid_year' | null |
Le plan acheté par l'acheteur. |
wallet |
string | null |
Le portefeuille auquel la licence est liée — celui qui a payé. |
paidAt |
Date | null |
Date d'émission de la licence. |
expiresAt |
Date | null |
Date de fin pour les plans limités dans le temps ; null pour à vie. |
source |
'cache' | 'network' |
D'où vient cette réponse. |
staleSince |
Date | null |
Renseigné lorsqu'un jeton périmé est utilisé dans la fenêtre de tolérance hors ligne de 30 jours. |
| Méthode | Description |
|---|---|
startBackground() |
À appeler une fois dans votre service worker. Branche la remise du jeton et l'alarme de rafraîchissement quotidien. |
getUser() |
Vérification de licence hors ligne d'abord. Valide localement le jeton ES256 mis en cache — aucun aller-retour réseau sur le chemin critique. |
openCheckout() |
Ouvre le paiement hébergé dans un nouvel onglet. L'acheteur choisit le réseau et le jeton de son choix parmi ceux activés. |
openRestore() |
« Je l'ai déjà acheté » — débloque un autre appareil par signature du portefeuille. Sans e-mail ni clé de licence. |
refresh() |
Force une revalidation en ligne. Détecte immédiatement remboursements et révocations. |
getPlans() |
Informations produit publiques : prix, type de plan, réseaux autorisés. |
onLicenseChanged |
Se déclenche à chaque changement d'état de la licence. |
Hors ligne un moment ? La licence continue de fonctionner 30 jours après l'expiration du jeton, puis passe en verrouillage souple avec une invite à se reconnecter — personne n'est bloqué en plein vol. Client remboursé ? Révoquez dans le tableau de bord : le renouvellement échoue aussitôt et le jeton meurt sous 7 jours.
Vos 300 premiers $ de ventes de licences sont totalement sans frais. Ensuite, c'est 2,9 % fixe, prélevé dans la même transaction on-chain que le paiement — pas de facture, rien à recouvrer ensuite. Pas de frais fixes, pas d'abonnement, pas de rétrofacturation. Le gas réseau est séparé et payé par l'acheteur.
Licence à 14 $, dans le palier gratuit -> vous recevez 14,00 $Licence à 14 $, après le palier gratuit -> vous recevez 13,59 $ (frais 0,41 $)
Les webhooks sont facultatifs — le Kit émet et vérifie les licences sans aucun backend de votre côté. Si vous voulez des événements côté serveur, ils utilisent le même schéma de signature que tous les webhooks XPayr (voir le guide de signature) et sont réessayés avec temporisation. Utilisez event_id pour l'idempotence.
| Événement | Quand |
|---|---|
license.issued |
Un paiement a produit une licence. Contient le portefeuille, le code produit, le plan et le hash de transaction. |
license.revoked |
Vous avez révoqué une licence depuis le tableau de bord, généralement après un remboursement. |
payment.pending |
Une session de paiement a été créée. |
payment.processing |
Le paiement est on-chain et attend des confirmations. |
payment.completed |
Paiement vérifié on-chain. |
payment.failed |
La transaction soumise n'a pas pu être vérifiée par rapport à la session. |
payment.expired |
La session a expiré sans paiement. |
Émettez et gérez des licences logicielles portefeuille ES256 directement depuis Claude Desktop, Cursor, VS Code Copilot ou des agents de support IA autonomes grâce au serveur officiel XPayr MCP (`xpayr_issue_wallet_license`).
{
"name": "xpayr_issue_wallet_license",
"arguments": {
"product_id": "prod_my_extension",
"buyer_wallet": "0x71C...89A",
"plan": "lifetime",
"tx_hash": "0x9f8e...3b2a"
}
}
Intégrez des badges de confiance SVG dynamiques (partner-badge.php) ou le widget sans dépendance Calculateur de Frais 0.5% et d'Économies (xpayr-fee-widget.js) dans le README de votre extension, votre portail documentaire ou la page de votre agence.
<!-- Official Dynamic SVG Trust Badge -->
<a href="https://xpayr.com?utm_source=partner_badge" target="_blank" rel="noopener">
<img src="https://xpayr.com/partner-badge.php?type=powered_by&theme=dark" alt="Powered by XPayr — 0.5% Non-Custodial Crypto Checkout" height="28">
</a>
<!-- Interactive 0.5% Fee & Savings Calculator Widget -->
<div data-xpayr-fee-widget data-volume="100000" data-invoice="250" data-rate="1.0"></div>
<script src="https://xpayr.com/public/sdk/xpayr-fee-widget.js" async></script>
| ExtensionPay | Kit XPayr |
|---|---|
ExtPay('extension-id') |
XPayrKit('prod_code') |
extpay.startBackground() |
xpayr.startBackground() |
user.paid |
user.licensed |
user.email |
user.wallet |
openPaymentPage() |
openCheckout() |
openLoginPage() |
openRestore() |
onPaid.addListener |
onLicenseChanged.addListener |
getPlans() |
getPlans() |
La seule différence structurelle est l'identité : ExtensionPay identifie le client par e-mail, le Kit par portefeuille. Cela supprime l'aller-retour du lien magique, et implique qu'une licence ne peut être partagée sans partager un portefeuille.
Installez @xpayr/node-sdk (v0.2.0), @xpayr/payment-evidence (v0.2.0), @xpayr/extension-kit (v0.2.0)ou @xpayr/mcp-server (v1.0.0) depuis NPM, ou exécutez des appels d'outils JSON-RPC 2.0 en direct via POST https://xpayr.com/api/mcp.