@schematichq/schematic-react 1.8.0 → 1.9.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.
@@ -45,6 +45,20 @@ declare type BaseSchematicProviderProps = Omit<SchematicJS.SchematicOptions, "cl
45
45
  initialData?: BillingData;
46
46
  } & SchematicI18nConfig;
47
47
 
48
+ /**
49
+ * The writes a source can carry out. Each rejects with the failure; a source
50
+ * that reads only (a prefetch with no client) leaves the object off, and the
51
+ * hooks reject every write with `BILLING_ACTION_UNAVAILABLE_MESSAGE`.
52
+ */
53
+ export declare interface BillingActions {
54
+ /** Makes `externalId` the default payment method and reloads the list. */
55
+ setDefaultPaymentMethod(externalId: string): Promise<void>;
56
+ /** Removes payment method `id` and reloads the list. */
57
+ removePaymentMethod(id: string): Promise<void>;
58
+ /** Mints a new setup intent every call; nothing is cached. */
59
+ createSetupIntent(): Promise<SetupIntent>;
60
+ }
61
+
48
62
  declare namespace billingApi {
49
63
  export {
50
64
  instanceOfApiError,
@@ -53,6 +67,12 @@ declare namespace billingApi {
53
67
  ApiErrorToJSON,
54
68
  ApiErrorToJSONTyped,
55
69
  ApiError,
70
+ instanceOfBillingProviderType,
71
+ BillingProviderTypeFromJSON,
72
+ BillingProviderTypeFromJSONTyped,
73
+ BillingProviderTypeToJSON,
74
+ BillingProviderTypeToJSONTyped,
75
+ BillingProviderType,
56
76
  instanceOfCompanyDiscountResponseData,
57
77
  CompanyDiscountResponseDataFromJSON,
58
78
  CompanyDiscountResponseDataFromJSONTyped,
@@ -71,12 +91,42 @@ declare namespace billingApi {
71
91
  CompanyInvoicesResponseDataToJSON,
72
92
  CompanyInvoicesResponseDataToJSONTyped,
73
93
  CompanyInvoicesResponseData,
94
+ instanceOfCompanyPaymentMethodResponseData,
95
+ CompanyPaymentMethodResponseDataFromJSON,
96
+ CompanyPaymentMethodResponseDataFromJSONTyped,
97
+ CompanyPaymentMethodResponseDataToJSON,
98
+ CompanyPaymentMethodResponseDataToJSONTyped,
99
+ CompanyPaymentMethodResponseData,
100
+ instanceOfCompanyPaymentMethodsResponseData,
101
+ CompanyPaymentMethodsResponseDataFromJSON,
102
+ CompanyPaymentMethodsResponseDataFromJSONTyped,
103
+ CompanyPaymentMethodsResponseDataToJSON,
104
+ CompanyPaymentMethodsResponseDataToJSONTyped,
105
+ CompanyPaymentMethodsResponseData,
74
106
  instanceOfCompanyUpcomingInvoiceResponseData,
75
107
  CompanyUpcomingInvoiceResponseDataFromJSON,
76
108
  CompanyUpcomingInvoiceResponseDataFromJSONTyped,
77
109
  CompanyUpcomingInvoiceResponseDataToJSON,
78
110
  CompanyUpcomingInvoiceResponseDataToJSONTyped,
79
111
  CompanyUpcomingInvoiceResponseData,
112
+ instanceOfCreateSetupIntentResponse,
113
+ CreateSetupIntentResponseFromJSON,
114
+ CreateSetupIntentResponseFromJSONTyped,
115
+ CreateSetupIntentResponseToJSON,
116
+ CreateSetupIntentResponseToJSONTyped,
117
+ CreateSetupIntentResponse,
118
+ instanceOfDeletePaymentMethodResponse,
119
+ DeletePaymentMethodResponseFromJSON,
120
+ DeletePaymentMethodResponseFromJSONTyped,
121
+ DeletePaymentMethodResponseToJSON,
122
+ DeletePaymentMethodResponseToJSONTyped,
123
+ DeletePaymentMethodResponse,
124
+ instanceOfDeleteResponse,
125
+ DeleteResponseFromJSON,
126
+ DeleteResponseFromJSONTyped,
127
+ DeleteResponseToJSON,
128
+ DeleteResponseToJSONTyped,
129
+ DeleteResponse,
80
130
  instanceOfGetCompanyInvoicesParams,
81
131
  GetCompanyInvoicesParamsFromJSON,
82
132
  GetCompanyInvoicesParamsFromJSONTyped,
@@ -89,6 +139,12 @@ declare namespace billingApi {
89
139
  GetCompanyInvoicesResponseToJSON,
90
140
  GetCompanyInvoicesResponseToJSONTyped,
91
141
  GetCompanyInvoicesResponse,
142
+ instanceOfGetCompanyPaymentMethodsResponse,
143
+ GetCompanyPaymentMethodsResponseFromJSON,
144
+ GetCompanyPaymentMethodsResponseFromJSONTyped,
145
+ GetCompanyPaymentMethodsResponseToJSON,
146
+ GetCompanyPaymentMethodsResponseToJSONTyped,
147
+ GetCompanyPaymentMethodsResponse,
92
148
  instanceOfGetCompanyUpcomingInvoiceResponse,
93
149
  GetCompanyUpcomingInvoiceResponseFromJSON,
94
150
  GetCompanyUpcomingInvoiceResponseFromJSONTyped,
@@ -100,19 +156,52 @@ declare namespace billingApi {
100
156
  InvoiceStatusFromJSONTyped,
101
157
  InvoiceStatusToJSON,
102
158
  InvoiceStatusToJSONTyped,
103
- InvoiceStatus
159
+ InvoiceStatus,
160
+ instanceOfPaymentMethodResponseData,
161
+ PaymentMethodResponseDataFromJSON,
162
+ PaymentMethodResponseDataFromJSONTyped,
163
+ PaymentMethodResponseDataToJSON,
164
+ PaymentMethodResponseDataToJSONTyped,
165
+ PaymentMethodResponseData,
166
+ instanceOfSetupIntentResponseData,
167
+ SetupIntentResponseDataFromJSON,
168
+ SetupIntentResponseDataFromJSONTyped,
169
+ SetupIntentResponseDataToJSON,
170
+ SetupIntentResponseDataToJSONTyped,
171
+ SetupIntentResponseData,
172
+ instanceOfUpdatePaymentMethodRequestBody,
173
+ UpdatePaymentMethodRequestBodyFromJSON,
174
+ UpdatePaymentMethodRequestBodyFromJSONTyped,
175
+ UpdatePaymentMethodRequestBodyToJSON,
176
+ UpdatePaymentMethodRequestBodyToJSONTyped,
177
+ UpdatePaymentMethodRequestBody,
178
+ instanceOfUpdatePaymentMethodResponse,
179
+ UpdatePaymentMethodResponseFromJSON,
180
+ UpdatePaymentMethodResponseFromJSONTyped,
181
+ UpdatePaymentMethodResponseToJSON,
182
+ UpdatePaymentMethodResponseToJSONTyped,
183
+ UpdatePaymentMethodResponse
104
184
  }
105
185
  }
106
186
 
107
187
  /**
108
- * What a reader of billing data can ask for. Subscription and usage — the
109
- * rest of what `hydrate` serves — and the checkout calls that change them
110
- * join this interface as their endpoints ship.
188
+ * What a reader of billing data can ask for, and the few writes beside it.
189
+ * Subscription and usage — the rest of what `hydrate` serves — and the
190
+ * checkout calls that change them join this interface as their endpoints
191
+ * ship.
111
192
  */
112
193
  declare interface BillingClient {
113
194
  fetchInvoices(params: InvoicesRequest): Promise<InvoicesResult>;
114
195
  /** `null` when the company has no next bill. */
115
196
  fetchUpcomingInvoice(): Promise<UpcomingInvoice | null>;
197
+ /** Empty when the company has no method on file. */
198
+ fetchPaymentMethods(): Promise<PaymentMethod[]>;
199
+ /** What a provider's card form is mounted with to add a method. */
200
+ createSetupIntent(): Promise<SetupIntent>;
201
+ /** Makes the method the default, by the provider's id (`externalId`). */
202
+ updatePaymentMethod(externalId: string): Promise<void>;
203
+ /** Removes the method, by Schematic's id (`id`). */
204
+ deletePaymentMethod(id: string): Promise<void>;
116
205
  readonly sessionStatus: SessionStatus;
117
206
  readonly sessionKey: string | undefined;
118
207
  setSession(session: SessionInput): void;
@@ -138,7 +227,7 @@ export declare type BillingData = {
138
227
  sessionKey?: string;
139
228
  };
140
229
 
141
- export declare function BillingDataProvider({ children, data, locale, onLoadMoreInvoices, onMissingString, onRefetch, status, strings, translate, }: BillingDataProviderProps): React_2.JSX.Element;
230
+ export declare function BillingDataProvider({ actions, children, data, locale, onLoadMoreInvoices, onMissingString, onRefetch, status, strings, translate, }: BillingDataProviderProps): React_2.JSX.Element;
142
231
 
143
232
  declare interface BillingDataProviderDataProps {
144
233
  /** A missing key reports as pending. */
@@ -147,6 +236,13 @@ declare interface BillingDataProviderDataProps {
147
236
  status?: BillingDataStatus;
148
237
  onRefetch?: (name: BillingResourceName) => void;
149
238
  onLoadMoreInvoices?: (query: InvoiceQuery) => void;
239
+ /**
240
+ * What the write hooks call. Each rejects on its own; an action left out
241
+ * rejects with `BILLING_ACTION_UNAVAILABLE_MESSAGE`. Nothing here touches
242
+ * `data`: a fixture that wants the list to change after a write hands in
243
+ * new `data`.
244
+ */
245
+ actions?: Partial<BillingActions>;
150
246
  children?: React_2.ReactNode;
151
247
  }
152
248
 
@@ -171,6 +267,8 @@ export declare interface BillingDataSource {
171
267
  /** Never rejects: a failure lands on the resource's `error`. */
172
268
  loadMoreInvoices: (query: InvoiceQuery) => Promise<void>;
173
269
  invalidateAll: () => void;
270
+ /** Absent on a source that only reads. */
271
+ actions?: BillingActions;
174
272
  }
175
273
 
176
274
  /** Per-resource status overrides, for fixtures that simulate loading and failure. */
@@ -200,13 +298,14 @@ declare interface BillingPrefetchOptions {
200
298
  export declare function BillingProvider({ billingClient, children, initialData, locale, onMissingString, session, strings, translate, }: BillingProviderProps): React_2.JSX.Element;
201
299
 
202
300
  /**
203
- * What `BillingProvider` asks of its client: the session it reads under, and
204
- * the fetch behind each resource above. schematic-js's `SchematicBillingClient`
301
+ * What `BillingProvider` asks of its client: the session it reads under, the
302
+ * fetch behind each resource above, and the payment-method actions the hooks
303
+ * expose. schematic-js's `SchematicBillingClient`
205
304
  * satisfies it, and so does a host's own client that implements only this
206
305
  * much. Named apart from schematic-js's `BillingClient`, which is the whole
207
306
  * interface; this is the part the hooks here call.
208
307
  */
209
- export declare type BillingProviderClient = Pick<BillingClient, "sessionStatus" | "sessionKey" | "setSession" | "onSessionChange" | "fetchInvoices" | "fetchUpcomingInvoice">;
308
+ export declare type BillingProviderClient = Pick<BillingClient, "sessionStatus" | "sessionKey" | "setSession" | "onSessionChange" | "fetchInvoices" | "fetchUpcomingInvoice" | "fetchPaymentMethods" | "createSetupIntent" | "updatePaymentMethod" | "deletePaymentMethod">;
210
309
 
211
310
  declare interface BillingProviderDataProps {
212
311
  /**
@@ -246,7 +345,7 @@ declare interface BillingProviderDataProps {
246
345
  export declare type BillingProviderProps = BillingProviderDataProps & SchematicI18nConfig;
247
346
 
248
347
  /** The resources this package serves; a key of schematic-js's contract. */
249
- export declare type BillingResourceName = "invoices" | "upcomingInvoice";
348
+ export declare type BillingResourceName = "invoices" | "upcomingInvoice" | "paymentMethods";
250
349
 
251
350
  declare type BillingResourceName_2 = keyof BillingResources_2;
252
351
 
@@ -256,6 +355,7 @@ export declare type BillingResourceParams = Pick<BillingResourceParams_2, Billin
256
355
  declare interface BillingResourceParams_2 {
257
356
  invoices: InvoiceQuery;
258
357
  upcomingInvoice: Record<string, never>;
358
+ paymentMethods: Record<string, never>;
259
359
  }
260
360
 
261
361
  export declare type BillingResources = Pick<BillingResources_2, BillingResourceName>;
@@ -276,6 +376,11 @@ declare interface BillingResources_2 {
276
376
  * `undefined` means the resource has not loaded.
277
377
  */
278
378
  upcomingInvoice: UpcomingInvoice | null;
379
+ /**
380
+ * `GET /company/payment-methods`. Empty is a loaded value — the company
381
+ * has no method on file — so only `undefined` means not loaded.
382
+ */
383
+ paymentMethods: PaymentMethod[];
279
384
  }
280
385
 
281
386
  declare type BooleanListenerFn = (value: boolean) => void;
@@ -669,6 +774,109 @@ declare interface CompanyInvoiceResponseData {
669
774
  url?: string | null;
670
775
  }
671
776
 
777
+ /**
778
+ * Schematic API
779
+ * Schematic API
780
+ *
781
+ * The version of the OpenAPI document: 0.1
782
+ *
783
+ *
784
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
785
+ * https://openapi-generator.tech
786
+ * Do not edit the class manually.
787
+ */
788
+ /**
789
+ *
790
+ * @export
791
+ * @interface CompanyPaymentMethodResponseData
792
+ */
793
+ declare interface CompanyPaymentMethodResponseData {
794
+ /**
795
+ *
796
+ * @type {string}
797
+ * @memberof CompanyPaymentMethodResponseData
798
+ */
799
+ accountLast4?: string | null;
800
+ /**
801
+ *
802
+ * @type {string}
803
+ * @memberof CompanyPaymentMethodResponseData
804
+ */
805
+ accountName?: string | null;
806
+ /**
807
+ *
808
+ * @type {string}
809
+ * @memberof CompanyPaymentMethodResponseData
810
+ */
811
+ bankName?: string | null;
812
+ /**
813
+ *
814
+ * @type {string}
815
+ * @memberof CompanyPaymentMethodResponseData
816
+ */
817
+ billingEmail?: string | null;
818
+ /**
819
+ *
820
+ * @type {string}
821
+ * @memberof CompanyPaymentMethodResponseData
822
+ */
823
+ billingName?: string | null;
824
+ /**
825
+ * Whether DELETE /checkout/paymentmethod/:id would succeed. False only for the sole method while an active paid subscription needs it; the default can be removed like any other.
826
+ * @type {boolean}
827
+ * @memberof CompanyPaymentMethodResponseData
828
+ */
829
+ canRemove: boolean;
830
+ /**
831
+ *
832
+ * @type {string}
833
+ * @memberof CompanyPaymentMethodResponseData
834
+ */
835
+ cardBrand?: string | null;
836
+ /**
837
+ *
838
+ * @type {number}
839
+ * @memberof CompanyPaymentMethodResponseData
840
+ */
841
+ cardExpMonth?: number | null;
842
+ /**
843
+ *
844
+ * @type {number}
845
+ * @memberof CompanyPaymentMethodResponseData
846
+ */
847
+ cardExpYear?: number | null;
848
+ /**
849
+ *
850
+ * @type {string}
851
+ * @memberof CompanyPaymentMethodResponseData
852
+ */
853
+ cardLast4?: string | null;
854
+ /**
855
+ *
856
+ * @type {string}
857
+ * @memberof CompanyPaymentMethodResponseData
858
+ */
859
+ externalId: string;
860
+ /**
861
+ *
862
+ * @type {string}
863
+ * @memberof CompanyPaymentMethodResponseData
864
+ */
865
+ id: string;
866
+ /**
867
+ * Whether this is the method the company is billed with: the subscription's own when it has one, else the customer default. At most one method is the default.
868
+ * @type {boolean}
869
+ * @memberof CompanyPaymentMethodResponseData
870
+ */
871
+ isDefault: boolean;
872
+ /**
873
+ * The Stripe payment method type, such as card or us_bank_account.
874
+ * @type {string}
875
+ * @memberof CompanyPaymentMethodResponseData
876
+ */
877
+ type: string;
878
+ }
879
+
672
880
  /**
673
881
  *
674
882
  * @export
@@ -700,7 +908,7 @@ declare interface CompanyUpcomingInvoiceResponseData {
700
908
  */
701
909
  customerBalanceRemaining: number;
702
910
  /**
703
- * Only active discounts that reduce the bill.
911
+ * The subscription's active discounts, to show beside the bill. Informational: the amounts come from the provider's preview and already reflect whatever it applied, so subtotal less these need not equal amount_due.
704
912
  * @type {Array<CompanyDiscountResponseData>}
705
913
  * @memberof CompanyUpcomingInvoiceResponseData
706
914
  */
@@ -1146,6 +1354,35 @@ export declare function normalizeInvoiceQuery(query: InvoiceQuery): InvoiceQuery
1146
1354
  */
1147
1355
  declare function normalizeInvoiceQuery_2(query: InvoiceQuery): InvoiceQuery;
1148
1356
 
1357
+ /**
1358
+ * One way the company pays. Two flags the server has already decided, so a
1359
+ * consumer never re-derives a provider's rules:
1360
+ *
1361
+ * * `isDefault` — the subscription's default method, or, when the
1362
+ * subscription names none, the customer's.
1363
+ * * `canRemove` — whether a delete would be accepted; the server's rule,
1364
+ * not `!isDefault`.
1365
+ *
1366
+ * `id` is Schematic's, and is what a delete takes; `externalId` is the
1367
+ * provider's, and is what making it the default takes.
1368
+ */
1369
+ export declare type PaymentMethod = CompanyPaymentMethodResponseData;
1370
+
1371
+ export declare interface PaymentMethodsHandle extends ResourceHandle<PaymentMethod[]> {
1372
+ /**
1373
+ * Makes `externalId` the default; `data` reloads once it has. Rejects
1374
+ * with the failure and records it on `mutationError`, so a caller can
1375
+ * await it or read it, whichever the component does.
1376
+ */
1377
+ setDefault: (externalId: string) => Promise<void>;
1378
+ /** Removes payment method `id`; `data` reloads once it has. Rejects as `setDefault` does. */
1379
+ remove: (id: string) => Promise<void>;
1380
+ /** A write is in flight. Distinct from `isPending`, which is the list loading. */
1381
+ isMutating: boolean;
1382
+ /** The last write's failure; cleared when the next write starts. */
1383
+ mutationError: Error | undefined;
1384
+ }
1385
+
1149
1386
  declare type PendingListenerFn = BooleanListenerFn | EmptyListenerFn;
1150
1387
 
1151
1388
  declare type PlanListenerFn = CheckPlanReturnListenerFn | EmptyListenerFn;
@@ -1491,6 +1728,10 @@ declare class SchematicBillingClient implements BillingClient {
1491
1728
  onSessionChange(listener: (event: SessionEvent) => void): () => void;
1492
1729
  fetchInvoices(params: InvoicesRequest): Promise<InvoicesResult>;
1493
1730
  fetchUpcomingInvoice(): Promise<UpcomingInvoice | null>;
1731
+ fetchPaymentMethods(): Promise<PaymentMethod[]>;
1732
+ createSetupIntent(): Promise<SetupIntent>;
1733
+ updatePaymentMethod(externalId: string): Promise<void>;
1734
+ deletePaymentMethod(id: string): Promise<void>;
1494
1735
  }
1495
1736
 
1496
1737
  /** Context for checking flags and sending events */
@@ -1574,6 +1815,7 @@ declare namespace SchematicJS {
1574
1815
  CompanyCreditBalance,
1575
1816
  CompanyDiscountResponseData,
1576
1817
  CompanyInvoiceResponseData,
1818
+ CompanyPaymentMethodResponseData,
1577
1819
  CompanyUpcomingInvoiceResponseData,
1578
1820
  CreditBalance,
1579
1821
  CreditBalanceListenerFn,
@@ -1600,6 +1842,7 @@ declare namespace SchematicJS {
1600
1842
  InvoicesResult,
1601
1843
  InvoiceStatus,
1602
1844
  Keys,
1845
+ PaymentMethod,
1603
1846
  PendingListenerFn,
1604
1847
  PlanListenerFn,
1605
1848
  RequestOptions,
@@ -1616,6 +1859,8 @@ declare namespace SchematicJS {
1616
1859
  SessionInput,
1617
1860
  SessionOptions,
1618
1861
  SessionStatus,
1862
+ SetupIntent,
1863
+ SetupIntentResponseData,
1619
1864
  SINGLETON,
1620
1865
  StoragePersister,
1621
1866
  TOKEN_CACHE_SIZE,
@@ -1796,6 +2041,57 @@ declare interface SessionOptions {
1796
2041
 
1797
2042
  export declare type SessionStatus = "pending" | "active" | "ended";
1798
2043
 
2044
+ /** What a provider's card form is mounted with to add a method. */
2045
+ export declare type SetupIntent = SetupIntentResponseData;
2046
+
2047
+ export declare interface SetupIntentHandle {
2048
+ /** A new intent every call: an intent is single-use, so none is kept. */
2049
+ create: () => Promise<SetupIntent>;
2050
+ }
2051
+
2052
+ /**
2053
+ * Schematic API
2054
+ * Schematic API
2055
+ *
2056
+ * The version of the OpenAPI document: 0.1
2057
+ *
2058
+ *
2059
+ * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
2060
+ * https://openapi-generator.tech
2061
+ * Do not edit the class manually.
2062
+ */
2063
+ /**
2064
+ *
2065
+ * @export
2066
+ * @interface SetupIntentResponseData
2067
+ */
2068
+ declare interface SetupIntentResponseData {
2069
+ /**
2070
+ *
2071
+ * @type {string}
2072
+ * @memberof SetupIntentResponseData
2073
+ */
2074
+ accountId?: string | null;
2075
+ /**
2076
+ *
2077
+ * @type {string}
2078
+ * @memberof SetupIntentResponseData
2079
+ */
2080
+ publishableKey?: string | null;
2081
+ /**
2082
+ *
2083
+ * @type {string}
2084
+ * @memberof SetupIntentResponseData
2085
+ */
2086
+ schematicPublishableKey: string;
2087
+ /**
2088
+ *
2089
+ * @type {string}
2090
+ * @memberof SetupIntentResponseData
2091
+ */
2092
+ setupIntentClientSecret?: string | null;
2093
+ }
2094
+
1799
2095
  /** The params of every singleton resource. */
1800
2096
  export declare const SINGLETON: Record<string, never>;
1801
2097
 
@@ -1876,6 +2172,19 @@ export declare function useInvalidateBillingData(): () => void;
1876
2172
  */
1877
2173
  export declare function useInvoices(query?: InvoiceQuery): InvoicesHandle;
1878
2174
 
2175
+ /**
2176
+ * The company's payment methods, with the writes on them. `data` is the
2177
+ * list, `isPending` and `error` its load, and `isMutating` and
2178
+ * `mutationError` the last write; a write's failure never lands on `error`,
2179
+ * which stays the list's own.
2180
+ *
2181
+ * Writes are not coalesced: a second call while one is in flight runs too,
2182
+ * the store reloads the list after each, and `isMutating` stays true until
2183
+ * the last lands. A component that wants one at a time disables its buttons
2184
+ * on `isMutating`.
2185
+ */
2186
+ export declare function usePaymentMethods(): PaymentMethodsHandle;
2187
+
1879
2188
  export declare const useSchematic: () => SchematicContextProps;
1880
2189
 
1881
2190
  export declare const useSchematicContext: (opts?: SchematicHookOpts) => {
@@ -1928,6 +2237,14 @@ export declare function useSchematicStrings(): StringOverrides | undefined;
1928
2237
 
1929
2238
  export declare function useSchematicTranslate(): Translate | undefined;
1930
2239
 
2240
+ /**
2241
+ * Mints setup intents for adding a payment method. Subscribes to no
2242
+ * resource, reports no state, and rejects with the failure. Once the
2243
+ * provider confirms the intent, the list is reloaded by whoever adds the
2244
+ * method — `refetch` on `usePaymentMethods`, or `useInvalidateBillingData`.
2245
+ */
2246
+ export declare function useSetupIntent(): SetupIntentHandle;
2247
+
1931
2248
  /**
1932
2249
  * The company's next bill. `data` is `null` when there is nothing to bill —
1933
2250
  * no subscription, which the endpoint reports as a 204 — so an element can