spree_api 5.4.0.beta6 → 5.4.0.beta8
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.
- checksums.yaml +4 -4
- data/README.md +3 -3
- data/app/controllers/concerns/spree/api/v3/cart_resolvable.rb +45 -0
- data/app/controllers/concerns/spree/api/v3/error_handler.rb +22 -15
- data/app/controllers/concerns/spree/api/v3/order_lock.rb +4 -4
- data/app/controllers/spree/api/v3/store/carts/coupon_codes_controller.rb +57 -0
- data/app/controllers/spree/api/v3/store/{orders/line_items_controller.rb → carts/items_controller.rb} +18 -31
- data/app/controllers/spree/api/v3/store/carts/payment_methods_controller.rb +24 -0
- data/app/controllers/spree/api/v3/store/{orders → carts}/payment_sessions_controller.rb +14 -19
- data/app/controllers/spree/api/v3/store/{orders → carts}/payments_controller.rb +18 -29
- data/app/controllers/spree/api/v3/store/carts/shipments_controller.rb +65 -0
- data/app/controllers/spree/api/v3/store/{orders → carts}/store_credits_controller.rb +9 -10
- data/app/controllers/spree/api/v3/store/carts_controller.rb +176 -0
- data/app/controllers/spree/api/v3/store/customer/orders_controller.rb +1 -1
- data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +89 -0
- data/app/controllers/spree/api/v3/store/orders_controller.rb +21 -114
- data/app/controllers/spree/api/v3/store/products_controller.rb +1 -1
- data/app/controllers/spree/api/v3/webhooks/payments_controller.rb +52 -0
- data/app/serializers/spree/api/v3/admin/allowed_origin_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/media_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/admin/order_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/product_serializer.rb +8 -4
- data/app/serializers/spree/api/v3/admin/variant_serializer.rb +8 -3
- data/app/serializers/spree/api/v3/base_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/cart_promotion_serializer.rb +18 -0
- data/app/serializers/spree/api/v3/cart_serializer.rb +56 -0
- data/app/serializers/spree/api/v3/media_serializer.rb +60 -0
- data/app/serializers/spree/api/v3/order_serializer.rb +7 -9
- data/app/serializers/spree/api/v3/product_serializer.rb +10 -6
- data/app/serializers/spree/api/v3/variant_serializer.rb +14 -9
- data/config/locales/en.yml +3 -0
- data/config/routes.rb +23 -24
- data/lib/spree/api/configuration.rb +1 -0
- data/lib/spree/api/dependencies.rb +4 -2
- data/lib/spree/api/openapi/schema_helper.rb +28 -0
- metadata +22 -17
- data/app/controllers/concerns/spree/api/v3/order_concern.rb +0 -46
- data/app/controllers/spree/api/v3/store/cart_controller.rb +0 -97
- data/app/controllers/spree/api/v3/store/orders/coupon_codes_controller.rb +0 -73
- data/app/controllers/spree/api/v3/store/orders/payment_methods_controller.rb +0 -43
- data/app/controllers/spree/api/v3/store/orders/shipments_controller.rb +0 -56
- data/app/serializers/spree/api/v3/admin/image_serializer.rb +0 -10
- data/app/serializers/spree/api/v3/image_serializer.rb +0 -43
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d59f56e428252697b4360183c26b92d20fe7607630b84589a5203ad766d6a467
|
|
4
|
+
data.tar.gz: 2807c39fa35138ae1db42e5fb184998dfc8e9c25d7309f11b43edc0af1751877
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ed23df8b1714945bb9b4718f0c81443fb140fb3ddbaf48e72fbc4de1f9b6b0f9b41373587cf57f69fcc4e928aa75fc1636c7dc57b700e24c9958a3bd70c42bc0
|
|
7
|
+
data.tar.gz: bc499f9d970dc0fc0d24de5c711070b267e103d60c82704e5de1f48c7bcd635183cf024e1cfef4b0f9d0841f5e2ea150e74618f7ec3283dd59ee73f20059682f
|
data/README.md
CHANGED
|
@@ -82,10 +82,10 @@ curl -H "Authorization: Bearer spree_sk_xxx" \
|
|
|
82
82
|
|
|
83
83
|
### Guest Cart Token
|
|
84
84
|
|
|
85
|
-
For guest checkout, use the `X-Spree-
|
|
85
|
+
For guest checkout, use the `X-Spree-Token` header:
|
|
86
86
|
|
|
87
87
|
```bash
|
|
88
|
-
curl -H "X-Spree-
|
|
88
|
+
curl -H "X-Spree-Token: ORDER_TOKEN" \
|
|
89
89
|
https://your-store.com/api/v3/cart
|
|
90
90
|
```
|
|
91
91
|
|
|
@@ -134,4 +134,4 @@ bundle exec rspec
|
|
|
134
134
|
## Documentation
|
|
135
135
|
|
|
136
136
|
- [API Reference](https://docs.spreecommerce.org/api)
|
|
137
|
-
- [Authentication Guide](https://docs.spreecommerce.org/developer/api/authentication)
|
|
137
|
+
- [Authentication Guide](https://docs.spreecommerce.org/developer/api/authentication)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module CartResolvable
|
|
5
|
+
extend ActiveSupport::Concern
|
|
6
|
+
|
|
7
|
+
protected
|
|
8
|
+
|
|
9
|
+
# Find cart by prefixed ID and authorize access via CanCanCan.
|
|
10
|
+
# @return [Spree::Order]
|
|
11
|
+
def find_cart
|
|
12
|
+
cart_id = params[:cart_id] || params[:id]
|
|
13
|
+
@cart = current_store.carts.find_by_prefix_id!(cart_id)
|
|
14
|
+
authorize!(:show, @cart, cart_token)
|
|
15
|
+
@cart
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# Find the cart and authorize it for update.
|
|
19
|
+
# @return [Spree::Order]
|
|
20
|
+
def find_cart!
|
|
21
|
+
cart_id = params[:cart_id] || params[:id]
|
|
22
|
+
@cart = current_store.carts.find_by_prefix_id!(cart_id)
|
|
23
|
+
authorize!(:update, @cart, cart_token)
|
|
24
|
+
@cart
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Render the cart as JSON using the cart serializer.
|
|
28
|
+
def render_cart(status: :ok)
|
|
29
|
+
render json: Spree.api.cart_serializer.new(@cart.reload, params: serializer_params).to_h, status: status
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Render the order as JSON using the order serializer (for complete action).
|
|
33
|
+
def render_order(status: :ok)
|
|
34
|
+
render json: Spree.api.order_serializer.new(@cart.reload, params: serializer_params).to_h, status: status
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Return the cart token from the request headers.
|
|
38
|
+
# @return [String, nil]
|
|
39
|
+
def cart_token
|
|
40
|
+
request.headers['x-spree-token']
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -13,18 +13,23 @@ module Spree
|
|
|
13
13
|
invalid_token: 'invalid_token',
|
|
14
14
|
invalid_provider: 'invalid_provider',
|
|
15
15
|
current_password_invalid: 'current_password_invalid',
|
|
16
|
+
password_reset_token_invalid: 'password_reset_token_invalid',
|
|
17
|
+
redirect_url_not_allowed: 'redirect_url_not_allowed',
|
|
16
18
|
|
|
17
19
|
# Resource errors
|
|
18
20
|
record_not_found: 'record_not_found',
|
|
19
21
|
resource_invalid: 'resource_invalid',
|
|
20
22
|
|
|
23
|
+
# Cart errors
|
|
24
|
+
cart_not_found: 'cart_not_found',
|
|
25
|
+
cart_cannot_transition: 'cart_cannot_transition',
|
|
26
|
+
cart_empty: 'cart_empty',
|
|
27
|
+
cart_invalid_state: 'cart_invalid_state',
|
|
28
|
+
cart_already_updated: 'cart_already_updated',
|
|
29
|
+
cart_cannot_complete: 'cart_cannot_complete',
|
|
30
|
+
|
|
21
31
|
# Order errors
|
|
22
32
|
order_not_found: 'order_not_found',
|
|
23
|
-
order_already_completed: 'order_already_completed',
|
|
24
|
-
order_cannot_transition: 'order_cannot_transition',
|
|
25
|
-
order_empty: 'order_empty',
|
|
26
|
-
order_invalid_state: 'order_invalid_state',
|
|
27
|
-
order_already_updated: 'order_already_updated',
|
|
28
33
|
|
|
29
34
|
# Line item errors
|
|
30
35
|
line_item_not_found: 'line_item_not_found',
|
|
@@ -191,7 +196,7 @@ module Spree
|
|
|
191
196
|
def handle_invalid_transition(exception)
|
|
192
197
|
Rails.error.report(exception, context: error_context, source: 'spree.api.v3')
|
|
193
198
|
render_error(
|
|
194
|
-
code: ERROR_CODES[:
|
|
199
|
+
code: ERROR_CODES[:cart_cannot_transition],
|
|
195
200
|
message: exception.message,
|
|
196
201
|
status: :unprocessable_content
|
|
197
202
|
)
|
|
@@ -229,7 +234,7 @@ module Spree
|
|
|
229
234
|
|
|
230
235
|
case model_name
|
|
231
236
|
when 'order'
|
|
232
|
-
ERROR_CODES[:order_not_found]
|
|
237
|
+
request.path.include?('/carts') ? ERROR_CODES[:cart_not_found] : ERROR_CODES[:order_not_found]
|
|
233
238
|
when 'line_item'
|
|
234
239
|
ERROR_CODES[:line_item_not_found]
|
|
235
240
|
when 'variant'
|
|
@@ -240,15 +245,17 @@ module Spree
|
|
|
240
245
|
end
|
|
241
246
|
|
|
242
247
|
# Generate human-readable not found message
|
|
243
|
-
# Uses the exception's own message when it contains useful context (e.g. prefixed ID),
|
|
244
|
-
# otherwise falls back to a generic "[Model] not found" translation.
|
|
245
248
|
def generate_not_found_message(exception)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
249
|
+
model_name = extract_model_name(exception)
|
|
250
|
+
|
|
251
|
+
# Use "Cart" for order models in cart context
|
|
252
|
+
label = if model_name == 'order' && request.path.include?('/carts')
|
|
253
|
+
'Cart'
|
|
254
|
+
else
|
|
255
|
+
model_name&.humanize || 'record'
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
Spree.t(:record_not_found, scope: 'api', model: label)
|
|
252
259
|
end
|
|
253
260
|
|
|
254
261
|
# Extract clean model name from exception
|
|
@@ -12,7 +12,7 @@ module Spree
|
|
|
12
12
|
private
|
|
13
13
|
|
|
14
14
|
def with_order_lock
|
|
15
|
-
order = @order || @parent
|
|
15
|
+
order = @order || @parent || @cart
|
|
16
16
|
|
|
17
17
|
order.with_lock do
|
|
18
18
|
# Persist increment within the transaction so reloads inside yield see the new version
|
|
@@ -29,10 +29,10 @@ module Spree
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def handle_order_lock_conflict(exception)
|
|
32
|
-
Rails.error.report(exception, context: { order_id: (@order || @parent)&.id }, source: 'spree.api.v3')
|
|
32
|
+
Rails.error.report(exception, context: { order_id: (@order || @parent || @cart)&.id }, source: 'spree.api.v3')
|
|
33
33
|
render_error(
|
|
34
|
-
code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:
|
|
35
|
-
message: Spree.t(:
|
|
34
|
+
code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:cart_already_updated],
|
|
35
|
+
message: Spree.t(:cart_already_updated),
|
|
36
36
|
status: :conflict
|
|
37
37
|
)
|
|
38
38
|
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Store
|
|
5
|
+
module Carts
|
|
6
|
+
class CouponCodesController < Store::BaseController
|
|
7
|
+
include Spree::Api::V3::CartResolvable
|
|
8
|
+
include Spree::Api::V3::OrderLock
|
|
9
|
+
|
|
10
|
+
before_action :find_cart!
|
|
11
|
+
|
|
12
|
+
# POST /api/v3/store/carts/:cart_id/coupon_codes
|
|
13
|
+
# Apply a coupon code to the cart
|
|
14
|
+
def create
|
|
15
|
+
with_order_lock do
|
|
16
|
+
@cart.coupon_code = permitted_params[:code]
|
|
17
|
+
|
|
18
|
+
coupon_handler.apply
|
|
19
|
+
|
|
20
|
+
if coupon_handler.successful?
|
|
21
|
+
render_cart(status: :created)
|
|
22
|
+
else
|
|
23
|
+
render_errors(coupon_handler.error)
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# DELETE /api/v3/store/carts/:cart_id/coupon_codes/:id
|
|
29
|
+
# Remove a coupon code from the cart
|
|
30
|
+
# :id is the coupon code string (e.g., SAVE10)
|
|
31
|
+
def destroy
|
|
32
|
+
with_order_lock do
|
|
33
|
+
coupon_handler.remove(params[:id])
|
|
34
|
+
|
|
35
|
+
if coupon_handler.successful?
|
|
36
|
+
render_cart
|
|
37
|
+
else
|
|
38
|
+
render_errors(coupon_handler.error)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def coupon_handler
|
|
46
|
+
@coupon_handler ||= Spree.coupon_handler.new(@cart)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def permitted_params
|
|
50
|
+
params.permit(:code)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -2,19 +2,18 @@ module Spree
|
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
4
|
module Store
|
|
5
|
-
module
|
|
6
|
-
class
|
|
7
|
-
include Spree::Api::V3::
|
|
5
|
+
module Carts
|
|
6
|
+
class ItemsController < Store::BaseController
|
|
7
|
+
include Spree::Api::V3::CartResolvable
|
|
8
8
|
include Spree::Api::V3::OrderLock
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
before_action :authorize_order_access!
|
|
10
|
+
before_action :find_cart!
|
|
12
11
|
|
|
13
|
-
# POST /api/v3/store/
|
|
12
|
+
# POST /api/v3/store/carts/:cart_id/items
|
|
14
13
|
def create
|
|
15
14
|
with_order_lock do
|
|
16
15
|
result = Spree.cart_add_item_service.call(
|
|
17
|
-
order: @
|
|
16
|
+
order: @cart,
|
|
18
17
|
variant: variant,
|
|
19
18
|
quantity: permitted_params[:quantity] || 1,
|
|
20
19
|
metadata: permitted_params[:metadata] || {},
|
|
@@ -22,73 +21,61 @@ module Spree
|
|
|
22
21
|
)
|
|
23
22
|
|
|
24
23
|
if result.success?
|
|
25
|
-
|
|
24
|
+
render_cart(status: :created)
|
|
26
25
|
else
|
|
27
26
|
render_service_error(result.error, code: ERROR_CODES[:insufficient_stock])
|
|
28
27
|
end
|
|
29
28
|
end
|
|
30
29
|
end
|
|
31
30
|
|
|
32
|
-
# PATCH /api/v3/store/
|
|
31
|
+
# PATCH /api/v3/store/carts/:cart_id/items/:id
|
|
33
32
|
def update
|
|
34
33
|
with_order_lock do
|
|
35
|
-
@line_item =
|
|
34
|
+
@line_item = @cart.line_items.find_by_prefix_id!(params[:id])
|
|
36
35
|
|
|
37
36
|
@line_item.metadata = @line_item.metadata.merge(permitted_params[:metadata].to_h) if permitted_params[:metadata].present?
|
|
38
37
|
|
|
39
38
|
if permitted_params[:quantity].present?
|
|
40
39
|
result = Spree.cart_set_item_quantity_service.call(
|
|
41
|
-
order: @
|
|
40
|
+
order: @cart,
|
|
42
41
|
line_item: @line_item,
|
|
43
42
|
quantity: permitted_params[:quantity]
|
|
44
43
|
)
|
|
45
44
|
|
|
46
45
|
if result.success?
|
|
47
|
-
|
|
46
|
+
render_cart
|
|
48
47
|
else
|
|
49
48
|
render_service_error(result.error, code: ERROR_CODES[:invalid_quantity])
|
|
50
49
|
end
|
|
51
50
|
elsif @line_item.changed?
|
|
52
51
|
@line_item.save!
|
|
53
|
-
|
|
52
|
+
render_cart
|
|
54
53
|
else
|
|
55
|
-
|
|
54
|
+
render_cart
|
|
56
55
|
end
|
|
57
56
|
end
|
|
58
57
|
end
|
|
59
58
|
|
|
60
|
-
# DELETE /api/v3/store/
|
|
59
|
+
# DELETE /api/v3/store/carts/:cart_id/items/:id
|
|
61
60
|
def destroy
|
|
62
61
|
with_order_lock do
|
|
63
|
-
@line_item =
|
|
62
|
+
@line_item = @cart.line_items.find_by_prefix_id!(params[:id])
|
|
64
63
|
|
|
65
64
|
Spree.cart_remove_line_item_service.call(
|
|
66
|
-
order: @
|
|
65
|
+
order: @cart,
|
|
67
66
|
line_item: @line_item
|
|
68
67
|
)
|
|
69
68
|
|
|
70
|
-
|
|
69
|
+
render_cart
|
|
71
70
|
end
|
|
72
71
|
end
|
|
73
72
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
def parent_association
|
|
77
|
-
:line_items
|
|
78
|
-
end
|
|
73
|
+
private
|
|
79
74
|
|
|
80
75
|
def variant
|
|
81
76
|
@variant ||= current_store.variants.accessible_by(current_ability).find_by_prefix_id!(permitted_params[:variant_id])
|
|
82
77
|
end
|
|
83
78
|
|
|
84
|
-
def model_class
|
|
85
|
-
Spree::LineItem
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def serializer_class
|
|
89
|
-
Spree.api.line_item_serializer
|
|
90
|
-
end
|
|
91
|
-
|
|
92
79
|
def permitted_params
|
|
93
80
|
params.permit(Spree::PermittedAttributes.line_item_attributes + [{ options: {} }])
|
|
94
81
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Store
|
|
5
|
+
module Carts
|
|
6
|
+
class PaymentMethodsController < Store::BaseController
|
|
7
|
+
include Spree::Api::V3::CartResolvable
|
|
8
|
+
|
|
9
|
+
before_action :find_cart!
|
|
10
|
+
|
|
11
|
+
# GET /api/v3/store/carts/:cart_id/payment_methods
|
|
12
|
+
def index
|
|
13
|
+
methods = @cart.collect_frontend_payment_methods
|
|
14
|
+
render json: {
|
|
15
|
+
data: methods.map { |m| Spree.api.payment_method_serializer.new(m, params: serializer_params).to_h },
|
|
16
|
+
meta: { count: methods.size }
|
|
17
|
+
}
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -2,20 +2,19 @@ module Spree
|
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
4
|
module Store
|
|
5
|
-
module
|
|
6
|
-
class PaymentSessionsController <
|
|
7
|
-
include Spree::Api::V3::
|
|
5
|
+
module Carts
|
|
6
|
+
class PaymentSessionsController < Store::BaseController
|
|
7
|
+
include Spree::Api::V3::CartResolvable
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
before_action :authorize_order_access!
|
|
9
|
+
before_action :find_cart!
|
|
11
10
|
before_action :set_payment_session, only: [:show, :update, :complete]
|
|
12
11
|
|
|
13
|
-
# POST /api/v3/store/
|
|
12
|
+
# POST /api/v3/store/carts/:cart_id/payment_sessions
|
|
14
13
|
def create
|
|
15
14
|
payment_method = current_store.payment_methods.find_by_prefix_id!(permitted_params[:payment_method_id])
|
|
16
15
|
|
|
17
16
|
@payment_session = payment_method.create_payment_session(
|
|
18
|
-
order: @
|
|
17
|
+
order: @cart,
|
|
19
18
|
amount: permitted_params[:amount],
|
|
20
19
|
external_data: permitted_params[:external_data] || {}
|
|
21
20
|
)
|
|
@@ -27,12 +26,12 @@ module Spree
|
|
|
27
26
|
end
|
|
28
27
|
end
|
|
29
28
|
|
|
30
|
-
# GET /api/v3/store/
|
|
29
|
+
# GET /api/v3/store/carts/:cart_id/payment_sessions/:id
|
|
31
30
|
def show
|
|
32
31
|
render json: serialize_resource(@payment_session)
|
|
33
32
|
end
|
|
34
33
|
|
|
35
|
-
# PATCH /api/v3/store/
|
|
34
|
+
# PATCH /api/v3/store/carts/:cart_id/payment_sessions/:id
|
|
36
35
|
def update
|
|
37
36
|
@payment_session.payment_method.update_payment_session(
|
|
38
37
|
payment_session: @payment_session,
|
|
@@ -47,7 +46,7 @@ module Spree
|
|
|
47
46
|
end
|
|
48
47
|
end
|
|
49
48
|
|
|
50
|
-
# PATCH /api/v3/store/
|
|
49
|
+
# PATCH /api/v3/store/carts/:cart_id/payment_sessions/:id/complete
|
|
51
50
|
def complete
|
|
52
51
|
@payment_session.payment_method.complete_payment_session(
|
|
53
52
|
payment_session: @payment_session,
|
|
@@ -63,14 +62,6 @@ module Spree
|
|
|
63
62
|
|
|
64
63
|
protected
|
|
65
64
|
|
|
66
|
-
def parent_association
|
|
67
|
-
:payment_sessions
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def model_class
|
|
71
|
-
Spree::PaymentSession
|
|
72
|
-
end
|
|
73
|
-
|
|
74
65
|
def serializer_class
|
|
75
66
|
Spree.api.payment_session_serializer
|
|
76
67
|
end
|
|
@@ -86,7 +77,11 @@ module Spree
|
|
|
86
77
|
private
|
|
87
78
|
|
|
88
79
|
def set_payment_session
|
|
89
|
-
@payment_session = @
|
|
80
|
+
@payment_session = @cart.payment_sessions.find_by_prefix_id!(params[:id])
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def serialize_resource(resource)
|
|
84
|
+
serializer_class.new(resource, params: serializer_params).to_h
|
|
90
85
|
end
|
|
91
86
|
end
|
|
92
87
|
end
|
|
@@ -2,29 +2,11 @@ module Spree
|
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
4
|
module Store
|
|
5
|
-
module
|
|
6
|
-
class PaymentsController < Store::
|
|
7
|
-
include Spree::Api::V3::
|
|
8
|
-
include Spree::Api::V3::ResourceSerializer
|
|
5
|
+
module Carts
|
|
6
|
+
class PaymentsController < Store::ResourceController
|
|
7
|
+
include Spree::Api::V3::CartResolvable
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
before_action :set_payment, only: [:show]
|
|
12
|
-
|
|
13
|
-
# GET /api/v3/store/orders/:order_id/payments
|
|
14
|
-
def index
|
|
15
|
-
payments = @parent.payments.includes(:payment_method)
|
|
16
|
-
render json: {
|
|
17
|
-
data: serialize_payments(payments),
|
|
18
|
-
meta: {}
|
|
19
|
-
}
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# GET /api/v3/store/orders/:order_id/payments/:id
|
|
23
|
-
def show
|
|
24
|
-
render json: serialize_resource(@payment)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# POST /api/v3/store/orders/:order_id/payments
|
|
9
|
+
# POST /api/v3/store/carts/:cart_id/payments
|
|
28
10
|
# Creates a payment for non-session payment methods (e.g. Check, Cash on Delivery, Bank Transfer)
|
|
29
11
|
def create
|
|
30
12
|
payment_method = current_store.payment_methods.find_by_prefix_id!(params[:payment_method_id])
|
|
@@ -53,8 +35,6 @@ module Spree
|
|
|
53
35
|
metadata: params[:metadata].present? ? params[:metadata].to_unsafe_h : {}
|
|
54
36
|
)
|
|
55
37
|
|
|
56
|
-
authorize!(:update, @parent, order_token)
|
|
57
|
-
|
|
58
38
|
if @payment.save
|
|
59
39
|
render json: serialize_resource(@payment), status: :created
|
|
60
40
|
else
|
|
@@ -62,18 +42,27 @@ module Spree
|
|
|
62
42
|
end
|
|
63
43
|
end
|
|
64
44
|
|
|
65
|
-
|
|
45
|
+
protected
|
|
46
|
+
|
|
47
|
+
def set_parent
|
|
48
|
+
find_cart!
|
|
49
|
+
@parent = @cart
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def parent_association
|
|
53
|
+
:payments
|
|
54
|
+
end
|
|
66
55
|
|
|
67
|
-
def
|
|
68
|
-
|
|
56
|
+
def model_class
|
|
57
|
+
Spree::Payment
|
|
69
58
|
end
|
|
70
59
|
|
|
71
60
|
def serializer_class
|
|
72
61
|
Spree.api.payment_serializer
|
|
73
62
|
end
|
|
74
63
|
|
|
75
|
-
|
|
76
|
-
|
|
64
|
+
# Authorization is handled by find_cart! in set_parent
|
|
65
|
+
def authorize_resource!(*)
|
|
77
66
|
end
|
|
78
67
|
end
|
|
79
68
|
end
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Store
|
|
5
|
+
module Carts
|
|
6
|
+
class ShipmentsController < Store::BaseController
|
|
7
|
+
include Spree::Api::V3::CartResolvable
|
|
8
|
+
include Spree::Api::V3::OrderLock
|
|
9
|
+
|
|
10
|
+
before_action :find_cart!
|
|
11
|
+
|
|
12
|
+
# GET /api/v3/store/carts/:cart_id/shipments
|
|
13
|
+
def index
|
|
14
|
+
shipments = @cart.shipments.includes(shipping_rates: :shipping_method)
|
|
15
|
+
render json: {
|
|
16
|
+
data: shipments.map { |s| Spree.api.shipment_serializer.new(s, params: serializer_params).to_h },
|
|
17
|
+
meta: { count: shipments.size }
|
|
18
|
+
}
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# PATCH /api/v3/store/carts/:cart_id/shipments/:id
|
|
22
|
+
# Select a shipping rate for a specific shipment
|
|
23
|
+
def update
|
|
24
|
+
with_order_lock do
|
|
25
|
+
shipment = @cart.shipments.find_by_prefix_id!(params[:id])
|
|
26
|
+
|
|
27
|
+
if permitted_params[:selected_shipping_rate_id].present?
|
|
28
|
+
shipping_rate = shipment.shipping_rates.find_by_prefix_id!(permitted_params[:selected_shipping_rate_id])
|
|
29
|
+
shipment.selected_shipping_rate_id = shipping_rate.id
|
|
30
|
+
shipment.save!
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Auto-advance (e.g. delivery → payment) after rate selection.
|
|
34
|
+
# Temporary — Spree 6 removes the checkout state machine.
|
|
35
|
+
try_advance
|
|
36
|
+
|
|
37
|
+
render_cart
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def permitted_params
|
|
44
|
+
params.permit(:selected_shipping_rate_id)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Temporary — Spree 6 removes the checkout state machine.
|
|
48
|
+
def try_advance
|
|
49
|
+
return if @cart.complete? || @cart.canceled?
|
|
50
|
+
|
|
51
|
+
loop do
|
|
52
|
+
break unless @cart.next
|
|
53
|
+
break if @cart.confirm? || @cart.complete?
|
|
54
|
+
end
|
|
55
|
+
rescue StandardError => e
|
|
56
|
+
Rails.error.report(e, context: { order_id: @cart.id, state: @cart.state }, source: 'spree.checkout')
|
|
57
|
+
ensure
|
|
58
|
+
@cart.reload
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
@@ -2,38 +2,37 @@ module Spree
|
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
4
|
module Store
|
|
5
|
-
module
|
|
5
|
+
module Carts
|
|
6
6
|
class StoreCreditsController < Store::BaseController
|
|
7
|
-
include Spree::Api::V3::
|
|
7
|
+
include Spree::Api::V3::CartResolvable
|
|
8
8
|
include Spree::Api::V3::OrderLock
|
|
9
9
|
|
|
10
10
|
before_action :require_authentication!
|
|
11
|
-
before_action :
|
|
12
|
-
before_action :authorize_order_access!
|
|
11
|
+
before_action :find_cart!
|
|
13
12
|
|
|
14
|
-
# POST /api/v3/store/
|
|
13
|
+
# POST /api/v3/store/carts/:cart_id/store_credits
|
|
15
14
|
def create
|
|
16
15
|
with_order_lock do
|
|
17
16
|
result = Spree.checkout_add_store_credit_service.call(
|
|
18
|
-
order: @
|
|
17
|
+
order: @cart,
|
|
19
18
|
amount: params[:amount].try(:to_f)
|
|
20
19
|
)
|
|
21
20
|
|
|
22
21
|
if result.success?
|
|
23
|
-
|
|
22
|
+
render_cart
|
|
24
23
|
else
|
|
25
24
|
render_service_error(result.error)
|
|
26
25
|
end
|
|
27
26
|
end
|
|
28
27
|
end
|
|
29
28
|
|
|
30
|
-
# DELETE /api/v3/store/
|
|
29
|
+
# DELETE /api/v3/store/carts/:cart_id/store_credits
|
|
31
30
|
def destroy
|
|
32
31
|
with_order_lock do
|
|
33
|
-
result = Spree.checkout_remove_store_credit_service.call(order: @
|
|
32
|
+
result = Spree.checkout_remove_store_credit_service.call(order: @cart)
|
|
34
33
|
|
|
35
34
|
if result.success?
|
|
36
|
-
|
|
35
|
+
render_cart
|
|
37
36
|
else
|
|
38
37
|
render_service_error(result.error)
|
|
39
38
|
end
|