@hanzo/commerce 7.5.1 → 7.6.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.
- package/client.ts +455 -57
- package/components/checkout/payment-step-form/index.tsx +3 -16
- package/index.ts +25 -2
- package/package.json +9 -12
- package/.turbo/turbo-build.log +0 -5
- package/LICENSE.md +0 -21
- package/dist/billing.d.ts +0 -2
- package/dist/billing.js +0 -3
- package/dist/billing.js.map +0 -1
- package/dist/client.d.ts +0 -151
- package/dist/client.js +0 -188
- package/dist/client.js.map +0 -1
- package/dist/components/Icons.d.ts +0 -18
- package/dist/components/Icons.js +0 -19
- package/dist/components/Icons.js.map +0 -1
- package/dist/components/Icons.jsx +0 -19
- package/dist/components/Icons.jsx.map +0 -1
- package/dist/components/add-to-cart-widget.d.ts +0 -11
- package/dist/components/add-to-cart-widget.js +0 -85
- package/dist/components/add-to-cart-widget.js.map +0 -1
- package/dist/components/add-to-cart-widget.jsx +0 -99
- package/dist/components/add-to-cart-widget.jsx.map +0 -1
- package/dist/components/buy/buy-card.d.ts +0 -30
- package/dist/components/buy/buy-card.js +0 -109
- package/dist/components/buy/buy-card.js.map +0 -1
- package/dist/components/buy/buy-card.jsx +0 -123
- package/dist/components/buy/buy-card.jsx.map +0 -1
- package/dist/components/buy/carousel-buy-card.d.ts +0 -12
- package/dist/components/buy/carousel-buy-card.js +0 -94
- package/dist/components/buy/carousel-buy-card.js.map +0 -1
- package/dist/components/buy/carousel-buy-card.jsx +0 -99
- package/dist/components/buy/carousel-buy-card.jsx.map +0 -1
- package/dist/components/buy/multi-family/all-variants-carousel.d.ts +0 -4
- package/dist/components/buy/multi-family/all-variants-carousel.js +0 -115
- package/dist/components/buy/multi-family/all-variants-carousel.js.map +0 -1
- package/dist/components/buy/multi-family/all-variants-carousel.jsx +0 -147
- package/dist/components/buy/multi-family/all-variants-carousel.jsx.map +0 -1
- package/dist/components/buy/multi-family/family-carousel/index.d.ts +0 -4
- package/dist/components/buy/multi-family/family-carousel/index.js +0 -27
- package/dist/components/buy/multi-family/family-carousel/index.js.map +0 -1
- package/dist/components/buy/multi-family/family-carousel/index.jsx +0 -34
- package/dist/components/buy/multi-family/family-carousel/index.jsx.map +0 -1
- package/dist/components/buy/multi-family/family-carousel/slide.d.ts +0 -11
- package/dist/components/buy/multi-family/family-carousel/slide.js +0 -35
- package/dist/components/buy/multi-family/family-carousel/slide.js.map +0 -1
- package/dist/components/buy/multi-family/family-carousel/slide.jsx +0 -41
- package/dist/components/buy/multi-family/family-carousel/slide.jsx.map +0 -1
- package/dist/components/buy/multi-family/family-carousel/state.d.ts +0 -20
- package/dist/components/buy/multi-family/family-carousel/state.js +0 -59
- package/dist/components/buy/multi-family/family-carousel/state.js.map +0 -1
- package/dist/components/buy/multi-family/index.d.ts +0 -2
- package/dist/components/buy/multi-family/index.js +0 -3
- package/dist/components/buy/multi-family/index.js.map +0 -1
- package/dist/components/buy/single-family-selector.d.ts +0 -15
- package/dist/components/buy/single-family-selector.js +0 -28
- package/dist/components/buy/single-family-selector.js.map +0 -1
- package/dist/components/buy/single-family-selector.jsx +0 -31
- package/dist/components/buy/single-family-selector.jsx.map +0 -1
- package/dist/components/buy/title-and-byline.d.ts +0 -8
- package/dist/components/buy/title-and-byline.js +0 -7
- package/dist/components/buy/title-and-byline.js.map +0 -1
- package/dist/components/buy/title-and-byline.jsx +0 -9
- package/dist/components/buy/title-and-byline.jsx.map +0 -1
- package/dist/components/cart/cart-panel/cart-line-item.d.ts +0 -11
- package/dist/components/cart/cart-panel/cart-line-item.js +0 -25
- package/dist/components/cart/cart-panel/cart-line-item.js.map +0 -1
- package/dist/components/cart/cart-panel/cart-line-item.jsx +0 -39
- package/dist/components/cart/cart-panel/cart-line-item.jsx.map +0 -1
- package/dist/components/cart/cart-panel/index.d.ts +0 -19
- package/dist/components/cart/cart-panel/index.js +0 -65
- package/dist/components/cart/cart-panel/index.js.map +0 -1
- package/dist/components/cart/cart-panel/index.jsx +0 -79
- package/dist/components/cart/cart-panel/index.jsx.map +0 -1
- package/dist/components/cart/cart-panel/promo-code.d.ts +0 -4
- package/dist/components/cart/cart-panel/promo-code.js +0 -62
- package/dist/components/cart/cart-panel/promo-code.js.map +0 -1
- package/dist/components/cart/cart-panel/promo-code.jsx +0 -74
- package/dist/components/cart/cart-panel/promo-code.jsx.map +0 -1
- package/dist/components/cart/cart-panel/total-area.d.ts +0 -7
- package/dist/components/cart/cart-panel/total-area.js +0 -14
- package/dist/components/cart/cart-panel/total-area.js.map +0 -1
- package/dist/components/cart/cart-panel/total-area.jsx +0 -37
- package/dist/components/cart/cart-panel/total-area.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icon-row.d.ts +0 -2
- package/dist/components/checkout/payment-step-form/card-icon-row.js +0 -14
- package/dist/components/checkout/payment-step-form/card-icon-row.js.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icon-row.jsx +0 -22
- package/dist/components/checkout/payment-step-form/card-icon-row.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/amex.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/card-icons/amex.js +0 -6
- package/dist/components/checkout/payment-step-form/card-icons/amex.js.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/amex.jsx +0 -12
- package/dist/components/checkout/payment-step-form/card-icons/amex.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/diners-club.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/card-icons/diners-club.js +0 -6
- package/dist/components/checkout/payment-step-form/card-icons/diners-club.js.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/diners-club.jsx +0 -10
- package/dist/components/checkout/payment-step-form/card-icons/diners-club.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/discover.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/card-icons/discover.js +0 -6
- package/dist/components/checkout/payment-step-form/card-icons/discover.js.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/discover.jsx +0 -12
- package/dist/components/checkout/payment-step-form/card-icons/discover.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/jcb.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/card-icons/jcb.js +0 -6
- package/dist/components/checkout/payment-step-form/card-icons/jcb.js.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/jcb.jsx +0 -23
- package/dist/components/checkout/payment-step-form/card-icons/jcb.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/mastercard.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/card-icons/mastercard.js +0 -6
- package/dist/components/checkout/payment-step-form/card-icons/mastercard.js.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/mastercard.jsx +0 -12
- package/dist/components/checkout/payment-step-form/card-icons/mastercard.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/visa.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/card-icons/visa.js +0 -6
- package/dist/components/checkout/payment-step-form/card-icons/visa.js.map +0 -1
- package/dist/components/checkout/payment-step-form/card-icons/visa.jsx +0 -10
- package/dist/components/checkout/payment-step-form/card-icons/visa.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/cc-button.d.ts +0 -3
- package/dist/components/checkout/payment-step-form/cc-button.js +0 -6
- package/dist/components/checkout/payment-step-form/cc-button.js.map +0 -1
- package/dist/components/checkout/payment-step-form/cc-button.jsx +0 -9
- package/dist/components/checkout/payment-step-form/cc-button.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/contact-form.d.ts +0 -5
- package/dist/components/checkout/payment-step-form/contact-form.js +0 -6
- package/dist/components/checkout/payment-step-form/contact-form.js.map +0 -1
- package/dist/components/checkout/payment-step-form/contact-form.jsx +0 -21
- package/dist/components/checkout/payment-step-form/contact-form.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/crypto-icons/btc.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/crypto-icons/btc.js +0 -6
- package/dist/components/checkout/payment-step-form/crypto-icons/btc.js.map +0 -1
- package/dist/components/checkout/payment-step-form/crypto-icons/btc.jsx +0 -8
- package/dist/components/checkout/payment-step-form/crypto-icons/btc.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/crypto-icons/eth.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/crypto-icons/eth.js +0 -6
- package/dist/components/checkout/payment-step-form/crypto-icons/eth.js.map +0 -1
- package/dist/components/checkout/payment-step-form/crypto-icons/eth.jsx +0 -17
- package/dist/components/checkout/payment-step-form/crypto-icons/eth.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/crypto-icons/usdt.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/crypto-icons/usdt.js +0 -6
- package/dist/components/checkout/payment-step-form/crypto-icons/usdt.js.map +0 -1
- package/dist/components/checkout/payment-step-form/crypto-icons/usdt.jsx +0 -10
- package/dist/components/checkout/payment-step-form/crypto-icons/usdt.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/index.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/index.js +0 -77
- package/dist/components/checkout/payment-step-form/index.js.map +0 -1
- package/dist/components/checkout/payment-step-form/index.jsx +0 -86
- package/dist/components/checkout/payment-step-form/index.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/methods/bank-transfer.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/methods/bank-transfer.js +0 -24
- package/dist/components/checkout/payment-step-form/methods/bank-transfer.js.map +0 -1
- package/dist/components/checkout/payment-step-form/methods/bank-transfer.jsx +0 -44
- package/dist/components/checkout/payment-step-form/methods/bank-transfer.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/methods/card.d.ts +0 -4
- package/dist/components/checkout/payment-step-form/methods/card.js +0 -160
- package/dist/components/checkout/payment-step-form/methods/card.js.map +0 -1
- package/dist/components/checkout/payment-step-form/methods/card.jsx +0 -182
- package/dist/components/checkout/payment-step-form/methods/card.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/methods/crypto.d.ts +0 -9
- package/dist/components/checkout/payment-step-form/methods/crypto.js +0 -137
- package/dist/components/checkout/payment-step-form/methods/crypto.js.map +0 -1
- package/dist/components/checkout/payment-step-form/methods/crypto.jsx +0 -167
- package/dist/components/checkout/payment-step-form/methods/crypto.jsx.map +0 -1
- package/dist/components/checkout/payment-step-form/methods/index.d.ts +0 -6
- package/dist/components/checkout/payment-step-form/methods/index.js +0 -21
- package/dist/components/checkout/payment-step-form/methods/index.js.map +0 -1
- package/dist/components/checkout/shipping-step-form.d.ts +0 -3
- package/dist/components/checkout/shipping-step-form.js +0 -53
- package/dist/components/checkout/shipping-step-form.js.map +0 -1
- package/dist/components/checkout/shipping-step-form.jsx +0 -106
- package/dist/components/checkout/shipping-step-form.jsx.map +0 -1
- package/dist/components/index.d.ts +0 -8
- package/dist/components/index.js +0 -9
- package/dist/components/index.js.map +0 -1
- package/dist/components/item/product-card.d.ts +0 -7
- package/dist/components/item/product-card.js +0 -9
- package/dist/components/item/product-card.js.map +0 -1
- package/dist/components/item/product-card.jsx +0 -21
- package/dist/components/item/product-card.jsx.map +0 -1
- package/dist/components/item-selector/button.d.ts +0 -4
- package/dist/components/item-selector/button.js +0 -47
- package/dist/components/item-selector/button.js.map +0 -1
- package/dist/components/item-selector/button.jsx +0 -65
- package/dist/components/item-selector/button.jsx.map +0 -1
- package/dist/components/item-selector/carousel/index.d.ts +0 -12
- package/dist/components/item-selector/carousel/index.js +0 -74
- package/dist/components/item-selector/carousel/index.js.map +0 -1
- package/dist/components/item-selector/carousel/index.jsx +0 -101
- package/dist/components/item-selector/carousel/index.jsx.map +0 -1
- package/dist/components/item-selector/carousel/slider.d.ts +0 -8
- package/dist/components/item-selector/carousel/slider.js +0 -12
- package/dist/components/item-selector/carousel/slider.js.map +0 -1
- package/dist/components/item-selector/carousel/slider.jsx +0 -11
- package/dist/components/item-selector/carousel/slider.jsx.map +0 -1
- package/dist/components/item-selector/index.d.ts +0 -2
- package/dist/components/item-selector/index.js +0 -3
- package/dist/components/item-selector/index.js.map +0 -1
- package/dist/components/item-selector/quantity-indicator.d.ts +0 -9
- package/dist/components/item-selector/quantity-indicator.js +0 -16
- package/dist/components/item-selector/quantity-indicator.js.map +0 -1
- package/dist/components/item-selector/quantity-indicator.jsx +0 -23
- package/dist/components/item-selector/quantity-indicator.jsx.map +0 -1
- package/dist/components/node-tabs/index.d.ts +0 -14
- package/dist/components/node-tabs/index.js +0 -42
- package/dist/components/node-tabs/index.js.map +0 -1
- package/dist/components/node-tabs/index.jsx +0 -48
- package/dist/components/node-tabs/index.jsx.map +0 -1
- package/dist/components/node-tabs/node-image.d.ts +0 -6
- package/dist/components/node-tabs/node-image.js +0 -13
- package/dist/components/node-tabs/node-image.js.map +0 -1
- package/dist/components/node-tabs/node-image.jsx +0 -12
- package/dist/components/node-tabs/node-image.jsx.map +0 -1
- package/dist/index.d.ts +0 -7
- package/dist/index.js +0 -7
- package/dist/index.js.map +0 -1
- package/dist/service/context.d.ts +0 -8
- package/dist/service/context.js +0 -19
- package/dist/service/context.js.map +0 -1
- package/dist/service/context.jsx +0 -20
- package/dist/service/context.jsx.map +0 -1
- package/dist/service/debug.d.ts +0 -10
- package/dist/service/debug.js +0 -30
- package/dist/service/debug.js.map +0 -1
- package/dist/service/impls/standalone/actual-line-item.d.ts +0 -40
- package/dist/service/impls/standalone/actual-line-item.js +0 -84
- package/dist/service/impls/standalone/actual-line-item.js.map +0 -1
- package/dist/service/impls/standalone/get-instance.d.ts +0 -2
- package/dist/service/impls/standalone/get-instance.js +0 -39
- package/dist/service/impls/standalone/get-instance.js.map +0 -1
- package/dist/service/impls/standalone/index.d.ts +0 -67
- package/dist/service/impls/standalone/index.js +0 -416
- package/dist/service/impls/standalone/index.js.map +0 -1
- package/dist/service/impls/standalone/order/firebase.d.ts +0 -6
- package/dist/service/impls/standalone/order/firebase.js +0 -6
- package/dist/service/impls/standalone/order/firebase.js.map +0 -1
- package/dist/service/impls/standalone/order/index.d.ts +0 -30
- package/dist/service/impls/standalone/order/index.js +0 -21
- package/dist/service/impls/standalone/order/index.js.map +0 -1
- package/dist/service/impls/standalone/persistence.d.ts +0 -4
- package/dist/service/impls/standalone/persistence.js +0 -22
- package/dist/service/impls/standalone/persistence.js.map +0 -1
- package/dist/service/path-utils.d.ts +0 -7
- package/dist/service/path-utils.js +0 -16
- package/dist/service/path-utils.js.map +0 -1
- package/dist/service/sep.d.ts +0 -6
- package/dist/service/sep.js +0 -6
- package/dist/service/sep.js.map +0 -1
- package/dist/types/category-node.d.ts +0 -36
- package/dist/types/category-node.js +0 -2
- package/dist/types/category-node.js.map +0 -1
- package/dist/types/checkout.d.ts +0 -33
- package/dist/types/checkout.js +0 -2
- package/dist/types/checkout.js.map +0 -1
- package/dist/types/commerce-config.d.ts +0 -11
- package/dist/types/commerce-config.js +0 -2
- package/dist/types/commerce-config.js.map +0 -1
- package/dist/types/commerce-service.d.ts +0 -109
- package/dist/types/commerce-service.js +0 -2
- package/dist/types/commerce-service.js.map +0 -1
- package/dist/types/family.d.ts +0 -16
- package/dist/types/family.js +0 -2
- package/dist/types/family.js.map +0 -1
- package/dist/types/index.d.ts +0 -13
- package/dist/types/index.js +0 -8
- package/dist/types/index.js.map +0 -1
- package/dist/types/item-selector.d.ts +0 -72
- package/dist/types/item-selector.js +0 -2
- package/dist/types/item-selector.js.map +0 -1
- package/dist/types/line-item.d.ts +0 -14
- package/dist/types/line-item.js +0 -2
- package/dist/types/line-item.js.map +0 -1
- package/dist/types/multi-family-selector-props.d.ts +0 -16
- package/dist/types/multi-family-selector-props.js +0 -2
- package/dist/types/multi-family-selector-props.js.map +0 -1
- package/dist/types/product.d.ts +0 -15
- package/dist/types/product.js +0 -2
- package/dist/types/product.js.map +0 -1
- package/dist/types/promo.d.ts +0 -7
- package/dist/types/promo.js +0 -2
- package/dist/types/promo.js.map +0 -1
- package/dist/types/selection-ui-specifier.d.ts +0 -40
- package/dist/types/selection-ui-specifier.js +0 -2
- package/dist/types/selection-ui-specifier.js.map +0 -1
- package/dist/types/string-mutator.d.ts +0 -9
- package/dist/types/string-mutator.js +0 -2
- package/dist/types/string-mutator.js.map +0 -1
- package/dist/types/token-separators.d.ts +0 -6
- package/dist/types/token-separators.js +0 -2
- package/dist/types/token-separators.js.map +0 -1
- package/dist/util/analytics.d.ts +0 -9
- package/dist/util/analytics.js +0 -10
- package/dist/util/analytics.js.map +0 -1
- package/dist/util/countries.d.ts +0 -7
- package/dist/util/countries.js +0 -197
- package/dist/util/countries.js.map +0 -1
- package/dist/util/error.d.ts +0 -1
- package/dist/util/error.js +0 -22
- package/dist/util/error.js.map +0 -1
- package/dist/util/index.d.ts +0 -15
- package/dist/util/index.js +0 -54
- package/dist/util/index.js.map +0 -1
- package/dist/util/item-selector-options-accessor.d.ts +0 -3
- package/dist/util/item-selector-options-accessor.js +0 -27
- package/dist/util/item-selector-options-accessor.js.map +0 -1
- package/dist/util/line-item-ref.d.ts +0 -8
- package/dist/util/line-item-ref.js +0 -15
- package/dist/util/line-item-ref.js.map +0 -1
- package/dist/util/multi-family-selector-options-accessor.d.ts +0 -3
- package/dist/util/multi-family-selector-options-accessor.js +0 -11
- package/dist/util/multi-family-selector-options-accessor.js.map +0 -1
- package/dist/util/obs-string-mutator.d.ts +0 -8
- package/dist/util/obs-string-mutator.js +0 -15
- package/dist/util/obs-string-mutator.js.map +0 -1
- package/dist/util/product-media-accessor.d.ts +0 -29
- package/dist/util/product-media-accessor.js +0 -22
- package/dist/util/product-media-accessor.js.map +0 -1
- package/dist/util/promo-codes.d.ts +0 -3
- package/dist/util/promo-codes.js +0 -100
- package/dist/util/promo-codes.js.map +0 -1
- package/dist/util/selection-ui-specifiers.d.ts +0 -3
- package/dist/util/selection-ui-specifiers.js +0 -24
- package/dist/util/selection-ui-specifiers.js.map +0 -1
- package/dist/util/square-payment.d.ts +0 -7
- package/dist/util/square-payment.js +0 -37
- package/dist/util/square-payment.js.map +0 -1
- package/dist/util/use-sync-sku-param-w-current-item.d.ts +0 -2
- package/dist/util/use-sync-sku-param-w-current-item.js +0 -61
- package/dist/util/use-sync-sku-param-w-current-item.js.map +0 -1
package/client.ts
CHANGED
|
@@ -1,29 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @hanzo/commerce/client
|
|
3
3
|
*
|
|
4
|
-
* TypeScript client for the Hanzo Commerce API.
|
|
5
|
-
*
|
|
4
|
+
* Universal TypeScript client for the Hanzo Commerce API.
|
|
5
|
+
* Works in browser, Node.js, and edge runtimes — no backend required.
|
|
6
|
+
* Covers billing, subscriptions, payments, checkout, coupons,
|
|
7
|
+
* referrals, affiliates, usage, and plans.
|
|
6
8
|
*
|
|
7
9
|
* @example
|
|
8
10
|
* ```ts
|
|
9
|
-
* import { Commerce } from '@hanzo/commerce'
|
|
11
|
+
* import { Commerce } from '@hanzo/commerce/client'
|
|
10
12
|
*
|
|
11
|
-
* const commerce = new Commerce({
|
|
12
|
-
* commerceUrl: 'https://commerce.hanzo.ai',
|
|
13
|
-
* token: iamAccessToken,
|
|
14
|
-
* })
|
|
13
|
+
* const commerce = new Commerce({ baseUrl: 'https://api.hanzo.ai', token: iamToken })
|
|
15
14
|
*
|
|
16
|
-
* //
|
|
17
|
-
* const
|
|
15
|
+
* // Validate a coupon before checkout
|
|
16
|
+
* const coupon = await commerce.validateCoupon('LAUNCH50')
|
|
18
17
|
*
|
|
19
|
-
* //
|
|
20
|
-
* await commerce.
|
|
18
|
+
* // Create a checkout session
|
|
19
|
+
* const session = await commerce.createCheckoutSession({
|
|
20
|
+
* items: [{ id: 'plan_pro', quantity: 1 }],
|
|
21
|
+
* couponCode: 'LAUNCH50',
|
|
22
|
+
* referrerId: 'ref_abc123',
|
|
23
|
+
* successUrl: 'https://app.example.com/success',
|
|
24
|
+
* cancelUrl: 'https://app.example.com/cancel',
|
|
25
|
+
* })
|
|
26
|
+
* window.location.href = session.checkoutUrl
|
|
21
27
|
*
|
|
22
|
-
* //
|
|
23
|
-
* await commerce.
|
|
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
|
+
* })
|
|
24
36
|
*
|
|
25
|
-
* //
|
|
26
|
-
* await commerce.
|
|
37
|
+
* // Subscribe
|
|
38
|
+
* const sub = await commerce.subscribe({ planId: 'pro', userId: 'user_xyz' })
|
|
27
39
|
* ```
|
|
28
40
|
*/
|
|
29
41
|
|
|
@@ -32,15 +44,21 @@
|
|
|
32
44
|
// ---------------------------------------------------------------------------
|
|
33
45
|
|
|
34
46
|
export type CommerceClientConfig = {
|
|
35
|
-
/**
|
|
36
|
-
|
|
37
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Commerce API base URL.
|
|
49
|
+
* Defaults to https://api.hanzo.ai
|
|
50
|
+
*/
|
|
51
|
+
baseUrl?: string
|
|
52
|
+
/** @deprecated use baseUrl */
|
|
53
|
+
commerceUrl?: string
|
|
54
|
+
/** IAM access token for authenticated requests. */
|
|
38
55
|
token?: string
|
|
56
|
+
/** Request timeout in milliseconds. Default 15 000. */
|
|
57
|
+
timeoutMs?: number
|
|
39
58
|
}
|
|
40
59
|
|
|
41
|
-
|
|
42
60
|
// ---------------------------------------------------------------------------
|
|
43
|
-
//
|
|
61
|
+
// Core types
|
|
44
62
|
// ---------------------------------------------------------------------------
|
|
45
63
|
|
|
46
64
|
export type Balance = {
|
|
@@ -69,6 +87,7 @@ export type Subscription = {
|
|
|
69
87
|
id?: string
|
|
70
88
|
planId?: string
|
|
71
89
|
userId?: string
|
|
90
|
+
customerId?: string
|
|
72
91
|
status?: 'trialing' | 'active' | 'past_due' | 'canceled' | 'unpaid' | string
|
|
73
92
|
billingType?: 'charge_automatically' | 'send_invoice'
|
|
74
93
|
periodStart?: string
|
|
@@ -77,17 +96,25 @@ export type Subscription = {
|
|
|
77
96
|
trialEnd?: string
|
|
78
97
|
quantity?: number
|
|
79
98
|
createdAt?: string
|
|
99
|
+
cancelAtPeriodEnd?: boolean
|
|
100
|
+
currentPeriodEnd?: string
|
|
80
101
|
}
|
|
81
102
|
|
|
82
103
|
export type Plan = {
|
|
104
|
+
id?: string
|
|
83
105
|
slug?: string
|
|
84
106
|
name?: string
|
|
85
107
|
description?: string
|
|
86
108
|
price?: number
|
|
109
|
+
priceMonthly?: number
|
|
110
|
+
priceAnnual?: number
|
|
87
111
|
currency?: string
|
|
88
112
|
interval?: 'monthly' | 'yearly' | string
|
|
89
113
|
intervalCount?: number
|
|
90
114
|
trialPeriodDays?: number
|
|
115
|
+
features?: string[]
|
|
116
|
+
popular?: boolean
|
|
117
|
+
contactSales?: boolean
|
|
91
118
|
metadata?: Record<string, unknown>
|
|
92
119
|
}
|
|
93
120
|
|
|
@@ -116,23 +143,202 @@ export type UsageRecord = {
|
|
|
116
143
|
completionTokens?: number
|
|
117
144
|
}
|
|
118
145
|
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Coupon / Discount types
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
|
|
150
|
+
export type CouponType = 'Percent' | 'Flat' | 'FreeShipping' | 'FreeItem'
|
|
151
|
+
|
|
152
|
+
export type Coupon = {
|
|
153
|
+
id?: string
|
|
154
|
+
code: string
|
|
155
|
+
type: CouponType
|
|
156
|
+
/** Amount: percentage (0-100) for Percent, cents for Flat */
|
|
157
|
+
amount: number
|
|
158
|
+
description?: string
|
|
159
|
+
limit?: number
|
|
160
|
+
used?: number
|
|
161
|
+
startDate?: string
|
|
162
|
+
endDate?: string
|
|
163
|
+
enabled?: boolean
|
|
164
|
+
/** Calculated discount in cents (returned by validateCoupon) */
|
|
165
|
+
discountCents?: number
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export type CouponValidateResult = {
|
|
169
|
+
valid: boolean
|
|
170
|
+
coupon?: Coupon
|
|
171
|
+
error?: string
|
|
172
|
+
/** Discount in cents for a given subtotal */
|
|
173
|
+
discountCents?: number
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export type Discount = {
|
|
177
|
+
id?: string
|
|
178
|
+
type: 'Percent' | 'Flat' | 'FreeShipping' | 'FreeItem' | 'Bulk'
|
|
179
|
+
amount: number
|
|
180
|
+
scope?: 'Product' | 'Variant' | 'Collection' | 'Store'
|
|
181
|
+
enabled?: boolean
|
|
182
|
+
startDate?: string
|
|
183
|
+
endDate?: string
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ---------------------------------------------------------------------------
|
|
187
|
+
// Checkout types
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
|
|
190
|
+
export type CheckoutItem = {
|
|
191
|
+
id: string
|
|
192
|
+
quantity?: number
|
|
193
|
+
/** Price override in cents */
|
|
194
|
+
price?: number
|
|
195
|
+
name?: string
|
|
196
|
+
description?: string
|
|
197
|
+
imageUrl?: string
|
|
198
|
+
metadata?: Record<string, unknown>
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
export type CheckoutSessionRequest = {
|
|
202
|
+
items: CheckoutItem[]
|
|
203
|
+
successUrl: string
|
|
204
|
+
cancelUrl: string
|
|
205
|
+
couponCode?: string
|
|
206
|
+
referrerId?: string
|
|
207
|
+
affiliateId?: string
|
|
208
|
+
currency?: string
|
|
209
|
+
customer?: {
|
|
210
|
+
email?: string
|
|
211
|
+
name?: string
|
|
212
|
+
address?: string
|
|
213
|
+
city?: string
|
|
214
|
+
zip?: string
|
|
215
|
+
}
|
|
216
|
+
metadata?: Record<string, unknown>
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export type CheckoutSessionResponse = {
|
|
220
|
+
checkoutUrl: string
|
|
221
|
+
sessionId: string
|
|
222
|
+
/** Original total in cents before discount */
|
|
223
|
+
originalTotal?: number
|
|
224
|
+
/** Final total in cents after discount */
|
|
225
|
+
finalTotal?: number
|
|
226
|
+
discount?: {
|
|
227
|
+
code: string
|
|
228
|
+
type: CouponType
|
|
229
|
+
amount: number
|
|
230
|
+
discountCents: number
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
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
|
+
// ---------------------------------------------------------------------------
|
|
257
|
+
// Payment method types
|
|
258
|
+
// ---------------------------------------------------------------------------
|
|
259
|
+
|
|
260
|
+
export type PaymentMethodType = 'card' | 'bank_account' | 'balance' | 'crypto' | 'wire'
|
|
261
|
+
|
|
262
|
+
export type PaymentMethod = {
|
|
263
|
+
id: string
|
|
264
|
+
type: PaymentMethodType
|
|
265
|
+
isDefault?: boolean
|
|
266
|
+
customerId?: string
|
|
267
|
+
card?: {
|
|
268
|
+
brand: string
|
|
269
|
+
last4: string
|
|
270
|
+
expMonth: number
|
|
271
|
+
expYear: number
|
|
272
|
+
}
|
|
273
|
+
providerRef?: string
|
|
274
|
+
providerType?: string
|
|
275
|
+
createdAt?: string
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// ---------------------------------------------------------------------------
|
|
279
|
+
// Referral / Affiliate types
|
|
280
|
+
// ---------------------------------------------------------------------------
|
|
281
|
+
|
|
282
|
+
export type Referral = {
|
|
283
|
+
id?: string
|
|
284
|
+
userId?: string
|
|
285
|
+
referrerId?: string
|
|
286
|
+
affiliateId?: string
|
|
287
|
+
orderId?: string
|
|
288
|
+
fee?: number
|
|
289
|
+
createdAt?: string
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export type Referrer = {
|
|
293
|
+
id?: string
|
|
294
|
+
userId?: string
|
|
295
|
+
enabled?: boolean
|
|
296
|
+
code?: string
|
|
297
|
+
referrals?: Referral[]
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export type Affiliate = {
|
|
301
|
+
id?: string
|
|
302
|
+
userId?: string
|
|
303
|
+
enabled?: boolean
|
|
304
|
+
commission?: number
|
|
305
|
+
couponId?: string
|
|
306
|
+
connectUrl?: string
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
// ---------------------------------------------------------------------------
|
|
310
|
+
// Credit grant
|
|
311
|
+
// ---------------------------------------------------------------------------
|
|
312
|
+
|
|
313
|
+
export type CreditGrant = {
|
|
314
|
+
id?: string
|
|
315
|
+
userId?: string
|
|
316
|
+
amount: number
|
|
317
|
+
currency: string
|
|
318
|
+
expiresAt?: string
|
|
319
|
+
tags?: string[]
|
|
320
|
+
}
|
|
321
|
+
|
|
119
322
|
// ---------------------------------------------------------------------------
|
|
120
323
|
// Client
|
|
121
324
|
// ---------------------------------------------------------------------------
|
|
122
325
|
|
|
123
|
-
const
|
|
326
|
+
const DEFAULT_BASE_URL = 'https://api.hanzo.ai'
|
|
327
|
+
const DEFAULT_TIMEOUT_MS = 15_000
|
|
124
328
|
|
|
125
329
|
export class Commerce {
|
|
126
330
|
private readonly baseUrl: string
|
|
127
331
|
private token: string | undefined
|
|
332
|
+
private readonly timeoutMs: number
|
|
128
333
|
|
|
129
|
-
constructor(config: CommerceClientConfig) {
|
|
130
|
-
this.baseUrl = config.commerceUrl.replace(/\/+$/, '')
|
|
334
|
+
constructor(config: CommerceClientConfig = {}) {
|
|
335
|
+
this.baseUrl = (config.baseUrl ?? config.commerceUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, '')
|
|
131
336
|
this.token = config.token
|
|
337
|
+
this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS
|
|
132
338
|
}
|
|
133
339
|
|
|
134
340
|
/** Update the auth token (e.g. after IAM token refresh). */
|
|
135
|
-
setToken(token: string) {
|
|
341
|
+
setToken(token: string): void {
|
|
136
342
|
this.token = token
|
|
137
343
|
}
|
|
138
344
|
|
|
@@ -153,11 +359,11 @@ export class Commerce {
|
|
|
153
359
|
}
|
|
154
360
|
|
|
155
361
|
const controller = new AbortController()
|
|
156
|
-
const timer = setTimeout(() => controller.abort(),
|
|
362
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs)
|
|
157
363
|
|
|
158
364
|
const headers: Record<string, string> = { Accept: 'application/json' }
|
|
159
365
|
const authToken = opts?.token ?? this.token
|
|
160
|
-
if (authToken) headers
|
|
366
|
+
if (authToken) headers['Authorization'] = `Bearer ${authToken}`
|
|
161
367
|
if (opts?.body) headers['Content-Type'] = 'application/json'
|
|
162
368
|
|
|
163
369
|
try {
|
|
@@ -230,36 +436,231 @@ export class Commerce {
|
|
|
230
436
|
})
|
|
231
437
|
}
|
|
232
438
|
|
|
439
|
+
// -----------------------------------------------------------------------
|
|
440
|
+
// Plans
|
|
441
|
+
// -----------------------------------------------------------------------
|
|
442
|
+
|
|
443
|
+
async getPlans(token?: string): Promise<Plan[]> {
|
|
444
|
+
return this.request<Plan[]>('/api/v1/billing/plans', { token })
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
async getPlan(planId: string, token?: string): Promise<Plan | null> {
|
|
448
|
+
try {
|
|
449
|
+
return await this.request<Plan>(`/api/v1/billing/plans/${planId}`, { token })
|
|
450
|
+
} catch { return null }
|
|
451
|
+
}
|
|
452
|
+
|
|
233
453
|
// -----------------------------------------------------------------------
|
|
234
454
|
// Subscriptions
|
|
235
455
|
// -----------------------------------------------------------------------
|
|
236
456
|
|
|
237
|
-
async subscribe(
|
|
238
|
-
|
|
457
|
+
async subscribe(
|
|
458
|
+
params: { planId: string; userId?: string; customerId?: string; paymentMethodId?: string; couponCode?: string; trialDays?: number },
|
|
459
|
+
token?: string,
|
|
460
|
+
): Promise<Subscription> {
|
|
461
|
+
return this.request<Subscription>('/api/v1/billing/subscriptions', {
|
|
239
462
|
method: 'POST', body: params, token,
|
|
240
463
|
})
|
|
241
464
|
}
|
|
242
465
|
|
|
243
466
|
async getSubscription(subscriptionId: string, token?: string): Promise<Subscription | null> {
|
|
244
467
|
try {
|
|
245
|
-
return await this.request<Subscription>(`/api/v1/
|
|
468
|
+
return await this.request<Subscription>(`/api/v1/billing/subscriptions/${subscriptionId}`, { token })
|
|
246
469
|
} catch { return null }
|
|
247
470
|
}
|
|
248
471
|
|
|
472
|
+
async listSubscriptions(params?: { customerId?: string }, token?: string): Promise<Subscription[]> {
|
|
473
|
+
return this.request<Subscription[]>('/api/v1/billing/subscriptions', {
|
|
474
|
+
params: params as Record<string, string> | undefined, token,
|
|
475
|
+
})
|
|
476
|
+
}
|
|
477
|
+
|
|
249
478
|
async updateSubscription(subscriptionId: string, update: Partial<Subscription>, token?: string): Promise<Subscription> {
|
|
250
|
-
return this.request<Subscription>(`/api/v1/
|
|
479
|
+
return this.request<Subscription>(`/api/v1/billing/subscriptions/${subscriptionId}`, {
|
|
251
480
|
method: 'PATCH', body: update, token,
|
|
252
481
|
})
|
|
253
482
|
}
|
|
254
483
|
|
|
255
|
-
async cancelSubscription(subscriptionId: string, token?: string): Promise<
|
|
256
|
-
|
|
484
|
+
async cancelSubscription(subscriptionId: string, immediately = false, token?: string): Promise<Subscription> {
|
|
485
|
+
return this.request<Subscription>(`/api/v1/billing/subscriptions/${subscriptionId}/cancel`, {
|
|
486
|
+
method: 'POST', body: { immediately }, token,
|
|
487
|
+
})
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
async reactivateSubscription(subscriptionId: string, token?: string): Promise<Subscription> {
|
|
491
|
+
return this.request<Subscription>(`/api/v1/billing/subscriptions/${subscriptionId}/reactivate`, {
|
|
492
|
+
method: 'POST', token,
|
|
493
|
+
})
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// -----------------------------------------------------------------------
|
|
497
|
+
// Checkout sessions
|
|
498
|
+
// -----------------------------------------------------------------------
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Create a hosted checkout session.
|
|
502
|
+
* Returns a URL to redirect the customer to for payment.
|
|
503
|
+
* Supports coupons, referral tracking, and multiple currencies.
|
|
504
|
+
*/
|
|
505
|
+
async createCheckoutSession(
|
|
506
|
+
params: CheckoutSessionRequest,
|
|
507
|
+
token?: string,
|
|
508
|
+
): Promise<CheckoutSessionResponse> {
|
|
509
|
+
return this.request<CheckoutSessionResponse>('/api/v1/checkout/sessions', {
|
|
510
|
+
method: 'POST', body: params, token,
|
|
511
|
+
})
|
|
512
|
+
}
|
|
513
|
+
|
|
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>('/api/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
|
+
// -----------------------------------------------------------------------
|
|
540
|
+
// Payment methods
|
|
541
|
+
// -----------------------------------------------------------------------
|
|
542
|
+
|
|
543
|
+
async addPaymentMethod(
|
|
544
|
+
params: {
|
|
545
|
+
customerId: string
|
|
546
|
+
type: PaymentMethodType
|
|
547
|
+
token?: string // from tokenizeCard
|
|
548
|
+
providerRef?: string
|
|
549
|
+
providerType?: string
|
|
550
|
+
},
|
|
551
|
+
token?: string,
|
|
552
|
+
): Promise<PaymentMethod> {
|
|
553
|
+
return this.request<PaymentMethod>('/api/v1/billing/payment-methods', {
|
|
554
|
+
method: 'POST', body: params, token,
|
|
555
|
+
})
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
async listPaymentMethods(customerId: string, token?: string): Promise<PaymentMethod[]> {
|
|
559
|
+
return this.request<PaymentMethod[]>('/api/v1/billing/payment-methods', {
|
|
560
|
+
params: { customerId }, token,
|
|
561
|
+
})
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
async removePaymentMethod(paymentMethodId: string, token?: string): Promise<void> {
|
|
565
|
+
await this.request<void>(`/api/v1/billing/payment-methods/${paymentMethodId}`, {
|
|
257
566
|
method: 'DELETE', token,
|
|
258
567
|
})
|
|
259
568
|
}
|
|
260
569
|
|
|
570
|
+
async setDefaultPaymentMethod(customerId: string, paymentMethodId: string, token?: string): Promise<PaymentMethod> {
|
|
571
|
+
return this.request<PaymentMethod>(`/api/v1/billing/customers/${customerId}/default-payment-method`, {
|
|
572
|
+
method: 'POST', body: { paymentMethodId }, token,
|
|
573
|
+
})
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
// -----------------------------------------------------------------------
|
|
577
|
+
// Coupons / Promo codes
|
|
578
|
+
// -----------------------------------------------------------------------
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Validate a coupon code.
|
|
582
|
+
* Optionally pass a subtotalCents to get the calculated discount amount.
|
|
583
|
+
*/
|
|
584
|
+
async validateCoupon(code: string, subtotalCents?: number, token?: string): Promise<CouponValidateResult> {
|
|
585
|
+
try {
|
|
586
|
+
const result = await this.request<Coupon>('/api/v1/coupon/validate', {
|
|
587
|
+
method: 'POST',
|
|
588
|
+
body: { code: code.toUpperCase().trim(), subtotalCents },
|
|
589
|
+
token,
|
|
590
|
+
})
|
|
591
|
+
return { valid: true, coupon: result }
|
|
592
|
+
} catch (err) {
|
|
593
|
+
const msg = err instanceof CommerceApiError ? err.message : 'Invalid coupon'
|
|
594
|
+
return { valid: false, error: msg }
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* Redeem a coupon for a user. Creates credit grant records.
|
|
600
|
+
*/
|
|
601
|
+
async redeemCoupon(code: string, userId: string, token?: string): Promise<CreditGrant[]> {
|
|
602
|
+
return this.request<CreditGrant[]>('/api/v1/coupon/redeem', {
|
|
603
|
+
method: 'POST',
|
|
604
|
+
body: { code: code.toUpperCase().trim(), userId },
|
|
605
|
+
token,
|
|
606
|
+
})
|
|
607
|
+
}
|
|
608
|
+
|
|
261
609
|
// -----------------------------------------------------------------------
|
|
262
|
-
//
|
|
610
|
+
// Referrals & Affiliates
|
|
611
|
+
// -----------------------------------------------------------------------
|
|
612
|
+
|
|
613
|
+
/**
|
|
614
|
+
* Get or create a referrer record for a user.
|
|
615
|
+
* Returns the referral code/link the user can share.
|
|
616
|
+
*/
|
|
617
|
+
async getOrCreateReferrer(userId: string, token?: string): Promise<Referrer> {
|
|
618
|
+
return this.request<Referrer>('/api/v1/referrer', {
|
|
619
|
+
method: 'POST', body: { userId }, token,
|
|
620
|
+
})
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
async getReferrals(userId: string, token?: string): Promise<Referral[]> {
|
|
624
|
+
return this.request<Referral[]>(`/api/v1/user/${userId}/referrals`, { token })
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
async getReferrers(userId: string, token?: string): Promise<Referrer[]> {
|
|
628
|
+
return this.request<Referrer[]>(`/api/v1/user/${userId}/referrers`, { token })
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Get affiliate details for a user.
|
|
633
|
+
*/
|
|
634
|
+
async getAffiliate(userId: string, token?: string): Promise<Affiliate | null> {
|
|
635
|
+
try {
|
|
636
|
+
return await this.request<Affiliate>(`/api/v1/user/${userId}/affiliate`, { token })
|
|
637
|
+
} catch { return null }
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/**
|
|
641
|
+
* Create an affiliate account for a user.
|
|
642
|
+
* After creation, user can connect their bank via the returnedconnectUrl.
|
|
643
|
+
*/
|
|
644
|
+
async createAffiliate(userId: string, token?: string): Promise<Affiliate> {
|
|
645
|
+
return this.request<Affiliate>('/api/v1/affiliate', {
|
|
646
|
+
method: 'POST', body: { userId }, token,
|
|
647
|
+
})
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
async getAffiliateReferrals(affiliateId: string, token?: string): Promise<Referral[]> {
|
|
651
|
+
return this.request<Referral[]>(`/api/v1/affiliate/${affiliateId}/referrals`, { token })
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
async getAffiliateOrders(affiliateId: string, token?: string): Promise<unknown[]> {
|
|
655
|
+
return this.request<unknown[]>(`/api/v1/affiliate/${affiliateId}/orders`, { token })
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
async getAffiliateTransactions(affiliateId: string, token?: string): Promise<Transaction[]> {
|
|
659
|
+
return this.request<Transaction[]>(`/api/v1/affiliate/${affiliateId}/transactions`, { token })
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
// -----------------------------------------------------------------------
|
|
663
|
+
// Legacy checkout (order-based)
|
|
263
664
|
// -----------------------------------------------------------------------
|
|
264
665
|
|
|
265
666
|
async authorize(orderId: string, token?: string): Promise<Payment> {
|
|
@@ -278,38 +679,35 @@ export class Commerce {
|
|
|
278
679
|
return this.request<Payment>(`/api/v1/refund/${paymentId}`, { method: 'POST', token })
|
|
279
680
|
}
|
|
280
681
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
async billingRefund(params: {
|
|
286
|
-
user: string
|
|
287
|
-
amount: number
|
|
288
|
-
originalTransactionId: string
|
|
289
|
-
currency?: string
|
|
290
|
-
notes?: string
|
|
291
|
-
}, token?: string): Promise<Transaction> {
|
|
682
|
+
async billingRefund(
|
|
683
|
+
params: { user: string; amount: number; originalTransactionId: string; currency?: string; notes?: string },
|
|
684
|
+
token?: string,
|
|
685
|
+
): Promise<Transaction> {
|
|
292
686
|
return this.request<Transaction>('/api/v1/billing/refund', {
|
|
293
687
|
method: 'POST', body: params, token,
|
|
294
688
|
})
|
|
295
689
|
}
|
|
690
|
+
}
|
|
296
691
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
async getPlans(token?: string): Promise<Plan[]> {
|
|
302
|
-
return this.request<Plan[]>('/api/v1/plan', { token })
|
|
303
|
-
}
|
|
692
|
+
// ---------------------------------------------------------------------------
|
|
693
|
+
// Standalone factory helpers — import these for quick setup
|
|
694
|
+
// ---------------------------------------------------------------------------
|
|
304
695
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
696
|
+
/**
|
|
697
|
+
* Create a commerce client pre-configured for api.hanzo.ai.
|
|
698
|
+
* Pass your IAM access token (read from localStorage or cookie).
|
|
699
|
+
*
|
|
700
|
+
* @example
|
|
701
|
+
* ```ts
|
|
702
|
+
* import { hanzoCommerce } from '@hanzo/commerce/client'
|
|
703
|
+
* const commerce = hanzoCommerce(localStorage.getItem('hanzo-auth-token') ?? undefined)
|
|
704
|
+
* const plans = await commerce.getPlans()
|
|
705
|
+
* ```
|
|
706
|
+
*/
|
|
707
|
+
export function hanzoCommerce(token?: string): Commerce {
|
|
708
|
+
return new Commerce({ token })
|
|
310
709
|
}
|
|
311
710
|
|
|
312
|
-
|
|
313
711
|
// ---------------------------------------------------------------------------
|
|
314
712
|
// Error
|
|
315
713
|
// ---------------------------------------------------------------------------
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { useState } from 'react'
|
|
3
3
|
import { observer } from 'mobx-react-lite'
|
|
4
4
|
|
|
5
5
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
@@ -7,7 +7,6 @@ import * as z from 'zod'
|
|
|
7
7
|
import { useForm } from 'react-hook-form'
|
|
8
8
|
|
|
9
9
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@hanzo/ui/primitives'
|
|
10
|
-
import { useAuth } from '@hanzo/auth/service'
|
|
11
10
|
|
|
12
11
|
import { useCommerce } from '../../../service/context'
|
|
13
12
|
import { sendFBEvent, sendGAEvent } from '../../../util/analytics'
|
|
@@ -26,29 +25,17 @@ const PaymentStepForm: React.FC<CheckoutStepComponentProps> = observer(({
|
|
|
26
25
|
setOrderId
|
|
27
26
|
}) => {
|
|
28
27
|
const cmmc = useCommerce()
|
|
29
|
-
const auth = useAuth() // may be null in some cases
|
|
30
28
|
|
|
31
29
|
const [transactionStatus, setTransactionStatus] = useState<TransactionStatus>('unpaid')
|
|
32
30
|
|
|
33
|
-
if (!auth) {
|
|
34
|
-
console.log("PAYMENT STEP FORM: auth service is null! ")
|
|
35
|
-
}
|
|
36
|
-
|
|
37
31
|
const contactForm = useForm<z.infer<typeof contactFormSchema>>({
|
|
38
32
|
resolver: zodResolver(contactFormSchema as any),
|
|
39
33
|
defaultValues: {
|
|
40
|
-
name:
|
|
41
|
-
email:
|
|
34
|
+
name: '',
|
|
35
|
+
email: '',
|
|
42
36
|
},
|
|
43
37
|
})
|
|
44
38
|
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
if (auth?.loggedIn) {
|
|
47
|
-
contactForm.setValue('name', auth!.user?.displayName ?? '')
|
|
48
|
-
contactForm.setValue('email', auth!.user?.email ?? '')
|
|
49
|
-
}
|
|
50
|
-
}, [auth?.loggedIn])
|
|
51
|
-
|
|
52
39
|
const storePaymentInfo = async (paymentInfo: any) => {
|
|
53
40
|
const {name, email} = contactForm.getValues()
|
|
54
41
|
let id: string | undefined = undefined
|