Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [2.0.1] - 2026-02-06

### Fixed

- `createCharge()` now returns consistent V2 response format matching `chargeInfo()`
- `amount` → `price`
- `lightning_invoice` → `lightning`
- Timestamps now ISO 8601 format
- `chargeInfo()` now returns all fields from V1 (`callback_url`, `success_url`, `notif_email`, `uri`)
- Consolidated `OpenNodeCharge` type - removed separate `OpenNodeChargeV2`

### Changed

- `chargeInfo()` is now a superset of `createCharge()` (contains all fields plus extras like `fee`, `net_fiat_value`, etc.)

## [2.0.0] - 2026-02-05

### ⚠️ BREAKING CHANGES
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"opennode"
],
"main": "dist/index.js",
"version": "2.0.0",
"version": "2.0.1",
"dependencies": {
"axios": "^1.3.4"
},
Expand All @@ -41,5 +41,6 @@
"test": "pnpm build && mocha",
"build": "rm -rf dist/ && tsc",
"prepack": "pnpm build"
}
},
"packageManager": "pnpm@8.14.1+sha512.856c4ecd97c5d3f30354ebc373cd32fb37274295c489db2d0f613a1e60f010cadfbb15036d525f3a06dec1897e4219b3c4f6d3be8f2f62fb0a366bee6aaa7533"
}
17 changes: 15 additions & 2 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,23 @@ export class OpenNodeClient {
}

async createCharge(charge: OpenNodeChargeRequest): Promise<OpenNodeCharge> {
return this.instanceV1.post(`/charges`, charge);
const response: any = await this.instanceV1.post(`/charges`, charge);

// Remove V1-specific fields and transform to consistent format
const { amount, lightning_invoice, created_at, ...rest } = response;

return {
...rest,
price: amount,
created_at: new Date(created_at * 1000).toISOString(),
lightning: lightning_invoice ? {
payreq: lightning_invoice.payreq,
expires_at: new Date(lightning_invoice.expires_at * 1000).toISOString(),
} : null,
};
}

async chargeInfo(id: string): Promise<v2.OpenNodeChargeV2> {
async chargeInfo(id: string): Promise<OpenNodeCharge> {
return this.instanceV2.get(`/charges/${id}`);
}

Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export function createCharge(
return instance.createCharge(charge);
}

export function chargeInfo(id: string): Promise<v2.OpenNodeChargeV2> {
export function chargeInfo(id: string): Promise<v1.OpenNodeCharge> {
return instance.chargeInfo(id);
}

Expand Down
65 changes: 56 additions & 9 deletions src/types/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,23 +64,70 @@ export interface OpenNodeChargeRequest {

export type OpenNodeChargeWebhook = { hashed_order: string } & OpenNodeCharge;

export interface OpenNodeLightningInvoice {
id?: string;
status?: string;
price?: number;
payreq: string;
created_at?: string;
expires_at: string;
settled_at?: string | null;
checkout_id?: string;
}

export interface OpenNodeCharge {
/** Unique charge identifier */
id: string;
/** Charge description provided at creation */
description: string;
amount: number;
missing_amt: number;
/** Amount in satoshis */
price: number;
/** Charge status: unpaid, paid, processing, underpaid, refunded, expired, failed */
status: string;
/** ISO timestamp when charge was created */
created_at: string;
/** ISO timestamp when charge expires */
expires_at?: string;
/** OpenNode fee in satoshis */
fee?: number;
/** Value in merchant's account currency */
fiat_value: number;
/** Original charge amount in the currency specified at creation */
source_fiat_value: number;
/** Currency code specified when creating the charge */
currency: string;
created_at: number;
order_id: string;
address: string;
metadata?: OpenNodeChargeMetadata;
expires_at?: string;
/** Whether the charge is configured to auto-settle to fiat */
auto_settle?: boolean;
chain_invoice?: OpenNodeOnchainInvoice;
transactions?: OpenNodeChargeTransaction[];
/** Optional notes attached to the charge */
notes?: string | null;
/** Merchant's order ID if provided */
order_id?: string | null;
/** On-chain payment details */
onchain?: unknown[];
/** Lightning invoice details */
lightning?: OpenNodeLightningInvoice | null;
/** Custom metadata provided at charge creation */
metadata?: Record<string, unknown>;
/** Bitcoin address for on-chain payments */
address: string;
/** Whether the charge was exchanged to fiat */
exchanged?: boolean;
/** Net fiat value after fees */
net_fiat_value?: number;
/** Remaining amount in satoshis (for underpaid charges) */
missing_amt?: number;
/** ISO timestamp when charge was settled */
settled_at?: string | null;
/** Payment method used: lightning, onchain, or null if unpaid */
payment_method?: string | null;
/** Time-to-live in minutes */
ttl?: number;
/** Whether description hash was used */
desc_hash?: boolean;
/** URL to the hosted checkout page */
hosted_checkout_url?: string;
/** Customer site ID if applicable */
customer_site_id?: string | null;
}

export interface OpenNodeOnchainInvoice {
Expand Down
65 changes: 0 additions & 65 deletions src/types/v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,68 +167,3 @@ export interface OpenNodeLnURLWithdrawalRequest {
expiry_date?: number;
}

export interface OpenNodeLightningInvoice {
id: string;
status: string;
price: number;
payreq: string;
created_at: string;
expires_at: string;
settled_at: string | null;
checkout_id: string;
}

export interface OpenNodeChargeV2 {
/** Unique charge identifier */
id: string;
/** Charge description provided at creation */
description: string;
/** Amount in satoshis */
price: number;
/** Charge status: unpaid, paid, processing, underpaid, refunded, expired, failed */
status: string;
/** ISO timestamp when charge was created */
created_at: string;
/** ISO timestamp when charge expires and we stop monitoring for payments */
expires_at: string;
/** OpenNode fee in satoshis */
fee: number;
/** Value in merchant's account currency (e.g., if account is USD, this is in USD) */
fiat_value: number;
/** Original charge amount in the currency specified at creation */
source_fiat_value: number;
/** Currency code specified when creating the charge (e.g., USD, EUR) */
currency: string;
/** Whether the charge is configured to auto-settle to fiat */
auto_settle: boolean;
/** Optional notes attached to the charge */
notes: string | null;
/** Merchant's order ID if provided */
order_id: string | null;
/** On-chain payment details */
onchain: unknown[];
/** Lightning invoice details */
lightning: OpenNodeLightningInvoice | null;
/** Custom metadata provided at charge creation */
metadata: Record<string, unknown>;
/** Bitcoin address for on-chain payments */
address: string;
/** Whether the charge was exchanged to fiat */
exchanged: boolean;
/** Net fiat value after fees */
net_fiat_value: number;
/** Remaining amount in satoshis (for underpaid charges) */
missing_amt: number;
/** ISO timestamp when charge was settled, null if not yet settled */
settled_at: string | null;
/** Payment method used: lightning, onchain, or null if unpaid */
payment_method: string | null;
/** Time-to-live in minutes */
ttl: number;
/** Whether description hash was used for the lightning invoice */
desc_hash: boolean;
/** URL to the hosted checkout page */
hosted_checkout_url: string;
/** Customer site ID if applicable */
customer_site_id: string | null;
}