@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,323 @@
1
+ ---
2
+ title: Calculators
3
+ ---
4
+
5
+ ## Overview
6
+
7
+ ### Calculator Model Diagram
8
+
9
+ ```mermaid
10
+ erDiagram
11
+ Calculator {
12
+ string type
13
+ string calculable_type
14
+ text preferences
15
+ }
16
+
17
+ TaxRate {
18
+ string name
19
+ decimal amount
20
+ boolean included_in_price
21
+ }
22
+
23
+ ShippingMethod {
24
+ string name
25
+ string display_on
26
+ }
27
+
28
+ PromotionAction {
29
+ string type
30
+ }
31
+
32
+ Adjustment {
33
+ decimal amount
34
+ string label
35
+ }
36
+
37
+ TaxRate ||--|| Calculator : "has one"
38
+ ShippingMethod ||--|| Calculator : "has one"
39
+ PromotionAction ||--|| Calculator : "has one"
40
+ TaxRate ||--o{ Adjustment : "creates"
41
+ ShippingMethod ||--o{ ShippingRate : "calculates"
42
+ PromotionAction ||--o{ Adjustment : "creates"
43
+ ```
44
+
45
+ **Key relationships:**
46
+ - **Calculator** computes amounts for various features
47
+ - Used by **[Tax Rates](/developer/core-concepts/taxes)** to calculate tax amounts
48
+ - Used by **[Shipping Methods](/developer/core-concepts/shipments)** to calculate shipping costs
49
+ - Used by **[Promotion Actions](/developer/core-concepts/promotions)** to calculate discounts
50
+ - Calculators store preferences (rates, percentages, etc.) for their calculations
51
+
52
+ Spree makes extensive use of the `Spree::Calculator` model and there are several subclasses provided to deal with various types of calculations flat rate, percentage discount, sales tax, VAT, etc. All calculators extend the `Spree::Calculator` class and must provide the following methods:
53
+
54
+ ```ruby
55
+ def self.description
56
+ # Human readable description of the calculator
57
+ end
58
+
59
+ def compute(object=nil)
60
+ # Returns the value after performing the required calculation
61
+ end
62
+ ```
63
+
64
+ Calculators link to a `calculable` object, which are typically one of `Spree::ShippingMethod`, `Spree::TaxRate`, or `Spree::Promotion::Actions::CreateAdjustment`. These three classes use the `Spree::Core::CalculatedAdjustment` module described below to provide an easy way to calculate adjustments for their objects.
65
+
66
+ ## Available Calculators
67
+
68
+ The following are descriptions of the currently available calculators in Spree. If you would like to add your own, please see the [Creating a New Calculator](#creating-a-new-calculator) section.
69
+
70
+ ### Default Tax
71
+
72
+ For information about this calculator, please read the [Taxes](/developer/core-concepts/taxes) guide.
73
+
74
+ ### Flat Percent Per Item Total
75
+
76
+ This calculator has one preference: `flat_percent` and can be set like this:
77
+
78
+ ```ruby
79
+ calculator.preferred_flat_percent = 10
80
+ ```
81
+
82
+ This calculator takes an order and calculates an amount using this calculation:
83
+
84
+ ```ruby
85
+ [item total] x [flat percentage]
86
+ ```
87
+
88
+ For example, if an order had an item total of `$31` and the calculator was configured to have a flat percent amount of `10`, the discount would be `$3.10`, because `$31 x 10% = $3.10`.
89
+
90
+ ### Flat Rate
91
+
92
+ This calculator can be used to provide a flat rate discount.
93
+
94
+ This calculator has two preferences: `amount` and `currency`. These can be set like this:
95
+
96
+ ```ruby
97
+ calculator.preferred_amount = 10
98
+ calculator.currency = "USD"
99
+ ```
100
+
101
+ The currency for this calculator is used to check to see if a shipping method is available for an order. If an order's currency does not match the shipping method's currency, then that shipping method will not be displayed on the frontend.
102
+
103
+ This calculator can take any object and will return simply the preferred amount.
104
+
105
+ ### Flexi Rate
106
+
107
+ This calculator is typically used for promotional discounts when you want a specific discount for the first product, and then subsequent discounts for other products, up to a certain amount.
108
+
109
+ This calculator takes three preferences:
110
+
111
+ * `first_item`: The discounted price of the first items.
112
+ * `additional_item`: The discounted price of subsequent items.
113
+ * `max_items`: The maximum number of items this discount applies to.
114
+
115
+ The calculator computes based on this:
116
+
117
+ ```text
118
+ [first item discount] + (([items_count*] - 1) x [additional item discount])
119
+ ```
120
+
121
+ * up to the `max_items`
122
+
123
+ Thus, if you have ten items in your shopping cart, your `first_item` preference is set to `$10`, your `additional_items` preference is set to `$5`, and your `max_items` preference is set to `4`, the total discount would be `$25`:
124
+
125
+ * `$10` for the first item
126
+ * `$5` for each of the `3` subsequent items: `$5 \* 3 = $15`
127
+ * `$0` for the remaining `6` items
128
+
129
+ ### Per Item
130
+
131
+ The Per Item calculator computes a value for every item within an order. This is useful for providing a discount for a specific product, without it affecting others.
132
+
133
+ This calculator takes two preferences:
134
+
135
+ * `amount`: The amount per item to calculate.
136
+ * `currency`: The currency for this calculator.
137
+
138
+ This calculator depends on its `calculable` responding to a `promotion` method, which should return a `Spree::Promotion` or similar object. This object should then return a list of rules, which should respond to a `products` method. This is used to return a result of matching products.
139
+
140
+ The list of matching products is compared against the line items for the order being calculated. If any of the matching products are included in the order, they are eligible for this calculator. The calculation is this:
141
+
142
+ \[matching product quantity\] x \[amount\]
143
+
144
+ Every matching product within an order will add to the calculator's total. For example, assuming the calculator has an `amount` of 5 and there's an order with the following line items:
145
+
146
+ * Product A: `$15.00` x `2` within matching products
147
+ * Product B: `$10.00` x `1` within matching products
148
+ * Product C: `$20.00` x `4` excluded from matching products
149
+
150
+ The calculation would be:
151
+
152
+ ```text
153
+ = (2 x 5) + (1 x 5)
154
+ = 10 + 5
155
+ ```
156
+
157
+ meaning the calculator will compute an amount of 15.
158
+
159
+ ### Percent Per Item
160
+
161
+ The Percent Per Item calculator works in a near-identical fashion to the [Per Item Calculator](#per-item), with the exception that rather than providing a flat-rate per item, it is a percentage.
162
+
163
+ Assuming a calculator amount of 10% and an order such as this:
164
+
165
+ * Product A: $15.00 x 2 within matching products
166
+ * Product B: $10.00 x 1 within matching products
167
+ * Product C: $20.00 x 4 excluded from matching products
168
+
169
+ The calculation would be:
170
+
171
+ ```text
172
+ = ($15 x 2 x 10%) + ($10 x 10%)
173
+ = ($30 x 10%) + ($10 x 10%)
174
+ = $3 + $1
175
+ ```
176
+
177
+ The calculator will calculate a discount of $4.
178
+
179
+ ### Price Sack
180
+
181
+ The Price Sack calculator is useful for when you want to provide a discount for an order which is over a certain price. The calculator has four preferences:
182
+
183
+ * `minimal_amount`: The minimum amount for the line items total to trigger the calculator.
184
+ * `discount_amount`: The amount to discount from the order if the line items total is equal to or greater than the `minimal_amount`.
185
+ * `normal_amount`: The amount to discount from the order if the line items total is less than the `minimal_amount`.
186
+ * `currency`: The currency for this calculator. Defaults to the store currency
187
+
188
+ Suppose you have a Price Sack calculator with a `minimal_amount` preference of `$50`, a `normal_amount` preference of `$2`, and a `discount_amount` of `$5`. An order with a line items total of `$60` would result in a discount of `$5` for the whole order. An order of `$20` would result in a discount of `$2`.
189
+
190
+ ## Creating a New Calculator
191
+
192
+ To create a new calculator for Spree, you need to do two things. The first is to inherit from the `Spree::Calculator` class and define `description` and `compute` methods on that class:
193
+
194
+ ```ruby
195
+ class CustomCalculator < Spree::Calculator
196
+ def self.description
197
+ # Human readable description of the calculator
198
+ end
199
+
200
+ def compute(object=nil)
201
+ # Returns the value after performing the required calculation
202
+ end
203
+ end
204
+ ```
205
+
206
+ If you are creating a new calculator for shipping methods, please be aware that you need to inherit from `Spree::ShippingCalculator` instead, and define a `compute_package` method:
207
+
208
+ ```ruby
209
+ class CustomCalculator < Spree::ShippingCalculator
210
+ def self.description
211
+ # Human readable description of the calculator
212
+ end
213
+
214
+ def compute_package(package)
215
+ # Returns the value after performing the required calculation
216
+ end
217
+ end
218
+ ```
219
+
220
+ The second thing is to register this calculator as a tax, shipping, or promotion adjustment calculator by calling code like this at the end of `config/initializers/spree.rb` inside your application `config` variable defined for brevity:
221
+
222
+ **Spree 5.2+:**
223
+
224
+ ```ruby config/initializers/spree.rb
225
+ Rails.application.config.after_initialize do
226
+ Spree.calculators.tax_rates << CustomCalculator
227
+ Spree.calculators.shipping_methods << CustomCalculator
228
+ Spree.calculators.promotion_actions_create_adjustments << CustomCalculator
229
+ end
230
+ ```
231
+
232
+ **Spree 5.1 and below:**
233
+
234
+ ```ruby config/initializers/spree.rb
235
+ Rails.application.config.spree.calculators.tax_rates << CustomCalculator
236
+ Rails.application.config.spree.calculators.shipping_methods << CustomCalculator
237
+ Rails.application.config.spree.calculators.promotion_actions_create_adjustments << CustomCalculator
238
+ ```
239
+
240
+
241
+ For example if your calculator is placed in `app/models/spree/calculator/shipping/my_own_calculator.rb` you should call:
242
+
243
+ **Spree 5.2+:**
244
+
245
+ ```ruby config/initializers/spree.rb
246
+ Rails.application.config.after_initialize do
247
+ Spree.calculators.shipping_methods << Spree::Calculator::Shipping::MyOwnCalculator
248
+ end
249
+ ```
250
+
251
+ **Spree 5.1 and below:**
252
+
253
+ ```ruby config/initializers/spree.rb
254
+ Rails.application.config.spree.calculators.shipping_methods << Spree::Calculator::Shipping::MyOwnCalculator
255
+ ```
256
+
257
+
258
+ ### Determining Availability
259
+
260
+ By default, all shipping method calculators are available at all times. If you wish to make this dependent on something from the order, you can re-define the `available?` method inside your calculator:
261
+
262
+ ```ruby app/models/custom_calculator.rb
263
+ class CustomCalculator < Spree::Calculator
264
+ def available?(object)
265
+ object.currency == "USD"
266
+ end
267
+ end
268
+ ```
269
+
270
+ ## Calculated Adjustments
271
+
272
+ If you wish to use Spree's calculator functionality for your own application, you can include the `Spree::Core::CalculatedAdjustments` module into a model of your choosing.
273
+
274
+ ```ruby app/models/plan.rb
275
+ class Plan < ActiveRecord::Base
276
+ include Spree::Core::CalculatedAdjustments
277
+ end
278
+ ```
279
+
280
+ To have calculators available for this class, you will need to register them:
281
+
282
+ **Spree 5.2+:**
283
+
284
+ ```ruby config/initializers/spree.rb
285
+ Rails.application.config.after_initialize do
286
+ Spree.calculators.plans << CustomCalculator
287
+ end
288
+ ```
289
+
290
+ **Spree 5.1 and below:**
291
+
292
+ ```ruby config/initializers/spree.rb
293
+ Rails.application.config.spree.calculators.plans << CustomCalculator
294
+ ```
295
+
296
+
297
+ Then you can access these calculators by calling this method:
298
+
299
+ ```ruby
300
+ Plan.calculators
301
+ ```
302
+
303
+ Using this method, you can then display the calculators as you please. Each object for this new class will need to have a calculator associated so that adjustments can be calculated on them.
304
+
305
+ This module provides a `has_one` association to a `calculator` object, as well as some convenience helpers for creating and updating adjustments for objects. Assuming that an object has a calculator associated with it first, creating an adjustment is simple:
306
+
307
+ ```ruby
308
+ plan.create_adjustment("#{plan.name}", <target object>, <calculable object>)
309
+ ```
310
+
311
+ To update this adjustment:
312
+
313
+ ```ruby
314
+ plan.update_adjustment(<adjustment object>, <calculable object>)
315
+ ```
316
+
317
+ To work out what the calculator would compute an amount to be:
318
+
319
+ ```ruby
320
+ plan.compute_amount(<calculable object>)
321
+ ```
322
+
323
+ `create_adjustment`, `update_adjustment` and `compute_amount` will call `compute` on the `Calculator` object. This `calculable` amount is whatever object your `CustomCalculator` class supports.
@@ -0,0 +1,230 @@
1
+ ---
2
+ title: Customers
3
+ description: Customer accounts — registration, authentication, profiles, and guest checkout
4
+ ---
5
+
6
+ ## Overview
7
+
8
+ Customers interact with your store through the Store API. They can register, log in, manage their profile, and view order history.
9
+
10
+ ```mermaid
11
+ erDiagram
12
+ Customer ||--o{ Order : "places"
13
+ Customer ||--o{ Address : "has many"
14
+ Customer ||--o{ Wishlist : "has many"
15
+ Customer ||--o{ StoreCredit : "has many"
16
+ Customer ||--o{ PaymentSource : "has many"
17
+
18
+ Customer {
19
+ string id
20
+ string email
21
+ string first_name
22
+ string last_name
23
+ }
24
+
25
+ Order {
26
+ string number
27
+ string state
28
+ }
29
+
30
+ Address {
31
+ string firstname
32
+ string lastname
33
+ string address1
34
+ string city
35
+ }
36
+
37
+ Wishlist {
38
+ string name
39
+ boolean is_default
40
+ }
41
+ ```
42
+
43
+ ## Registration
44
+
45
+
46
+ ```typescript SDK
47
+ const { token, user } = await client.customers.create({
48
+ email: 'john@example.com',
49
+ password: 'password123',
50
+ password_confirmation: 'password123',
51
+ first_name: 'John',
52
+ last_name: 'Doe',
53
+ })
54
+ // token => JWT token for subsequent authenticated requests
55
+ // user => { id: "usr_xxx", email: "john@example.com", first_name: "John", ... }
56
+ ```
57
+
58
+ ```bash cURL
59
+ curl -X POST 'https://api.mystore.com/api/v3/store/customers' \
60
+ -H 'X-Spree-Api-Key: spree_pk_xxx' \
61
+ -H 'Content-Type: application/json' \
62
+ -d '{
63
+ "email": "john@example.com",
64
+ "password": "password123",
65
+ "password_confirmation": "password123",
66
+ "first_name": "John",
67
+ "last_name": "Doe"
68
+ }'
69
+ ```
70
+
71
+
72
+ ## Login
73
+
74
+
75
+ ```typescript SDK
76
+ const { token, user } = await client.auth.login({
77
+ email: 'john@example.com',
78
+ password: 'password123',
79
+ })
80
+ // Use the token for authenticated requests
81
+ ```
82
+
83
+ ```bash cURL
84
+ curl -X POST 'https://api.mystore.com/api/v3/store/auth/login' \
85
+ -H 'Authorization: Bearer spree_pk_xxx' \
86
+ -H 'Content-Type: application/json' \
87
+ -d '{
88
+ "email": "john@example.com",
89
+ "password": "password123"
90
+ }'
91
+ ```
92
+
93
+
94
+ The response includes a JWT `token` and a `user` object. Pass the token in subsequent requests via the `Authorization: Bearer <token>` header.
95
+
96
+ ## Token Refresh
97
+
98
+ Refresh an expiring token to keep the session alive:
99
+
100
+
101
+ ```typescript SDK
102
+ const { token } = await client.auth.refresh({
103
+ token: existingToken,
104
+ })
105
+ ```
106
+
107
+ ```bash cURL
108
+ curl -X POST 'https://api.mystore.com/api/v3/store/auth/refresh' \
109
+ -H 'Authorization: Bearer <jwt_token>'
110
+ ```
111
+
112
+
113
+ ## Password Reset
114
+
115
+ Password reset is a two-step flow. First, request a reset email. Then, use the token from the email to set a new password.
116
+
117
+ ### Step 1: Request Reset
118
+
119
+
120
+ ```typescript SDK
121
+ await client.customer.passwordResets.create({
122
+ email: 'john@example.com',
123
+ redirect_url: 'https://myshop.com/reset-password',
124
+ })
125
+ // Always returns { message: "..." } — even if the email doesn't exist
126
+ // This prevents email enumeration
127
+ ```
128
+
129
+ ```bash cURL
130
+ curl -X POST 'https://api.mystore.com/api/v3/store/customer/password_resets' \
131
+ -H 'X-Spree-Api-Key: spree_pk_xxx' \
132
+ -H 'Content-Type: application/json' \
133
+ -d '{
134
+ "email": "john@example.com",
135
+ "redirect_url": "https://myshop.com/reset-password"
136
+ }'
137
+ ```
138
+
139
+
140
+ The optional `redirect_url` parameter specifies where the password reset link in the email should point to. The token will be appended as a query parameter (e.g., `https://myshop.com/reset-password?token=...`). If the store has [Allowed Origins](/developer/core-concepts/allowed-origins) configured, the `redirect_url` must match one of them.
141
+
142
+ This fires a `customer.password_reset_requested` event with the reset token in the payload. If you're using the `spree_emails` package, the email is sent automatically. Otherwise, subscribe to this event to send the reset email yourself (see [Events](/developer/core-concepts/events)).
143
+
144
+ ### Step 2: Reset Password
145
+
146
+
147
+ ```typescript SDK
148
+ const { token, user } = await client.customer.passwordResets.update(
149
+ 'reset-token-from-email',
150
+ {
151
+ password: 'newsecurepassword',
152
+ password_confirmation: 'newsecurepassword',
153
+ }
154
+ )
155
+ // Returns JWT token + user (auto-login)
156
+ ```
157
+
158
+ ```bash cURL
159
+ curl -X PATCH 'https://api.mystore.com/api/v3/store/customer/password_resets/RESET_TOKEN' \
160
+ -H 'X-Spree-Api-Key: spree_pk_xxx' \
161
+ -H 'Content-Type: application/json' \
162
+ -d '{
163
+ "password": "newsecurepassword",
164
+ "password_confirmation": "newsecurepassword"
165
+ }'
166
+ ```
167
+
168
+
169
+ On success, the user is automatically logged in and a JWT token is returned. The reset token expires after 15 minutes (configurable via `Spree::Config.customer_password_reset_expires_in`) and is single-use (changing the password invalidates it).
170
+
171
+ ## Customer Profile
172
+
173
+
174
+ ```typescript SDK
175
+ // Get current customer
176
+ const customer = await client.customer.get()
177
+ // {
178
+ // id: "usr_xxx",
179
+ // email: "john@example.com",
180
+ // first_name: "John",
181
+ // last_name: "Doe",
182
+ // default_shipping_address: { ... },
183
+ // default_billing_address: { ... },
184
+ // addresses: [{ ... }, { ... }],
185
+ // }
186
+
187
+ // Update profile
188
+ const updated = await client.customer.update({
189
+ first_name: 'Jonathan',
190
+ accepts_email_marketing: true,
191
+ })
192
+ ```
193
+
194
+ ```bash cURL
195
+ # Get current customer
196
+ curl 'https://api.mystore.com/api/v3/store/customer' \
197
+ -H 'Authorization: Bearer <jwt_token>'
198
+
199
+ # Update profile
200
+ curl -X PATCH 'https://api.mystore.com/api/v3/store/customer' \
201
+ -H 'Authorization: Bearer <jwt_token>' \
202
+ -H 'Content-Type: application/json' \
203
+ -d '{ "first_name": "Jonathan", "accepts_email_marketing": true }'
204
+ ```
205
+
206
+
207
+ ## Customer Resources
208
+
209
+ Authenticated customers have access to these resources:
210
+
211
+ | Resource | Description |
212
+ |----------|-------------|
213
+ | [**Addresses**](/developer/core-concepts/addresses#customer-address-book) | Billing and shipping addresses with default selection |
214
+ | [**Orders**](/developer/core-concepts/orders#order-history) | Past order history |
215
+ | **Credit Cards** | Saved credit cards for checkout |
216
+ | **Payment Sources** | Other saved payment methods (PayPal, Klarna, etc.) |
217
+ | **Store Credits** | Balance assigned by the store, usable at checkout |
218
+ | **Gift Cards** | Gift cards owned by or assigned to the customer |
219
+ | **Wishlists** | Saved product lists |
220
+
221
+ ## Guest Checkout
222
+
223
+ Customers don't need to register to purchase. Guest checkout uses an order token (`X-Spree-Token`) to identify the cart. See [Orders — Cart](/developer/core-concepts/orders#cart) for details.
224
+
225
+ ## Related Documentation
226
+
227
+ - [Addresses](/developer/core-concepts/addresses) — Customer address management
228
+ - [Orders](/developer/core-concepts/orders) — Order history and checkout
229
+ - [Authentication](/developer/customization/authentication) — Custom authentication setup
230
+ - [Staff & Roles](/developer/core-concepts/staff-roles) — Admin users and permissions