@spree/docs 0.1.293 → 0.1.295
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api-reference/store.yaml +529 -44
- package/dist/api-reference/webhooks-events.md +20 -5
- package/dist/developer/core-concepts/events.md +11 -1
- package/dist/developer/core-concepts/webhooks.md +59 -15
- package/dist/developer/customization/email-variables.md +2 -1
- package/dist/developer/customization/emails.md +68 -1
- package/dist/developer/upgrades/5.6-to-6.0.md +12 -0
- package/package.json +1 -1
|
@@ -13241,6 +13241,141 @@ components:
|
|
|
13241
13241
|
- amount
|
|
13242
13242
|
- display_amount
|
|
13243
13243
|
x-typelizer: true
|
|
13244
|
+
ExchangeLineItem:
|
|
13245
|
+
type: object
|
|
13246
|
+
properties:
|
|
13247
|
+
id:
|
|
13248
|
+
type: string
|
|
13249
|
+
quantity:
|
|
13250
|
+
type: number
|
|
13251
|
+
received_quantity:
|
|
13252
|
+
type: number
|
|
13253
|
+
resellable:
|
|
13254
|
+
type: boolean
|
|
13255
|
+
original_price:
|
|
13256
|
+
type: string
|
|
13257
|
+
new_variant_price:
|
|
13258
|
+
type: string
|
|
13259
|
+
price_difference:
|
|
13260
|
+
type: string
|
|
13261
|
+
original_variant_id:
|
|
13262
|
+
type: string
|
|
13263
|
+
nullable: true
|
|
13264
|
+
new_variant_id:
|
|
13265
|
+
type: string
|
|
13266
|
+
nullable: true
|
|
13267
|
+
line_item_id:
|
|
13268
|
+
type: string
|
|
13269
|
+
nullable: true
|
|
13270
|
+
fulfillment_item_id:
|
|
13271
|
+
type: string
|
|
13272
|
+
nullable: true
|
|
13273
|
+
original_variant:
|
|
13274
|
+
"$ref": "#/components/schemas/Variant"
|
|
13275
|
+
new_variant:
|
|
13276
|
+
"$ref": "#/components/schemas/Variant"
|
|
13277
|
+
required:
|
|
13278
|
+
- id
|
|
13279
|
+
- quantity
|
|
13280
|
+
- received_quantity
|
|
13281
|
+
- resellable
|
|
13282
|
+
- original_price
|
|
13283
|
+
- new_variant_price
|
|
13284
|
+
- price_difference
|
|
13285
|
+
- original_variant_id
|
|
13286
|
+
- new_variant_id
|
|
13287
|
+
- line_item_id
|
|
13288
|
+
- fulfillment_item_id
|
|
13289
|
+
x-typelizer: true
|
|
13290
|
+
Exchange:
|
|
13291
|
+
type: object
|
|
13292
|
+
properties:
|
|
13293
|
+
id:
|
|
13294
|
+
type: string
|
|
13295
|
+
number:
|
|
13296
|
+
type: string
|
|
13297
|
+
status:
|
|
13298
|
+
anyOf:
|
|
13299
|
+
- type: string
|
|
13300
|
+
enum:
|
|
13301
|
+
- requested
|
|
13302
|
+
- approved
|
|
13303
|
+
- received
|
|
13304
|
+
- fulfilled
|
|
13305
|
+
- canceled
|
|
13306
|
+
- type: string
|
|
13307
|
+
description: The values listed are the built-in ones; extensions may add
|
|
13308
|
+
more.
|
|
13309
|
+
order_id:
|
|
13310
|
+
type: string
|
|
13311
|
+
nullable: true
|
|
13312
|
+
reason_id:
|
|
13313
|
+
type: string
|
|
13314
|
+
nullable: true
|
|
13315
|
+
price_difference:
|
|
13316
|
+
type: string
|
|
13317
|
+
display_price_difference:
|
|
13318
|
+
type: string
|
|
13319
|
+
approved_at:
|
|
13320
|
+
type: string
|
|
13321
|
+
nullable: true
|
|
13322
|
+
received_at:
|
|
13323
|
+
type: string
|
|
13324
|
+
nullable: true
|
|
13325
|
+
fulfilled_at:
|
|
13326
|
+
type: string
|
|
13327
|
+
nullable: true
|
|
13328
|
+
canceled_at:
|
|
13329
|
+
type: string
|
|
13330
|
+
nullable: true
|
|
13331
|
+
reason:
|
|
13332
|
+
"$ref": "#/components/schemas/ReturnReason"
|
|
13333
|
+
exchange_line_items:
|
|
13334
|
+
type: array
|
|
13335
|
+
items:
|
|
13336
|
+
"$ref": "#/components/schemas/ExchangeLineItem"
|
|
13337
|
+
required:
|
|
13338
|
+
- id
|
|
13339
|
+
- number
|
|
13340
|
+
- status
|
|
13341
|
+
- order_id
|
|
13342
|
+
- reason_id
|
|
13343
|
+
- price_difference
|
|
13344
|
+
- display_price_difference
|
|
13345
|
+
- approved_at
|
|
13346
|
+
- received_at
|
|
13347
|
+
- fulfilled_at
|
|
13348
|
+
- canceled_at
|
|
13349
|
+
x-typelizer: true
|
|
13350
|
+
Export:
|
|
13351
|
+
type: object
|
|
13352
|
+
properties:
|
|
13353
|
+
id:
|
|
13354
|
+
type: string
|
|
13355
|
+
number:
|
|
13356
|
+
type: string
|
|
13357
|
+
format:
|
|
13358
|
+
type: string
|
|
13359
|
+
nullable: true
|
|
13360
|
+
created_at:
|
|
13361
|
+
type: string
|
|
13362
|
+
updated_at:
|
|
13363
|
+
type: string
|
|
13364
|
+
type:
|
|
13365
|
+
type: string
|
|
13366
|
+
nullable: true
|
|
13367
|
+
user_id:
|
|
13368
|
+
type: string
|
|
13369
|
+
nullable: true
|
|
13370
|
+
required:
|
|
13371
|
+
- id
|
|
13372
|
+
- number
|
|
13373
|
+
- format
|
|
13374
|
+
- created_at
|
|
13375
|
+
- updated_at
|
|
13376
|
+
- type
|
|
13377
|
+
- user_id
|
|
13378
|
+
x-typelizer: true
|
|
13244
13379
|
Fee:
|
|
13245
13380
|
type: object
|
|
13246
13381
|
properties:
|
|
@@ -13545,6 +13680,111 @@ components:
|
|
|
13545
13680
|
- expired
|
|
13546
13681
|
- active
|
|
13547
13682
|
x-typelizer: true
|
|
13683
|
+
ImportRow:
|
|
13684
|
+
type: object
|
|
13685
|
+
properties:
|
|
13686
|
+
id:
|
|
13687
|
+
type: string
|
|
13688
|
+
row_number:
|
|
13689
|
+
type: number
|
|
13690
|
+
status:
|
|
13691
|
+
anyOf:
|
|
13692
|
+
- type: string
|
|
13693
|
+
enum:
|
|
13694
|
+
- pending
|
|
13695
|
+
- processing
|
|
13696
|
+
- completed
|
|
13697
|
+
- failed
|
|
13698
|
+
- type: string
|
|
13699
|
+
description: The values listed are the built-in ones; extensions may add
|
|
13700
|
+
more.
|
|
13701
|
+
validation_errors:
|
|
13702
|
+
type: string
|
|
13703
|
+
nullable: true
|
|
13704
|
+
created_at:
|
|
13705
|
+
type: string
|
|
13706
|
+
updated_at:
|
|
13707
|
+
type: string
|
|
13708
|
+
import_id:
|
|
13709
|
+
type: string
|
|
13710
|
+
nullable: true
|
|
13711
|
+
item_type:
|
|
13712
|
+
type: string
|
|
13713
|
+
nullable: true
|
|
13714
|
+
item_id:
|
|
13715
|
+
type: string
|
|
13716
|
+
nullable: true
|
|
13717
|
+
required:
|
|
13718
|
+
- id
|
|
13719
|
+
- row_number
|
|
13720
|
+
- status
|
|
13721
|
+
- validation_errors
|
|
13722
|
+
- created_at
|
|
13723
|
+
- updated_at
|
|
13724
|
+
- import_id
|
|
13725
|
+
- item_type
|
|
13726
|
+
- item_id
|
|
13727
|
+
x-typelizer: true
|
|
13728
|
+
Import:
|
|
13729
|
+
type: object
|
|
13730
|
+
properties:
|
|
13731
|
+
id:
|
|
13732
|
+
type: string
|
|
13733
|
+
number:
|
|
13734
|
+
type: string
|
|
13735
|
+
rows_count:
|
|
13736
|
+
type: number
|
|
13737
|
+
created_at:
|
|
13738
|
+
type: string
|
|
13739
|
+
updated_at:
|
|
13740
|
+
type: string
|
|
13741
|
+
type:
|
|
13742
|
+
type: string
|
|
13743
|
+
nullable: true
|
|
13744
|
+
description: 'Import type. Built-in: products, product_translations, customers,
|
|
13745
|
+
price_list_prices. Extensions may register more.'
|
|
13746
|
+
status:
|
|
13747
|
+
anyOf:
|
|
13748
|
+
- type: string
|
|
13749
|
+
enum:
|
|
13750
|
+
- pending
|
|
13751
|
+
- mapping
|
|
13752
|
+
- completed_mapping
|
|
13753
|
+
- processing
|
|
13754
|
+
- completed
|
|
13755
|
+
- failed
|
|
13756
|
+
- type: string
|
|
13757
|
+
description: The values listed are the built-in ones; extensions may add
|
|
13758
|
+
more.
|
|
13759
|
+
store_id:
|
|
13760
|
+
type: string
|
|
13761
|
+
nullable: true
|
|
13762
|
+
seller_id:
|
|
13763
|
+
type: string
|
|
13764
|
+
nullable: true
|
|
13765
|
+
owner_type:
|
|
13766
|
+
type: string
|
|
13767
|
+
nullable: true
|
|
13768
|
+
owner_id:
|
|
13769
|
+
type: string
|
|
13770
|
+
nullable: true
|
|
13771
|
+
user_id:
|
|
13772
|
+
type: string
|
|
13773
|
+
nullable: true
|
|
13774
|
+
required:
|
|
13775
|
+
- id
|
|
13776
|
+
- number
|
|
13777
|
+
- rows_count
|
|
13778
|
+
- created_at
|
|
13779
|
+
- updated_at
|
|
13780
|
+
- type
|
|
13781
|
+
- status
|
|
13782
|
+
- store_id
|
|
13783
|
+
- seller_id
|
|
13784
|
+
- owner_type
|
|
13785
|
+
- owner_id
|
|
13786
|
+
- user_id
|
|
13787
|
+
x-typelizer: true
|
|
13548
13788
|
Invitation:
|
|
13549
13789
|
type: object
|
|
13550
13790
|
properties:
|
|
@@ -13917,6 +14157,32 @@ components:
|
|
|
13917
14157
|
- xlarge_url
|
|
13918
14158
|
- og_image_url
|
|
13919
14159
|
x-typelizer: true
|
|
14160
|
+
NewsletterSubscriberRequestEvent:
|
|
14161
|
+
type: object
|
|
14162
|
+
properties:
|
|
14163
|
+
id:
|
|
14164
|
+
type: string
|
|
14165
|
+
email:
|
|
14166
|
+
type: string
|
|
14167
|
+
verification_token:
|
|
14168
|
+
type: string
|
|
14169
|
+
unsubscribe_token:
|
|
14170
|
+
type: string
|
|
14171
|
+
store_id:
|
|
14172
|
+
type: string
|
|
14173
|
+
nullable: true
|
|
14174
|
+
customer_id:
|
|
14175
|
+
type: string
|
|
14176
|
+
nullable: true
|
|
14177
|
+
redirect_url:
|
|
14178
|
+
type: string
|
|
14179
|
+
required:
|
|
14180
|
+
- id
|
|
14181
|
+
- email
|
|
14182
|
+
- unsubscribe_token
|
|
14183
|
+
- store_id
|
|
14184
|
+
- customer_id
|
|
14185
|
+
x-typelizer: true
|
|
13920
14186
|
NewsletterSubscriber:
|
|
13921
14187
|
type: object
|
|
13922
14188
|
properties:
|
|
@@ -14329,6 +14595,26 @@ components:
|
|
|
14329
14595
|
- gift_card
|
|
14330
14596
|
- market
|
|
14331
14597
|
x-typelizer: true
|
|
14598
|
+
PasswordResetRequestedEvent:
|
|
14599
|
+
type: object
|
|
14600
|
+
properties:
|
|
14601
|
+
id:
|
|
14602
|
+
type: string
|
|
14603
|
+
email:
|
|
14604
|
+
type: string
|
|
14605
|
+
reset_token:
|
|
14606
|
+
type: string
|
|
14607
|
+
store_id:
|
|
14608
|
+
type: string
|
|
14609
|
+
nullable: true
|
|
14610
|
+
redirect_url:
|
|
14611
|
+
type: string
|
|
14612
|
+
required:
|
|
14613
|
+
- id
|
|
14614
|
+
- email
|
|
14615
|
+
- reset_token
|
|
14616
|
+
- store_id
|
|
14617
|
+
x-typelizer: true
|
|
14332
14618
|
PaymentMethod:
|
|
14333
14619
|
type: object
|
|
14334
14620
|
properties:
|
|
@@ -14955,6 +15241,40 @@ components:
|
|
|
14955
15241
|
- original_price
|
|
14956
15242
|
- seller_id
|
|
14957
15243
|
x-typelizer: true
|
|
15244
|
+
ProductSubmission:
|
|
15245
|
+
type: object
|
|
15246
|
+
properties:
|
|
15247
|
+
id:
|
|
15248
|
+
type: string
|
|
15249
|
+
status:
|
|
15250
|
+
anyOf:
|
|
15251
|
+
- type: string
|
|
15252
|
+
enum:
|
|
15253
|
+
- pending
|
|
15254
|
+
- approved
|
|
15255
|
+
- rejected
|
|
15256
|
+
- withdrawn
|
|
15257
|
+
- type: string
|
|
15258
|
+
description: The values listed are the built-in ones; extensions may add
|
|
15259
|
+
more.
|
|
15260
|
+
review_note:
|
|
15261
|
+
type: string
|
|
15262
|
+
nullable: true
|
|
15263
|
+
reviewed_at:
|
|
15264
|
+
type: string
|
|
15265
|
+
nullable: true
|
|
15266
|
+
created_at:
|
|
15267
|
+
type: string
|
|
15268
|
+
product_id:
|
|
15269
|
+
type: string
|
|
15270
|
+
required:
|
|
15271
|
+
- id
|
|
15272
|
+
- status
|
|
15273
|
+
- review_note
|
|
15274
|
+
- reviewed_at
|
|
15275
|
+
- created_at
|
|
15276
|
+
- product_id
|
|
15277
|
+
x-typelizer: true
|
|
14958
15278
|
ProductType:
|
|
14959
15279
|
type: object
|
|
14960
15280
|
properties:
|
|
@@ -14985,6 +15305,46 @@ components:
|
|
|
14985
15305
|
- description
|
|
14986
15306
|
- code
|
|
14987
15307
|
x-typelizer: true
|
|
15308
|
+
PurchaseOrderEvent:
|
|
15309
|
+
type: object
|
|
15310
|
+
properties:
|
|
15311
|
+
id:
|
|
15312
|
+
type: string
|
|
15313
|
+
number:
|
|
15314
|
+
type: string
|
|
15315
|
+
status:
|
|
15316
|
+
type: string
|
|
15317
|
+
ordered_at:
|
|
15318
|
+
type: string
|
|
15319
|
+
nullable: true
|
|
15320
|
+
received_at:
|
|
15321
|
+
type: string
|
|
15322
|
+
nullable: true
|
|
15323
|
+
closed_short_at:
|
|
15324
|
+
type: string
|
|
15325
|
+
nullable: true
|
|
15326
|
+
created_at:
|
|
15327
|
+
type: string
|
|
15328
|
+
updated_at:
|
|
15329
|
+
type: string
|
|
15330
|
+
supplier_id:
|
|
15331
|
+
type: string
|
|
15332
|
+
nullable: true
|
|
15333
|
+
destination_location_id:
|
|
15334
|
+
type: string
|
|
15335
|
+
nullable: true
|
|
15336
|
+
required:
|
|
15337
|
+
- id
|
|
15338
|
+
- number
|
|
15339
|
+
- status
|
|
15340
|
+
- ordered_at
|
|
15341
|
+
- received_at
|
|
15342
|
+
- closed_short_at
|
|
15343
|
+
- created_at
|
|
15344
|
+
- updated_at
|
|
15345
|
+
- supplier_id
|
|
15346
|
+
- destination_location_id
|
|
15347
|
+
x-typelizer: true
|
|
14988
15348
|
Refund:
|
|
14989
15349
|
type: object
|
|
14990
15350
|
properties:
|
|
@@ -15152,6 +15512,37 @@ components:
|
|
|
15152
15512
|
- refunded_at
|
|
15153
15513
|
- canceled_at
|
|
15154
15514
|
x-typelizer: true
|
|
15515
|
+
SavedReportEvent:
|
|
15516
|
+
type: object
|
|
15517
|
+
properties:
|
|
15518
|
+
id:
|
|
15519
|
+
type: string
|
|
15520
|
+
name:
|
|
15521
|
+
type: string
|
|
15522
|
+
description:
|
|
15523
|
+
type: string
|
|
15524
|
+
nullable: true
|
|
15525
|
+
query:
|
|
15526
|
+
type: object
|
|
15527
|
+
seeded:
|
|
15528
|
+
type: boolean
|
|
15529
|
+
created_at:
|
|
15530
|
+
type: string
|
|
15531
|
+
updated_at:
|
|
15532
|
+
type: string
|
|
15533
|
+
user_id:
|
|
15534
|
+
type: string
|
|
15535
|
+
nullable: true
|
|
15536
|
+
required:
|
|
15537
|
+
- id
|
|
15538
|
+
- name
|
|
15539
|
+
- description
|
|
15540
|
+
- query
|
|
15541
|
+
- seeded
|
|
15542
|
+
- created_at
|
|
15543
|
+
- updated_at
|
|
15544
|
+
- user_id
|
|
15545
|
+
x-typelizer: true
|
|
15155
15546
|
Seller:
|
|
15156
15547
|
type: object
|
|
15157
15548
|
properties:
|
|
@@ -15193,11 +15584,6 @@ components:
|
|
|
15193
15584
|
properties:
|
|
15194
15585
|
id:
|
|
15195
15586
|
type: string
|
|
15196
|
-
source:
|
|
15197
|
-
type: string
|
|
15198
|
-
enum:
|
|
15199
|
-
- purchased
|
|
15200
|
-
- uploaded
|
|
15201
15587
|
status:
|
|
15202
15588
|
anyOf:
|
|
15203
15589
|
- type: string
|
|
@@ -15211,26 +15597,12 @@ components:
|
|
|
15211
15597
|
carrier:
|
|
15212
15598
|
type: string
|
|
15213
15599
|
nullable: true
|
|
15214
|
-
carrier_name:
|
|
15215
|
-
type: string
|
|
15216
|
-
nullable: true
|
|
15217
15600
|
service:
|
|
15218
15601
|
type: string
|
|
15219
15602
|
nullable: true
|
|
15220
15603
|
tracking_number:
|
|
15221
15604
|
type: string
|
|
15222
15605
|
nullable: true
|
|
15223
|
-
currency:
|
|
15224
|
-
type: string
|
|
15225
|
-
nullable: true
|
|
15226
|
-
format:
|
|
15227
|
-
type: string
|
|
15228
|
-
nullable: true
|
|
15229
|
-
external_id:
|
|
15230
|
-
type: string
|
|
15231
|
-
nullable: true
|
|
15232
|
-
metadata:
|
|
15233
|
-
type: object
|
|
15234
15606
|
refunded_at:
|
|
15235
15607
|
type: string
|
|
15236
15608
|
nullable: true
|
|
@@ -15243,42 +15615,19 @@ components:
|
|
|
15243
15615
|
owner_type:
|
|
15244
15616
|
type: string
|
|
15245
15617
|
enum:
|
|
15246
|
-
-
|
|
15247
|
-
-
|
|
15248
|
-
cost:
|
|
15249
|
-
type: string
|
|
15250
|
-
display_cost:
|
|
15251
|
-
type: string
|
|
15252
|
-
integration_id:
|
|
15253
|
-
type: string
|
|
15254
|
-
nullable: true
|
|
15255
|
-
file_pending:
|
|
15256
|
-
type: boolean
|
|
15257
|
-
download_url:
|
|
15258
|
-
type: string
|
|
15259
|
-
nullable: true
|
|
15618
|
+
- fulfillment
|
|
15619
|
+
- return
|
|
15260
15620
|
required:
|
|
15261
15621
|
- id
|
|
15262
|
-
- source
|
|
15263
15622
|
- status
|
|
15264
15623
|
- carrier
|
|
15265
|
-
- carrier_name
|
|
15266
15624
|
- service
|
|
15267
15625
|
- tracking_number
|
|
15268
|
-
- currency
|
|
15269
|
-
- format
|
|
15270
|
-
- external_id
|
|
15271
|
-
- metadata
|
|
15272
15626
|
- refunded_at
|
|
15273
15627
|
- created_at
|
|
15274
15628
|
- updated_at
|
|
15275
15629
|
- owner_id
|
|
15276
15630
|
- owner_type
|
|
15277
|
-
- cost
|
|
15278
|
-
- display_cost
|
|
15279
|
-
- integration_id
|
|
15280
|
-
- file_pending
|
|
15281
|
-
- download_url
|
|
15282
15631
|
x-typelizer: true
|
|
15283
15632
|
State:
|
|
15284
15633
|
type: object
|
|
@@ -15291,6 +15640,28 @@ components:
|
|
|
15291
15640
|
- abbr
|
|
15292
15641
|
- name
|
|
15293
15642
|
x-typelizer: true
|
|
15643
|
+
StockLevel:
|
|
15644
|
+
type: object
|
|
15645
|
+
properties:
|
|
15646
|
+
id:
|
|
15647
|
+
type: string
|
|
15648
|
+
count_on_hand:
|
|
15649
|
+
type: number
|
|
15650
|
+
backorderable:
|
|
15651
|
+
type: boolean
|
|
15652
|
+
stock_location_id:
|
|
15653
|
+
type: string
|
|
15654
|
+
nullable: true
|
|
15655
|
+
variant_id:
|
|
15656
|
+
type: string
|
|
15657
|
+
nullable: true
|
|
15658
|
+
required:
|
|
15659
|
+
- id
|
|
15660
|
+
- count_on_hand
|
|
15661
|
+
- backorderable
|
|
15662
|
+
- stock_location_id
|
|
15663
|
+
- variant_id
|
|
15664
|
+
x-typelizer: true
|
|
15294
15665
|
StockLocation:
|
|
15295
15666
|
type: object
|
|
15296
15667
|
properties:
|
|
@@ -15338,6 +15709,76 @@ components:
|
|
|
15338
15709
|
- pickup_ready_in_minutes
|
|
15339
15710
|
- pickup_instructions
|
|
15340
15711
|
x-typelizer: true
|
|
15712
|
+
StockMovement:
|
|
15713
|
+
type: object
|
|
15714
|
+
properties:
|
|
15715
|
+
id:
|
|
15716
|
+
type: string
|
|
15717
|
+
quantity:
|
|
15718
|
+
type: number
|
|
15719
|
+
kind:
|
|
15720
|
+
type: string
|
|
15721
|
+
nullable: true
|
|
15722
|
+
enum:
|
|
15723
|
+
- received
|
|
15724
|
+
- allocated
|
|
15725
|
+
- shipped
|
|
15726
|
+
- released
|
|
15727
|
+
- adjusted
|
|
15728
|
+
reason:
|
|
15729
|
+
type: string
|
|
15730
|
+
nullable: true
|
|
15731
|
+
created_at:
|
|
15732
|
+
type: string
|
|
15733
|
+
updated_at:
|
|
15734
|
+
type: string
|
|
15735
|
+
stock_level_id:
|
|
15736
|
+
type: string
|
|
15737
|
+
nullable: true
|
|
15738
|
+
required:
|
|
15739
|
+
- id
|
|
15740
|
+
- quantity
|
|
15741
|
+
- kind
|
|
15742
|
+
- reason
|
|
15743
|
+
- created_at
|
|
15744
|
+
- updated_at
|
|
15745
|
+
- stock_level_id
|
|
15746
|
+
x-typelizer: true
|
|
15747
|
+
StockReceiptEvent:
|
|
15748
|
+
type: object
|
|
15749
|
+
properties:
|
|
15750
|
+
id:
|
|
15751
|
+
type: string
|
|
15752
|
+
number:
|
|
15753
|
+
type: string
|
|
15754
|
+
quantity_accepted_total:
|
|
15755
|
+
type: number
|
|
15756
|
+
quantity_rejected_total:
|
|
15757
|
+
type: number
|
|
15758
|
+
received_at:
|
|
15759
|
+
type: string
|
|
15760
|
+
created_at:
|
|
15761
|
+
type: string
|
|
15762
|
+
updated_at:
|
|
15763
|
+
type: string
|
|
15764
|
+
receivable_type:
|
|
15765
|
+
type: string
|
|
15766
|
+
enum:
|
|
15767
|
+
- purchase_order
|
|
15768
|
+
- stock_transfer
|
|
15769
|
+
receivable_id:
|
|
15770
|
+
type: string
|
|
15771
|
+
required:
|
|
15772
|
+
- id
|
|
15773
|
+
- number
|
|
15774
|
+
- quantity_accepted_total
|
|
15775
|
+
- quantity_rejected_total
|
|
15776
|
+
- received_at
|
|
15777
|
+
- created_at
|
|
15778
|
+
- updated_at
|
|
15779
|
+
- receivable_type
|
|
15780
|
+
- receivable_id
|
|
15781
|
+
x-typelizer: true
|
|
15341
15782
|
StockReservation:
|
|
15342
15783
|
type: object
|
|
15343
15784
|
properties:
|
|
@@ -15346,6 +15787,33 @@ components:
|
|
|
15346
15787
|
required:
|
|
15347
15788
|
- id
|
|
15348
15789
|
x-typelizer: true
|
|
15790
|
+
StockTransfer:
|
|
15791
|
+
type: object
|
|
15792
|
+
properties:
|
|
15793
|
+
id:
|
|
15794
|
+
type: string
|
|
15795
|
+
number:
|
|
15796
|
+
type: string
|
|
15797
|
+
reference:
|
|
15798
|
+
type: string
|
|
15799
|
+
nullable: true
|
|
15800
|
+
created_at:
|
|
15801
|
+
type: string
|
|
15802
|
+
updated_at:
|
|
15803
|
+
type: string
|
|
15804
|
+
source_location_id:
|
|
15805
|
+
type: string
|
|
15806
|
+
destination_location_id:
|
|
15807
|
+
type: string
|
|
15808
|
+
required:
|
|
15809
|
+
- id
|
|
15810
|
+
- number
|
|
15811
|
+
- reference
|
|
15812
|
+
- created_at
|
|
15813
|
+
- updated_at
|
|
15814
|
+
- source_location_id
|
|
15815
|
+
- destination_location_id
|
|
15816
|
+
x-typelizer: true
|
|
15349
15817
|
StoreCreditEvent:
|
|
15350
15818
|
type: object
|
|
15351
15819
|
properties:
|
|
@@ -15403,6 +15871,23 @@ components:
|
|
|
15403
15871
|
- display_amount_remaining
|
|
15404
15872
|
- currency
|
|
15405
15873
|
x-typelizer: true
|
|
15874
|
+
SupplierEvent:
|
|
15875
|
+
type: object
|
|
15876
|
+
properties:
|
|
15877
|
+
id:
|
|
15878
|
+
type: string
|
|
15879
|
+
name:
|
|
15880
|
+
type: string
|
|
15881
|
+
created_at:
|
|
15882
|
+
type: string
|
|
15883
|
+
updated_at:
|
|
15884
|
+
type: string
|
|
15885
|
+
required:
|
|
15886
|
+
- id
|
|
15887
|
+
- name
|
|
15888
|
+
- created_at
|
|
15889
|
+
- updated_at
|
|
15890
|
+
x-typelizer: true
|
|
15406
15891
|
TaxIdentifier:
|
|
15407
15892
|
type: object
|
|
15408
15893
|
properties:
|
|
@@ -23,9 +23,9 @@ Every webhook delivery sends a JSON envelope with the event metadata and a `data
|
|
|
23
23
|
| `name` | string | Event name (e.g., `order.placed`) |
|
|
24
24
|
| `created_at` | string | ISO 8601 timestamp |
|
|
25
25
|
| `data` | object | Serialized resource (see payloads below) |
|
|
26
|
-
| `metadata` | object | Additional context: always the Spree version, plus event-specific keys such as `notify_customer`
|
|
26
|
+
| `metadata` | object | Additional context: always the Spree version, plus event-specific keys such as `notify_customer` or `deprecated_alias_of` |
|
|
27
27
|
|
|
28
|
-
Event payloads use the same [Store API V3 serializers](introduction.md) as the REST API. All `id` fields use [prefixed IDs](introduction.md) (e.g., `or_m3Rp9wXz`, `prod_86Rf07xd4z`). All monetary values are strings. All timestamps are ISO 8601.
|
|
28
|
+
Event payloads use the same [Store API V3 serializers](introduction.md) as the REST API, so they never carry back-office fields such as costs, internal notes or staff names. When you need those, fetch the record from the [Admin API](admin-api/introduction.md) using the `id` in the payload. All `id` fields use [prefixed IDs](introduction.md) (e.g., `or_m3Rp9wXz`, `prod_86Rf07xd4z`). All monetary values are strings. All timestamps are ISO 8601.
|
|
29
29
|
|
|
30
30
|
For details on creating webhook endpoints and verifying signatures, see [Webhooks](../developer/core-concepts/webhooks.md). For the event system and the subscriber pattern, see [Events](../developer/core-concepts/events.md).
|
|
31
31
|
|
|
@@ -73,7 +73,7 @@ Events: `order.created`, `order.updated`, `order.deleted`, `order.placed`, `orde
|
|
|
73
73
|
| `order.resend_confirmation_email` | An admin asked to send the order confirmation again |
|
|
74
74
|
| `order.resend_digital_links_email` | An admin asked to send the download links again |
|
|
75
75
|
|
|
76
|
-
The `order.placed` and `order.canceled`
|
|
76
|
+
The `metadata` of `order.placed` and `order.canceled` contains a `notify_customer` boolean. It is `false` when whoever placed or canceled the order asked for the customer not to be emailed.
|
|
77
77
|
|
|
78
78
|
Order payloads include nested `items`, `fulfillments`, `payments`, `discounts`, `fees`, `billing_address`, `shipping_address`, `gift_card`, and `market`.
|
|
79
79
|
|
|
@@ -171,7 +171,7 @@ Carts publish their own events, separate from orders. Use them to follow carts t
|
|
|
171
171
|
|
|
172
172
|
Events: `order_group.created`, `order_group.updated`, `order_group.deleted`, `order_group.completed`
|
|
173
173
|
|
|
174
|
-
When one checkout creates several orders (for example, one per seller), they belong to an order group. `order_group.completed` fires once every order in the group is placed. The payload includes the group's `number`, `email`, `currency`, `total`, `item_total`, `fulfillment_status`, `payment_status`, `completed_at`, the addresses, and the nested `orders`.
|
|
174
|
+
When one checkout creates several orders (for example, one per seller), they belong to an order group. `order_group.completed` fires once every order in the group is placed. The payload includes the group's `number`, `email`, `currency`, `total`, `item_total`, `fulfillment_status`, `payment_status`, `completed_at`, the addresses, and the nested `orders`. Its `metadata` contains `notify_customer`, as on `order.placed`.
|
|
175
175
|
|
|
176
176
|
## Line Item Events
|
|
177
177
|
|
|
@@ -542,6 +542,21 @@ Events: `user.created`, `user.updated`, `user.deleted`, `customer.anonymized`, `
|
|
|
542
542
|
|
|
543
543
|
Customer lifecycle events use the `user` prefix. Customer payloads include nested `addresses`, `default_billing_address`, `default_shipping_address`, `newsletter_subscriber`, and `customer_groups`.
|
|
544
544
|
|
|
545
|
+
`customer.password_reset_requested` carries what you need to send the reset email yourself, rather than the customer record:
|
|
546
|
+
|
|
547
|
+
```json
|
|
548
|
+
{
|
|
549
|
+
"email": "customer@example.com",
|
|
550
|
+
"reset_token": "eyJfcmFpbHMiOnsi...",
|
|
551
|
+
"store_id": "store_UkLWZg9DAJ",
|
|
552
|
+
"redirect_url": "https://shop.example.com/account/reset-password"
|
|
553
|
+
}
|
|
554
|
+
```
|
|
555
|
+
|
|
556
|
+
`redirect_url` is present only when the request included one.
|
|
557
|
+
|
|
558
|
+
> **WARNING:** A reset token lets whoever holds it take over the account. `customer.password_reset_requested` is therefore sent only to endpoints that name it — never to an endpoint subscribed to `*` or `customer.*` — and subscribing to it needs the permission to manage customers. The staff and seller equivalents are never sent to webhooks at all: Spree sends those emails itself.
|
|
559
|
+
|
|
545
560
|
```json
|
|
546
561
|
{
|
|
547
562
|
"id": "cust_k5nR8xLq",
|
|
@@ -865,7 +880,7 @@ Events: `invitation.created`, `invitation.resent`, `invitation.accepted`
|
|
|
865
880
|
|
|
866
881
|
## Other Events
|
|
867
882
|
|
|
868
|
-
These resources publish events too.
|
|
883
|
+
These resources publish events too. Back-office records (purchase orders, stock receipts, suppliers and shipping labels) send a short payload with their status, related record IDs and timestamps; fetch the rest from the Admin API.
|
|
869
884
|
|
|
870
885
|
| Resource | Events |
|
|
871
886
|
|---|---|
|
|
@@ -134,7 +134,13 @@ subscribes_to 'order.placed', async: false
|
|
|
134
134
|
|
|
135
135
|
## Publishing your own events
|
|
136
136
|
|
|
137
|
-
Anything in your own code can announce something, and subscribers and webhooks treat it like any built-in event:
|
|
137
|
+
Anything in your own code can announce something, and subscribers and webhooks treat it like any built-in event. Declare the event on the model first, then publish it:
|
|
138
|
+
|
|
139
|
+
```ruby server/config/initializers/spree_events.rb
|
|
140
|
+
Rails.application.config.to_prepare do
|
|
141
|
+
Spree::Order.publishes_event :flagged_for_review
|
|
142
|
+
end
|
|
143
|
+
```
|
|
138
144
|
|
|
139
145
|
```ruby server/app/services/fraud_check.rb
|
|
140
146
|
order.publish_event('order.flagged_for_review')
|
|
@@ -142,6 +148,10 @@ order.publish_event('order.flagged_for_review')
|
|
|
142
148
|
|
|
143
149
|
Useful when your own domain has moments worth reacting to — a fraud check completing, an approval granted.
|
|
144
150
|
|
|
151
|
+
Every event Spree publishes is declared this way, which is what lets the admin dashboard's webhook picker, the [webhook events endpoint](webhooks.md#event-subscriptions) and the typed events in `@spree/sdk/webhooks` list it. Publishing an event nobody declared raises an error in development and test, so a typo is caught before it ships; in production it is logged and delivered anyway.
|
|
152
|
+
|
|
153
|
+
The payload is the model's Store API serializer, as for built-in events. To send something else, pass a serializer of your own: `publishes_event :flagged_for_review, serializer: 'MyApp::FraudFlagEventSerializer'`. Keep it to what a customer could see; back-office fields belong behind the Admin API. Facts about the event rather than the record, such as who triggered it, go in its metadata: `order.publish_event('order.flagged_for_review', nil, rule: 'velocity')`.
|
|
154
|
+
|
|
145
155
|
## Guidance
|
|
146
156
|
|
|
147
157
|
**Listen for the specific event.** `order.placed` rather than `order.updated` with a status check.
|
|
@@ -141,6 +141,28 @@ The `subscriptions` array accepts exact event names and wildcard patterns:
|
|
|
141
141
|
| `['order.*', 'payment.*', 'fulfillment.fulfilled']` | Multiple patterns |
|
|
142
142
|
| `[]` or `['*']` | All events |
|
|
143
143
|
|
|
144
|
+
An event that carries a credential — `customer.password_reset_requested`, which includes a reset token — is never matched by a pattern. An endpoint receives it only when it names it, and naming it needs the permission to manage customers. Password reset requests for staff and sellers are never sent to webhooks: Spree emails those itself.
|
|
145
|
+
|
|
146
|
+
To see every event you can subscribe to, including those your installed extensions add, list them:
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
```typescript Admin SDK
|
|
150
|
+
const { data: events } = await client.webhookEvents.list()
|
|
151
|
+
// [{ name: 'order.placed', group: 'order', credential: false, deprecated: false, ... }, ...]
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
```bash CLI
|
|
155
|
+
spree api get /webhook_events
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
```bash cURL
|
|
159
|
+
curl 'https://api.mystore.com/api/v3/admin/webhook_events' \
|
|
160
|
+
-H 'X-Spree-API-Key: sk_xxx'
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
Each entry says whether the event carries a credential (and which permission subscribing to it needs), and whether it is a deprecated name along with the event that replaces it.
|
|
165
|
+
|
|
144
166
|
## Webhook Payload
|
|
145
167
|
|
|
146
168
|
Each webhook delivery sends a JSON payload with the following structure. The `data` object uses the same [Store API V3 serializers](../../api-reference/introduction.md) as the REST API, so webhook payloads and API responses share the same schema:
|
|
@@ -175,7 +197,9 @@ Each webhook delivery sends a JSON payload with the following structure. The `da
|
|
|
175
197
|
| `name` | Event name (e.g., `order.placed`) |
|
|
176
198
|
| `created_at` | ISO8601 timestamp when event occurred |
|
|
177
199
|
| `data` | Serialized resource data (V3 API format with [prefixed IDs](../../api-reference/introduction.md)) |
|
|
178
|
-
| `metadata` | Additional context
|
|
200
|
+
| `metadata` | Additional context: the Spree version, plus facts about the event itself, such as `notify_customer` |
|
|
201
|
+
|
|
202
|
+
Payloads carry what a customer could see, never back-office fields such as costs, internal notes or staff names. When an integration needs those, it fetches the record from the Admin API with the `id` in the payload, using a key scoped to what it may read.
|
|
179
203
|
|
|
180
204
|
For complete payload schemas for each event type, see [Webhook Events & Payloads](../../api-reference/webhooks-events.md).
|
|
181
205
|
|
|
@@ -203,29 +227,49 @@ The [Spree Storefront](https://github.com/spree/storefront) includes a ready-mad
|
|
|
203
227
|
|
|
204
228
|
#### Any JavaScript/TypeScript framework
|
|
205
229
|
|
|
206
|
-
Use `@spree/sdk/webhooks` for framework-agnostic verification:
|
|
230
|
+
Use `@spree/sdk/webhooks` for framework-agnostic verification. `constructWebhookEvent` checks the signature and returns a typed event: once you check `event.name`, `event.data` has the type of the record that event carries.
|
|
207
231
|
|
|
208
232
|
```typescript Store SDK
|
|
209
|
-
import {
|
|
210
|
-
import
|
|
211
|
-
import type { Order } from '@spree/sdk'
|
|
233
|
+
import { constructWebhookEvent, WebhookVerificationError } from '@spree/sdk/webhooks'
|
|
234
|
+
import { webhookEventSchemas } from '@spree/sdk/zod'
|
|
212
235
|
|
|
213
236
|
// Hono, Cloudflare Workers, or any Web Fetch API-based framework
|
|
214
|
-
app.post('/webhooks/spree', async (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
237
|
+
app.post('/webhooks/spree', async (c) => {
|
|
238
|
+
let event
|
|
239
|
+
try {
|
|
240
|
+
event = constructWebhookEvent(await c.req.text(), c.req.raw.headers, process.env.SPREE_WEBHOOK_SECRET!, {
|
|
241
|
+
schemas: webhookEventSchemas, // optional: validate `data` at runtime
|
|
242
|
+
})
|
|
243
|
+
} catch (error) {
|
|
244
|
+
if (error instanceof WebhookVerificationError) return c.json({ error: 'Invalid signature' }, 401)
|
|
245
|
+
throw error
|
|
246
|
+
}
|
|
218
247
|
|
|
219
|
-
|
|
220
|
-
|
|
248
|
+
switch (event.name) {
|
|
249
|
+
case 'order.placed':
|
|
250
|
+
await fulfil(event.data) // typed as Order
|
|
251
|
+
break
|
|
252
|
+
case 'customer.password_reset_requested':
|
|
253
|
+
await sendResetEmail(event.data.email, event.data.reset_token)
|
|
254
|
+
break
|
|
221
255
|
}
|
|
222
256
|
|
|
223
|
-
|
|
224
|
-
// handle event...
|
|
225
|
-
res.json({ received: true })
|
|
257
|
+
return c.json({ received: true })
|
|
226
258
|
})
|
|
227
259
|
```
|
|
228
260
|
|
|
261
|
+
Pass the body exactly as received: parsing and re-serializing it changes the bytes the signature covers. `verifyWebhookSignature` is still available when you only need the check.
|
|
262
|
+
|
|
263
|
+
Events your own code or an extension publishes can be typed too, by adding them to `WebhookEventMap`:
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
declare module '@spree/sdk/webhooks' {
|
|
267
|
+
interface WebhookEventMap {
|
|
268
|
+
'loyalty.points_earned': { id: string; points: number }
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
229
273
|
#### Ruby
|
|
230
274
|
|
|
231
275
|
```ruby server/app/controllers/webhooks_controller.rb
|
|
@@ -324,7 +368,7 @@ SSL certificates are verified in production, and not in development — so you c
|
|
|
324
368
|
|
|
325
369
|
## Available Events
|
|
326
370
|
|
|
327
|
-
Webhooks can subscribe to any event in Spree's event system. See [Webhook Events & Payloads](../../api-reference/webhooks-events.md) for the complete list.
|
|
371
|
+
Webhooks can subscribe to any event in Spree's event system. See [Webhook Events & Payloads](../../api-reference/webhooks-events.md) for the complete list, or [list them through the Admin API](#event-subscriptions) to include the events your extensions add.
|
|
328
372
|
|
|
329
373
|
Common webhook events include:
|
|
330
374
|
|
|
@@ -42,7 +42,8 @@ Each object's fields, and the fields of the objects nested in it.
|
|
|
42
42
|
|
|
43
43
|
### `store`
|
|
44
44
|
|
|
45
|
-
- `store`: `id`, `name`, `address`, `mail_from_address`, `default_currency`, `default_locale`, `url`, `support_email`, `logo_url`, `logo_width`
|
|
45
|
+
- `store`: `id`, `name`, `address`, `mail_from_address`, `default_currency`, `default_locale`, `url`, `support_email`, `logo_url`, `logo_width`, `branding`
|
|
46
|
+
- `store.branding`: `background_color`, `card_color`, `text_color`, `heading_color`, `accent_color` (empty unless the merchant set one), `link_color`, `button_color`, `button_text_color`, `button_border`, `font`, `font_family`, `heading_font_family`, `font_url` (a web font's stylesheet, empty for email-safe fonts)
|
|
46
47
|
|
|
47
48
|
### `order`
|
|
48
49
|
|
|
@@ -8,7 +8,7 @@ Every email Spree sends — order confirmations, shipping notices, password rese
|
|
|
8
8
|
|
|
9
9
|
To change an email, you copy its template into your app and edit it. Nothing else changes: Spree still picks the recipient, the language and the sender, and delivers the email through your [SMTP provider](../providers/emails.md).
|
|
10
10
|
|
|
11
|
-
> **NOTE:** Templates read plain data — the same fields the [Store API](../../api-reference/store-api/introduction.md) returns, plus what only an email needs — never Ruby objects. The same template can
|
|
11
|
+
> **NOTE:** Templates read plain data — the same fields the [Store API](../../api-reference/store-api/introduction.md) returns, plus what only an email needs — never Ruby objects. The same template can run outside Ruby, and merchants can edit customer emails safely from the dashboard.
|
|
12
12
|
|
|
13
13
|
## Where templates live
|
|
14
14
|
|
|
@@ -102,6 +102,73 @@ In development and test, a variable that does not exist raises an error instead
|
|
|
102
102
|
|
|
103
103
|
To look at every email with real data, open the mailer previews at `/rails/mailers` on your Spree server.
|
|
104
104
|
|
|
105
|
+
## Templates merchants edit in the dashboard
|
|
106
|
+
|
|
107
|
+
Merchants can edit the emails their customers receive in **Settings → Emails → Templates**, along with the layout and the shared blocks in `spree/shared`. An edit is saved as a draft and goes live when published; publishing renders it with the store's own data first and refuses a template that does not render. An email built from a record the store does not have yet, such as an order confirmation in a store with no orders, is checked for template syntax only. Staff, store-owner and seller emails are not editable and always render from files.
|
|
108
|
+
|
|
109
|
+
A store's published template comes first, so the lookup for an editable email is:
|
|
110
|
+
|
|
111
|
+
1. the store's published template in the email's language
|
|
112
|
+
2. the store's published template for every language
|
|
113
|
+
3. your app's file
|
|
114
|
+
4. Spree's file
|
|
115
|
+
|
|
116
|
+
Your file stays the default the dashboard starts from and reverts to, so overriding a template in code and letting merchants edit it work together. When a Spree upgrade or a change to your file alters a default a merchant has customized, the dashboard tells them and shows what changed.
|
|
117
|
+
|
|
118
|
+
The same operations are open to integrations through the [Admin API](../../api-reference/admin-api/introduction.md), with the `email_templates` permission:
|
|
119
|
+
|
|
120
|
+
**Admin SDK:**
|
|
121
|
+
|
|
122
|
+
```typescript
|
|
123
|
+
const preview = await client.emailTemplates.preview('spree.order_mailer.confirm_email', {
|
|
124
|
+
body: '<mj-section><mj-column><mj-text>Thanks, {{ order.customer_name }}!</mj-text></mj-column></mj-section>',
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
await client.emailTemplates.draft.update('spree.order_mailer.confirm_email', {
|
|
128
|
+
body: '<mj-section><mj-column><mj-text>Thanks, {{ order.customer_name }}!</mj-text></mj-column></mj-section>',
|
|
129
|
+
})
|
|
130
|
+
await client.emailTemplates.publish('spree.order_mailer.confirm_email')
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**cURL:**
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
curl -X PUT https://your-store.com/api/v3/admin/email_templates/spree.order_mailer.confirm_email/draft \
|
|
137
|
+
-H "X-Spree-Api-Key: sk_xxx" -H "Content-Type: application/json" \
|
|
138
|
+
-d '{"body": "<mj-section><mj-column><mj-text>Thanks, {{ order.customer_name }}!</mj-text></mj-column></mj-section>"}'
|
|
139
|
+
|
|
140
|
+
curl -X POST https://your-store.com/api/v3/admin/email_templates/spree.order_mailer.confirm_email/publication \
|
|
141
|
+
-H "X-Spree-Api-Key: sk_xxx"
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
### Branding
|
|
146
|
+
|
|
147
|
+
Merchants set the colors and font of their customer emails in **Settings → Emails**, without touching a template. Templates read them from [`store.branding`](email-variables.md#store), and Spree's layout uses them throughout. If you override the layout or a template, read colors and fonts from `store.branding` rather than writing them in, so a store's branding keeps applying.
|
|
148
|
+
|
|
149
|
+
### Making your own customer email editable
|
|
150
|
+
|
|
151
|
+
A customer email your app adds can be edited like Spree's own. Register it with a class that builds the data its preview renders with:
|
|
152
|
+
|
|
153
|
+
```ruby server/config/initializers/spree.rb
|
|
154
|
+
Rails.application.config.after_initialize do
|
|
155
|
+
Spree.editable_email_templates.register(
|
|
156
|
+
'spree/review_mailer/request_email', kind: :email, sample: 'ReviewRequestSample'
|
|
157
|
+
)
|
|
158
|
+
end
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
```ruby server/app/services/review_request_sample.rb
|
|
162
|
+
# Previews with the store's latest completed order, or the one the merchant picks.
|
|
163
|
+
class ReviewRequestSample < Spree::Emails::Samples::Order
|
|
164
|
+
def variables
|
|
165
|
+
{ order: super[:order], review_url: placeholder_url('reviews/new') }
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
A sample builds from the record the merchant picked, else the store's latest one; a store with none is told there is nothing to preview with yet. Pass placeholder URLs, never real tokens, and register only emails your customers receive.
|
|
171
|
+
|
|
105
172
|
## Your own mailers
|
|
106
173
|
|
|
107
174
|
A mailer that inherits `Spree::BaseMailer` and renders its own ERB views with `mail` keeps working. Spree wraps its HTML in the same layout as every other email, so it carries the store's logo, header and footer. The `spree/shared/mailer_hero` and `spree/shared/mailer_button` partials are still there for those views.
|
|
@@ -495,6 +495,18 @@ now returns `nil` for an ID with another model's prefix, the same as
|
|
|
495
495
|
`find_by_prefix_id`. Call `Spree::PrefixedId.decode_prefixed_id` if you
|
|
496
496
|
really need to decode any prefix.
|
|
497
497
|
|
|
498
|
+
## Every event is declared
|
|
499
|
+
|
|
500
|
+
Events are now declared on the model that publishes them (`publishes_event`, `publishes_events`), and `publish_event` raises in development and test for a name nobody declared. Extensions that publish their own events need one line each — see [Publishing your own events](../core-concepts/events.md#publishing-your-own-events). In production an undeclared event is logged and still delivered.
|
|
501
|
+
|
|
502
|
+
Some payloads changed so that every webhook carries the Store API shape and nothing more:
|
|
503
|
+
|
|
504
|
+
- **`notify_customer` moved to `metadata`** on `order.placed`, `order.completed`, `order.canceled` and `order_group.completed`. Read `event.metadata['notify_customer']` in subscribers and `metadata.notify_customer` in webhook receivers.
|
|
505
|
+
- **`customer.anonymized`** carries the customer record; the store and the requester moved to `metadata` (`store_id`, `requested_by_id`).
|
|
506
|
+
- **Purchase order, stock receipt, supplier and shipping label events** carry a short payload — status, related record IDs and timestamps. Costs, notes, contact details and label files are read from the Admin API.
|
|
507
|
+
- **`saved_report.*`** no longer includes the author's name.
|
|
508
|
+
- **Subscribing an endpoint to `customer.password_reset_requested`** needs the permission to manage customers. The staff and seller reset events are still never sent to webhooks.
|
|
509
|
+
|
|
498
510
|
## Removed in 6.0
|
|
499
511
|
|
|
500
512
|
These were deprecated in 5.x and are **gone now** — there is no bridge, so calls raise `NoMethodError`. Most were one-line delegations to a replacement that already exists.
|