@beinfi/pulse-sdk 0.1.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 +103 -0
- package/dist/ai.d.mts +934 -0
- package/dist/ai.d.ts +934 -0
- package/dist/ai.js +73 -0
- package/dist/ai.mjs +48 -0
- package/dist/checkout.js +1 -0
- package/dist/index.d.mts +1094 -0
- package/dist/index.d.ts +1094 -0
- package/dist/index.js +712 -0
- package/dist/index.mjs +679 -0
- package/package.json +83 -0
package/dist/ai.d.mts
ADDED
|
@@ -0,0 +1,934 @@
|
|
|
1
|
+
import { LanguageModelV3Middleware } from '@ai-sdk/provider';
|
|
2
|
+
|
|
3
|
+
declare class HttpClient {
|
|
4
|
+
private readonly apiKey;
|
|
5
|
+
private readonly baseUrl;
|
|
6
|
+
constructor(apiKey: string, baseUrl?: string);
|
|
7
|
+
request<T>(method: string, path: string, options?: {
|
|
8
|
+
body?: unknown;
|
|
9
|
+
query?: Record<string, string | number | undefined>;
|
|
10
|
+
}): Promise<T>;
|
|
11
|
+
private parseRateLimit;
|
|
12
|
+
private safeJson;
|
|
13
|
+
private handleError;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Configuration options for the Pulse SDK client.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* const pulse = new Pulse({
|
|
22
|
+
* apiKey: 'sk_live_...',
|
|
23
|
+
* baseUrl: 'https://api.beinfi.com'
|
|
24
|
+
* })
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
interface PulseConfig {
|
|
28
|
+
/** API key starting with `sk_live_`. Obtain from the Pulse dashboard under Developers > API Keys. */
|
|
29
|
+
apiKey: string;
|
|
30
|
+
/** Override the API base URL. Defaults to `https://api.beinfi.com`. */
|
|
31
|
+
baseUrl?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Parameters for creating a new payment link.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```typescript
|
|
38
|
+
* const link = await pulse.paymentLinks.create({
|
|
39
|
+
* title: 'Web Development',
|
|
40
|
+
* amount: '150.00',
|
|
41
|
+
* currency: 'USD',
|
|
42
|
+
* description: 'Landing page development'
|
|
43
|
+
* })
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
interface CreatePaymentLinkParams {
|
|
47
|
+
/** Human-readable title shown to the payer (e.g. "Order #42"). */
|
|
48
|
+
title: string;
|
|
49
|
+
/** Payment amount as a decimal string (e.g. `"99.90"`). */
|
|
50
|
+
amount: string;
|
|
51
|
+
/** Optional description shown on the checkout page. */
|
|
52
|
+
description?: string;
|
|
53
|
+
/** Currency code. Defaults to `"USD"`. */
|
|
54
|
+
currency?: 'USD' | 'BRL';
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* A payment link object returned by the API.
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* const link = await pulse.paymentLinks.get('link-id')
|
|
62
|
+
* console.log(link.title, link.amount, link.status)
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
interface PaymentLink {
|
|
66
|
+
/** Unique identifier (UUID). */
|
|
67
|
+
id: string;
|
|
68
|
+
/** Human-readable title. */
|
|
69
|
+
title: string;
|
|
70
|
+
/** Optional description, or `null` if not set. */
|
|
71
|
+
description: string | null;
|
|
72
|
+
/** Payment amount as a decimal string (e.g. `"100.00"`). */
|
|
73
|
+
amount: string;
|
|
74
|
+
/** Currency code (e.g. `"USD"`, `"BRL"`). */
|
|
75
|
+
currency: string;
|
|
76
|
+
/** Current status of the link (e.g. `"active"`, `"inactive"`). */
|
|
77
|
+
status: string;
|
|
78
|
+
/** URL-friendly slug for the payment page. */
|
|
79
|
+
slug: string;
|
|
80
|
+
/** ID of the user who created this link. */
|
|
81
|
+
userId: string;
|
|
82
|
+
/** ISO 8601 timestamp of creation. */
|
|
83
|
+
createdAt: string;
|
|
84
|
+
/** ISO 8601 timestamp of last update. */
|
|
85
|
+
updatedAt: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Query parameters for listing payment links.
|
|
89
|
+
*
|
|
90
|
+
* @example
|
|
91
|
+
* ```typescript
|
|
92
|
+
* const links = await pulse.paymentLinks.list({ limit: 10, offset: 0 })
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
interface ListPaymentLinksParams {
|
|
96
|
+
/** Maximum number of results to return. Defaults to 20. */
|
|
97
|
+
limit?: number;
|
|
98
|
+
/** Number of results to skip (for pagination). Defaults to 0. */
|
|
99
|
+
offset?: number;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* A payment intent represents a single payment attempt against a payment link.
|
|
103
|
+
*
|
|
104
|
+
* @example
|
|
105
|
+
* ```typescript
|
|
106
|
+
* const intents = await pulse.paymentLinks.listIntents('link-id')
|
|
107
|
+
* for (const intent of intents) {
|
|
108
|
+
* console.log(intent.status, intent.amount, intent.method)
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
interface PaymentIntent {
|
|
113
|
+
/** Unique identifier (UUID). */
|
|
114
|
+
id: string;
|
|
115
|
+
/** ID of the parent payment link. */
|
|
116
|
+
paymentLinkId: string;
|
|
117
|
+
/** Payment amount as a decimal string, or `null` if not yet determined. */
|
|
118
|
+
amount: string;
|
|
119
|
+
/** Currency code (e.g. `"USD"`). */
|
|
120
|
+
currency: string;
|
|
121
|
+
/** Intent status: `"pending"` | `"observed"` | `"confirmed"` | `"failed"` | `"expired"`. */
|
|
122
|
+
status: string;
|
|
123
|
+
/** Payment method used (e.g. `"crypto"`, `"pix"`), or `null` if not yet selected. */
|
|
124
|
+
method: string | null;
|
|
125
|
+
/** Blockchain transaction hash, or `null` if not a crypto payment. */
|
|
126
|
+
txHash: string | null;
|
|
127
|
+
/** ISO 8601 timestamp when the payment was confirmed, or `null`. */
|
|
128
|
+
confirmedAt: string | null;
|
|
129
|
+
/** ISO 8601 timestamp of creation. */
|
|
130
|
+
createdAt: string;
|
|
131
|
+
/** ISO 8601 timestamp of last update. */
|
|
132
|
+
updatedAt: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Parameters for creating a new webhook subscription.
|
|
136
|
+
*
|
|
137
|
+
* @example
|
|
138
|
+
* ```typescript
|
|
139
|
+
* const wh = await pulse.webhooks.create({
|
|
140
|
+
* url: 'https://example.com/webhook',
|
|
141
|
+
* events: ['payment.confirmed']
|
|
142
|
+
* })
|
|
143
|
+
* // Save wh.secret — it's only returned once at creation time
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
interface CreateWebhookParams {
|
|
147
|
+
/** The HTTPS URL that will receive webhook POST requests. */
|
|
148
|
+
url: string;
|
|
149
|
+
/** Array of event types to subscribe to (e.g. `["payment.confirmed"]`). */
|
|
150
|
+
events: string[];
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* A webhook subscription object.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* const webhooks = await pulse.webhooks.list()
|
|
158
|
+
* for (const wh of webhooks) {
|
|
159
|
+
* console.log(wh.url, wh.events, wh.isActive)
|
|
160
|
+
* }
|
|
161
|
+
* ```
|
|
162
|
+
*/
|
|
163
|
+
interface Webhook {
|
|
164
|
+
/** Unique identifier (UUID). */
|
|
165
|
+
id: string;
|
|
166
|
+
/** The URL receiving webhook deliveries. */
|
|
167
|
+
url: string;
|
|
168
|
+
/** Event types this webhook is subscribed to. */
|
|
169
|
+
events: string[];
|
|
170
|
+
/** Whether the webhook is currently active. */
|
|
171
|
+
isActive: boolean;
|
|
172
|
+
/** ISO 8601 timestamp of creation. */
|
|
173
|
+
createdAt: string;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Webhook object returned after creation, includes the signing secret.
|
|
177
|
+
* The `secret` is only returned once — store it securely.
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```typescript
|
|
181
|
+
* const wh = await pulse.webhooks.create({
|
|
182
|
+
* url: 'https://example.com/webhook',
|
|
183
|
+
* events: ['payment.confirmed']
|
|
184
|
+
* })
|
|
185
|
+
* console.log(wh.secret) // "a1b2c3..." (64-char hex) — save this!
|
|
186
|
+
* ```
|
|
187
|
+
*/
|
|
188
|
+
interface WebhookCreated extends Webhook {
|
|
189
|
+
/** HMAC signing secret (64-character hex string). Only returned at creation time. */
|
|
190
|
+
secret: string;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Parameters for tracking a usage event.
|
|
194
|
+
*
|
|
195
|
+
* @example
|
|
196
|
+
* ```typescript
|
|
197
|
+
* await pulse.metering.track({
|
|
198
|
+
* meterId: 'tokens',
|
|
199
|
+
* customerId: 'user_123',
|
|
200
|
+
* value: 1500,
|
|
201
|
+
* metadata: { model: 'gpt-4' }
|
|
202
|
+
* })
|
|
203
|
+
* ```
|
|
204
|
+
*/
|
|
205
|
+
interface TrackEventParams {
|
|
206
|
+
/** Idempotency key. Auto-generated if not provided. */
|
|
207
|
+
eventId?: string;
|
|
208
|
+
/** Meter ID or slug to track against. */
|
|
209
|
+
meterId: string;
|
|
210
|
+
/** Your customer's identifier (externalId). */
|
|
211
|
+
customerId: string;
|
|
212
|
+
/** Quantity consumed (e.g. number of tokens). */
|
|
213
|
+
value: number | string;
|
|
214
|
+
/** When the event occurred. Defaults to now. */
|
|
215
|
+
timestamp?: Date;
|
|
216
|
+
/** Additional metadata attached to the event. */
|
|
217
|
+
metadata?: Record<string, unknown>;
|
|
218
|
+
}
|
|
219
|
+
/** A tracked event as returned by the API. */
|
|
220
|
+
interface TrackEventResponse {
|
|
221
|
+
id: string;
|
|
222
|
+
eventId: string;
|
|
223
|
+
meterId: string;
|
|
224
|
+
customerId: string;
|
|
225
|
+
value: string;
|
|
226
|
+
timestamp: string;
|
|
227
|
+
createdAt: string;
|
|
228
|
+
}
|
|
229
|
+
/** Result of a batch track operation. */
|
|
230
|
+
interface BatchTrackResponse {
|
|
231
|
+
accepted: number;
|
|
232
|
+
failed: number;
|
|
233
|
+
results: TrackEventResponse[];
|
|
234
|
+
errors?: Array<{
|
|
235
|
+
eventId?: string;
|
|
236
|
+
error: string;
|
|
237
|
+
}>;
|
|
238
|
+
}
|
|
239
|
+
/** Query parameters for aggregated usage. */
|
|
240
|
+
interface UsageQuery {
|
|
241
|
+
customerId?: string;
|
|
242
|
+
startDate?: string;
|
|
243
|
+
endDate?: string;
|
|
244
|
+
}
|
|
245
|
+
/** A single meter's aggregated usage. */
|
|
246
|
+
interface UsageItem {
|
|
247
|
+
meterId: string;
|
|
248
|
+
meterName: string;
|
|
249
|
+
unit: string;
|
|
250
|
+
unitPrice: string;
|
|
251
|
+
totalValue: string;
|
|
252
|
+
totalAmount: string;
|
|
253
|
+
eventCount: number;
|
|
254
|
+
}
|
|
255
|
+
/** Aggregated usage response. */
|
|
256
|
+
interface UsageResponse {
|
|
257
|
+
data: UsageItem[];
|
|
258
|
+
}
|
|
259
|
+
/** Parameters for creating a customer on a product. */
|
|
260
|
+
interface CreateCustomerParams {
|
|
261
|
+
externalId: string;
|
|
262
|
+
name?: string;
|
|
263
|
+
email?: string;
|
|
264
|
+
metadata?: Record<string, unknown>;
|
|
265
|
+
}
|
|
266
|
+
/** Parameters for creating a product. */
|
|
267
|
+
interface CreateProductParams {
|
|
268
|
+
name: string;
|
|
269
|
+
description?: string;
|
|
270
|
+
}
|
|
271
|
+
/** Parameters for creating a meter on a product. */
|
|
272
|
+
interface CreateMeterParams {
|
|
273
|
+
name: string;
|
|
274
|
+
displayName: string;
|
|
275
|
+
unit: string;
|
|
276
|
+
unitPrice: string;
|
|
277
|
+
}
|
|
278
|
+
/** A meter object returned by the API. */
|
|
279
|
+
interface Meter {
|
|
280
|
+
id: string;
|
|
281
|
+
name: string;
|
|
282
|
+
displayName: string;
|
|
283
|
+
unit: string;
|
|
284
|
+
unitPrice: string;
|
|
285
|
+
status: string;
|
|
286
|
+
}
|
|
287
|
+
/** A product with meters. */
|
|
288
|
+
interface MeteringProduct {
|
|
289
|
+
id: string;
|
|
290
|
+
name: string;
|
|
291
|
+
description?: string;
|
|
292
|
+
status: string;
|
|
293
|
+
meters: Array<{
|
|
294
|
+
id: string;
|
|
295
|
+
name: string;
|
|
296
|
+
displayName: string;
|
|
297
|
+
unit: string;
|
|
298
|
+
unitPrice: string;
|
|
299
|
+
}>;
|
|
300
|
+
}
|
|
301
|
+
/** A customer linked to a product. */
|
|
302
|
+
interface ProductCustomer {
|
|
303
|
+
id: string;
|
|
304
|
+
externalId: string;
|
|
305
|
+
name?: string | null;
|
|
306
|
+
email?: string | null;
|
|
307
|
+
createdAt: string;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Resource for managing payment links.
|
|
312
|
+
* Access via `pulse.paymentLinks`.
|
|
313
|
+
*
|
|
314
|
+
* @example
|
|
315
|
+
* ```typescript
|
|
316
|
+
* const pulse = new Pulse('sk_live_...')
|
|
317
|
+
*
|
|
318
|
+
* // Create a payment link
|
|
319
|
+
* const link = await pulse.paymentLinks.create({
|
|
320
|
+
* title: 'Order #42',
|
|
321
|
+
* amount: '100.00',
|
|
322
|
+
* })
|
|
323
|
+
*
|
|
324
|
+
* // List all links
|
|
325
|
+
* const links = await pulse.paymentLinks.list({ limit: 10 })
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
declare class PaymentLinksResource {
|
|
329
|
+
private readonly client;
|
|
330
|
+
constructor(client: HttpClient);
|
|
331
|
+
/**
|
|
332
|
+
* Create a new payment link.
|
|
333
|
+
*
|
|
334
|
+
* @param params - Payment link parameters (title, amount, optional currency and description).
|
|
335
|
+
* @returns The created payment link object.
|
|
336
|
+
* @throws {PulseAuthenticationError} If the API key is invalid.
|
|
337
|
+
* @throws {PulseApiError} If validation fails (e.g. invalid currency).
|
|
338
|
+
*
|
|
339
|
+
* @example
|
|
340
|
+
* ```typescript
|
|
341
|
+
* const link = await pulse.paymentLinks.create({
|
|
342
|
+
* title: 'Web Development',
|
|
343
|
+
* amount: '150.00',
|
|
344
|
+
* currency: 'USD',
|
|
345
|
+
* description: 'Landing page development',
|
|
346
|
+
* })
|
|
347
|
+
* console.log(link.id, link.slug)
|
|
348
|
+
* ```
|
|
349
|
+
*/
|
|
350
|
+
create(params: CreatePaymentLinkParams): Promise<PaymentLink>;
|
|
351
|
+
/**
|
|
352
|
+
* List payment links for the authenticated user.
|
|
353
|
+
*
|
|
354
|
+
* @param params - Optional pagination parameters (limit, offset).
|
|
355
|
+
* @returns Array of payment link objects.
|
|
356
|
+
* @throws {PulseAuthenticationError} If the API key is invalid.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* ```typescript
|
|
360
|
+
* const links = await pulse.paymentLinks.list({ limit: 10, offset: 0 })
|
|
361
|
+
* for (const link of links) {
|
|
362
|
+
* console.log(link.title, link.amount, link.status)
|
|
363
|
+
* }
|
|
364
|
+
* ```
|
|
365
|
+
*/
|
|
366
|
+
list(params?: ListPaymentLinksParams): Promise<PaymentLink[]>;
|
|
367
|
+
/**
|
|
368
|
+
* Get a single payment link by ID.
|
|
369
|
+
*
|
|
370
|
+
* @param linkId - The payment link UUID.
|
|
371
|
+
* @returns The payment link object.
|
|
372
|
+
* @throws {PulseAuthenticationError} If the API key is invalid.
|
|
373
|
+
* @throws {PulseApiError} With status 404 if the link doesn't exist.
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* ```typescript
|
|
377
|
+
* const link = await pulse.paymentLinks.get('abc-123-def')
|
|
378
|
+
* console.log(link.title, link.amount)
|
|
379
|
+
* ```
|
|
380
|
+
*/
|
|
381
|
+
get(linkId: string): Promise<PaymentLink>;
|
|
382
|
+
/**
|
|
383
|
+
* List payment intents (payment attempts) for a specific payment link.
|
|
384
|
+
*
|
|
385
|
+
* @param linkId - The payment link UUID.
|
|
386
|
+
* @returns Array of payment intent objects.
|
|
387
|
+
* @throws {PulseAuthenticationError} If the API key is invalid.
|
|
388
|
+
*
|
|
389
|
+
* @example
|
|
390
|
+
* ```typescript
|
|
391
|
+
* const intents = await pulse.paymentLinks.listIntents('abc-123-def')
|
|
392
|
+
* const confirmed = intents.filter(i => i.status === 'confirmed')
|
|
393
|
+
* console.log(`${confirmed.length} confirmed payments`)
|
|
394
|
+
* ```
|
|
395
|
+
*/
|
|
396
|
+
listIntents(linkId: string): Promise<PaymentIntent[]>;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Resource for managing webhook subscriptions.
|
|
401
|
+
* Access via `pulse.webhooks`.
|
|
402
|
+
*
|
|
403
|
+
* @example
|
|
404
|
+
* ```typescript
|
|
405
|
+
* const pulse = new Pulse('sk_live_...')
|
|
406
|
+
*
|
|
407
|
+
* // Create a webhook
|
|
408
|
+
* const wh = await pulse.webhooks.create({
|
|
409
|
+
* url: 'https://example.com/webhook',
|
|
410
|
+
* events: ['payment.confirmed'],
|
|
411
|
+
* })
|
|
412
|
+
* console.log(wh.secret) // save this!
|
|
413
|
+
*
|
|
414
|
+
* // List webhooks
|
|
415
|
+
* const list = await pulse.webhooks.list()
|
|
416
|
+
* ```
|
|
417
|
+
*/
|
|
418
|
+
declare class WebhooksResource {
|
|
419
|
+
private readonly client;
|
|
420
|
+
constructor(client: HttpClient);
|
|
421
|
+
/**
|
|
422
|
+
* Create a new webhook subscription.
|
|
423
|
+
* The response includes a `secret` field (64-char hex) used to verify signatures.
|
|
424
|
+
* **Store this secret securely** — it is only returned once at creation time.
|
|
425
|
+
*
|
|
426
|
+
* @param params - Webhook URL and event types to subscribe to.
|
|
427
|
+
* @returns The created webhook with its signing secret.
|
|
428
|
+
* @throws {PulseAuthenticationError} If the API key is invalid.
|
|
429
|
+
*
|
|
430
|
+
* @example
|
|
431
|
+
* ```typescript
|
|
432
|
+
* const wh = await pulse.webhooks.create({
|
|
433
|
+
* url: 'https://example.com/webhook',
|
|
434
|
+
* events: ['payment.confirmed'],
|
|
435
|
+
* })
|
|
436
|
+
* // Save wh.secret to your environment/secrets manager
|
|
437
|
+
* console.log('Webhook secret:', wh.secret)
|
|
438
|
+
* ```
|
|
439
|
+
*/
|
|
440
|
+
create(params: CreateWebhookParams): Promise<WebhookCreated>;
|
|
441
|
+
/**
|
|
442
|
+
* List all webhook subscriptions for the authenticated user.
|
|
443
|
+
*
|
|
444
|
+
* @returns Array of webhook objects (without secrets).
|
|
445
|
+
* @throws {PulseAuthenticationError} If the API key is invalid.
|
|
446
|
+
*
|
|
447
|
+
* @example
|
|
448
|
+
* ```typescript
|
|
449
|
+
* const webhooks = await pulse.webhooks.list()
|
|
450
|
+
* for (const wh of webhooks) {
|
|
451
|
+
* console.log(wh.url, wh.events, wh.isActive)
|
|
452
|
+
* }
|
|
453
|
+
* ```
|
|
454
|
+
*/
|
|
455
|
+
list(): Promise<Webhook[]>;
|
|
456
|
+
/**
|
|
457
|
+
* Delete a webhook subscription.
|
|
458
|
+
*
|
|
459
|
+
* @param id - The webhook UUID to delete.
|
|
460
|
+
* @throws {PulseAuthenticationError} If the API key is invalid.
|
|
461
|
+
*
|
|
462
|
+
* @example
|
|
463
|
+
* ```typescript
|
|
464
|
+
* await pulse.webhooks.delete('webhook-id')
|
|
465
|
+
* ```
|
|
466
|
+
*/
|
|
467
|
+
delete(id: string): Promise<void>;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* Resource for usage-based metering and billing.
|
|
472
|
+
* Access via `pulse.metering`.
|
|
473
|
+
*
|
|
474
|
+
* @example
|
|
475
|
+
* ```typescript
|
|
476
|
+
* const pulse = new Pulse('sk_live_...')
|
|
477
|
+
*
|
|
478
|
+
* // Track a usage event
|
|
479
|
+
* await pulse.metering.track({
|
|
480
|
+
* meterId: 'meter_id',
|
|
481
|
+
* customerId: 'user_123',
|
|
482
|
+
* value: 1500,
|
|
483
|
+
* })
|
|
484
|
+
*
|
|
485
|
+
* // Query aggregated usage
|
|
486
|
+
* const usage = await pulse.metering.getUsage({ customerId: 'user_123' })
|
|
487
|
+
* ```
|
|
488
|
+
*/
|
|
489
|
+
declare class MeteringResource {
|
|
490
|
+
private readonly client;
|
|
491
|
+
constructor(client: HttpClient);
|
|
492
|
+
/**
|
|
493
|
+
* Track a single usage event.
|
|
494
|
+
*
|
|
495
|
+
* @param params - Event parameters (meterId, customerId, value).
|
|
496
|
+
* @returns The created event object.
|
|
497
|
+
*
|
|
498
|
+
* @example
|
|
499
|
+
* ```typescript
|
|
500
|
+
* await pulse.metering.track({
|
|
501
|
+
* meterId: 'tokens',
|
|
502
|
+
* customerId: 'user_123',
|
|
503
|
+
* value: 1500,
|
|
504
|
+
* metadata: { model: 'gpt-4' }
|
|
505
|
+
* })
|
|
506
|
+
* ```
|
|
507
|
+
*/
|
|
508
|
+
track(params: TrackEventParams): Promise<TrackEventResponse>;
|
|
509
|
+
/**
|
|
510
|
+
* Track multiple usage events in a single request.
|
|
511
|
+
*
|
|
512
|
+
* @param events - Array of event parameters.
|
|
513
|
+
* @returns Batch result with accepted/failed counts.
|
|
514
|
+
*
|
|
515
|
+
* @example
|
|
516
|
+
* ```typescript
|
|
517
|
+
* await pulse.metering.trackBatch([
|
|
518
|
+
* { meterId: 'tokens', customerId: 'user_1', value: 500 },
|
|
519
|
+
* { meterId: 'tokens', customerId: 'user_2', value: 1200 },
|
|
520
|
+
* ])
|
|
521
|
+
* ```
|
|
522
|
+
*/
|
|
523
|
+
trackBatch(events: TrackEventParams[]): Promise<BatchTrackResponse>;
|
|
524
|
+
/**
|
|
525
|
+
* Query aggregated usage data.
|
|
526
|
+
*
|
|
527
|
+
* @param query - Optional filters (customerId, date range).
|
|
528
|
+
* @returns Aggregated usage by meter.
|
|
529
|
+
*
|
|
530
|
+
* @example
|
|
531
|
+
* ```typescript
|
|
532
|
+
* const usage = await pulse.metering.getUsage({ customerId: 'user_123' })
|
|
533
|
+
* for (const item of usage.data) {
|
|
534
|
+
* console.log(item.meterName, item.totalValue, item.totalAmount)
|
|
535
|
+
* }
|
|
536
|
+
* ```
|
|
537
|
+
*/
|
|
538
|
+
getUsage(query?: UsageQuery): Promise<UsageResponse>;
|
|
539
|
+
/**
|
|
540
|
+
* List all products.
|
|
541
|
+
*
|
|
542
|
+
* @returns Array of product objects with meters.
|
|
543
|
+
*/
|
|
544
|
+
listProducts(): Promise<MeteringProduct[]>;
|
|
545
|
+
/**
|
|
546
|
+
* Create a new product.
|
|
547
|
+
*
|
|
548
|
+
* @param data - Product data (name, optional description).
|
|
549
|
+
* @returns The created product object.
|
|
550
|
+
*
|
|
551
|
+
* @example
|
|
552
|
+
* ```typescript
|
|
553
|
+
* const product = await pulse.metering.createProduct({
|
|
554
|
+
* name: 'AI Agent',
|
|
555
|
+
* description: 'Usage-based AI agent billing',
|
|
556
|
+
* })
|
|
557
|
+
* ```
|
|
558
|
+
*/
|
|
559
|
+
createProduct(data: CreateProductParams): Promise<MeteringProduct>;
|
|
560
|
+
/**
|
|
561
|
+
* Create a new meter on a product.
|
|
562
|
+
*
|
|
563
|
+
* @param productId - The product UUID.
|
|
564
|
+
* @param data - Meter data (name, displayName, unit, unitPrice).
|
|
565
|
+
* @returns The created meter object.
|
|
566
|
+
*
|
|
567
|
+
* @example
|
|
568
|
+
* ```typescript
|
|
569
|
+
* const meter = await pulse.metering.createMeter('product-id', {
|
|
570
|
+
* name: 'tokens',
|
|
571
|
+
* displayName: 'AI Tokens',
|
|
572
|
+
* unit: 'token',
|
|
573
|
+
* unitPrice: '0.0001',
|
|
574
|
+
* })
|
|
575
|
+
* ```
|
|
576
|
+
*/
|
|
577
|
+
createMeter(productId: string, data: CreateMeterParams): Promise<Meter>;
|
|
578
|
+
/**
|
|
579
|
+
* Create a customer for a product.
|
|
580
|
+
*
|
|
581
|
+
* @param productId - The product UUID.
|
|
582
|
+
* @param data - Customer data (externalId, name, email, metadata).
|
|
583
|
+
* @returns The created customer object.
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* ```typescript
|
|
587
|
+
* const customer = await pulse.metering.createCustomer('product-id', {
|
|
588
|
+
* externalId: 'user_123',
|
|
589
|
+
* name: 'John Doe',
|
|
590
|
+
* email: 'john@example.com',
|
|
591
|
+
* })
|
|
592
|
+
* ```
|
|
593
|
+
*/
|
|
594
|
+
createCustomer(productId: string, data: CreateCustomerParams): Promise<ProductCustomer>;
|
|
595
|
+
/**
|
|
596
|
+
* Get customer usage for a specific product.
|
|
597
|
+
*
|
|
598
|
+
* @param productId - The product UUID.
|
|
599
|
+
* @param customerId - The customer external ID.
|
|
600
|
+
* @param query - Optional date range filters.
|
|
601
|
+
* @returns Aggregated usage by meter for the customer.
|
|
602
|
+
*/
|
|
603
|
+
getCustomerUsage(productId: string, customerId: string, query?: {
|
|
604
|
+
startDate?: string;
|
|
605
|
+
endDate?: string;
|
|
606
|
+
}): Promise<UsageResponse>;
|
|
607
|
+
/**
|
|
608
|
+
* Create a session for tracking multiple events for a customer.
|
|
609
|
+
* Events are accumulated and sent as a batch when `.end()` is called.
|
|
610
|
+
*
|
|
611
|
+
* @param customerId - The customer external ID.
|
|
612
|
+
* @returns A session instance.
|
|
613
|
+
*
|
|
614
|
+
* @example
|
|
615
|
+
* ```typescript
|
|
616
|
+
* const session = pulse.metering.session('user_123')
|
|
617
|
+
* session.track('tokens', 500)
|
|
618
|
+
* session.track('tokens', 300)
|
|
619
|
+
* session.track('requests', 1)
|
|
620
|
+
* await session.end() // sends batch: tokens=800, requests=1
|
|
621
|
+
* ```
|
|
622
|
+
*/
|
|
623
|
+
session(customerId: string): MeteringSession;
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* A session accumulates track calls and sends them as a batch.
|
|
627
|
+
*/
|
|
628
|
+
declare class MeteringSession {
|
|
629
|
+
private readonly metering;
|
|
630
|
+
private readonly customerId;
|
|
631
|
+
private events;
|
|
632
|
+
constructor(metering: MeteringResource, customerId: string);
|
|
633
|
+
/**
|
|
634
|
+
* Queue a tracking event in this session.
|
|
635
|
+
*/
|
|
636
|
+
track(meterId: string, value: number | string, metadata?: Record<string, unknown>): this;
|
|
637
|
+
/**
|
|
638
|
+
* Send all accumulated events as a batch and clear the session.
|
|
639
|
+
*/
|
|
640
|
+
end(): Promise<BatchTrackResponse>;
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* Verify the HMAC-SHA256 signature of an incoming webhook request.
|
|
645
|
+
* Use this to ensure the request came from Pulse and wasn't tampered with.
|
|
646
|
+
*
|
|
647
|
+
* The signature is sent in the `X-Pulse-Signature` header as `sha256={hex}`.
|
|
648
|
+
*
|
|
649
|
+
* @param rawBody - The raw request body as a string (not parsed JSON).
|
|
650
|
+
* @param signatureHeader - The `X-Pulse-Signature` header value (e.g. `"sha256=abc123..."`).
|
|
651
|
+
* @param secret - Your webhook signing secret (64-char hex, from webhook creation).
|
|
652
|
+
* @returns `true` if the signature is valid, `false` otherwise.
|
|
653
|
+
*
|
|
654
|
+
* @example
|
|
655
|
+
* ```typescript
|
|
656
|
+
* import { Pulse } from '@beinfi/pulse-sdk'
|
|
657
|
+
*
|
|
658
|
+
* // Express/Node.js example
|
|
659
|
+
* app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
|
|
660
|
+
* const isValid = Pulse.webhooks.verifySignature(
|
|
661
|
+
* req.body.toString(),
|
|
662
|
+
* req.headers['x-pulse-signature'] as string,
|
|
663
|
+
* process.env.PULSE_WEBHOOK_SECRET!
|
|
664
|
+
* )
|
|
665
|
+
*
|
|
666
|
+
* if (!isValid) {
|
|
667
|
+
* return res.status(401).send('Invalid signature')
|
|
668
|
+
* }
|
|
669
|
+
*
|
|
670
|
+
* const event = JSON.parse(req.body.toString())
|
|
671
|
+
* console.log('Payment confirmed:', event.paymentIntentId)
|
|
672
|
+
* res.sendStatus(200)
|
|
673
|
+
* })
|
|
674
|
+
* ```
|
|
675
|
+
*
|
|
676
|
+
* @example
|
|
677
|
+
* ```typescript
|
|
678
|
+
* // Standalone import
|
|
679
|
+
* import { verifyWebhookSignature } from '@beinfi/pulse-sdk'
|
|
680
|
+
*
|
|
681
|
+
* const valid = verifyWebhookSignature(rawBody, signatureHeader, secret)
|
|
682
|
+
* ```
|
|
683
|
+
*/
|
|
684
|
+
declare function verifyWebhookSignature(rawBody: string, signatureHeader: string, secret: string): boolean;
|
|
685
|
+
|
|
686
|
+
/**
|
|
687
|
+
* Successful payment data returned by the checkout widget.
|
|
688
|
+
*/
|
|
689
|
+
interface CheckoutPayment {
|
|
690
|
+
/** ID of the completed payment intent. */
|
|
691
|
+
paymentIntentId: string;
|
|
692
|
+
/** Payment amount as a decimal string. */
|
|
693
|
+
amount: string;
|
|
694
|
+
/** Currency code (e.g. `"USD"`). */
|
|
695
|
+
currency: string;
|
|
696
|
+
/** Payment method used (e.g. `"crypto"`, `"pix"`). */
|
|
697
|
+
method: string;
|
|
698
|
+
/** Blockchain transaction hash (present for crypto payments). */
|
|
699
|
+
txHash?: string;
|
|
700
|
+
}
|
|
701
|
+
/**
|
|
702
|
+
* Error object emitted by the checkout widget.
|
|
703
|
+
*/
|
|
704
|
+
interface CheckoutError {
|
|
705
|
+
/** Human-readable error message. */
|
|
706
|
+
message: string;
|
|
707
|
+
/** Machine-readable error code. */
|
|
708
|
+
code?: string;
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Theme customization for the checkout widget.
|
|
712
|
+
* All values are CSS color strings (hex, rgb, hsl, etc.).
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* ```typescript
|
|
716
|
+
* const instance = Pulse.checkout.mount('#checkout', {
|
|
717
|
+
* linkId: 'link-id',
|
|
718
|
+
* theme: {
|
|
719
|
+
* background: '#1a1a2e',
|
|
720
|
+
* foreground: '#ffffff',
|
|
721
|
+
* accent: '#e94560',
|
|
722
|
+
* }
|
|
723
|
+
* })
|
|
724
|
+
* ```
|
|
725
|
+
*/
|
|
726
|
+
interface CheckoutTheme {
|
|
727
|
+
/** Background color of the checkout widget. */
|
|
728
|
+
background?: string;
|
|
729
|
+
/** Primary text color. */
|
|
730
|
+
foreground?: string;
|
|
731
|
+
/** Card/surface background color. */
|
|
732
|
+
card?: string;
|
|
733
|
+
/** Accent color for buttons and interactive elements. */
|
|
734
|
+
accent?: string;
|
|
735
|
+
/** Text color on accent-colored elements. */
|
|
736
|
+
accentForeground?: string;
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Options for mounting the Pulse checkout widget.
|
|
740
|
+
*
|
|
741
|
+
* @example
|
|
742
|
+
* ```typescript
|
|
743
|
+
* const instance = Pulse.checkout.mount('#checkout', {
|
|
744
|
+
* linkId: 'abc-123',
|
|
745
|
+
* onSuccess: (payment) => console.log('Paid!', payment),
|
|
746
|
+
* onError: (err) => console.error('Failed:', err.message),
|
|
747
|
+
* })
|
|
748
|
+
* ```
|
|
749
|
+
*/
|
|
750
|
+
interface CheckoutMountOptions {
|
|
751
|
+
/** The payment link ID to load in the checkout widget. */
|
|
752
|
+
linkId: string;
|
|
753
|
+
/** Override the checkout base URL. Defaults to `https://pulse.beinfi.com`. */
|
|
754
|
+
baseUrl?: string;
|
|
755
|
+
/** Custom theme colors for the checkout widget. */
|
|
756
|
+
theme?: CheckoutTheme;
|
|
757
|
+
/** Called when the checkout iframe is ready and rendered. */
|
|
758
|
+
onReady?: () => void;
|
|
759
|
+
/** Called when the payment is successfully confirmed. */
|
|
760
|
+
onSuccess?: (payment: CheckoutPayment) => void;
|
|
761
|
+
/** Called when a payment error occurs. */
|
|
762
|
+
onError?: (error: CheckoutError) => void;
|
|
763
|
+
/** Called when the checkout widget is unmounted/closed. */
|
|
764
|
+
onClose?: () => void;
|
|
765
|
+
}
|
|
766
|
+
/**
|
|
767
|
+
* Handle returned by {@link mountCheckout}. Use it to control the checkout widget lifecycle.
|
|
768
|
+
*
|
|
769
|
+
* @example
|
|
770
|
+
* ```typescript
|
|
771
|
+
* const instance = Pulse.checkout.mount('#checkout', { linkId: 'abc-123' })
|
|
772
|
+
*
|
|
773
|
+
* // Listen for events
|
|
774
|
+
* instance.on('success', (payment) => console.log('Paid!', payment))
|
|
775
|
+
*
|
|
776
|
+
* // Clean up when done
|
|
777
|
+
* instance.unmount()
|
|
778
|
+
* ```
|
|
779
|
+
*/
|
|
780
|
+
interface CheckoutInstance {
|
|
781
|
+
/** Remove the checkout iframe and clean up event listeners. */
|
|
782
|
+
unmount: () => void;
|
|
783
|
+
/** Subscribe to checkout events: `"ready"`, `"success"`, `"error"`, `"close"`. */
|
|
784
|
+
on: (event: 'ready' | 'success' | 'error' | 'close', handler: (...args: any[]) => void) => void;
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
/**
|
|
788
|
+
* Mount the Pulse checkout widget into a DOM element.
|
|
789
|
+
* Embeds an iframe-based checkout that handles payment flow (crypto, PIX)
|
|
790
|
+
* and communicates back via postMessage events.
|
|
791
|
+
*
|
|
792
|
+
* @param selector - A CSS selector string or an HTMLElement to mount the checkout into.
|
|
793
|
+
* @param options - Checkout configuration including the payment link ID and event callbacks.
|
|
794
|
+
* @returns A {@link CheckoutInstance} with `unmount()` and `on()` methods.
|
|
795
|
+
* @throws {Error} If the container element is not found.
|
|
796
|
+
*
|
|
797
|
+
* @example
|
|
798
|
+
* ```typescript
|
|
799
|
+
* import { Pulse } from '@beinfi/pulse-sdk'
|
|
800
|
+
*
|
|
801
|
+
* // Mount into a div
|
|
802
|
+
* const checkout = Pulse.checkout.mount('#checkout-container', {
|
|
803
|
+
* linkId: 'abc-123',
|
|
804
|
+
* theme: {
|
|
805
|
+
* background: '#0f0f23',
|
|
806
|
+
* accent: '#6366f1',
|
|
807
|
+
* },
|
|
808
|
+
* onReady: () => console.log('Checkout loaded'),
|
|
809
|
+
* onSuccess: (payment) => {
|
|
810
|
+
* console.log('Payment confirmed!', payment.paymentIntentId)
|
|
811
|
+
* checkout.unmount()
|
|
812
|
+
* },
|
|
813
|
+
* onError: (err) => console.error('Payment failed:', err.message),
|
|
814
|
+
* })
|
|
815
|
+
*
|
|
816
|
+
* // Alternative: use .on() event listeners
|
|
817
|
+
* checkout.on('success', (payment) => {
|
|
818
|
+
* window.location.href = '/thank-you'
|
|
819
|
+
* })
|
|
820
|
+
* ```
|
|
821
|
+
*
|
|
822
|
+
* @example
|
|
823
|
+
* ```typescript
|
|
824
|
+
* // Standalone import
|
|
825
|
+
* import { mountCheckout } from '@beinfi/pulse-sdk'
|
|
826
|
+
*
|
|
827
|
+
* const instance = mountCheckout('#checkout', { linkId: 'abc-123' })
|
|
828
|
+
* ```
|
|
829
|
+
*/
|
|
830
|
+
declare function mountCheckout(selector: string | HTMLElement, options: CheckoutMountOptions): CheckoutInstance;
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* Main entry point for the Pulse SDK.
|
|
834
|
+
* Create an instance with your API key to access payment links and webhooks.
|
|
835
|
+
*
|
|
836
|
+
* @example
|
|
837
|
+
* ```typescript
|
|
838
|
+
* import { Pulse } from '@beinfi/pulse-sdk'
|
|
839
|
+
*
|
|
840
|
+
* // Quick setup with just an API key
|
|
841
|
+
* const pulse = new Pulse('sk_live_...')
|
|
842
|
+
*
|
|
843
|
+
* // Or with full config
|
|
844
|
+
* const pulse = new Pulse({
|
|
845
|
+
* apiKey: 'sk_live_...',
|
|
846
|
+
* baseUrl: 'https://api.beinfi.com',
|
|
847
|
+
* })
|
|
848
|
+
*
|
|
849
|
+
* // Create a payment link
|
|
850
|
+
* const link = await pulse.paymentLinks.create({
|
|
851
|
+
* title: 'Order #42',
|
|
852
|
+
* amount: '100.00',
|
|
853
|
+
* })
|
|
854
|
+
*
|
|
855
|
+
* // Verify webhook signatures (static method, no instance needed)
|
|
856
|
+
* const isValid = Pulse.webhooks.verifySignature(rawBody, signature, secret)
|
|
857
|
+
*
|
|
858
|
+
* // Mount checkout widget (static method, browser only)
|
|
859
|
+
* const checkout = Pulse.checkout.mount('#container', { linkId: link.id })
|
|
860
|
+
* ```
|
|
861
|
+
*/
|
|
862
|
+
declare class Pulse {
|
|
863
|
+
/** Resource for creating, listing, and fetching payment links. */
|
|
864
|
+
readonly paymentLinks: PaymentLinksResource;
|
|
865
|
+
/** Resource for creating, listing, and deleting webhook subscriptions. */
|
|
866
|
+
readonly webhooks: WebhooksResource;
|
|
867
|
+
/** Resource for usage-based metering, tracking events, and querying usage. */
|
|
868
|
+
readonly metering: MeteringResource;
|
|
869
|
+
private readonly client;
|
|
870
|
+
/**
|
|
871
|
+
* Static utilities for verifying webhook signatures.
|
|
872
|
+
* Does not require a Pulse instance — useful in webhook handler endpoints.
|
|
873
|
+
*
|
|
874
|
+
* @example
|
|
875
|
+
* ```typescript
|
|
876
|
+
* const isValid = Pulse.webhooks.verifySignature(
|
|
877
|
+
* rawBody,
|
|
878
|
+
* req.headers['x-pulse-signature'],
|
|
879
|
+
* process.env.PULSE_WEBHOOK_SECRET
|
|
880
|
+
* )
|
|
881
|
+
* ```
|
|
882
|
+
*/
|
|
883
|
+
static webhooks: {
|
|
884
|
+
verifySignature: typeof verifyWebhookSignature;
|
|
885
|
+
};
|
|
886
|
+
/**
|
|
887
|
+
* Static utilities for mounting the checkout widget.
|
|
888
|
+
* Browser-only — embeds an iframe-based checkout for a payment link.
|
|
889
|
+
*
|
|
890
|
+
* @example
|
|
891
|
+
* ```typescript
|
|
892
|
+
* const instance = Pulse.checkout.mount('#checkout', {
|
|
893
|
+
* linkId: 'abc-123',
|
|
894
|
+
* onSuccess: (payment) => console.log('Paid!', payment),
|
|
895
|
+
* })
|
|
896
|
+
* ```
|
|
897
|
+
*/
|
|
898
|
+
static checkout: {
|
|
899
|
+
mount: typeof mountCheckout;
|
|
900
|
+
};
|
|
901
|
+
/**
|
|
902
|
+
* Create a new Pulse SDK client.
|
|
903
|
+
*
|
|
904
|
+
* @param config - Either an API key string (`"sk_live_..."`) or a {@link PulseConfig} object.
|
|
905
|
+
* @throws {PulseError} If the API key doesn't start with `"sk_live_"`.
|
|
906
|
+
*
|
|
907
|
+
* @example
|
|
908
|
+
* ```typescript
|
|
909
|
+
* // String shorthand
|
|
910
|
+
* const pulse = new Pulse('sk_live_...')
|
|
911
|
+
*
|
|
912
|
+
* // Config object
|
|
913
|
+
* const pulse = new Pulse({ apiKey: 'sk_live_...', baseUrl: 'https://api.beinfi.com' })
|
|
914
|
+
* ```
|
|
915
|
+
*/
|
|
916
|
+
constructor(config: string | PulseConfig);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
interface PulseMiddlewareConfig {
|
|
920
|
+
/** Pulse SDK instance (already configured with API key) */
|
|
921
|
+
pulse: Pulse;
|
|
922
|
+
/** Customer ID — string or function that resolves at call time */
|
|
923
|
+
customerId: string | (() => string | Promise<string>);
|
|
924
|
+
/** Meter IDs for input and output tokens */
|
|
925
|
+
meters: {
|
|
926
|
+
input: string;
|
|
927
|
+
output: string;
|
|
928
|
+
};
|
|
929
|
+
/** Optional metadata to attach to every event */
|
|
930
|
+
metadata?: Record<string, unknown>;
|
|
931
|
+
}
|
|
932
|
+
declare function pulseMiddleware(config: PulseMiddlewareConfig): LanguageModelV3Middleware;
|
|
933
|
+
|
|
934
|
+
export { type PulseMiddlewareConfig, pulseMiddleware };
|