PersonalBusinessEnterprise
    In a rush? Schedule an Appointment
    Fetching local time...
    Anytime CapitalforBusiness
    Pricing

    Get started

    • Overview
    • Quickstart
    • Test mode
    • Guides & recipes
    • Switch from Stripe
    • Import from Shopify
    • Import from WooCommerce
    • Import from Square
    • Import a CSV file
    • Stripe API mapping
    • Pricing
    • Support
    • FAQ

    Payments

    • Checkout & website
    • Guide: Next.js checkout
    • In person (QR)
    • Payment methods
    • Stablecoin checkout
    • Guide: take stablecoins
    • Fraud rules & 3D Secure
    • Dispute evidence
    • International customers
    • Guide: safe refunds
    • Bank transfers on invoices

    Billing

    • Subscription discounts
    • Guide: sell subscriptions
    • Usage billing
    • Guide: report usage

    Money movement

    • Payout options
    • Guide: reconcile payouts
    • Accounting sync
    • Revenue analytics

    Developers

    • Authentication
    • Errors & retries
    • Pagination
    • Idempotency
    • Rate limits
    • Webhooks
    • Verify webhooks
    • Node SDK (preview)
    • CLI (preview)
    • Postman collection

    AI

    • AI agents hub
    • Safe AI agents
    • Custom agents
    • Prompt library

    Integrations

    • Website builders
    • Shopify
    • Shopify orders by invoice
    • WooCommerce
    • Zapier
    • Slack, Discord and Teams

    Reference

    • Payments
    • Refunds
    • Disputes
    • Payment links
    • Invoices
    • Customers
    • Products
    • Subscriptions & plans
    • Discount codes
    • Meters & usage events
    • Payouts & balance
    • Webhook endpoints
    • Events
    • Test helpers
    • OpenAPI spec
    • Error codes
    • Changelog
    • Glossary

    For AI tools

    • llms-full.txt
    • MCP server
    • openapi.json
    Docs menu · Guide: sell subscriptions

    Get started

    • Overview
    • Quickstart
    • Test mode
    • Guides & recipes
    • Switch from Stripe
    • Import from Shopify
    • Import from WooCommerce
    • Import from Square
    • Import a CSV file
    • Stripe API mapping
    • Pricing
    • Support
    • FAQ

    Payments

    • Checkout & website
    • Guide: Next.js checkout
    • In person (QR)
    • Payment methods
    • Stablecoin checkout
    • Guide: take stablecoins
    • Fraud rules & 3D Secure
    • Dispute evidence
    • International customers
    • Guide: safe refunds
    • Bank transfers on invoices

    Billing

    • Subscription discounts
    • Guide: sell subscriptions
    • Usage billing
    • Guide: report usage

    Money movement

    • Payout options
    • Guide: reconcile payouts
    • Accounting sync
    • Revenue analytics

    Developers

    • Authentication
    • Errors & retries
    • Pagination
    • Idempotency
    • Rate limits
    • Webhooks
    • Verify webhooks
    • Node SDK (preview)
    • CLI (preview)
    • Postman collection

    AI

    • AI agents hub
    • Safe AI agents
    • Custom agents
    • Prompt library

    Integrations

    • Website builders
    • Shopify
    • Shopify orders by invoice
    • WooCommerce
    • Zapier
    • Slack, Discord and Teams

    Reference

    • Payments
    • Refunds
    • Disputes
    • Payment links
    • Invoices
    • Customers
    • Products
    • Subscriptions & plans
    • Discount codes
    • Meters & usage events
    • Payouts & balance
    • Webhook endpoints
    • Events
    • Test helpers
    • OpenAPI spec
    • Error codes
    • Changelog
    • Glossary

    For AI tools

    • llms-full.txt
    • MCP server
    • openapi.json
    DocsBillingGuide: sell subscriptions

    Sell subscriptions with coupons and plan changes

    Create subscription plans, send customers to subscribe, offer coupon codes, let them change plans, and keep access in your app in step with webhooks.

    View as MarkdownOpen in Claude

    Customers subscribe on Anytime Capital's hosted page for each plan. Your app creates the plans, sends customers to them, and keeps access in step with webhooks. Coupons and plan changes are switched on in the dashboard; no code needed for those. Endpoint details: Subscriptions & plans.

    1. Create your plans

    Make them in Subscriptions → Plans in the dashboard, or from code with a key that has subscriptions write. A plan's price and interval are fixed once it exists; for a new price, make a new plan.

    create-plans.mjs
    // create-plans.mjs — run once: node create-plans.mjs
    const API = "https://anytime-capital.com/api/v1";
    
    const PLANS = [
      { key: "plan-basic-monthly", title: "Basic", amountCents: 1900, interval: "month", trialDays: 14 },
      { key: "plan-pro-monthly", title: "Pro", amountCents: 4900, interval: "month", trialDays: 14 },
      { key: "plan-pro-yearly", title: "Pro (yearly)", amountCents: 49000, interval: "year" },
    ];
    
    for (const { key, ...plan } of PLANS) {
      const res = await fetch(`${API}/subscription-plans`, {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
          "Content-Type": "application/json",
          "Idempotency-Key": key, // run it twice within 24 hours and you still get one plan each
        },
        body: JSON.stringify(plan),
      });
      const created = await res.json();
      if (!res.ok) throw new Error(`${created.error.code}: ${created.error.message}`);
      console.log(created.id, created.title, created.url); // put each url behind its Subscribe button
    }

    2. Send customers to subscribe

    Each plan's url is its subscribe page: link your Subscribe buttons to it. Free trials start there, and the subscription appears on your Subscriptions page and in subscription.created.

    3. Offer coupons

    1. Create a code on the Discounts page, or with POST /api/v1/discount-codes (see Discount codes).
    2. In the dashboard, turn on Use on subscriptions for it and choose how long it lasts: the first payment, several months, or every payment, and which plans it covers.
    3. The plan's subscribe page then shows Have a discount code?. You can also add a code to an existing subscriber from their details.

    How long a discount lasts and new-customers-only rules are on Subscription discounts; subscription settings for a code can't be set through the API.

    4. Keep access in step

    Subscribe your endpoint to subscription.created, subscription.updated, subscription.paused, subscription.resumed, subscription.past_due and subscription.canceled. Events can arrive more than once and out of order, so on each one, read the subscription as it is now and store that.

    subscriptions-webhook.mjs
    // subscriptions-webhook.mjs — Node.js 18+ with Express: npm install express
    import crypto from "node:crypto";
    import express from "express";
    
    const API = "https://anytime-capital.com/api/v1";
    const secret = process.env.ANYTIME_WEBHOOK_SECRET; // whsec_…
    const access = new Map(); // email → { plan, status, until }: use your database
    
    /** Which statuses keep the product open. */
    function hasAccess(status) {
      return ["trialing", "active", "canceling", "past_due"].includes(status); // past_due: renewal being retried
    }
    
    function verify(rawBody, header) {
      const parts = Object.fromEntries(String(header ?? "").split(",").map((part) => part.split("=")));
      const expected = crypto.createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
      return (
        typeof parts.v1 === "string" &&
        parts.v1.length === expected.length &&
        crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected)) &&
        Math.abs(Date.now() / 1000 - Number(parts.t)) <= 300
      );
    }
    
    /** Events can arrive out of order: always store the subscription as it is now. */
    async function syncSubscription(id) {
      const res = await fetch(`${API}/subscriptions/${id}`, {
        headers: { Authorization: `Bearer ${process.env.ANYTIME_API_KEY}` },
      });
      const subscription = await res.json();
      if (!res.ok) throw new Error(`${subscription.error.code}: ${subscription.error.message}`);
      access.set(subscription.customer.email, {
        plan: subscription.plan.id,
        status: subscription.status,
        allowed: hasAccess(subscription.status),
        until: subscription.currentPeriodEnd,
      });
    }
    
    const app = express();
    app.post("/webhooks/anytime", express.raw({ type: "application/json" }), async (req, res) => {
      const rawBody = req.body.toString("utf8");
      if (!verify(rawBody, req.get("Anytime-Signature"))) return res.status(400).send("Invalid signature");
      const event = JSON.parse(rawBody);
      if (event.type.startsWith("subscription.")) {
        try {
          await syncSubscription(event.data.id);
        } catch (error) {
          console.error(error);
          return res.sendStatus(500); // not 2xx, so the event is sent again later
        }
      }
      res.sendStatus(200);
    });
    
    app.listen(3000);

    A nightly safety net

    Once a day, page through GET /api/v1/subscriptions and run each through the same sync. It catches anything a missed event would have changed, plan changes included.

    5. Plan changes

    Move a subscriber with Change plan from their details on the Subscriptions page, now (with the unused part of the period refunded) or at the next renewal. To let subscribers switch themselves, mark the plans they may move to and turn on Subscribers can switch plans. Plan changes aren't in the API: read plan.id from the subscription, never from what you remember. See plan changes.

    6. Cancel, pause and resume from your app

    From your admin screen
    // From your admin screen: end, pause or resume a subscriber (subscriptions:write).
    async function subscriptionAction(id, action, body) {
      const res = await fetch(`https://anytime-capital.com/api/v1/subscriptions/${id}/${action}`, {
        method: "POST",
        headers: {
          Authorization: `Bearer ${process.env.ANYTIME_API_KEY}`,
          "Idempotency-Key": `${action}-${id}-${new Date().toISOString().slice(0, 10)}`,
          ...(body ? { "Content-Type": "application/json" } : {}),
        },
        body: body ? JSON.stringify(body) : undefined,
      });
      const subscription = await res.json();
      if (!res.ok) throw new Error(`${subscription.error.code}: ${subscription.error.message}`); // e.g. CANNOT_PAUSE
      return subscription;
    }
    
    await subscriptionAction("sub_2208", "cancel", { atPeriodEnd: true }); // or { atPeriodEnd: false } to end now
    await subscriptionAction("sub_2208", "resume"); // undoes the cancellation set for the period's end

    The subscriber gets the same emails as when you act from the dashboard. Errors such as 409 CANNOT_PAUSE or 409 SUBSCRIPTION_ENDED explain themselves: see the error code catalogue.

    Bill usage with metersCharge for what subscribers use on top of the plan.Verify webhooksThe signature check in Node.js, Python and PHP.
    PreviousSubscription discountsNext Usage billing

    Anytime Capital is a fintech company, not a bank. Payment processing, banking and payout services are provided by Anytime Capital's licensed partners. Rates shown are for US card payments; international cards, currency conversion and disputes may carry additional fees shown in your dashboard before you accept a payment.

    On this page

    • 1. Create your plans
    • 2. Send customers to subscribe
    • 3. Offer coupons
    • 4. Keep access in step
    • 5. Plan changes
    • 6. Cancel, pause and resume from your app
    Anytime Capital
    (470) 748-2530
    App Store

    Business

    • Business Checking
    • Business Debit Cards
    • Payments
    • Ecommerce Payments
    • Invoicing
    • Developer Docs

    Solutions

    • CPAs & Accountants
    • Financial Advisors
    • Boat & Auto Dealerships
    • Dental & Medical Practices
    • Creators & Coaches
    • All solutions

    Crypto

    • Crypto Wallet
    • Tether Wallet
    • Buy Digital Assets
    • Explore Markets
    • Security & Licenses
    • Compare Platforms
    • Bitcoin ATM Alternative

    Company

    • Our Story
    • Schedule Appointment
    • Careers
    • Media & Press
    • Investor Relations
    • FAQ

    Branches

    • Atlanta, Georgia
    • Miami, Florida
    • Houston, Texas
    • All branches

    Legal

    • Terms & Conditions
    • Privacy Policy
    • Your Privacy Choices
    • Fraud Notice

    © 2026 Anytime Capital LLC. Anytime Capital is a fintech company, not a bank.

    The Anytime Capital Mastercard® Prepaid Card is issued by Pathward®, N.A., Member FDIC. Mastercard® is a registered trademark of Mastercard International Incorporated. All other trademarks and service marks belong to their respective owners.

    Mastercard