@volter/twin-stripe 3.0.0 → 3.0.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.
Files changed (253) hide show
  1. package/README.md +51 -21
  2. package/dist/generated/pack-facts.json +3 -3
  3. package/dist/journeys/coverage.json +596 -0
  4. package/dist/journeys/customer-life.json +6108 -0
  5. package/dist/journeys/customer-life.outline.md +371 -0
  6. package/dist/journeys/decisions.json +677 -0
  7. package/dist/journeys/demand.json +706 -0
  8. package/dist/journeys/score.json +853 -0
  9. package/dist/journeys/unreachable.json +102 -0
  10. package/dist/journeys/vendor-examples.json +8010 -0
  11. package/dist/spec/SOURCE.md +5 -1
  12. package/dist/spec/doc-examples.json +445 -0
  13. package/dist/spec/sources.json +135 -207
  14. package/dist/src/cli.d.ts +0 -1
  15. package/dist/src/cli.js +0 -2
  16. package/dist/src/engine/after-payment.d.ts +0 -1
  17. package/dist/src/engine/after-payment.js +0 -1
  18. package/dist/src/engine/common.d.ts +5 -5
  19. package/dist/src/engine/common.js +13 -11
  20. package/dist/src/engine/connect.d.ts +0 -21
  21. package/dist/src/engine/connect.js +1 -82
  22. package/dist/src/engine/customers.d.ts +0 -8
  23. package/dist/src/engine/customers.js +0 -22
  24. package/dist/src/engine/display.d.ts +0 -3
  25. package/dist/src/engine/display.js +0 -3
  26. package/dist/src/engine/files.d.ts +0 -7
  27. package/dist/src/engine/files.js +0 -10
  28. package/dist/src/engine/invoices.d.ts +6 -9
  29. package/dist/src/engine/invoices.js +56 -29
  30. package/dist/src/engine/issuing.d.ts +6 -8
  31. package/dist/src/engine/issuing.js +19 -10
  32. package/dist/src/engine/ledger.d.ts +0 -1
  33. package/dist/src/engine/ledger.js +0 -1
  34. package/dist/src/engine/oauth.js +1 -2
  35. package/dist/src/engine/refunds.js +2 -27
  36. package/dist/src/engine/stripe.d.ts +2 -7
  37. package/dist/src/engine/stripe.js +34 -83
  38. package/dist/src/engine/subscriptions.d.ts +0 -1
  39. package/dist/src/engine/subscriptions.js +0 -1
  40. package/dist/src/engine/version.d.ts +0 -2
  41. package/dist/src/engine/version.js +17 -6
  42. package/dist/src/fetch.js +2 -2
  43. package/dist/src/generated/surface.gen.json +1 -1
  44. package/dist/src/generated/ui.gen.json +1 -1
  45. package/dist/src/index.js +5 -3
  46. package/dist/src/manifest.js +348 -220
  47. package/dist/src/screens/billing-portal.js +5 -5
  48. package/dist/src/screens/{connect-oauth.d.ts → checkout-js.d.ts} +0 -1
  49. package/dist/src/screens/checkout-js.js +84 -0
  50. package/dist/src/screens/connect-onboarding.js +3 -3
  51. package/dist/src/screens/dashboard.d.ts +1 -1
  52. package/dist/src/screens/dashboard.js +52 -53
  53. package/dist/src/screens/stripe-js.js +53 -93
  54. package/dist/src/semantics/account.d.ts +2 -0
  55. package/dist/src/semantics/account.js +8 -0
  56. package/dist/src/semantics/accounts.js +3 -1
  57. package/dist/src/semantics/around.js +3 -6
  58. package/dist/src/semantics/billing_portal.d.ts +0 -1
  59. package/dist/src/semantics/billing_portal.js +1 -7
  60. package/dist/src/semantics/checkout.d.ts +1 -1
  61. package/dist/src/semantics/checkout.js +18 -15
  62. package/dist/src/semantics/clock.js +1 -7
  63. package/dist/src/semantics/customers.d.ts +1 -2
  64. package/dist/src/semantics/customers.js +32 -38
  65. package/dist/src/semantics/entitlements.d.ts +0 -2
  66. package/dist/src/semantics/entitlements.js +4 -50
  67. package/dist/src/semantics/events.d.ts +2 -3
  68. package/dist/src/semantics/events.js +6 -11
  69. package/dist/src/semantics/index.js +16 -38
  70. package/dist/src/semantics/invoices.d.ts +3 -8
  71. package/dist/src/semantics/invoices.js +134 -127
  72. package/dist/src/semantics/issuing.d.ts +6 -0
  73. package/dist/src/semantics/issuing.js +77 -0
  74. package/dist/src/semantics/payment_intents.d.ts +0 -1
  75. package/dist/src/semantics/payment_intents.js +5 -13
  76. package/dist/src/semantics/payment_methods.d.ts +0 -2
  77. package/dist/src/semantics/payment_methods.js +2 -26
  78. package/dist/src/semantics/payouts.d.ts +1 -0
  79. package/dist/src/semantics/payouts.js +8 -1
  80. package/dist/src/semantics/products.d.ts +1 -3
  81. package/dist/src/semantics/products.js +3 -14
  82. package/dist/src/semantics/refunds.d.ts +1 -2
  83. package/dist/src/semantics/refunds.js +1 -5
  84. package/dist/src/semantics/shared.d.ts +64 -336
  85. package/dist/src/semantics/shared.js +326 -1336
  86. package/dist/src/semantics/states.d.ts +20 -89
  87. package/dist/src/semantics/states.js +116 -334
  88. package/dist/src/semantics/subscriptions.d.ts +1 -2
  89. package/dist/src/semantics/subscriptions.js +23 -145
  90. package/dist/src/semantics/test_helpers.d.ts +2 -5
  91. package/dist/src/semantics/test_helpers.js +121 -43
  92. package/dist/src/semantics/webhook_endpoints.d.ts +2 -0
  93. package/dist/src/semantics/webhook_endpoints.js +26 -0
  94. package/generated/pack-facts.json +3 -3
  95. package/journeys/coverage.json +596 -0
  96. package/journeys/customer-life.json +6108 -0
  97. package/journeys/customer-life.outline.md +371 -0
  98. package/journeys/decisions.json +677 -0
  99. package/journeys/demand.json +706 -0
  100. package/journeys/score.json +853 -0
  101. package/journeys/unreachable.json +102 -0
  102. package/journeys/vendor-examples.json +8010 -0
  103. package/package.json +4 -3
  104. package/spec/SOURCE.md +5 -1
  105. package/spec/doc-examples.json +445 -0
  106. package/spec/sources.json +135 -207
  107. package/src/cli.ts +0 -3
  108. package/src/engine/after-payment.ts +0 -2
  109. package/src/engine/balance.ts +0 -1
  110. package/src/engine/checkout.ts +0 -1
  111. package/src/engine/common.ts +19 -17
  112. package/src/engine/connect.ts +1 -79
  113. package/src/engine/customers.ts +0 -25
  114. package/src/engine/display.ts +2 -3
  115. package/src/engine/files.ts +0 -13
  116. package/src/engine/invoices.ts +64 -33
  117. package/src/engine/issuing.ts +16 -11
  118. package/src/engine/ledger.ts +0 -2
  119. package/src/engine/oauth.ts +1 -2
  120. package/src/engine/onboarding.ts +0 -1
  121. package/src/engine/params.ts +0 -1
  122. package/src/engine/payment-intents.ts +0 -1
  123. package/src/engine/payment-methods.ts +0 -1
  124. package/src/engine/refunds.ts +2 -28
  125. package/src/engine/renewals.ts +0 -1
  126. package/src/engine/stripe.ts +35 -83
  127. package/src/engine/subscriptions.ts +0 -3
  128. package/src/engine/transfers.ts +0 -1
  129. package/src/engine/version.ts +15 -7
  130. package/src/engine/webhooks.ts +0 -2
  131. package/src/fetch.ts +2 -2
  132. package/src/generated/surface.gen.json +1 -1
  133. package/src/generated/ui.gen.json +1 -1
  134. package/src/index.ts +6 -4
  135. package/src/manifest.ts +348 -220
  136. package/src/screens/billing-portal.tsx +5 -7
  137. package/src/screens/checkout-js.ts +80 -0
  138. package/src/screens/checkout.tsx +0 -2
  139. package/src/screens/connect-onboarding.tsx +3 -5
  140. package/src/screens/dashboard.tsx +53 -73
  141. package/src/screens/stripe-js.ts +57 -125
  142. package/src/semantics/account.ts +10 -0
  143. package/src/semantics/account_links.ts +0 -1
  144. package/src/semantics/accounts.ts +8 -7
  145. package/src/semantics/apps.ts +1 -2
  146. package/src/semantics/around.ts +3 -6
  147. package/src/semantics/balance.ts +0 -1
  148. package/src/semantics/balance_transactions.ts +1 -3
  149. package/src/semantics/billing_portal.ts +1 -7
  150. package/src/semantics/charges.ts +1 -6
  151. package/src/semantics/checkout.ts +16 -12
  152. package/src/semantics/clock.ts +1 -8
  153. package/src/semantics/coupons.ts +0 -1
  154. package/src/semantics/customers.ts +32 -35
  155. package/src/semantics/doors.ts +2 -3
  156. package/src/semantics/entitlements.ts +1 -45
  157. package/src/semantics/events.ts +7 -14
  158. package/src/semantics/index.ts +16 -38
  159. package/src/semantics/invoice_payments.ts +1 -3
  160. package/src/semantics/invoices.ts +124 -119
  161. package/src/semantics/issuing.ts +74 -0
  162. package/src/semantics/payment_intents.ts +10 -17
  163. package/src/semantics/payment_methods.ts +2 -25
  164. package/src/semantics/payouts.ts +9 -3
  165. package/src/semantics/prices.ts +0 -1
  166. package/src/semantics/products.ts +4 -14
  167. package/src/semantics/promotion_codes.ts +0 -1
  168. package/src/semantics/radar.ts +1 -3
  169. package/src/semantics/refunds.ts +2 -11
  170. package/src/semantics/shared.ts +350 -1382
  171. package/src/semantics/states.ts +109 -330
  172. package/src/semantics/subscriptions.ts +25 -145
  173. package/src/semantics/test_helpers.ts +109 -43
  174. package/src/semantics/transfers.ts +1 -3
  175. package/src/semantics/webhook_endpoints.ts +27 -0
  176. package/src/server.ts +0 -1
  177. package/dist/src/engine/billing.d.ts +0 -5
  178. package/dist/src/engine/billing.js +0 -6
  179. package/dist/src/engine/charges.d.ts +0 -6
  180. package/dist/src/engine/charges.js +0 -13
  181. package/dist/src/engine/connect-settings.d.ts +0 -16
  182. package/dist/src/engine/connect-settings.js +0 -26
  183. package/dist/src/engine/coupons.d.ts +0 -0
  184. package/dist/src/engine/coupons.js +0 -5
  185. package/dist/src/engine/credit-notes.d.ts +0 -1
  186. package/dist/src/engine/credit-notes.js +0 -5
  187. package/dist/src/engine/disputes.d.ts +0 -0
  188. package/dist/src/engine/disputes.js +0 -9
  189. package/dist/src/engine/entitlements.d.ts +0 -1
  190. package/dist/src/engine/entitlements.js +0 -4
  191. package/dist/src/engine/ephemeral-keys.d.ts +0 -0
  192. package/dist/src/engine/ephemeral-keys.js +0 -4
  193. package/dist/src/engine/front.d.ts +0 -5
  194. package/dist/src/engine/front.js +0 -25
  195. package/dist/src/engine/payment-links.d.ts +0 -1
  196. package/dist/src/engine/payment-links.js +0 -5
  197. package/dist/src/engine/plans.d.ts +0 -6
  198. package/dist/src/engine/plans.js +0 -26
  199. package/dist/src/engine/platform.d.ts +0 -39
  200. package/dist/src/engine/platform.js +0 -34
  201. package/dist/src/engine/products.d.ts +0 -0
  202. package/dist/src/engine/products.js +0 -4
  203. package/dist/src/engine/setup-intents.d.ts +0 -1
  204. package/dist/src/engine/setup-intents.js +0 -4
  205. package/dist/src/engine/subscription-schedules.d.ts +0 -3
  206. package/dist/src/engine/subscription-schedules.js +0 -1
  207. package/dist/src/engine/tax.d.ts +0 -7
  208. package/dist/src/engine/tax.js +0 -28
  209. package/dist/src/engine/terminal.d.ts +0 -4
  210. package/dist/src/engine/terminal.js +0 -20
  211. package/dist/src/engine/test-clocks.d.ts +0 -5
  212. package/dist/src/engine/test-clocks.js +0 -9
  213. package/dist/src/engine/tokens.d.ts +0 -7
  214. package/dist/src/engine/tokens.js +0 -20
  215. package/dist/src/engine/treasury.d.ts +0 -23
  216. package/dist/src/engine/treasury.js +0 -45
  217. package/dist/src/screens/connect-oauth.js +0 -333
  218. package/dist/src/semantics/disputes.d.ts +0 -2
  219. package/dist/src/semantics/disputes.js +0 -5
  220. package/dist/src/semantics/invoiceitems.d.ts +0 -3
  221. package/dist/src/semantics/invoiceitems.js +0 -59
  222. package/dist/src/semantics/setup_intents.d.ts +0 -3
  223. package/dist/src/semantics/setup_intents.js +0 -41
  224. package/dist/src/semantics/subscription_items.d.ts +0 -5
  225. package/dist/src/semantics/subscription_items.js +0 -55
  226. package/dist/src/semantics/subscription_schedules.d.ts +0 -4
  227. package/dist/src/semantics/subscription_schedules.js +0 -60
  228. package/src/engine/billing.ts +0 -16
  229. package/src/engine/charges.ts +0 -19
  230. package/src/engine/connect-settings.ts +0 -23
  231. package/src/engine/coupons.ts +0 -5
  232. package/src/engine/credit-notes.ts +0 -6
  233. package/src/engine/disputes.ts +0 -9
  234. package/src/engine/entitlements.ts +0 -5
  235. package/src/engine/ephemeral-keys.ts +0 -3
  236. package/src/engine/front.ts +0 -31
  237. package/src/engine/payment-links.ts +0 -6
  238. package/src/engine/plans.ts +0 -42
  239. package/src/engine/platform.ts +0 -47
  240. package/src/engine/products.ts +0 -3
  241. package/src/engine/setup-intents.ts +0 -5
  242. package/src/engine/subscription-schedules.ts +0 -10
  243. package/src/engine/tax.ts +0 -39
  244. package/src/engine/terminal.ts +0 -23
  245. package/src/engine/test-clocks.ts +0 -11
  246. package/src/engine/tokens.ts +0 -22
  247. package/src/engine/treasury.ts +0 -47
  248. package/src/screens/connect-oauth.tsx +0 -376
  249. package/src/semantics/disputes.ts +0 -12
  250. package/src/semantics/invoiceitems.ts +0 -59
  251. package/src/semantics/setup_intents.ts +0 -45
  252. package/src/semantics/subscription_items.ts +0 -54
  253. package/src/semantics/subscription_schedules.ts +0 -66
@@ -3,7 +3,7 @@
3
3
  // sessions. A new connected account is not yet active: charges and payouts are off and its
4
4
  // requirements are outstanding, as on Stripe before onboarding. Account retrieve and delete and
5
5
  // the person list are the derived core's.
6
- import { accountRequirements, accountSettings, asBool, PLATFORM_ACCOUNT_ID } from "./stripe.js";
6
+ import { accountRequirements, accountSettings, PLATFORM_ACCOUNT_ID } from "./stripe.js";
7
7
  import { currentlyDue, kindOf } from "./onboarding.js";
8
8
  import { externalList } from "./common.js";
9
9
  // the platform's own account: stored once it is written, otherwise Stripe's default. It "controls itself" (controller
@@ -60,8 +60,6 @@ export const at_path = (a, path) => path.split('.').reduce((v, k) => (v && typeo
60
60
  export const CARD_COMPANY_NOW = ['business_profile.mcc', 'company.address.line1', 'company.address.city', 'company.address.state', 'company.address.postal_code', 'company.owners_provided', 'owners.first_name', 'owners.last_name', 'owners.email', 'representative.first_name', 'representative.last_name', 'representative.email', 'representative.address.line1', 'representative.address.city', 'representative.address.state', 'representative.address.postal_code', 'representative.relationship.title', 'representative.ssn_last_4'];
61
61
  export const CARD_COMPANY_LATER = ['company.phone', 'settings.payments.statement_descriptor', 'representative.dob.day', 'representative.dob.month', 'representative.dob.year', 'representative.phone'];
62
62
  export const CARD_INDIVIDUAL_NOW = ['business_profile.mcc', 'individual.address.line1', 'individual.address.city', 'individual.address.state', 'individual.address.postal_code', 'individual.email', 'individual.ssn_last_4'];
63
- /** A field only card_payments asks for (the transfers capability's requirements leave it out). */
64
- export const cardOnly = (field) => [...CARD_COMPANY_NOW, ...CARD_COMPANY_LATER, ...CARD_INDIVIDUAL_NOW].includes(field);
65
63
  export const personHas = (p, field) => {
66
64
  if (field === 'ssn_last_4')
67
65
  return p.ssn_last_4_provided === true;
@@ -108,82 +106,3 @@ export function keptKyc(params) {
108
106
  }
109
107
  return out;
110
108
  }
111
- /** A person's details as Stripe keeps them: an SSN or ID number given is kept only as provided (the Person object
112
- * answers ssn_last_4_provided and id_number_provided, never the numbers; docs.stripe.com/api/persons/object). */
113
- export function keptPerson(params, was = {}) {
114
- const { ssn_last_4, id_number, ...rest } = params;
115
- const out = { ...rest, ...(ssn_last_4 !== undefined && ssn_last_4 !== '' ? { ssn_last_4_provided: true } : {}), ...(id_number !== undefined && id_number !== '' ? { id_number_provided: true } : {}) };
116
- // a relationship, address or date of birth given in part is laid over what the person holds
117
- for (const k of ['relationship', 'address', 'dob'])
118
- if (out[k] && typeof out[k] === 'object' && was[k] && typeof was[k] === 'object')
119
- out[k] = { ...was[k], ...out[k] };
120
- return out;
121
- }
122
- export const RELATIONSHIP = { director: false, executive: false, owner: false, representative: false, percent_ownership: null, title: null };
123
- // ── capabilities: the account's capability map is the truth; requesting one leaves it pending ──
124
- /** A capability as its account stands: its status, and the account's requirements that capability asks for (transfers
125
- * leaves out what only card_payments asks for). Where the documentation stops and the twin decides: the account-wide
126
- * fields (the bank account, the terms) belong to every capability. */
127
- export const capabilityBody = (acct, id, status, requested = true, requestedAt = null) => {
128
- const req = acct.requirements ?? {};
129
- const mine = (list) => (Array.isArray(list) ? list : []).filter((f) => id === 'card_payments' || !cardOnly(f));
130
- const due = mine(req.currently_due);
131
- return {
132
- id, object: 'capability', account: acct.id, status, requested, requested_at: requestedAt,
133
- requirements: { currently_due: due, eventually_due: mine(req.eventually_due), past_due: [], pending_verification: [], errors: [], alternatives: [], current_deadline: null, disabled_reason: due.length ? 'requirements.past_due' : null },
134
- };
135
- };
136
- // a session is identified by its client_secret: the row is kept for traceability, the answer has no id
137
- /** Every embedded component an account session answers (the served spec requires all of them), each enabled only when
138
- * the request enables it, with its features: what the request gives, else the spec's stated default, "The default
139
- * value for this feature is `true`" (external_account_collection); disable_stripe_user_authentication "the opposite of
140
- * the `external_account_collection` value"; edit_payout_schedule and standard_payouts "Defaults to `true` when
141
- * `controller.losses.payments` is set to `stripe` for the account, otherwise `false`"; capture_payments, dispute_management
142
- * and refund_management "true by default"; destination_on_behalf_of_charge_management "false by default";
143
- * smart_disputes_management "Defaults to the value of `dispute_management`". Where the documentation stops and the twin
144
- * decides: instant_payouts (described as `enabled` "when Stripe is responsible for negative account balances", typed
145
- * boolean) is true exactly then, and the Issuing and financial-account features, which state no default, are false. */
146
- export const SESSION_COMPONENTS = {
147
- account_management: ['external_account_collection', 'disable_stripe_user_authentication'],
148
- account_onboarding: ['external_account_collection', 'disable_stripe_user_authentication'],
149
- balance_report: [], documents: [], payout_details: [], payout_reconciliation_report: [], payouts_list: [], tax_registrations: [], tax_settings: [],
150
- balances: ['external_account_collection', 'disable_stripe_user_authentication', 'edit_payout_schedule', 'instant_payouts', 'standard_payouts'],
151
- payouts: ['external_account_collection', 'disable_stripe_user_authentication', 'edit_payout_schedule', 'instant_payouts', 'standard_payouts'],
152
- disputes_list: ['capture_payments', 'destination_on_behalf_of_charge_management', 'dispute_management', 'refund_management', 'smart_disputes_management'],
153
- payment_details: ['capture_payments', 'destination_on_behalf_of_charge_management', 'dispute_management', 'refund_management', 'smart_disputes_management'],
154
- payments: ['capture_payments', 'destination_on_behalf_of_charge_management', 'dispute_management', 'refund_management', 'smart_disputes_management'],
155
- payment_disputes: ['destination_on_behalf_of_charge_management', 'dispute_management', 'refund_management', 'smart_disputes_management'],
156
- financial_account: ['external_account_collection', 'disable_stripe_user_authentication', 'send_money', 'transfer_balance'],
157
- financial_account_transactions: ['card_spend_dispute_management'],
158
- instant_payouts_promotion: ['external_account_collection', 'disable_stripe_user_authentication', 'instant_payouts'],
159
- issuing_card: ['card_management', 'card_spend_dispute_management', 'cardholder_management', 'spend_control_management'],
160
- issuing_cards_list: ['card_management', 'card_spend_dispute_management', 'cardholder_management', 'disable_stripe_user_authentication', 'spend_control_management'],
161
- notification_banner: ['external_account_collection', 'disable_stripe_user_authentication'],
162
- payment_method_settings: ['disable_stripe_user_authentication'],
163
- };
164
- export function sessionComponents(account, given) {
165
- const stripeLosses = (account.controller?.losses?.payments) === 'stripe';
166
- const out = {};
167
- for (const [name, featureNames] of Object.entries(SESSION_COMPONENTS)) {
168
- const c = given[name] && typeof given[name] === 'object' ? given[name] : {};
169
- const asked = c.features && typeof c.features === 'object' ? c.features : {};
170
- const f = {};
171
- const val = (k, fallback) => (asked[k] !== undefined ? asBool(asked[k]) : fallback);
172
- for (const k of featureNames) {
173
- if (k === 'external_account_collection')
174
- f[k] = val(k, true);
175
- else if (k === 'disable_stripe_user_authentication')
176
- f[k] = val(k, !val('external_account_collection', true));
177
- else if (k === 'edit_payout_schedule' || k === 'standard_payouts' || k === 'instant_payouts')
178
- f[k] = val(k, stripeLosses);
179
- else if (k === 'capture_payments' || k === 'dispute_management' || k === 'refund_management')
180
- f[k] = val(k, true);
181
- else if (k === 'smart_disputes_management')
182
- f[k] = val(k, val('dispute_management', true));
183
- else
184
- f[k] = val(k, false);
185
- }
186
- out[name] = { enabled: c.enabled !== undefined ? asBool(c.enabled) : false, features: f };
187
- }
188
- return out;
189
- }
@@ -2,11 +2,3 @@ import type { Row } from './common.js';
2
2
  /** What a new customer answers before any invoice: its invoice_prefix and a next_invoice_sequence of 1, a zero balance,
3
3
  * no metadata (docs.stripe.com/api/customers/object). */
4
4
  export declare const newCustomer: (id: string) => Row;
5
- export declare const EU_VAT: Record<string, RegExp>;
6
- export declare const euVatCountry: (value: string) => string | undefined;
7
- /** The tax ID types Stripe checks against a government register: "Stripe automatically validates all Australian
8
- * Business Numbers (ABNs)", "all European Value-Added-Tax (EU VAT) numbers" (VIES) and "all UK Value-Added-Tax (GB VAT)
9
- * numbers" (HMRC); a verification's status "is pending, verified, unverified, or unavailable", and "When automatic
10
- * validation is unavailable, you must manually verify the tax ID" (docs.stripe.com/billing/customer/tax-ids). Any other
11
- * type answers unavailable; one of these waits pending. */
12
- export declare const AUTO_VALIDATED: Set<string>;
@@ -6,25 +6,3 @@ import { invoicePrefix } from "./invoices.js";
6
6
  * no metadata (docs.stripe.com/api/customers/object). */
7
7
  export const newCustomer = (id) => ({ invoice_prefix: invoicePrefix(id), next_invoice_sequence: 1, balance: 0, metadata: {}, invoice_settings: {} });
8
8
  // ── tax ids: a customer's, keyed under it; `type` and `value` are required ──
9
- // An EU VAT number is its country's prefix and that country's format (the European Commission's VIES formats,
10
- // ec.europa.eu/taxation_customs/vies); Stripe refuses one that does not fit as tax_id_invalid
11
- // (docs.stripe.com/error-codes#tax-id-invalid). The message's wording is the twin's.
12
- export const EU_VAT = {
13
- AT: /^U\d{8}$/, BE: /^[01]\d{9}$/, BG: /^\d{9,10}$/, CY: /^\d{8}[A-Z]$/, CZ: /^\d{8,10}$/, DE: /^\d{9}$/, DK: /^\d{8}$/,
14
- EE: /^\d{9}$/, EL: /^\d{9}$/, ES: /^[A-Z0-9]\d{7}[A-Z0-9]$/, FI: /^\d{8}$/, FR: /^[A-Z0-9]{2}\d{9}$/, HR: /^\d{11}$/,
15
- HU: /^\d{8}$/, IE: /^(\d{7}[A-W][A-I]?|\d[A-Z+*]\d{5}[A-W])$/, IT: /^\d{11}$/, LT: /^(\d{9}|\d{12})$/, LU: /^\d{8}$/,
16
- LV: /^\d{11}$/, MT: /^\d{8}$/, NL: /^\d{9}B\d{2}$/, PL: /^\d{10}$/, PT: /^\d{9}$/, RO: /^\d{2,10}$/, SE: /^\d{12}$/,
17
- SI: /^\d{8}$/, SK: /^\d{10}$/, XI: /^(\d{9}|\d{12}|GD\d{3}|HA\d{3})$/,
18
- };
19
- export const euVatCountry = (value) => {
20
- const v = value.replace(/[\s.-]/g, '').toUpperCase();
21
- const prefix = v.slice(0, 2);
22
- const format = EU_VAT[prefix];
23
- return format && format.test(v.slice(2)) ? (prefix === 'EL' ? 'GR' : prefix) : undefined;
24
- };
25
- /** The tax ID types Stripe checks against a government register: "Stripe automatically validates all Australian
26
- * Business Numbers (ABNs)", "all European Value-Added-Tax (EU VAT) numbers" (VIES) and "all UK Value-Added-Tax (GB VAT)
27
- * numbers" (HMRC); a verification's status "is pending, verified, unverified, or unavailable", and "When automatic
28
- * validation is unavailable, you must manually verify the tax ID" (docs.stripe.com/billing/customer/tax-ids). Any other
29
- * type answers unavailable; one of these waits pending. */
30
- export const AUTO_VALIDATED = new Set(['au_abn', 'eu_vat', 'gb_vat']);
@@ -7,8 +7,5 @@ type Row = Record<string, any>;
7
7
  * Dashboard to differentiate between accounts", the same object page), and with neither to "Twin Inc.", the name the
8
8
  * twin has always given the World's own account. */
9
9
  export declare const PLATFORM_DEFAULT_NAME = "Twin Inc.";
10
- /** The bookkeeping type of a connected account's Connect OAuth connection (../screens/connect-oauth.tsx): one row per
11
- * account, `revoked: true` once deauthorized or its code reused. Read by the account list and the event path too. */
12
- export declare const OAUTH_CONNECTIONS = "_oauth_connection";
13
10
  export declare function publicBusinessName(account: Row | undefined): string;
14
11
  export {};
@@ -7,9 +7,6 @@
7
7
  * Dashboard to differentiate between accounts", the same object page), and with neither to "Twin Inc.", the name the
8
8
  * twin has always given the World's own account. */
9
9
  export const PLATFORM_DEFAULT_NAME = 'Twin Inc.';
10
- /** The bookkeeping type of a connected account's Connect OAuth connection (../screens/connect-oauth.tsx): one row per
11
- * account, `revoked: true` once deauthorized or its code reused. Read by the account list and the event path too. */
12
- export const OAUTH_CONNECTIONS = '_oauth_connection';
13
10
  export function publicBusinessName(account) {
14
11
  const named = (v) => (typeof v === 'string' && v.trim() ? v : undefined);
15
12
  return named(account?.business_profile?.name) ?? named(account?.settings?.dashboard?.display_name) ?? PLATFORM_DEFAULT_NAME;
@@ -1,11 +1,4 @@
1
1
  import type { Row } from './common.js';
2
- /** The type Stripe answers for an uploaded file: "The returned file type (for example, csv, pdf, jpg, or png)"
3
- * (docs.stripe.com/api/files/object). Where the documentation stops and the twin decides: read from the name's
4
- * extension (jpeg as jpg), and null for a name without one. */
5
- export declare function fileType(name: string): string | null;
6
- /** The purposes a file link may be made to: "The file's `purpose` must be one of the following: …" (the served
7
- * spec, POST /v1/file_links `file`). */
8
- export declare const LINKABLE: readonly ["business_icon", "business_logo", "customer_signature", "dispute_evidence", "finance_report_run", "financial_account_statement", "identity_document_downloadable", "issuing_regulatory_reporting", "pci_document", "selfie", "sigma_scheduled_query", "tax_document_user_upload", "terminal_android_apk", "terminal_reader_splashscreen"];
9
2
  export declare const PBC = "billing_portal.configuration";
10
3
  /** A portal configuration's features, each filled where the request leaves it: every feature is answered (the served
11
4
  * spec requires all five), as the create page's example answers a request that sets only customer_update and
@@ -1,13 +1,3 @@
1
- /** The type Stripe answers for an uploaded file: "The returned file type (for example, csv, pdf, jpg, or png)"
2
- * (docs.stripe.com/api/files/object). Where the documentation stops and the twin decides: read from the name's
3
- * extension (jpeg as jpg), and null for a name without one. */
4
- export function fileType(name) {
5
- const ext = /\.([a-z0-9]+)$/i.exec(name)?.[1]?.toLowerCase();
6
- return ext ? (ext === 'jpeg' ? 'jpg' : ext) : null;
7
- }
8
- /** The purposes a file link may be made to: "The file's `purpose` must be one of the following: …" (the served
9
- * spec, POST /v1/file_links `file`). */
10
- export const LINKABLE = ['business_icon', 'business_logo', 'customer_signature', 'dispute_evidence', 'finance_report_run', 'financial_account_statement', 'identity_document_downloadable', 'issuing_regulatory_reporting', 'pci_document', 'selfie', 'sigma_scheduled_query', 'tax_document_user_upload', 'terminal_android_apk', 'terminal_reader_splashscreen'];
11
1
  export const PBC = 'billing_portal.configuration';
12
2
  /** A portal configuration's features, each filled where the request leaves it: every feature is answered (the served
13
3
  * spec requires all five), as the create page's example answers a request that sets only customer_update and
@@ -1,14 +1,5 @@
1
1
  import type { Row } from './common.js';
2
2
  export declare const INV = "invoice";
3
- export declare const linesOf: (inv: Row) => Row[];
4
- export declare const sumLines: (lines: Row[]) => number;
5
- /** A draft's line no invoice item made (a subscription's) stays as it is when an item changes. */
6
- export declare function unlinkedLine(line: Row): Row;
7
- /** A preview's proration for a change at proration_date. Where the documentation stops and the twin decides: half the
8
- * period's charge credited as unused time and half charged as remaining time. */
9
- export declare function prorationLines(out: Row[], subtotal: number, currency: string, now: number, period: number): void;
10
- /** A draft invoice's fields before anything is on it: what a new invoice and a preview start from. */
11
- export declare const draft: (now: number) => Row;
12
3
  /** Whether leaving draft mints a PaymentIntent: only a charge_automatically invoice with a balance. */
13
4
  export declare const collectsThroughIntent: (inv: Row) => boolean;
14
5
  export declare const transitions: (inv: Row) => object;
@@ -22,3 +13,9 @@ export declare const invoicePrefix: (customerId: string) => string;
22
13
  * collects the invoice, open until the invoice is paid. Where the documentation stops and the twin decides: an
23
14
  * invoice has one payment, its default, and the payment's id is the invoice's with `inpay_`. */
24
15
  export declare function invoicePayment(inv: Row): Row | undefined;
16
+ export declare const linesOf: (inv: Row) => Row[];
17
+ export declare const sumLines: (lines: Row[]) => number;
18
+ /** Credit the previous price and debit the replacement for the same remaining service time. */
19
+ export declare function prorationLines(before: Row[], after: Row[], time: number, start: number, end: number, coupon: Row | undefined): Row[];
20
+ /** A draft invoice's fields before anything is on it: what a new invoice and a preview start from. */
21
+ export declare const draft: (now: number) => Row;
@@ -1,33 +1,5 @@
1
+ import { applyCouponDiscount } from "./stripe.js";
1
2
  export const INV = 'invoice';
2
- export const linesOf = (inv) => inv.lines?.data ?? [];
3
- export const sumLines = (lines) => lines.reduce((s, l) => s + (Number(l.amount) || 0), 0);
4
- /** A draft's line no invoice item made (a subscription's) stays as it is when an item changes. */
5
- export function unlinkedLine(line) {
6
- return line;
7
- }
8
- /** A preview's proration for a change at proration_date. Where the documentation stops and the twin decides: half the
9
- * period's charge credited as unused time and half charged as remaining time. */
10
- export function prorationLines(out, subtotal, currency, now, period) {
11
- const half = Math.round(subtotal / 2);
12
- out.unshift({ id: 'il_twin_proration_unused', object: 'line_item', type: 'invoiceitem', amount: -half, currency, proration: true, period: { start: now, end: period }, description: 'Unused time (proration credit)' });
13
- out.push({ id: 'il_twin_proration_remaining', object: 'line_item', type: 'invoiceitem', amount: half, currency, proration: true, period: { start: now, end: period }, description: 'Remaining time (proration charge)' });
14
- }
15
- // ── invoices ──
16
- /** A draft invoice's fields before anything is on it: what a new invoice and a preview start from. */
17
- export const draft = (now) => ({
18
- status: 'draft', livemode: false, currency: 'usd', collection_method: 'charge_automatically',
19
- auto_advance: false, attempt_count: 0, attempted: false,
20
- amount_due: 0, amount_paid: 0, amount_remaining: 0, amount_overpaid: 0, amount_paid_off_stripe: 0, amount_shipping: 0,
21
- subtotal: 0, total: 0, starting_balance: 0, post_payment_credit_notes_amount: 0, pre_payment_credit_notes_amount: 0,
22
- period_start: now, period_end: now, default_tax_rates: [], discounts: [],
23
- lines: { object: 'list', data: [], has_more: false, total_count: 0 },
24
- automatic_tax: { enabled: false, liability: null, status: null },
25
- status_transitions: { finalized_at: null, marked_uncollectible_at: null, paid_at: null, voided_at: null },
26
- issuer: { type: 'self' },
27
- payment_settings: { default_mandate: null, payment_method_options: null, payment_method_types: null },
28
- // a draft has no PaymentIntent: finalize mints it
29
- payment_intent: null,
30
- });
31
3
  /** Whether leaving draft mints a PaymentIntent: only a charge_automatically invoice with a balance. */
32
4
  // "Finalizing an invoice does the following: ... It creates an incomplete payment intent for the invoice"
33
5
  // (docs.stripe.com/invoicing/integration/workflow-transitions), whichever its collection method
@@ -55,3 +27,58 @@ export function invoicePayment(inv) {
55
27
  status_transitions: { paid_at: paid ? (transitions.paid_at ?? null) : null, canceled_at: inv.status === 'void' ? (transitions.voided_at ?? null) : null },
56
28
  };
57
29
  }
30
+ export const linesOf = (inv) => inv.lines?.data ?? [];
31
+ export const sumLines = (lines) => lines.reduce((s, l) => s + (Number(l.amount) || 0), 0);
32
+ /** Credit the previous price and debit the replacement for the same remaining service time. */
33
+ // source: https://docs.stripe.com/billing/subscriptions/prorations "Unused time on original 10 USD plan (credit)"
34
+ // source: https://docs.stripe.com/billing/subscriptions/prorations "Remaining time on new 20 USD plan (debit)"
35
+ // source: https://docs.stripe.com/billing/subscriptions/prorations "The current billing period’s start and end times are used to calculate the cost of the subscription before and after the change."
36
+ // source: https://docs.stripe.com/billing/subscriptions/prorations "By default, Stripe calculates prorations down to the second."
37
+ export function prorationLines(before, after, time, start, end, coupon) {
38
+ const out = [];
39
+ const discounted = (line, lines) => {
40
+ const total = sumLines(lines);
41
+ // source: https://docs.stripe.com/billing/subscriptions/prorations "When calculating proration credits or debits, Stripe uses the subscription’s discounted price, not the original price."
42
+ return Number(line.amount) - (total > 0 ? applyCouponDiscount(total, coupon) * Number(line.amount) / total : 0);
43
+ };
44
+ const priceId = (line) => typeof line.price === 'object' ? line.price.id : line.price;
45
+ const append = (line, lines, credit) => {
46
+ const billingPeriod = line.period;
47
+ const periodStart = Number(billingPeriod.start ?? start), periodEnd = Number(billingPeriod.end ?? end);
48
+ const fraction = Math.max(0, Math.min(1, (periodEnd - time) / Math.max(1, periodEnd - periodStart)));
49
+ const amount = Math.round(discounted(line, lines) * fraction) * (credit ? -1 : 1);
50
+ if (!amount)
51
+ return;
52
+ out.push({ ...line, id: `${line.id}_${credit ? 'unused' : 'remaining'}`, amount, proration: true, discountable: false,
53
+ period: { start: time, end: periodEnd }, description: `${credit ? 'Unused' : 'Remaining'} time on ${String(line.price?.nickname ?? priceId(line))}` });
54
+ };
55
+ for (const old of before) {
56
+ const replacement = after.find(line => line.subscription_item === old.subscription_item);
57
+ if (replacement && priceId(replacement) === priceId(old) && replacement.quantity === old.quantity)
58
+ continue;
59
+ append(old, before, true);
60
+ }
61
+ for (const next of after) {
62
+ const previous = before.find(line => line.subscription_item && line.subscription_item === next.subscription_item);
63
+ if (previous && priceId(previous) === priceId(next) && previous.quantity === next.quantity)
64
+ continue;
65
+ append(next, after, false);
66
+ }
67
+ return out;
68
+ }
69
+ // ── invoices ──
70
+ /** A draft invoice's fields before anything is on it: what a new invoice and a preview start from. */
71
+ export const draft = (now) => ({
72
+ status: 'draft', livemode: false, currency: 'usd', collection_method: 'charge_automatically',
73
+ auto_advance: false, attempt_count: 0, attempted: false,
74
+ amount_due: 0, amount_paid: 0, amount_remaining: 0, amount_overpaid: 0, amount_paid_off_stripe: 0, amount_shipping: 0,
75
+ subtotal: 0, total: 0, starting_balance: 0, post_payment_credit_notes_amount: 0, pre_payment_credit_notes_amount: 0,
76
+ period_start: now, period_end: now, default_tax_rates: [], discounts: [],
77
+ lines: { object: 'list', data: [], has_more: false, total_count: 0 },
78
+ automatic_tax: { enabled: false, liability: null, status: null },
79
+ status_transitions: { finalized_at: null, marked_uncollectible_at: null, paid_at: null, voided_at: null },
80
+ issuer: { type: 'self' },
81
+ payment_settings: { default_mandate: null, payment_method_options: null, payment_method_types: null },
82
+ // a draft has no PaymentIntent: finalize mints it
83
+ payment_intent: null,
84
+ });
@@ -6,9 +6,6 @@ export declare const holderId: (c: Row) => string;
6
6
  export declare const CARD = "issuing.card";
7
7
  export declare const AUTH = "issuing.authorization";
8
8
  export declare const TXN = "issuing.transaction";
9
- export declare const DSP = "issuing.dispute";
10
- export declare const TOK = "issuing.token";
11
- export declare const PD = "issuing.personalization_design";
12
9
  /** One request_history entry; the authorization code is derived from the request time (Stripe's is not unique either). */
13
10
  export declare function historyEntry(o: {
14
11
  amount: number;
@@ -28,8 +25,9 @@ export declare const cardId: (auth: Row) => unknown;
28
25
  * Authorization is automatically approved or declined based on your timeout settings"
29
26
  * (docs.stripe.com/issuing/controls/real-time-authorizations). */
30
27
  export declare const REALTIME_WINDOW_SECONDS = 2;
31
- /** Stripe's physical bundles are its catalog, not the account's: the twin serves the one its reference publishes
32
- * (docs.stripe.com/api/issuing/physical_bundles: "US Visa Credit White", standard, active, a card logo required and
33
- * carrier text optional). Where the documentation stops and the twin decides: the catalog is that one bundle, and its
34
- * second_line (required by the served spec, absent from the example) is optional. */
35
- export declare const PHYSICAL_BUNDLES: Row[];
28
+ /** A virtual card's number, drawn from the World: a 16-digit Visa number ("The brand of the card": the twin issues
29
+ * Visa) whose last digit is the Luhn check digit every card number carries. Where the documentation stops and the twin
30
+ * decides: the digits are the World's draw, Stripe's are the issuer's. */
31
+ export declare function cardNumberOf(drawn: string): string;
32
+ /** A virtual card's CVC, drawn from the World: three digits. */
33
+ export declare const cvcOf: (drawn: string) => string;
@@ -5,9 +5,6 @@ export const holderId = (c) => (typeof c.cardholder === 'string' ? c.cardholder
5
5
  export const CARD = 'issuing.card';
6
6
  export const AUTH = 'issuing.authorization';
7
7
  export const TXN = 'issuing.transaction';
8
- export const DSP = 'issuing.dispute';
9
- export const TOK = 'issuing.token';
10
- export const PD = 'issuing.personalization_design';
11
8
  /** One request_history entry; the authorization code is derived from the request time (Stripe's is not unique either). */
12
9
  export function historyEntry(o) {
13
10
  return {
@@ -36,10 +33,22 @@ export const cardId = (auth) => (auth.card && typeof auth.card === 'object' ? au
36
33
  * Authorization is automatically approved or declined based on your timeout settings"
37
34
  * (docs.stripe.com/issuing/controls/real-time-authorizations). */
38
35
  export const REALTIME_WINDOW_SECONDS = 2;
39
- /** Stripe's physical bundles are its catalog, not the account's: the twin serves the one its reference publishes
40
- * (docs.stripe.com/api/issuing/physical_bundles: "US Visa Credit White", standard, active, a card logo required and
41
- * carrier text optional). Where the documentation stops and the twin decides: the catalog is that one bundle, and its
42
- * second_line (required by the served spec, absent from the example) is optional. */
43
- export const PHYSICAL_BUNDLES = [
44
- { id: 'ics_NLuXJPDYSTjFON', object: 'issuing.physical_bundle', livemode: false, name: 'US Visa Credit White', features: { card_logo: 'required', carrier_text: 'optional', second_line: 'optional' }, status: 'active', type: 'standard' },
45
- ];
36
+ /** A virtual card's number, drawn from the World: a 16-digit Visa number ("The brand of the card": the twin issues
37
+ * Visa) whose last digit is the Luhn check digit every card number carries. Where the documentation stops and the twin
38
+ * decides: the digits are the World's draw, Stripe's are the issuer's. */
39
+ export function cardNumberOf(drawn) {
40
+ const body = `4${[...drawn].map((ch) => String(ch.charCodeAt(0) % 10)).join('').padEnd(14, '0').slice(0, 14)}`;
41
+ let sum = 0;
42
+ for (let i = 0; i < body.length; i++) {
43
+ let d = Number(body[body.length - 1 - i]);
44
+ if (i % 2 === 0) {
45
+ d *= 2;
46
+ if (d > 9)
47
+ d -= 9;
48
+ }
49
+ sum += d;
50
+ }
51
+ return `${body}${(10 - (sum % 10)) % 10}`;
52
+ }
53
+ /** A virtual card's CVC, drawn from the World: three digits. */
54
+ export const cvcOf = (drawn) => [...drawn].map((ch) => String(ch.charCodeAt(0) % 10)).join('').padEnd(3, '0').slice(0, 3);
@@ -1,6 +1,5 @@
1
1
  import type { Row } from './common.js';
2
2
  export declare const BT = "balance_transaction";
3
- export declare const DAY = 86400;
4
3
  /** A ledger entry's mark: available at once, its balance.available not yet sent (settleDueEntries). */
5
4
  export declare const UNSENT = "_availableUnsent";
6
5
  export declare const BYPASS_NUMBERS: Set<string>;
@@ -1,6 +1,5 @@
1
1
  import { BYPASS_PENDING_CARDS } from "./test-cards.js";
2
2
  export const BT = 'balance_transaction';
3
- export const DAY = 86_400;
4
3
  /** A ledger entry's mark: available at once, its balance.available not yet sent (settleDueEntries). */
5
4
  export const UNSENT = '_availableUnsent';
6
5
  export const BYPASS_NUMBERS = new Set(Object.values(BYPASS_PENDING_CARDS).map((c) => c.number));
@@ -1,5 +1,4 @@
1
- // A connected account's OAuth connection to the platform (../screens/connect-oauth.tsx makes it), as the API reads it:
2
- // whether it was revoked, which account an OAuth key acts as, and a key shown as Stripe's errors show one.
1
+ // Stripe API key parsing and error redaction, from the API authentication documentation.
3
2
  /** A key shown the way Stripe's errors show one: its prefix and its last four. */
4
3
  export const redactKey = (key) => {
5
4
  const prefix = /^(sk|rk|pk)_(test|live)_/.exec(key)?.[0] ?? '';
@@ -1,28 +1,3 @@
1
- // Refund semantics. A refund always names what it took money out of and lands there: a refund
2
- // naming nothing, an id nobody minted, or more than the charge has left is refused as Stripe
3
- // refuses it. The machine in ../manifest.ts says only a refund waiting on the customer
4
- // (requires_action) may be canceled. List and update are the derived core's.
5
- //
6
- // Refunding a destination charge can take back the connected account's share (reverse_transfer: a reversal of the
7
- // charge's transfer, in proportion to the refund) and the platform's (refund_application_fee: a refund of the
8
- // application fee, in proportion) (docs.stripe.com/api/refunds/create#create_refund-reverse_transfer,
9
- // docs.stripe.com/connect/destination-charges#issue-refunds). Where the documentation stops and the twin decides: the
10
- // twin's destination charge transfers the amount less the fee (the fee is kept back rather than collected from the
11
- // connected account), so a fee refund moves no money of its own; the reversal and the refund settle both shares.
12
- //
13
- // A payment made by bank transfer (from the customer's cash balance) is refunded to the customer's bank account: Stripe
14
- // emails the customer (instructions_email, else the customer's email) for their bank details and the refund waits in
15
- // requires_action, moving no money, until they answer; only then can it still be canceled. With origin=customer_balance
16
- // it goes back to the cash balance at once (docs.stripe.com/payments/customer-balance/refunding,
17
- // docs.stripe.com/api/refunds/cancel). Where the documentation stops and the twin decides: the customer never answers
18
- // the email in the World, and its link expires 30 days on.
19
- //
20
- // An uncaptured charge holds an authorization, not money. A PaymentIntent's is not refunded: "the charge attached to the
21
- // PaymentIntent remains uncaptured and can't be refunded directly. You must cancel the PaymentIntent"
22
- // (docs.stripe.com/refunds), which releases it (charges.ts cancelAuthorization). A charge made with capture=false is
23
- // released by its refund, as its authorization would be "automatically refunded if uncaptured" (spec/openapi.json.gz,
24
- // `capture_before`): refunded in full, no balance moved, and its capture refused afterwards. Where the documentation
25
- // stops and the twin decides: the refusal's code (payment_intent_unexpected_state) and wording, and that a refund of a
26
- // capture=false charge releases the whole authorization, so an `amount` short of it is refused.
27
- // the reasons a caller may give; `expired_uncaptured_charge` is Stripe's own
1
+ // The published refund reasons; expired_uncaptured_charge is Stripe's own, not a request reason.
2
+ // source: spec:/paths/~1v1~1refunds/post/requestBody/content/application~1x-www-form-urlencoded/schema/properties/reason "String indicating the reason for the refund."
28
3
  export const REFUND_REASONS = new Set(['duplicate', 'fraudulent', 'requested_by_customer']);
@@ -22,7 +22,6 @@ export declare function requiresAuthentication(...paramSets: Array<Record<string
22
22
  export declare function threeDsNextAction(): Record<string, unknown>;
23
23
  export declare function requiresMicrodeposits(...paramSets: Array<Record<string, unknown>>): boolean;
24
24
  export declare function microdepositsNextAction(): Record<string, unknown>;
25
- export declare function verifyMicrodeposits(params: Record<string, unknown>, _existing: Record<string, unknown>): StripeResponse | null;
26
25
  /** A card error's body: `charge` "For card errors, the ID of the failed charge", and `payment_intent` "The PaymentIntent
27
26
  * object for errors returned on a request involving a PaymentIntent" (docs.stripe.com/api/errors). */
28
27
  export declare function cardError(outcome: DeclineOutcome, attach?: {
@@ -51,10 +50,6 @@ export declare function subscriptionCouponParam(params: Record<string, unknown>)
51
50
  export declare function buildDiscount(coupon: Record<string, unknown>, customer: string, at: number, on?: {
52
51
  subscription?: string;
53
52
  }): Record<string, unknown>;
54
- export declare function subscriptionItemPairs(sub: Record<string, unknown>): Array<{
55
- price: string;
56
- quantity: number;
57
- }>;
58
53
  export declare function subscriptionItemEntries(value: unknown): Array<Record<string, unknown>>;
59
54
  type BillingInterval = 'day' | 'week' | 'month' | 'year';
60
55
  export declare function resolveSubscriptionBillingInterval(entries: Array<Record<string, unknown>>, find: FindStored): {
@@ -81,9 +76,8 @@ export declare function resolveTrial(params: Record<string, unknown>, at: number
81
76
  start: number;
82
77
  end: number;
83
78
  } | undefined;
84
- export declare function embedIssuingAuthorizationCard(body: Record<string, unknown>, find: FindStored): Record<string, unknown>;
85
79
  export declare function emptySpendingControls(): Record<string, unknown>;
86
- export declare function normalizeSpendingControls(raw: unknown, currency: string | null): {
80
+ export declare function normalizeSpendingControls(raw: unknown, currency: string | null, previous?: Record<string, unknown>): {
87
81
  controls?: Record<string, unknown>;
88
82
  error?: StripeResponse;
89
83
  };
@@ -124,4 +118,5 @@ export declare function resolveLineItem(entry: Record<string, unknown>, index: n
124
118
  };
125
119
  export declare function lineItemEntries(params: Record<string, unknown>): Array<Record<string, unknown>>;
126
120
  export declare function chargeDefaults(chargeId: string, amount: number, captured: boolean, occurredAt?: string): Record<string, unknown>;
121
+ export declare function planView(price: Record<string, unknown>): Record<string, unknown>;
127
122
  export {};