RupayDeveloper docsOpenAPI specification

Stripe SDK compatibility

Rupay supports the Stripe Node SDK for fixed-period hosted purchases. This is a supported subset, not full Stripe Billing or automatic-renewal parity. The initial client/API contract is Stripe Node 20.4.1, API version 2026-02-25.clover. Configure that version explicitly.

Available methods

SDK methodSupported behavior
customers.createOptional name/email/phone/metadata; idempotent creation
customers.retrieveMerchant-scoped Customer object and metadata
products.list, products.retrieveRead the existing Rupay catalog; cursor pagination on lists
prices.list, prices.retrieveImmutable catalog Price snapshots; product/active filtering; cursor pagination
checkout.sessions.createmode: "payment"; one line_items[].price item; existing customer or customer email; order reference; registered return URLs; promotion-code flag
checkout.sessions.retrieveSDK-shaped session status, customer ID, payment status and verified access-period metadata
checkout.sessions.expireExpire an unpaid session
webhookEndpoints.createRegister checkout.session.completed; endpoint-specific secret and pinned payload format
webhooks.constructEventAsyncVerify the raw body with the returned secret and Stripe-Signature header
refunds.list, refunds.retrieveSupport-managed refund records in Stripe Refund format; read-only
disputes.list, disputes.retrieveExisting provider cases in Stripe Dispute format; read-only

Product and Price writes remain managed through Rupay's catalog admin. Catalog creation/editing generates Price snapshots transactionally; amount/duration changes archive the old offer and produce a new ID. Existing sessions keep their original amount and duration. Migration 0032 also creates Prices for existing simple products and variants. Because the legacy catalog rebuilds variants on edit, editing a variable product can replace its variant and Price IDs; refresh the configured plan mapping after such an edit. Product/Price list and retrieval currently require checkout_sessions:read; checkout creation/expiry require checkout_sessions:write.

A fixed-period catalog subscription is exposed as a one-time Price with metadata.rupay_period_interval. It does not claim Stripe recurring collection. A paid checkout exposes authoritative Unix-second values as strings in metadata.rupay_period_start and metadata.rupay_period_end, with metadata.rupay_renewal_mode: "manual". Its subscription field is null.

Version and backward compatibility

The Stripe SDK sends Stripe-Version; Rupay selects the supported SDK contract when it equals 2026-02-25.clover. Other nonempty versions are rejected. Requests without this header retain the native response format. This prevents an SDK integration from changing existing native merchant responses.

SDK-created webhook endpoints store that API version. Their completed-checkout payloads use the SDK format and include Stripe-Signature; native endpoints keep their existing format. Secret generation is per SDK endpoint. Verification must use the raw body; use the async verifier in Cloudflare/Bun.

Idempotency keys are optional in SDK mode, but callers should always supply a stable key for customer creation, checkout creation, and webhook registration. Keys are merchant-scoped. Replays preserve the original response; differing request bodies cannot reuse the same key. Resource IDs and credentials must belong to Rupay, not Stripe.

Explicit boundaries

  • mode: "subscription", recurring collection, saved payment methods, subscription CRUD, trials, proration, and cancellation of future charges are not implemented. Unsupported payment-affecting request fields are rejected.
  • Early manual purchases start at their own payment time; periods do not stack.
  • The Price checkout supports one item. Fixed-period access requires quantity 1.
  • Customer update/list/delete, Product/Price write APIs, Checkout list/line-item APIs and expansions are not part of this supported subset.
  • SDK webhook registration currently accepts only checkout.session.completed. Enforce expiry locally on entitlement reads; do not wait for an expiry event.
  • Card/eSewa/Khalti selection stays inside Rupay hosted checkout. Local rail names in payment_method_types are Rupay extensions, not Stripe payment method enums. This does not redirect Stripe.js/Elements to Rupay.
  • Provider invoice/payment-intent IDs are private. Corresponding SDK checkout fields remain null; a public Stripe Invoice/PaymentIntent API is not supplied.
  • Full Stripe field/default/error parity is not claimed. Native checkout lifetime and return-origin restrictions still apply. Hosted success/cancel URLs must be supplied for this subset.

Nepse Edge usage and validation

See Nepse Edge SDK integration for setup, plan mapping, checkout, and verified Premium synchronization.

apps/web/scripts/test-stripe-sdk-integration.ts runs the actual Stripe SDK through the actual API handlers against a dedicated local PostgreSQL database, with provider credentials disabled. It verifies migration/backfill, replay, merchant isolation, pagination, catalog price changes, checkout payment/expiry, webhook registration, signature validation, and outbox deduplication. It does not make live charges or deliver webhooks to external servers.

Remaining full compatibility work

The broader five-domain roadmap still requires Product/Price write endpoints, Customer CRUD, complete Checkout shapes/options, expansions and errors, independent Subscription/SubscriptionItem storage, invoice and payment-attempt lifecycles, confirmed recurring-provider support, retry/recovery and cancellation, and resource-correct invoice.* / customer.subscription.* events. These must be implemented and tested before advertising full Stripe API parity.

References: Stripe SDK configuration, Checkout, subscription lifecycle, webhook verification.

Refund and chargeback inquiries are made by email or phone to Rupay support. Refund creation/update/cancellation and dispute evidence/closure methods are unavailable through the API. See Refunds and disputes for supported read filters and the support workflow.