Skip to main content

Subscriptions

Settlx subscriptions let you charge customers on a recurring schedule — weekly, monthly, annually, or any custom interval — using crypto. You create a plan once, enroll your customers, and Settlx handles the billing cycle automatically.

How it works

Plan ─── defines interval, amount, currency

 └─► Subscriber ─── a customer enrolled into a plan

          └─► Invoice ─── created automatically each billing cycle

                   └─► Customer pays ─► subscriber advances to next period
  1. Create a plan in the dashboard. Plans define the price, interval, and grace period.
  2. Enroll a subscriber via API from your backend whenever a customer signs up.
  3. Settlx creates the first invoice immediately and fires a subscriber.enrolled webhook.
  4. When the customer pays, Settlx fires subscriber.activated and advances their subscription period.
  5. At the start of each new billing cycle, Settlx creates a new invoice automatically and fires subscriber.past_due.
  6. If payment is not received before the grace period ends, the subscriber is expired and subscriber.expired fires.

Subscriber statuses

StatusMeaning
pendingEnrolled, first invoice created, awaiting first payment
trialingIn free-trial period — no invoice created until trial ends
activePaid up — subscription is in good standing
past_dueNew billing cycle started, invoice created, payment not yet received
pausedManually paused by the merchant — no new invoices created
cancelledCancelled by merchant — subscription will not renew
expiredGrace period elapsed without payment
Subscribers start as pending and only become active after their first payment is confirmed on-chain. Do not provision access until you receive the subscriber.activated webhook.

Plans

Plans are created and managed from the Subscriptions → Plans section of your dashboard. The following fields are set at creation and cannot be changed after subscribers have enrolled:
FieldNotes
amountBilling amount per cycle
currencyFiat currency (e.g. USD)
intervalday, week, month, or year
intervalCountNumber of intervals per cycle (e.g. 3 months = quarterly)
trialPeriodDaysDays of free trial before first charge
These fields can be updated at any time:
FieldNotes
nameDisplay name
descriptionDescription shown to subscribers
gracePeriodDaysDays a subscriber has to pay before expiring (minimum 1)

Grace period

Every subscriber has a grace period — the window they have to pay each invoice before their subscription is expired. The grace period starts from the moment an invoice is created.
  • Minimum grace period is 1 day
  • If a subscriber does not pay within the grace period, their status transitions to expired and subscriber.expired fires
  • To reinstate an expired subscriber, you must re-enroll them

Trial periods

If a plan has trialPeriodDays > 0, enrolled subscribers start as trialing. No invoice is created during the trial. When the trial ends, the first invoice is generated automatically and billing begins.

Enrolling subscribers

Enroll subscribers from your backend server using your API key:
curl -X POST https://api.settlx.io/api/v1/subscriptions/subscribers \
  -H "Authorization: Bearer pk_live_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "planId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "email": "customer@example.com",
    "externalId": "usr_789",
    "metadata": { "userId": "usr_789" }
  }'
See Enroll Subscriber for the full API reference.
Never enroll subscribers from client-side code. Your API key must be kept server-side only.

Receiving subscription webhooks

Set your Webhook URL in Settings → Developer. Settlx will POST all subscription lifecycle events to that URL — signed with the same HMAC-SHA256 secret as invoice webhooks. Subscription events use a flat payload (no data wrapper):
{
  "event": "subscriber.activated",
  "subscriberId": "9f1e2d3c-4b5a-6789-abcd-ef0123456789",
  "merchantId": "f9e8d7c6-b5a4-3210-9876-543210fedcba",
  "planId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "email": "customer@example.com",
  "status": "active",
  "currentPeriodEnd": "2026-05-19T06:00:00.000Z",
  "timestamp": "2026-04-19T06:00:00.000Z"
}
The signature is in the X-Webhook-Signature header — same as invoice webhooks. Verify it the same way — see Webhook Integration.

Handling all event types together

Node.js
app.post('/webhooks/settlx', express.raw({ type: 'application/json' }), async (req, res) => {
  verifySignature(req); // same verification as invoice webhooks

  const event = JSON.parse(req.body);

  if (event.event.startsWith('invoice.')) {
    // Invoice payment events
    if (event.event === 'invoice.settled') {
      await fulfillOneTimeOrder(event.data.invoice.metadata.orderId);
    }
  }

  if (event.event.startsWith('subscriber.')) {
    // Subscription lifecycle events
    switch (event.event) {
      case 'subscriber.activated':
        await activateSubscription(event.email, event.planId);
        break;
      case 'subscriber.expired':
      case 'subscriber.cancelled':
        await revokeAccess(event.email);
        break;
      case 'subscriber.paused':
        await pauseAccess(event.email);
        break;
      case 'subscriber.resumed':
        await restoreAccess(event.email);
        break;
    }
  }

  res.status(200).json({ received: true });
});

Subscription lifecycle reference

EventStatus transitionWhat to do
subscriber.enrolledpendingSend a welcome email; show payment instructions
subscriber.activatedactiveProvision access to your product
subscriber.past_duepast_dueSend payment reminder; restrict non-critical features
subscriber.expiredexpiredRevoke access; offer resubscribe flow
subscriber.cancelledcancelledSchedule access revocation at period end
subscriber.pausedpausedSuspend access for the pause duration
subscriber.resumedactiveRestore access

Manual actions

From the dashboard (Subscriptions → Subscribers → [subscriber]) you can:
ActionWhen to use
Send InvoiceManually trigger a new invoice for a pending or past_due subscriber
PauseTemporarily halt billing without cancelling
ResumeRestart a paused subscription
CancelEnd a subscription immediately or at period end

Re-billing

If a subscriber is stuck in pending or past_due and you want to prompt them to pay again, use the Send Invoice button on the subscriber detail page (or POST .../rebill via the merchant API). This is fully idempotent — if a pending invoice already exists, no duplicate is created.