solidus_paypal_commerce_platform 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +41 -0
- data/.gem_release.yml +5 -0
- data/.github/stale.yml +17 -0
- data/.gitignore +20 -0
- data/.rspec +2 -0
- data/.rubocop.yml +56 -0
- data/Gemfile +33 -0
- data/LICENSE +26 -0
- data/README.md +173 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/spree/backend/solidus_paypal_commerce_platform.js +2 -0
- data/app/assets/javascripts/spree/backend/solidus_paypal_commerce_platform/namespace.js +1 -0
- data/app/assets/javascripts/spree/backend/solidus_paypal_commerce_platform/wizard.js +28 -0
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform.js +3 -0
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js +191 -0
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js +26 -0
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/namespace.js +1 -0
- data/app/assets/stylesheets/spree/backend/solidus_paypal_commerce_platform.css +4 -0
- data/app/assets/stylesheets/spree/frontend/solidus_paypal_commerce_platform.css +17 -0
- data/app/controllers/solidus_paypal_commerce_platform/orders_controller.rb +83 -0
- data/app/controllers/solidus_paypal_commerce_platform/payments_controller.rb +44 -0
- data/app/controllers/solidus_paypal_commerce_platform/paypal_orders_controller.rb +19 -0
- data/app/controllers/solidus_paypal_commerce_platform/shipping_rates_controller.rb +31 -0
- data/app/controllers/solidus_paypal_commerce_platform/wizard_controller.rb +47 -0
- data/app/decorators/solidus_paypal_commerce_platform/remove_required_phone_from_address.rb +13 -0
- data/app/helpers/solidus_paypal_commerce_platform/button_options_helper.rb +21 -0
- data/app/jobs/solidus_paypal_commerce_platform/application_job.rb +6 -0
- data/app/jobs/solidus_paypal_commerce_platform/webhook_job.rb +22 -0
- data/app/models/solidus_paypal_commerce_platform/gateway.rb +88 -0
- data/app/models/solidus_paypal_commerce_platform/payment_method.rb +75 -0
- data/app/models/solidus_paypal_commerce_platform/payment_source.rb +27 -0
- data/app/models/solidus_paypal_commerce_platform/paypal_address.rb +81 -0
- data/app/models/solidus_paypal_commerce_platform/paypal_order.rb +107 -0
- data/app/models/solidus_paypal_commerce_platform/pricing_options.rb +9 -0
- data/app/models/solidus_paypal_commerce_platform/wizard.rb +40 -0
- data/app/overrides/spree/admin/payment_methods/form/insert_email_verification_notification.rb +9 -0
- data/app/overrides/spree/admin/payment_methods/index/insert_setup_wizards.rb +17 -0
- data/app/overrides/spree/admin/payments/log_entries/add_paypal_debug_id.rb +9 -0
- data/app/overrides/spree/orders/edit/insert_cart_buttons.rb +9 -0
- data/app/overrides/spree/payments/payment/add_paypal_email_to_payment.rb +9 -0
- data/app/overrides/spree/products/cart_form/insert_product_buttons.rb +10 -0
- data/app/views/solidus_paypal_commerce_platform/admin/payment_methods/_available_to_users.html.erb +6 -0
- data/app/views/solidus_paypal_commerce_platform/admin/payment_methods/_paypal_wizard.html.erb +16 -0
- data/app/views/solidus_paypal_commerce_platform/admin/payment_methods/_setup_wizards.html.erb +16 -0
- data/app/views/solidus_paypal_commerce_platform/admin/payments/_log_entries.html.erb +32 -0
- data/bin/console +17 -0
- data/bin/rails +7 -0
- data/bin/rails-engine +13 -0
- data/bin/rails-sandbox +18 -0
- data/bin/rake +7 -0
- data/bin/sandbox +86 -0
- data/bin/setup +8 -0
- data/codecov.yml +14 -0
- data/config/locales/en.yml +37 -0
- data/config/routes.rb +12 -0
- data/db/migrate/20200521190038_add_paypal_commerce_platform_sources.rb +13 -0
- data/lib/generators/solidus_paypal_commerce_platform/install/install_generator.rb +38 -0
- data/lib/solidus_paypal_commerce_platform.rb +21 -0
- data/lib/solidus_paypal_commerce_platform/access_token_authorization_request.rb +21 -0
- data/lib/solidus_paypal_commerce_platform/client.rb +84 -0
- data/lib/solidus_paypal_commerce_platform/configuration.rb +64 -0
- data/lib/solidus_paypal_commerce_platform/engine.rb +45 -0
- data/lib/solidus_paypal_commerce_platform/factories.rb +14 -0
- data/lib/solidus_paypal_commerce_platform/fetch_merchant_credentials_request.rb +17 -0
- data/lib/solidus_paypal_commerce_platform/version.rb +5 -0
- data/lib/views/api/spree/api/payments/source_views/_paypal_commerce_platform.json.jbuilder +3 -0
- data/lib/views/backend/spree/admin/payments/source_forms/_paypal_commerce_platform.html.erb +1 -0
- data/lib/views/backend/spree/admin/payments/source_views/_paypal_commerce_platform.html.erb +18 -0
- data/lib/views/backend/spree/admin/shared/preference_fields/_paypal_select.html.erb +13 -0
- data/lib/views/frontend/solidus_paypal_commerce_platform/cart/_cart_buttons.html.erb +3 -0
- data/lib/views/frontend/solidus_paypal_commerce_platform/payments/_payment.html.erb +4 -0
- data/lib/views/frontend/solidus_paypal_commerce_platform/product/_product_buttons.html.erb +3 -0
- data/lib/views/frontend/spree/checkout/payment/_paypal_commerce_platform.html.erb +13 -0
- data/lib/views/frontend/spree/orders/payment/_paypal_commerce_platform.html.erb +17 -0
- data/lib/views/frontend/spree/products/payment/_paypal_commerce_platform.html.erb +15 -0
- data/solidus_paypal_commerce_platform.gemspec +39 -0
- data/spec/features/backend/new_payment_method_spec.rb +40 -0
- data/spec/features/frontend/cart_spec.rb +38 -0
- data/spec/features/frontend/checkout_spec.rb +81 -0
- data/spec/features/frontend/product_spec.rb +79 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.COMPLETED.v2.json +121 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.PROCESSED.v2.json +121 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v1.json +50 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v2.json +72 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v1.json +50 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v2.json +68 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v1.json +51 -0
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v2.json +63 -0
- data/spec/jobs/solidus_paypal_commerce_platform/webhook_job_spec.rb +44 -0
- data/spec/lib/solidus_paypal_commerce_platform/client_spec.rb +21 -0
- data/spec/lib/solidus_paypal_commerce_platform/configuration_spec.rb +67 -0
- data/spec/models/solidus_paypal_commerce_platform/payment_method_spec.rb +102 -0
- data/spec/models/solidus_paypal_commerce_platform/payment_source_spec.rb +62 -0
- data/spec/models/solidus_paypal_commerce_platform/paypal_address_spec.rb +55 -0
- data/spec/models/solidus_paypal_commerce_platform/wizard_spec.rb +9 -0
- data/spec/requests/solidus_paypal_commerce_platform/orders_controller_spec.rb +36 -0
- data/spec/requests/solidus_paypal_commerce_platform/shipping_rates_controller_spec.rb +44 -0
- data/spec/requests/solidus_paypal_commerce_platform/wizard_controller_spec.rb +44 -0
- data/spec/spec_helper.rb +30 -0
- 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,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,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
|