solidus_paypal_commerce_platform 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +4 -0
  3. data/.rubocop.yml +4 -4
  4. data/CHANGELOG.md +46 -2
  5. data/Gemfile +2 -2
  6. data/README.md +25 -0
  7. data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js +3 -1
  8. data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js +14 -0
  9. data/app/controllers/solidus_paypal_commerce_platform/payments_controller.rb +4 -2
  10. data/app/helpers/solidus_paypal_commerce_platform/button_options_helper.rb +4 -0
  11. data/app/models/solidus_paypal_commerce_platform/gateway.rb +20 -1
  12. data/app/models/solidus_paypal_commerce_platform/payment_method.rb +20 -0
  13. data/app/models/solidus_paypal_commerce_platform/payment_source.rb +11 -0
  14. data/app/models/solidus_paypal_commerce_platform/wizard.rb +1 -1
  15. data/bin/rails-engine +1 -1
  16. data/config/locales/en.yml +34 -1
  17. data/db/migrate/20211220133406_add_paypal_funding_source_to_paypal_commerce_platform_sources.rb +5 -0
  18. data/lib/solidus_paypal_commerce_platform/client.rb +3 -3
  19. data/lib/solidus_paypal_commerce_platform/configuration.rb +3 -3
  20. data/lib/solidus_paypal_commerce_platform/engine.rb +11 -3
  21. data/lib/solidus_paypal_commerce_platform/testing_support/factories.rb +2 -1
  22. data/lib/solidus_paypal_commerce_platform/version.rb +1 -1
  23. data/lib/views/backend/spree/admin/payments/source_views/_paypal_commerce_platform.html.erb +3 -0
  24. data/lib/views/frontend/solidus_paypal_commerce_platform/payments/_payment.html.erb +4 -0
  25. data/lib/views/frontend/spree/checkout/payment/_paypal_commerce_platform.html.erb +17 -3
  26. data/solidus_paypal_commerce_platform.gemspec +2 -2
  27. metadata +11 -63
  28. data/spec/features/backend/new_payment_method_spec.rb +0 -40
  29. data/spec/features/frontend/cart_spec.rb +0 -46
  30. data/spec/features/frontend/checkout_spec.rb +0 -89
  31. data/spec/features/frontend/product_spec.rb +0 -91
  32. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.COMPLETED.v2.json +0 -121
  33. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.PROCESSED.v2.json +0 -121
  34. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v1.json +0 -50
  35. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v2.json +0 -72
  36. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v1.json +0 -50
  37. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v2.json +0 -68
  38. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v1.json +0 -51
  39. data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v2.json +0 -63
  40. data/spec/jobs/solidus_paypal_commerce_platform/webhook_job_spec.rb +0 -44
  41. data/spec/lib/solidus_paypal_commerce_platform/client_spec.rb +0 -21
  42. data/spec/lib/solidus_paypal_commerce_platform/configuration_spec.rb +0 -91
  43. data/spec/models/solidus_paypal_commerce_platform/payment_method_spec.rb +0 -129
  44. data/spec/models/solidus_paypal_commerce_platform/payment_source_spec.rb +0 -62
  45. data/spec/models/solidus_paypal_commerce_platform/paypal_address_spec.rb +0 -67
  46. data/spec/models/solidus_paypal_commerce_platform/paypal_order_spec.rb +0 -33
  47. data/spec/models/solidus_paypal_commerce_platform/state_guesser_spec.rb +0 -38
  48. data/spec/models/solidus_paypal_commerce_platform/wizard_spec.rb +0 -9
  49. data/spec/requests/solidus_paypal_commerce_platform/orders_controller_spec.rb +0 -36
  50. data/spec/requests/solidus_paypal_commerce_platform/shipping_rates_controller_spec.rb +0 -44
  51. data/spec/requests/solidus_paypal_commerce_platform/wizard_controller_spec.rb +0 -44
  52. data/spec/spec_helper.rb +0 -32
  53. data/spec/support/capybara.rb +0 -11
  54. data/spec/support/paypal_sdk_script_tag_helper.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f0a234ec6a201a2b7e7a4f9e3c65359c70acaea23995134f7de9513a96530fc4
4
- data.tar.gz: b94786018f9da41a5e5915db8c87b87c2eaa767580e8739c11ae472fb248d782
3
+ metadata.gz: b2d50512fee899487beba77fee503dd0dfe94f4b4b6dc842fa4598c6fb243623
4
+ data.tar.gz: '0444833a634b9afadcda2125d9b965964832e31fcf6365f013121ad6a4b42945'
5
5
  SHA512:
6
- metadata.gz: 825f4bcff61bbb9ff666391607dc657383d67b2635454375bc12df1a8bef1c02e2cff334b0474ce53dd9d7e04c4d8885dcc9a85ccb729d31a641ab5b9ccaa84c
7
- data.tar.gz: 7589bcb66e13a57e5154227ef9212b209177f1a3f76338c67c852ca837c9df60670e8ce1730153b7121db364034f191170f59d95a863b563663ba47fcfde6b35
6
+ metadata.gz: d41a23f1448ee2633da0af85607432a657bfc3853c58b4a4ed8a65226023c10f2e0ff2eaa9b021a08a108e4f7dd5a938fe66cb1e23d17cc8e35f1a23adbab231
7
+ data.tar.gz: fb6dc9b34cc7363cc028925601bd10448a9c78ee1588fcc4483a8f4d26abd7db9a30e7329da7c89df5bc28e02187c42fa20826d2825e2185d99e92e40ab69954
data/.circleci/config.yml CHANGED
@@ -1,6 +1,8 @@
1
1
  version: 2.1
2
2
 
3
3
  orbs:
4
+ browser-tools: circleci/browser-tools@1.1
5
+
4
6
  # Always take the latest version of the orb, this allows us to
5
7
  # run specs against Solidus supported versions only without the need
6
8
  # to change this configuration every time a Solidus version is released
@@ -11,10 +13,12 @@ jobs:
11
13
  run-specs-with-postgres:
12
14
  executor: solidusio_extensions/postgres
13
15
  steps:
16
+ - browser-tools/install-browser-tools
14
17
  - solidusio_extensions/run-tests
15
18
  run-specs-with-mysql:
16
19
  executor: solidusio_extensions/mysql
17
20
  steps:
21
+ - browser-tools/install-browser-tools
18
22
  - solidusio_extensions/run-tests
19
23
  lint-code:
20
24
  executor: solidusio_extensions/sqlite-memory
data/.rubocop.yml CHANGED
@@ -14,6 +14,10 @@ Layout/FirstArgumentIndentation:
14
14
  Layout/FirstArrayElementIndentation:
15
15
  EnforcedStyle: consistent
16
16
 
17
+ Naming/VariableNumber:
18
+ # PayPal uses snake_case, we use normal_case ¯\_(ツ)_/¯
19
+ Enabled: false
20
+
17
21
  # We use this extensively, the alternatives are not viable or desirable.
18
22
  RSpec/AnyInstance:
19
23
  Enabled: false
@@ -43,10 +47,6 @@ RSpec/VerifiedDoubles:
43
47
  # Sometimes you really need an "anything" double
44
48
  IgnoreSymbolicNames: true
45
49
 
46
- Rspec/Naming/VariableNumber:
47
- # PayPal uses snake_case, we use normal_case ¯\_(ツ)_/¯
48
- Enabled: false
49
-
50
50
  Style/FrozenStringLiteralComment:
51
51
  Exclude:
52
52
  - spec/**/*
data/CHANGELOG.md CHANGED
@@ -1,5 +1,49 @@
1
1
  # Changelog
2
2
 
3
+ ## [v0.4.0](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/tree/v0.4.0) (2022-06-02)
4
+
5
+ [Full Changelog](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/compare/v0.3.2...v0.4.0)
6
+
7
+ **Closed issues:**
8
+
9
+ - Gem has RuboCop warnings [\#144](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/issues/144)
10
+ - Silent Failure In JS [\#130](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/issues/130)
11
+ - Not Applying Sales Tax [\#126](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/issues/126)
12
+
13
+ **Merged pull requests:**
14
+
15
+ - Fix Rails 7 autoloading issues with SolidusPaypalCommercePlatform [\#156](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/156) ([gsmendoza](https://github.com/gsmendoza))
16
+ - Block \#capture on Pending Payments" [\#155](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/155) ([Naokimi](https://github.com/Naokimi))
17
+ - Block \#capture on PayPal PENDING Payments [\#154](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/154) ([Naokimi](https://github.com/Naokimi))
18
+ - Change Venmo integration to use Venmo standalone [\#151](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/151) ([RyanofWoods](https://github.com/RyanofWoods))
19
+ - Allow enable\_venmo preference to have default Venmo behaviour [\#148](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/148) ([RyanofWoods](https://github.com/RyanofWoods))
20
+ - Fix RuboCop warnings [\#147](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/147) ([RyanofWoods](https://github.com/RyanofWoods))
21
+ - Revert "Allow Ruby 3" [\#146](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/146) ([RyanofWoods](https://github.com/RyanofWoods))
22
+ - Add Venmo as payment option [\#138](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/138) ([RyanofWoods](https://github.com/RyanofWoods))
23
+ - Wizard\#logo use `image_path` over `image_url`. [\#131](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/131) ([essn](https://github.com/essn))
24
+
25
+ ## [v0.3.2](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/tree/v0.3.2) (2021-05-11)
26
+
27
+ [Full Changelog](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/compare/v0.3.1...v0.3.2)
28
+
29
+ **Closed issues:**
30
+
31
+ - Unable To Cancel An Order [\#120](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/issues/120)
32
+
33
+ **Merged pull requests:**
34
+
35
+ - Update solidus using solidus\_dev\_support [\#124](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/124) ([DanielePalombo](https://github.com/DanielePalombo))
36
+ - Add NO\_SHIPPING to shipping preference [\#123](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/123) ([DanielePalombo](https://github.com/DanielePalombo))
37
+ - Support solidus 3.0 [\#122](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/122) ([DanielePalombo](https://github.com/DanielePalombo))
38
+
39
+ ## [v0.3.1](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/tree/v0.3.1) (2021-04-20)
40
+
41
+ [Full Changelog](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/compare/v0.3.0...v0.3.1)
42
+
43
+ **Merged pull requests:**
44
+
45
+ - Allow Solidus 3 [\#121](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/121) ([kennyadsl](https://github.com/kennyadsl))
46
+
3
47
  ## [v0.3.0](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/tree/v0.3.0) (2021-03-16)
4
48
 
5
49
  [Full Changelog](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/compare/v0.2.2...v0.3.0)
@@ -55,7 +99,7 @@
55
99
  **Closed issues:**
56
100
 
57
101
  - README lists two different types of PayPal credentials [\#97](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/issues/97)
58
- - `paypal\_email\_confirmed` is not an actual preference [\#96](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/issues/96)
102
+ - `paypal_email_confirmed` is not an actual preference [\#96](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/issues/96)
59
103
  - Make this extension the default option for Solidus [\#88](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/issues/88)
60
104
 
61
105
  **Merged pull requests:**
@@ -75,6 +119,7 @@
75
119
  **Merged pull requests:**
76
120
 
77
121
  - Temporarily switch from apparition to cuprite [\#92](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/92) ([elia](https://github.com/elia))
122
+ - Update links after moving the repo to solidusio-contrib [\#91](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/91) ([elia](https://github.com/elia))
78
123
  - Add a configurable state\_guesser class to guess states [\#90](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/90) ([seand7565](https://github.com/seand7565))
79
124
  - Add better error handling to button\_actions.js [\#89](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/89) ([seand7565](https://github.com/seand7565))
80
125
 
@@ -128,7 +173,6 @@
128
173
 
129
174
  **Merged pull requests:**
130
175
 
131
- - Update links after moving the repo to solidusio-contrib [\#91](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/91) ([elia](https://github.com/elia))
132
176
  - Use live partner ids [\#85](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/85) ([elia](https://github.com/elia))
133
177
  - Update README to account for checkouts without a confirmation step [\#84](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/84) ([seand7565](https://github.com/seand7565))
134
178
  - Replace order simulator with something simpler [\#82](https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/pull/82) ([seand7565](https://github.com/seand7565))
data/Gemfile CHANGED
@@ -9,12 +9,12 @@ gem 'solidus', github: 'solidusio/solidus', branch: branch
9
9
  # Needed to help Bundler figure out how to resolve dependencies,
10
10
  # otherwise it takes forever to resolve them.
11
11
  # See https://github.com/bundler/bundler/issues/6677
12
- gem 'rails', '>0.a'
12
+ gem 'rails', ENV.fetch('RAILS_VERSION', '>0.a')
13
13
 
14
14
  # Provides basic authentication functionality for testing parts of your engine
15
15
  gem 'solidus_auth_devise'
16
16
 
17
- case ENV['DB']
17
+ case ENV.fetch('DB', nil)
18
18
  when 'mysql'
19
19
  gem 'mysql2'
20
20
  when 'postgresql'
data/README.md CHANGED
@@ -120,6 +120,25 @@ With product and cart page checkout, the user is directed to the checkout confir
120
120
 
121
121
  PayPals API does not allow for admin-side payments. Instead, backend users taking payments for customers will need to use the PayPal Virtual Terminal to take payments. [More info is available on the PayPal website.](https://www.paypal.com/merchantapps/appcenter/acceptpayments/virtualterminal?locale.x=en_US)
122
122
 
123
+ ## Venmo
124
+ Venmo is currently available to US merchants and buyers. There are also other [prequisites](https://developer.paypal.com/docs/business/checkout/pay-with-venmo/#eligibility).
125
+
126
+ If the transaction supports Venmo and it is enabled by the following, then a button should appear for it on checkout payment page. Note, Venmo cannot currently be rendered on the product or cart pages.
127
+
128
+ Set the PaypalCommercePlatform `PaymentMethod` `venmo_standalone` preference to:
129
+ - `render only standalone`, show Venmo on the payment page and do not show the other funding sources (i.e. PayPal, Credit); or
130
+ - `enabled`, show Venmo on the payment page; or
131
+ - `disabled` (default), do not show the Venmo button.
132
+
133
+ See more about preferences([Configuration](#configuration)) below.
134
+
135
+ [_As Venmo is only available in the US, you may want to mock your location for testing_](#mocking-your-buyer-country)
136
+
137
+ ## Configuration
138
+ The easiest way to change the `Payment Method`'s preferences is through admin: `Settings > Payments > "PayPal Commerce Platform" > Edit`.
139
+
140
+ See more about preferences [here](https://guides.solidus.io/developers/preferences/add-model-preferences.html#access-your-preferences)/
141
+
123
142
  ## Development
124
143
 
125
144
  ### Testing the extension
@@ -162,6 +181,12 @@ $ bin/rails server
162
181
  Use Ctrl-C to stop
163
182
  ```
164
183
 
184
+ ### Mocking your buyer country
185
+ PayPal normally looks at your IP geolocation to see where you are located to determine what funding sources are available to you. For example, Venmo is currently only available to US buyers.
186
+ Because of this, you may want to pretend you are from US check that that Venmo is correctly integrated for these customers. To do this, set the payment method's preference of `force_buyer_country` to "US". See more information about preferences above.
187
+
188
+ This preference has no effect on production.
189
+
165
190
  ### Updating the changelog
166
191
 
167
192
  Before and after releases the changelog should be updated to reflect the up-to-date status of
@@ -84,6 +84,7 @@ SolidusPaypalCommercePlatform.approveOrder = function(data, actions) {
84
84
  SolidusPaypalCommercePlatform.verifyTotal(response.purchase_units[0].amount.value).then(function(){
85
85
  $("#payments_source_paypal_order_id").val(data.orderID)
86
86
  $("#payments_source_paypal_email").val(response.payer.email_address)
87
+ $("#payments_source_paypal_funding_source").val(SolidusPaypalCommercePlatform.fundingSource)
87
88
  $("#checkout_form_payment").submit()
88
89
  })
89
90
  })
@@ -168,7 +169,8 @@ SolidusPaypalCommercePlatform.addPayment = function(paypal_amount, payment_metho
168
169
  payment_method_id: payment_method_id,
169
170
  source_attributes: {
170
171
  paypal_order_id: data.orderID,
171
- paypal_email: email
172
+ paypal_email: email,
173
+ paypal_funding_source: SolidusPaypalCommercePlatform.fundingSource
172
174
  }
173
175
  }
174
176
  },
@@ -2,6 +2,7 @@ SolidusPaypalCommercePlatform.renderButton = function(payment_method_id, style)
2
2
  paypal.Buttons({
3
3
  style: style,
4
4
  createOrder: SolidusPaypalCommercePlatform.sendOrder.bind(null, payment_method_id),
5
+ onClick: (data) => { SolidusPaypalCommercePlatform.fundingSource = data.fundingSource },
5
6
  onApprove: SolidusPaypalCommercePlatform.approveOrder,
6
7
  onShippingChange: SolidusPaypalCommercePlatform.shippingChange,
7
8
  onError: SolidusPaypalCommercePlatform.handleError
@@ -12,6 +13,7 @@ SolidusPaypalCommercePlatform.renderCartButton = function(payment_method_id, sty
12
13
  paypal.Buttons({
13
14
  style: style,
14
15
  createOrder: SolidusPaypalCommercePlatform.sendOrder.bind(null, payment_method_id),
16
+ onClick: (data) => { SolidusPaypalCommercePlatform.fundingSource = data.fundingSource },
15
17
  onApprove: SolidusPaypalCommercePlatform.finalizeOrder.bind(null, payment_method_id),
16
18
  onShippingChange: SolidusPaypalCommercePlatform.shippingChange,
17
19
  onError: SolidusPaypalCommercePlatform.handleError
@@ -22,8 +24,20 @@ SolidusPaypalCommercePlatform.renderProductButton = function(payment_method_id,
22
24
  paypal.Buttons({
23
25
  style: style,
24
26
  createOrder: SolidusPaypalCommercePlatform.createAndSendOrder.bind(null, payment_method_id),
27
+ onClick: (data) => { SolidusPaypalCommercePlatform.fundingSource = data.fundingSource },
25
28
  onApprove: SolidusPaypalCommercePlatform.finalizeOrder.bind(null, payment_method_id),
26
29
  onShippingChange: SolidusPaypalCommercePlatform.shippingChange,
27
30
  onError: SolidusPaypalCommercePlatform.handleError
28
31
  }).render('#paypal-button-container')
29
32
  }
33
+
34
+ SolidusPaypalCommercePlatform.renderVenmoStandalone = function(payment_method_id, style) {
35
+ paypal.Buttons({
36
+ style: style,
37
+ fundingSource: paypal.FUNDING.VENMO,
38
+ createOrder: SolidusPaypalCommercePlatform.sendOrder.bind(null, payment_method_id),
39
+ onClick: () => { SolidusPaypalCommercePlatform.fundingSource = paypal.FUNDING.VENMO },
40
+ onApprove: SolidusPaypalCommercePlatform.approveOrder,
41
+ onError: SolidusPaypalCommercePlatform.handleError
42
+ }).render('#paypal-button-container')
43
+ }
@@ -10,11 +10,13 @@ module SolidusPaypalCommercePlatform
10
10
  paypal_order_id = paypal_params[:paypal_order_id]
11
11
 
12
12
  if !paypal_order_id
13
- return redirect_to checkout_state_path(@order.state), notice: "Invalid order confirmation data passed in"
13
+ return redirect_to checkout_state_path(@order.state),
14
+ notice: I18n.t("solidus_paypal_commerce_platform.controllers.payments_controller.invalid_paypal_order_id")
14
15
  end
15
16
 
16
17
  if @order.complete?
17
- return redirect_to spree.order_path(@order), notice: "Order is already in complete state"
18
+ return redirect_to spree.order_path(@order),
19
+ notice: I18n.t("solidus_paypal_commerce_platform.controllers.payments_controller.order_complete")
18
20
  end
19
21
 
20
22
  source = SolidusPaypalCommercePlatform::PaymentSource.new(paypal_order_id: paypal_order_id)
@@ -17,5 +17,9 @@ module SolidusPaypalCommercePlatform
17
17
  def preferred_paypal_button_layout_options
18
18
  [["Vertical", "vertical"], ["Horizontal", "horizontal"]]
19
19
  end
20
+
21
+ def preferred_venmo_standalone_options
22
+ [['Render only standalone', 'render only standalone'], ['Enabled', 'Enabled'], ['Disabled', 'disabled']]
23
+ end
20
24
  end
21
25
  end
@@ -45,7 +45,7 @@ module SolidusPaypalCommercePlatform
45
45
  request = AuthorizationsCaptureRequest.new(source.authorization_id)
46
46
  request.request_body(amount: { currency_code: options[:currency], value: Money.new(money).dollars })
47
47
 
48
- response = @client.execute_with_response(request)
48
+ response = capture_with_response(request)
49
49
  if response.success?
50
50
  source.update(capture_id: response.params["result"].id)
51
51
  end
@@ -83,5 +83,24 @@ module SolidusPaypalCommercePlatform
83
83
  def get_order(order_id)
84
84
  @client.execute(OrdersGetRequest.new(order_id)).result
85
85
  end
86
+
87
+ private
88
+
89
+ def capture_with_response(request, success_message: nil, failure_message: nil)
90
+ response = @client.execute(request)
91
+ if response.result&.status == "PENDING"
92
+ ActiveMerchant::Billing::Response.new(
93
+ false,
94
+ "Payment is awaiting processing on PayPal's side"
95
+ )
96
+ else
97
+ i18n_scope = @client.i18n_scope_for(request)
98
+ @client.wrap_response(
99
+ response,
100
+ success_message: success_message || I18n.t("#{i18n_scope}.success", default: nil),
101
+ failure_message: failure_message || I18n.t("#{i18n_scope}.failure", default: nil)
102
+ )
103
+ end
104
+ end
86
105
  end
87
106
  end
@@ -12,6 +12,21 @@ module SolidusPaypalCommercePlatform
12
12
  preference :display_on_cart, :boolean, default: true
13
13
  preference :display_on_product_page, :boolean, default: true
14
14
  preference :display_credit_messaging, :boolean, default: true
15
+ preference :venmo_standalone, :paypal_select, default: 'disabled'
16
+ preference :force_buyer_country, :string
17
+
18
+ validates :preferred_paypal_button_color, exclusion: {
19
+ in: %w[gold],
20
+ message: I18n.t("solidus_paypal_commerce_platform.payment_method.gold_button_message")
21
+ }, if: :venmo_standalone_enabled?
22
+
23
+ def venmo_standalone_enabled?
24
+ options[:venmo_standalone] != 'disabled'
25
+ end
26
+
27
+ def render_only_venmo_standalone?
28
+ options[:venmo_standalone] == 'render only standalone'
29
+ end
15
30
 
16
31
  def partial_name
17
32
  "paypal_commerce_platform"
@@ -73,6 +88,11 @@ module SolidusPaypalCommercePlatform
73
88
  }
74
89
 
75
90
  parameters[:shipping_preference] = 'NO_SHIPPING' if step_names.exclude? 'delivery'
91
+ parameters['enable-funding'] = 'venmo' if venmo_standalone_enabled?
92
+
93
+ if !Rails.env.production? && options[:force_buyer_country].present?
94
+ parameters['buyer-country'] = options[:force_buyer_country]
95
+ end
76
96
 
77
97
  "https://www.paypal.com/sdk/js?#{parameters.to_query}"
78
98
  end
@@ -3,8 +3,19 @@
3
3
  module SolidusPaypalCommercePlatform
4
4
  class PaymentSource < SolidusSupport.payment_source_parent_class
5
5
  self.table_name = "paypal_commerce_platform_sources"
6
+ enum paypal_funding_source: {
7
+ applepay: 0, bancontact: 1, blik: 2, boleto: 3, card: 4, credit: 5, eps: 6, giropay: 7, ideal: 8,
8
+ itau: 9, maxima: 10, mercadopago: 11, mybank: 12, oxxo: 13, p24: 14, paylater: 15, paypal: 16, payu: 17,
9
+ sepa: 18, sofort: 19, trustly: 20, venmo: 21, verkkopankki: 22, wechatpay: 23, zimpler: 24
10
+ }, _suffix: :funding
6
11
  validates :paypal_order_id, :payment_method_id, presence: true
7
12
 
13
+ def display_paypal_funding_source
14
+ I18n.t(paypal_funding_source,
15
+ scope: 'solidus_paypal_commerce_platform.paypal_funding_sources',
16
+ default: paypal_funding_source)
17
+ end
18
+
8
19
  def actions
9
20
  %w(capture void credit)
10
21
  end
@@ -34,7 +34,7 @@ module SolidusPaypalCommercePlatform
34
34
  private
35
35
 
36
36
  def logo
37
- ActionController::Base.helpers.image_url(::Spree::Config[:admin_interface_logo])
37
+ ActionController::Base.helpers.image_path(::Spree::Config[:admin_interface_logo])
38
38
  end
39
39
  end
40
40
  end
data/bin/rails-engine CHANGED
@@ -7,7 +7,7 @@ ENGINE_PATH = File.expand_path('../lib/solidus_paypal_commerce_platform/engine',
7
7
 
8
8
  # Set up gems listed in the Gemfile.
9
9
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
10
- require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
10
+ require 'bundler/setup' if File.exist?(ENV.fetch('BUNDLE_GEMFILE', nil))
11
11
 
12
12
  require 'rails/all'
13
13
  require 'rails/engine/commands'
@@ -18,9 +18,15 @@ en:
18
18
  paypal_capture_id: PayPal Capture ID
19
19
  paypal_debug_id: PayPal Debug ID
20
20
  paypal_email: PayPal Email
21
+ paypal_funding: 'PayPal Funding: %{funding}'
22
+ paypal_funding_source: 'PayPal Funding Source'
21
23
  payment_email: "Payment Email: %{email}"
22
24
  virtual_terminal_notice_html: Backend Credit Card payments can only be accepted through PayPal via the <a href="https://www.paypal.com/merchantapps/appcenter/acceptpayments/virtualterminal">PayPal Virtual Terminal</a>.
23
25
  solidus_paypal_commerce_platform:
26
+ controllers:
27
+ payments_controller:
28
+ invalid_paypal_order_id: "Invalid order confirmation data passed in"
29
+ order_complete: "Order is already in complete state"
24
30
  responses:
25
31
  pay_pal_checkout_sdk/orders/orders_capture_request:
26
32
  success: "Payment captured"
@@ -34,4 +40,31 @@ en:
34
40
  success: "Payment refunded for %{amount}"
35
41
  pay_pal_checkout_sdk/payments/authorizations_void_request:
36
42
  success: "Payment voided"
37
-
43
+ payment_method:
44
+ gold_button_message: "cannot be 'gold' when Venmo standalone is enabled."
45
+ paypal_funding_sources:
46
+ applepay: 'Apple Pay'
47
+ bancontact: 'Bancontact'
48
+ blik: 'BLIK'
49
+ boleto: 'Boleto'
50
+ card: 'Credit or debit card'
51
+ credit: 'PayPal Credit'
52
+ eps: 'eps'
53
+ giropay: 'giropay'
54
+ ideal: 'iDEAL'
55
+ itau: 'Itau'
56
+ maxima: 'Maxima'
57
+ mercadopago: 'Mercado Pago'
58
+ mybank: 'MyBank'
59
+ oxxo: 'Oxxo'
60
+ p24: 'Przelewy24'
61
+ paylater: 'Pay Later'
62
+ paypal: 'PayPal'
63
+ payu: 'PayU'
64
+ sepa: 'SEPA-Lastschrift'
65
+ sofort: 'Sofort'
66
+ trustly: 'Trustly'
67
+ venmo: 'Venmo'
68
+ verkkopankki: 'Verkkopankki'
69
+ wechatpay: 'WeChat Pay'
70
+ zimpler: 'Zimpler'
@@ -0,0 +1,5 @@
1
+ class AddPaypalFundingSourceToPaypalCommercePlatformSources < ActiveRecord::Migration[6.1]
2
+ def change
3
+ add_column :paypal_commerce_platform_sources, :paypal_funding_source, :integer
4
+ end
5
+ end
@@ -13,6 +13,8 @@ module SolidusPaypalCommercePlatform
13
13
  request.headers["PayPal-Partner-Attribution-Id"] = SolidusPaypalCommercePlatform.config.partner_code
14
14
  }.freeze
15
15
 
16
+ Response = Struct.new(:status_code, :error)
17
+
16
18
  attr_reader :environment
17
19
 
18
20
  def initialize(client_id:, client_secret: "", test_mode: nil)
@@ -29,7 +31,7 @@ module SolidusPaypalCommercePlatform
29
31
  @paypal_client.execute(request)
30
32
  rescue PayPalHttp::HttpError => e
31
33
  Rails.logger.error e.result
32
- OpenStruct.new(status_code: 422, error: e.result)
34
+ Response.new(status_code: 422, error: e.result)
33
35
  end
34
36
 
35
37
  def execute_with_response(request, success_message: nil, failure_message: nil)
@@ -60,8 +62,6 @@ module SolidusPaypalCommercePlatform
60
62
  )).result
61
63
  end
62
64
 
63
- private
64
-
65
65
  def wrap_response(response, success_message: nil, failure_message: nil)
66
66
  if SUCCESS_STATUS_CODES.include? response.status_code
67
67
  success_message ||= "Success."
@@ -39,7 +39,7 @@ module SolidusPaypalCommercePlatform
39
39
  end
40
40
 
41
41
  def default_env
42
- return ENV['PAYPAL_ENV'] if ENV['PAYPAL_ENV'] # rubocop:disable Rails/EnvironmentVariableAccess
42
+ return ENV['PAYPAL_ENV'] if ENV['PAYPAL_ENV']
43
43
 
44
44
  case Rails.env
45
45
  when 'production'
@@ -60,11 +60,11 @@ module SolidusPaypalCommercePlatform
60
60
  end
61
61
 
62
62
  def partner_id
63
- @partner_id ||= ENV['PAYPAL_PARTNER_ID'] || DEFAULT_PARTNER_ID[env.to_sym] # rubocop:disable Rails/EnvironmentVariableAccess
63
+ @partner_id ||= ENV.fetch('PAYPAL_PARTNER_ID') { DEFAULT_PARTNER_ID[env.to_sym] }
64
64
  end
65
65
 
66
66
  def partner_client_id
67
- @partner_client_id ||= ENV['PAYPAL_PARTNER_CLIENT_ID'] || DEFAULT_PARTNER_CLIENT_ID[env.to_sym] # rubocop:disable Rails/EnvironmentVariableAccess
67
+ @partner_client_id ||= ENV.fetch('PAYPAL_PARTNER_CLIENT_ID') { DEFAULT_PARTNER_CLIENT_ID[env.to_sym] }
68
68
  end
69
69
 
70
70
  def partner_code
@@ -15,9 +15,17 @@ module SolidusPaypalCommercePlatform
15
15
  engine_name 'solidus_paypal_commerce_platform'
16
16
 
17
17
  initializer "solidus_paypal_commerce_platform.add_payment_method", after: "spree.register.payment_methods" do |app|
18
- app.config.spree.payment_methods << SolidusPaypalCommercePlatform::PaymentMethod
19
- SolidusPaypalCommercePlatform::PaymentMethod.allowed_admin_form_preference_types << :paypal_select
20
- Spree::PermittedAttributes.source_attributes.concat [:paypal_order_id, :authorization_id, :paypal_email]
18
+ app.config.to_prepare do
19
+ app.config.spree.payment_methods << SolidusPaypalCommercePlatform::PaymentMethod
20
+
21
+ unless SolidusPaypalCommercePlatform::PaymentMethod.allowed_admin_form_preference_types.include?(:paypal_select)
22
+ SolidusPaypalCommercePlatform::PaymentMethod.allowed_admin_form_preference_types << :paypal_select
23
+ end
24
+
25
+ old_source_attributes = ::Spree::PermittedAttributes.source_attributes
26
+ new_source_attributes = [:paypal_order_id, :authorization_id, :paypal_email, :paypal_funding_source]
27
+ ::Spree::PermittedAttributes.source_attributes.concat(new_source_attributes - old_source_attributes)
28
+ end
21
29
  end
22
30
 
23
31
  initializer "solidus_paypal_commerce_platform.add_wizard", after: "spree.register.payment_methods" do |app|
@@ -7,7 +7,8 @@ FactoryBot.define do
7
7
  preferences {
8
8
  {
9
9
  client_id: SecureRandom.hex(8),
10
- client_secret: SecureRandom.hex(10)
10
+ client_secret: SecureRandom.hex(10),
11
+ venmo_standalone: 'disabled'
11
12
  }
12
13
  }
13
14
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SolidusPaypalCommercePlatform
4
- VERSION = '0.3.2'
4
+ VERSION = '0.4.0'
5
5
  end
@@ -12,6 +12,9 @@
12
12
 
13
13
  <dt><%= I18n.t("paypal_email") %>:</dt>
14
14
  <dd><%= payment.source.paypal_email %></dd>
15
+
16
+ <dt><%= I18n.t("paypal_funding_source") %>:</dt>
17
+ <dd><%= payment.source.display_paypal_funding_source %></dd>
15
18
  </dl>
16
19
  </div>
17
20
  </div>
@@ -1,3 +1,7 @@
1
+ <% if payment.source.respond_to?(:paypal_funding_source) %>
2
+ <br />
3
+ <%= t('paypal_funding', funding: payment.source.display_paypal_funding_source) %>
4
+ <% end %>
1
5
  <% if payment.source.respond_to?(:paypal_email) %>
2
6
  <br />
3
7
  <%= t('payment_email', email: payment.source.paypal_email) %>
@@ -6,13 +6,27 @@
6
6
 
7
7
  <input type="hidden" name="payment_source[<%= payment_method.id %>][paypal_order_id]" id="payments_source_paypal_order_id">
8
8
  <input type="hidden" name="payment_source[<%= payment_method.id %>][paypal_email]" id="payments_source_paypal_email">
9
+ <input type="hidden" name="payment_source[<%= payment_method.id %>][paypal_funding_source]" id="payments_source_paypal_funding_source">
9
10
 
10
11
  <script>
11
12
  Spree.current_order_id = "<%= @order.number %>"
12
13
  Spree.current_order_token = "<%= @order.guest_token %>"
13
- $( document ).ready(function() {
14
- SolidusPaypalCommercePlatform.renderButton("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
15
- })
16
14
  </script>
17
15
 
16
+ <% unless payment_method.render_only_venmo_standalone? %>
17
+ <script>
18
+ $( document ).ready(function() {
19
+ SolidusPaypalCommercePlatform.renderButton("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
20
+ })
21
+ </script>
22
+ <% end %>
23
+
24
+ <% if payment_method.venmo_standalone_enabled? %>
25
+ <script>
26
+ $( document ).ready(function() {
27
+ SolidusPaypalCommercePlatform.renderVenmoStandalone("<%= payment_method.id %>",<%= raw payment_method.button_style.to_json %>)
28
+ })
29
+ </script>
30
+ <% end %>
31
+
18
32
  <div id="paypal_commerce_platform_overlay"></div>
@@ -15,15 +15,15 @@ Gem::Specification.new do |spec|
15
15
  spec.metadata['homepage_uri'] = spec.homepage
16
16
  spec.metadata['source_code_uri'] = 'https://github.com/solidusio-contrib/solidus_paypal_commerce_platform'
17
17
  spec.metadata['changelog_uri'] = 'https://github.com/solidusio-contrib/solidus_paypal_commerce_platform/releases'
18
+ spec.metadata['rubygems_mfa_required'] = 'true'
18
19
 
19
- spec.required_ruby_version = Gem::Requirement.new('>= 2.5')
20
+ spec.required_ruby_version = Gem::Requirement.new('~> 2.5')
20
21
 
21
22
  # Specify which files should be added to the gem when it is released.
22
23
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
24
  files = Dir.chdir(__dir__) { `git ls-files -z`.split("\x0") }
24
25
 
25
26
  spec.files = files.grep_v(%r{^(test|spec|features)/})
26
- spec.test_files = files.grep(%r{^(test|spec|features)/})
27
27
  spec.bindir = "exe"
28
28
  spec.executables = files.grep(%r{^exe/}) { |f| File.basename(f) }
29
29
  spec.require_paths = ["lib"]