NodeRailsCRYPTO PAYMENT INFRASTRUCTURE
DocumentationAPI Reference
Dashboard

Subscriptions

Subscriptions enable recurring crypto payments. Create a subscription tied to a product plan and price, then manage its lifecycle through pause, resume, and cancel actions.

Subscription lifecycle

Status flowtext
PENDING → ACTIVE → PAUSED → ACTIVE (resume)
                   ↘ CANCELLED
                   ↘ PAST_DUE → CANCELLED

Create a subscription

POST/subscriptions

Request body

ParameterTypeRequiredDescription
appIdstringYesYour app UUID
customerAccountIdstringYesCustomer UUID
productPlanIdstringYesProduct plan UUID
productPlanPriceIdstringYesSpecific price UUID
allowedChains"ALL" | number[]NoAllowed blockchain chain IDs
allowedTokens"ALL" | string[]NoAllowed token identifiers
metadataobjectNoArbitrary key-value metadata
SDK exampletypescript
const subscription = await noderails.subscriptions.create({
  customerAccountId: 'cust_abc123',
  productPlanId: 'plan_xyz',
  productPlanPriceId: 'price_monthly',
  allowedChains: [1, 137],
});

console.log(subscription.id);     // "sub_abc123"
console.log(subscription.status); // "PENDING"
💡

Initial payment

After creating a subscription, use the Create checkout endpoint to generate a payment page for the first billing period.

Create subscription checkout

POST/subscriptions/:id/checkout

Creates a checkout session for the subscription's initial payment. The customer pays through the hosted checkout, and the subscription moves to ACTIVE on success.

SDK exampletypescript
const checkout = await noderails.subscriptions.createCheckout('sub_abc123');
console.log(checkout.url); // Redirect customer here

List subscriptions

GET/subscriptions

Query parameters

ParameterTypeDescription
appIdstringFilter by app UUID
statusstringFilter by status
pagenumberPage number (default: 1)
pageSizenumberItems per page (max 100)
SDK exampletypescript
const result = await noderails.subscriptions.list({
  status: 'ACTIVE',
  page: 1,
});

for (const sub of result.data) {
  console.log(sub.id, sub.status, sub.currentPeriodEnd);
}

Retrieve a subscription

GET/subscriptions/:id
SDK exampletypescript
const sub = await noderails.subscriptions.retrieve('sub_abc123');
console.log(sub.productPlan);    // { name: "Pro Plan", ... }
console.log(sub.currentPeriodEnd); // "2025-02-15T00:00:00.000Z"

Pause a subscription

POST/subscriptions/:id/pause

Pauses an active subscription. No further invoices are generated until resumed.

SDK exampletypescript
const paused = await noderails.subscriptions.pause('sub_abc123');
console.log(paused.status); // "PAUSED"

Resume a subscription

POST/subscriptions/:id/resume
SDK exampletypescript
const resumed = await noderails.subscriptions.resume('sub_abc123');
console.log(resumed.status); // "ACTIVE"

Cancel a subscription

POST/subscriptions/:id/cancel
ParameterTypeRequiredDescription
cancelAtPeriodEndbooleanNoIf true, cancel at end of current period (default: false = immediate)
SDK exampletypescript
// Cancel at end of billing period
const cancelled = await noderails.subscriptions.cancel('sub_abc123', {
  cancelAtPeriodEnd: true,
});

// Cancel immediately
const cancelled2 = await noderails.subscriptions.cancel('sub_abc123');

Response object

All responses are wrapped in { "success": true, "data": ... }. List endpoints add pagination.

Subscription object (create)json
{
  "success": true,
  "data": {
    "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "appId": "b2c3d4e5-f6a7-8901-bcde-f23456789012",
    "customerAccountId": "c3d4e5f6-a7b8-9012-cdef-345678901234",
    "productPlanId": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a",
    "productPlanPriceId": "e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9a0b",
    "status": "PENDING",
    "customerWalletId": null,
    "authorizationMethod": null,
    "authorizationChainId": null,
    "authorizationTokenKey": null,
    "permitSignature": null,
    "permitDeadline": null,
    "permitNonce": null,
    "approvedAllowance": null,
    "currentPeriodStart": null,
    "currentPeriodEnd": null,
    "billingCycleAnchor": null,
    "trialStart": null,
    "trialEnd": null,
    "cancelAt": null,
    "cancelledAt": null,
    "cancelAtPeriodEnd": false,
    "pausedAt": null,
    "pastDueSince": null,
    "captureRetryCount": 0,
    "maxCaptureRetries": 3,
    "pendingJobId": null,
    "allowedChains": [1, 137],
    "allowedTokens": "ALL",
    "metadata": {},
    "createdAt": "2025-01-15T10:30:00.000Z",
    "updatedAt": "2025-01-15T10:30:00.000Z",
    "productPlan": {
      "id": "d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a",
      "name": "Pro Plan",
      "planType": "SUBSCRIPTION"
    },
    "productPlanPrice": {
      "id": "e5f6a7b8-c9d0-1e2f-3a4b-5c6d7e8f9a0b",
      "amount": "9.99",
      "currency": "USD",
      "billingInterval": "MONTH",
      "billingIntervalCount": 1,
      "nickname": "Monthly"
    }
  }
}

Subscription fields

idstringUnique subscription UUID
appIdstringApp this subscription belongs to
customerAccountIdstringCustomer UUID
productPlanIdstringProduct plan UUID
productPlanPriceIdstringSelected price UUID
statusstringPENDING, ACTIVE, PAUSED, CANCELLED, or PAST_DUE
customerWalletIdstring | nullWallet used for payments
authorizationMethodstring | nullDIRECT, PERMIT, or APPROVAL
authorizationChainIdnumber | nullChain ID for recurring charges
authorizationTokenKeystring | nullToken key for recurring charges
permitSignaturestring | nullEIP-2612 permit signature
permitDeadlinestring | nullPermit expiration timestamp
permitNoncestring | nullPermit nonce
approvedAllowancestring | nullERC-20 approved allowance amount
currentPeriodStartstring | nullISO 8601 current billing period start
currentPeriodEndstring | nullISO 8601 current billing period end
billingCycleAnchorstring | nullISO 8601 anchor date for billing cycles
trialStartstring | nullISO 8601 trial start
trialEndstring | nullISO 8601 trial end
cancelAtstring | nullISO 8601 scheduled cancellation date
cancelledAtstring | nullISO 8601 actual cancellation timestamp
cancelAtPeriodEndbooleanWhether to cancel at end of current period
pausedAtstring | nullISO 8601 pause timestamp
pastDueSincestring | nullISO 8601 timestamp when subscription became past due
captureRetryCountnumberNumber of failed capture attempts this cycle
maxCaptureRetriesnumberMaximum capture retries before marking past due
pendingJobIdstring | nullInternal scheduler job ID
allowedChains'ALL' | number[]Permitted blockchain chain IDs
allowedTokens'ALL' | string[]Permitted token identifiers
metadataobjectArbitrary key-value pairs
createdAtstringISO 8601 creation timestamp
updatedAtstringISO 8601 last-update timestamp
💡

Endpoint variations

Create includes productPlan and productPlanPrice. List adds customerAccount and productPlan.taxRate. Retrieve is the richest: includes app, customerAccount, customerWallet, productPlan.taxRate, and the last 10 invoices (with items, taxRate, and paymentIntent). Pause/resume/cancel return scalar fields only (no relations).