File size: 15,199 Bytes
04f1444
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
// Code generated by @openmeter/typespec-go. DO NOT EDIT.

package openmeter

import (
	"encoding/json"
	"fmt"
	"time"
)

// Installed application.
//
// App is a JSON-preserving tagged union: its zero value marshals as JSON null, and values must be built with the AppFrom* constructors.
// The exported Type field is decode-side metadata; MarshalJSON round-trips the original payload and ignores writes to it.
type App struct {
	Type string `json:"type"`
	raw  json.RawMessage
}

func (u *App) UnmarshalJSON(data []byte) error {
	u.raw = append([]byte(nil), data...)
	if string(data) == "null" {
		u.Type = ""
		return nil
	}

	var envelope struct {
		Value string `json:"type"`
	}
	if err := json.Unmarshal(data, &envelope); err != nil {
		return err
	}
	u.Type = envelope.Value
	return nil
}

func (u App) MarshalJSON() ([]byte, error) {
	if len(u.raw) == 0 {
		return []byte("null"), nil
	}
	return append([]byte(nil), u.raw...), nil
}

func (u App) AsAppStripe() (*AppStripe, error) {
	if u.Type != "stripe" {
		return nil, fmt.Errorf("App: expected type %q, got %q", "stripe", u.Type)
	}
	var value AppStripe
	if err := json.Unmarshal(u.raw, &value); err != nil {
		return nil, err
	}
	return &value, nil
}

func AppFromAppStripe(value AppStripe) (App, error) {
	value.Type = "stripe"
	raw, err := json.Marshal(value)
	if err != nil {
		return App{}, err
	}
	var result App
	if err := result.UnmarshalJSON(raw); err != nil {
		return App{}, err
	}
	return result, nil
}

func (u App) AsAppSandbox() (*AppSandbox, error) {
	if u.Type != "sandbox" {
		return nil, fmt.Errorf("App: expected type %q, got %q", "sandbox", u.Type)
	}
	var value AppSandbox
	if err := json.Unmarshal(u.raw, &value); err != nil {
		return nil, err
	}
	return &value, nil
}

func AppFromAppSandbox(value AppSandbox) (App, error) {
	value.Type = "sandbox"
	raw, err := json.Marshal(value)
	if err != nil {
		return App{}, err
	}
	var result App
	if err := result.UnmarshalJSON(raw); err != nil {
		return App{}, err
	}
	return result, nil
}

func (u App) AsAppExternalInvoicing() (*AppExternalInvoicing, error) {
	if u.Type != "external_invoicing" {
		return nil, fmt.Errorf("App: expected type %q, got %q", "external_invoicing", u.Type)
	}
	var value AppExternalInvoicing
	if err := json.Unmarshal(u.raw, &value); err != nil {
		return nil, err
	}
	return &value, nil
}

func AppFromAppExternalInvoicing(value AppExternalInvoicing) (App, error) {
	value.Type = "external_invoicing"
	raw, err := json.Marshal(value)
	if err != nil {
		return App{}, err
	}
	var result App
	if err := result.UnmarshalJSON(raw); err != nil {
		return App{}, err
	}
	return result, nil
}

// App capability describes a function that an App can perform.
type AppCapability struct {
	// Type of the capability.
	Type AppCapabilityType `json:"type"`
	// Key of the capability.
	Key string `json:"key"`
	// Name of the capability.
	Name string `json:"name"`
	// Description of the capability.
	Description string `json:"description"`
}

// Supported capability types for an App.
//
// Each capability defines an integration function that an App can perform.
type AppCapabilityType string

const (
	AppCapabilityTypeReportUsage      AppCapabilityType = "report_usage"
	AppCapabilityTypeReportEvents     AppCapabilityType = "report_events"
	AppCapabilityTypeCalculateTax     AppCapabilityType = "calculate_tax"
	AppCapabilityTypeInvoiceCustomers AppCapabilityType = "invoice_customers"
	AppCapabilityTypeCollectPayments  AppCapabilityType = "collect_payments"
)

func (value AppCapabilityType) Valid() bool {
	switch value {
	case AppCapabilityTypeReportUsage, AppCapabilityTypeReportEvents, AppCapabilityTypeCalculateTax, AppCapabilityTypeInvoiceCustomers, AppCapabilityTypeCollectPayments:
		return true
	default:
		return false
	}
}

// Available apps for billing integrations to connect with third-party services.
// Apps can have various capabilities like syncing data from or to external
// systems, integrating with third-party services for tax calculation, delivery of
// invoices, collection of payments, etc.
type AppCatalogItem struct {
	// Type of the app.
	Type AppType `json:"type"`
	// Name of the app.
	Name string `json:"name"`
	// Description of the app.
	Description string `json:"description"`
	// Capabilities of the app.
	Capabilities []AppCapability `json:"capabilities"`
	// Available install methods of the app.
	InstallMethods []AppInstallMethods `json:"install_methods"`
}

// Page paginated response.
type AppCatalogItemPagePaginatedResponse struct {
	Data []AppCatalogItem `json:"data"`
	Meta PaginatedMeta    `json:"meta"`
}

// External Invoicing app enables integration with third-party invoicing or payment
// system.
//
// The app supports a bi-directional synchronization pattern where OpenMeter
// Billing manages the invoice lifecycle while the external system handles invoice
// presentation and payment collection.
//
// Integration workflow:
//
// 1. The billing system creates invoices and transitions them through lifecycle
// states (draft → issuing → issued)
// 2. The integration receives webhook notifications about invoice state changes
// 3. The integration calls back to provide external system IDs and metadata
// 4. The integration reports payment events back via the payment status API
//
// State synchronization is controlled by hooks that pause invoice progression
// until the external system confirms synchronization via API callbacks.
type AppExternalInvoicing struct {
	ID string `json:"id"`
	// Display name of the resource.
	//
	// Between 1 and 256 characters.
	Name string `json:"name"`
	// Optional description of the resource.
	//
	// Maximum 1024 characters.
	Description *string           `json:"description,omitempty"`
	Labels      map[string]string `json:"labels,omitempty"`
	// An ISO-8601 timestamp representation of entity creation date.
	CreatedAt time.Time `json:"created_at"`
	// An ISO-8601 timestamp representation of entity last update date.
	UpdatedAt time.Time `json:"updated_at"`
	// An ISO-8601 timestamp representation of entity deletion date.
	DeletedAt *time.Time `json:"deleted_at,omitempty"`
	// The app type.
	Type AppType `json:"type"`
	// The app catalog definition that this installed app is based on.
	Definition AppCatalogItem `json:"definition"`
	// Status of the app connection.
	Status AppStatus `json:"status"`
	// Enable draft synchronization hook.
	//
	// When enabled, invoices will pause at the draft state and wait for the
	// integration to call the draft synchronized endpoint before progressing to the
	// issuing state. This allows the external system to validate and prepare the
	// invoice data.
	//
	// When disabled, invoices automatically progress through the draft state based on
	// the configured workflow timing.
	EnableDraftSyncHook bool `json:"enable_draft_sync_hook"`
	// Enable issuing synchronization hook.
	//
	// When enabled, invoices will pause at the issuing state and wait for the
	// integration to call the issuing synchronized endpoint before progressing to the
	// issued state. This ensures the external invoicing system has successfully
	// created and finalized the invoice before it is marked as issued.
	//
	// When disabled, invoices automatically progress through the issuing state and are
	// immediately marked as issued.
	EnableIssuingSyncHook bool `json:"enable_issuing_sync_hook"`
}

// Supported installation methods for an app.
type AppInstallMethods string

const (
	AppInstallMethodsWithOAuth2            AppInstallMethods = "with_oauth2"
	AppInstallMethodsWithAPIKey            AppInstallMethods = "with_api_key"
	AppInstallMethodsNoCredentialsRequired AppInstallMethods = "no_credentials_required"
)

func (value AppInstallMethods) Valid() bool {
	switch value {
	case AppInstallMethodsWithOAuth2, AppInstallMethodsWithAPIKey, AppInstallMethodsNoCredentialsRequired:
		return true
	default:
		return false
	}
}

// Page paginated response.
type AppPagePaginatedResponse struct {
	Data []App         `json:"data"`
	Meta PaginatedMeta `json:"meta"`
}

// Sandbox app can be used for testing billing features.
type AppSandbox struct {
	ID string `json:"id"`
	// Display name of the resource.
	//
	// Between 1 and 256 characters.
	Name string `json:"name"`
	// Optional description of the resource.
	//
	// Maximum 1024 characters.
	Description *string           `json:"description,omitempty"`
	Labels      map[string]string `json:"labels,omitempty"`
	// An ISO-8601 timestamp representation of entity creation date.
	CreatedAt time.Time `json:"created_at"`
	// An ISO-8601 timestamp representation of entity last update date.
	UpdatedAt time.Time `json:"updated_at"`
	// An ISO-8601 timestamp representation of entity deletion date.
	DeletedAt *time.Time `json:"deleted_at,omitempty"`
	// The app type.
	Type AppType `json:"type"`
	// The app catalog definition that this installed app is based on.
	Definition AppCatalogItem `json:"definition"`
	// Status of the app connection.
	Status AppStatus `json:"status"`
}

// Connection status of an installed app.
type AppStatus string

const (
	AppStatusReady        AppStatus = "ready"
	AppStatusUnauthorized AppStatus = "unauthorized"
)

func (value AppStatus) Valid() bool {
	switch value {
	case AppStatusReady, AppStatusUnauthorized:
		return true
	default:
		return false
	}
}

// Stripe app.
type AppStripe struct {
	ID string `json:"id"`
	// Display name of the resource.
	//
	// Between 1 and 256 characters.
	Name string `json:"name"`
	// Optional description of the resource.
	//
	// Maximum 1024 characters.
	Description *string           `json:"description,omitempty"`
	Labels      map[string]string `json:"labels,omitempty"`
	// An ISO-8601 timestamp representation of entity creation date.
	CreatedAt time.Time `json:"created_at"`
	// An ISO-8601 timestamp representation of entity last update date.
	UpdatedAt time.Time `json:"updated_at"`
	// An ISO-8601 timestamp representation of entity deletion date.
	DeletedAt *time.Time `json:"deleted_at,omitempty"`
	// The app type.
	Type AppType `json:"type"`
	// The app catalog definition that this installed app is based on.
	Definition AppCatalogItem `json:"definition"`
	// Status of the app connection.
	Status AppStatus `json:"status"`
	// The Stripe account ID associated with the connected Stripe account.
	AccountID string `json:"account_id"`
	// Indicates whether the app is connected to a live Stripe account.
	Livemode bool `json:"livemode"`
	// The masked Stripe API key that only exposes the first and last few characters.
	MaskedAPIKey string `json:"masked_api_key"`
}

// Base model for installing an app from the catalog.
type InstallAppExternalInvoicing struct {
	// Type of the app.
	Type AppType `json:"type"`
	// Name of the app.
	Name string `json:"name"`
	// If true, a billing profile will be created for the app. The Stripe app will be
	// also set as the default billing profile if the current default is a Sandbox app.
	CreateBillingProfile bool `json:"create_billing_profile"`
}

// Request to install an app from the catalog.
//
// InstallAppRequest is a JSON-preserving tagged union: its zero value marshals as JSON null, and values must be built with the InstallAppRequestFrom* constructors.
// The exported Type field is decode-side metadata; MarshalJSON round-trips the original payload and ignores writes to it.
type InstallAppRequest struct {
	Type string `json:"type"`
	raw  json.RawMessage
}

func (u *InstallAppRequest) UnmarshalJSON(data []byte) error {
	u.raw = append([]byte(nil), data...)
	if string(data) == "null" {
		u.Type = ""
		return nil
	}

	var envelope struct {
		Value string `json:"type"`
	}
	if err := json.Unmarshal(data, &envelope); err != nil {
		return err
	}
	u.Type = envelope.Value
	return nil
}

func (u InstallAppRequest) MarshalJSON() ([]byte, error) {
	if len(u.raw) == 0 {
		return []byte("null"), nil
	}
	return append([]byte(nil), u.raw...), nil
}

func (u InstallAppRequest) AsInstallAppStripeWithAPIKey() (*InstallAppStripeWithAPIKey, error) {
	if u.Type != "stripe" {
		return nil, fmt.Errorf("InstallAppRequest: expected type %q, got %q", "stripe", u.Type)
	}
	var value InstallAppStripeWithAPIKey
	if err := json.Unmarshal(u.raw, &value); err != nil {
		return nil, err
	}
	return &value, nil
}

func InstallAppRequestFromInstallAppStripeWithAPIKey(value InstallAppStripeWithAPIKey) (InstallAppRequest, error) {
	value.Type = "stripe"
	raw, err := json.Marshal(value)
	if err != nil {
		return InstallAppRequest{}, err
	}
	var result InstallAppRequest
	if err := result.UnmarshalJSON(raw); err != nil {
		return InstallAppRequest{}, err
	}
	return result, nil
}

func (u InstallAppRequest) AsInstallAppSandbox() (*InstallAppSandbox, error) {
	if u.Type != "sandbox" {
		return nil, fmt.Errorf("InstallAppRequest: expected type %q, got %q", "sandbox", u.Type)
	}
	var value InstallAppSandbox
	if err := json.Unmarshal(u.raw, &value); err != nil {
		return nil, err
	}
	return &value, nil
}

func InstallAppRequestFromInstallAppSandbox(value InstallAppSandbox) (InstallAppRequest, error) {
	value.Type = "sandbox"
	raw, err := json.Marshal(value)
	if err != nil {
		return InstallAppRequest{}, err
	}
	var result InstallAppRequest
	if err := result.UnmarshalJSON(raw); err != nil {
		return InstallAppRequest{}, err
	}
	return result, nil
}

func (u InstallAppRequest) AsInstallAppExternalInvoicing() (*InstallAppExternalInvoicing, error) {
	if u.Type != "external_invoicing" {
		return nil, fmt.Errorf("InstallAppRequest: expected type %q, got %q", "external_invoicing", u.Type)
	}
	var value InstallAppExternalInvoicing
	if err := json.Unmarshal(u.raw, &value); err != nil {
		return nil, err
	}
	return &value, nil
}

func InstallAppRequestFromInstallAppExternalInvoicing(value InstallAppExternalInvoicing) (InstallAppRequest, error) {
	value.Type = "external_invoicing"
	raw, err := json.Marshal(value)
	if err != nil {
		return InstallAppRequest{}, err
	}
	var result InstallAppRequest
	if err := result.UnmarshalJSON(raw); err != nil {
		return InstallAppRequest{}, err
	}
	return result, nil
}

// Response of the app install.
type InstallAppResponse struct {
	App                       App                 `json:"app"`
	DefaultForCapabilityTypes []AppCapabilityType `json:"default_for_capability_types"`
}

// Base model for installing an app from the catalog.
type InstallAppSandbox struct {
	// Type of the app.
	Type AppType `json:"type"`
	// Name of the app.
	Name string `json:"name"`
	// If true, a billing profile will be created for the app. The Stripe app will be
	// also set as the default billing profile if the current default is a Sandbox app.
	CreateBillingProfile bool `json:"create_billing_profile"`
}

// Model for installing an app from the catalog with an API key.
type InstallAppStripeWithAPIKey struct {
	// Type of the app.
	Type AppType `json:"type"`
	// Name of the app.
	Name string `json:"name"`
	// If true, a billing profile will be created for the app. The Stripe app will be
	// also set as the default billing profile if the current default is a Sandbox app.
	CreateBillingProfile bool `json:"create_billing_profile"`
	// API key for the app.
	APIKey string `json:"api_key"`
}