🟦JavaScript SDK

DevPayr Node.js SDK

The official Node.js SDK for DevPayr β€” a secure license enforcement and access control system for SaaS platforms, downloadable software, and digital tools.

This SDK allows you to:

  • πŸ” Validate license keys in real-time

  • πŸ“¦ Deliver encrypted injectables conditionally

  • 🌐 Enforce domain-based restrictions

  • πŸ’΅ Check project payment/subscription status

  • βš™οΈ Manage licenses, projects, and domain rules via API

Whether you're building a backend API, SaaS platform, CLI tool, or desktop software, DevPayr gives you the infrastructure to protect your code, enforce payments, and control usage β€” all without locking you into a specific framework.

✨ Features

  • βœ… License Validation β€” Verify license keys securely using DevPayr’s API.

  • πŸ” Runtime Enforcement β€” Automatically block access when license is invalid, unpaid, or expired.

  • πŸ“¦ Injectables Delivery β€” Distribute encrypted SDK assets (e.g. config, binaries, tokens) based on license.

  • 🌐 Domain Locking β€” Limit usage to specific domains or subdomains.

  • πŸ“‘ API Key & License Support β€” Works with both API Keys (project scoped) and License Keys (runtime scoped).

  • βš™οΈ Service-Oriented Architecture β€” Easily access all DevPayr APIs via built-in services.

  • 🧩 Custom Injectable Processor β€” Plug in your own logic to decrypt, transform, or store injectables.

  • ⚑ Lightweight & Framework-Agnostic β€” Works with Express, NestJS, CLI tools, and more.

πŸ“¦ Installation

Using npm:

Using yarn:

Requires Node.js v14+ and TypeScript (if using types).

πŸš€ Getting Started (QuickStart)

Start by bootstrapping DevPayr with your license key and configuration options:

If the license is invalid or payment status of the project is unpaid, DevPayr will:

  • Show a modal by default (customizable)

  • Or redirect / silently fail / log based on invalidBehavior

πŸ”’ Secure by Default – No valid license, no access.

βš™οΈ Configuration Options

You can customize DevPayr behavior by passing configuration options into the DevPayr.bootstrap() method. Some fields are required, while others have sensible defaults.

Required Config

Key
Type
Description

base_url

string

API base URL (e.g., https://api.devpayr.com/api/v1/)

secret

string

Secret used to decrypt injectables (AES-256-CBC)

Default Config (Optional)

Key
Type
Description

license

string

License key for validation (optional if using API key only)

api_key

string

API key for project-scoped or global API access

recheck

boolean

Whether to skip local cache and revalidate license (true by default)

action

string

Optional identifier to include in validation requests (e.g. 'boot', 'start')

timeout

number

Timeout for HTTP requests in ms (1000 default)

per_page

number

Used for paginated listing (e.g., licenses, domains)

injectables

boolean

Whether to fetch injectables during validation (true by default)

injectablesVerify

boolean

Verify HMAC signature of injectables (true by default)

injectablesPath

string

Directory to write injectables to (optional, otherwise temp path)

handleInjectables

boolean

If true, SDK will decrypt + store injectables automatically

injectablesProcessor

function

Custom handler function/class for injectables

invalidBehavior

string

'modal' (default), 'redirect', 'log', or 'silent'

redirectUrl

string

URL to redirect to if license is invalid (used if invalidBehavior = 'redirect')

customInvalidMessage

string

Message to display or log if license is invalid

customInvalidView

string

Custom HTML file to show for unlicensed copies

onReady

function

Callback executed after successful validation


You can override any of these when calling DevPayr.bootstrap({ ... }).

πŸ“¦ Service API Access

DevPayr provides access to powerful core services through static methods. Once the SDK is bootstrapped, you can use the following service accessors:

πŸ›  Available Service Methods

Each service exposes methods for interacting with your licensing and project environment:

Service
Methods

projects()

list(), create(), show(), update(), delete()

licenses()

list(), show(), create(), revoke(), reactivate(), delete()

domains()

list(), create(), show(), update(), delete()

injectables()

list(), create(), show(), update(), delete(), stream()

payments()

checkWithLicenseKey(), checkWithApiKey()

πŸ’‰ Injectables

Injectables are encrypted assets (scripts, config, JSON blobs, etc.) attached to your project via DevPayr. These are securely streamed at runtime and optionally auto-processed.

πŸ” How Injectables Are Fetched

If enabled in the config (injectables: true), injectables are fetched during DevPayr.bootstrap() using the license key. The endpoint returns a list of encrypted injectables tied to that license.

Each injectable contains:

  • name: The file or block name

  • content: AES-256-CBC encrypted and base64 encoded

  • signature: HMAC-SHA256 signature of the encrypted content

  • mode: append, prepend, replace, etc.

πŸ§ͺ How to Override Injectable Processing

You can define a custom processor to handle injectables however you like:

Alternatively, implement the full InjectableProcessorContract for structure and consistency.

πŸ” Signature Verification

By default, DevPayr verifies each injectable’s HMAC signature using the license key or provided secret. You can disable this by setting:

⚠️ Disabling verification may expose your application to tampered injectables. Use with caution.

πŸ” Crypto & Hash Utilities

DevPayr exposes powerful cryptographic helpers to handle encryption, decryption, hashing, and signature verification. These can be used independently in your application for custom workflows.

πŸ”„ CryptoHelper

This utility helps encrypt and decrypt strings using AES-256-CBC and is perfect for handling secure injectables.

πŸ”“ Decrypt Encrypted Content

  • Decrypts base64 strings formatted as iv::cipherText

  • Uses AES-256-CBC with SHA-256–derived keys

  • Throws meaningful exceptions on failure

Encrypt Plaintext Content

  • Returns base64-encoded iv::cipherText

  • Securely generates IV with crypto.randomBytes

πŸ”‘ HashHelper

Handles SHA-256 hashing and HMAC signature generation/verification. Ideal for verifying injectables or signing internal payloads.

πŸ“¦ Generate Hash or Signature

βœ… Verify Integrity

  • Uses constant-time comparison with crypto.timingSafeEqual

  • Supports secure hash comparison to prevent timing attacks

These tools are used internally by DevPayr to handle decrypting injectables, verifying payloads, and ensuring content hasn’t been tampered with. You can also use them for your own custom secure workflows.

🚨 Failure Modes & Error Handling

DevPayr handles errors and failed license checks gracefully. You can customize how the SDK behaves when validation fails or when an API call throws an error.

❌ Invalid License Handling

When a license is invalid, expired, or unauthorized, the SDK triggers the configured invalid behavior:

Available Modes

Mode
Description

modal

Displays a built-in HTML modal (default) with an error message.

redirect

Redirects the user to a custom URL.

log

Logs the error to the console using error_log (or console in JS).

silent

Does nothing. Use when you want to handle errors manually.

You can configure this using the invalidBehavior option:

🧰 Custom Modal or View

By default, the SDK shows a built-in modal with a styled message. You can replace it with a fully customized HTML file:

This file will be loaded and the {{message}} placeholder will be replaced with the failure message.

🧱 API Errors and Exceptions

The DevPayr SDK throws structured exceptions that help you understand what went wrong β€” whether it’s a failed license validation, a network error, or cryptographic issue. All custom errors extend the base DevPayrException.

You can import and catch any of these exceptions in your application:

⚠️ Base Exception: DevPayrException

All errors thrown by the SDK extend from this class:

πŸ” LicenseValidationException

Thrown when a license check fails or returns an invalid result.

πŸ’Ύ InjectableVerificationException

Thrown when fetched injectables fail HMAC verification, are tampered with, or cannot be parsed.

🌐 HttpRequestException

Thrown when a DevPayr API call fails meaningfully (e.g., 401, 403, 422). This exception includes status code and response body:

πŸ”’ CryptoException

Thrown when encryption or decryption fails (e.g., wrong AES key, corrupt payload):

βœ… Example Catching Block

πŸ§ͺ Examples

The SDK ships with a few ready-to-run examples inside the src/examples/ folder to help you quickly get started with common use cases.

βœ… validateLicense.ts

This example demonstrates how to bootstrap the SDK, validate a license key, and handle both success and failure cases:

All examples live under: src/examples/ and you can run them using npm run example ✳️ More examples coming soon:

  • Creating a new project

  • Managing injectables manually

  • Validating licenses inside CLI tools

  • Using a custom injectable processor

🧠 Advanced Usage

While most users will use DevPayr.bootstrap() for automatic license validation and injectable handling, the SDK offers full flexibility and composability. All core classes, services, utilities, and exceptions are directly exported and can be used independently.

πŸ“¦ Direct Service Access

If you're only interested in calling API services without runtime validation, you can instantiate them manually:

πŸ›  Use in CLI / Cron Jobs

You can safely use the SDK in headless or non-browser environments (e.g., CLI scripts) by setting:

This disables modal or redirect behavior for invalid licenses.

πŸ”„ Custom Injectable Processing

DevPayr supports encrypted injectables β€” small pieces of SDK-managed data (like scripts, configs, or logic) that are delivered after license validation. These are decrypted and can be automatically applied using a processor.

By default, if handleInjectables: true is set, DevPayr will attempt to apply injectables internally (e.g., print to console, save to memory). However, for full control over how these are handled β€” especially in environments like CLI tools, microservices, or embedded runtimes β€” you can override the injectablesProcessor option.


🧩 What is injectablesProcessor?

It's a function or class that gets invoked for each decrypted injectable, giving you the power to decide how to apply, transform, or persist the content.

Signature

Or, for class-based control:

πŸ“¦ InjectablePayload Structure

Every injectable is passed to your processor in the following format:

✍️ Writing a Custom Processor

Here’s an example processor that saves injectables as text files under a custom directory:

πŸš€ Enabling the Custom Processor

To use your custom processor, simply pass it during bootstrap:

πŸ›‘οΈ Security Recommendation

If you're processing any dynamic code or configuration, we strongly recommend enabling HMAC signature verification β€” which is enabled by default (injectablesVerify: true) β€” to protect against tampered or spoofed injectables.

When implementing a custom injectable handler, you are responsible for:

  • Decrypting the injectable content using the correct AES-256-CBC logic.

  • Verifying its integrity using HMAC-SHA256 signature verification.

DevPayr provides internal utilities to simplify this securely:

  • πŸ” CryptoHelper.decrypt(encryptedContent, secret) β€” Decrypts base64-encoded content in iv::cipherText format.

  • πŸ” HashHelper.verifySignature(content, secret, expectedSignature) β€” Verifies HMAC-SHA256 signatures in a timing-safe way.

Example usage inside a custom processor:

🧠 TypeScript Support

DevPayr is written entirely in TypeScript, offering first-class developer experience out of the box.

There is no need to install any additional typings β€” type declarations are automatically included via:

βœ… Benefits:

  • IntelliSense in modern editors (VSCode, WebStorm, etc.)

  • Strict typings on configuration options, service methods, and utility helpers

  • Easy-to-extend interfaces like InjectableProcessor and InjectablePayload

  • Robust error type detection (DevPayrException, LicenseValidationException, etc.)

πŸ” Example with Type Inference:

Last updated