solidus_paypal_commerce_platform 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +41 -0
  3. data/.gem_release.yml +5 -0
  4. data/.github/stale.yml +17 -0
  5. data/.gitignore +20 -0
  6. data/.rspec +2 -0
  7. data/.rubocop.yml +56 -0
  8. data/Gemfile +33 -0
  9. data/LICENSE +26 -0
  10. data/README.md +173 -0
  11. data/Rakefile +6 -0
  12. data/app/assets/javascripts/spree/backend/solidus_paypal_commerce_platform.js +2 -0
  13. data/app/assets/javascripts/spree/backend/solidus_paypal_commerce_platform/namespace.js +1 -0
  14. data/app/assets/javascripts/spree/backend/solidus_paypal_commerce_platform/wizard.js +28 -0
  15. data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform.js +3 -0
  16. data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js +191 -0
  17. data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js +26 -0
  18. data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/namespace.js +1 -0
  19. data/app/assets/stylesheets/spree/backend/solidus_paypal_commerce_platform.css +4 -0
  20. data/app/assets/stylesheets/spree/frontend/solidus_paypal_commerce_platform.css +17 -0
  21. data/app/controllers/solidus_paypal_commerce_platform/orders_controller.rb +83 -0
  22. data/app/controllers/solidus_paypal_commerce_platform/payments_controller.rb +44 -0
  23. data/app/controllers/solidus_paypal_commerce_platform/paypal_orders_controller.rb +19 -0
  24. data/app/controllers/solidus_paypal_commerce_platform/shipping_rates_controller.rb +31 -0
  25. data/app/controllers/solidus_paypal_commerce_platform/wizard_controller.rb +47 -0
  26. data/app/decorators/solidus_paypal_commerce_platform/remove_required_phone_from_address.rb +13 -0
  27. data/app/helpers/solidus_paypal_commerce_platform/button_options_helper.rb +21 -0
  28. data/app/jobs/solidus_paypal_commerce_platform/application_job.rb +6 -0
  29. data/app/jobs/solidus_paypal_commerce_platform/webhook_job.rb +22 -0
  30. data/app/models/solidus_paypal_commerce_platform/gateway.rb +88 -0
  31. data/app/models/solidus_paypal_commerce_platform/payment_method.rb +75 -0
  32. data/app/models/solidus_paypal_commerce_platform/payment_source.rb +27 -0
  33. data/app/models/solidus_paypal_commerce_platform/paypal_address.rb +81 -0
  34. data/app/models/solidus_paypal_commerce_platform/paypal_order.rb +107 -0
  35. data/app/models/solidus_paypal_commerce_platform/pricing_options.rb +9 -0
  36. data/app/models/solidus_paypal_commerce_platform/wizard.rb +40 -0
  37. data/app/overrides/spree/admin/payment_methods/form/insert_email_verification_notification.rb +9 -0
  38. data/app/overrides/spree/admin/payment_methods/index/insert_setup_wizards.rb +17 -0
  39. data/app/overrides/spree/admin/payments/log_entries/add_paypal_debug_id.rb +9 -0
  40. data/app/overrides/spree/orders/edit/insert_cart_buttons.rb +9 -0
  41. data/app/overrides/spree/payments/payment/add_paypal_email_to_payment.rb +9 -0
  42. data/app/overrides/spree/products/cart_form/insert_product_buttons.rb +10 -0
  43. data/app/views/solidus_paypal_commerce_platform/admin/payment_methods/_available_to_users.html.erb +6 -0
  44. data/app/views/solidus_paypal_commerce_platform/admin/payment_methods/_paypal_wizard.html.erb +16 -0
  45. data/app/views/solidus_paypal_commerce_platform/admin/payment_methods/_setup_wizards.html.erb +16 -0
  46. data/app/views/solidus_paypal_commerce_platform/admin/payments/_log_entries.html.erb +32 -0
  47. data/bin/console +17 -0
  48. data/bin/rails +7 -0
  49. data/bin/rails-engine +13 -0
  50. data/bin/rails-sandbox +18 -0
  51. data/bin/rake +7 -0
  52. data/bin/sandbox +86 -0
  53. data/bin/setup +8 -0
  54. data/codecov.yml +14 -0
  55. data/config/locales/en.yml +37 -0
  56. data/config/routes.rb +12 -0
  57. data/db/migrate/20200521190038_add_paypal_commerce_platform_sources.rb +13 -0
  58. data/lib/generators/solidus_paypal_commerce_platform/install/install_generator.rb +38 -0
  59. data/lib/solidus_paypal_commerce_platform.rb +21 -0
  60. data/lib/solidus_paypal_commerce_platform/access_token_authorization_request.rb +21 -0
  61. data/lib/solidus_paypal_commerce_platform/client.rb +84 -0
  62. data/lib/solidus_paypal_commerce_platform/configuration.rb +64 -0
  63. data/lib/solidus_paypal_commerce_platform/engine.rb +45 -0
  64. data/lib/solidus_paypal_commerce_platform/factories.rb +14 -0
  65. data/lib/solidus_paypal_commerce_platform/fetch_merchant_credentials_request.rb +17 -0
  66. data/lib/solidus_paypal_commerce_platform/version.rb +5 -0
  67. data/lib/views/api/spree/api/payments/source_views/_paypal_commerce_platform.json.jbuilder +3 -0
  68. data/lib/views/backend/spree/admin/payments/source_forms/_paypal_commerce_platform.html.erb +1 -0
  69. data/lib/views/backend/spree/admin/payments/source_views/_paypal_commerce_platform.html.erb +18 -0
  70. data/lib/views/backend/spree/admin/shared/preference_fields/_paypal_select.html.erb +13 -0
  71. data/lib/views/frontend/solidus_paypal_commerce_platform/cart/_cart_buttons.html.erb +3 -0
  72. data/lib/views/frontend/solidus_paypal_commerce_platform/payments/_payment.html.erb +4 -0
  73. data/lib/views/frontend/solidus_paypal_commerce_platform/product/_product_buttons.html.erb +3 -0
  74. data/lib/views/frontend/spree/checkout/payment/_paypal_commerce_platform.html.erb +13 -0
  75. data/lib/views/frontend/spree/orders/payment/_paypal_commerce_platform.html.erb +17 -0
  76. data/lib/views/frontend/spree/products/payment/_paypal_commerce_platform.html.erb +15 -0
  77. data/solidus_paypal_commerce_platform.gemspec +39 -0
  78. data/spec/features/backend/new_payment_method_spec.rb +40 -0
  79. data/spec/features/frontend/cart_spec.rb +38 -0
  80. data/spec/features/frontend/checkout_spec.rb +81 -0
  81. data/spec/features/frontend/product_spec.rb +79 -0
  82. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.COMPLETED.v2.json +121 -0
  83. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.PROCESSED.v2.json +121 -0
  84. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v1.json +50 -0
  85. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v2.json +72 -0
  86. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v1.json +50 -0
  87. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v2.json +68 -0
  88. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v1.json +51 -0
  89. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v2.json +63 -0
  90. data/spec/jobs/solidus_paypal_commerce_platform/webhook_job_spec.rb +44 -0
  91. data/spec/lib/solidus_paypal_commerce_platform/client_spec.rb +21 -0
  92. data/spec/lib/solidus_paypal_commerce_platform/configuration_spec.rb +67 -0
  93. data/spec/models/solidus_paypal_commerce_platform/payment_method_spec.rb +102 -0
  94. data/spec/models/solidus_paypal_commerce_platform/payment_source_spec.rb +62 -0
  95. data/spec/models/solidus_paypal_commerce_platform/paypal_address_spec.rb +55 -0
  96. data/spec/models/solidus_paypal_commerce_platform/wizard_spec.rb +9 -0
  97. data/spec/requests/solidus_paypal_commerce_platform/orders_controller_spec.rb +36 -0
  98. data/spec/requests/solidus_paypal_commerce_platform/shipping_rates_controller_spec.rb +44 -0
  99. data/spec/requests/solidus_paypal_commerce_platform/wizard_controller_spec.rb +44 -0
  100. data/spec/spec_helper.rb +30 -0
  101. metadata +258 -0
@@ -0,0 +1,26 @@
1
+ SolidusPaypalCommercePlatform.renderButton = function(payment_method_id, style) {
2
+ paypal.Buttons({
3
+ style: style,
4
+ createOrder: SolidusPaypalCommercePlatform.sendOrder.bind(null, payment_method_id),
5
+ onApprove: SolidusPaypalCommercePlatform.approveOrder,
6
+ onShippingChange: SolidusPaypalCommercePlatform.shippingChange
7
+ }).render('#paypal-button-container')
8
+ }
9
+
10
+ SolidusPaypalCommercePlatform.renderCartButton = function(payment_method_id, style) {
11
+ paypal.Buttons({
12
+ style: style,
13
+ createOrder: SolidusPaypalCommercePlatform.sendOrder.bind(null, payment_method_id),
14
+ onApprove: SolidusPaypalCommercePlatform.finalizeOrder.bind(null, payment_method_id),
15
+ onShippingChange: SolidusPaypalCommercePlatform.shippingChange
16
+ }).render('#paypal-button-container')
17
+ }
18
+
19
+ SolidusPaypalCommercePlatform.renderProductButton = function(payment_method_id, style) {
20
+ paypal.Buttons({
21
+ style: style,
22
+ createOrder: SolidusPaypalCommercePlatform.createAndSendOrder.bind(null, payment_method_id),
23
+ onApprove: SolidusPaypalCommercePlatform.finalizeOrder.bind(null, payment_method_id),
24
+ onShippingChange: SolidusPaypalCommercePlatform.shippingChange
25
+ }).render('#paypal-button-container')
26
+ }
@@ -0,0 +1 @@
1
+ window.SolidusPaypalCommercePlatform = {}
@@ -0,0 +1,4 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/backend/all.css'
4
+ */
@@ -0,0 +1,17 @@
1
+ /*
2
+ Placeholder manifest file.
3
+ the installer will append this file to the app vendored assets here: 'vendor/assets/stylesheets/spree/frontend/all.css'
4
+ */
5
+
6
+ #paypal_commerce_platform_overlay{
7
+ position: fixed;
8
+ display: none;
9
+ width: 100%;
10
+ height: 100%;
11
+ top: 0;
12
+ left: 0;
13
+ right: 0;
14
+ bottom: 0;
15
+ background-color: rgba(0, 0, 0, 0.8);
16
+ z-index: 100;
17
+ }
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalCommercePlatform
4
+ class OrdersController < ::Spree::Api::BaseController
5
+ before_action :load_order, except: :create
6
+ skip_before_action :authenticate_user
7
+ include ::Spree::Core::ControllerHelpers::Auth
8
+
9
+ def create
10
+ authorize! :create, ::Spree::Order
11
+
12
+ @order = ::Spree::Order.create!(
13
+ user: try_spree_current_user,
14
+ store: current_store
15
+ )
16
+
17
+ if @order.contents.update_cart order_params
18
+ # Overriding any existing orders
19
+ cookies.signed[:guest_token] = @order.guest_token
20
+ render json: @order, status: :ok
21
+ else
22
+ render json: @order.errors.full_messages, status: :unprocessable_entity
23
+ end
24
+ end
25
+
26
+ def update_address
27
+ authorize! :update, @order, order_token
28
+ paypal_address = SolidusPaypalCommercePlatform::PaypalAddress.new(@order)
29
+
30
+ if paypal_address.update(paypal_address_params).valid?
31
+ @order.ensure_updated_shipments
32
+ @order.contents.advance
33
+ render json: {}, status: :ok
34
+ else
35
+ render json: paypal_address.errors.full_messages, status: :unprocessable_entity
36
+ end
37
+ end
38
+
39
+ def verify_total
40
+ authorize! :show, @order, order_token
41
+
42
+ if total_is_correct?(params[:paypal_total])
43
+ render json: {}, status: :ok
44
+ else
45
+ respond_with(@order, default_template: 'spree/api/orders/expected_total_mismatch', status: 400)
46
+ end
47
+ end
48
+
49
+ private
50
+
51
+ def total_is_correct?(paypal_total)
52
+ @order.total == BigDecimal(paypal_total)
53
+ end
54
+
55
+ def paypal_address_params
56
+ params.require(:address).permit(
57
+ updated_address: [
58
+ :address_line_1,
59
+ :address_line_2,
60
+ :admin_area_1,
61
+ :admin_area_2,
62
+ :postal_code,
63
+ :country_code,
64
+ ],
65
+ recipient: [
66
+ :email_address,
67
+ name: [
68
+ :given_name,
69
+ :surname,
70
+ ]
71
+ ]
72
+ )
73
+ end
74
+
75
+ def order_params
76
+ params.require(:order).permit(permitted_order_attributes)
77
+ end
78
+
79
+ def load_order
80
+ @order = ::Spree::Order.find_by!(number: params[:order_id])
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalCommercePlatform
4
+ class PaymentsController < ::Spree::Api::BaseController
5
+ before_action :load_order
6
+ skip_before_action :authenticate_user
7
+
8
+ def create
9
+ authorize! :update, @order, order_token
10
+ paypal_order_id = paypal_params[:paypal_order_id]
11
+
12
+ if !paypal_order_id
13
+ return redirect_to checkout_state_path(@order.state), notice: "Invalid order confirmation data passed in"
14
+ end
15
+
16
+ if @order.complete?
17
+ return redirect_to spree.order_path(@order), notice: "Order is already in complete state"
18
+ end
19
+
20
+ source = SolidusPaypalCommercePlatform::PaymentSource.new(paypal_order_id: paypal_order_id)
21
+
22
+ source.transaction do
23
+ if source.save!
24
+ @order.payments.create!(
25
+ payment_method_id: paypal_params[:payment_method_id],
26
+ source: source
27
+ )
28
+
29
+ render json: {}, status: :ok
30
+ end
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def paypal_params
37
+ params.permit(:paypal_order_id, :order_id, :order_token, :payment_method_id)
38
+ end
39
+
40
+ def load_order
41
+ @order = ::Spree::Order.find_by!(number: params[:order_id])
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalCommercePlatform
4
+ class PaypalOrdersController < ::Spree::Api::BaseController
5
+ before_action :load_payment_method
6
+ skip_before_action :authenticate_user
7
+
8
+ def show
9
+ authorize! :show, @order, order_token
10
+ render json: @payment_method.gateway.create_order(@order, @payment_method.auto_capture), status: :ok
11
+ end
12
+
13
+ private
14
+
15
+ def load_payment_method
16
+ @payment_method = ::Spree::PaymentMethod.find(params[:payment_method_id])
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalCommercePlatform
4
+ class ShippingRatesController < ::Spree::Api::BaseController
5
+ before_action :load_order
6
+ skip_before_action :authenticate_user
7
+
8
+ def simulate_shipping_rates
9
+ authorize! :show, @order, order_token
10
+
11
+ @order.transaction do
12
+ SolidusPaypalCommercePlatform::PaypalAddress.new(@order).simulate_update(params[:address])
13
+ @errors = @order.ship_address.errors.dup
14
+ @paypal_order = SolidusPaypalCommercePlatform::PaypalOrder.new(@order).to_replace_json
15
+ raise ActiveRecord::Rollback
16
+ end
17
+
18
+ if @errors.none?
19
+ render json: @paypal_order, status: :ok
20
+ else
21
+ render json: @errors.full_messages, status: :unprocessable_entity
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def load_order
28
+ @order = ::Spree::Order.find_by(number: params[:order_id])
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalCommercePlatform
4
+ class WizardController < ::Spree::Api::BaseController
5
+ helper ::Spree::Core::Engine.routes.url_helpers
6
+
7
+ def create
8
+ authorize! :create, ::Spree::PaymentMethod
9
+
10
+ @payment_method = ::Spree::PaymentMethod.new(payment_method_params)
11
+
12
+ if @payment_method.save
13
+ edit_url = spree.edit_admin_payment_method_url(@payment_method)
14
+
15
+ render(
16
+ json: { redirectUrl: edit_url },
17
+ status: :created,
18
+ location: edit_url,
19
+ notice: "The PayPal Commerce Platform payment method has been successfully created"
20
+ )
21
+ else
22
+ render json: @payment_method.errors, status: :unprocessable_entity
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def payment_method_params
29
+ {
30
+ name: "PayPal Commerce Platform",
31
+ type: SolidusPaypalCommercePlatform::PaymentMethod,
32
+ preferred_client_id: api_credentials.client_id,
33
+ preferred_client_secret: api_credentials.client_secret,
34
+ preferred_test_mode: SolidusPaypalCommercePlatform.config.env.sandbox?,
35
+ available_to_admin: false,
36
+ }
37
+ end
38
+
39
+ def api_credentials
40
+ @api_credentials ||= SolidusPaypalCommercePlatform::Client.fetch_api_credentials(
41
+ auth_code: params.fetch(:authCode),
42
+ client_id: params.fetch(:sharedId),
43
+ nonce: params.fetch(:nonce),
44
+ )
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RemoveRequiredPhoneFromAddress
4
+ # PayPal doesn't use the phone number, so in cases where the user checks out via
5
+ # PayPal, this field will be unpopulated. If you want to require phone numbers,
6
+ # you'll need to turn off cart & product page displays on the payment method edit
7
+ # page.
8
+ def require_phone?
9
+ super && false
10
+ end
11
+
12
+ ::Spree::Address.prepend self
13
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalCommercePlatform
4
+ module ButtonOptionsHelper
5
+ def preferred_paypal_button_color_options
6
+ [["Gold", "gold"], ["Blue", "blue"], ["Silver", "silver"], ["White", "white"], ["Black", "black"]]
7
+ end
8
+
9
+ def preferred_paypal_button_size_options
10
+ [["Small", "small"], ["Medium", "medium"], ["Large", "large"], ["Responsive", "responsive"]]
11
+ end
12
+
13
+ def preferred_paypal_button_shape_options
14
+ [["Pill", "pill"], ["Rectangular", "rect"]]
15
+ end
16
+
17
+ def preferred_paypal_button_layout_options
18
+ [["Vertical", "vertical"], ["Horizontal", "horizontal"]]
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalCommercePlatform
4
+ class ApplicationJob < ActiveJob::Base
5
+ end
6
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalCommercePlatform
4
+ class WebhookJob < SolidusPaypalCommercePlatform::ApplicationJob
5
+ def perform(payload)
6
+ case payload["resource_type"]
7
+ when "checkout-order"
8
+ payment_source = PaymentSource.find_by!(paypal_order_id: payload.dig("resource", "id"))
9
+ payment = Spree::Payment.where(source: payment_source).last!
10
+ payment.log_entries.create!(details: payload.to_yaml)
11
+ when "capture"
12
+ payment_source = PaymentSource.find_by!(capture_id: payload.dig("resource", "id"))
13
+ payment = Spree::Payment.where(source: payment_source).last!
14
+ payment.log_entries.create!(details: payload.to_yaml)
15
+ when "refund"
16
+ payment_source = PaymentSource.find_by!(refund_id: payload.dig("resource", "id"))
17
+ payment = Spree::Payment.where(source: payment_source).last!
18
+ payment.log_entries.create!(details: payload.to_yaml)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'paypal-checkout-sdk'
4
+
5
+ module SolidusPaypalCommercePlatform
6
+ class Gateway
7
+ include PayPalCheckoutSdk::Orders
8
+ include PayPalCheckoutSdk::Payments
9
+
10
+ def initialize(options)
11
+ # Cannot use kwargs because of how the Gateway is initialize by Solidus.
12
+ @client = Client.new(
13
+ test_mode: options.fetch(:test_mode, nil),
14
+ client_id: options.fetch(:client_id),
15
+ client_secret: options.fetch(:client_secret),
16
+ )
17
+ @options = options
18
+ end
19
+
20
+ def purchase(money, source, options)
21
+ request = OrdersCaptureRequest.new(source.paypal_order_id)
22
+ request.request_body(amount: { currency_code: options[:currency], value: Money.new(money).dollars })
23
+
24
+ response = @client.execute_with_response(request)
25
+ if response.success?
26
+ capture_id = response.params["result"].purchase_units[0].payments.captures[0].id
27
+ source.update(capture_id: capture_id)
28
+ end
29
+ response
30
+ end
31
+
32
+ def authorize(_money, source, _options)
33
+ request = OrdersAuthorizeRequest.new(source.paypal_order_id)
34
+
35
+ response = @client.execute_with_response(request)
36
+ if response.success?
37
+ authorization_id = response.params["result"].purchase_units[0].payments.authorizations[0].id
38
+ source.update(authorization_id: authorization_id)
39
+ end
40
+ response
41
+ end
42
+
43
+ def capture(money, _response_code, options)
44
+ source = options[:originator].source
45
+ request = AuthorizationsCaptureRequest.new(source.authorization_id)
46
+ request.request_body(amount: { currency_code: options[:currency], value: Money.new(money).dollars })
47
+
48
+ response = @client.execute_with_response(request)
49
+ if response.success?
50
+ source.update(capture_id: response.params["result"].id)
51
+ end
52
+ response
53
+ end
54
+
55
+ def credit(_money_cents, _transaction_id, options)
56
+ refund = options[:originator]
57
+ source = refund.payment.source
58
+ capture_id = source.capture_id
59
+ request = CapturesRefundRequest.new(capture_id)
60
+ request.request_body(amount: { currency_code: refund.currency, value: refund.amount })
61
+ message = I18n.t('success', scope: @client.i18n_scope_for(request), amount: refund.amount)
62
+
63
+ response = @client.execute_with_response(request, success_message: message)
64
+ source.update(refund_id: response.params["result"].id) if response.success?
65
+ response
66
+ end
67
+
68
+ def void(_response_code, options)
69
+ authorization_id = options[:originator].source.authorization_id
70
+ request = AuthorizationsVoidRequest.new(authorization_id)
71
+
72
+ @client.execute_with_response(request)
73
+ end
74
+
75
+ def create_order(order, auto_capture)
76
+ intent = auto_capture ? "CAPTURE" : "AUTHORIZE"
77
+ request = OrdersCreateRequest.new
78
+ paypal_order = SolidusPaypalCommercePlatform::PaypalOrder.new(order)
79
+ request.request_body paypal_order.to_json(intent)
80
+
81
+ @client.execute(request).result
82
+ end
83
+
84
+ def get_order(order_id)
85
+ @client.execute(OrdersGetRequest.new(order_id)).result
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidusPaypalCommercePlatform
4
+ class PaymentMethod < SolidusSupport.payment_method_parent_class
5
+ include SolidusPaypalCommercePlatform::ButtonOptionsHelper
6
+ preference :client_id, :string
7
+ preference :client_secret, :string
8
+ preference :paypal_button_color, :paypal_select, default: "gold"
9
+ preference :paypal_button_size, :paypal_select, default: "responsive"
10
+ preference :paypal_button_shape, :paypal_select, default: "rect"
11
+ preference :paypal_button_layout, :paypal_select, default: "vertical"
12
+ preference :display_on_cart, :boolean, default: true
13
+ preference :display_on_product_page, :boolean, default: true
14
+
15
+ def partial_name
16
+ "paypal_commerce_platform"
17
+ end
18
+
19
+ def display_on_cart
20
+ options[:display_on_cart] || false
21
+ end
22
+
23
+ def cart_partial_name
24
+ "paypal_commerce_platform"
25
+ end
26
+
27
+ def display_on_product_page
28
+ options[:display_on_product_page] || false
29
+ end
30
+
31
+ def product_page_partial_name
32
+ "paypal_commerce_platform"
33
+ end
34
+
35
+ def client_id
36
+ options[:client_id]
37
+ end
38
+
39
+ def client_secret
40
+ options[:client_secret]
41
+ end
42
+
43
+ def payment_source_class
44
+ PaymentSource
45
+ end
46
+
47
+ def gateway_class
48
+ Gateway
49
+ end
50
+
51
+ def button_style
52
+ {
53
+ color: options[:paypal_button_color] || "gold",
54
+ size: options[:paypal_button_size] || "responsive",
55
+ shape: options[:paypal_button_shape] || "rect",
56
+ layout: options[:paypal_button_layout] || "vertical"
57
+ }
58
+ end
59
+
60
+ def javascript_sdk_url(order: nil)
61
+ # Both instance and class respond to checkout_steps.
62
+ step_names = order ? order.checkout_steps : ::Spree::Order.checkout_steps.keys
63
+
64
+ commit_immediately = step_names.include? "confirm"
65
+
66
+ parameters = {
67
+ 'client-id': client_id,
68
+ intent: auto_capture ? "capture" : "authorize",
69
+ commit: commit_immediately ? "false" : "true",
70
+ }
71
+
72
+ "https://www.paypal.com/sdk/js?#{parameters.to_query}"
73
+ end
74
+ end
75
+ end