solidus_paypal_commerce_platform 0.3.2 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +25 -2
- data/.rubocop.yml +6 -5
- data/CHANGELOG.md +180 -122
- data/Gemfile +16 -3
- data/README.md +27 -2
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js +3 -1
- data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/buttons.js +14 -0
- data/app/controllers/solidus_paypal_commerce_platform/orders_controller.rb +1 -1
- data/app/controllers/solidus_paypal_commerce_platform/payments_controller.rb +4 -2
- data/app/helpers/solidus_paypal_commerce_platform/button_options_helper.rb +4 -0
- data/app/models/solidus_paypal_commerce_platform/gateway.rb +20 -3
- data/app/models/solidus_paypal_commerce_platform/payment_method.rb +21 -1
- data/app/models/solidus_paypal_commerce_platform/payment_source.rb +12 -1
- data/app/models/solidus_paypal_commerce_platform/paypal_order.rb +6 -21
- data/app/models/solidus_paypal_commerce_platform/wizard.rb +1 -1
- data/bin/rails-engine +1 -1
- data/config/locales/en.yml +34 -1
- data/db/migrate/20211220133406_add_paypal_funding_source_to_paypal_commerce_platform_sources.rb +5 -0
- data/lib/paypal/access_token.rb +22 -0
- data/lib/paypal/lib.rb +19 -0
- data/lib/paypal/paypal_checkout_sdk/orders/orders_authorize_request.rb +44 -0
- data/lib/paypal/paypal_checkout_sdk/orders/orders_capture_request.rb +42 -0
- data/lib/paypal/paypal_checkout_sdk/orders/orders_create_request.rb +36 -0
- data/lib/paypal/paypal_checkout_sdk/orders/orders_get_request.rb +26 -0
- data/lib/paypal/paypal_checkout_sdk/orders/orders_patch_request.rb +77 -0
- data/lib/paypal/paypal_checkout_sdk/orders/orders_validate_request.rb +34 -0
- data/lib/paypal/paypal_checkout_sdk/payments/authorizations_capture_request.rb +38 -0
- data/lib/paypal/paypal_checkout_sdk/payments/authorizations_get_request.rb +26 -0
- data/lib/paypal/paypal_checkout_sdk/payments/authorizations_reauthorize_request.rb +45 -0
- data/lib/paypal/paypal_checkout_sdk/payments/authorizations_void_request.rb +27 -0
- data/lib/paypal/paypal_checkout_sdk/payments/captures_get_request.rb +26 -0
- data/lib/paypal/paypal_checkout_sdk/payments/captures_refund_request.rb +40 -0
- data/lib/paypal/paypal_checkout_sdk/payments/refunds_get_request.rb +26 -0
- data/lib/paypal/paypal_environment.rb +39 -0
- data/lib/paypal/paypal_http_client.rb +56 -0
- data/lib/paypal/token_requests.rb +42 -0
- data/lib/solidus_paypal_commerce_platform/access_token_authorization_request.rb +1 -1
- data/lib/solidus_paypal_commerce_platform/client.rb +4 -4
- data/lib/solidus_paypal_commerce_platform/configuration.rb +4 -4
- data/lib/solidus_paypal_commerce_platform/engine.rb +11 -3
- data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/orders/orders_authorize_request.rb +48 -0
- data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/orders/orders_capture_request.rb +46 -0
- data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/orders/orders_patch_request.rb +80 -0
- data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/orders/orders_validate_request.rb +36 -0
- data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/payments/authorizations_reauthorize_request.rb +50 -0
- data/lib/solidus_paypal_commerce_platform/paypal_checkout_sdk/payments/captures_refund_request.rb +43 -0
- data/lib/solidus_paypal_commerce_platform/testing_support/factories.rb +2 -1
- data/lib/solidus_paypal_commerce_platform/version.rb +1 -1
- data/lib/solidus_paypal_commerce_platform.rb +1 -0
- data/lib/views/backend/spree/admin/payments/source_views/_paypal_commerce_platform.html.erb +3 -0
- data/lib/views/frontend/solidus_paypal_commerce_platform/payments/_payment.html.erb +4 -0
- data/lib/views/frontend/spree/checkout/payment/_paypal_commerce_platform.html.erb +17 -3
- data/solidus_paypal_commerce_platform.gemspec +9 -8
- metadata +52 -78
- data/spec/features/backend/new_payment_method_spec.rb +0 -40
- data/spec/features/frontend/cart_spec.rb +0 -46
- data/spec/features/frontend/checkout_spec.rb +0 -89
- data/spec/features/frontend/product_spec.rb +0 -91
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.COMPLETED.v2.json +0 -121
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/CHECKOUT.ORDER.PROCESSED.v2.json +0 -121
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v1.json +0 -50
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.COMPLETED.v2.json +0 -72
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v1.json +0 -50
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.DENIED.v2.json +0 -68
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v1.json +0 -51
- data/spec/jobs/solidus_paypal_commerce_platform/fixtures/PAYMENT.CAPTURE.REFUNDED.v2.json +0 -63
- data/spec/jobs/solidus_paypal_commerce_platform/webhook_job_spec.rb +0 -44
- data/spec/lib/solidus_paypal_commerce_platform/client_spec.rb +0 -21
- data/spec/lib/solidus_paypal_commerce_platform/configuration_spec.rb +0 -91
- data/spec/models/solidus_paypal_commerce_platform/payment_method_spec.rb +0 -129
- data/spec/models/solidus_paypal_commerce_platform/payment_source_spec.rb +0 -62
- data/spec/models/solidus_paypal_commerce_platform/paypal_address_spec.rb +0 -67
- data/spec/models/solidus_paypal_commerce_platform/paypal_order_spec.rb +0 -33
- data/spec/models/solidus_paypal_commerce_platform/state_guesser_spec.rb +0 -38
- data/spec/models/solidus_paypal_commerce_platform/wizard_spec.rb +0 -9
- data/spec/requests/solidus_paypal_commerce_platform/orders_controller_spec.rb +0 -36
- data/spec/requests/solidus_paypal_commerce_platform/shipping_rates_controller_spec.rb +0 -44
- data/spec/requests/solidus_paypal_commerce_platform/wizard_controller_spec.rb +0 -44
- data/spec/spec_helper.rb +0 -32
- data/spec/support/capybara.rb +0 -11
- data/spec/support/paypal_sdk_script_tag_helper.rb +0 -13
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# Solidus Paypal Commerce Platform
|
2
2
|
|
3
|
-
[![CircleCI](https://circleci.com/gh/solidusio
|
4
|
-
[![codecov](https://codecov.io/gh/solidusio
|
3
|
+
[![CircleCI](https://circleci.com/gh/solidusio/solidus_paypal_commerce_platform.svg?style=shield)](https://circleci.com/gh/solidusio/solidus_paypal_commerce_platform)
|
4
|
+
[![codecov](https://codecov.io/gh/solidusio/solidus_paypal_commerce_platform/branch/master/graph/badge.svg)](https://codecov.io/gh/solidusio/solidus_paypal_commerce_platform)
|
5
5
|
|
6
6
|
The official PayPal integration of Solidus.
|
7
7
|
|
@@ -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
|
data/app/assets/javascripts/spree/frontend/solidus_paypal_commerce_platform/button_actions.js
CHANGED
@@ -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),
|
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),
|
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
|
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'paypal-checkout-sdk'
|
4
|
-
|
5
3
|
module SolidusPaypalCommercePlatform
|
6
4
|
class Gateway
|
7
5
|
include PayPalCheckoutSdk::Orders
|
@@ -45,7 +43,7 @@ module SolidusPaypalCommercePlatform
|
|
45
43
|
request = AuthorizationsCaptureRequest.new(source.authorization_id)
|
46
44
|
request.request_body(amount: { currency_code: options[:currency], value: Money.new(money).dollars })
|
47
45
|
|
48
|
-
response =
|
46
|
+
response = capture_with_response(request)
|
49
47
|
if response.success?
|
50
48
|
source.update(capture_id: response.params["result"].id)
|
51
49
|
end
|
@@ -83,5 +81,24 @@ module SolidusPaypalCommercePlatform
|
|
83
81
|
def get_order(order_id)
|
84
82
|
@client.execute(OrdersGetRequest.new(order_id)).result
|
85
83
|
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def capture_with_response(request, success_message: nil, failure_message: nil)
|
88
|
+
response = @client.execute(request)
|
89
|
+
if response.result&.status == "PENDING"
|
90
|
+
ActiveMerchant::Billing::Response.new(
|
91
|
+
false,
|
92
|
+
"Payment is awaiting processing on PayPal's side"
|
93
|
+
)
|
94
|
+
else
|
95
|
+
i18n_scope = @client.i18n_scope_for(request)
|
96
|
+
@client.wrap_response(
|
97
|
+
response,
|
98
|
+
success_message: success_message || I18n.t("#{i18n_scope}.success", default: nil),
|
99
|
+
failure_message: failure_message || I18n.t("#{i18n_scope}.failure", default: nil)
|
100
|
+
)
|
101
|
+
end
|
102
|
+
end
|
86
103
|
end
|
87
104
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SolidusPaypalCommercePlatform
|
4
|
-
class PaymentMethod <
|
4
|
+
class PaymentMethod < ::Spree::PaymentMethod
|
5
5
|
include SolidusPaypalCommercePlatform::ButtonOptionsHelper
|
6
6
|
preference :client_id, :string
|
7
7
|
preference :client_secret, :string
|
@@ -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
|
@@ -1,10 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SolidusPaypalCommercePlatform
|
4
|
-
class PaymentSource <
|
4
|
+
class PaymentSource < ::Spree::PaymentSource
|
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
|
@@ -44,19 +44,12 @@ module SolidusPaypalCommercePlatform
|
|
44
44
|
end
|
45
45
|
|
46
46
|
def name(address)
|
47
|
-
|
48
|
-
name = ::Spree::Address::Name.new @order.ship_address.name
|
47
|
+
name = ::Spree::Address::Name.new address.name
|
49
48
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
else
|
55
|
-
{
|
56
|
-
given_name: address.firstname,
|
57
|
-
surname: address.lastname
|
58
|
-
}
|
59
|
-
end
|
49
|
+
{
|
50
|
+
given_name: name.first_name,
|
51
|
+
surname: name.last_name
|
52
|
+
}
|
60
53
|
end
|
61
54
|
|
62
55
|
def purchase_units(include_shipping_address: true)
|
@@ -80,11 +73,7 @@ module SolidusPaypalCommercePlatform
|
|
80
73
|
end
|
81
74
|
|
82
75
|
def full_name
|
83
|
-
|
84
|
-
@order.ship_address.name
|
85
|
-
else
|
86
|
-
@order.ship_address.full_name
|
87
|
-
end
|
76
|
+
@order.ship_address.name
|
88
77
|
end
|
89
78
|
|
90
79
|
def line_items
|
@@ -120,9 +109,5 @@ module SolidusPaypalCommercePlatform
|
|
120
109
|
value: amount
|
121
110
|
}
|
122
111
|
end
|
123
|
-
|
124
|
-
def greater_than_2_10?
|
125
|
-
::Spree.solidus_gem_version >= Gem::Version.new('2.11')
|
126
|
-
end
|
127
112
|
end
|
128
113
|
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
|
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'
|
data/config/locales/en.yml
CHANGED
@@ -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,22 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
module PayPal
|
4
|
+
class AccessToken
|
5
|
+
attr_accessor :access_token, :token_type, :expires_in, :date_created
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@access_token = options.access_token
|
9
|
+
@token_type = options.token_type
|
10
|
+
@expires_in = options.expires_in
|
11
|
+
@date_created = Time.zone.now
|
12
|
+
end
|
13
|
+
|
14
|
+
def expired?
|
15
|
+
Time.zone.now > @date_created + @expires_in
|
16
|
+
end
|
17
|
+
|
18
|
+
def authorization_string
|
19
|
+
"#{@token_type} #{@access_token}"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/paypal/lib.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
require 'paypal/paypal_environment'
|
4
|
+
require 'paypal/paypal_http_client'
|
5
|
+
require 'paypal/token_requests'
|
6
|
+
require 'paypal/access_token'
|
7
|
+
require 'paypal/paypal_checkout_sdk/orders/orders_authorize_request'
|
8
|
+
require 'paypal/paypal_checkout_sdk/orders/orders_capture_request'
|
9
|
+
require 'paypal/paypal_checkout_sdk/orders/orders_create_request'
|
10
|
+
require 'paypal/paypal_checkout_sdk/orders/orders_get_request'
|
11
|
+
require 'paypal/paypal_checkout_sdk/orders/orders_patch_request'
|
12
|
+
require 'paypal/paypal_checkout_sdk/orders/orders_validate_request'
|
13
|
+
require 'paypal/paypal_checkout_sdk/payments/authorizations_capture_request'
|
14
|
+
require 'paypal/paypal_checkout_sdk/payments/authorizations_get_request'
|
15
|
+
require 'paypal/paypal_checkout_sdk/payments/authorizations_reauthorize_request'
|
16
|
+
require 'paypal/paypal_checkout_sdk/payments/authorizations_void_request'
|
17
|
+
require 'paypal/paypal_checkout_sdk/payments/captures_get_request'
|
18
|
+
require 'paypal/paypal_checkout_sdk/payments/refunds_get_request'
|
19
|
+
require 'paypal/paypal_checkout_sdk/payments/captures_refund_request'
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
# This class was generated on Mon, 27 Aug 2018 13:51:59 PDT by version 0.1.0-dev+904328-dirty of Braintree SDK Generator
|
4
|
+
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
module PayPalCheckoutSdk
|
8
|
+
module Orders
|
9
|
+
#
|
10
|
+
# Authorizes payment for an order. The response shows details
|
11
|
+
# of authorizations. You can make this call only if you specified
|
12
|
+
# `intent=AUTHORIZE` in the create order call.
|
13
|
+
#
|
14
|
+
class OrdersAuthorizeRequest
|
15
|
+
attr_accessor :path, :body, :headers, :verb
|
16
|
+
|
17
|
+
def initialize(order_id)
|
18
|
+
@headers = {}
|
19
|
+
@body = nil
|
20
|
+
@verb = "POST"
|
21
|
+
@path = "/v2/checkout/orders/{order_id}/authorize?"
|
22
|
+
|
23
|
+
@path = @path.gsub("{order_id}", CGI.escape(order_id.to_s))
|
24
|
+
@headers["Content-Type"] = "application/json"
|
25
|
+
end
|
26
|
+
|
27
|
+
def pay_pal_client_metadata_id(pay_pal_client_metadata_id)
|
28
|
+
@headers["PayPal-Client-Metadata-Id"] = pay_pal_client_metadata_id
|
29
|
+
end
|
30
|
+
|
31
|
+
def pay_pal_request_id(pay_pal_request_id)
|
32
|
+
@headers["PayPal-Request-Id"] = pay_pal_request_id
|
33
|
+
end
|
34
|
+
|
35
|
+
def prefer(prefer)
|
36
|
+
@headers["Prefer"] = prefer
|
37
|
+
end
|
38
|
+
|
39
|
+
def request_body(order_action_request)
|
40
|
+
@body = order_action_request
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
# This class was generated on Mon, 27 Aug 2018 13:51:59 PDT by version 0.1.0-dev+904328-dirty of Braintree SDK Generator
|
4
|
+
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
module PayPalCheckoutSdk
|
8
|
+
module Orders
|
9
|
+
#
|
10
|
+
# Captures a payment for an order.
|
11
|
+
#
|
12
|
+
class OrdersCaptureRequest
|
13
|
+
attr_accessor :path, :body, :headers, :verb
|
14
|
+
|
15
|
+
def initialize(order_id)
|
16
|
+
@headers = {}
|
17
|
+
@body = nil
|
18
|
+
@verb = "POST"
|
19
|
+
@path = "/v2/checkout/orders/{order_id}/capture?"
|
20
|
+
|
21
|
+
@path = @path.gsub("{order_id}", CGI.escape(order_id.to_s))
|
22
|
+
@headers["Content-Type"] = "application/json"
|
23
|
+
end
|
24
|
+
|
25
|
+
def pay_pal_client_metadata_id(pay_pal_client_metadata_id)
|
26
|
+
@headers["PayPal-Client-Metadata-Id"] = pay_pal_client_metadata_id
|
27
|
+
end
|
28
|
+
|
29
|
+
def pay_pal_request_id(pay_pal_request_id)
|
30
|
+
@headers["PayPal-Request-Id"] = pay_pal_request_id
|
31
|
+
end
|
32
|
+
|
33
|
+
def prefer(prefer)
|
34
|
+
@headers["Prefer"] = prefer
|
35
|
+
end
|
36
|
+
|
37
|
+
def request_body(order_action_request)
|
38
|
+
@body = order_action_request
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
# This class was generated on Mon, 27 Aug 2018 13:51:59 PDT by version 0.1.0-dev+904328-dirty of Braintree SDK Generator
|
4
|
+
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
module PayPalCheckoutSdk
|
8
|
+
module Orders
|
9
|
+
#
|
10
|
+
# Creates an order. Supports only orders with one purchase unit.
|
11
|
+
#
|
12
|
+
class OrdersCreateRequest
|
13
|
+
attr_accessor :path, :body, :headers, :verb
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@headers = {}
|
17
|
+
@body = nil
|
18
|
+
@verb = "POST"
|
19
|
+
@path = "/v2/checkout/orders?"
|
20
|
+
@headers["Content-Type"] = "application/json"
|
21
|
+
end
|
22
|
+
|
23
|
+
def pay_pal_partner_attribution_id(pay_pal_partner_attribution_id)
|
24
|
+
@headers["PayPal-Partner-Attribution-Id"] = pay_pal_partner_attribution_id
|
25
|
+
end
|
26
|
+
|
27
|
+
def prefer(prefer)
|
28
|
+
@headers["Prefer"] = prefer
|
29
|
+
end
|
30
|
+
|
31
|
+
def request_body(order)
|
32
|
+
@body = order
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
# This class was generated on Mon, 27 Aug 2018 13:51:59 PDT by version 0.1.0-dev+904328-dirty of Braintree SDK Generator
|
4
|
+
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
module PayPalCheckoutSdk
|
8
|
+
module Orders
|
9
|
+
#
|
10
|
+
# Shows details for an order, by ID.
|
11
|
+
#
|
12
|
+
class OrdersGetRequest
|
13
|
+
attr_accessor :path, :body, :headers, :verb
|
14
|
+
|
15
|
+
def initialize(order_id)
|
16
|
+
@headers = {}
|
17
|
+
@body = nil
|
18
|
+
@verb = "GET"
|
19
|
+
@path = "/v2/checkout/orders/{order_id}?"
|
20
|
+
|
21
|
+
@path = @path.gsub("{order_id}", CGI.escape(order_id.to_s))
|
22
|
+
@headers["Content-Type"] = "application/json"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: false
|
2
|
+
|
3
|
+
# This class was generated on Mon, 27 Aug 2018 13:51:59 PDT by version 0.1.0-dev+904328-dirty of Braintree SDK Generator
|
4
|
+
|
5
|
+
require 'cgi'
|
6
|
+
|
7
|
+
module PayPalCheckoutSdk
|
8
|
+
module Orders
|
9
|
+
#
|
10
|
+
# Updates an order that has the `CREATED` or `APPROVED` status. You cannot update an order with `COMPLETED` status.
|
11
|
+
# You can patch these attributes and objects:
|
12
|
+
# <table>
|
13
|
+
# <thead>
|
14
|
+
# <tr>
|
15
|
+
# <th align="left">Attribute or object</th>
|
16
|
+
# <th align="left">Operations</th>
|
17
|
+
# </tr>
|
18
|
+
# </thead>
|
19
|
+
# <tbody>
|
20
|
+
# <tr>
|
21
|
+
# <td><code>intent</code></td>
|
22
|
+
# <td align="left">Replace</td>
|
23
|
+
# </tr>
|
24
|
+
# <tr>
|
25
|
+
# <td><code>purchase_units</code></td>
|
26
|
+
# <td align="left">Replace, add</td>
|
27
|
+
# </tr>
|
28
|
+
# <tr>
|
29
|
+
# <td><code>purchase_units[].custom_id</code></td>
|
30
|
+
# <td align="left">Replace, add, remove</td>
|
31
|
+
# </tr>
|
32
|
+
# <tr>
|
33
|
+
# <td><code>purchase_units[].description</code></td>
|
34
|
+
# <td align="left">Replace, add, remove</td>
|
35
|
+
# </tr>
|
36
|
+
# <tr>
|
37
|
+
# <td><code>purchase_units[].payee.email</code></td>
|
38
|
+
# <td align="left">Replace, add</td>
|
39
|
+
# </tr>
|
40
|
+
# <tr>
|
41
|
+
# <td><code>purchase_units[].shipping</code></td>
|
42
|
+
# <td align="left">Replace, add, remove</td>
|
43
|
+
# </tr>
|
44
|
+
# <tr>
|
45
|
+
# <td><code>purchase_units[].soft_descriptor</code></td>
|
46
|
+
# <td align="left">Replace, add, remove</td>
|
47
|
+
# </tr>
|
48
|
+
# <tr>
|
49
|
+
# <td><code>purchase_units[].amount</code></td>
|
50
|
+
# <td align="left">Replace</td>
|
51
|
+
# </tr>
|
52
|
+
# <tr>
|
53
|
+
# <td><code>purchase_units[].invoice_id</code></td>
|
54
|
+
# <td align="left">Replace, add, remove</td>
|
55
|
+
# </tr>
|
56
|
+
# </tbody>
|
57
|
+
# </table>
|
58
|
+
#
|
59
|
+
class OrdersPatchRequest
|
60
|
+
attr_accessor :path, :body, :headers, :verb
|
61
|
+
|
62
|
+
def initialize(order_id)
|
63
|
+
@headers = {}
|
64
|
+
@body = nil
|
65
|
+
@verb = "PATCH"
|
66
|
+
@path = "/v2/checkout/orders/{order_id}?"
|
67
|
+
|
68
|
+
@path = @path.gsub("{order_id}", CGI.escape(order_id.to_s))
|
69
|
+
@headers["Content-Type"] = "application/json"
|
70
|
+
end
|
71
|
+
|
72
|
+
def request_body(patch_request)
|
73
|
+
@body = patch_request
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|