services-as-software 2.0.1 → 2.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/CHANGELOG.md +28 -0
- package/examples/client-usage.js +68 -0
- package/examples/translation-service.js +214 -0
- package/package.json +4 -5
- package/src/client.js +102 -0
- package/src/endpoint.js +95 -0
- package/src/entities/billing.js +953 -0
- package/src/entities/customers.js +678 -0
- package/src/entities/delivery.js +889 -0
- package/src/entities/index.js +88 -0
- package/src/entities/operations.js +1009 -0
- package/src/entities/orchestration.js +882 -0
- package/src/entities/services.js +804 -0
- package/src/helpers.js +399 -0
- package/src/index.js +17 -0
- package/src/provider.js +157 -0
- package/src/service.js +205 -0
- package/src/service.test.js +164 -0
- package/src/types.js +4 -0
|
@@ -0,0 +1,953 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Billing Entity Types (Nouns)
|
|
3
|
+
*
|
|
4
|
+
* Billing & commerce: ServiceQuote, ServiceOrder, ServiceSubscription, Usage, Invoice, Payment
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// ServiceQuote
|
|
10
|
+
// =============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* ServiceQuote entity
|
|
13
|
+
*
|
|
14
|
+
* Price quote for a service.
|
|
15
|
+
*/
|
|
16
|
+
export const ServiceQuote = {
|
|
17
|
+
singular: 'service-quote',
|
|
18
|
+
plural: 'service-quotes',
|
|
19
|
+
description: 'A price quote for a service',
|
|
20
|
+
properties: {
|
|
21
|
+
// Identity
|
|
22
|
+
id: {
|
|
23
|
+
type: 'string',
|
|
24
|
+
description: 'Quote ID',
|
|
25
|
+
},
|
|
26
|
+
number: {
|
|
27
|
+
type: 'string',
|
|
28
|
+
optional: true,
|
|
29
|
+
description: 'Quote number',
|
|
30
|
+
},
|
|
31
|
+
// Details
|
|
32
|
+
title: {
|
|
33
|
+
type: 'string',
|
|
34
|
+
optional: true,
|
|
35
|
+
description: 'Quote title',
|
|
36
|
+
},
|
|
37
|
+
description: {
|
|
38
|
+
type: 'string',
|
|
39
|
+
optional: true,
|
|
40
|
+
description: 'Quote description',
|
|
41
|
+
},
|
|
42
|
+
scope: {
|
|
43
|
+
type: 'string',
|
|
44
|
+
optional: true,
|
|
45
|
+
description: 'Scope of work',
|
|
46
|
+
},
|
|
47
|
+
// Line Items
|
|
48
|
+
lineItems: {
|
|
49
|
+
type: 'json',
|
|
50
|
+
optional: true,
|
|
51
|
+
description: 'Quote line items',
|
|
52
|
+
},
|
|
53
|
+
// Pricing
|
|
54
|
+
subtotal: {
|
|
55
|
+
type: 'number',
|
|
56
|
+
optional: true,
|
|
57
|
+
description: 'Subtotal before tax/discount',
|
|
58
|
+
},
|
|
59
|
+
discount: {
|
|
60
|
+
type: 'number',
|
|
61
|
+
optional: true,
|
|
62
|
+
description: 'Discount amount',
|
|
63
|
+
},
|
|
64
|
+
discountPercent: {
|
|
65
|
+
type: 'number',
|
|
66
|
+
optional: true,
|
|
67
|
+
description: 'Discount percentage',
|
|
68
|
+
},
|
|
69
|
+
tax: {
|
|
70
|
+
type: 'number',
|
|
71
|
+
optional: true,
|
|
72
|
+
description: 'Tax amount',
|
|
73
|
+
},
|
|
74
|
+
total: {
|
|
75
|
+
type: 'number',
|
|
76
|
+
description: 'Total quoted amount',
|
|
77
|
+
},
|
|
78
|
+
currency: {
|
|
79
|
+
type: 'string',
|
|
80
|
+
optional: true,
|
|
81
|
+
description: 'Currency code',
|
|
82
|
+
},
|
|
83
|
+
// Terms
|
|
84
|
+
paymentTerms: {
|
|
85
|
+
type: 'string',
|
|
86
|
+
optional: true,
|
|
87
|
+
description: 'Payment terms',
|
|
88
|
+
examples: ['net-30', 'net-60', 'due-on-receipt', 'milestone', 'upfront'],
|
|
89
|
+
},
|
|
90
|
+
deliveryTerms: {
|
|
91
|
+
type: 'string',
|
|
92
|
+
optional: true,
|
|
93
|
+
description: 'Delivery terms',
|
|
94
|
+
},
|
|
95
|
+
// Validity
|
|
96
|
+
validFrom: {
|
|
97
|
+
type: 'date',
|
|
98
|
+
optional: true,
|
|
99
|
+
description: 'Valid from date',
|
|
100
|
+
},
|
|
101
|
+
validUntil: {
|
|
102
|
+
type: 'date',
|
|
103
|
+
optional: true,
|
|
104
|
+
description: 'Valid until date',
|
|
105
|
+
},
|
|
106
|
+
// Acceptance
|
|
107
|
+
acceptedAt: {
|
|
108
|
+
type: 'date',
|
|
109
|
+
optional: true,
|
|
110
|
+
description: 'Acceptance date',
|
|
111
|
+
},
|
|
112
|
+
acceptedBy: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
optional: true,
|
|
115
|
+
description: 'Accepted by',
|
|
116
|
+
},
|
|
117
|
+
// Status
|
|
118
|
+
status: {
|
|
119
|
+
type: 'string',
|
|
120
|
+
description: 'Quote status',
|
|
121
|
+
examples: ['draft', 'sent', 'viewed', 'accepted', 'rejected', 'expired', 'superseded'],
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
relationships: {
|
|
125
|
+
service: {
|
|
126
|
+
type: 'ProductizedService',
|
|
127
|
+
description: 'Quoted service',
|
|
128
|
+
},
|
|
129
|
+
offering: {
|
|
130
|
+
type: 'ServiceOffering',
|
|
131
|
+
required: false,
|
|
132
|
+
description: 'Service offering',
|
|
133
|
+
},
|
|
134
|
+
customer: {
|
|
135
|
+
type: 'ServiceCustomer',
|
|
136
|
+
description: 'Customer',
|
|
137
|
+
},
|
|
138
|
+
order: {
|
|
139
|
+
type: 'ServiceOrder',
|
|
140
|
+
required: false,
|
|
141
|
+
description: 'Resulting order',
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
actions: [
|
|
145
|
+
'create',
|
|
146
|
+
'update',
|
|
147
|
+
'send',
|
|
148
|
+
'resend',
|
|
149
|
+
'accept',
|
|
150
|
+
'reject',
|
|
151
|
+
'expire',
|
|
152
|
+
'supersede',
|
|
153
|
+
],
|
|
154
|
+
events: [
|
|
155
|
+
'created',
|
|
156
|
+
'updated',
|
|
157
|
+
'sent',
|
|
158
|
+
'viewed',
|
|
159
|
+
'accepted',
|
|
160
|
+
'rejected',
|
|
161
|
+
'expired',
|
|
162
|
+
'superseded',
|
|
163
|
+
],
|
|
164
|
+
};
|
|
165
|
+
// =============================================================================
|
|
166
|
+
// ServiceOrder
|
|
167
|
+
// =============================================================================
|
|
168
|
+
/**
|
|
169
|
+
* ServiceOrder entity
|
|
170
|
+
*
|
|
171
|
+
* Customer order for a service.
|
|
172
|
+
*/
|
|
173
|
+
export const ServiceOrder = {
|
|
174
|
+
singular: 'service-order',
|
|
175
|
+
plural: 'service-orders',
|
|
176
|
+
description: 'A customer order for a service',
|
|
177
|
+
properties: {
|
|
178
|
+
// Identity
|
|
179
|
+
id: {
|
|
180
|
+
type: 'string',
|
|
181
|
+
description: 'Order ID',
|
|
182
|
+
},
|
|
183
|
+
orderNumber: {
|
|
184
|
+
type: 'string',
|
|
185
|
+
optional: true,
|
|
186
|
+
description: 'Order number',
|
|
187
|
+
},
|
|
188
|
+
// Details
|
|
189
|
+
description: {
|
|
190
|
+
type: 'string',
|
|
191
|
+
optional: true,
|
|
192
|
+
description: 'Order description',
|
|
193
|
+
},
|
|
194
|
+
requirements: {
|
|
195
|
+
type: 'json',
|
|
196
|
+
optional: true,
|
|
197
|
+
description: 'Customer requirements',
|
|
198
|
+
},
|
|
199
|
+
notes: {
|
|
200
|
+
type: 'string',
|
|
201
|
+
optional: true,
|
|
202
|
+
description: 'Order notes',
|
|
203
|
+
},
|
|
204
|
+
// Line Items
|
|
205
|
+
lineItems: {
|
|
206
|
+
type: 'json',
|
|
207
|
+
optional: true,
|
|
208
|
+
description: 'Order line items',
|
|
209
|
+
},
|
|
210
|
+
quantity: {
|
|
211
|
+
type: 'number',
|
|
212
|
+
optional: true,
|
|
213
|
+
description: 'Quantity ordered',
|
|
214
|
+
},
|
|
215
|
+
// Pricing
|
|
216
|
+
subtotal: {
|
|
217
|
+
type: 'number',
|
|
218
|
+
optional: true,
|
|
219
|
+
description: 'Subtotal',
|
|
220
|
+
},
|
|
221
|
+
discount: {
|
|
222
|
+
type: 'number',
|
|
223
|
+
optional: true,
|
|
224
|
+
description: 'Discount amount',
|
|
225
|
+
},
|
|
226
|
+
tax: {
|
|
227
|
+
type: 'number',
|
|
228
|
+
optional: true,
|
|
229
|
+
description: 'Tax amount',
|
|
230
|
+
},
|
|
231
|
+
total: {
|
|
232
|
+
type: 'number',
|
|
233
|
+
description: 'Total amount',
|
|
234
|
+
},
|
|
235
|
+
currency: {
|
|
236
|
+
type: 'string',
|
|
237
|
+
optional: true,
|
|
238
|
+
description: 'Currency code',
|
|
239
|
+
},
|
|
240
|
+
// Delivery
|
|
241
|
+
deliveryMethod: {
|
|
242
|
+
type: 'string',
|
|
243
|
+
optional: true,
|
|
244
|
+
description: 'Delivery method',
|
|
245
|
+
},
|
|
246
|
+
expectedDelivery: {
|
|
247
|
+
type: 'date',
|
|
248
|
+
optional: true,
|
|
249
|
+
description: 'Expected delivery date',
|
|
250
|
+
},
|
|
251
|
+
actualDelivery: {
|
|
252
|
+
type: 'date',
|
|
253
|
+
optional: true,
|
|
254
|
+
description: 'Actual delivery date',
|
|
255
|
+
},
|
|
256
|
+
// Priority
|
|
257
|
+
priority: {
|
|
258
|
+
type: 'string',
|
|
259
|
+
optional: true,
|
|
260
|
+
description: 'Order priority',
|
|
261
|
+
examples: ['standard', 'rush', 'express', 'critical'],
|
|
262
|
+
},
|
|
263
|
+
// Dates
|
|
264
|
+
orderedAt: {
|
|
265
|
+
type: 'date',
|
|
266
|
+
optional: true,
|
|
267
|
+
description: 'Order date',
|
|
268
|
+
},
|
|
269
|
+
completedAt: {
|
|
270
|
+
type: 'date',
|
|
271
|
+
optional: true,
|
|
272
|
+
description: 'Completion date',
|
|
273
|
+
},
|
|
274
|
+
// Status
|
|
275
|
+
status: {
|
|
276
|
+
type: 'string',
|
|
277
|
+
description: 'Order status',
|
|
278
|
+
examples: ['pending', 'confirmed', 'processing', 'in-progress', 'review', 'completed', 'delivered', 'cancelled', 'refunded'],
|
|
279
|
+
},
|
|
280
|
+
fulfillmentStatus: {
|
|
281
|
+
type: 'string',
|
|
282
|
+
optional: true,
|
|
283
|
+
description: 'Fulfillment status',
|
|
284
|
+
examples: ['unfulfilled', 'partial', 'fulfilled'],
|
|
285
|
+
},
|
|
286
|
+
paymentStatus: {
|
|
287
|
+
type: 'string',
|
|
288
|
+
optional: true,
|
|
289
|
+
description: 'Payment status',
|
|
290
|
+
examples: ['unpaid', 'partial', 'paid', 'refunded'],
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
relationships: {
|
|
294
|
+
service: {
|
|
295
|
+
type: 'ProductizedService',
|
|
296
|
+
description: 'Service ordered',
|
|
297
|
+
},
|
|
298
|
+
offering: {
|
|
299
|
+
type: 'ServiceOffering',
|
|
300
|
+
required: false,
|
|
301
|
+
description: 'Service offering',
|
|
302
|
+
},
|
|
303
|
+
customer: {
|
|
304
|
+
type: 'ServiceCustomer',
|
|
305
|
+
description: 'Customer',
|
|
306
|
+
},
|
|
307
|
+
quote: {
|
|
308
|
+
type: 'ServiceQuote',
|
|
309
|
+
required: false,
|
|
310
|
+
description: 'Source quote',
|
|
311
|
+
},
|
|
312
|
+
executions: {
|
|
313
|
+
type: 'ServiceExecution[]',
|
|
314
|
+
description: 'Service executions',
|
|
315
|
+
},
|
|
316
|
+
invoices: {
|
|
317
|
+
type: 'Invoice[]',
|
|
318
|
+
description: 'Related invoices',
|
|
319
|
+
},
|
|
320
|
+
},
|
|
321
|
+
actions: [
|
|
322
|
+
'create',
|
|
323
|
+
'confirm',
|
|
324
|
+
'process',
|
|
325
|
+
'start',
|
|
326
|
+
'complete',
|
|
327
|
+
'deliver',
|
|
328
|
+
'cancel',
|
|
329
|
+
'refund',
|
|
330
|
+
],
|
|
331
|
+
events: [
|
|
332
|
+
'created',
|
|
333
|
+
'confirmed',
|
|
334
|
+
'processing',
|
|
335
|
+
'started',
|
|
336
|
+
'completed',
|
|
337
|
+
'delivered',
|
|
338
|
+
'cancelled',
|
|
339
|
+
'refunded',
|
|
340
|
+
],
|
|
341
|
+
};
|
|
342
|
+
// =============================================================================
|
|
343
|
+
// ServiceSubscription
|
|
344
|
+
// =============================================================================
|
|
345
|
+
/**
|
|
346
|
+
* ServiceSubscription entity
|
|
347
|
+
*
|
|
348
|
+
* Recurring service subscription.
|
|
349
|
+
*/
|
|
350
|
+
export const ServiceSubscription = {
|
|
351
|
+
singular: 'service-subscription',
|
|
352
|
+
plural: 'service-subscriptions',
|
|
353
|
+
description: 'A recurring subscription to a service',
|
|
354
|
+
properties: {
|
|
355
|
+
// Identity
|
|
356
|
+
id: {
|
|
357
|
+
type: 'string',
|
|
358
|
+
description: 'Subscription ID',
|
|
359
|
+
},
|
|
360
|
+
// Billing
|
|
361
|
+
billingCycle: {
|
|
362
|
+
type: 'string',
|
|
363
|
+
description: 'Billing cycle',
|
|
364
|
+
examples: ['monthly', 'quarterly', 'yearly'],
|
|
365
|
+
},
|
|
366
|
+
price: {
|
|
367
|
+
type: 'number',
|
|
368
|
+
description: 'Subscription price',
|
|
369
|
+
},
|
|
370
|
+
currency: {
|
|
371
|
+
type: 'string',
|
|
372
|
+
optional: true,
|
|
373
|
+
description: 'Currency code',
|
|
374
|
+
},
|
|
375
|
+
// Period
|
|
376
|
+
currentPeriodStart: {
|
|
377
|
+
type: 'date',
|
|
378
|
+
optional: true,
|
|
379
|
+
description: 'Current period start',
|
|
380
|
+
},
|
|
381
|
+
currentPeriodEnd: {
|
|
382
|
+
type: 'date',
|
|
383
|
+
optional: true,
|
|
384
|
+
description: 'Current period end',
|
|
385
|
+
},
|
|
386
|
+
nextBillingDate: {
|
|
387
|
+
type: 'date',
|
|
388
|
+
optional: true,
|
|
389
|
+
description: 'Next billing date',
|
|
390
|
+
},
|
|
391
|
+
// Trial
|
|
392
|
+
trialStart: {
|
|
393
|
+
type: 'date',
|
|
394
|
+
optional: true,
|
|
395
|
+
description: 'Trial start date',
|
|
396
|
+
},
|
|
397
|
+
trialEnd: {
|
|
398
|
+
type: 'date',
|
|
399
|
+
optional: true,
|
|
400
|
+
description: 'Trial end date',
|
|
401
|
+
},
|
|
402
|
+
onTrial: {
|
|
403
|
+
type: 'boolean',
|
|
404
|
+
optional: true,
|
|
405
|
+
description: 'Currently on trial',
|
|
406
|
+
},
|
|
407
|
+
// Usage
|
|
408
|
+
usageThisPeriod: {
|
|
409
|
+
type: 'json',
|
|
410
|
+
optional: true,
|
|
411
|
+
description: 'Usage in current period',
|
|
412
|
+
},
|
|
413
|
+
usageLimits: {
|
|
414
|
+
type: 'json',
|
|
415
|
+
optional: true,
|
|
416
|
+
description: 'Usage limits',
|
|
417
|
+
},
|
|
418
|
+
// Entitlements
|
|
419
|
+
entitlements: {
|
|
420
|
+
type: 'string',
|
|
421
|
+
array: true,
|
|
422
|
+
optional: true,
|
|
423
|
+
description: 'Active entitlements',
|
|
424
|
+
},
|
|
425
|
+
// Cancellation
|
|
426
|
+
cancelAtPeriodEnd: {
|
|
427
|
+
type: 'boolean',
|
|
428
|
+
optional: true,
|
|
429
|
+
description: 'Cancel at period end',
|
|
430
|
+
},
|
|
431
|
+
cancelledAt: {
|
|
432
|
+
type: 'date',
|
|
433
|
+
optional: true,
|
|
434
|
+
description: 'Cancellation date',
|
|
435
|
+
},
|
|
436
|
+
cancellationReason: {
|
|
437
|
+
type: 'string',
|
|
438
|
+
optional: true,
|
|
439
|
+
description: 'Cancellation reason',
|
|
440
|
+
},
|
|
441
|
+
// Dates
|
|
442
|
+
startedAt: {
|
|
443
|
+
type: 'date',
|
|
444
|
+
optional: true,
|
|
445
|
+
description: 'Subscription start',
|
|
446
|
+
},
|
|
447
|
+
endedAt: {
|
|
448
|
+
type: 'date',
|
|
449
|
+
optional: true,
|
|
450
|
+
description: 'Subscription end',
|
|
451
|
+
},
|
|
452
|
+
// Status
|
|
453
|
+
status: {
|
|
454
|
+
type: 'string',
|
|
455
|
+
description: 'Subscription status',
|
|
456
|
+
examples: ['trialing', 'active', 'past_due', 'paused', 'cancelled', 'expired'],
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
relationships: {
|
|
460
|
+
service: {
|
|
461
|
+
type: 'ProductizedService',
|
|
462
|
+
description: 'Service subscribed to',
|
|
463
|
+
},
|
|
464
|
+
plan: {
|
|
465
|
+
type: 'ServicePlan',
|
|
466
|
+
description: 'Subscription plan',
|
|
467
|
+
},
|
|
468
|
+
customer: {
|
|
469
|
+
type: 'ServiceCustomer',
|
|
470
|
+
description: 'Customer',
|
|
471
|
+
},
|
|
472
|
+
invoices: {
|
|
473
|
+
type: 'Invoice[]',
|
|
474
|
+
description: 'Subscription invoices',
|
|
475
|
+
},
|
|
476
|
+
payments: {
|
|
477
|
+
type: 'Payment[]',
|
|
478
|
+
description: 'Subscription payments',
|
|
479
|
+
},
|
|
480
|
+
},
|
|
481
|
+
actions: [
|
|
482
|
+
'create',
|
|
483
|
+
'activate',
|
|
484
|
+
'pause',
|
|
485
|
+
'resume',
|
|
486
|
+
'upgrade',
|
|
487
|
+
'downgrade',
|
|
488
|
+
'cancel',
|
|
489
|
+
'renew',
|
|
490
|
+
],
|
|
491
|
+
events: [
|
|
492
|
+
'created',
|
|
493
|
+
'activated',
|
|
494
|
+
'paused',
|
|
495
|
+
'resumed',
|
|
496
|
+
'upgraded',
|
|
497
|
+
'downgraded',
|
|
498
|
+
'cancelled',
|
|
499
|
+
'renewed',
|
|
500
|
+
'trialEnded',
|
|
501
|
+
],
|
|
502
|
+
};
|
|
503
|
+
// =============================================================================
|
|
504
|
+
// Usage
|
|
505
|
+
// =============================================================================
|
|
506
|
+
/**
|
|
507
|
+
* Usage entity
|
|
508
|
+
*
|
|
509
|
+
* Service usage tracking record.
|
|
510
|
+
*/
|
|
511
|
+
export const Usage = {
|
|
512
|
+
singular: 'usage',
|
|
513
|
+
plural: 'usages',
|
|
514
|
+
description: 'A service usage tracking record',
|
|
515
|
+
properties: {
|
|
516
|
+
// Identity
|
|
517
|
+
id: {
|
|
518
|
+
type: 'string',
|
|
519
|
+
description: 'Usage record ID',
|
|
520
|
+
},
|
|
521
|
+
// Resource
|
|
522
|
+
resource: {
|
|
523
|
+
type: 'string',
|
|
524
|
+
description: 'Resource used',
|
|
525
|
+
},
|
|
526
|
+
resourceType: {
|
|
527
|
+
type: 'string',
|
|
528
|
+
optional: true,
|
|
529
|
+
description: 'Resource type',
|
|
530
|
+
examples: ['api-call', 'execution', 'storage', 'compute', 'tokens', 'bandwidth'],
|
|
531
|
+
},
|
|
532
|
+
// Quantity
|
|
533
|
+
quantity: {
|
|
534
|
+
type: 'number',
|
|
535
|
+
description: 'Usage quantity',
|
|
536
|
+
},
|
|
537
|
+
unit: {
|
|
538
|
+
type: 'string',
|
|
539
|
+
optional: true,
|
|
540
|
+
description: 'Unit of measure',
|
|
541
|
+
examples: ['requests', 'minutes', 'gb', 'tokens', 'executions'],
|
|
542
|
+
},
|
|
543
|
+
// Time
|
|
544
|
+
timestamp: {
|
|
545
|
+
type: 'date',
|
|
546
|
+
description: 'Usage timestamp',
|
|
547
|
+
},
|
|
548
|
+
periodStart: {
|
|
549
|
+
type: 'date',
|
|
550
|
+
optional: true,
|
|
551
|
+
description: 'Period start',
|
|
552
|
+
},
|
|
553
|
+
periodEnd: {
|
|
554
|
+
type: 'date',
|
|
555
|
+
optional: true,
|
|
556
|
+
description: 'Period end',
|
|
557
|
+
},
|
|
558
|
+
// Cost
|
|
559
|
+
unitCost: {
|
|
560
|
+
type: 'number',
|
|
561
|
+
optional: true,
|
|
562
|
+
description: 'Cost per unit',
|
|
563
|
+
},
|
|
564
|
+
totalCost: {
|
|
565
|
+
type: 'number',
|
|
566
|
+
optional: true,
|
|
567
|
+
description: 'Total cost',
|
|
568
|
+
},
|
|
569
|
+
currency: {
|
|
570
|
+
type: 'string',
|
|
571
|
+
optional: true,
|
|
572
|
+
description: 'Currency code',
|
|
573
|
+
},
|
|
574
|
+
// Context
|
|
575
|
+
metadata: {
|
|
576
|
+
type: 'json',
|
|
577
|
+
optional: true,
|
|
578
|
+
description: 'Usage metadata',
|
|
579
|
+
},
|
|
580
|
+
requestId: {
|
|
581
|
+
type: 'string',
|
|
582
|
+
optional: true,
|
|
583
|
+
description: 'Related request ID',
|
|
584
|
+
},
|
|
585
|
+
// Billing
|
|
586
|
+
billed: {
|
|
587
|
+
type: 'boolean',
|
|
588
|
+
optional: true,
|
|
589
|
+
description: 'Has been billed',
|
|
590
|
+
},
|
|
591
|
+
invoiceId: {
|
|
592
|
+
type: 'string',
|
|
593
|
+
optional: true,
|
|
594
|
+
description: 'Related invoice ID',
|
|
595
|
+
},
|
|
596
|
+
// Status
|
|
597
|
+
status: {
|
|
598
|
+
type: 'string',
|
|
599
|
+
description: 'Usage status',
|
|
600
|
+
examples: ['recorded', 'aggregated', 'billed', 'disputed'],
|
|
601
|
+
},
|
|
602
|
+
},
|
|
603
|
+
relationships: {
|
|
604
|
+
customer: {
|
|
605
|
+
type: 'ServiceCustomer',
|
|
606
|
+
description: 'Customer',
|
|
607
|
+
},
|
|
608
|
+
subscription: {
|
|
609
|
+
type: 'ServiceSubscription',
|
|
610
|
+
required: false,
|
|
611
|
+
description: 'Related subscription',
|
|
612
|
+
},
|
|
613
|
+
execution: {
|
|
614
|
+
type: 'ServiceExecution',
|
|
615
|
+
required: false,
|
|
616
|
+
description: 'Related execution',
|
|
617
|
+
},
|
|
618
|
+
},
|
|
619
|
+
actions: [
|
|
620
|
+
'record',
|
|
621
|
+
'aggregate',
|
|
622
|
+
'bill',
|
|
623
|
+
'dispute',
|
|
624
|
+
'adjust',
|
|
625
|
+
],
|
|
626
|
+
events: [
|
|
627
|
+
'recorded',
|
|
628
|
+
'aggregated',
|
|
629
|
+
'billed',
|
|
630
|
+
'disputed',
|
|
631
|
+
'adjusted',
|
|
632
|
+
],
|
|
633
|
+
};
|
|
634
|
+
// =============================================================================
|
|
635
|
+
// Invoice
|
|
636
|
+
// =============================================================================
|
|
637
|
+
/**
|
|
638
|
+
* Invoice entity
|
|
639
|
+
*
|
|
640
|
+
* Billing invoice.
|
|
641
|
+
*/
|
|
642
|
+
export const Invoice = {
|
|
643
|
+
singular: 'invoice',
|
|
644
|
+
plural: 'invoices',
|
|
645
|
+
description: 'A billing invoice',
|
|
646
|
+
properties: {
|
|
647
|
+
// Identity
|
|
648
|
+
id: {
|
|
649
|
+
type: 'string',
|
|
650
|
+
description: 'Invoice ID',
|
|
651
|
+
},
|
|
652
|
+
number: {
|
|
653
|
+
type: 'string',
|
|
654
|
+
optional: true,
|
|
655
|
+
description: 'Invoice number',
|
|
656
|
+
},
|
|
657
|
+
// Details
|
|
658
|
+
description: {
|
|
659
|
+
type: 'string',
|
|
660
|
+
optional: true,
|
|
661
|
+
description: 'Invoice description',
|
|
662
|
+
},
|
|
663
|
+
lineItems: {
|
|
664
|
+
type: 'json',
|
|
665
|
+
optional: true,
|
|
666
|
+
description: 'Invoice line items',
|
|
667
|
+
},
|
|
668
|
+
// Amounts
|
|
669
|
+
subtotal: {
|
|
670
|
+
type: 'number',
|
|
671
|
+
optional: true,
|
|
672
|
+
description: 'Subtotal',
|
|
673
|
+
},
|
|
674
|
+
discount: {
|
|
675
|
+
type: 'number',
|
|
676
|
+
optional: true,
|
|
677
|
+
description: 'Discount amount',
|
|
678
|
+
},
|
|
679
|
+
tax: {
|
|
680
|
+
type: 'number',
|
|
681
|
+
optional: true,
|
|
682
|
+
description: 'Tax amount',
|
|
683
|
+
},
|
|
684
|
+
total: {
|
|
685
|
+
type: 'number',
|
|
686
|
+
description: 'Total amount',
|
|
687
|
+
},
|
|
688
|
+
amountDue: {
|
|
689
|
+
type: 'number',
|
|
690
|
+
optional: true,
|
|
691
|
+
description: 'Amount due',
|
|
692
|
+
},
|
|
693
|
+
amountPaid: {
|
|
694
|
+
type: 'number',
|
|
695
|
+
optional: true,
|
|
696
|
+
description: 'Amount paid',
|
|
697
|
+
},
|
|
698
|
+
currency: {
|
|
699
|
+
type: 'string',
|
|
700
|
+
optional: true,
|
|
701
|
+
description: 'Currency code',
|
|
702
|
+
},
|
|
703
|
+
// Period
|
|
704
|
+
periodStart: {
|
|
705
|
+
type: 'date',
|
|
706
|
+
optional: true,
|
|
707
|
+
description: 'Billing period start',
|
|
708
|
+
},
|
|
709
|
+
periodEnd: {
|
|
710
|
+
type: 'date',
|
|
711
|
+
optional: true,
|
|
712
|
+
description: 'Billing period end',
|
|
713
|
+
},
|
|
714
|
+
// Dates
|
|
715
|
+
issuedAt: {
|
|
716
|
+
type: 'date',
|
|
717
|
+
optional: true,
|
|
718
|
+
description: 'Issue date',
|
|
719
|
+
},
|
|
720
|
+
dueDate: {
|
|
721
|
+
type: 'date',
|
|
722
|
+
optional: true,
|
|
723
|
+
description: 'Due date',
|
|
724
|
+
},
|
|
725
|
+
paidAt: {
|
|
726
|
+
type: 'date',
|
|
727
|
+
optional: true,
|
|
728
|
+
description: 'Payment date',
|
|
729
|
+
},
|
|
730
|
+
// Delivery
|
|
731
|
+
sentAt: {
|
|
732
|
+
type: 'date',
|
|
733
|
+
optional: true,
|
|
734
|
+
description: 'Sent date',
|
|
735
|
+
},
|
|
736
|
+
sentTo: {
|
|
737
|
+
type: 'string',
|
|
738
|
+
optional: true,
|
|
739
|
+
description: 'Sent to email',
|
|
740
|
+
},
|
|
741
|
+
// PDF
|
|
742
|
+
pdfUrl: {
|
|
743
|
+
type: 'string',
|
|
744
|
+
optional: true,
|
|
745
|
+
description: 'PDF download URL',
|
|
746
|
+
},
|
|
747
|
+
// Status
|
|
748
|
+
status: {
|
|
749
|
+
type: 'string',
|
|
750
|
+
description: 'Invoice status',
|
|
751
|
+
examples: ['draft', 'open', 'sent', 'paid', 'partial', 'overdue', 'void', 'uncollectible'],
|
|
752
|
+
},
|
|
753
|
+
},
|
|
754
|
+
relationships: {
|
|
755
|
+
customer: {
|
|
756
|
+
type: 'ServiceCustomer',
|
|
757
|
+
description: 'Customer',
|
|
758
|
+
},
|
|
759
|
+
subscription: {
|
|
760
|
+
type: 'ServiceSubscription',
|
|
761
|
+
required: false,
|
|
762
|
+
description: 'Related subscription',
|
|
763
|
+
},
|
|
764
|
+
order: {
|
|
765
|
+
type: 'ServiceOrder',
|
|
766
|
+
required: false,
|
|
767
|
+
description: 'Related order',
|
|
768
|
+
},
|
|
769
|
+
payments: {
|
|
770
|
+
type: 'Payment[]',
|
|
771
|
+
description: 'Invoice payments',
|
|
772
|
+
},
|
|
773
|
+
},
|
|
774
|
+
actions: [
|
|
775
|
+
'create',
|
|
776
|
+
'finalize',
|
|
777
|
+
'send',
|
|
778
|
+
'pay',
|
|
779
|
+
'void',
|
|
780
|
+
'markUncollectible',
|
|
781
|
+
'refund',
|
|
782
|
+
],
|
|
783
|
+
events: [
|
|
784
|
+
'created',
|
|
785
|
+
'finalized',
|
|
786
|
+
'sent',
|
|
787
|
+
'paid',
|
|
788
|
+
'voided',
|
|
789
|
+
'markedUncollectible',
|
|
790
|
+
'refunded',
|
|
791
|
+
],
|
|
792
|
+
};
|
|
793
|
+
// =============================================================================
|
|
794
|
+
// Payment
|
|
795
|
+
// =============================================================================
|
|
796
|
+
/**
|
|
797
|
+
* Payment entity
|
|
798
|
+
*
|
|
799
|
+
* Payment record.
|
|
800
|
+
*/
|
|
801
|
+
export const Payment = {
|
|
802
|
+
singular: 'payment',
|
|
803
|
+
plural: 'payments',
|
|
804
|
+
description: 'A payment record',
|
|
805
|
+
properties: {
|
|
806
|
+
// Identity
|
|
807
|
+
id: {
|
|
808
|
+
type: 'string',
|
|
809
|
+
description: 'Payment ID',
|
|
810
|
+
},
|
|
811
|
+
externalId: {
|
|
812
|
+
type: 'string',
|
|
813
|
+
optional: true,
|
|
814
|
+
description: 'External payment ID (Stripe, etc.)',
|
|
815
|
+
},
|
|
816
|
+
// Amount
|
|
817
|
+
amount: {
|
|
818
|
+
type: 'number',
|
|
819
|
+
description: 'Payment amount',
|
|
820
|
+
},
|
|
821
|
+
currency: {
|
|
822
|
+
type: 'string',
|
|
823
|
+
optional: true,
|
|
824
|
+
description: 'Currency code',
|
|
825
|
+
},
|
|
826
|
+
fee: {
|
|
827
|
+
type: 'number',
|
|
828
|
+
optional: true,
|
|
829
|
+
description: 'Processing fee',
|
|
830
|
+
},
|
|
831
|
+
netAmount: {
|
|
832
|
+
type: 'number',
|
|
833
|
+
optional: true,
|
|
834
|
+
description: 'Net amount after fees',
|
|
835
|
+
},
|
|
836
|
+
// Method
|
|
837
|
+
method: {
|
|
838
|
+
type: 'string',
|
|
839
|
+
description: 'Payment method',
|
|
840
|
+
examples: ['card', 'bank_transfer', 'paypal', 'crypto', 'invoice', 'check'],
|
|
841
|
+
},
|
|
842
|
+
methodDetails: {
|
|
843
|
+
type: 'json',
|
|
844
|
+
optional: true,
|
|
845
|
+
description: 'Method details (card last 4, etc.)',
|
|
846
|
+
},
|
|
847
|
+
// Provider
|
|
848
|
+
provider: {
|
|
849
|
+
type: 'string',
|
|
850
|
+
optional: true,
|
|
851
|
+
description: 'Payment provider',
|
|
852
|
+
examples: ['stripe', 'paypal', 'square', 'manual'],
|
|
853
|
+
},
|
|
854
|
+
// Timing
|
|
855
|
+
createdAt: {
|
|
856
|
+
type: 'date',
|
|
857
|
+
optional: true,
|
|
858
|
+
description: 'Creation date',
|
|
859
|
+
},
|
|
860
|
+
processedAt: {
|
|
861
|
+
type: 'date',
|
|
862
|
+
optional: true,
|
|
863
|
+
description: 'Processing date',
|
|
864
|
+
},
|
|
865
|
+
settledAt: {
|
|
866
|
+
type: 'date',
|
|
867
|
+
optional: true,
|
|
868
|
+
description: 'Settlement date',
|
|
869
|
+
},
|
|
870
|
+
// Refund
|
|
871
|
+
refundedAmount: {
|
|
872
|
+
type: 'number',
|
|
873
|
+
optional: true,
|
|
874
|
+
description: 'Amount refunded',
|
|
875
|
+
},
|
|
876
|
+
refundedAt: {
|
|
877
|
+
type: 'date',
|
|
878
|
+
optional: true,
|
|
879
|
+
description: 'Refund date',
|
|
880
|
+
},
|
|
881
|
+
refundReason: {
|
|
882
|
+
type: 'string',
|
|
883
|
+
optional: true,
|
|
884
|
+
description: 'Refund reason',
|
|
885
|
+
},
|
|
886
|
+
// Failure
|
|
887
|
+
failureCode: {
|
|
888
|
+
type: 'string',
|
|
889
|
+
optional: true,
|
|
890
|
+
description: 'Failure code',
|
|
891
|
+
},
|
|
892
|
+
failureMessage: {
|
|
893
|
+
type: 'string',
|
|
894
|
+
optional: true,
|
|
895
|
+
description: 'Failure message',
|
|
896
|
+
},
|
|
897
|
+
// Status
|
|
898
|
+
status: {
|
|
899
|
+
type: 'string',
|
|
900
|
+
description: 'Payment status',
|
|
901
|
+
examples: ['pending', 'processing', 'succeeded', 'failed', 'refunded', 'disputed'],
|
|
902
|
+
},
|
|
903
|
+
},
|
|
904
|
+
relationships: {
|
|
905
|
+
customer: {
|
|
906
|
+
type: 'ServiceCustomer',
|
|
907
|
+
description: 'Customer',
|
|
908
|
+
},
|
|
909
|
+
invoice: {
|
|
910
|
+
type: 'Invoice',
|
|
911
|
+
required: false,
|
|
912
|
+
description: 'Related invoice',
|
|
913
|
+
},
|
|
914
|
+
subscription: {
|
|
915
|
+
type: 'ServiceSubscription',
|
|
916
|
+
required: false,
|
|
917
|
+
description: 'Related subscription',
|
|
918
|
+
},
|
|
919
|
+
},
|
|
920
|
+
actions: [
|
|
921
|
+
'create',
|
|
922
|
+
'process',
|
|
923
|
+
'capture',
|
|
924
|
+
'refund',
|
|
925
|
+
'dispute',
|
|
926
|
+
],
|
|
927
|
+
events: [
|
|
928
|
+
'created',
|
|
929
|
+
'processing',
|
|
930
|
+
'succeeded',
|
|
931
|
+
'failed',
|
|
932
|
+
'refunded',
|
|
933
|
+
'disputed',
|
|
934
|
+
],
|
|
935
|
+
};
|
|
936
|
+
// =============================================================================
|
|
937
|
+
// Exports
|
|
938
|
+
// =============================================================================
|
|
939
|
+
export const BillingEntities = {
|
|
940
|
+
ServiceQuote,
|
|
941
|
+
ServiceOrder,
|
|
942
|
+
ServiceSubscription,
|
|
943
|
+
Usage,
|
|
944
|
+
Invoice,
|
|
945
|
+
Payment,
|
|
946
|
+
};
|
|
947
|
+
export const BillingCategories = {
|
|
948
|
+
quotes: ['ServiceQuote'],
|
|
949
|
+
orders: ['ServiceOrder'],
|
|
950
|
+
subscriptions: ['ServiceSubscription'],
|
|
951
|
+
usage: ['Usage'],
|
|
952
|
+
invoicing: ['Invoice', 'Payment'],
|
|
953
|
+
};
|