Checkout Sessions
Checkout sessions are the easiest way to accept a payment. Create a session on your server, redirect the customer to the hosted payment page, and wait for the webhook.
Step 1: Create a checkout session
Session URL
https://pay.noderails.com/checkout/SESSION_ID. Redirect your customer here after creating the session.Step 2: Customer completes payment
On the hosted checkout page, the customer selects their preferred chain and token, connects their wallet, and approves the transaction. You don't need to build any of this. NodeRails handles the entire payment UI.
Once the customer pays, they're redirected to your successUrl. But don't rely on the redirect to confirm the payment. Always use webhooks.
Step 3: Listen for the webhook
NodeRails sends a payment.captured event to your webhook endpoint when funds have been taken from the customer's wallet, locked in escrow, and confirmed on-chain. This is your signal to fulfill the order.
Step 4: Check payment status
After creating a checkout session, you can check its status at any time. When the customer completes payment, the full payment intent is included in the response, no extra API call needed.
No extra calls needed
paymentIntent object is automatically included once the customer has paid. You don't need to make a separate call to paymentIntents.retrieve().List checkout sessions
Expire a session
Manually expire an open checkout session. This prevents the customer from completing the payment after the session is expired.
Methods reference
| Method | Description |
|---|---|
create(params) | Create a new checkout session |
retrieve(id) | Retrieve a session by ID |
list(params?) | List sessions with optional filters |
expire(id) | Expire an open session |
TypeScript types
Response body reference
All responses are wrapped in { success: true, data: ... }. The fields below describe what's inside data.
create() response
CheckoutSession (create)
idstringUnique session ID (UUID)appIdstringYour app IDcustomerAccountIdstring | nullLinked customer, if providedpaymentIntentIdnullAlways null at creationmodestring"PAYMENT" or "SUBSCRIPTION"statusstring"OPEN" at creationsourceTypestring"API" when created via SDKsourceIdnullNot set at creationamountstring | nullTotal amount (null until computed)currencystringCurrency code, default "USD"subtotalstring | nullPre-tax totaltaxAmountstring | nullTax portiontaxDescriptionstring | nullTax label, e.g. "VAT 20%"allowedChainsstring | number[]"ALL" or array of chain IDsallowedTokensstring | string[]"ALL" or array of token keyssuccessUrlstringRedirect URL after paymentcancelUrlstringRedirect URL if cancelledrequireBillingDetailsbooleanWhether billing details are requiredmetadataobjectYour metadata key-value pairsexpiresAtstringISO 8601 expiration timestampcompletedAtnullSet when session completescreatedAtstringISO 8601 creation timestampupdatedAtstringISO 8601 last update timestampitemsCheckoutSessionItem[]Line items (see below)CheckoutSessionItem (nested in items[])
idstringItem ID (UUID)checkoutSessionIdstringParent session IDproductPlanIdstring | nullLinked product plan, if anyproductPlanPriceIdstring | nullLinked price, if anynamestringItem namedescriptionstring | nullItem descriptionamountstring | nullItem amount (Decimal as string)currencystringItem currencyquantitynumberItem quantityisPriceOptionbooleanWhether this is a price selectioncreatedAtstringISO 8601 timestampretrieve() response
Returns all fields from create() above, plus these additional nested objects:
Additional fields on retrieve
appAppFull app object (id, name, environment, etc.)paymentIntentPaymentIntent | nullFull payment intent once customer pays (all PI fields)items[].productPlanProductPlan | nullFull product plan on each item, if linkeditems[].productPlanPriceProductPlanPrice | nullFull price on each item, if linkedlist() response
Returns an array of sessions. Each session has the same shape as create()(with items but without app, paymentIntent, or nested plan/price on items). The response includes pagination:
expire() response
Same shape as create() (session + items). The status field will be "EXPIRED".