Recur Docs

Quickstart

Install the SDK and create your first subscription in 5 minutes.

Quickstart

Installation

Releasing soon on npm. The @recur/sdk package is fully built and will be published to npm shortly. Stay tuned!

Terminal
npm install @recur/sdk @solana/web3.js @solana/spl-token

Initialize the client

Use getClusterDefaults to get the correct RPC URL, program ID, and USDC mint for your target cluster:

recur.ts
import { RecurClient, getClusterDefaults } from "@recur/sdk";
 
const defaults = getClusterDefaults("devnet");
// defaults = { rpcUrl, programId, usdcMint }
 
const recur = new RecurClient({
  rpcUrl: defaults.rpcUrl,
  apiBaseUrl: "https://api.recur.so",
  programId: defaults.programId,   // optional — already the default for devnet
  usdcMint: defaults.usdcMint,     // optional — already the default for devnet
  apiKey: process.env.RECUR_API_KEY, // optional, for merchant-authenticated calls
});

Or provide explicit values:

const recur = new RecurClient({
  rpcUrl: "https://api.devnet.solana.com",
  apiBaseUrl: "https://api.recur.so",
});

Subscribe a user

Build the instructions that create an on-chain subscription. The subscriber signs the resulting transaction in their wallet — no backend signature needed.

subscribe.ts
import { RecurClient, getClusterDefaults } from "@recur/sdk";
import { Connection, Transaction } from "@solana/web3.js";
 
const defaults = getClusterDefaults("devnet");
const recur = new RecurClient({
  rpcUrl: defaults.rpcUrl,
  apiBaseUrl: "https://api.recur.so",
});
 
// Plan details (from your backend / the Recur API)
const plan = await recur.getPlan("app_xxx", "plan_abc123");
 
const { subscriptionPda, instructions, bump } = recur.buildSubscribeTransaction(
  wallet.publicKey,
  {
    planId: plan.id,
    merchantWallet: plan.app.merchant.walletAddress,
    planSeed: plan.planSeed,
    amount: Number(plan.amountBaseUnits),
    intervalSeconds: plan.intervalSeconds,
  },
);
 
const tx = new Transaction().add(...instructions);
const signed = await wallet.signTransaction(tx);
const sig = await connection.sendRawTransaction(signed.serialize());
await connection.confirmTransaction(sig, "confirmed");

The returned instructions array contains exactly two instructions:

  1. SPL Token approve — delegates amount × delegationCycles (default 12) to the Subscription PDA
  2. initialize_subscription — creates the on-chain PDA with amount, interval, and plan seed

Or use the high-level subscribe method

const token = await recur.authenticate(wallet);
const { subscriptionPda, signature, subscription } = await recur.subscribe(
  wallet,
  {
    appId: "app_xxx",
    planId: plan.id,
    merchantWallet: plan.app.merchant.walletAddress,
    planSeed: plan.planSeed,
    amount: Number(plan.amountBaseUnits),
    intervalSeconds: plan.intervalSeconds,
  },
  token,
);

This builds, signs, confirms, and registers the subscription in one call.

What happens next

Once the subscription is created on-chain:

  1. The first payment is processed immediately — no waiting for the billing interval
  2. The Keeper detects the subscription and registers it in the database (your frontend can also call registerSubscription directly with the subscriber JWT)
  3. After each subsequent billing interval elapses, the Keeper calls process_payment
  4. Funds are pulled from the subscriber's wallet: net amount to the merchant, platform fee to the treasury
  5. A webhook fires to the merchant's registered endpoint with payment details

When the SPL approve runs out (after delegationCycles payments), call buildReapproveTransaction to top it up — no on-chain subscription state is touched.

@recur/react — Coming Soon. A React package with RecurProvider, SubscribeButton, and hooks is planned. For now, use @recur/sdk directly as shown above.

Next steps

  • Subscribe — full subscribe API reference
  • Cancel — let subscribers cancel
  • Webhooks — handle payment notifications in your backend
  • Plans — create and manage plans via the API
  • Errors — handle errors gracefully

On this page