@mercurjs/docs 2.2.0-canary.40

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 (283) hide show
  1. package/README.md +24 -0
  2. package/content/blocks.mdx +209 -0
  3. package/content/learn/architecture.mdx +215 -0
  4. package/content/learn/attributes.mdx +89 -0
  5. package/content/learn/blocks.mdx +99 -0
  6. package/content/learn/commissions.mdx +175 -0
  7. package/content/learn/concepts.mdx +84 -0
  8. package/content/learn/installation.mdx +117 -0
  9. package/content/learn/introduction.mdx +71 -0
  10. package/content/learn/offers.mdx +78 -0
  11. package/content/learn/order-groups.mdx +114 -0
  12. package/content/learn/payouts.mdx +175 -0
  13. package/content/learn/product-requests.mdx +82 -0
  14. package/content/learn/products.mdx +79 -0
  15. package/content/learn/registry.mdx +155 -0
  16. package/content/learn/seller-members.mdx +62 -0
  17. package/content/learn/sellers.mdx +118 -0
  18. package/content/migration/from-1-x-to-2-0.mdx +152 -0
  19. package/content/migration/from-2-0-to-2-1.mdx +105 -0
  20. package/content/migration/overview.mdx +58 -0
  21. package/content/references/api/admin/commission-rates/batch-commission-rules.mdx +70 -0
  22. package/content/references/api/admin/commission-rates/create-commission-rate.mdx +95 -0
  23. package/content/references/api/admin/commission-rates/delete-commission-rate.mdx +40 -0
  24. package/content/references/api/admin/commission-rates/list-commission-rates.mdx +92 -0
  25. package/content/references/api/admin/commission-rates/retrieve-commission-rate.mdx +70 -0
  26. package/content/references/api/admin/commission-rates/update-commission-rate.mdx +84 -0
  27. package/content/references/api/admin/members/list-members.mdx +61 -0
  28. package/content/references/api/admin/offers/batch-create-offers.mdx +130 -0
  29. package/content/references/api/admin/offers/delete-offer.mdx +40 -0
  30. package/content/references/api/admin/offers/list-offers.mdx +106 -0
  31. package/content/references/api/admin/offers/retrieve-offer.mdx +82 -0
  32. package/content/references/api/admin/order-groups/list-order-groups.mdx +77 -0
  33. package/content/references/api/admin/order-groups/retrieve-order-group.mdx +56 -0
  34. package/content/references/api/admin/orders/get-order-commission-lines.mdx +65 -0
  35. package/content/references/api/admin/orders/get-order-order-group.mdx +56 -0
  36. package/content/references/api/admin/orders/list-orders.mdx +79 -0
  37. package/content/references/api/admin/payouts/list-payouts.mdx +75 -0
  38. package/content/references/api/admin/payouts/retrieve-payout.mdx +62 -0
  39. package/content/references/api/admin/product-attributes/create-attribute-value.mdx +76 -0
  40. package/content/references/api/admin/product-attributes/create-product-attribute.mdx +99 -0
  41. package/content/references/api/admin/product-attributes/delete-attribute-value.mdx +52 -0
  42. package/content/references/api/admin/product-attributes/delete-product-attribute.mdx +40 -0
  43. package/content/references/api/admin/product-attributes/list-product-attributes.mdx +91 -0
  44. package/content/references/api/admin/product-attributes/retrieve-product-attribute.mdx +81 -0
  45. package/content/references/api/admin/product-attributes/update-attribute-value.mdx +66 -0
  46. package/content/references/api/admin/product-attributes/update-product-attribute.mdx +76 -0
  47. package/content/references/api/admin/product-changes/cancel-product-change.mdx +68 -0
  48. package/content/references/api/admin/product-changes/confirm-product-change.mdx +47 -0
  49. package/content/references/api/admin/products/batch-product-attributes.mdx +96 -0
  50. package/content/references/api/admin/products/confirm-product.mdx +59 -0
  51. package/content/references/api/admin/products/create-product-variant.mdx +78 -0
  52. package/content/references/api/admin/products/create-product.mdx +169 -0
  53. package/content/references/api/admin/products/delete-product-variant.mdx +48 -0
  54. package/content/references/api/admin/products/delete-product.mdx +40 -0
  55. package/content/references/api/admin/products/list-product-variants.mdx +91 -0
  56. package/content/references/api/admin/products/list-products.mdx +109 -0
  57. package/content/references/api/admin/products/preview-product.mdx +78 -0
  58. package/content/references/api/admin/products/reject-product.mdx +59 -0
  59. package/content/references/api/admin/products/request-product-changes.mdx +59 -0
  60. package/content/references/api/admin/products/retrieve-product-variant.mdx +73 -0
  61. package/content/references/api/admin/products/retrieve-product.mdx +96 -0
  62. package/content/references/api/admin/products/set-product-sellers.mdx +47 -0
  63. package/content/references/api/admin/products/update-product-variant.mdx +89 -0
  64. package/content/references/api/admin/products/update-product.mdx +133 -0
  65. package/content/references/api/admin/sellers/add-seller-member.mdx +63 -0
  66. package/content/references/api/admin/sellers/approve-seller.mdx +54 -0
  67. package/content/references/api/admin/sellers/create-seller.mdx +100 -0
  68. package/content/references/api/admin/sellers/delete-member-invite.mdx +42 -0
  69. package/content/references/api/admin/sellers/delete-professional-details.mdx +52 -0
  70. package/content/references/api/admin/sellers/invite-seller-member.mdx +63 -0
  71. package/content/references/api/admin/sellers/list-member-invites.mdx +71 -0
  72. package/content/references/api/admin/sellers/list-seller-members.mdx +71 -0
  73. package/content/references/api/admin/sellers/list-seller-products.mdx +85 -0
  74. package/content/references/api/admin/sellers/list-sellers.mdx +96 -0
  75. package/content/references/api/admin/sellers/remove-seller-member.mdx +42 -0
  76. package/content/references/api/admin/sellers/resend-member-invite.mdx +55 -0
  77. package/content/references/api/admin/sellers/retrieve-seller.mdx +81 -0
  78. package/content/references/api/admin/sellers/suspend-seller.mdx +60 -0
  79. package/content/references/api/admin/sellers/terminate-seller.mdx +60 -0
  80. package/content/references/api/admin/sellers/unsuspend-seller.mdx +52 -0
  81. package/content/references/api/admin/sellers/unterminate-seller.mdx +52 -0
  82. package/content/references/api/admin/sellers/update-seller.mdx +83 -0
  83. package/content/references/api/admin/sellers/upsert-payment-details.mdx +88 -0
  84. package/content/references/api/admin/sellers/upsert-professional-details.mdx +78 -0
  85. package/content/references/api/admin/sellers/upsert-seller-address.mdx +91 -0
  86. package/content/references/api/admin.mdx +134 -0
  87. package/content/references/api/conventions.mdx +109 -0
  88. package/content/references/api/store/carts/add-line-item.mdx +115 -0
  89. package/content/references/api/store/carts/add-shipping-methods.mdx +84 -0
  90. package/content/references/api/store/carts/apply-promotions.mdx +83 -0
  91. package/content/references/api/store/carts/complete-cart.mdx +98 -0
  92. package/content/references/api/store/offers/list-offers.mdx +161 -0
  93. package/content/references/api/store/offers/retrieve-offer.mdx +112 -0
  94. package/content/references/api/store/order-groups/list-order-groups.mdx +105 -0
  95. package/content/references/api/store/order-groups/retrieve-order-group.mdx +78 -0
  96. package/content/references/api/store/product-attributes/list-product-attributes.mdx +134 -0
  97. package/content/references/api/store/product-attributes/retrieve-product-attribute.mdx +78 -0
  98. package/content/references/api/store/product-categories/list-product-categories.mdx +126 -0
  99. package/content/references/api/store/product-categories/retrieve-product-category.mdx +79 -0
  100. package/content/references/api/store/products/list-products.mdx +184 -0
  101. package/content/references/api/store/products/retrieve-product.mdx +107 -0
  102. package/content/references/api/store/search/search.mdx +136 -0
  103. package/content/references/api/store/sellers/list-sellers.mdx +105 -0
  104. package/content/references/api/store/sellers/retrieve-seller.mdx +62 -0
  105. package/content/references/api/store/shipping-options/list-shipping-options.mdx +74 -0
  106. package/content/references/api/store.mdx +67 -0
  107. package/content/references/api/vendor/members/accept-member-invite.mdx +65 -0
  108. package/content/references/api/vendor/members/retrieve-current-member.mdx +51 -0
  109. package/content/references/api/vendor/members/update-current-member.mdx +70 -0
  110. package/content/references/api/vendor/offers/batch-create-offers.mdx +123 -0
  111. package/content/references/api/vendor/offers/batch-offer-inventory-items.mdx +103 -0
  112. package/content/references/api/vendor/offers/create-offer.mdx +141 -0
  113. package/content/references/api/vendor/offers/delete-offer.mdx +51 -0
  114. package/content/references/api/vendor/offers/list-offers.mdx +125 -0
  115. package/content/references/api/vendor/offers/retrieve-offer.mdx +74 -0
  116. package/content/references/api/vendor/offers/update-offer.mdx +82 -0
  117. package/content/references/api/vendor/orders/cancel-fulfillment.mdx +63 -0
  118. package/content/references/api/vendor/orders/cancel-order.mdx +56 -0
  119. package/content/references/api/vendor/orders/complete-order.mdx +55 -0
  120. package/content/references/api/vendor/orders/create-fulfillment.mdx +76 -0
  121. package/content/references/api/vendor/orders/create-shipment.mdx +99 -0
  122. package/content/references/api/vendor/orders/get-order-commission-lines.mdx +66 -0
  123. package/content/references/api/vendor/orders/list-order-changes.mdx +75 -0
  124. package/content/references/api/vendor/orders/list-orders.mdx +103 -0
  125. package/content/references/api/vendor/orders/mark-fulfillment-delivered.mdx +62 -0
  126. package/content/references/api/vendor/orders/preview-order.mdx +65 -0
  127. package/content/references/api/vendor/orders/retrieve-order.mdx +84 -0
  128. package/content/references/api/vendor/payout-accounts/create-onboarding.mdx +68 -0
  129. package/content/references/api/vendor/payout-accounts/create-payout-account.mdx +59 -0
  130. package/content/references/api/vendor/payout-accounts/retrieve-payout-account-by-id.mdx +60 -0
  131. package/content/references/api/vendor/payout-accounts/retrieve-payout-account.mdx +77 -0
  132. package/content/references/api/vendor/payouts/list-payouts.mdx +90 -0
  133. package/content/references/api/vendor/payouts/retrieve-payout.mdx +63 -0
  134. package/content/references/api/vendor/product-attributes/list-product-attributes.mdx +135 -0
  135. package/content/references/api/vendor/product-attributes/retrieve-product-attribute.mdx +71 -0
  136. package/content/references/api/vendor/product-variants/list-variants.mdx +136 -0
  137. package/content/references/api/vendor/products/batch-product-attributes.mdx +104 -0
  138. package/content/references/api/vendor/products/cancel-product-change.mdx +62 -0
  139. package/content/references/api/vendor/products/create-product-variant.mdx +92 -0
  140. package/content/references/api/vendor/products/create-product.mdx +197 -0
  141. package/content/references/api/vendor/products/delete-product-variant.mdx +68 -0
  142. package/content/references/api/vendor/products/delete-product.mdx +62 -0
  143. package/content/references/api/vendor/products/list-product-variants.mdx +114 -0
  144. package/content/references/api/vendor/products/list-products.mdx +163 -0
  145. package/content/references/api/vendor/products/preview-product.mdx +61 -0
  146. package/content/references/api/vendor/products/retrieve-product-variant.mdx +76 -0
  147. package/content/references/api/vendor/products/retrieve-product.mdx +69 -0
  148. package/content/references/api/vendor/products/update-product-variant.mdx +104 -0
  149. package/content/references/api/vendor/products/update-product.mdx +148 -0
  150. package/content/references/api/vendor/sellers/create-seller.mdx +150 -0
  151. package/content/references/api/vendor/sellers/delete-professional-details.mdx +54 -0
  152. package/content/references/api/vendor/sellers/invite-seller-member.mdx +67 -0
  153. package/content/references/api/vendor/sellers/list-member-invites.mdx +82 -0
  154. package/content/references/api/vendor/sellers/list-seller-members.mdx +80 -0
  155. package/content/references/api/vendor/sellers/list-sellers.mdx +71 -0
  156. package/content/references/api/vendor/sellers/remove-seller-member.mdx +48 -0
  157. package/content/references/api/vendor/sellers/retrieve-current-seller-member.mdx +59 -0
  158. package/content/references/api/vendor/sellers/retrieve-current-seller.mdx +69 -0
  159. package/content/references/api/vendor/sellers/select-seller.mdx +44 -0
  160. package/content/references/api/vendor/sellers/update-current-seller.mdx +108 -0
  161. package/content/references/api/vendor/sellers/update-member-role.mdx +51 -0
  162. package/content/references/api/vendor/sellers/upsert-payment-details.mdx +74 -0
  163. package/content/references/api/vendor/sellers/upsert-professional-details.mdx +70 -0
  164. package/content/references/api/vendor/sellers/upsert-seller-address.mdx +81 -0
  165. package/content/references/api/vendor.mdx +150 -0
  166. package/content/references/configuration.mdx +155 -0
  167. package/content/references/modules/commission.mdx +106 -0
  168. package/content/references/modules/custom-fields.mdx +45 -0
  169. package/content/references/modules/media.mdx +55 -0
  170. package/content/references/modules/offer.mdx +64 -0
  171. package/content/references/modules/payout.mdx +121 -0
  172. package/content/references/modules/product-attribute.mdx +111 -0
  173. package/content/references/modules/product-edit.mdx +80 -0
  174. package/content/references/modules/search.mdx +112 -0
  175. package/content/references/modules/seller.mdx +175 -0
  176. package/content/references/overview.mdx +70 -0
  177. package/content/references/workflows/cart/add-seller-shipping-method-to-cart.mdx +44 -0
  178. package/content/references/workflows/cart/complete-cart-with-split-orders.mdx +36 -0
  179. package/content/references/workflows/cart/list-seller-shipping-options-for-cart.mdx +39 -0
  180. package/content/references/workflows/cart/update-cart-seller-promotions.mdx +42 -0
  181. package/content/references/workflows/commission/batch-commission-rules.mdx +45 -0
  182. package/content/references/workflows/commission/create-commission-rates.mdx +41 -0
  183. package/content/references/workflows/commission/delete-commission-rates.mdx +34 -0
  184. package/content/references/workflows/commission/refresh-order-commission-lines.mdx +30 -0
  185. package/content/references/workflows/commission/update-commission-rates.mdx +35 -0
  186. package/content/references/workflows/media/set-category-images.mdx +41 -0
  187. package/content/references/workflows/media/set-collection-images.mdx +41 -0
  188. package/content/references/workflows/member/accept-member-invite.mdx +33 -0
  189. package/content/references/workflows/member/add-seller-member.mdx +30 -0
  190. package/content/references/workflows/member/create-member-invites.mdx +34 -0
  191. package/content/references/workflows/member/delete-member-invite.mdx +24 -0
  192. package/content/references/workflows/member/remove-seller-member.mdx +28 -0
  193. package/content/references/workflows/member/resend-member-invite.mdx +28 -0
  194. package/content/references/workflows/member/update-member-role.mdx +28 -0
  195. package/content/references/workflows/member/update-member.mdx +35 -0
  196. package/content/references/workflows/offer/batch-offer-inventory-items.mdx +58 -0
  197. package/content/references/workflows/offer/create-offers.mdx +63 -0
  198. package/content/references/workflows/offer/delete-offers.mdx +35 -0
  199. package/content/references/workflows/offer/update-offers.mdx +51 -0
  200. package/content/references/workflows/order/cancel-order-fulfillment.mdx +34 -0
  201. package/content/references/workflows/order/confirm-claim-request.mdx +25 -0
  202. package/content/references/workflows/order/confirm-exchange-request.mdx +25 -0
  203. package/content/references/workflows/order/confirm-order-edit-request.mdx +25 -0
  204. package/content/references/workflows/order/confirm-return-receive.mdx +25 -0
  205. package/content/references/workflows/order/create-order-fulfillment.mdx +45 -0
  206. package/content/references/workflows/order-group/get-order-group-detail.mdx +29 -0
  207. package/content/references/workflows/order-group/get-order-groups-list.mdx +36 -0
  208. package/content/references/workflows/overview.mdx +72 -0
  209. package/content/references/workflows/payout/create-onboarding.mdx +36 -0
  210. package/content/references/workflows/payout/create-payout-account.mdx +33 -0
  211. package/content/references/workflows/payout/create-payout.mdx +30 -0
  212. package/content/references/workflows/payout/process-payout-for-webhook.mdx +32 -0
  213. package/content/references/workflows/product/confirm-products.mdx +46 -0
  214. package/content/references/workflows/product/create-products.mdx +63 -0
  215. package/content/references/workflows/product/link-sellers-to-product-category.mdx +40 -0
  216. package/content/references/workflows/product/link-sellers-to-product.mdx +40 -0
  217. package/content/references/workflows/product/reject-product.mdx +46 -0
  218. package/content/references/workflows/product/request-product-change.mdx +46 -0
  219. package/content/references/workflows/product-attribute/add-product-attributes-to-product.mdx +49 -0
  220. package/content/references/workflows/product-attribute/create-and-link-product-attributes-to-product.mdx +46 -0
  221. package/content/references/workflows/product-attribute/create-product-attribute-values.mdx +43 -0
  222. package/content/references/workflows/product-attribute/create-product-attributes.mdx +56 -0
  223. package/content/references/workflows/product-attribute/delete-product-attribute-values.mdx +30 -0
  224. package/content/references/workflows/product-attribute/delete-product-attributes.mdx +30 -0
  225. package/content/references/workflows/product-attribute/remove-product-attributes-from-product.mdx +29 -0
  226. package/content/references/workflows/product-attribute/update-product-attribute-values.mdx +44 -0
  227. package/content/references/workflows/product-attribute/update-product-attributes-on-product.mdx +41 -0
  228. package/content/references/workflows/product-attribute/update-product-attributes.mdx +48 -0
  229. package/content/references/workflows/product-attribute/upsert-product-attribute-values.mdx +43 -0
  230. package/content/references/workflows/product-edit/auto-confirm-product-change.mdx +39 -0
  231. package/content/references/workflows/product-edit/cancel-product-change.mdx +49 -0
  232. package/content/references/workflows/product-edit/confirm-product-change.mdx +57 -0
  233. package/content/references/workflows/product-edit/create-product-change.mdx +72 -0
  234. package/content/references/workflows/product-edit/reject-product-change.mdx +54 -0
  235. package/content/references/workflows/product-edit/stage-product-change.mdx +75 -0
  236. package/content/references/workflows/seller/approve-seller.mdx +34 -0
  237. package/content/references/workflows/seller/create-seller-account.mdx +59 -0
  238. package/content/references/workflows/seller/create-seller-defaults.mdx +22 -0
  239. package/content/references/workflows/seller/create-sellers.mdx +65 -0
  240. package/content/references/workflows/seller/delete-seller-professional-details.mdx +37 -0
  241. package/content/references/workflows/seller/delete-sellers.mdx +24 -0
  242. package/content/references/workflows/seller/invite-seller.mdx +28 -0
  243. package/content/references/workflows/seller/suspend-seller.mdx +35 -0
  244. package/content/references/workflows/seller/terminate-seller.mdx +35 -0
  245. package/content/references/workflows/seller/unsuspend-seller.mdx +34 -0
  246. package/content/references/workflows/seller/unterminate-seller.mdx +34 -0
  247. package/content/references/workflows/seller/update-seller-address.mdx +55 -0
  248. package/content/references/workflows/seller/update-seller-payment-details.mdx +52 -0
  249. package/content/references/workflows/seller/update-seller-professional-details.mdx +48 -0
  250. package/content/references/workflows/seller/update-sellers.mdx +57 -0
  251. package/content/resources/ai/llms.mdx +74 -0
  252. package/content/resources/ai/mcp.mdx +152 -0
  253. package/content/resources/ai/overview.mdx +97 -0
  254. package/content/resources/customization/custom-fields.mdx +182 -0
  255. package/content/resources/customization/extend-a-workflow.mdx +39 -0
  256. package/content/resources/customization/extending-panels.mdx +309 -0
  257. package/content/resources/deployment/medusa-cloud.mdx +167 -0
  258. package/content/resources/integrations/notifications.mdx +39 -0
  259. package/content/resources/integrations/search.mdx +122 -0
  260. package/content/resources/integrations/stripe-connect.mdx +395 -0
  261. package/content/resources/tutorials/add-a-block.mdx +74 -0
  262. package/content/resources/tutorials/attributes-and-variant-axes.mdx +111 -0
  263. package/content/resources/tutorials/build-a-block.mdx +134 -0
  264. package/content/resources/tutorials/configure-commissions.mdx +127 -0
  265. package/content/resources/tutorials/custom-api-route.mdx +142 -0
  266. package/content/resources/tutorials/custom-panel-page.mdx +78 -0
  267. package/content/resources/tutorials/first-marketplace.mdx +45 -0
  268. package/content/resources/tutorials/handle-product-requests.mdx +80 -0
  269. package/content/resources/tutorials/import-export-products.mdx +96 -0
  270. package/content/resources/tutorials/master-products-and-offers.mdx +89 -0
  271. package/content/resources/tutorials/recompose-a-page.mdx +129 -0
  272. package/content/resources/tutorials/replace-panel-components.mdx +116 -0
  273. package/content/resources/tutorials/seller-payouts-stripe.mdx +89 -0
  274. package/content/telemetry.mdx +67 -0
  275. package/content/tools/api-client.mdx +155 -0
  276. package/content/tools/cli.mdx +196 -0
  277. package/content/tools/dashboard-sdk.mdx +35 -0
  278. package/content/user-guide/admin/overview.mdx +23 -0
  279. package/content/user-guide/admin/stores.mdx +193 -0
  280. package/content/user-guide/vendor/overview.mdx +23 -0
  281. package/content/user-guide/vendor/stores.mdx +209 -0
  282. package/llms.txt +307 -0
  283. package/package.json +33 -0
@@ -0,0 +1,96 @@
1
+ ---
2
+ title: "Import and export products via CSV"
3
+ description: "Install the product-import-export block and give vendors CSV import and export drawers on their product list."
4
+ ---
5
+
6
+ Bulk catalog operations belong to vendors, not the operator — a seller migrating from another platform needs to bring hundreds of listings with them. The `product-import-export` block adds CSV import and export to the Vendor Portal: API routes, workflows built on Medusa's product CSV steps, and drawer UIs wired into the product list.
7
+
8
+ <Info>
9
+ **This block is also a masterclass in Mercur's extension model.** It ships backend workflows and routes into your API package, and it overrides the vendor `/products` page by dropping a route file that [re-composes the built-in page's compound slots](/rc/resources/tutorials/recompose-a-page) — adding Import/Export buttons while keeping the stock table untouched. After installing, read its source; you own every file.
10
+ </Info>
11
+
12
+ ## What you'll build
13
+
14
+ A vendor product list with **Import** and **Export** header buttons, a working CSV round-trip, and the block's source code in your project.
15
+
16
+ ## Install and wire the block
17
+
18
+ <Steps>
19
+ <Step title="Install the block">
20
+ ```bash
21
+ bunx @mercurjs/cli@rc add product-import-export
22
+ ```
23
+
24
+ The CLI copies the block's files into the directories mapped by your `blocks.json` aliases — workflows and routes into the API package, pages and hooks into the vendor app.
25
+ </Step>
26
+ <Step title="Install its dependencies">
27
+ The block uses Medusa's CSV flows and `multer` for uploads. Install them in the **API workspace**, not the project root:
28
+
29
+ ```bash
30
+ cd packages/api
31
+ bun add @medusajs/core-flows multer @types/multer
32
+ ```
33
+ </Step>
34
+ <Step title="Register the middleware">
35
+ The import route needs its upload middleware. Add it to your API's `middlewares.ts`:
36
+
37
+ ```typescript packages/api/src/api/middlewares.ts
38
+ import { defineMiddlewares } from '@medusajs/medusa'
39
+ import { productImportExportMiddlewares } from './vendor/products/middlewares'
40
+
41
+ export default defineMiddlewares({
42
+ routes: [...productImportExportMiddlewares],
43
+ })
44
+ ```
45
+ </Step>
46
+ <Step title="Regenerate types">
47
+ The block added `POST /vendor/products/import` and `GET /vendor/products/export`. Regenerate the route map so the vendor app's typed client knows about them:
48
+
49
+ ```bash
50
+ bunx @mercurjs/cli@rc codegen
51
+ ```
52
+
53
+ <Note>
54
+ No new modules and no migrations — the block reuses Medusa's built-in product CSV steps, so there's nothing to add to `medusa-config.ts` for this one. Always read a block's post-install output: each block declares its own setup steps.
55
+ </Note>
56
+ </Step>
57
+ <Step title="Run a round-trip">
58
+ Start the project and open the Vendor Portal's **Products** page — the header now shows Import and Export next to Create.
59
+
60
+ 1. **Export** — opens the drawer at `/products/export` and downloads the seller's current products as CSV.
61
+ 2. Edit the CSV: tweak a title, add a row.
62
+ 3. **Import** — the drawer at `/products/import` accepts the file, validates rows, and shows an import summary before applying.
63
+ </Step>
64
+ </Steps>
65
+
66
+ ## Verify
67
+
68
+ 1. The Products header shows Import and Export buttons; the rest of the page (search, filters, pagination) behaves exactly as before.
69
+ 2. The exported CSV contains the seller's products — and only theirs; the workflow scopes to the authenticated seller.
70
+ 3. After importing the edited CSV, the changed title appears in the product list.
71
+ 4. The block's source lives in your repo (e.g. `packages/api/src/workflows/import-seller-products.ts`, `apps/vendor/src/routes/products/page.tsx`) — run `bunx @mercurjs/cli@rc diff product-import-export` to compare against the registry later.
72
+
73
+ ## FAQ
74
+
75
+ <AccordionGroup>
76
+ <Accordion title="Can I customize the CSV columns or validation?">
77
+ Yes — the block is source code in your repo. The import workflow (`import-seller-products.ts`) and its validation step are yours to edit; the drawer UI under `routes/products/import/` includes the CSV template helper you can extend.
78
+ </Accordion>
79
+ <Accordion title="I already customized my /products page — will the block overwrite it?">
80
+ The block ships its own `routes/products/page.tsx`. If you already have one, the CLI asks before overwriting (or use `--overwrite` explicitly). Merge by hand in that case: keep your composition and add the block's Import/Export buttons to your `HeaderActions`.
81
+ </Accordion>
82
+ <Accordion title="Does import respect the product approval flow?">
83
+ Imported products enter through the same vendor create path as manual submissions — so they follow the [product-request pipeline](/rc/resources/tutorials/handle-product-requests) and land as `proposed` for operator review, not as instantly published records.
84
+ </Accordion>
85
+ </AccordionGroup>
86
+
87
+ ## Next steps
88
+
89
+ <CardGroup cols={2}>
90
+ <Card title="Re-compose a built-in page" href="/rc/resources/tutorials/recompose-a-page">
91
+ The page-override technique this block uses, explained step by step.
92
+ </Card>
93
+ <Card title="Build your own block" href="/rc/resources/tutorials/build-a-block">
94
+ Package a feature like this one and publish it to your own registry.
95
+ </Card>
96
+ </CardGroup>
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: "Work with master products and offers"
3
+ description: "Two sellers compete on one catalog entry: publish a master product, create competing offers, and read per-offer prices from the Store API."
4
+ ---
5
+
6
+ Mercur's catalog is a **master catalog**: one canonical product record, many sellers listing against it. The product defines *what the item is*; each seller's **offer** defines *how they sell it* — their SKU, price, stock, and shipping. This tutorial builds the classic "buy box" scenario: two sellers, one product, two competing offers.
7
+
8
+ <Info>
9
+ **No seller owns a product.** There is no owner column. Creating a product adds a candidate to the shared catalog — the creator gets attribution (so their unpublished submissions appear in their own list) but no rights over the record after publication. What looks like ownership elsewhere is split into selling eligibility, creator attribution, and the status lifecycle. See [Products](/rc/learn/products).
10
+ </Info>
11
+
12
+ ## What you'll build
13
+
14
+ A published master product with offers from two sellers at different prices, visible side by side through the Store API with per-offer calculated prices.
15
+
16
+ ## Product vs offer
17
+
18
+ | Concern | Lives on | Example |
19
+ |---------|----------|---------|
20
+ | What the item is | Master product | "Classic White T-Shirt", variants, attributes |
21
+ | Who may sell it | `product_seller` allowlist | Empty = every seller; assigned = only those sellers |
22
+ | How a seller sells it | Offer | SKU, price, stock, shipping profile |
23
+
24
+ ## Build the buy box
25
+
26
+ <Steps>
27
+ <Step title="Publish a master product">
28
+ As Seller A, create a product in the Vendor Portal — say "Classic White T-Shirt" with a size variant. It enters as `proposed`; as the operator, confirm it in the Admin Panel so it's `published` (the review flow is covered in [Handle product requests](/rc/resources/tutorials/handle-product-requests)).
29
+
30
+ The published product now belongs to the shared catalog. Note what it does **not** have: a seller price or seller stock.
31
+ </Step>
32
+ <Step title="Seller A creates an offer">
33
+ In Seller A's Vendor Portal, create an offer against the product's variant: their own SKU, a price of $25, stock of 100, and one of their shipping profiles.
34
+
35
+ <Warning>
36
+ Offer inventory is linked to the **offer, not the variant**. Each seller manages stock for their own listing independently — a variant has no marketplace-wide stock figure, and its own `inventory_items` relation is empty for offer-based listings. Always read stock through the offer.
37
+ </Warning>
38
+ </Step>
39
+ <Step title="Seller B lists the same product">
40
+ As Seller B, find the same published product in the catalog and create a competing offer on the same variant — different SKU, $23, stock of 40. The `(seller_id, sku)` pair is unique per seller, so both sellers can use whatever SKU scheme they like.
41
+
42
+ Nothing about the master product changed. Two commercial listings now point at one catalog entry.
43
+ </Step>
44
+ <Step title="Read the buy box from the Store API">
45
+ The Store API exposes offers directly, each with its own calculated price:
46
+
47
+ ```bash
48
+ curl "http://localhost:9000/store/offers?product_id=prod_123" \
49
+ -H "x-publishable-api-key: <key>"
50
+ ```
51
+
52
+ Offers share the variant's price set scoped by an offer rule — each offer carries its own prices without duplicating the variant, and the storefront computes a `calculated_price` per offer. A buy-box storefront fetches the product once, then renders every seller's offer against it.
53
+ </Step>
54
+ <Step title="Check out against an offer">
55
+ Add Seller B's offer to a cart and place the order. The cart line item links to the **specific offer** purchased, and that link is preserved onto the order line item — so fulfillment, [commission calculation](/rc/learn/commissions), and [payouts](/rc/learn/payouts) all resolve to Seller B, even though both sellers list the same variant.
56
+ </Step>
57
+ </Steps>
58
+
59
+ ## Verify
60
+
61
+ 1. Both offers appear in `GET /store/offers?product_id=...` with different `calculated_price` values.
62
+ 2. Each seller's Vendor Portal shows only their own offer; the Admin Panel lists both with store, pricing, and inventory.
63
+ 3. After the checkout in step 5, the order lands with Seller B; Seller A's offer and stock are untouched.
64
+ 4. Reducing Seller B's offer stock doesn't affect Seller A's availability — inventory is per offer.
65
+
66
+ ## FAQ
67
+
68
+ <AccordionGroup>
69
+ <Accordion title="How do I restrict who may sell a product?">
70
+ The operator manages the `product_seller` allowlist: a product with assignments is visible and sellable only for those sellers, while a product with **no** assignments is open to every seller. Eligibility limits selling — it does not limit who may propose edits to the shared record.
71
+ </Accordion>
72
+ <Accordion title="Can two sellers use the same SKU?">
73
+ Yes — SKU uniqueness is per seller (`seller_id` + `sku`). Seller A and Seller B can both use `TSHIRT-WHITE-M`; a single seller cannot list the same SKU twice.
74
+ </Accordion>
75
+ <Accordion title="Who fulfills, refunds, and gets paid when several sellers list the same variant?">
76
+ Always the seller whose **offer** was purchased. The offer link travels from cart line to order line, so fulfillment, returns, commission, and payout all resolve through it — the variant alone is never enough to identify the seller.
77
+ </Accordion>
78
+ </AccordionGroup>
79
+
80
+ ## Next steps
81
+
82
+ <CardGroup cols={2}>
83
+ <Card title="Offers" href="/rc/learn/offers">
84
+ The offer data model, relationships, and checkout links.
85
+ </Card>
86
+ <Card title="Order Groups" href="/rc/learn/order-groups">
87
+ What happens when a cart spans both sellers — the multi-vendor split.
88
+ </Card>
89
+ </CardGroup>
@@ -0,0 +1,129 @@
1
+ ---
2
+ title: "Re-compose a built-in page"
3
+ description: "Override a built-in panel page by dropping a route file at the same path and re-composing its compound component slots."
4
+ ---
5
+
6
+ Every page in the admin and vendor panels is exported as a **compound component** — a root plus named slots like `Header`, `HeaderActions`, and `DataTable`. That means you never fork a page to change one part of it: you drop a `page.tsx` at the same route path, render the original page, and swap only the slot you care about. Everything you don't touch keeps its default behavior — data fetching, filters, pagination, i18n, all of it.
7
+
8
+ <Info>
9
+ **This is not Medusa's widget system.** Medusa's admin lets you inject widgets into predefined zones around a page. Mercur takes a different approach: pages are React compound components you re-compose directly. There are no injection zones and no `defineWidgetConfig` — you get the actual page component and decide what renders inside it. See [Extending Panels](/rc/resources/customization/extending-panels) for the full comparison.
10
+ </Info>
11
+
12
+ ## What you'll build
13
+
14
+ A vendor portal `/products` page with **Import** and **Export** buttons added next to the built-in Create button — while the table, search, filters, and everything else stay exactly as shipped. This is the same technique the official `product-import-export` block uses.
15
+
16
+ ## Slot anatomy
17
+
18
+ Built-in pages are exported from the `/pages` subpath of each panel package:
19
+
20
+ ```typescript
21
+ import { ProductListPage } from "@mercurjs/vendor/pages" // vendor portal
22
+ import { CustomerListPage } from "@mercurjs/admin/pages" // admin panel
23
+ ```
24
+
25
+ Each list page exposes the same family of slots:
26
+
27
+ | Slot | Renders |
28
+ |------|---------|
29
+ | `Table` | The `Container` shell holding header + table |
30
+ | `Header` | The title/actions row |
31
+ | `HeaderTitle` | Heading and subtitle |
32
+ | `HeaderActions` | The action button cluster |
33
+ | `HeaderCreateButton` | The built-in Create button |
34
+ | `DataTable` | The wired data table — fetching, columns, filters, pagination |
35
+
36
+ Detail pages expose section slots instead (e.g. `CustomerDetailPage.Main`, `CustomerDetailPage.Sidebar`, `CustomerDetailPage.MainGeneralSection`).
37
+
38
+ ## Override the page
39
+
40
+ <Steps>
41
+ <Step title="Drop a route file at the same path">
42
+ Create the file in your vendor app at the path that matches the built-in route. `/products` maps to `src/routes/products/page.tsx`:
43
+
44
+ ```tsx apps/vendor/src/routes/products/page.tsx
45
+ import { Link } from "react-router-dom"
46
+ import { Button } from "@medusajs/ui"
47
+ import { ArrowDownTray, ArrowUpTray } from "@medusajs/icons"
48
+ import { ProductListPage } from "@mercurjs/vendor/pages"
49
+
50
+ export default function ProductsWithImportExport() {
51
+ return (
52
+ <ProductListPage>
53
+ <ProductListPage.Table>
54
+ <ProductListPage.Header>
55
+ <ProductListPage.HeaderTitle />
56
+ <ProductListPage.HeaderActions>
57
+ <Button size="small" variant="secondary" asChild>
58
+ <Link to="import">
59
+ <ArrowUpTray />
60
+ Import
61
+ </Link>
62
+ </Button>
63
+ <Button size="small" variant="secondary" asChild>
64
+ <Link to="export">
65
+ <ArrowDownTray />
66
+ Export
67
+ </Link>
68
+ </Button>
69
+ <ProductListPage.HeaderCreateButton />
70
+ </ProductListPage.HeaderActions>
71
+ </ProductListPage.Header>
72
+ <ProductListPage.DataTable />
73
+ </ProductListPage.Table>
74
+ </ProductListPage>
75
+ )
76
+ }
77
+ ```
78
+ </Step>
79
+ <Step title="Reuse the slots you don't change">
80
+ Note what happened in that file: `HeaderTitle`, `HeaderCreateButton`, and `DataTable` are the originals, rendered untouched. Only `HeaderActions` gained two buttons. You re-compose top-down — render the page, re-declare only the branch you're changing, and keep original slots for everything inside it.
81
+ </Step>
82
+ <Step title="Reload the panel">
83
+ The dashboard SDK picks the file up automatically (adding or removing a route file triggers a full reload in dev). Because the path matches a built-in route, **your page replaces the built-in one** — no configuration, no registration.
84
+ </Step>
85
+ </Steps>
86
+
87
+ <Note>
88
+ When a custom route's path matches a built-in route, your page replaces the built-in one. Routes at new paths are appended instead. That one rule is the entire override mechanism.
89
+ </Note>
90
+
91
+ ## How defaults work
92
+
93
+ If you render a compound page with **no children**, it renders its full default composition — so `<ProductListPage />` alone is identical to the built-in page. Every page root follows the pattern:
94
+
95
+ ```tsx
96
+ Children.count(children) > 0 ? children : <DefaultComposition />
97
+ ```
98
+
99
+ ## Verify
100
+
101
+ 1. Run your project (`bun run dev`) and open the vendor portal.
102
+ 2. Navigate to **Products** — the list should look identical to before, plus Import and Export buttons in the header.
103
+ 3. Search, filter, and paginate the table — all built-in behavior must still work, since `DataTable` is untouched.
104
+ 4. Delete your `src/routes/products/page.tsx` and reload — the built-in page comes back. Nothing was forked.
105
+
106
+ ## FAQ
107
+
108
+ <AccordionGroup>
109
+ <Accordion title="Where do I find which slots a page exposes?">
110
+ Import the page from `@mercurjs/vendor/pages` or `@mercurjs/admin/pages` and let your editor's autocomplete list the attached members — every slot is a static property on the page component. The naming is consistent across pages: list pages expose `Table`/`Header`/`HeaderTitle`/`HeaderActions`/`HeaderCreateButton`/`DataTable`; detail pages expose `Main`/`Sidebar` plus one property per section.
111
+ </Accordion>
112
+ <Accordion title="Can I remove a built-in element, like the Create button?">
113
+ Yes — re-composition is declarative. Anything you don't render doesn't appear: re-declare `HeaderActions` with only your own buttons and omit `HeaderCreateButton`.
114
+ </Accordion>
115
+ <Accordion title="What about changing the table columns?">
116
+ `DataTable` is a single slot — you either keep it wholesale or replace it with your own table. For a different column set, replace the slot with your own component built on the shared `DataTable`/`useDataTable` primitives from the panel package.
117
+ </Accordion>
118
+ </AccordionGroup>
119
+
120
+ ## Next steps
121
+
122
+ <CardGroup cols={2}>
123
+ <Card title="Replace panel components" href="/rc/resources/tutorials/replace-panel-components">
124
+ Swap global chrome like the sidebar or topbar instead of a single page.
125
+ </Card>
126
+ <Card title="Add a custom API route" href="/rc/resources/tutorials/custom-api-route">
127
+ Back your custom page with a typed endpoint of your own.
128
+ </Card>
129
+ </CardGroup>
@@ -0,0 +1,116 @@
1
+ ---
2
+ title: "Replace panel components"
3
+ description: "Swap the sidebar, topbar actions, or store setup screen for your own components through dashboard SDK configuration."
4
+ ---
5
+
6
+ Some customizations aren't about one page — they change the panel's global chrome. For those, the dashboard SDK exposes a small set of **named component overrides**: you point the plugin config at your own file, and the panel renders your component in place of the built-in one everywhere it appears.
7
+
8
+ <Info>
9
+ **Choose the right tool.** A component override replaces one of four global layout slots across the whole panel. If you want to change a single page, [re-compose it](/rc/resources/tutorials/recompose-a-page) instead — and if you want to add a new screen, just [drop in a route](/rc/resources/tutorials/custom-panel-page). The decision guide in [Extending Panels](/rc/resources/customization/extending-panels#choosing-your-extension-mechanism) compares all three.
10
+ </Info>
11
+
12
+ ## What you'll build
13
+
14
+ A vendor portal with custom topbar actions (a help link and a status badge) and a custom main sidebar, configured entirely from `vite.config.ts`.
15
+
16
+ ## The available slots
17
+
18
+ Exactly four layout components can be replaced:
19
+
20
+ | Component | Where it renders |
21
+ |-----------|------------------|
22
+ | `MainSidebar` | Primary navigation sidebar on every main page |
23
+ | `SettingsSidebar` | Sidebar of the `/settings` section |
24
+ | `TopbarActions` | Action cluster on the right side of the top bar |
25
+ | `StoreSetup` | The store setup screen shown to new sellers (vendor portal) |
26
+
27
+ Anything else — a page, a section, a table — is customized through routes and compound components, not through overrides.
28
+
29
+ ## Set up the override
30
+
31
+ <Steps>
32
+ <Step title="Write the replacement component">
33
+ Create the component anywhere under `src/`. It must have a **default export**:
34
+
35
+ ```tsx apps/vendor/src/components/topbar-actions.tsx
36
+ import { Badge, Button } from "@medusajs/ui"
37
+
38
+ export default function TopbarActions() {
39
+ return (
40
+ <div className="flex items-center gap-x-2">
41
+ <Badge size="2xsmall" color="green">
42
+ All systems operational
43
+ </Badge>
44
+ <Button size="small" variant="transparent" asChild>
45
+ <a href="https://help.example.com" target="_blank" rel="noreferrer">
46
+ Help
47
+ </a>
48
+ </Button>
49
+ </div>
50
+ )
51
+ }
52
+ ```
53
+ </Step>
54
+ <Step title="Register it in the Vite config">
55
+ Component overrides live in the `components` option of `mercurDashboardPlugin`, in your panel app's `vite.config.ts`. Paths are **relative to `src/`**:
56
+
57
+ ```typescript apps/vendor/vite.config.ts
58
+ import { defineConfig } from 'vite'
59
+ import react from '@vitejs/plugin-react'
60
+ import { mercurDashboardPlugin } from '@mercurjs/dashboard-sdk'
61
+
62
+ export default defineConfig({
63
+ plugins: [
64
+ react(),
65
+ mercurDashboardPlugin({
66
+ medusaConfigPath: '../../packages/api/medusa-config.ts',
67
+ components: {
68
+ TopbarActions: 'components/topbar-actions',
69
+ MainSidebar: 'components/main-sidebar',
70
+ },
71
+ }),
72
+ ],
73
+ })
74
+ ```
75
+
76
+ The plugin resolves each path at build time and swaps your component in through the `virtual:mercur/components` module — no runtime registration, no context providers to wire.
77
+ </Step>
78
+ <Step title="Restart the dev server">
79
+ Vite config changes require a restart. After it, your components render everywhere their slots appear.
80
+ </Step>
81
+ </Steps>
82
+
83
+ <Tip>
84
+ Build overrides with `@medusajs/ui` components and Medusa UI color tokens so they match the rest of the panel. The panels ship no other UI library.
85
+ </Tip>
86
+
87
+ ## Verify
88
+
89
+ 1. Open the vendor portal — the top bar shows your badge and Help link on every page.
90
+ 2. Navigate between main pages and `/settings` — the override applies everywhere its slot renders.
91
+ 3. Remove the `components` entry and restart — the built-in components return. The originals were never modified.
92
+
93
+ ## FAQ
94
+
95
+ <AccordionGroup>
96
+ <Accordion title="If I replace MainSidebar, do my custom routes still show up in the menu?">
97
+ Only if your sidebar renders them. A `MainSidebar` override replaces the **entire** navigation sidebar, including the auto-generated menu items from route `config` exports — read them from `virtual:mercur/menu-items` if you want to keep automatic navigation. If you only want to add or reorder items, you don't need an override at all: the `config` export on route files (with `rank` and `nested`) covers that.
98
+ </Accordion>
99
+ <Accordion title="Can I override other components, like the login page or a form?">
100
+ No — these four slots are the complete list. The login flow, forms, and everything page-level are customized through drop-in routes and [compound re-composition](/rc/resources/tutorials/recompose-a-page).
101
+ </Accordion>
102
+ <Accordion title="Do overrides apply to both panels?">
103
+ Each panel app has its own `vite.config.ts`, so overrides are configured per panel. `StoreSetup` only exists in the vendor portal; the other three slots exist in both.
104
+ </Accordion>
105
+ </AccordionGroup>
106
+
107
+ ## Next steps
108
+
109
+ <CardGroup cols={2}>
110
+ <Card title="Re-compose a built-in page" href="/rc/resources/tutorials/recompose-a-page">
111
+ Change one page's composition instead of global chrome.
112
+ </Card>
113
+ <Card title="Extending Panels" href="/rc/resources/customization/extending-panels">
114
+ The full reference for routes, navigation, branding, and overrides.
115
+ </Card>
116
+ </CardGroup>
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: "Set up seller payouts"
3
+ description: "Take a seller from zero to paid: Stripe Connect onboarding, an order through fulfillment, capture, and the automated payout."
4
+ ---
5
+
6
+ Payouts are the last mile of a marketplace — the marketplace collects the customer's payment, deducts its commission, and transfers the remainder to the seller. In Mercur that pipeline is **fully automated**: once a seller is onboarded and an order is fulfilled, scheduled jobs and subscribers handle capture and transfer without any manual step. This tutorial follows one order through the entire pipeline.
7
+
8
+ <Info>
9
+ **Nothing pays out until the seller's account is `ACTIVE`.** Every stage of the pipeline checks the payout account status. A seller who skips onboarding can sell, but their orders sit uncaptured until the authorization window forces the issue — which is exactly why surfacing onboarding status in the vendor portal matters.
10
+ </Info>
11
+
12
+ ## What you'll build
13
+
14
+ A working payout loop: a seller with an active Stripe Connect account, one fulfilled order, a captured payment, and a payout record that settles via webhook.
15
+
16
+ ## Prerequisites
17
+
18
+ Stripe Connect must be configured first — provider registration, API keys, and **both** webhooks (payment and payout). Follow the [Stripe Connect integration guide](/rc/resources/integrations/stripe-connect) up to and including "Set up webhooks", then come back here. For local development, keep `stripe listen` forwarding running.
19
+
20
+ ## Run the pipeline
21
+
22
+ <Steps>
23
+ <Step title="Onboard the seller">
24
+ In the Vendor Portal, the seller opens **Settings → Payouts** and starts onboarding. Under the hood this creates a `PayoutAccount` (status `PENDING`) and an `Onboarding` record holding the Stripe onboarding link:
25
+
26
+ ```bash
27
+ curl -X POST http://localhost:9000/vendor/payout-accounts/<account-id>/onboarding \
28
+ -H "Authorization: Bearer <seller-token>" \
29
+ -H "Content-Type: application/json" \
30
+ -d '{ "context": { "return_url": "http://localhost:7001/settings/payouts" } }'
31
+ ```
32
+
33
+ The seller completes Stripe's hosted flow (identity, bank account) — in test mode, Stripe's test data completes it in a minute. When Stripe activates the account, the payout webhook delivers an `account.activated` event and Mercur flips the account to `ACTIVE`. No polling — the webhook is the source of truth.
34
+ </Step>
35
+ <Step title="Place and fulfill an order">
36
+ Place an order for one of the seller's listings, then in the Vendor Portal fulfill it. Fulfillment matters: by default, capture requires the order to reach `fulfilled` status (configurable via the payout module's `requiredFulfillmentStatus` option).
37
+ </Step>
38
+ <Step title="Watch the capture">
39
+ A scheduled job runs every 15 minutes looking for orders that are ready: payment `authorized`, seller `ACTIVE`, fulfillment status met, no payout yet. When the capture deadline approaches it emits `order.capture_requested`, and a subscriber captures the payment.
40
+
41
+ To move faster while testing, wait for the next 15-minute tick after fulfillment.
42
+
43
+ <Warning>
44
+ Payment authorizations expire — 7 days by default (`authorizationWindowMs`). Sellers who don't fulfill within the window (`sellerActionWindowMs`, 72h default) risk the capture buffer kicking in or the authorization expiring entirely. Tune these in the payout module options with your fulfillment SLAs in mind.
45
+ </Warning>
46
+ </Step>
47
+ <Step title="The payout lands">
48
+ Once per day (1 AM UTC) a job scans captured orders without payouts and emits `payout.requested` per order. The `createPayoutWorkflow` then:
49
+
50
+ 1. Loads the order with its commission lines.
51
+ 2. Calculates `payout_amount = order.total − total_commission`.
52
+ 3. Calls Stripe to create the transfer and records a `Payout` (status `PENDING`).
53
+
54
+ Stripe's webhook then walks the payout through `PROCESSING` → `PAID` (or `FAILED`).
55
+ </Step>
56
+ </Steps>
57
+
58
+ ## Verify
59
+
60
+ 1. **Account**: `GET /vendor/payout-accounts/<id>` returns `status: "ACTIVE"` after onboarding.
61
+ 2. **Capture**: after fulfillment plus one job tick, the order's payment shows as captured.
62
+ 3. **Payout**: `GET /admin/payouts` lists a payout for the order, with `amount` equal to the order total minus the commission lines from your [commission configuration](/rc/resources/tutorials/configure-commissions).
63
+ 4. **Vendor view**: the seller sees the payout and its status in the Vendor Portal's payout history.
64
+ 5. **Stripe**: the transfer appears on the connected account in the Stripe test dashboard.
65
+
66
+ ## FAQ
67
+
68
+ <AccordionGroup>
69
+ <Accordion title="What if the seller never completes onboarding?">
70
+ Their orders stay uncaptured. The capture job skips orders whose seller isn't `ACTIVE`, and once the authorization window lapses the payment expires (an `order.authorization_expired` event fires). Surface the onboarding status prominently and chase incomplete sellers early.
71
+ </Accordion>
72
+ <Accordion title="Why hasn't a payout appeared even though the order is captured?">
73
+ The payout job runs once per day at 1 AM UTC — a captured order waits for the next daily tick. Also check that no payout already exists for the order and that the seller's account is still `ACTIVE` (a `RESTRICTED` account pauses payouts until the provider clears it).
74
+ </Accordion>
75
+ <Accordion title="What do the payout statuses mean?">
76
+ `PENDING` — transfer initiated; `PROCESSING` — the provider is moving funds; `PAID` — settled; `FAILED` / `CANCELED` — the transfer didn't complete. All transitions after `PENDING` come from provider webhook events, so a stuck status usually means the payout webhook isn't reaching your API.
77
+ </Accordion>
78
+ </AccordionGroup>
79
+
80
+ ## Next steps
81
+
82
+ <CardGroup cols={2}>
83
+ <Card title="Payout" href="/rc/learn/payouts">
84
+ The full pipeline reference — statuses, jobs, webhook events, module options.
85
+ </Card>
86
+ <Card title="Stripe Connect" href="/rc/resources/integrations/stripe-connect">
87
+ Provider configuration, transfers vs payouts, refunds, and EU considerations.
88
+ </Card>
89
+ </CardGroup>
@@ -0,0 +1,67 @@
1
+ ---
2
+ title: "Telemetry"
3
+ description: "Learn about the anonymous usage data collected by the Mercur CLI"
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ The Mercur CLI collects **anonymous usage data** to help us understand how the CLI is used and improve the developer experience. This data is collected by default but can be easily disabled.
9
+
10
+ ## What We Collect
11
+
12
+ When you run CLI commands (`create`, `init`, `add`, `registry:build`), the following data is sent:
13
+
14
+ | Data | Description |
15
+ |------|-------------|
16
+ | Event type | Which command was run and its outcome |
17
+ | Node.js version | Your Node.js runtime version |
18
+ | Node environment | The `NODE_ENV` value |
19
+ | Mercur version | Version of `@mercurjs/cli` in your project |
20
+ | Medusa version | Version of `@medusajs/framework` in your project |
21
+ | Package manager | npm, yarn, pnpm, or bun |
22
+ | Project structure | Whether `src/` directory is used, alias prefix |
23
+ | System info | OS, platform, architecture, CPU model/speed/count, RAM |
24
+ | Environment | Whether running in WSL, Docker, or a TTY |
25
+ | Deployment vendor | Detected hosting platform (Railway, Fly.io, Heroku, etc.) |
26
+ | Project ID | SHA-256 hash (base64) of your git remote URL — **not the URL itself** |
27
+ | Project config | Contents of your `blocks.json` configuration |
28
+ | Email | **Only** if you voluntarily provided it during `create-mercur-app` |
29
+
30
+ ## What We Do NOT Collect
31
+
32
+ - Source code or file contents
33
+ - File names or directory structure
34
+ - Git history or commit messages
35
+ - Personal data (beyond the optional email above)
36
+
37
+ ## How to Opt Out
38
+
39
+ ### Using the CLI
40
+
41
+ ```bash
42
+ mercurjs telemetry --disable
43
+ ```
44
+
45
+ ### Using an environment variable
46
+
47
+ ```bash
48
+ export MERCUR_DISABLE_TELEMETRY=true
49
+ ```
50
+
51
+ This is useful for CI/CD environments or shared configurations.
52
+
53
+ ### Check current status
54
+
55
+ ```bash
56
+ mercurjs telemetry
57
+ ```
58
+
59
+ ## Where Data Goes
60
+
61
+ Telemetry events are sent to `https://telemetry.mercurjs.com`. The data is used exclusively by the Mercur team to prioritize features and fix issues.
62
+
63
+ ## Re-enabling Telemetry
64
+
65
+ ```bash
66
+ mercurjs telemetry --enable
67
+ ```