From e09d864ad978dc49a50894479343e232f958259d Mon Sep 17 00:00:00 2001 From: Sean Date: Mon, 10 Aug 2020 10:48:13 -0500 Subject: [PATCH] Add better error handling to button_actions.js Previously, if an error occurred in the send_order function - like if the order does not total up correctly - the user would see the PayPal loading screen forever. This handles the error - closing the PayPal screen when they occur - and logging the error + debug ID both to console and to the Rails logger. This also ensures that an address is rejected if there is an issue sending the updated order details to PayPal, otherwise PayPal would allow paying for an order with address issues. --- .../button_actions.js | 18 ++++++++++++++---- .../buttons.js | 9 ++++++--- .../paypal_orders_controller.rb | 4 +++- .../gateway.rb | 3 +-- lib/solidus_paypal_commerce_platform/client.rb | 5 +++-- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js b/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js index 6da6c15b..88fd5ead 100644 --- a/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js +++ b/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js @@ -6,6 +6,12 @@ SolidusPaypalCommercePlatform.hideOverlay = function() { document.getElementById("paypal_commerce_platform_overlay").style.display = "none"; } +SolidusPaypalCommercePlatform.handleError = function(error) { + console.log(error.name, error.message) + console.log("PayPal Debug ID: " + error.debug_id) + alert("There was a problem connecting with PayPal.") +} + SolidusPaypalCommercePlatform.sendOrder = function(payment_method_id) { return Spree.ajax({ url: '/solidus_paypal_commerce_platform/paypal_orders/' + Spree.current_order_id, @@ -14,8 +20,10 @@ SolidusPaypalCommercePlatform.sendOrder = function(payment_method_id) { payment_method_id: payment_method_id, order_token: Spree.current_order_token } - }).then(function(response) { - return response.table.id; + }).then(function(success_response) { + return success_response.table.result.table.id + }, function(failure_response) { + return failure_response.responseJSON.table.error.table }) } @@ -97,8 +105,10 @@ SolidusPaypalCommercePlatform.shippingChange = function(data, actions) { actions.reject() } }).then(function(response) { - actions.order.patch([response]); - }); + actions.order.patch([response]).catch(function() { + actions.reject() + }) + }) } SolidusPaypalCommercePlatform.verifyTotal = function(paypal_total) { diff --git a/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js b/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js index bff8a170..5d020bd6 100644 --- a/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js +++ b/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js @@ -3,7 +3,8 @@ SolidusPaypalCommercePlatform.renderButton = function(payment_method_id, style) style: style, createOrder: SolidusPaypalCommercePlatform.sendOrder.bind(null, payment_method_id), onApprove: SolidusPaypalCommercePlatform.approveOrder, - onShippingChange: SolidusPaypalCommercePlatform.shippingChange + onShippingChange: SolidusPaypalCommercePlatform.shippingChange, + onError: SolidusPaypalCommercePlatform.handleError }).render('#paypal-button-container') } @@ -12,7 +13,8 @@ SolidusPaypalCommercePlatform.renderCartButton = function(payment_method_id, sty style: style, createOrder: SolidusPaypalCommercePlatform.sendOrder.bind(null, payment_method_id), onApprove: SolidusPaypalCommercePlatform.finalizeOrder.bind(null, payment_method_id), - onShippingChange: SolidusPaypalCommercePlatform.shippingChange + onShippingChange: SolidusPaypalCommercePlatform.shippingChange, + onError: SolidusPaypalCommercePlatform.handleError }).render('#paypal-button-container') } @@ -21,6 +23,7 @@ SolidusPaypalCommercePlatform.renderProductButton = function(payment_method_id, style: style, createOrder: SolidusPaypalCommercePlatform.createAndSendOrder.bind(null, payment_method_id), onApprove: SolidusPaypalCommercePlatform.finalizeOrder.bind(null, payment_method_id), - onShippingChange: SolidusPaypalCommercePlatform.shippingChange + onShippingChange: SolidusPaypalCommercePlatform.shippingChange, + onError: SolidusPaypalCommercePlatform.handleError }).render('#paypal-button-container') } diff --git a/app/controllers/solidus_paypal_commerce_platform/paypal_orders_controller.rb b/app/controllers/solidus_paypal_commerce_platform/paypal_orders_controller.rb index 9e51167e..f2f09cbe 100644 --- a/app/controllers/solidus_paypal_commerce_platform/paypal_orders_controller.rb +++ b/app/controllers/solidus_paypal_commerce_platform/paypal_orders_controller.rb @@ -7,7 +7,9 @@ class PaypalOrdersController < ::Spree::Api::BaseController def show authorize! :show, @order, order_token - render json: @payment_method.gateway.create_order(@order, @payment_method.auto_capture), status: :ok + order_request = @payment_method.gateway.create_order(@order, @payment_method.auto_capture) + + render json: order_request, status: order_request.status_code end private diff --git a/app/models/solidus_paypal_commerce_platform/gateway.rb b/app/models/solidus_paypal_commerce_platform/gateway.rb index 4a3221cf..a007b81c 100644 --- a/app/models/solidus_paypal_commerce_platform/gateway.rb +++ b/app/models/solidus_paypal_commerce_platform/gateway.rb @@ -77,8 +77,7 @@ def create_order(order, auto_capture) request = OrdersCreateRequest.new paypal_order = SolidusPaypalCommercePlatform::PaypalOrder.new(order) request.request_body paypal_order.to_json(intent) - - @client.execute(request).result + @client.execute(request) end def get_order(order_id) diff --git a/lib/solidus_paypal_commerce_platform/client.rb b/lib/solidus_paypal_commerce_platform/client.rb index a0180020..465c90d8 100644 --- a/lib/solidus_paypal_commerce_platform/client.rb +++ b/lib/solidus_paypal_commerce_platform/client.rb @@ -27,8 +27,9 @@ def initialize(test_mode: nil, client_id:, client_secret: "") def execute(request) @paypal_client.execute(request) - rescue PayPalHttp::HttpError - OpenStruct.new(status_code: nil) + rescue PayPalHttp::HttpError => e + Rails.logger.error e.result + OpenStruct.new(status_code: 422, error: e.result) end def execute_with_response(request, success_message: nil, failure_message: nil)