@spree/docs 0.1.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.
Files changed (183) hide show
  1. package/README.md +54 -0
  2. package/dist/api-reference/platform/authentication.md +38 -0
  3. package/dist/api-reference/store-api/authentication.md +188 -0
  4. package/dist/api-reference/store-api/errors.md +277 -0
  5. package/dist/api-reference/store-api/idempotency.md +129 -0
  6. package/dist/api-reference/store-api/introduction.md +34 -0
  7. package/dist/api-reference/store-api/localization.md +279 -0
  8. package/dist/api-reference/store-api/metadata.md +160 -0
  9. package/dist/api-reference/store-api/monetary-amounts.md +65 -0
  10. package/dist/api-reference/store-api/querying.md +399 -0
  11. package/dist/api-reference/store-api/rate-limitting.md +103 -0
  12. package/dist/api-reference/store-api/relations.md +185 -0
  13. package/dist/api-reference/storefront/authentication.md +88 -0
  14. package/dist/api-reference/tutorials/adyen-integration-guide-for-android.md +165 -0
  15. package/dist/api-reference/tutorials/adyen-integration-guide-for-ios.md +194 -0
  16. package/dist/api-reference/tutorials/quick-checkout-with-stripe.md +248 -0
  17. package/dist/api-reference/v2/fetching-multiple-resources.md +26 -0
  18. package/dist/api-reference/v2/filtering-and-sorting.md +53 -0
  19. package/dist/api-reference/v2/introduction.md +22 -0
  20. package/dist/api-reference/v2/pagination.md +37 -0
  21. package/dist/api-reference/webhooks-events.md +883 -0
  22. package/dist/developer/admin/admin.md +205 -0
  23. package/dist/developer/admin/authentication.md +59 -0
  24. package/dist/developer/admin/components.md +711 -0
  25. package/dist/developer/admin/custom-css.md +243 -0
  26. package/dist/developer/admin/custom-javascript.md +116 -0
  27. package/dist/developer/admin/extending-ui.md +1964 -0
  28. package/dist/developer/admin/form-builder.md +444 -0
  29. package/dist/developer/admin/helper-methods.md +531 -0
  30. package/dist/developer/admin/navigation.md +805 -0
  31. package/dist/developer/admin/tables.md +491 -0
  32. package/dist/developer/advanced/adding_spree_to_rails_app.md +106 -0
  33. package/dist/developer/cli/quickstart.md +137 -0
  34. package/dist/developer/contributing/creating-an-extension.md +258 -0
  35. package/dist/developer/contributing/developing-spree.md +339 -0
  36. package/dist/developer/contributing/quickstart.md +32 -0
  37. package/dist/developer/contributing/updating-extensions.md +67 -0
  38. package/dist/developer/core-concepts/addresses.md +265 -0
  39. package/dist/developer/core-concepts/adjustments.md +107 -0
  40. package/dist/developer/core-concepts/architecture.md +177 -0
  41. package/dist/developer/core-concepts/calculators.md +323 -0
  42. package/dist/developer/core-concepts/customers.md +230 -0
  43. package/dist/developer/core-concepts/events.md +624 -0
  44. package/dist/developer/core-concepts/imports-exports.md +698 -0
  45. package/dist/developer/core-concepts/inventory.md +191 -0
  46. package/dist/developer/core-concepts/markets.md +250 -0
  47. package/dist/developer/core-concepts/media.md +167 -0
  48. package/dist/developer/core-concepts/metafields.md +187 -0
  49. package/dist/developer/core-concepts/orders.md +328 -0
  50. package/dist/developer/core-concepts/payments.md +710 -0
  51. package/dist/developer/core-concepts/pricing.md +163 -0
  52. package/dist/developer/core-concepts/products.md +360 -0
  53. package/dist/developer/core-concepts/promotions.md +322 -0
  54. package/dist/developer/core-concepts/reports.md +206 -0
  55. package/dist/developer/core-concepts/search-filtering.md +237 -0
  56. package/dist/developer/core-concepts/shipments.md +212 -0
  57. package/dist/developer/core-concepts/slugs.md +111 -0
  58. package/dist/developer/core-concepts/staff-roles.md +123 -0
  59. package/dist/developer/core-concepts/store-credits-gift-cards.md +317 -0
  60. package/dist/developer/core-concepts/stores.md +117 -0
  61. package/dist/developer/core-concepts/taxes.md +135 -0
  62. package/dist/developer/core-concepts/translations.md +120 -0
  63. package/dist/developer/core-concepts/users.md +299 -0
  64. package/dist/developer/core-concepts/webhooks.md +378 -0
  65. package/dist/developer/create-spree-app/quickstart.md +158 -0
  66. package/dist/developer/customization/api.md +93 -0
  67. package/dist/developer/customization/authentication.md +88 -0
  68. package/dist/developer/customization/checkout.md +204 -0
  69. package/dist/developer/customization/configuration.md +55 -0
  70. package/dist/developer/customization/decorators.md +523 -0
  71. package/dist/developer/customization/dependencies.md +232 -0
  72. package/dist/developer/customization/emails.md +21 -0
  73. package/dist/developer/customization/extensions.md +92 -0
  74. package/dist/developer/customization/metadata.md +236 -0
  75. package/dist/developer/customization/model-preferences.md +130 -0
  76. package/dist/developer/customization/permissions.md +265 -0
  77. package/dist/developer/customization/quickstart.md +229 -0
  78. package/dist/developer/customization/routes.md +24 -0
  79. package/dist/developer/customization/v4/admin-panel.md +78 -0
  80. package/dist/developer/customization/v4/authentication.md +210 -0
  81. package/dist/developer/customization/v4/checkout.md +212 -0
  82. package/dist/developer/customization/v4/deface.md +251 -0
  83. package/dist/developer/customization/v4/images.md +86 -0
  84. package/dist/developer/customization/v4/storefront.md +450 -0
  85. package/dist/developer/deployment/assets.md +87 -0
  86. package/dist/developer/deployment/aws.md +335 -0
  87. package/dist/developer/deployment/caching.md +27 -0
  88. package/dist/developer/deployment/cdn.md +39 -0
  89. package/dist/developer/deployment/database.md +155 -0
  90. package/dist/developer/deployment/docker.md +128 -0
  91. package/dist/developer/deployment/emails.md +77 -0
  92. package/dist/developer/deployment/environment_variables.md +111 -0
  93. package/dist/developer/deployment/heroku.md +51 -0
  94. package/dist/developer/deployment/render.md +95 -0
  95. package/dist/developer/getting-started/quickstart.md +82 -0
  96. package/dist/developer/how-to/custom-payment-method.md +374 -0
  97. package/dist/developer/how-to/custom-promotion.md +373 -0
  98. package/dist/developer/how-to/custom-report.md +387 -0
  99. package/dist/developer/how-to/custom-search-provider.md +230 -0
  100. package/dist/developer/multi-store/quickstart.md +71 -0
  101. package/dist/developer/multi-store/setup.md +38 -0
  102. package/dist/developer/multi-tenant/configuration.md +41 -0
  103. package/dist/developer/multi-tenant/core-concepts.md +75 -0
  104. package/dist/developer/multi-tenant/installation.md +96 -0
  105. package/dist/developer/multi-tenant/quickstart.md +20 -0
  106. package/dist/developer/multi-vendor/installation.md +45 -0
  107. package/dist/developer/multi-vendor/quickstart.md +17 -0
  108. package/dist/developer/sdk/admin/quickstart.md +22 -0
  109. package/dist/developer/sdk/authentication.md +89 -0
  110. package/dist/developer/sdk/configuration.md +225 -0
  111. package/dist/developer/sdk/quickstart.md +82 -0
  112. package/dist/developer/sdk/store/account.md +67 -0
  113. package/dist/developer/sdk/store/cart-checkout.md +140 -0
  114. package/dist/developer/sdk/store/markets.md +151 -0
  115. package/dist/developer/sdk/store/payments.md +96 -0
  116. package/dist/developer/sdk/store/products.md +149 -0
  117. package/dist/developer/sdk/store/wishlists.md +52 -0
  118. package/dist/developer/security/pci_compliance.md +15 -0
  119. package/dist/developer/security/security_policy.md +68 -0
  120. package/dist/developer/storefront/blocks.md +285 -0
  121. package/dist/developer/storefront/custom-css.md +260 -0
  122. package/dist/developer/storefront/custom-javascript.md +166 -0
  123. package/dist/developer/storefront/helper-methods.md +1288 -0
  124. package/dist/developer/storefront/links.md +298 -0
  125. package/dist/developer/storefront/nextjs/architecture.md +150 -0
  126. package/dist/developer/storefront/nextjs/customization.md +141 -0
  127. package/dist/developer/storefront/nextjs/deployment.md +180 -0
  128. package/dist/developer/storefront/nextjs/quickstart.md +92 -0
  129. package/dist/developer/storefront/nextjs/spree-next-package.md +314 -0
  130. package/dist/developer/storefront/pages.md +163 -0
  131. package/dist/developer/storefront/sections.md +569 -0
  132. package/dist/developer/storefront/storefront.md +56 -0
  133. package/dist/developer/storefront/themes.md +161 -0
  134. package/dist/developer/tutorial/admin.md +134 -0
  135. package/dist/developer/tutorial/extending-models.md +380 -0
  136. package/dist/developer/tutorial/file-uploads.md +121 -0
  137. package/dist/developer/tutorial/introduction.md +33 -0
  138. package/dist/developer/tutorial/model.md +41 -0
  139. package/dist/developer/tutorial/page-builder.md +487 -0
  140. package/dist/developer/tutorial/rich-text.md +73 -0
  141. package/dist/developer/tutorial/seo.md +332 -0
  142. package/dist/developer/tutorial/storefront.md +352 -0
  143. package/dist/developer/tutorial/testing.md +558 -0
  144. package/dist/developer/upgrades/2.0-to-2.1.md +46 -0
  145. package/dist/developer/upgrades/2.1-to-2.2.md +59 -0
  146. package/dist/developer/upgrades/2.2-to-2.3.md +44 -0
  147. package/dist/developer/upgrades/2.3-to-2.4.md +42 -0
  148. package/dist/developer/upgrades/3.0-to-3.1.md +47 -0
  149. package/dist/developer/upgrades/3.1-to-3.2.md +34 -0
  150. package/dist/developer/upgrades/3.2-to-3.3.md +70 -0
  151. package/dist/developer/upgrades/3.3-to-3.4.md +36 -0
  152. package/dist/developer/upgrades/3.4-to-3.5.md +44 -0
  153. package/dist/developer/upgrades/3.5-to-3.6.md +40 -0
  154. package/dist/developer/upgrades/3.6-to-3.7.md +62 -0
  155. package/dist/developer/upgrades/3.7-to-4.0.md +152 -0
  156. package/dist/developer/upgrades/4.0-to-4.1.md +92 -0
  157. package/dist/developer/upgrades/4.1-to-4.2.md +109 -0
  158. package/dist/developer/upgrades/4.10-to-5.0.md +129 -0
  159. package/dist/developer/upgrades/4.2-to-4.3.md +100 -0
  160. package/dist/developer/upgrades/4.3-to-4.4.md +125 -0
  161. package/dist/developer/upgrades/4.4-to-4.5.md +94 -0
  162. package/dist/developer/upgrades/4.5-to-4.6.md +119 -0
  163. package/dist/developer/upgrades/4.6-to-4.7.md +39 -0
  164. package/dist/developer/upgrades/4.8-to-4.9.md +24 -0
  165. package/dist/developer/upgrades/4.9-to-4.10.md +24 -0
  166. package/dist/developer/upgrades/4.x-to-4.8.md +52 -0
  167. package/dist/developer/upgrades/5.0-to-5.1.md +28 -0
  168. package/dist/developer/upgrades/5.1-to-5.2.md +127 -0
  169. package/dist/developer/upgrades/5.2-to-5.3.md +338 -0
  170. package/dist/developer/upgrades/5.3-to-5.4.md +248 -0
  171. package/dist/developer/upgrades/quickstart.md +36 -0
  172. package/dist/integrations/analytics/google-analytics.md +64 -0
  173. package/dist/integrations/analytics/google-tag-manager.md +78 -0
  174. package/dist/integrations/integrations.md +39 -0
  175. package/dist/integrations/marketing/klaviyo.md +99 -0
  176. package/dist/integrations/payments/adyen.md +90 -0
  177. package/dist/integrations/payments/paypal.md +41 -0
  178. package/dist/integrations/payments/razorpay.md +45 -0
  179. package/dist/integrations/payments/stripe.md +109 -0
  180. package/dist/integrations/search/meilisearch.md +236 -0
  181. package/dist/integrations/sso-mfa-social-login/admin-dashboard.md +57 -0
  182. package/dist/integrations/sso-mfa-social-login/storefront.md +56 -0
  183. package/package.json +27 -0
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: Multi-Store Setup
3
+ sidebarTitle: Setup
4
+ ---
5
+
6
+ ## Root domain
7
+
8
+ You need to set a wildcard `root_domain` on the store to enable multi-store setup
9
+
10
+ ```ruby
11
+ Spree.root_domain = ENV.fetch('SPREE_ROOT_DOMAIN', 'lvh.me')
12
+ ```
13
+
14
+ This will be used to generate the store URLs, eg. `store1.lvh.me`, `store2.lvh.me`, etc.
15
+
16
+ `store1` part is the unique store `code` identifier, which is auto-generated based on the store name. You can change it in the admin panel in **Settings -> Domains**.
17
+
18
+ > **INFO:** If you later change the `root_domain`, you will need to run:
19
+ >
20
+ > ```ruby
21
+ Spree::Store.all.each(&:save)
22
+ ```
23
+ >
24
+ > to update the store URLs.
25
+
26
+ ## Creating new stores
27
+
28
+ After you restart your application, you will see a new option in the admin panel, under new item menu:
29
+
30
+ ![](/images/new_store_dropdown.png)
31
+
32
+ You can also create a new store from the rails console:
33
+
34
+ ```ruby
35
+ Spree::Store.create!(name: 'New Store')
36
+ ```
37
+
38
+ This will create a new store with the given name, code and URL.
@@ -0,0 +1,41 @@
1
+ ---
2
+ title: Spree Multi Tenant Configuration
3
+ sidebarTitle: Configuration
4
+ ---
5
+
6
+ Multi-tenant applications include additional configuration options. All configuration should be placed in `config/initializers/spree_multi_tenant.rb` file.
7
+
8
+ ### Root domain
9
+
10
+ To make multi-tenant, you need a root/wildcard domain, eg. `*.example.com`. Tenant stores are usually accessed via subdomains, eg. `store1.example.com`, `store2.example.com`, etc.
11
+
12
+ ```bash
13
+ Spree.root_domain = 'example.com'
14
+ ```
15
+
16
+ Still your tenants will be able to add custom domains, eg. `myflowerstore.com` via the Spree admin panel. Tenant subdomains are used only for admin panel access.
17
+
18
+ ### App subdomain
19
+
20
+ Application subdomains is used to access the application, eg. `app.example.com`. By default for existing tenants it will redirect them to their tenant subdomain, eg. `store1.example.com`. If you want, you can also use this as a tenant signup/store setup page, this is available under `app.example.com/tenants/new`.
21
+
22
+ You can customize the app subdomain by:
23
+
24
+ ```ruby
25
+ SpreeMultiTenant::Config[:app_subdomain] = 'admin'
26
+ ```
27
+
28
+ This will change `app.example.com` to `admin.example.com`.
29
+
30
+ ### Emails
31
+
32
+ Usually email providers, such as SendGrid, require emails to be send from a valid / verified email address, which will be your root domain.
33
+
34
+ ```ruby
35
+ SpreeMultiTenant::Config[:mail_from_name] = ENV.fetch('MAIL_FROM_NAME', 'Your SaaS Name')
36
+ SpreeMultiTenant::Config[:mail_from_address] = ENV.fetch('MAIL_FROM_ADDRESS', "support@#{Spree.root_domain}")
37
+ ```
38
+
39
+ > **INFO:** `mail_from_name` is only used in admin emails, such as admin staff invitations, exports, etc. For consumer facing emails, this will be your tenant store name, eg. 'My Flower Store` (or whatever they set in the store settings).
40
+ >
41
+ > Also, customer facing emails will use the tenant email address in `Reply-To` header.
@@ -0,0 +1,75 @@
1
+ ---
2
+ title: Multi-Tenant Core Concepts
3
+ sidebarTitle: Core Concepts
4
+ ---
5
+
6
+ ## Tenant class
7
+
8
+ The center of the multi-tenant architecture is the `Spree::Tenant` class. This is the highest level class in the multi-tenant system.
9
+
10
+ Every tenanted model includes a `tenant_id` column. This is used to identify which tenant a record belongs to. It's row-level multi-tenancy.
11
+
12
+ After creating a new tenant it will automatically create store and run [Spree seeds](https://github.com/spree/spree/tree/main/core/app/services/spree/seeds) to populate data such as countries, zones, tax rates, etc.
13
+
14
+ ## Tenanted models
15
+
16
+ All models that are tenanted inherit from `SpreeMultiTenant::Base` class. `spree_multi_tenant` automatically sets the `Spree.base_class` to `SpreeMultiTenant::Base` so all standard Spree models will be tenanted (with an exclusion of `Spree::CustomDomain`).
17
+
18
+ When creating a new model that you want to be tenanted remember to inherit from `SpreeMultiTenant::Base` and not from `Spree::Base` and add `tenant_id` column to the table, eg.
19
+
20
+ ```bash
21
+ bin/rails g model Spree::NewModel tenant:references name:string --parent SpreeMultiTenant::Base
22
+ ```
23
+
24
+ > **INFO:** You don't need to add `belongs_to :tenant` to the model, it's handled by gem.
25
+
26
+ ## Tenant selector
27
+
28
+ By default the current tenant is selected based on the subdomain or `Spree::CustomDomain`. The selector works in tandem with the default [Spree::Stores::FindCurrent](https://github.com/spree/spree/blob/main/core/app/finders/spree/stores/find_current.rb) finder.
29
+
30
+ First it finds the current store, and later sets the current tenant based on the store's `tenant_id`.
31
+
32
+ Tenant record is accessible in views and controllers as `current_tenant`. In models you can access it via `SpreeMultiTenant.current_tenant`.
33
+
34
+ > **INFO:** One tenant can have multiple stores. Calling `Spree::Store.default` will return the default store for the first tenant.
35
+
36
+ ## Code isolation
37
+
38
+ All code run when `SpreeMultiTenant.current_tenant` is set will be executed in the context of the tenant, what that means:
39
+
40
+ * all finder queries will always attach `tenant_id = <current_tenant.id>` to the query
41
+ * all writes will automatically set `tenant_id` to the current tenant ID (you don't need to do it manually)
42
+
43
+ > **WARNING:** [insert_all](https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-insert_all) / [upsert_all](https://api.rubyonrails.org/classes/ActiveRecord/Relation.html#method-i-upsert_all) methods will require you to manually set `tenant_id` to the desired value.
44
+
45
+ ## Background jobs
46
+
47
+ Background jobs enqueued when `SpreeMultiTenant.current_tenant` is set will be executed in the context of the tenant.
48
+
49
+ ## Enforce tenant context
50
+
51
+ Sometimes when you're not sure if the tenant context is active you can use `SpreeMultiTenant.with_tenant` to enforce it, eg.
52
+
53
+ ```ruby
54
+ SpreeMultiTenant.with_tenant(tenant) do
55
+ # all operations here will be executed in the context of the tenant
56
+ end
57
+ ```
58
+
59
+ ## Excluding tenant context
60
+
61
+ Sometimes you want to run a piece of code outside of the tenant context, for that you can use `SpreeMultiTenant.without_tenant`
62
+
63
+ ```ruby
64
+ SpreeMultiTenant.without_tenant do
65
+ # all operations here will be executed outside of the tenant context
66
+ end
67
+ ```
68
+
69
+ ## Command line
70
+
71
+ When using `bin/rails console` or `bin/rails runner` you can set the tenant context by:
72
+
73
+ ```ruby
74
+ SpreeMultiTenant.current_tenant = Spree::Store.find_by(code: 'my_store').tenant
75
+ ```
@@ -0,0 +1,96 @@
1
+ ---
2
+ title: Spree Multi Tenant Installation
3
+ sidebarTitle: Installation
4
+ description: Learn how to setup a multi-tenant eCommerce (SaaS) with Spree
5
+ ---
6
+
7
+ > **WARNING:** This installation instructions assume you have a clean Spree Starter installation and you've purchased the [Spree Enterprise Edition license](https://spreecommerce.org/pricing).
8
+ >
9
+ > For migrating existing application from single-tenant to multi-tenant, please contact us at [support@spreecommerce.org](mailto:support@spreecommerce.org).
10
+
11
+ ## Prerequisites
12
+
13
+ * You need to be on Spree 5.1+, we recommend using [spree_starter](https://github.com/spree/spree_starter) as a base for your application
14
+ * You need to have 2 environment variables set:
15
+ * `KEYGEN_ACCOUNT_ID`
16
+ * `KEYGEN_LICENSE_KEY`
17
+ * We support both PostgreSQL and MySQL databases
18
+
19
+ > **INFO:** Environment variables will be provided to you after purchasing the [Spree Enterprise Edition license](https://spreecommerce.org/pricing).
20
+
21
+ > **WARNING:** You will need to add these environment variables to your CI/CD pipeline and production environments.
22
+
23
+ ## Customer User Class
24
+
25
+ Please follow [Authentication](/docs/developer/customization/authentication) documentation to create a new user class.
26
+
27
+ Now we will need to make slight adjustments to the generated user class so it can work in a multi-tenant environment.
28
+
29
+ If you're using Devise, you will need to remove `:validatable` module. This module is responsible for validating the user's email uniqueness. We need to change it to validate it in the scope of the tenant.
30
+
31
+ Spree Multi-Tenant gem injects `SpreeMultiTenant::CustomerUserConcern` that handles that instead.
32
+
33
+ ## Admin User Class
34
+
35
+ For our multi-tenant setup we will need a separate Admin user class. Our standard User class will be only used for customer accounts which will be isolated by tenant.
36
+ Admin user classes will be shared across tenants allowing them to manage multiple tenants from a single admin panel.
37
+
38
+ Let's create a new model with Devise (unless you already have one):
39
+
40
+ ```bash
41
+ rails g devise Spree::AdminUser
42
+ ```
43
+
44
+ Replace the generated Devise code with the following:
45
+
46
+ ```ruby
47
+ class Spree::AdminUser < Spree::Base
48
+ # Include default devise modules. Others available are:
49
+ # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
50
+ devise :database_authenticatable, :registerable,
51
+ :recoverable, :rememberable, :validatable
52
+
53
+ # Spree modules
54
+ include Spree::UserMethods
55
+ end
56
+ ```
57
+
58
+ If you already have a custom Admin user class, you can add the following code to it:
59
+
60
+ ```ruby
61
+ # Spree modules
62
+ include Spree::UserMethods
63
+ ```
64
+
65
+ This will make sure that the Admin user class works well with Spree ecosystem.
66
+
67
+ Register new model in `config/initializers/spree.rb`:
68
+
69
+ ```ruby
70
+ Spree.admin_user_class = "Spree::AdminUser"
71
+ ```
72
+
73
+ ## Installing gems
74
+
75
+ 1. Add the following code to your `Gemfile`:
76
+
77
+ ```ruby
78
+ source "https://license:#{ENV['KEYGEN_LICENSE_KEY']}@rubygems.pkg.keygen.sh/#{ENV['KEYGEN_ACCOUNT_ID']}" do
79
+ gem 'spree_enterprise'
80
+ gem 'spree_multi_tenant'
81
+ end
82
+ ```
83
+
84
+ 2. Install gems:
85
+
86
+ ```bash
87
+ bundle install
88
+ ```
89
+
90
+ 3. Run generators:
91
+
92
+ ```bash
93
+ bundle exec rails g spree_enterprise:install && bundle exec rails g spree_multi_tenant:install
94
+ ```
95
+
96
+ > **INFO:** This will copy and run migrations for `spree_enterprise` and `spree_multi_tenant` gems.
@@ -0,0 +1,20 @@
1
+ ---
2
+ title: Building a Multi-Tenant Spree Application
3
+ sidebarTitle: Quickstart
4
+ ---
5
+
6
+ Spree out of the box is a single-tenant application. You can have multiple stores on the same instance of Spree, but they share the same products, admin user accounts and other resources.
7
+ Multi-Store Spree setup is recommended for running multiple brands or multiple language versions of the same brand on the same instance.
8
+
9
+ If you want to have a true multi-tenant application, you will need to purchase [Enterprise Edition license](https://spreecommerce.org/pricing) which includes `spree_multi_tenant` gem providing full multi-tenant support.
10
+
11
+ ## Multi-Store vs Multi-Tenant
12
+
13
+ To sum it up:
14
+
15
+ * Multi-Store setup is recommended for running multiple brands or multiple language versions of the same store
16
+ * Multi-Tenant allows you to create a SaaS application with multiple tenants, each of them with their own Spree instance
17
+
18
+ ## Setup SaaS application
19
+
20
+ [Follow the installation instructions](/developer/multi-tenant/installation) to setup a multi-tenant Spree application.
@@ -0,0 +1,45 @@
1
+ ---
2
+ title: Spree Multi Vendor Installation
3
+ sidebarTitle: Installation
4
+ description: Learn how to setup a multi-vendor marketplace with Spree
5
+ ---
6
+
7
+ > **WARNING:** This installation instructions assume you have purchased the [Spree Enterprise Edition license](https://spreecommerce.org/pricing).
8
+
9
+ ## Prerequisites
10
+
11
+ * You need to be on Spree 5.1+, we recommend using [spree_starter](https://github.com/spree/spree_starter) as a base for your application
12
+ * You need to have 2 environment variables set:
13
+ * `KEYGEN_ACCOUNT_ID`
14
+ * `KEYGEN_LICENSE_KEY`
15
+ * We support both PostgreSQL and MySQL databases
16
+ * Redis/Valkey for background jobs
17
+
18
+ > **INFO:** Environment variables will be provided to you after purchasing the [Spree Enterprise Edition license](https://spreecommerce.org/pricing).
19
+
20
+ > **WARNING:** You will need to add these environment variables to your CI/CD pipeline and production environments.
21
+
22
+ ## Installing gems
23
+
24
+ 1. Add the following code to your `Gemfile`:
25
+
26
+ ```ruby
27
+ source "https://license:#{ENV['KEYGEN_LICENSE_KEY']}@rubygems.pkg.keygen.sh/#{ENV['KEYGEN_ACCOUNT_ID']}" do
28
+ gem 'spree_enterprise'
29
+ gem 'spree_multi_vendor'
30
+ end
31
+ ```
32
+
33
+ 2. Install gems:
34
+
35
+ ```bash
36
+ bundle install
37
+ ```
38
+
39
+ 3. Run generators:
40
+
41
+ ```bash
42
+ bundle exec rails g spree_enterprise:install && bundle exec rails g spree_multi_vendor:install
43
+ ```
44
+
45
+ > **INFO:** This will copy and run migrations for `spree_enterprise` and `spree_multi_vendor` gems.
@@ -0,0 +1,17 @@
1
+ ---
2
+ title: Building a Multi-Vendor Marketplace with Spree
3
+ sidebarTitle: Quickstart
4
+ ---
5
+
6
+ If you want to have a true multi-vendor marketplace, you will need to purchase [Enterprise Edition license](https://spreecommerce.org/pricing) which includes `spree_multi_vendor` gem providing full multi-vendor support.
7
+
8
+ ## What is included in `spree_multi_vendor`
9
+
10
+ 1. **Ability to invite and manage vendors**, their products and orders
11
+ 2. Full fledged **vendor dashboard** where vendors can self-serve orders, products, manage their team, etc.
12
+ 3. White-label **Shopify Sales Channel application** allowing vendors to connect their Shopify stores, import products, shipping rates and receive orders to fulfill them like a regular order in their Shopify store.
13
+ 4. White-label **WooCommerce application** allowing vendors to connect their WooCommerce stores, import products, shipping rates and receive orders to fulfill them like a regular order in their WooCommerce store
14
+ 5. **Stripe Connect** integration allowing vendors to receive payments directly to their Stripe accounts, split payments between marketplace and vendors, automated payouts and more
15
+ 6. **Multi-party checkout** allowing customers to checkout with multiple vendors, split payments between them and receive separate invoices for each vendor
16
+ 7. **Flexible permission system** to tailor the marketplace to your needs (eg. disable/enable vendor panel features)
17
+ 8. **Vendor API** endpoints to allow vendors to manage their products, orders, etc.
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: Admin API
3
+ description: Manage your store programmatically with the Spree Admin SDK
4
+ ---
5
+
6
+ > **INFO:** The Admin API SDK is coming soon. The `client.admin` namespace is ready and will provide full access to administrative endpoints for managing products, orders, customers, and store settings.
7
+
8
+ ## Preview
9
+
10
+ ```typescript
11
+ import { createClient } from '@spree/sdk';
12
+
13
+ const client = createClient({
14
+ baseUrl: 'https://api.mystore.com',
15
+ secretKey: 'spree_sk_xxx', // Admin API requires a secret key
16
+ });
17
+
18
+ // Admin endpoints will be available under client.admin.*
19
+ // client.admin.products.list()
20
+ // client.admin.orders.list()
21
+ // client.admin.customers.list()
22
+ ```
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: Authentication
3
+ description: Authentication modes and guest checkout with the Spree SDK
4
+ ---
5
+
6
+ The SDK supports multiple authentication modes depending on your use case. For a full overview of the API authentication methods, see the [Store API Authentication](/api-reference/store-api/authentication) reference.
7
+
8
+ ## Publishable Key Only (Guest/Public Access)
9
+
10
+ Use a publishable API key for public endpoints like browsing products:
11
+
12
+ ```typescript
13
+ import { createClient } from '@spree/sdk'
14
+
15
+ const client = createClient({
16
+ baseUrl: 'http://localhost:3000',
17
+ publishableKey: 'spree_pk_xxx',
18
+ })
19
+ ```
20
+
21
+
22
+ ```typescript
23
+ // Public endpoints work without user authentication
24
+ const products = await client.products.list()
25
+ ```
26
+
27
+ ## Publishable Key + JWT (Authenticated Customer)
28
+
29
+ For authenticated customer actions like viewing orders or managing addresses:
30
+
31
+ ```typescript
32
+ // Login to get a JWT token
33
+ const { token, user } = await client.auth.login({
34
+ email: 'customer@example.com',
35
+ password: 'password123',
36
+ })
37
+
38
+ // Use the token for authenticated requests
39
+ const orders = await client.customer.orders.list({}, { token })
40
+ ```
41
+
42
+
43
+ ```typescript
44
+ // Refresh token when needed
45
+ const newTokens = await client.auth.refresh({ token })
46
+ ```
47
+
48
+ ## Register New Customer
49
+
50
+ ```typescript
51
+ const { token, user } = await client.customers.create({
52
+ email: 'new@example.com',
53
+ password: 'password123',
54
+ password_confirmation: 'password123',
55
+ first_name: 'John',
56
+ last_name: 'Doe',
57
+ })
58
+ ```
59
+
60
+ ## Guest Checkout
61
+
62
+ For guest checkout, use the `token` returned when creating a cart. The SDK automatically sends it via the `x-spree-token` header:
63
+
64
+ ```typescript
65
+ // Create a cart (guest)
66
+ const cart = await client.carts.create()
67
+
68
+ // Use spreeToken for all cart and checkout operations
69
+ const options = { spreeToken: cart.token }
70
+
71
+ // Add items
72
+ await client.carts.items.create(cart.id, {
73
+ variant_id: 'variant_abc123',
74
+ quantity: 1,
75
+ }, options)
76
+ ```
77
+
78
+
79
+ ```typescript
80
+ const options = { spreeToken: cart.token }
81
+
82
+ // Update cart with email
83
+ await client.carts.update(cart.id, {
84
+ email: 'guest@example.com',
85
+ }, options)
86
+
87
+ // Complete checkout
88
+ await client.carts.complete(cart.id, options)
89
+ ```
@@ -0,0 +1,225 @@
1
+ ---
2
+ title: Configuration
3
+ description: Localization, error handling, TypeScript types, and custom fetch
4
+ ---
5
+
6
+ ## Localization & Currency
7
+
8
+ Pass locale and currency headers with any request. For full details, see the [Localization](/api-reference/store-api/localization) reference.
9
+
10
+ ```typescript
11
+ // Set locale and currency per request
12
+ const products = await client.products.list({}, {
13
+ locale: 'fr',
14
+ currency: 'EUR',
15
+ country: 'FR',
16
+ })
17
+ ```
18
+
19
+
20
+ ```typescript
21
+ // Works with all endpoints
22
+ const category = await client.categories.get('clothing/shirts', {
23
+ expand: ['ancestors'],
24
+ }, {
25
+ locale: 'de',
26
+ currency: 'EUR',
27
+ })
28
+ ```
29
+
30
+ ## Error Handling
31
+
32
+ ```typescript
33
+ import { SpreeError } from '@spree/sdk';
34
+
35
+ try {
36
+ await client.products.get('non-existent');
37
+ } catch (error) {
38
+ if (error instanceof SpreeError) {
39
+ console.log(error.code); // 'record_not_found'
40
+ console.log(error.message); // 'Product not found'
41
+ console.log(error.status); // 404
42
+ console.log(error.details); // Validation errors (if any)
43
+ }
44
+ }
45
+ ```
46
+
47
+ ## Custom Fetch
48
+
49
+ You can provide a custom fetch implementation:
50
+
51
+ ```typescript
52
+ import { createClient } from '@spree/sdk';
53
+
54
+ const client = createClient({
55
+ baseUrl: 'https://api.mystore.com',
56
+ publishableKey: 'spree_pk_xxx',
57
+ fetch: customFetchImplementation,
58
+ });
59
+ ```
60
+
61
+ ## Monetary Amounts
62
+
63
+ All monetary values in the API are returned as **strings** (e.g., `"29.99"`, `"0.0"`), not numbers. This preserves decimal precision and avoids floating-point rounding issues.
64
+
65
+ ```typescript
66
+ const order = await client.orders.get('or_abc123', {}, { token });
67
+
68
+ // Monetary fields are strings
69
+ order.total; // "129.99"
70
+ order.item_total; // "99.99"
71
+ order.delivery_total; // "10.00"
72
+ order.tax_total; // "20.00"
73
+
74
+ // Display fields include currency formatting
75
+ order.display_total; // "$129.99"
76
+
77
+ // Convert to number when needed for calculations
78
+ const total = parseFloat(order.total);
79
+ ```
80
+
81
+ This applies to all monetary fields across all types: `Order`, `LineItem`, `Fulfillment`, `Payment`, `GiftCard`, `Price`, etc.
82
+
83
+ ## TypeScript Support
84
+
85
+ The SDK includes full TypeScript support with generated types from the API serializers:
86
+
87
+ ```typescript
88
+ import type {
89
+ Product,
90
+ Order,
91
+ Cart,
92
+ Variant,
93
+ Category,
94
+ LineItem,
95
+ Address,
96
+ Customer,
97
+ PaginatedResponse,
98
+ } from '@spree/sdk';
99
+
100
+ // All responses are fully typed
101
+ const products: PaginatedResponse<Product> = await client.products.list();
102
+ const category: Category = await client.categories.get('clothing');
103
+ ```
104
+
105
+ ## Available Types
106
+
107
+ All types are exported as unprefixed names (e.g., `Product`, `Order`). Legacy `Store*` prefixed aliases (e.g., `StoreProduct`) are still available for backward compatibility.
108
+
109
+ ### Core Types
110
+ - `Product` - Product data
111
+ - `Variant` - Variant data
112
+ - `Cart` - Cart data (uses `cart_` prefixed IDs)
113
+ - `Order` - Completed order data (uses `or_` prefixed IDs)
114
+ - `LineItem` - Line item in cart
115
+ - `Category` - Category
116
+ - `Country` - Country with states
117
+ - `State` - State/province
118
+ - `Address` - Customer address
119
+ - `Customer` - Customer profile
120
+ - `Market` - Market configuration (currency, locales, countries)
121
+
122
+ ### Commerce Types
123
+ - `Payment` - Payment record
124
+ - `PaymentMethod` - Payment method
125
+ - `PaymentSession` - Provider-agnostic payment session
126
+ - `Fulfillment` - Fulfillment record
127
+ - `DeliveryRate` - Delivery rate option
128
+ - `DeliveryMethod` - Delivery method
129
+ - `CreditCard` - Saved credit card
130
+ - `GiftCard` - Gift card
131
+ - `Discount` - Discount applied to a cart or order
132
+
133
+ ### Product Types
134
+ - `Media` - Product media (images, videos)
135
+ - `Price` - Price data
136
+ - `OptionType` - Option type (e.g., Size, Color)
137
+ - `OptionValue` - Option value (e.g., Small, Red)
138
+ - `DigitalLink` - Digital download link
139
+ - `Metafield` - Custom metafield data
140
+
141
+ ### Wishlist Types
142
+ - `Wishlist` - Wishlist
143
+ - `WishlistItem` - Wishlist item
144
+
145
+ ### Client Types
146
+ - `Client` - Main client interface
147
+ - `StoreClient` - Store API client class
148
+ - `ClientConfig` - Client configuration
149
+ - `RequestOptions` - Per-request options
150
+ - `RetryConfig` - Retry behavior configuration
151
+
152
+ ### Utility Types
153
+ - `PaginatedResponse<T>` - Paginated API response
154
+ - `ListResponse<T>` - List API response
155
+ - `AuthTokens` - JWT tokens from login
156
+ - `AddressParams` - Address input parameters
157
+ - `UpdateCartParams` - Cart update parameters
158
+ - `CreatePaymentParams` - Direct payment creation parameters
159
+ - `CreatePaymentSessionParams` - Payment session creation parameters
160
+ - `UpdatePaymentSessionParams` - Payment session update parameters
161
+ - `CompletePaymentSessionParams` - Payment session completion parameters
162
+ - `ProductFiltersResponse` - Product filters response
163
+ - `CheckoutRequirement` - Checkout requirement (`{ step, field, message }`)
164
+
165
+ ## Extending Types
166
+
167
+ All generated SDK types are TypeScript `interface`s, which means you can extend them via [declaration merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html) when you customize API serializers on the backend.
168
+
169
+ ### Example: Adding a Brand to Products
170
+
171
+ If you've customized the `ProductSerializer` in your app to include a `brand_id` attribute:
172
+
173
+ ```ruby
174
+ # app/serializers/my_store/product_serializer.rb
175
+ module MyStore
176
+ class ProductSerializer < Spree::Api::V3::ProductSerializer
177
+ typelize brand_id: :string
178
+
179
+ attribute :brand_id do |product|
180
+ product.brand&.prefixed_id
181
+ end
182
+ end
183
+ end
184
+
185
+ # config/initializers/spree.rb
186
+ Spree.api.product_serializer = MyStore::ProductSerializer
187
+ ```
188
+
189
+ You can extend the SDK type in your frontend code so TypeScript knows about the new field:
190
+
191
+ ```typescript
192
+ // types/spree.d.ts
193
+ declare module '@spree/sdk' {
194
+ interface Product {
195
+ brand_id: string;
196
+ }
197
+ }
198
+ ```
199
+
200
+ Now `brand_id` is available on every `Product` across your app — no type casting needed:
201
+
202
+ ```typescript
203
+ const products = await client.products.list();
204
+ products.data.forEach((product) => {
205
+ console.log(product.brand_id); // fully typed
206
+ });
207
+ ```
208
+
209
+ ### Extending Zod Schemas
210
+
211
+ If you use the SDK's Zod schemas for runtime validation, extend them with `.extend()`:
212
+
213
+ ```typescript
214
+ import { z } from 'zod';
215
+ import { ProductSchema } from '@spree/sdk/zod';
216
+
217
+ const MyProductSchema = ProductSchema.extend({
218
+ brand_id: z.string(),
219
+ });
220
+
221
+ // Use for runtime validation
222
+ const product = MyProductSchema.parse(apiResponse);
223
+ ```
224
+
225
+ > **NOTE:** Declaration merging only affects TypeScript types (compile-time). Zod schemas perform runtime validation and must be extended separately if you need validation of custom fields.