@orvion/n8n-nodes-orvion 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Orvion
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,316 @@
1
+ # n8n-nodes-orvion
2
+
3
+ This is an n8n community node for [Orvion](https://orvion.sh) - the payment orchestration platform for AI agents.
4
+
5
+ Create payment charges and receive `checkout_url` for payment collection. Perfect for:
6
+
7
+ - AI agent workflows that need to charge for services
8
+ - Automated billing flows
9
+ - Pay-per-use API integrations
10
+ - Crypto/stablecoin payment collection
11
+
12
+ ## Installation
13
+
14
+ ### In n8n (Recommended)
15
+
16
+ 1. Go to **Settings** > **Community Nodes**
17
+ 2. Click **Install**
18
+ 3. Enter `n8n-nodes-orvion`
19
+ 4. Click **Install**
20
+
21
+ ### Manual Installation
22
+
23
+ ```bash
24
+ npm install n8n-nodes-orvion
25
+ ```
26
+
27
+ ## Prerequisites
28
+
29
+ 1. An Orvion account ([sign up here](https://orvion.sh))
30
+ 2. An API key from your Orvion dashboard (Settings > API Keys)
31
+
32
+ ## Credentials
33
+
34
+ 1. In n8n, go to **Credentials** > **New**
35
+ 2. Search for "Orvion API"
36
+ 3. Enter your API key
37
+ 4. (Optional) Override the Base URL if testing with a local backend instance
38
+
39
+ ## Nodes
40
+
41
+ This package provides **2 nodes**:
42
+
43
+ | Node | Type | Description |
44
+ |------|------|-------------|
45
+ | **Orvion** | Action | Create charges with optional "Wait for Payment" feature |
46
+ | **Orvion Trigger** | Trigger | Receive webhook events when payments succeed/fail |
47
+
48
+ ---
49
+
50
+ ## Orvion Node (Action)
51
+
52
+ ### Wait for Payment (Recommended)
53
+
54
+ The **Wait for Payment** feature allows you to create a charge and automatically pause the workflow until the customer pays. This enables a single-workflow pattern where:
55
+
56
+ 1. Your workflow creates a charge
57
+ 2. Workflow pauses (status: "Waiting...")
58
+ 3. Customer pays on the checkout page
59
+ 4. Workflow resumes automatically with payment data
60
+ 5. Your business logic continues
61
+
62
+ **Enable "Wait for Payment":**
63
+
64
+ | Field | Required | Description |
65
+ |-------|----------|-------------|
66
+ | **Wait for Payment** | No | Toggle ON to pause workflow until payment completes |
67
+ | Amount | Yes | Charge amount (e.g., 0.50) |
68
+ | Currency | Yes | Currency code (default: USDC) |
69
+ | Flow Slug | No | Billing flow for x402 config |
70
+ | Customer Ref | No | Your customer identifier |
71
+ | Resource Ref | No | Resource being purchased |
72
+ | **Notify Email** | Yes | Email to send checkout URL to |
73
+
74
+ **Output after payment:**
75
+
76
+ ```json
77
+ {
78
+ "id": "550e8400-e29b-41d4-a716-446655440000",
79
+ "charge_id": "550e8400-e29b-41d4-a716-446655440000",
80
+ "status": "succeeded",
81
+ "is_paid": true,
82
+ "is_pending": false,
83
+ "is_failed": false,
84
+ "amount": "0.50",
85
+ "currency": "USDC",
86
+ "tx_hash": "5nwz8X3Lgf8dqwV8EKQ2...",
87
+ "payer_address": "0x1234...5678",
88
+ "confirmed_at": "2025-01-08T12:00:00Z"
89
+ }
90
+ ```
91
+
92
+ ### Create Charge (Without Wait)
93
+
94
+ If "Wait for Payment" is OFF, the node creates a charge and immediately returns with the `checkout_url`. Use this when you prefer the 2-workflow pattern with `Orvion Trigger`.
95
+
96
+ **Output (immediate):**
97
+
98
+ ```json
99
+ {
100
+ "id": "550e8400-e29b-41d4-a716-446655440000",
101
+ "status": "pending",
102
+ "amount": "0.50",
103
+ "currency": "USDC",
104
+ "checkout_url": "https://pay.orvion.sh/checkout/550e8400-..."
105
+ }
106
+ ```
107
+
108
+ #### 2. Check Payment
109
+
110
+ Check payment status with optional reference validation. Returns `is_paid` boolean for easy workflow branching.
111
+
112
+ | Field | Required | Description |
113
+ |-------|----------|-------------|
114
+ | Charge ID | Yes | The charge ID to check (use `{{ $json.charge_id }}` from Create Charge) |
115
+ | Expected Customer Ref | No | Optional: Validate customer reference matches |
116
+ | Expected Resource Ref | No | Optional: Validate resource reference matches |
117
+
118
+ **Output:**
119
+
120
+ ```json
121
+ {
122
+ "id": "550e8400-e29b-41d4-a716-446655440000",
123
+ "status": "succeeded",
124
+ "is_paid": true,
125
+ "is_terminal": true,
126
+ "amount": "0.50",
127
+ "currency": "USDC",
128
+ "checkout_url": "https://pay.orvion.sh/checkout/550e8400-...",
129
+ "tx_hash": "5nwz8X3Lgf8dqwV8EKQ2...",
130
+ "payer_address": "0x1234...5678",
131
+ "confirmed_at": "2025-01-08T12:00:00Z",
132
+ "validation": {
133
+ "valid": true,
134
+ "customer_ref_match": true,
135
+ "resource_ref_match": true
136
+ }
137
+ }
138
+ ```
139
+
140
+ **Helper booleans:**
141
+ - `is_paid`: `true` if status is `succeeded`
142
+ - `is_terminal`: `true` if status is `succeeded`, `failed`, or `expired` (no more polling needed)
143
+
144
+ #### 3. Share Checkout URL
145
+
146
+ Send the checkout URL via email to a customer.
147
+
148
+ | Field | Required | Description |
149
+ |-------|----------|-------------|
150
+ | Charge ID | Yes | The charge ID to share (use `{{ $json.charge_id }}` from Create Charge) |
151
+ | Recipient Email | Yes | Customer's email address |
152
+
153
+ ---
154
+
155
+ ## Orvion Trigger Node (NEW)
156
+
157
+ The **Orvion Trigger** node automatically registers a webhook endpoint with Orvion and triggers your workflow when payment events occur.
158
+
159
+ ### Events
160
+
161
+ | Event | Description |
162
+ |-------|-------------|
163
+ | Payment Succeeded | Triggered when payment is confirmed on blockchain |
164
+ | Payment Failed | Triggered when payment fails |
165
+ | Payment Cancelled | Triggered when payment is cancelled |
166
+
167
+ ### Output
168
+
169
+ ```json
170
+ {
171
+ "event": "billing.transaction.succeeded",
172
+ "timestamp": "2025-01-08T12:00:00Z",
173
+ "charge_id": "550e8400-e29b-41d4-a716-446655440000",
174
+ "is_paid": true,
175
+ "is_failed": false,
176
+ "is_cancelled": false,
177
+ "id": "550e8400-e29b-41d4-a716-446655440000",
178
+ "status": "succeeded",
179
+ "amount": "0.50",
180
+ "currency": "USDC",
181
+ "tx_hash": "5nwz8X3Lgf8dqwV8EKQ2...",
182
+ "payer_address": "0x1234...5678",
183
+ "customer_ref": "user_123",
184
+ "resource_ref": "article:42"
185
+ }
186
+ ```
187
+
188
+ ### How It Works
189
+
190
+ 1. When you activate your workflow, the trigger automatically registers its webhook URL with Orvion
191
+ 2. When a payment event occurs, Orvion sends the event data to your n8n instance
192
+ 3. Your workflow continues with the payment data
193
+ 4. When you deactivate the workflow, the webhook endpoint is automatically removed
194
+
195
+ ---
196
+
197
+ ## Recommended Workflow Patterns
198
+
199
+ ### Pattern 1: Single Workflow with Wait for Payment (Recommended)
200
+
201
+ **Best for:** Most use cases. Everything in one workflow!
202
+
203
+ ```
204
+ [Manual Trigger]
205
+ → [Orvion: Create Charge]
206
+ - Wait for Payment: ON
207
+ - Notify Email: customer@example.com
208
+ → [PAUSES - waiting for payment]
209
+ → [RESUMES when customer pays]
210
+ → [Your business logic]
211
+ ```
212
+
213
+ The workflow pauses after creating the charge, and automatically resumes when the customer completes payment. No need for a second workflow or polling!
214
+
215
+ ### Pattern 2: Two Workflows with Orvion Trigger
216
+
217
+ **Best for:** When you need separate workflows for charge creation and fulfillment.
218
+
219
+ **Workflow 1: Collect Payment**
220
+ ```
221
+ [Your Trigger]
222
+ → [Orvion: Create Charge + Notify Email]
223
+ → [Respond with checkout_url]
224
+ ```
225
+
226
+ **Workflow 2: Handle Payment (separate workflow)**
227
+ ```
228
+ [Orvion Trigger: Payment Succeeded]
229
+ → [Your business logic]
230
+ ```
231
+
232
+ The Orvion Trigger node automatically registers itself as a webhook, so when the customer pays, your second workflow fires immediately.
233
+
234
+ ### Pattern 3: API/Agent Integration
235
+
236
+ **Best for:** APIs, apps, or agents that call your n8n workflow and need the checkout_url back.
237
+
238
+ ```
239
+ [Webhook Trigger]
240
+ → [Orvion: Create Charge]
241
+ - Wait for Payment: ON
242
+ → [PAUSES - waiting for payment]
243
+ → [RESUMES when customer pays]
244
+ → [Respond to Webhook with payment result]
245
+ ```
246
+
247
+ Your app/agent calls the n8n webhook URL → waits → gets payment confirmation in the response.
248
+
249
+ ---
250
+
251
+ ## Complete Example: Order Processing
252
+
253
+ ### Single Workflow Pattern (Recommended)
254
+
255
+ ```
256
+ [Webhook Trigger: POST /order]
257
+ → [Orvion: Create Charge]
258
+ Wait for Payment: ON
259
+ Amount: {{ $json.total }}
260
+ Currency: USDC
261
+ Customer Ref: {{ $json.customer_id }}
262
+ Resource Ref: order:{{ $json.order_id }}
263
+ Notify Email: {{ $json.customer_email }}
264
+ → [PAUSES - waiting for payment]
265
+ → [RESUMES when customer pays]
266
+ → [IF] {{ $json.is_paid }}
267
+ → [Update order status in your database]
268
+ → [Send confirmation email]
269
+ → [Trigger fulfillment]
270
+ → [ELSE]
271
+ → [Handle payment failure]
272
+ ```
273
+
274
+ ### Two Workflow Pattern (Legacy)
275
+
276
+ **Workflow 1: Create Order** (triggered by your app)
277
+ ```
278
+ [Webhook Trigger: POST /order]
279
+ → [Orvion: Create Charge]
280
+ Wait for Payment: OFF
281
+ Amount: {{ $json.total }}
282
+ Notify Email: {{ $json.customer_email }}
283
+ → [Respond to Webhook]
284
+ { "checkout_url": "{{ $json.checkout_url }}" }
285
+ ```
286
+
287
+ **Workflow 2: Fulfill Order** (triggered by Orvion webhook)
288
+ ```
289
+ [Orvion Trigger: Payment Succeeded]
290
+ → [Update order status in your database]
291
+ → [Send confirmation email]
292
+ → [Trigger fulfillment]
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Local Development
298
+
299
+ See the [n8n/dev](../dev) folder for Docker Compose setup for local testing.
300
+
301
+ ```bash
302
+ cd n8n/dev
303
+ cp .env.example .env
304
+ # Edit .env with your values
305
+ docker-compose up
306
+ ```
307
+
308
+ ## Support
309
+
310
+ - [Orvion Documentation](https://docs.orvion.sh)
311
+ - [GitHub Issues](https://github.com/orvion/agent-pay/issues)
312
+ - [Discord Community](https://discord.gg/orvion)
313
+
314
+ ## License
315
+
316
+ MIT
@@ -0,0 +1,9 @@
1
+ import { IAuthenticateGeneric, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class OrvionApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ documentationUrl: string;
6
+ properties: INodeProperties[];
7
+ authenticate: IAuthenticateGeneric;
8
+ test: ICredentialTestRequest;
9
+ }
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OrvionApi = void 0;
4
+ class OrvionApi {
5
+ constructor() {
6
+ this.name = 'orvionApi';
7
+ this.displayName = 'Orvion API';
8
+ this.documentationUrl = 'https://docs.orvion.sh/api/authentication';
9
+ this.properties = [
10
+ {
11
+ displayName: 'API Key',
12
+ name: 'apiKey',
13
+ type: 'string',
14
+ typeOptions: {
15
+ password: true,
16
+ },
17
+ default: '',
18
+ required: true,
19
+ description: 'Your Orvion API key. Get it from the Orvion dashboard under Settings > API Keys.',
20
+ },
21
+ {
22
+ displayName: 'Base URL',
23
+ name: 'baseUrl',
24
+ type: 'string',
25
+ default: 'https://api.orvion.sh/v1',
26
+ required: false,
27
+ description: 'The Orvion API base URL. Defaults to production. Only override if testing with a local backend instance.',
28
+ },
29
+ ];
30
+ this.authenticate = {
31
+ type: 'generic',
32
+ properties: {
33
+ headers: {
34
+ 'X-API-Key': '={{$credentials.apiKey}}',
35
+ 'Content-Type': 'application/json',
36
+ 'User-Agent': 'n8n-nodes-orvion/0.1.0',
37
+ },
38
+ },
39
+ };
40
+ this.test = {
41
+ request: {
42
+ baseURL: '={{$credentials.baseUrl}}',
43
+ url: '/health',
44
+ method: 'GET',
45
+ headers: {
46
+ 'X-API-Key': '={{$credentials.apiKey}}',
47
+ 'Content-Type': 'application/json',
48
+ },
49
+ },
50
+ };
51
+ }
52
+ }
53
+ exports.OrvionApi = OrvionApi;
54
+ //# sourceMappingURL=OrvionApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrvionApi.credentials.js","sourceRoot":"","sources":["../../credentials/OrvionApi.credentials.ts"],"names":[],"mappings":";;;AAOA,MAAa,SAAS;IAAtB;QACC,SAAI,GAAG,WAAW,CAAC;QACnB,gBAAW,GAAG,YAAY,CAAC;QAC3B,qBAAgB,GAAG,2CAA2C,CAAC;QAC/D,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE;oBACZ,QAAQ,EAAE,IAAI;iBACd;gBACD,OAAO,EAAE,EAAE;gBACX,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,kFAAkF;aAC/F;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,0BAA0B;gBACnC,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,0GAA0G;aACvH;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,WAAW,EAAE,0BAA0B;oBACvC,cAAc,EAAE,kBAAkB;oBAClC,YAAY,EAAE,wBAAwB;iBACtC;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,2BAA2B;gBACpC,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACR,WAAW,EAAE,0BAA0B;oBACvC,cAAc,EAAE,kBAAkB;iBAClC;aACD;SACD,CAAC;IACH,CAAC;CAAA;AAhDD,8BAgDC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * n8n-nodes-orvion
3
+ *
4
+ * Orvion community node for n8n - Create payment-protected charges
5
+ * and wait for payment confirmation.
6
+ */
7
+ export * from './credentials/OrvionApi.credentials';
8
+ export * from './nodes/Orvion/Orvion.node';
9
+ export * from './nodes/OrvionTrigger/OrvionTrigger.node';
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ /**
3
+ * n8n-nodes-orvion
4
+ *
5
+ * Orvion community node for n8n - Create payment-protected charges
6
+ * and wait for payment confirmation.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
+ };
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ __exportStar(require("./credentials/OrvionApi.credentials"), exports);
24
+ __exportStar(require("./nodes/Orvion/Orvion.node"), exports);
25
+ __exportStar(require("./nodes/OrvionTrigger/OrvionTrigger.node"), exports);
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;AAEH,sEAAoD;AACpD,6DAA2C;AAC3C,2EAAyD"}
@@ -0,0 +1,10 @@
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';
2
+ export declare class Orvion implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ /**
6
+ * Webhook handler for Wait for Payment feature.
7
+ * Called when the payment callback is received from Orvion.
8
+ */
9
+ webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
10
+ }
@@ -0,0 +1,265 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Orvion = void 0;
4
+ // Fixed timeout: 10 minutes
5
+ const TIMEOUT_MS = 10 * 60 * 1000;
6
+ class Orvion {
7
+ constructor() {
8
+ this.description = {
9
+ displayName: 'Orvion',
10
+ name: 'orvion',
11
+ icon: 'file:orvion.svg',
12
+ group: ['transform'],
13
+ version: 1,
14
+ subtitle: '={{$parameter["waitForPayment"] ? "Create & wait for payment" : "Create charge"}}',
15
+ description: 'Create a payment charge and optionally wait for payment completion. When "Wait for Payment" is enabled, the workflow pauses until the customer pays.',
16
+ defaults: {
17
+ name: 'Orvion',
18
+ },
19
+ inputs: ['main'],
20
+ outputs: ['main', 'main', 'main'],
21
+ outputNames: ['Success', 'Pending', 'Failed'],
22
+ credentials: [
23
+ {
24
+ name: 'orvionApi',
25
+ required: true,
26
+ },
27
+ ],
28
+ // Webhook configuration for Wait for Payment feature
29
+ webhooks: [
30
+ {
31
+ name: 'default',
32
+ httpMethod: 'POST',
33
+ responseMode: 'onReceived',
34
+ path: '={{ $nodeId }}',
35
+ restartWebhook: true,
36
+ isFullPath: true,
37
+ },
38
+ ],
39
+ properties: [
40
+ {
41
+ displayName: 'Wait for Payment',
42
+ name: 'waitForPayment',
43
+ type: 'boolean',
44
+ default: false,
45
+ description: 'When enabled, the workflow pauses after creating the charge and automatically resumes when the customer completes payment. This allows a single workflow to handle both charge creation and payment completion.',
46
+ },
47
+ {
48
+ displayName: 'Amount',
49
+ name: 'amount',
50
+ type: 'number',
51
+ typeOptions: {
52
+ numberPrecision: 6,
53
+ },
54
+ default: 0.5,
55
+ required: true,
56
+ description: 'The charge amount (e.g., 0.50 for 50 cents)',
57
+ },
58
+ {
59
+ displayName: 'Currency',
60
+ name: 'currency',
61
+ type: 'string',
62
+ default: 'USDC',
63
+ required: true,
64
+ description: 'Currency code (e.g., USDC, EURC, USD)',
65
+ },
66
+ {
67
+ displayName: 'Flow Slug',
68
+ name: 'flowSlug',
69
+ type: 'string',
70
+ default: '',
71
+ required: false,
72
+ description: 'Billing flow slug for x402 payment configuration. If not provided, uses your organization\'s default receiver config.',
73
+ },
74
+ {
75
+ displayName: 'Customer Reference',
76
+ name: 'customerRef',
77
+ type: 'string',
78
+ default: '',
79
+ required: false,
80
+ description: 'Your internal customer ID or reference',
81
+ },
82
+ {
83
+ displayName: 'Resource Reference',
84
+ name: 'resourceRef',
85
+ type: 'string',
86
+ default: '',
87
+ required: false,
88
+ description: 'Identifies the protected resource being purchased (e.g., article:42, image:prompt-text)',
89
+ },
90
+ {
91
+ displayName: 'Notify Email',
92
+ name: 'notifyEmail',
93
+ type: 'string',
94
+ default: '',
95
+ required: true,
96
+ description: 'Email address to send the checkout URL to. The customer will receive an email with a link to complete payment.',
97
+ placeholder: 'customer@example.com',
98
+ },
99
+ ],
100
+ };
101
+ }
102
+ async execute() {
103
+ const items = this.getInputData();
104
+ const successItems = [];
105
+ const pendingItems = [];
106
+ const failedItems = [];
107
+ // Get static data for storing state across wait/resume
108
+ const waitData = this.getWorkflowStaticData('node');
109
+ const credentials = await this.getCredentials('orvionApi');
110
+ const baseUrl = credentials.baseUrl;
111
+ const apiKey = credentials.apiKey;
112
+ for (let i = 0; i < items.length; i++) {
113
+ try {
114
+ const waitForPayment = this.getNodeParameter('waitForPayment', i, false);
115
+ const amount = this.getNodeParameter('amount', i);
116
+ const currency = this.getNodeParameter('currency', i);
117
+ const flowSlug = this.getNodeParameter('flowSlug', i, '');
118
+ const customerRef = this.getNodeParameter('customerRef', i, '');
119
+ const resourceRef = this.getNodeParameter('resourceRef', i, '');
120
+ const notifyEmail = this.getNodeParameter('notifyEmail', i, '');
121
+ const body = {
122
+ amount: amount.toString(),
123
+ currency,
124
+ };
125
+ if (flowSlug)
126
+ body.flow_slug = flowSlug;
127
+ if (customerRef)
128
+ body.customer_ref = customerRef;
129
+ if (resourceRef)
130
+ body.resource_ref = resourceRef;
131
+ if (notifyEmail)
132
+ body.notify_email = notifyEmail;
133
+ // If waitForPayment is enabled, add callback_url for webhook-based waiting
134
+ if (waitForPayment) {
135
+ // Get the resume URL and node ID to construct the proper callback URL
136
+ // n8n requires the format: ${resumeUrl}/${nodeId} for waiting webhooks
137
+ let callbackUrl;
138
+ try {
139
+ const resumeUrl = this.evaluateExpression('{{ $execution.resumeUrl }}', i);
140
+ const nodeId = this.evaluateExpression('{{ $nodeId }}', i);
141
+ if (resumeUrl && nodeId) {
142
+ // The callback URL must include the nodeId for n8n to route it correctly
143
+ callbackUrl = `${resumeUrl}/${nodeId}`;
144
+ }
145
+ }
146
+ catch (e) {
147
+ // Expression evaluation failed, try alternative method
148
+ console.warn('[Orvion] Could not evaluate expressions for resume URL:', e);
149
+ }
150
+ if (callbackUrl) {
151
+ body.callback_url = callbackUrl;
152
+ }
153
+ else {
154
+ // Log warning but continue - the workflow will work but won't auto-resume
155
+ console.warn('[Orvion] Could not determine callback URL for wait-for-payment. Callback will not be set.');
156
+ }
157
+ }
158
+ // Create the charge
159
+ const response = await this.helpers.httpRequest({
160
+ method: 'POST',
161
+ url: `${baseUrl}/charges`,
162
+ headers: {
163
+ 'X-API-Key': apiKey,
164
+ 'Content-Type': 'application/json',
165
+ 'User-Agent': 'n8n-nodes-orvion/0.1.0',
166
+ },
167
+ body,
168
+ json: true,
169
+ });
170
+ // Add convenience fields
171
+ const charge = {
172
+ ...response,
173
+ charge_id: response.id,
174
+ is_paid: response.status === 'succeeded',
175
+ is_pending: response.status === 'pending',
176
+ is_failed: ['failed', 'expired', 'cancelled'].includes(response.status),
177
+ };
178
+ // If waitForPayment is enabled and charge is pending, pause execution
179
+ if (waitForPayment && charge.is_pending) {
180
+ // Store state for when we resume
181
+ waitData.waitingForPayment = true;
182
+ waitData.chargeId = charge.id;
183
+ // Calculate timeout date (fixed 10 minute timeout)
184
+ const waitUntil = new Date(Date.now() + TIMEOUT_MS);
185
+ // Put execution to wait until timeout or webhook callback is received
186
+ await this.putExecutionToWait(waitUntil);
187
+ // This code won't be reached until the workflow resumes via webhook
188
+ // When it resumes, the webhook() method handles the callback data
189
+ return [this.getInputData()];
190
+ }
191
+ const item = {
192
+ json: charge,
193
+ pairedItem: { item: i },
194
+ };
195
+ // Route based on status
196
+ if (charge.is_paid) {
197
+ // Payment already succeeded (rare for new charges)
198
+ successItems.push(item);
199
+ }
200
+ else if (charge.is_pending) {
201
+ // Charge created, awaiting payment (most common)
202
+ pendingItems.push(item);
203
+ }
204
+ else {
205
+ // Charge failed/expired/cancelled
206
+ failedItems.push(item);
207
+ }
208
+ }
209
+ catch (error) {
210
+ if (this.continueOnFail()) {
211
+ failedItems.push({
212
+ json: {
213
+ error: error instanceof Error ? error.message : 'Unknown error',
214
+ is_paid: false,
215
+ is_pending: false,
216
+ is_failed: true,
217
+ },
218
+ pairedItem: { item: i },
219
+ });
220
+ continue;
221
+ }
222
+ throw error;
223
+ }
224
+ }
225
+ // Return 3 outputs: [Success, Pending, Failed]
226
+ return [successItems, pendingItems, failedItems];
227
+ }
228
+ /**
229
+ * Webhook handler for Wait for Payment feature.
230
+ * Called when the payment callback is received from Orvion.
231
+ */
232
+ async webhook() {
233
+ const req = this.getRequestObject();
234
+ const callbackData = req.body;
235
+ // Extract payment data from callback
236
+ const eventName = callbackData.event || 'unknown';
237
+ const paymentData = callbackData.data || callbackData;
238
+ // Build output with convenience fields
239
+ const outputData = {
240
+ ...paymentData,
241
+ id: paymentData.id || '',
242
+ charge_id: paymentData.id || '',
243
+ status: paymentData.status || '',
244
+ amount: paymentData.amount || '',
245
+ currency: paymentData.currency || '',
246
+ created_at: paymentData.created_at || '',
247
+ updated_at: paymentData.updated_at || '',
248
+ is_paid: eventName === 'billing.transaction.succeeded',
249
+ is_pending: false,
250
+ is_failed: eventName === 'billing.transaction.failed',
251
+ };
252
+ // Return success response to Orvion and resume workflow with payment data
253
+ return {
254
+ webhookResponse: JSON.stringify({ success: true, message: 'Callback received' }),
255
+ workflowData: [
256
+ // Route to appropriate output based on payment status
257
+ outputData.is_paid ? [{ json: outputData }] : [], // Success output
258
+ [], // Pending output (not used on callback)
259
+ outputData.is_failed ? [{ json: outputData }] : [], // Failed output
260
+ ],
261
+ };
262
+ }
263
+ }
264
+ exports.Orvion = Orvion;
265
+ //# sourceMappingURL=Orvion.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Orvion.node.js","sourceRoot":"","sources":["../../../nodes/Orvion/Orvion.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
2
+ <defs>
3
+ <linearGradient id="orvionGradient" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#6366f1;stop-opacity:1" />
5
+ <stop offset="100%" style="stop-color:#8b5cf6;stop-opacity:1" />
6
+ </linearGradient>
7
+ </defs>
8
+ <!-- Background circle -->
9
+ <circle cx="32" cy="32" r="30" fill="url(#orvionGradient)"/>
10
+ <!-- Dollar/payment symbol stylized as "O" for Orvion -->
11
+ <circle cx="32" cy="32" r="16" stroke="white" stroke-width="3" fill="none"/>
12
+ <!-- Payment arrow pointing right (represents flow/transaction) -->
13
+ <path d="M26 32h12M34 26l6 6-6 6" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
14
+ </svg>
@@ -0,0 +1,24 @@
1
+ import { IHookFunctions, INodeType, INodeTypeDescription, IWebhookFunctions, IWebhookResponseData } from 'n8n-workflow';
2
+ export declare class OrvionTrigger implements INodeType {
3
+ description: INodeTypeDescription;
4
+ webhookMethods: {
5
+ default: {
6
+ /**
7
+ * Check if a webhook endpoint already exists for this n8n webhook URL.
8
+ */
9
+ checkExists(this: IHookFunctions): Promise<boolean>;
10
+ /**
11
+ * Create a new webhook endpoint in Orvion.
12
+ */
13
+ create(this: IHookFunctions): Promise<boolean>;
14
+ /**
15
+ * Delete the webhook endpoint from Orvion.
16
+ */
17
+ delete(this: IHookFunctions): Promise<boolean>;
18
+ };
19
+ };
20
+ /**
21
+ * Handle incoming webhook events from Orvion.
22
+ */
23
+ webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
24
+ }
@@ -0,0 +1,215 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OrvionTrigger = void 0;
4
+ class OrvionTrigger {
5
+ constructor() {
6
+ this.description = {
7
+ displayName: 'Orvion Trigger',
8
+ name: 'orvionTrigger',
9
+ icon: 'file:orvion.svg',
10
+ group: ['trigger'],
11
+ version: 1,
12
+ subtitle: '={{$parameter["events"].join(", ")}}',
13
+ description: 'Triggers when a payment event occurs (e.g., payment succeeded, failed). Eliminates polling loops.',
14
+ defaults: {
15
+ name: 'Orvion Trigger',
16
+ },
17
+ inputs: [],
18
+ outputs: ['main'],
19
+ credentials: [
20
+ {
21
+ name: 'orvionApi',
22
+ required: true,
23
+ },
24
+ ],
25
+ webhooks: [
26
+ {
27
+ name: 'default',
28
+ httpMethod: 'POST',
29
+ responseMode: 'onReceived',
30
+ path: 'webhook',
31
+ },
32
+ ],
33
+ properties: [
34
+ {
35
+ displayName: 'Events',
36
+ name: 'events',
37
+ type: 'multiOptions',
38
+ required: true,
39
+ default: ['billing.transaction.succeeded'],
40
+ description: 'The events to listen to',
41
+ options: [
42
+ {
43
+ name: 'Payment Succeeded',
44
+ value: 'billing.transaction.succeeded',
45
+ description: 'Triggered when a payment is confirmed on the blockchain',
46
+ },
47
+ {
48
+ name: 'Payment Failed',
49
+ value: 'billing.transaction.failed',
50
+ description: 'Triggered when a payment fails',
51
+ },
52
+ {
53
+ name: 'Payment Cancelled',
54
+ value: 'billing.transaction.cancelled',
55
+ description: 'Triggered when a payment is cancelled',
56
+ },
57
+ ],
58
+ },
59
+ {
60
+ displayName: 'Description',
61
+ name: 'description',
62
+ type: 'string',
63
+ default: '',
64
+ description: 'Optional description for this webhook endpoint (shown in Orvion dashboard)',
65
+ placeholder: 'n8n workflow: Order Processing',
66
+ },
67
+ ],
68
+ };
69
+ this.webhookMethods = {
70
+ default: {
71
+ /**
72
+ * Check if a webhook endpoint already exists for this n8n webhook URL.
73
+ */
74
+ async checkExists() {
75
+ const webhookUrl = this.getNodeWebhookUrl('default');
76
+ const credentials = await this.getCredentials('orvionApi');
77
+ const baseUrl = credentials.baseUrl;
78
+ const apiKey = credentials.apiKey;
79
+ try {
80
+ // List all webhook endpoints and check if one matches our URL
81
+ const response = await this.helpers.httpRequest({
82
+ method: 'GET',
83
+ url: `${baseUrl}/webhook-endpoints`,
84
+ headers: {
85
+ 'X-API-Key': apiKey,
86
+ 'User-Agent': 'n8n-nodes-orvion/0.1.0',
87
+ },
88
+ json: true,
89
+ });
90
+ const existingEndpoint = response.endpoints.find((ep) => ep.url === webhookUrl && ep.is_active);
91
+ if (existingEndpoint) {
92
+ // Store the endpoint ID for later use
93
+ const webhookData = this.getWorkflowStaticData('node');
94
+ webhookData.webhookEndpointId = existingEndpoint.id;
95
+ return true;
96
+ }
97
+ return false;
98
+ }
99
+ catch (error) {
100
+ // If we get an error (e.g., 404, network), assume it doesn't exist
101
+ return false;
102
+ }
103
+ },
104
+ /**
105
+ * Create a new webhook endpoint in Orvion.
106
+ */
107
+ async create() {
108
+ const webhookUrl = this.getNodeWebhookUrl('default');
109
+ const events = this.getNodeParameter('events');
110
+ const description = this.getNodeParameter('description', '');
111
+ const credentials = await this.getCredentials('orvionApi');
112
+ const baseUrl = credentials.baseUrl;
113
+ const apiKey = credentials.apiKey;
114
+ try {
115
+ const body = {
116
+ url: webhookUrl,
117
+ event_types: events,
118
+ };
119
+ if (description) {
120
+ body.description = description;
121
+ }
122
+ const response = await this.helpers.httpRequest({
123
+ method: 'POST',
124
+ url: `${baseUrl}/webhook-endpoints`,
125
+ headers: {
126
+ 'X-API-Key': apiKey,
127
+ 'Content-Type': 'application/json',
128
+ 'User-Agent': 'n8n-nodes-orvion/0.1.0',
129
+ },
130
+ body,
131
+ json: true,
132
+ });
133
+ // Store the endpoint ID and secret for later use
134
+ const webhookData = this.getWorkflowStaticData('node');
135
+ webhookData.webhookEndpointId = response.id;
136
+ webhookData.webhookSecret = response.secret;
137
+ return true;
138
+ }
139
+ catch (error) {
140
+ const errorMessage = error instanceof Error ? error.message : 'Unknown error';
141
+ throw new Error(`Failed to register webhook endpoint with Orvion: ${errorMessage}`);
142
+ }
143
+ },
144
+ /**
145
+ * Delete the webhook endpoint from Orvion.
146
+ */
147
+ async delete() {
148
+ const credentials = await this.getCredentials('orvionApi');
149
+ const baseUrl = credentials.baseUrl;
150
+ const apiKey = credentials.apiKey;
151
+ const webhookData = this.getWorkflowStaticData('node');
152
+ const endpointId = webhookData.webhookEndpointId;
153
+ if (!endpointId) {
154
+ // No endpoint ID stored, nothing to delete
155
+ return true;
156
+ }
157
+ try {
158
+ await this.helpers.httpRequest({
159
+ method: 'DELETE',
160
+ url: `${baseUrl}/webhook-endpoints/${endpointId}`,
161
+ headers: {
162
+ 'X-API-Key': apiKey,
163
+ 'User-Agent': 'n8n-nodes-orvion/0.1.0',
164
+ },
165
+ });
166
+ // Clear stored data
167
+ delete webhookData.webhookEndpointId;
168
+ delete webhookData.webhookSecret;
169
+ return true;
170
+ }
171
+ catch (error) {
172
+ // If endpoint is already gone (404), consider it a success
173
+ if (error instanceof Error && error.message.includes('404')) {
174
+ delete webhookData.webhookEndpointId;
175
+ delete webhookData.webhookSecret;
176
+ return true;
177
+ }
178
+ throw error;
179
+ }
180
+ },
181
+ },
182
+ };
183
+ }
184
+ /**
185
+ * Handle incoming webhook events from Orvion.
186
+ */
187
+ async webhook() {
188
+ const req = this.getRequestObject();
189
+ const body = this.getBodyData();
190
+ // Extract event data
191
+ const eventName = body.event || req.headers['x-meshpay-event'] || 'unknown';
192
+ const eventData = body.data || body;
193
+ const timestamp = body.timestamp || new Date().toISOString();
194
+ // Build output item with helpful fields
195
+ const outputData = {
196
+ // Event metadata
197
+ event: eventName,
198
+ timestamp,
199
+ // Transaction data (flattened for easy access)
200
+ ...eventData,
201
+ // Convenience fields for common workflow patterns
202
+ charge_id: eventData.id || eventData.transaction_id,
203
+ is_paid: eventName === 'billing.transaction.succeeded',
204
+ is_failed: eventName === 'billing.transaction.failed',
205
+ is_cancelled: eventName === 'billing.transaction.cancelled',
206
+ };
207
+ return {
208
+ workflowData: [
209
+ this.helpers.returnJsonArray([outputData]),
210
+ ],
211
+ };
212
+ }
213
+ }
214
+ exports.OrvionTrigger = OrvionTrigger;
215
+ //# sourceMappingURL=OrvionTrigger.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OrvionTrigger.node.js","sourceRoot":"","sources":["../../../nodes/OrvionTrigger/OrvionTrigger.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64" fill="none">
2
+ <defs>
3
+ <linearGradient id="orvionGradient" x1="0%" y1="0%" x2="100%" y2="100%">
4
+ <stop offset="0%" style="stop-color:#6366f1;stop-opacity:1" />
5
+ <stop offset="100%" style="stop-color:#8b5cf6;stop-opacity:1" />
6
+ </linearGradient>
7
+ </defs>
8
+ <!-- Background circle -->
9
+ <circle cx="32" cy="32" r="30" fill="url(#orvionGradient)"/>
10
+ <!-- Dollar/payment symbol stylized as "O" for Orvion -->
11
+ <circle cx="32" cy="32" r="16" stroke="white" stroke-width="3" fill="none"/>
12
+ <!-- Payment arrow pointing right (represents flow/transaction) -->
13
+ <path d="M26 32h12M34 26l6 6-6 6" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round"/>
14
+ </svg>
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@orvion/n8n-nodes-orvion",
3
+ "version": "0.1.1",
4
+ "description": "n8n community node for Orvion - Create payment-protected charges and wait for payment confirmation",
5
+ "keywords": [
6
+ "n8n-community-node-package",
7
+ "n8n",
8
+ "orvion",
9
+ "payments",
10
+ "x402",
11
+ "crypto",
12
+ "stablecoin",
13
+ "USDC"
14
+ ],
15
+ "license": "MIT",
16
+ "homepage": "https://orvion.sh",
17
+ "publishConfig": {
18
+ "access": "public",
19
+ "registry": "https://registry.npmjs.org"
20
+ },
21
+ "author": {
22
+ "name": "Orvion",
23
+ "email": "ekinburakozturk@gmail.com"
24
+ },
25
+ "repository": {
26
+ "type": "git",
27
+ "url": "git+https://github.com/orvion/agent-pay.git"
28
+ },
29
+ "main": "dist/index.js",
30
+ "types": "dist/index.d.ts",
31
+ "scripts": {
32
+ "build": "tsc && gulp build:icons",
33
+ "dev": "tsc --watch",
34
+ "format": "prettier --write .",
35
+ "lint": "eslint nodes credentials --ext .ts",
36
+ "prepublishOnly": "npm run build"
37
+ },
38
+ "files": [
39
+ "dist"
40
+ ],
41
+ "n8n": {
42
+ "n8nNodesApiVersion": 1,
43
+ "credentials": [
44
+ "dist/credentials/OrvionApi.credentials.js"
45
+ ],
46
+ "nodes": [
47
+ "dist/nodes/Orvion/Orvion.node.js",
48
+ "dist/nodes/OrvionTrigger/OrvionTrigger.node.js"
49
+ ]
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^20.10.0",
53
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
54
+ "@typescript-eslint/parser": "^6.0.0",
55
+ "eslint": "^8.50.0",
56
+ "gulp": "^4.0.2",
57
+ "n8n-workflow": "^1.20.0",
58
+ "prettier": "^3.1.0",
59
+ "typescript": "^5.3.0"
60
+ },
61
+ "peerDependencies": {
62
+ "n8n-workflow": "*"
63
+ },
64
+ "engines": {
65
+ "node": ">=18.0.0"
66
+ }
67
+ }