NodeRailsCRYPTO PAYMENT INFRASTRUCTURE
DocumentationAPI Reference
Dashboard

Payment Intents

Payment intents are the core payment object. Every checkout session creates a payment intent under the hood when the customer pays. You can also create payment intents directly for more control over the payment flow.

💡

Payment intent lifecycle

A payment intent moves through these states: CREATEDAUTHORIZEDCAPTUREDSETTLED. It can also be CANCELLED (before capture) or REFUNDED (after capture). If a dispute is raised, it moves to DISPUTED and then DISPUTE_RESOLVED or DISPUTE_LOST.

Create a payment intent

Create payment intenttypescript
const intent = await noderails.paymentIntents.create({
  amount: '100.00',
  currency: 'USD',
  captureMode: 'AUTOMATIC',
  allowedChains: [1, 137, 42161],          // Ethereum, Polygon, Arbitrum
  allowedTokens: ['USDC', 'USDT'],         // Accept USDC and USDT
  externalId: 'order_456',                 // Your internal order ID
  metadata: { plan: 'enterprise' },
});

console.log(intent.id);     // Payment intent ID
console.log(intent.status); // "CREATED"

Retrieve a payment intent

Check a payment intent's status at any time. Useful for polling or verifying the state after receiving a webhook.

Check payment statustypescript
const intent = await noderails.paymentIntents.retrieve('payment-intent-id');

console.log(intent.status);           // Current status
console.log(intent.amount);           // Fiat amount
console.log(intent.cryptoAmount);     // Crypto amount paid
console.log(intent.captureTxHash);    // On-chain capture transaction hash
console.log(intent.authorizationChainId);  // Chain the payment was made on
console.log(intent.authorizationTokenKey); // Token used (e.g., "USDC-8453")
console.log(intent.externalId);       // Your order reference

List payment intents

List and filtertypescript
// List all captured payments
const captured = await noderails.paymentIntents.list({
  status: 'CAPTURED',
  page: 1,
  pageSize: 50,
});

for (const intent of captured.data) {
  console.log(intent.id, intent.amount, intent.cryptoAmount);
}

Cancel a payment intent

Cancel a payment that hasn't been captured yet. This releases the authorized funds back to the customer.

Canceltypescript
const cancelled = await noderails.paymentIntents.cancel('payment-intent-id');
console.log(cancelled.status); // "CANCELLED"

Refund a payment

Refund a captured payment. The funds are sent back to the customer's wallet on-chain.

Refundtypescript
const refunded = await noderails.paymentIntents.refund('payment-intent-id', {
  reason: 'Customer requested refund',
});
      console.log(refunded.status); // Updated payment status
⚠️

Refund timing

Refunds are processed on-chain and may take a few minutes to complete depending on the network. Track refundTxHash and webhook events to confirm completion.

Webhooks

Listen for these events to track payment intent state changes:

EventDescription
payment.authorizedCustomer gave approval to pull money from their wallet
payment.capturedFunds taken from wallet, locked in escrow, and confirmed on-chain
payment.settledFunds released to your merchant wallet
payment.refundedRefund completed on-chain
payment.disputedCustomer raised a dispute

Methods reference

MethodDescription
create(params)Create a new payment intent
retrieve(id)Retrieve a payment intent by ID
list(params?)List payment intents with optional filters
cancel(id)Cancel an authorized payment
refund(id, params?)Refund a captured payment

TypeScript types

Type importstypescript
import type {
  PaymentIntent,
  PaymentIntentCreateParams,
  PaymentIntentListParams,
} from '@noderails/sdk';

Response body reference

All responses are wrapped in { success: true, data: ... }. The fields below describe what's inside data.

create() response

Returns all scalar fields only (no relations):

PaymentIntent (create)

idstringUnique payment intent ID (UUID)
appIdstringYour app ID
customerAccountIdstring | nullLinked customer
externalIdstring | nullYour external reference ID
amountstringFiat amount (Decimal as string, e.g. "100.00")
currencystringCurrency code, e.g. "USD"
allowedChainsstring | number[]"ALL" or array of chain IDs
allowedTokensstring | string[]"ALL" or array of token symbols
captureModestring"AUTOMATIC" or "MANUAL"
timelockDurationnumberEscrow timelock in seconds (default 604800 = 7 days)
disputeStartDurationnumberDispute window in seconds (default 86400 = 1 day)
statusstring"CREATED" at creation
authorizationMethodnullSet when customer authorizes
authorizationChainIdnullChain used for payment
authorizationTokenKeynullToken key used (e.g. "USDC-8453")
authorizationWalletAddressnullCustomer wallet address
authorizationTxHashnullAuthorization transaction hash
authorizedAtnullTimestamp when authorized
cryptoAmountnullCrypto amount in smallest unit
cryptoTokenKeynullToken key of crypto used
cryptoTokenDecimalsnullToken decimals
exchangeRatenullUSD-to-crypto exchange rate used
captureTxHashnullCapture transaction hash
capturedAtnullTimestamp when captured
captureAttemptsnumberNumber of capture attempts (0)
timelockEndsAtnullWhen escrow timelock expires
settledAtnullTimestamp when settled
refundedAtnullTimestamp when refunded
refundTxHashnullRefund transaction hash
refundReasonnullReason for refund
platformFeeBpsnullPlatform fee in basis points
expiresAtstring | nullISO 8601 expiration timestamp
sourceTypestring | nullWhat created this intent (CHECKOUT_SESSION, INVOICE, etc.)
sourceIdstring | nullID of the source entity
successUrlstring | nullRedirect URL after payment
cancelUrlstring | nullRedirect URL if cancelled
metadataobjectYour metadata key-value pairs
idempotencyKeystring | nullIdempotency key if provided
createdAtstringISO 8601 creation timestamp
updatedAtstringISO 8601 last update timestamp

retrieve() response

Returns all scalar fields from create() above, plus three nested relations:

Additional fields on retrieve

transactionsTransaction[]On-chain transactions for this intent
disputeDispute | nullDispute details if one exists
customerAccountCustomerAccount | nullCustomer who paid

Transaction (nested in transactions[])

idstringTransaction record ID (UUID)
paymentIntentIdstring | nullLinked payment intent
mtxmTxIdstring | nullMTXM service transaction ID
txHashstring | nullOn-chain transaction hash
chainstringChain identifier
typestringAUTHORIZE, CAPTURE, SETTLE, DISPUTE, REFUND, or PAYOUT
statusstringPENDING, CONFIRMED, or FAILED
blockNumbernumber | nullBlock number when confirmed
gasUsedstring | nullGas used for the transaction
errorstring | nullError message if failed
createdAtstringISO 8601 timestamp
confirmedAtstring | nullWhen the transaction was confirmed

Dispute (nested in dispute)

idstringDispute ID (UUID)
paymentIntentIdstringLinked payment intent
reasonstringReason for the dispute
evidencestring | nullEvidence submitted
statusstringOPEN, RESOLVED_MERCHANT, or RESOLVED_PAYER
resolvedBystring | nullWho resolved the dispute
deadlinestringDispute resolution deadline
createdAtstringISO 8601 timestamp
resolvedAtstring | nullWhen it was resolved

list() response

Returns an array of payment intents. Each has all scalar fields plus transactions[]. No dispute or customerAccount in list.

Paginated response shapejson
{
  "success": true,
  "data": [ /* PaymentIntent[] with transactions */ ],
  "pagination": {
    "total": 100,
    "page": 1,
    "pageSize": 20,
    "totalPages": 5
  }
}

cancel() response

Returns all scalar fields only (no relations). The status field will be "CANCELLED".

refund() response

Returns the updated PaymentIntent object (same scalar shape as create()):

Key refund fields

idstringPayment intent ID
statusstringUpdated payment status (typically "REFUNDED" once finalized)
refundReasonstring | nullRefund reason you provided
refundTxHashstring | nullOn-chain refund tx hash (when available)
refundedAtstring | nullTimestamp when refund is finalized