spree_api 5.4.0.beta6 → 5.4.0.beta7
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 +20 -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/orders_controller.rb +21 -114
- data/app/controllers/spree/api/v3/webhooks/payments_controller.rb +52 -0
- data/app/serializers/spree/api/v3/admin/order_serializer.rb +2 -2
- 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/order_serializer.rb +7 -9
- data/config/routes.rb +21 -24
- data/lib/spree/api/dependencies.rb +2 -0
- data/lib/spree/api/openapi/schema_helper.rb +28 -0
- metadata +18 -15
- 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
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6f27a3d636c9e7fdac4e297ba4820d97f91831b4124a1b6aafcc734b4f3906bc
|
|
4
|
+
data.tar.gz: a436eac6eee920191894f256c587c12f852b5b86f3a978d6af43f032cff1908b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: adce2c15462e5c368813c95419047c83e686254e93af752832e370a2ed19aa7f5893659ed8b79c982bbe37294695b245d87671d196d93e92d759b9d8fe79caa9
|
|
7
|
+
data.tar.gz: 1cdec354c04bd65e731b2ee0309170e597012047ede52184ca0cbe2f8323d9af4c0f5ed967cb13fade6c74c3a1206aa058a803992c983b1ae351fc887f77b934
|
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
|
|
@@ -18,13 +18,16 @@ module Spree
|
|
|
18
18
|
record_not_found: 'record_not_found',
|
|
19
19
|
resource_invalid: 'resource_invalid',
|
|
20
20
|
|
|
21
|
+
# Cart errors
|
|
22
|
+
cart_not_found: 'cart_not_found',
|
|
23
|
+
cart_cannot_transition: 'cart_cannot_transition',
|
|
24
|
+
cart_empty: 'cart_empty',
|
|
25
|
+
cart_invalid_state: 'cart_invalid_state',
|
|
26
|
+
cart_already_updated: 'cart_already_updated',
|
|
27
|
+
cart_cannot_complete: 'cart_cannot_complete',
|
|
28
|
+
|
|
21
29
|
# Order errors
|
|
22
30
|
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
31
|
|
|
29
32
|
# Line item errors
|
|
30
33
|
line_item_not_found: 'line_item_not_found',
|
|
@@ -191,7 +194,7 @@ module Spree
|
|
|
191
194
|
def handle_invalid_transition(exception)
|
|
192
195
|
Rails.error.report(exception, context: error_context, source: 'spree.api.v3')
|
|
193
196
|
render_error(
|
|
194
|
-
code: ERROR_CODES[:
|
|
197
|
+
code: ERROR_CODES[:cart_cannot_transition],
|
|
195
198
|
message: exception.message,
|
|
196
199
|
status: :unprocessable_content
|
|
197
200
|
)
|
|
@@ -229,7 +232,7 @@ module Spree
|
|
|
229
232
|
|
|
230
233
|
case model_name
|
|
231
234
|
when 'order'
|
|
232
|
-
ERROR_CODES[:order_not_found]
|
|
235
|
+
request.path.include?('/carts') ? ERROR_CODES[:cart_not_found] : ERROR_CODES[:order_not_found]
|
|
233
236
|
when 'line_item'
|
|
234
237
|
ERROR_CODES[:line_item_not_found]
|
|
235
238
|
when 'variant'
|
|
@@ -240,15 +243,17 @@ module Spree
|
|
|
240
243
|
end
|
|
241
244
|
|
|
242
245
|
# 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
246
|
def generate_not_found_message(exception)
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
247
|
+
model_name = extract_model_name(exception)
|
|
248
|
+
|
|
249
|
+
# Use "Cart" for order models in cart context
|
|
250
|
+
label = if model_name == 'order' && request.path.include?('/carts')
|
|
251
|
+
'Cart'
|
|
252
|
+
else
|
|
253
|
+
model_name&.humanize || 'record'
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
Spree.t(:record_not_found, scope: 'api', model: label)
|
|
252
257
|
end
|
|
253
258
|
|
|
254
259
|
# 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
|