Skip to content
Blog

Subscriptions

Subscriptions let you offer recurring access plans paid with crypto. Define tiers in the dashboard, each with a name, billing interval, and token prices. When a user purchases and their payment confirms on-chain, the subscription activates automatically. No webhooks to configure, no third-party billing service to wrestle with.

  1. Go to the Tribe dashboard
  2. Open your site’s Settings → Subscriptions
  3. Create subscription tiers with:
    • Name for the plan, such as “Pro” or “Premium”
    • Interval as the billing period in days (30 for monthly, 365 for yearly)
    • Prices specifying the amount per token (for example, 0.5 SOL or 10 USDC)
  1. List tiersgetSubscriptions() returns all available tiers with prices
  2. PurchasepurchaseSubscription(tierId, mint) creates a payment
  3. Pay — complete via sendViaWallet() or QR code scan
  4. Verify — poll verifyPayment() until confirmed
  5. Active — subscription activates automatically after payment
import { Tribe } from "@tribecloud/sdk";
const tiers = await tribe.getSubscriptions();
// [{ id, name, intervalDays, prices: [{ mint, amount }] }]
const subs = await tribe.getActiveSubscriptions();
// [{ id, startsAt, expiresAt, isActive, tier: { id, name, intervalDays, prices } }]
const payment = await tribe.purchaseSubscription(tierId, "SOL");
// Returns: PaymentResult { id, paymentUrl, expiresAt }
// Complete payment via wallet
const status = await tribe.sendViaWallet({ mint: "SOL", amount: "0" });
// Or show a QR code with payment.paymentUrl
function SubscriptionPage() {
const [tiers, setTiers] = useState([]);
const [activeSubs, setActiveSubs] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
Promise.all([tribe.getSubscriptions(), tribe.getActiveSubscriptions()])
.then(([t, s]) => { setTiers(t); setActiveSubs(s); })
.finally(() => setLoading(false));
}, []);
const handlePurchase = async (tierId, mint) => {
try {
const payment = await tribe.purchaseSubscription(tierId, mint);
const status = await tribe.sendViaWallet({ mint, amount: "0" });
if (status.status === "confirmed") {
setActiveSubs(await tribe.getActiveSubscriptions());
}
} catch (err) {
console.error("Purchase failed:", err.message);
}
};
if (loading) return <p>Loading...</p>;
const activeIds = new Set(activeSubs.filter((s) => s.isActive).map((s) => s.tier.id));
return (
<div>
<h2>Subscription Plans</h2>
{tiers.map((tier) => (
<div key={tier.id}>
<h3>{tier.name}</h3>
<p>Renews every {tier.intervalDays} days</p>
{activeIds.has(tier.id) ? (
<span>Active</span>
) : (
tier.prices.map((p) => (
<button key={p.mint} onClick={() => handlePurchase(tier.id, p.mint)}>
Subscribe for {p.amount} {p.mint === "SOL" ? "SOL" : "tokens"}
</button>
))
)}
</div>
))}
</div>
);
}
  • Subscriptions expire automatically once intervalDays have passed. Users renew by purchasing again.
  • Early renewals extend from the current expiry date, so users don’t lose any time they’ve already paid for.
  • getSubscriptions() is a public call that doesn’t require authentication. getActiveSubscriptions() and purchaseSubscription() both need the user to be logged in.