@payotex.com/node 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,184 @@
1
+ # @payotex/node
2
+
3
+ Server-side SDK for Payotex crypto payment processing. Accept cryptocurrency payments with cross-chain swap support.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @payotex/node
9
+ ```
10
+
11
+ ## Requirements
12
+
13
+ - Node.js 18+ (uses native `fetch`)
14
+ - Zero runtime dependencies
15
+
16
+ ## Quick Start
17
+
18
+ ```typescript
19
+ import { Payotex } from '@payotex/node';
20
+
21
+ const payotex = new Payotex({
22
+ secretKey: 'sk_live_your_secret_key_here',
23
+ });
24
+
25
+ // Create a checkout session
26
+ const session = await payotex.checkout.create({
27
+ amount: '49.99',
28
+ currency: 'USD',
29
+ });
30
+
31
+ console.log(session.sessionId); // Redirect user to pay
32
+ ```
33
+
34
+ ## API Reference
35
+
36
+ ### Constructor
37
+
38
+ ```typescript
39
+ const payotex = new Payotex({
40
+ secretKey: 'sk_live_...', // Required. Your secret API key.
41
+ baseUrl: 'https://payotex.com', // Optional. Defaults to https://payotex.com
42
+ });
43
+ ```
44
+
45
+ ### Keys
46
+
47
+ #### `payotex.keys.create(params)`
48
+
49
+ Create a new API key pair for a merchant.
50
+
51
+ ```typescript
52
+ const keys = await payotex.keys.create({
53
+ payoutChain: 'ETH',
54
+ payoutToken: 'ETH.USDC-0XA0B86991C6218B36C1D19D4A2E9EB0CE3606EB48',
55
+ payoutAddress: '0xYourAddress...',
56
+ // Optional secondary payout
57
+ payoutChain2: 'BTC',
58
+ payoutToken2: 'BTC.BTC',
59
+ payoutAddress2: 'bc1q...',
60
+ label: 'My Store',
61
+ });
62
+
63
+ console.log(keys.secretKey); // sk_live_...
64
+ console.log(keys.publishableKey); // pk_live_...
65
+ ```
66
+
67
+ #### `payotex.keys.verify()`
68
+
69
+ Verify the current API key and get merchant configuration.
70
+
71
+ ```typescript
72
+ const info = await payotex.keys.verify();
73
+ console.log(info.payoutChain); // "ETH"
74
+ console.log(info.configValid); // true
75
+ console.log(info.isActive); // true
76
+ ```
77
+
78
+ ### Checkout
79
+
80
+ #### `payotex.checkout.create(params)`
81
+
82
+ Create a new checkout session.
83
+
84
+ ```typescript
85
+ const session = await payotex.checkout.create({
86
+ amount: '100.00', // Required. Amount as string or number.
87
+ currency: 'USD', // Required. USD, EUR, GBP, or crypto asset.
88
+ metadata: { // Optional. Custom metadata (max 4096 chars).
89
+ orderId: 'order-123',
90
+ customerId: 'cust-456',
91
+ },
92
+ expiresIn: 60, // Optional. Minutes until expiry (5-1440, default 30).
93
+ });
94
+
95
+ console.log(session.sessionId); // Use to track payment
96
+ console.log(session.status); // "pending"
97
+ ```
98
+
99
+ ### Sessions
100
+
101
+ #### `payotex.sessions.get(sessionId)`
102
+
103
+ Get details for a checkout session. This is a public endpoint (no auth required).
104
+
105
+ ```typescript
106
+ const details = await payotex.sessions.get('session-id-here');
107
+ console.log(details.status); // "pending" | "paid" | "expired"
108
+ console.log(details.payotex_fee_percent);
109
+ ```
110
+
111
+ #### `payotex.sessions.getAssets(sessionId)`
112
+
113
+ Get available payment assets for a session.
114
+
115
+ ```typescript
116
+ const assets = await payotex.sessions.getAssets('session-id-here');
117
+ assets.forEach(asset => {
118
+ console.log(`${asset.symbol} on ${asset.chain}`);
119
+ });
120
+ ```
121
+
122
+ #### `payotex.sessions.createQuote(sessionId, params)`
123
+
124
+ Create a swap quote for a session.
125
+
126
+ ```typescript
127
+ const quote = await payotex.sessions.createQuote('session-id-here', {
128
+ fromAsset: 'BTC.BTC',
129
+ });
130
+
131
+ console.log(quote.inbound_address); // Where to send funds
132
+ console.log(quote.expected_amount_in); // Amount to send
133
+ console.log(quote.expected_amount_out); // Amount merchant receives
134
+ console.log(quote.memo); // Include in transaction if present
135
+ ```
136
+
137
+ ## Error Handling
138
+
139
+ All methods throw on errors. Errors from the API include a `status` code and `response` object.
140
+
141
+ ```typescript
142
+ try {
143
+ const session = await payotex.checkout.create({
144
+ amount: '100',
145
+ currency: 'USD',
146
+ });
147
+ } catch (err) {
148
+ console.error(err.message); // Human-readable error
149
+ console.error(err.status); // HTTP status code (e.g., 400, 401)
150
+ console.error(err.response); // Full API response body
151
+ }
152
+ ```
153
+
154
+ ## TypeScript
155
+
156
+ All types are exported from the main entry point:
157
+
158
+ ```typescript
159
+ import {
160
+ Payotex,
161
+ PayotexConfig,
162
+ CreateKeysRequest,
163
+ CreateKeysResponse,
164
+ VerifyKeyResponse,
165
+ CreateCheckoutSessionRequest,
166
+ CheckoutSession,
167
+ SessionDetails,
168
+ SessionAsset,
169
+ CreateQuoteRequest,
170
+ SessionQuote,
171
+ PayotexError,
172
+ } from '@payotex/node';
173
+ ```
174
+
175
+ ## Security Best Practices
176
+
177
+ - **Never expose your secret key (`sk_live_`) client-side.** Use it only in server-side code.
178
+ - Use the publishable key (`pk_live_`) for client-side integrations.
179
+ - Store your secret key in environment variables, never in source code.
180
+ - The SDK validates key format on initialization and rejects publishable keys to prevent misuse.
181
+
182
+ ## License
183
+
184
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // packages/node/src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ Payotex: () => Payotex
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // packages/node/src/client.ts
28
+ var DEFAULT_BASE_URL = "https://payotex.com";
29
+ var Payotex = class {
30
+ secretKey;
31
+ baseUrl;
32
+ constructor(config) {
33
+ if (!config.secretKey) {
34
+ throw new Error("Payotex: secretKey is required");
35
+ }
36
+ if (!config.secretKey.startsWith("sk_live_")) {
37
+ throw new Error(
38
+ "Payotex: Invalid key format. Use your secret key (sk_live_...). Never use publishable keys (pk_live_) server-side."
39
+ );
40
+ }
41
+ this.secretKey = config.secretKey;
42
+ this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
43
+ }
44
+ async request(method, path, body, auth = true) {
45
+ const headers = {
46
+ "Content-Type": "application/json"
47
+ };
48
+ if (auth) {
49
+ headers["Authorization"] = `Bearer ${this.secretKey}`;
50
+ }
51
+ const url = `${this.baseUrl}${path}`;
52
+ const options = { method, headers };
53
+ if (body && (method === "POST" || method === "PUT" || method === "PATCH")) {
54
+ options.body = JSON.stringify(body);
55
+ }
56
+ const response = await fetch(url, options);
57
+ const data = await response.json();
58
+ if (!response.ok) {
59
+ const err = new Error(data.error || `HTTP ${response.status}`);
60
+ err.status = response.status;
61
+ err.response = data;
62
+ throw err;
63
+ }
64
+ return data;
65
+ }
66
+ keys = {
67
+ create: async (params) => {
68
+ if (!params.payoutChain || !params.payoutToken || !params.payoutAddress) {
69
+ throw new Error(
70
+ "payoutChain, payoutToken, and payoutAddress are required"
71
+ );
72
+ }
73
+ return this.request(
74
+ "POST",
75
+ "/api/merchant/keys",
76
+ params
77
+ );
78
+ },
79
+ verify: async () => {
80
+ return this.request("GET", "/api/merchant/keys/verify");
81
+ }
82
+ };
83
+ checkout = {
84
+ create: async (params) => {
85
+ if (!params.amount) {
86
+ throw new Error("amount is required");
87
+ }
88
+ if (!params.currency) {
89
+ throw new Error("currency is required");
90
+ }
91
+ const amount = typeof params.amount === "number" ? params.amount.toString() : params.amount;
92
+ if (isNaN(parseFloat(amount)) || parseFloat(amount) <= 0) {
93
+ throw new Error("amount must be a positive number");
94
+ }
95
+ return this.request("POST", "/api/merchant/checkout", {
96
+ ...params,
97
+ amount
98
+ });
99
+ }
100
+ };
101
+ sessions = {
102
+ get: async (sessionId) => {
103
+ if (!sessionId) throw new Error("sessionId is required");
104
+ return this.request(
105
+ "GET",
106
+ `/api/merchant/session/${encodeURIComponent(sessionId)}`,
107
+ void 0,
108
+ false
109
+ );
110
+ },
111
+ getAssets: async (sessionId) => {
112
+ if (!sessionId) throw new Error("sessionId is required");
113
+ return this.request(
114
+ "GET",
115
+ `/api/merchant/session/${encodeURIComponent(sessionId)}/assets`,
116
+ void 0,
117
+ false
118
+ );
119
+ },
120
+ createQuote: async (sessionId, params) => {
121
+ if (!sessionId) throw new Error("sessionId is required");
122
+ if (!params.fromAsset) throw new Error("fromAsset is required");
123
+ return this.request(
124
+ "POST",
125
+ `/api/merchant/session/${encodeURIComponent(sessionId)}/quote`,
126
+ params,
127
+ false
128
+ );
129
+ }
130
+ };
131
+ };
132
+ // Annotate the CommonJS export names for ESM import in node:
133
+ 0 && (module.exports = {
134
+ Payotex
135
+ });
@@ -0,0 +1,120 @@
1
+ interface PayotexConfig {
2
+ secretKey: string;
3
+ baseUrl?: string;
4
+ }
5
+ interface CreateKeysRequest {
6
+ payoutChain: string;
7
+ payoutToken: string;
8
+ payoutAddress: string;
9
+ payoutChain2?: string;
10
+ payoutToken2?: string;
11
+ payoutAddress2?: string;
12
+ label?: string;
13
+ }
14
+ interface CreateKeysResponse {
15
+ id: string;
16
+ secretKey: string;
17
+ publishableKey: string;
18
+ secretKeyPrefix: string;
19
+ publishableKeyPrefix: string;
20
+ payoutChain: string;
21
+ payoutToken: string;
22
+ payoutAddress: string;
23
+ payoutChain2?: string;
24
+ payoutToken2?: string;
25
+ payoutAddress2?: string;
26
+ configHash: string;
27
+ message: string;
28
+ }
29
+ interface VerifyKeyResponse {
30
+ id: string;
31
+ payoutChain: string;
32
+ payoutToken: string;
33
+ payoutAddress: string;
34
+ configHash: string;
35
+ configValid: boolean;
36
+ isActive: boolean;
37
+ createdAt: string;
38
+ }
39
+ interface CreateCheckoutSessionRequest {
40
+ amount: string | number;
41
+ currency: string;
42
+ metadata?: Record<string, any>;
43
+ expiresIn?: number;
44
+ }
45
+ interface CheckoutSession {
46
+ sessionId: string;
47
+ amount: string;
48
+ currency: string;
49
+ status: "pending" | "paid" | "expired";
50
+ expiresAt: string;
51
+ }
52
+ interface SessionDetails {
53
+ id: string;
54
+ amount: string;
55
+ currency: string;
56
+ status: "pending" | "paid" | "expired";
57
+ expiresAt: string;
58
+ payoutChain: string;
59
+ payoutChain2?: string;
60
+ payoutToken?: string;
61
+ payoutToken2?: string;
62
+ payotex_fee_percent: number;
63
+ }
64
+ interface SessionAsset {
65
+ chain: string;
66
+ asset: string;
67
+ symbol: string;
68
+ name: string;
69
+ decimals: number;
70
+ priceUsd?: number;
71
+ }
72
+ interface CreateQuoteRequest {
73
+ fromAsset: string;
74
+ }
75
+ interface SessionQuote {
76
+ inbound_address: string;
77
+ expected_amount_out: string;
78
+ expected_amount_in: string;
79
+ fees: {
80
+ total: string;
81
+ slippage_bps: number;
82
+ };
83
+ payotex_fee_percent: number;
84
+ expiry: number;
85
+ payout_chain: string;
86
+ payout_address: string;
87
+ from_asset: string;
88
+ to_asset: string;
89
+ session_id: string;
90
+ session_amount: string;
91
+ session_currency: string;
92
+ memo?: string;
93
+ total_swap_seconds?: number;
94
+ router?: string;
95
+ }
96
+ interface PayotexError {
97
+ error: string;
98
+ status: number;
99
+ }
100
+
101
+ declare class Payotex {
102
+ private secretKey;
103
+ private baseUrl;
104
+ constructor(config: PayotexConfig);
105
+ private request;
106
+ keys: {
107
+ create: (params: CreateKeysRequest) => Promise<CreateKeysResponse>;
108
+ verify: () => Promise<VerifyKeyResponse>;
109
+ };
110
+ checkout: {
111
+ create: (params: CreateCheckoutSessionRequest) => Promise<CheckoutSession>;
112
+ };
113
+ sessions: {
114
+ get: (sessionId: string) => Promise<SessionDetails>;
115
+ getAssets: (sessionId: string) => Promise<SessionAsset[]>;
116
+ createQuote: (sessionId: string, params: CreateQuoteRequest) => Promise<SessionQuote>;
117
+ };
118
+ }
119
+
120
+ export { type CheckoutSession, type CreateCheckoutSessionRequest, type CreateKeysRequest, type CreateKeysResponse, type CreateQuoteRequest, Payotex, type PayotexConfig, type PayotexError, type SessionAsset, type SessionDetails, type SessionQuote, type VerifyKeyResponse };
@@ -0,0 +1,120 @@
1
+ interface PayotexConfig {
2
+ secretKey: string;
3
+ baseUrl?: string;
4
+ }
5
+ interface CreateKeysRequest {
6
+ payoutChain: string;
7
+ payoutToken: string;
8
+ payoutAddress: string;
9
+ payoutChain2?: string;
10
+ payoutToken2?: string;
11
+ payoutAddress2?: string;
12
+ label?: string;
13
+ }
14
+ interface CreateKeysResponse {
15
+ id: string;
16
+ secretKey: string;
17
+ publishableKey: string;
18
+ secretKeyPrefix: string;
19
+ publishableKeyPrefix: string;
20
+ payoutChain: string;
21
+ payoutToken: string;
22
+ payoutAddress: string;
23
+ payoutChain2?: string;
24
+ payoutToken2?: string;
25
+ payoutAddress2?: string;
26
+ configHash: string;
27
+ message: string;
28
+ }
29
+ interface VerifyKeyResponse {
30
+ id: string;
31
+ payoutChain: string;
32
+ payoutToken: string;
33
+ payoutAddress: string;
34
+ configHash: string;
35
+ configValid: boolean;
36
+ isActive: boolean;
37
+ createdAt: string;
38
+ }
39
+ interface CreateCheckoutSessionRequest {
40
+ amount: string | number;
41
+ currency: string;
42
+ metadata?: Record<string, any>;
43
+ expiresIn?: number;
44
+ }
45
+ interface CheckoutSession {
46
+ sessionId: string;
47
+ amount: string;
48
+ currency: string;
49
+ status: "pending" | "paid" | "expired";
50
+ expiresAt: string;
51
+ }
52
+ interface SessionDetails {
53
+ id: string;
54
+ amount: string;
55
+ currency: string;
56
+ status: "pending" | "paid" | "expired";
57
+ expiresAt: string;
58
+ payoutChain: string;
59
+ payoutChain2?: string;
60
+ payoutToken?: string;
61
+ payoutToken2?: string;
62
+ payotex_fee_percent: number;
63
+ }
64
+ interface SessionAsset {
65
+ chain: string;
66
+ asset: string;
67
+ symbol: string;
68
+ name: string;
69
+ decimals: number;
70
+ priceUsd?: number;
71
+ }
72
+ interface CreateQuoteRequest {
73
+ fromAsset: string;
74
+ }
75
+ interface SessionQuote {
76
+ inbound_address: string;
77
+ expected_amount_out: string;
78
+ expected_amount_in: string;
79
+ fees: {
80
+ total: string;
81
+ slippage_bps: number;
82
+ };
83
+ payotex_fee_percent: number;
84
+ expiry: number;
85
+ payout_chain: string;
86
+ payout_address: string;
87
+ from_asset: string;
88
+ to_asset: string;
89
+ session_id: string;
90
+ session_amount: string;
91
+ session_currency: string;
92
+ memo?: string;
93
+ total_swap_seconds?: number;
94
+ router?: string;
95
+ }
96
+ interface PayotexError {
97
+ error: string;
98
+ status: number;
99
+ }
100
+
101
+ declare class Payotex {
102
+ private secretKey;
103
+ private baseUrl;
104
+ constructor(config: PayotexConfig);
105
+ private request;
106
+ keys: {
107
+ create: (params: CreateKeysRequest) => Promise<CreateKeysResponse>;
108
+ verify: () => Promise<VerifyKeyResponse>;
109
+ };
110
+ checkout: {
111
+ create: (params: CreateCheckoutSessionRequest) => Promise<CheckoutSession>;
112
+ };
113
+ sessions: {
114
+ get: (sessionId: string) => Promise<SessionDetails>;
115
+ getAssets: (sessionId: string) => Promise<SessionAsset[]>;
116
+ createQuote: (sessionId: string, params: CreateQuoteRequest) => Promise<SessionQuote>;
117
+ };
118
+ }
119
+
120
+ export { type CheckoutSession, type CreateCheckoutSessionRequest, type CreateKeysRequest, type CreateKeysResponse, type CreateQuoteRequest, Payotex, type PayotexConfig, type PayotexError, type SessionAsset, type SessionDetails, type SessionQuote, type VerifyKeyResponse };
package/dist/index.js ADDED
@@ -0,0 +1,108 @@
1
+ // packages/node/src/client.ts
2
+ var DEFAULT_BASE_URL = "https://payotex.com";
3
+ var Payotex = class {
4
+ secretKey;
5
+ baseUrl;
6
+ constructor(config) {
7
+ if (!config.secretKey) {
8
+ throw new Error("Payotex: secretKey is required");
9
+ }
10
+ if (!config.secretKey.startsWith("sk_live_")) {
11
+ throw new Error(
12
+ "Payotex: Invalid key format. Use your secret key (sk_live_...). Never use publishable keys (pk_live_) server-side."
13
+ );
14
+ }
15
+ this.secretKey = config.secretKey;
16
+ this.baseUrl = (config.baseUrl || DEFAULT_BASE_URL).replace(/\/+$/, "");
17
+ }
18
+ async request(method, path, body, auth = true) {
19
+ const headers = {
20
+ "Content-Type": "application/json"
21
+ };
22
+ if (auth) {
23
+ headers["Authorization"] = `Bearer ${this.secretKey}`;
24
+ }
25
+ const url = `${this.baseUrl}${path}`;
26
+ const options = { method, headers };
27
+ if (body && (method === "POST" || method === "PUT" || method === "PATCH")) {
28
+ options.body = JSON.stringify(body);
29
+ }
30
+ const response = await fetch(url, options);
31
+ const data = await response.json();
32
+ if (!response.ok) {
33
+ const err = new Error(data.error || `HTTP ${response.status}`);
34
+ err.status = response.status;
35
+ err.response = data;
36
+ throw err;
37
+ }
38
+ return data;
39
+ }
40
+ keys = {
41
+ create: async (params) => {
42
+ if (!params.payoutChain || !params.payoutToken || !params.payoutAddress) {
43
+ throw new Error(
44
+ "payoutChain, payoutToken, and payoutAddress are required"
45
+ );
46
+ }
47
+ return this.request(
48
+ "POST",
49
+ "/api/merchant/keys",
50
+ params
51
+ );
52
+ },
53
+ verify: async () => {
54
+ return this.request("GET", "/api/merchant/keys/verify");
55
+ }
56
+ };
57
+ checkout = {
58
+ create: async (params) => {
59
+ if (!params.amount) {
60
+ throw new Error("amount is required");
61
+ }
62
+ if (!params.currency) {
63
+ throw new Error("currency is required");
64
+ }
65
+ const amount = typeof params.amount === "number" ? params.amount.toString() : params.amount;
66
+ if (isNaN(parseFloat(amount)) || parseFloat(amount) <= 0) {
67
+ throw new Error("amount must be a positive number");
68
+ }
69
+ return this.request("POST", "/api/merchant/checkout", {
70
+ ...params,
71
+ amount
72
+ });
73
+ }
74
+ };
75
+ sessions = {
76
+ get: async (sessionId) => {
77
+ if (!sessionId) throw new Error("sessionId is required");
78
+ return this.request(
79
+ "GET",
80
+ `/api/merchant/session/${encodeURIComponent(sessionId)}`,
81
+ void 0,
82
+ false
83
+ );
84
+ },
85
+ getAssets: async (sessionId) => {
86
+ if (!sessionId) throw new Error("sessionId is required");
87
+ return this.request(
88
+ "GET",
89
+ `/api/merchant/session/${encodeURIComponent(sessionId)}/assets`,
90
+ void 0,
91
+ false
92
+ );
93
+ },
94
+ createQuote: async (sessionId, params) => {
95
+ if (!sessionId) throw new Error("sessionId is required");
96
+ if (!params.fromAsset) throw new Error("fromAsset is required");
97
+ return this.request(
98
+ "POST",
99
+ `/api/merchant/session/${encodeURIComponent(sessionId)}/quote`,
100
+ params,
101
+ false
102
+ );
103
+ }
104
+ };
105
+ };
106
+ export {
107
+ Payotex
108
+ };
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@payotex.com/node",
3
+ "version": "1.0.0",
4
+ "description": "Server-side SDK for Payotex crypto payment processing",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.mjs",
12
+ "require": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": ["dist"],
16
+ "scripts": {
17
+ "build": "tsup src/index.ts --format cjs,esm --dts --clean",
18
+ "test": "node --experimental-vm-modules ../../node_modules/.bin/vitest run --config vitest.config.ts"
19
+ },
20
+ "keywords": ["payotex", "crypto", "payments", "checkout", "cross-chain", "swap", "bitcoin", "ethereum"],
21
+ "license": "MIT",
22
+ "engines": {
23
+ "node": ">=18"
24
+ },
25
+ "devDependencies": {
26
+ "tsup": "^8.0.0",
27
+ "typescript": "^5.0.0",
28
+ "vitest": "^1.0.0"
29
+ }
30
+ }