Skip to content

Commit

Permalink
Merge pull request solidusio#4 from nebulab/checkout-with-paypal
Browse files Browse the repository at this point in the history
Add support for Checkout with PayPal flow
  • Loading branch information
aldesantis authored May 22, 2018
2 parents c2f0a48 + 3ae1110 commit 6fe9c00
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 10 deletions.
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ Payment methods can accept preferences either directly entered in admin, or from
environment: Rails.env.production? ? 'production' : 'sandbox',
merchant_id: ENV['BRAINTREE_MERCHANT_ID'],
public_key: ENV['BRAINTREE_PUBLIC_KEY'],
private_key: ENV['BRAINTREE_PRIVATE_KEY']
private_key: ENV['BRAINTREE_PRIVATE_KEY'],
paypal_flow: 'vault', # 'checkout' is accepted too
}
)
end
Expand Down Expand Up @@ -155,8 +156,10 @@ store's configuration.
The checkout view
[initializes the PayPal button](/lib/views/frontend/spree/checkout/payment/_paypal_braintree.html.erb)
using the
[vault flow](https://developers.braintreepayments.com/guides/paypal/overview/javascript/v3),
which allows the source to be reused.
[Vault flow](https://developers.braintreepayments.com/guides/paypal/overview/javascript/v3),
which allows the source to be reused. If you want, you can use [Checkout with PayPal](https://developers.braintreepayments.com/guides/paypal/checkout-with-paypal/javascript/v3)
instead, which doesn't allow you to reuse sources but allows your customers to pay with their PayPal
balance (see setup instructions).

If you are creating your own checkout view or would like to customize the
[options that get passed to tokenize](https://braintree.github.io/braintree-web/3.6.3/PayPal.html#tokenize)
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/spree/frontend/paypal_button.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $(document).ready(function() {
}).
load(function() {
var paypalOptions = {
flow: 'vault',
flow: window.payPalFlow,
enableShippingAddress: true
}
var button = new SolidusPaypalBraintree.createPaypalButton(document.querySelector("#paypal-button"), paypalOptions);
Expand Down
7 changes: 5 additions & 2 deletions app/models/solidus_paypal_braintree/gateway.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ class Gateway < ::Spree::PaymentMethod
preference(:merchant_currency_map, :hash, default: {})
preference(:paypal_payee_email_map, :hash, default: {})

# Which checkout flow to use (vault/checkout)
preference(:paypal_flow, :string, default: 'vault')

def partial_name
"paypal_braintree"
end
Expand Down Expand Up @@ -286,7 +289,7 @@ def transaction_options(source, options, submit_for_settlement = false)
end

params[:channel] = "Solidus"
params[:options] = { store_in_vault_on_success: true }
params[:options] = { store_in_vault_on_success: (preferred_paypal_flow == 'vault') }

if submit_for_settlement
params[:options][:submit_for_settlement] = true
Expand Down Expand Up @@ -357,7 +360,7 @@ def paypal_payee_email_for(source, options)
def customer_profile_params(payment)
params = {}

if payment.source.try(:nonce)
if preferred_paypal_flow == 'vault' && payment.source.try(:nonce)
params[:payment_method_nonce] = payment.source.nonce
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<% id = payment_method.id %>

<% content_for :head do %>
<script>
window.payPalFlow = '<%= SolidusPaypalBraintree::Gateway.first.preferred_paypal_flow %>';
</script>

<script src="https://js.braintreegateway.com/web/3.22.1/js/client.min.js"></script>
<script src="https://js.braintreegateway.com/web/3.22.1/js/data-collector.min.js"></script>

Expand Down Expand Up @@ -45,10 +49,12 @@
}

var paypalOptions = {
flow: 'vault',
flow: window.payPalFlow,
enableShippingAddress: true,
shippingAddressOverride: address,
shippingAddressEditable: false
shippingAddressEditable: false,
amount: '<%= current_order.total %>',
currency: '<%= current_order.currency %>'
}

var button = new SolidusPaypalBraintree.createPaypalButton(document.querySelector("#paypal-button"), paypalOptions);
Expand Down
65 changes: 63 additions & 2 deletions spec/features/frontend/paypal_checkout_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,34 @@
let!(:payment_method) { create_gateway }
let!(:zone) { create(:zone) }

context "goes through checkout using paypal one touch", vcr: { cassette_name: 'paypal/one_touch_checkout', match_requests_on: [:method, :uri] } do
context "goes through checkout using paypal one touch with the Vault flow", vcr: { cassette_name: 'paypal/one_touch_checkout', match_requests_on: [:method, :uri] } do
before do
SolidusPaypalBraintree::Gateway.first.tap do |gateway|
gateway.preferred_paypal_flow = 'vault'
gateway.save!
end

payment_method
add_mug_to_cart
end

it "should check out successfully using one touch" do
pend_if_paypal_slow do
move_through_paypal_popup
expect(page).to have_content("Shipments")
click_on "Place Order"
expect(page).to have_content("Your order has been processed successfully")
end
end
end

context "goes through checkout using paypal one touch with the Checkout with PayPal flow", vcr: { cassette_name: 'paypal/one_touch_checkout', match_requests_on: [:method, :uri] } do
before do
SolidusPaypalBraintree::Gateway.first.tap do |gateway|
gateway.preferred_paypal_flow = 'checkout'
gateway.save!
end

payment_method
add_mug_to_cart
end
Expand All @@ -31,8 +57,43 @@
end
end

context "goes through checkout using paypal", vcr: { cassette_name: 'paypal/checkout', match_requests_on: [:method, :uri] } do
context "goes through checkout using paypal with the Vault flow", vcr: { cassette_name: 'paypal/checkout', match_requests_on: [:method, :uri] } do
before do
SolidusPaypalBraintree::Gateway.first.tap do |gateway|
gateway.preferred_paypal_flow = 'vault'
gateway.save!
end

payment_method
add_mug_to_cart
end

it "should check out successfully through regular checkout" do
expect(page).to have_button("paypal-button")
click_button("Checkout")
fill_in("order_email", with: "[email protected]")
click_button("Continue")
expect(page).to have_content("Customer E-Mail")
fill_in_address
click_button("Save and Continue")
expect(page).to have_content("SHIPPING METHOD")
click_button("Save and Continue")
pend_if_paypal_slow do
move_through_paypal_popup
expect(page).to have_content("Shipments")
click_on "Place Order"
expect(page).to have_content("Your order has been processed successfully")
end
end
end

context "goes through checkout using paypal with the Checkout with PayPal flow", vcr: { cassette_name: 'paypal/checkout', match_requests_on: [:method, :uri] } do
before do
SolidusPaypalBraintree::Gateway.first.tap do |gateway|
gateway.preferred_paypal_flow = 'checkout'
gateway.save!
end

payment_method
add_mug_to_cart
end
Expand Down

0 comments on commit 6fe9c00

Please sign in to comment.