@hanzo/commerce 7.6.1 → 7.6.4

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 (264) hide show
  1. package/LICENSE.md +21 -0
  2. package/client.ts +124 -64
  3. package/components/add-to-cart-widget.tsx +6 -0
  4. package/components/item/product-card.tsx +18 -1
  5. package/dist/billing.d.ts +2 -0
  6. package/dist/billing.js +3 -0
  7. package/dist/billing.js.map +1 -0
  8. package/dist/client.d.ts +432 -0
  9. package/dist/client.js +392 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/components/Icons.d.ts +18 -0
  12. package/dist/components/Icons.js +19 -0
  13. package/dist/components/Icons.js.map +1 -0
  14. package/dist/components/add-to-cart-widget.d.ts +11 -0
  15. package/dist/components/add-to-cart-widget.js +85 -0
  16. package/dist/components/add-to-cart-widget.js.map +1 -0
  17. package/dist/components/buy/buy-card.d.ts +30 -0
  18. package/dist/components/buy/buy-card.js +109 -0
  19. package/dist/components/buy/buy-card.js.map +1 -0
  20. package/dist/components/buy/carousel-buy-card.d.ts +12 -0
  21. package/dist/components/buy/carousel-buy-card.js +94 -0
  22. package/dist/components/buy/carousel-buy-card.js.map +1 -0
  23. package/dist/components/buy/multi-family/all-variants-carousel.d.ts +4 -0
  24. package/dist/components/buy/multi-family/all-variants-carousel.js +115 -0
  25. package/dist/components/buy/multi-family/all-variants-carousel.js.map +1 -0
  26. package/dist/components/buy/multi-family/family-carousel/index.d.ts +4 -0
  27. package/dist/components/buy/multi-family/family-carousel/index.js +27 -0
  28. package/dist/components/buy/multi-family/family-carousel/index.js.map +1 -0
  29. package/dist/components/buy/multi-family/family-carousel/slide.d.ts +11 -0
  30. package/dist/components/buy/multi-family/family-carousel/slide.js +35 -0
  31. package/dist/components/buy/multi-family/family-carousel/slide.js.map +1 -0
  32. package/dist/components/buy/multi-family/family-carousel/state.d.ts +20 -0
  33. package/dist/components/buy/multi-family/family-carousel/state.js +59 -0
  34. package/dist/components/buy/multi-family/family-carousel/state.js.map +1 -0
  35. package/dist/components/buy/multi-family/index.d.ts +2 -0
  36. package/dist/components/buy/multi-family/index.js +3 -0
  37. package/dist/components/buy/multi-family/index.js.map +1 -0
  38. package/dist/components/buy/single-family-selector.d.ts +15 -0
  39. package/dist/components/buy/single-family-selector.js +28 -0
  40. package/dist/components/buy/single-family-selector.js.map +1 -0
  41. package/dist/components/buy/title-and-byline.d.ts +8 -0
  42. package/dist/components/buy/title-and-byline.js +7 -0
  43. package/dist/components/buy/title-and-byline.js.map +1 -0
  44. package/dist/components/cart/cart-panel/cart-line-item.d.ts +11 -0
  45. package/dist/components/cart/cart-panel/cart-line-item.js +25 -0
  46. package/dist/components/cart/cart-panel/cart-line-item.js.map +1 -0
  47. package/dist/components/cart/cart-panel/index.d.ts +19 -0
  48. package/dist/components/cart/cart-panel/index.js +65 -0
  49. package/dist/components/cart/cart-panel/index.js.map +1 -0
  50. package/dist/components/cart/cart-panel/promo-code.d.ts +4 -0
  51. package/dist/components/cart/cart-panel/promo-code.js +62 -0
  52. package/dist/components/cart/cart-panel/promo-code.js.map +1 -0
  53. package/dist/components/cart/cart-panel/total-area.d.ts +7 -0
  54. package/dist/components/cart/cart-panel/total-area.js +14 -0
  55. package/dist/components/cart/cart-panel/total-area.js.map +1 -0
  56. package/dist/components/checkout/payment-step-form/card-icon-row.d.ts +2 -0
  57. package/dist/components/checkout/payment-step-form/card-icon-row.js +14 -0
  58. package/dist/components/checkout/payment-step-form/card-icon-row.js.map +1 -0
  59. package/dist/components/checkout/payment-step-form/card-icons/amex.d.ts +4 -0
  60. package/dist/components/checkout/payment-step-form/card-icons/amex.js +6 -0
  61. package/dist/components/checkout/payment-step-form/card-icons/amex.js.map +1 -0
  62. package/dist/components/checkout/payment-step-form/card-icons/diners-club.d.ts +4 -0
  63. package/dist/components/checkout/payment-step-form/card-icons/diners-club.js +6 -0
  64. package/dist/components/checkout/payment-step-form/card-icons/diners-club.js.map +1 -0
  65. package/dist/components/checkout/payment-step-form/card-icons/discover.d.ts +4 -0
  66. package/dist/components/checkout/payment-step-form/card-icons/discover.js +6 -0
  67. package/dist/components/checkout/payment-step-form/card-icons/discover.js.map +1 -0
  68. package/dist/components/checkout/payment-step-form/card-icons/jcb.d.ts +4 -0
  69. package/dist/components/checkout/payment-step-form/card-icons/jcb.js +6 -0
  70. package/dist/components/checkout/payment-step-form/card-icons/jcb.js.map +1 -0
  71. package/dist/components/checkout/payment-step-form/card-icons/mastercard.d.ts +4 -0
  72. package/dist/components/checkout/payment-step-form/card-icons/mastercard.js +6 -0
  73. package/dist/components/checkout/payment-step-form/card-icons/mastercard.js.map +1 -0
  74. package/dist/components/checkout/payment-step-form/card-icons/visa.d.ts +4 -0
  75. package/dist/components/checkout/payment-step-form/card-icons/visa.js +6 -0
  76. package/dist/components/checkout/payment-step-form/card-icons/visa.js.map +1 -0
  77. package/dist/components/checkout/payment-step-form/cc-button.d.ts +3 -0
  78. package/dist/components/checkout/payment-step-form/cc-button.js +6 -0
  79. package/dist/components/checkout/payment-step-form/cc-button.js.map +1 -0
  80. package/dist/components/checkout/payment-step-form/contact-form.d.ts +5 -0
  81. package/dist/components/checkout/payment-step-form/contact-form.js +6 -0
  82. package/dist/components/checkout/payment-step-form/contact-form.js.map +1 -0
  83. package/dist/components/checkout/payment-step-form/crypto-icons/btc.d.ts +4 -0
  84. package/dist/components/checkout/payment-step-form/crypto-icons/btc.js +6 -0
  85. package/dist/components/checkout/payment-step-form/crypto-icons/btc.js.map +1 -0
  86. package/dist/components/checkout/payment-step-form/crypto-icons/eth.d.ts +4 -0
  87. package/dist/components/checkout/payment-step-form/crypto-icons/eth.js +6 -0
  88. package/dist/components/checkout/payment-step-form/crypto-icons/eth.js.map +1 -0
  89. package/dist/components/checkout/payment-step-form/crypto-icons/usdt.d.ts +4 -0
  90. package/dist/components/checkout/payment-step-form/crypto-icons/usdt.js +6 -0
  91. package/dist/components/checkout/payment-step-form/crypto-icons/usdt.js.map +1 -0
  92. package/dist/components/checkout/payment-step-form/index.d.ts +4 -0
  93. package/dist/components/checkout/payment-step-form/index.js +66 -0
  94. package/dist/components/checkout/payment-step-form/index.js.map +1 -0
  95. package/dist/components/checkout/payment-step-form/methods/bank-transfer.d.ts +4 -0
  96. package/dist/components/checkout/payment-step-form/methods/bank-transfer.js +24 -0
  97. package/dist/components/checkout/payment-step-form/methods/bank-transfer.js.map +1 -0
  98. package/dist/components/checkout/payment-step-form/methods/card.d.ts +4 -0
  99. package/dist/components/checkout/payment-step-form/methods/card.js +160 -0
  100. package/dist/components/checkout/payment-step-form/methods/card.js.map +1 -0
  101. package/dist/components/checkout/payment-step-form/methods/crypto.d.ts +9 -0
  102. package/dist/components/checkout/payment-step-form/methods/crypto.js +137 -0
  103. package/dist/components/checkout/payment-step-form/methods/crypto.js.map +1 -0
  104. package/dist/components/checkout/payment-step-form/methods/index.d.ts +6 -0
  105. package/dist/components/checkout/payment-step-form/methods/index.js +21 -0
  106. package/dist/components/checkout/payment-step-form/methods/index.js.map +1 -0
  107. package/dist/components/checkout/shipping-step-form.d.ts +3 -0
  108. package/dist/components/checkout/shipping-step-form.js +53 -0
  109. package/dist/components/checkout/shipping-step-form.js.map +1 -0
  110. package/dist/components/index.d.ts +8 -0
  111. package/dist/components/index.js +9 -0
  112. package/dist/components/index.js.map +1 -0
  113. package/dist/components/item/product-card.d.ts +7 -0
  114. package/dist/components/item/product-card.js +9 -0
  115. package/dist/components/item/product-card.js.map +1 -0
  116. package/dist/components/item-selector/button.d.ts +4 -0
  117. package/dist/components/item-selector/button.js +47 -0
  118. package/dist/components/item-selector/button.js.map +1 -0
  119. package/dist/components/item-selector/carousel/index.d.ts +12 -0
  120. package/dist/components/item-selector/carousel/index.js +74 -0
  121. package/dist/components/item-selector/carousel/index.js.map +1 -0
  122. package/dist/components/item-selector/carousel/slider.d.ts +8 -0
  123. package/dist/components/item-selector/carousel/slider.js +12 -0
  124. package/dist/components/item-selector/carousel/slider.js.map +1 -0
  125. package/dist/components/item-selector/index.d.ts +2 -0
  126. package/dist/components/item-selector/index.js +3 -0
  127. package/dist/components/item-selector/index.js.map +1 -0
  128. package/dist/components/item-selector/quantity-indicator.d.ts +9 -0
  129. package/dist/components/item-selector/quantity-indicator.js +16 -0
  130. package/dist/components/item-selector/quantity-indicator.js.map +1 -0
  131. package/dist/components/node-tabs/index.d.ts +14 -0
  132. package/dist/components/node-tabs/index.js +42 -0
  133. package/dist/components/node-tabs/index.js.map +1 -0
  134. package/dist/components/node-tabs/node-image.d.ts +6 -0
  135. package/dist/components/node-tabs/node-image.js +13 -0
  136. package/dist/components/node-tabs/node-image.js.map +1 -0
  137. package/dist/index.d.ts +9 -0
  138. package/dist/index.js +9 -0
  139. package/dist/index.js.map +1 -0
  140. package/dist/metering.d.ts +162 -0
  141. package/dist/metering.js +204 -0
  142. package/dist/metering.js.map +1 -0
  143. package/dist/metering.test.d.ts +13 -0
  144. package/dist/metering.test.js +181 -0
  145. package/dist/metering.test.js.map +1 -0
  146. package/dist/product-card.test.d.ts +14 -0
  147. package/dist/product-card.test.js +96 -0
  148. package/dist/product-card.test.js.map +1 -0
  149. package/dist/service/context.d.ts +8 -0
  150. package/dist/service/context.js +19 -0
  151. package/dist/service/context.js.map +1 -0
  152. package/dist/service/debug.d.ts +10 -0
  153. package/dist/service/debug.js +30 -0
  154. package/dist/service/debug.js.map +1 -0
  155. package/dist/service/impls/standalone/actual-line-item.d.ts +40 -0
  156. package/dist/service/impls/standalone/actual-line-item.js +84 -0
  157. package/dist/service/impls/standalone/actual-line-item.js.map +1 -0
  158. package/dist/service/impls/standalone/get-instance.d.ts +2 -0
  159. package/dist/service/impls/standalone/get-instance.js +39 -0
  160. package/dist/service/impls/standalone/get-instance.js.map +1 -0
  161. package/dist/service/impls/standalone/index.d.ts +67 -0
  162. package/dist/service/impls/standalone/index.js +416 -0
  163. package/dist/service/impls/standalone/index.js.map +1 -0
  164. package/dist/service/impls/standalone/order/firebase.d.ts +6 -0
  165. package/dist/service/impls/standalone/order/firebase.js +6 -0
  166. package/dist/service/impls/standalone/order/firebase.js.map +1 -0
  167. package/dist/service/impls/standalone/order/index.d.ts +30 -0
  168. package/dist/service/impls/standalone/order/index.js +21 -0
  169. package/dist/service/impls/standalone/order/index.js.map +1 -0
  170. package/dist/service/impls/standalone/persistence.d.ts +4 -0
  171. package/dist/service/impls/standalone/persistence.js +22 -0
  172. package/dist/service/impls/standalone/persistence.js.map +1 -0
  173. package/dist/service/path-utils.d.ts +7 -0
  174. package/dist/service/path-utils.js +16 -0
  175. package/dist/service/path-utils.js.map +1 -0
  176. package/dist/service/sep.d.ts +6 -0
  177. package/dist/service/sep.js +6 -0
  178. package/dist/service/sep.js.map +1 -0
  179. package/dist/types/category-node.d.ts +36 -0
  180. package/dist/types/category-node.js +2 -0
  181. package/dist/types/category-node.js.map +1 -0
  182. package/dist/types/checkout.d.ts +33 -0
  183. package/dist/types/checkout.js +2 -0
  184. package/dist/types/checkout.js.map +1 -0
  185. package/dist/types/commerce-config.d.ts +11 -0
  186. package/dist/types/commerce-config.js +2 -0
  187. package/dist/types/commerce-config.js.map +1 -0
  188. package/dist/types/commerce-service.d.ts +109 -0
  189. package/dist/types/commerce-service.js +2 -0
  190. package/dist/types/commerce-service.js.map +1 -0
  191. package/dist/types/family.d.ts +16 -0
  192. package/dist/types/family.js +2 -0
  193. package/dist/types/family.js.map +1 -0
  194. package/dist/types/index.d.ts +13 -0
  195. package/dist/types/index.js +8 -0
  196. package/dist/types/index.js.map +1 -0
  197. package/dist/types/item-selector.d.ts +72 -0
  198. package/dist/types/item-selector.js +2 -0
  199. package/dist/types/item-selector.js.map +1 -0
  200. package/dist/types/line-item.d.ts +14 -0
  201. package/dist/types/line-item.js +2 -0
  202. package/dist/types/line-item.js.map +1 -0
  203. package/dist/types/multi-family-selector-props.d.ts +16 -0
  204. package/dist/types/multi-family-selector-props.js +2 -0
  205. package/dist/types/multi-family-selector-props.js.map +1 -0
  206. package/dist/types/product.d.ts +15 -0
  207. package/dist/types/product.js +2 -0
  208. package/dist/types/product.js.map +1 -0
  209. package/dist/types/promo.d.ts +7 -0
  210. package/dist/types/promo.js +2 -0
  211. package/dist/types/promo.js.map +1 -0
  212. package/dist/types/selection-ui-specifier.d.ts +40 -0
  213. package/dist/types/selection-ui-specifier.js +2 -0
  214. package/dist/types/selection-ui-specifier.js.map +1 -0
  215. package/dist/types/string-mutator.d.ts +9 -0
  216. package/dist/types/string-mutator.js +2 -0
  217. package/dist/types/string-mutator.js.map +1 -0
  218. package/dist/types/token-separators.d.ts +6 -0
  219. package/dist/types/token-separators.js +2 -0
  220. package/dist/types/token-separators.js.map +1 -0
  221. package/dist/util/analytics.d.ts +9 -0
  222. package/dist/util/analytics.js +10 -0
  223. package/dist/util/analytics.js.map +1 -0
  224. package/dist/util/countries.d.ts +7 -0
  225. package/dist/util/countries.js +197 -0
  226. package/dist/util/countries.js.map +1 -0
  227. package/dist/util/error.d.ts +1 -0
  228. package/dist/util/error.js +22 -0
  229. package/dist/util/error.js.map +1 -0
  230. package/dist/util/index.d.ts +15 -0
  231. package/dist/util/index.js +54 -0
  232. package/dist/util/index.js.map +1 -0
  233. package/dist/util/item-selector-options-accessor.d.ts +3 -0
  234. package/dist/util/item-selector-options-accessor.js +27 -0
  235. package/dist/util/item-selector-options-accessor.js.map +1 -0
  236. package/dist/util/line-item-ref.d.ts +8 -0
  237. package/dist/util/line-item-ref.js +15 -0
  238. package/dist/util/line-item-ref.js.map +1 -0
  239. package/dist/util/multi-family-selector-options-accessor.d.ts +3 -0
  240. package/dist/util/multi-family-selector-options-accessor.js +11 -0
  241. package/dist/util/multi-family-selector-options-accessor.js.map +1 -0
  242. package/dist/util/obs-string-mutator.d.ts +8 -0
  243. package/dist/util/obs-string-mutator.js +15 -0
  244. package/dist/util/obs-string-mutator.js.map +1 -0
  245. package/dist/util/product-media-accessor.d.ts +29 -0
  246. package/dist/util/product-media-accessor.js +22 -0
  247. package/dist/util/product-media-accessor.js.map +1 -0
  248. package/dist/util/promo-codes.d.ts +3 -0
  249. package/dist/util/promo-codes.js +100 -0
  250. package/dist/util/promo-codes.js.map +1 -0
  251. package/dist/util/selection-ui-specifiers.d.ts +3 -0
  252. package/dist/util/selection-ui-specifiers.js +24 -0
  253. package/dist/util/selection-ui-specifiers.js.map +1 -0
  254. package/dist/util/square-payment.d.ts +7 -0
  255. package/dist/util/square-payment.js +37 -0
  256. package/dist/util/square-payment.js.map +1 -0
  257. package/dist/util/use-sync-sku-param-w-current-item.d.ts +2 -0
  258. package/dist/util/use-sync-sku-param-w-current-item.js +61 -0
  259. package/dist/util/use-sync-sku-param-w-current-item.js.map +1 -0
  260. package/index.ts +18 -3
  261. package/metering.test.ts +199 -0
  262. package/metering.ts +289 -0
  263. package/package.json +19 -17
  264. package/product-card.test.tsx +104 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 hanzo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/client.ts CHANGED
@@ -25,15 +25,6 @@
25
25
  * })
26
26
  * window.location.href = session.checkoutUrl
27
27
  *
28
- * // Tokenize a card (S2S — no external SDK required)
29
- * const token = await commerce.tokenizeCard({
30
- * number: '4242424242424242',
31
- * expiryMonth: '12',
32
- * expiryYear: '2027',
33
- * cvc: '123',
34
- * name: 'Jane Smith',
35
- * })
36
- *
37
28
  * // Subscribe
38
29
  * const sub = await commerce.subscribe({ planId: 'pro', userId: 'user_xyz' })
39
30
  * ```
@@ -67,6 +58,29 @@ export type Balance = {
67
58
  available: number
68
59
  }
69
60
 
61
+ /**
62
+ * Tier-aware balance from GET /v1/billing/tier. effectiveAvailable folds the
63
+ * tenant's included plan allotment (e.g. the free-tier daily credit) into the
64
+ * prepaid available balance — gate on this to honor included usage first.
65
+ */
66
+ export type TierResponse = {
67
+ user: string
68
+ tier: {
69
+ name: string
70
+ displayName?: string
71
+ maxAgents?: number
72
+ unlimitedAgents?: boolean
73
+ dailyCreditsCents?: number
74
+ allowedModels?: string[]
75
+ }
76
+ balance: {
77
+ currency: string
78
+ prepaidAvailable: number
79
+ dailyRemaining: number
80
+ effectiveAvailable: number
81
+ }
82
+ }
83
+
70
84
  export type Transaction = {
71
85
  id?: string
72
86
  owner?: string
@@ -231,28 +245,6 @@ export type CheckoutSessionResponse = {
231
245
  }
232
246
  }
233
247
 
234
- // ---------------------------------------------------------------------------
235
- // Card tokenization (S2S — no provider SDK needed on the frontend)
236
- // ---------------------------------------------------------------------------
237
-
238
- export type CardTokenizeRequest = {
239
- number: string
240
- expiryMonth: string // "01"–"12"
241
- expiryYear: string // "2025"–"2099"
242
- cvc: string
243
- name?: string
244
- zip?: string
245
- }
246
-
247
- export type CardTokenizeResult = {
248
- token: string
249
- brand: string
250
- last4: string
251
- expiryMonth: string
252
- expiryYear: string
253
- provider: string
254
- }
255
-
256
248
  // ---------------------------------------------------------------------------
257
249
  // Payment method types
258
250
  // ---------------------------------------------------------------------------
@@ -270,6 +262,17 @@ export type PaymentMethod = {
270
262
  expMonth: number
271
263
  expYear: number
272
264
  }
265
+ bank_account?: {
266
+ bankName?: string
267
+ last4?: string
268
+ accountType?: 'checking' | 'savings'
269
+ routingNumber?: string
270
+ }
271
+ crypto?: {
272
+ chain: string
273
+ address: string
274
+ label?: string
275
+ }
273
276
  providerRef?: string
274
277
  providerType?: string
275
278
  createdAt?: string
@@ -349,6 +352,8 @@ export class Commerce {
349
352
  body?: unknown
350
353
  token?: string
351
354
  params?: Record<string, string>
355
+ /** Extra request headers, e.g. X-IAM-Org-Id for S2S calls. */
356
+ headers?: Record<string, string>
352
357
  },
353
358
  ): Promise<T> {
354
359
  const url = new URL(path, this.baseUrl)
@@ -365,6 +370,7 @@ export class Commerce {
365
370
  const authToken = opts?.token ?? this.token
366
371
  if (authToken) headers['Authorization'] = `Bearer ${authToken}`
367
372
  if (opts?.body) headers['Content-Type'] = 'application/json'
373
+ if (opts?.headers) Object.assign(headers, opts.headers)
368
374
 
369
375
  try {
370
376
  const res = await fetch(url.toString(), {
@@ -389,9 +395,9 @@ export class Commerce {
389
395
  // Balance
390
396
  // -----------------------------------------------------------------------
391
397
 
392
- async getBalance(user: string, currency = 'usd', token?: string): Promise<Balance> {
398
+ async getBalance(user: string, currency = 'usd', token?: string, headers?: Record<string, string>): Promise<Balance> {
393
399
  return this.request<Balance>('/v1/billing/balance', {
394
- params: { user, currency }, token,
400
+ params: { user, currency }, token, headers,
395
401
  })
396
402
  }
397
403
 
@@ -401,13 +407,25 @@ export class Commerce {
401
407
  })
402
408
  }
403
409
 
410
+ /**
411
+ * Tier-aware balance: prepaid available plus the tenant's included plan
412
+ * allotment (effectiveAvailable). Use this for the metering gate when you
413
+ * want included usage (e.g. free-tier daily credit) honored before prepaid
414
+ * funds are drawn down.
415
+ */
416
+ async getTier(user: string, opts?: { token?: string; headers?: Record<string, string> }): Promise<TierResponse> {
417
+ return this.request<TierResponse>('/v1/billing/tier', {
418
+ params: { user }, token: opts?.token, headers: opts?.headers,
419
+ })
420
+ }
421
+
404
422
  // -----------------------------------------------------------------------
405
423
  // Usage
406
424
  // -----------------------------------------------------------------------
407
425
 
408
- async addUsageRecord(record: UsageRecord, token?: string): Promise<Transaction> {
426
+ async addUsageRecord(record: UsageRecord, token?: string, headers?: Record<string, string>): Promise<Transaction> {
409
427
  return this.request<Transaction>('/v1/billing/usage', {
410
- method: 'POST', body: record, token,
428
+ method: 'POST', body: record, token, headers,
411
429
  })
412
430
  }
413
431
 
@@ -511,31 +529,6 @@ export class Commerce {
511
529
  })
512
530
  }
513
531
 
514
- // -----------------------------------------------------------------------
515
- // Card tokenization (S2S — no external SDK required)
516
- // -----------------------------------------------------------------------
517
-
518
- /**
519
- * Tokenize a payment card server-side.
520
- * No external SDK (Square.js, Stripe.js, etc.) is needed on the frontend.
521
- * The card data is sent to the Hanzo Commerce API over HTTPS, which
522
- * tokenizes via the configured payment provider (Stripe).
523
- */
524
- async tokenizeCard(card: CardTokenizeRequest, token?: string): Promise<CardTokenizeResult> {
525
- return this.request<CardTokenizeResult>('/v1/billing/card/tokenize', {
526
- method: 'POST',
527
- body: {
528
- number: card.number.replace(/\s/g, ''),
529
- expiry_month: card.expiryMonth,
530
- expiry_year: card.expiryYear,
531
- cvc: card.cvc,
532
- name: card.name,
533
- zip: card.zip,
534
- },
535
- token,
536
- })
537
- }
538
-
539
532
  // -----------------------------------------------------------------------
540
533
  // Payment methods
541
534
  // -----------------------------------------------------------------------
@@ -544,25 +537,25 @@ export class Commerce {
544
537
  params: {
545
538
  customerId: string
546
539
  type: PaymentMethodType
547
- token?: string // from tokenizeCard
540
+ token?: string // provider nonce (Square Web Payments SDK)
548
541
  providerRef?: string
549
542
  providerType?: string
550
543
  },
551
544
  token?: string,
552
545
  ): Promise<PaymentMethod> {
553
- return this.request<PaymentMethod>('/v1/billing/payment-methods', {
546
+ return this.request<PaymentMethod>('/v1/billing/methods', {
554
547
  method: 'POST', body: params, token,
555
548
  })
556
549
  }
557
550
 
558
551
  async listPaymentMethods(customerId: string, token?: string): Promise<PaymentMethod[]> {
559
- return this.request<PaymentMethod[]>('/v1/billing/payment-methods', {
552
+ return this.request<PaymentMethod[]>('/v1/billing/methods', {
560
553
  params: { customerId }, token,
561
554
  })
562
555
  }
563
556
 
564
557
  async removePaymentMethod(paymentMethodId: string, token?: string): Promise<void> {
565
- await this.request<void>(`/v1/billing/payment-methods/${paymentMethodId}`, {
558
+ await this.request<void>(`/v1/billing/methods/${paymentMethodId}`, {
566
559
  method: 'DELETE', token,
567
560
  })
568
561
  }
@@ -687,6 +680,73 @@ export class Commerce {
687
680
  method: 'POST', body: params, token,
688
681
  })
689
682
  }
683
+
684
+ // -----------------------------------------------------------------------
685
+ // Crypto wallet deposit address
686
+ // -----------------------------------------------------------------------
687
+
688
+ /**
689
+ * Get or create a deposit address for a given chain.
690
+ * Used for crypto top-up — user sends funds to this address.
691
+ */
692
+ async getWalletAddress(params: { chain: string; userId: string }, token?: string): Promise<{ address: string; chain: string; qrCode?: string }> {
693
+ return this.request<{ address: string; chain: string; qrCode?: string }>('/api/wallet/account', {
694
+ method: 'POST',
695
+ body: { name: `${params.userId}-${params.chain}`, blockchainType: params.chain },
696
+ token,
697
+ })
698
+ }
699
+
700
+ // -----------------------------------------------------------------------
701
+ // Bank account (ACH) and crypto payment methods
702
+ // -----------------------------------------------------------------------
703
+
704
+ /**
705
+ * Add a bank account payment method (ACH).
706
+ * plaidToken from Plaid Link or Square bank OAuth.
707
+ */
708
+ async addBankAccount(
709
+ params: {
710
+ customerId: string
711
+ plaidToken?: string // Plaid public token
712
+ bankName?: string
713
+ accountType?: 'checking' | 'savings'
714
+ },
715
+ token?: string,
716
+ ): Promise<PaymentMethod> {
717
+ return this.request<PaymentMethod>('/v1/billing/methods', {
718
+ method: 'POST',
719
+ body: { customerId: params.customerId, type: 'bank_account', plaidToken: params.plaidToken, bankName: params.bankName, accountType: params.accountType },
720
+ token,
721
+ })
722
+ }
723
+
724
+ async addCryptoWallet(
725
+ params: { customerId: string; chain: string; address: string; label?: string },
726
+ token?: string,
727
+ ): Promise<PaymentMethod> {
728
+ return this.request<PaymentMethod>('/v1/billing/methods', {
729
+ method: 'POST',
730
+ body: { customerId: params.customerId, type: 'crypto', chain: params.chain, address: params.address, label: params.label },
731
+ token,
732
+ })
733
+ }
734
+
735
+ // -----------------------------------------------------------------------
736
+ // Top-up
737
+ // -----------------------------------------------------------------------
738
+
739
+ /**
740
+ * Convenience: charge a saved payment method and deposit credits.
741
+ * amount is in cents.
742
+ */
743
+ async topup(params: { userId: string; paymentMethodId: string; amountCents: number; currency?: string }, token?: string): Promise<Transaction> {
744
+ return this.request<Transaction>('/v1/billing/topup', {
745
+ method: 'POST',
746
+ body: params,
747
+ token,
748
+ })
749
+ }
690
750
  }
691
751
 
692
752
  // ---------------------------------------------------------------------------
@@ -148,6 +148,9 @@ const AddToCartWidget: React.FC<{
148
148
  </div>
149
149
  <Button
150
150
  aria-label={'Add another ' + item.title + ' to the cart'}
151
+ itemProp='potentialAction'
152
+ itemScope
153
+ itemType='https://schema.org/AddAction'
151
154
  size={ghost || priSmaller ? 'xs' : 'default'}
152
155
 
153
156
  variant={primary || priSmaller ? 'primary' : 'ghost'}
@@ -168,6 +171,9 @@ const AddToCartWidget: React.FC<{
168
171
  ) : (
169
172
  <Button
170
173
  aria-label={'Add a ' + item.title + ' to cart'}
174
+ itemProp='potentialAction'
175
+ itemScope
176
+ itemType='https://schema.org/AddAction'
171
177
  size={ghost || priSmaller ? 'xs' : 'default'}
172
178
  variant={ghost ? 'ghost' : (primary || priSmaller ? 'primary' : 'outline')}
173
179
  rounded={ROUNDED_VAL}
@@ -26,16 +26,33 @@ const ProductCard: React.FC<ProductCardProps> = ({
26
26
  ...props
27
27
  }) => (
28
28
  <Card
29
+ itemScope
30
+ itemType='https://schema.org/Product'
29
31
  className={cn('max-h-[360px] lg:min-w-[200px] max-w-[260px] overflow-hidden', className)}
30
32
  {...props}
31
33
  >
34
+ {/* Standard schema.org Product microdata. Neutral and analytics-agnostic:
35
+ track.js `annotate`, GA4 Merchant, or any reader picks up the item with
36
+ zero per-app config. Machine values live in <meta> so the visible,
37
+ formatted UI is untouched. */}
38
+ <meta itemProp='name' content={item.title} />
39
+ <meta itemProp='sku' content={item.sku} />
32
40
  <CardHeader className='w-full border-b p-6 min-h-[180px] max-h-[240px] relative'>
33
41
  <MediaStack media={item} constrainTo={{w: 700, h:700}} clx='p-6' />
34
42
  </CardHeader>
35
43
  <CardContent className='grid gap-2.5 p-4'>
36
44
  <CardTitle className='text-sm sm:text-base flex flex-col justify-start items-center line-clap-3'>
37
45
  {item.title.split(', ').map((e, i) => (<p key={i}>{e}</p>))}
38
- <p className='mt-1 font-semibold'>{formatCurrencyValue(item.price)}</p>
46
+ <p
47
+ className='mt-1 font-semibold'
48
+ itemProp='offers'
49
+ itemScope
50
+ itemType='https://schema.org/Offer'
51
+ >
52
+ <meta itemProp='price' content={String(item.price)} />
53
+ <meta itemProp='priceCurrency' content='USD' />
54
+ {formatCurrencyValue(item.price)}
55
+ </p>
39
56
  </CardTitle>
40
57
  </CardContent>
41
58
  <CardFooter className='p-4 flex flex-row justify-center'>
@@ -0,0 +1,2 @@
1
+ /** @hanzo/commerce/billing — re-exports from @hanzo/commerce/client */
2
+ export * from './client';
@@ -0,0 +1,3 @@
1
+ /** @hanzo/commerce/billing — re-exports from @hanzo/commerce/client */
2
+ export * from './client';
3
+ //# sourceMappingURL=billing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"billing.js","sourceRoot":"","sources":["../billing.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,cAAc,UAAU,CAAA"}