Skip to content

Commit

Permalink
Merge pull request #138 from RyanofWoods/add-venmo-as-payment-option
Browse files Browse the repository at this point in the history
Add Venmo as payment option
  • Loading branch information
DanielePalombo authored Dec 7, 2021
2 parents 0a18987 + 2498c7e commit 1984054
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 10 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,20 @@ With product and cart page checkout, the user is directed to the checkout confir

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)

## Venmo
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).

If the transaction supports Venmo then a button should appear for it on checkout, cart and product page, depending on your `Payment Method` preferences.

If you wish to disable Venmo, then set your `Payment Methods`'s `enable_venmo` preference to `false`. See more about preferences([Configuration](#configuration)) below.

[_As Venmo is only available in the US, you may want to mock your location for testing_](#mocking-your-buyer-country)

## Configuration
The easiest way to change the `Payment Method`'s preferences is through admin: `Settings > Payments > "PayPal Commerce Platform" > Edit`.

See more about preferences [here](https://guides.solidus.io/developers/preferences/add-model-preferences.html#access-your-preferences)/

## Development

### Testing the extension
Expand Down Expand Up @@ -162,6 +176,12 @@ $ bin/rails server
Use Ctrl-C to stop
```

### Mocking your buyer country
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.
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.

This preference has no effect on production.

### Updating the changelog

Before and after releases the changelog should be updated to reflect the up-to-date status of
Expand Down
8 changes: 8 additions & 0 deletions app/models/solidus_paypal_commerce_platform/payment_method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ class PaymentMethod < SolidusSupport.payment_method_parent_class
preference :display_on_cart, :boolean, default: true
preference :display_on_product_page, :boolean, default: true
preference :display_credit_messaging, :boolean, default: true
preference :enable_venmo, :boolean, default: true
preference :force_buyer_country, :string

def partial_name
"paypal_commerce_platform"
Expand Down Expand Up @@ -73,6 +75,12 @@ def javascript_sdk_url(order: nil, currency: nil)
}

parameters[:shipping_preference] = 'NO_SHIPPING' if step_names.exclude? 'delivery'
parameters['enable-funding'] = 'venmo' if options[:enable_venmo]
parameters['disable-funding'] = 'venmo' unless options[:enable_venmo]

if !Rails.env.production? && options[:force_buyer_country].present?
parameters['buyer-country'] = options[:force_buyer_country]
end

"https://www.paypal.com/sdk/js?#{parameters.to_query}"
end
Expand Down
63 changes: 53 additions & 10 deletions spec/models/solidus_paypal_commerce_platform/payment_method_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,48 +77,91 @@ def Struct(data) # rubocop:disable Naming/MethodName
describe '.javascript_sdk_url' do
subject(:url) { URI(paypal_payment_method.javascript_sdk_url(order: order)) }

context 'when checkout_steps include "confirm"' do
let(:order) { instance_double(Spree::Order, checkout_steps: { "confirm" => "bar" }) }
let(:order) { build_stubbed(:order) }

context 'when checkout_steps include "confirm"' do
it 'sets autocommit' do
expect(url.query.split("&")).to include("commit=false")
end
end

context 'when checkout_steps does not include "confirm"' do
let(:order) { instance_double(Spree::Order, checkout_steps: { "foo" => "bar" }) }

it 'disables autocommit' do
allow(order).to receive(:checkout_steps).and_return([:address, :delivery, :payment])
expect(url.query.split("&")).to include("commit=true")
end
end

context 'when checkout_steps does not include "delivery"' do
let(:order) { instance_double(Spree::Order, checkout_steps: { "foo" => "bar" }) }

it 'disables autocommit' do
allow(order).to receive(:checkout_steps).and_return([:address, :confirm, :payment])
expect(url.query.split("&")).to include("shipping_preference=NO_SHIPPING")
end
end

context 'when messaging is turned on' do
let(:order) { instance_double(Spree::Order, checkout_steps: { "foo" => "bar" }) }

it 'includes messaging component' do
paypal_payment_method.preferences.update(display_credit_messaging: true)
expect(url.query.split("&")).to include("components=buttons%2Cmessages")
end
end

context 'when messaging is turned off' do
let(:order) { instance_double(Spree::Order, checkout_steps: { "foo" => "bar" }) }

it 'only includes buttons components' do
paypal_payment_method.preferences.update(display_credit_messaging: false)
expect(url.query.split("&")).not_to include("messages")
expect(url.query.split("&")).to include("components=buttons")
end
end

context 'when enable_venmo is false' do
before { paypal_payment_method.preferences.update(enable_venmo: false) }

it 'does not include "enable-funding=venmo" as a parameter' do
expect(url.query.split('&')).not_to include('enable-funding=venmo')
end

it 'includes "disable-funding=venmo" as a parameter' do
expect(url.query.split('&')).to include('disable-funding=venmo')
end
end

context 'when enable_venmo is true' do
before { paypal_payment_method.preferences.update(enable_venmo: true) }

it 'includes "enable-funding=venmo" as a parameter' do
expect(url.query.split('&')).to include('enable-funding=venmo')
end

it 'does not include "disable-funding=venmo" as a parameter' do
expect(url.query.split('&')).not_to include('disable-funding=venmo')
end
end

context 'when force_buyer_country is an empty string' do
it 'does not include the "buyer-country" parameter' do
expect(url.query.split('&')).not_to include(match 'buyer-country')
end
end

context 'when force_buyer_country is "US"' do
before { paypal_payment_method.preferences.update(force_buyer_country: 'US') }

it 'includes "buyer-country=US" as a parameter' do
expect(url.query.split('&')).to include('buyer-country=US')
end
end

context 'when force_buyer_country is "US" but the environment is production' do
before {
allow(Rails.env).to receive(:production?).and_return(true)
paypal_payment_method.preferences.update(force_buyer_country: 'US')
}

it 'includes "buyer-country=US" as a parameter' do
expect(url.query.split('&')).not_to include(match 'buyer-country')
end
end
end

private
Expand Down

0 comments on commit 1984054

Please sign in to comment.