spree_paypal_rest 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d1865d63b26deae7c342e7376af9a4e779544489
4
+ data.tar.gz: 26e6b21025c41397eea41594e3605e2607696488
5
+ SHA512:
6
+ metadata.gz: 70a7191ac74db8576415841cf51c37c05239b77d14b292baaf0975c85e2c444f9176f4f3ec2f6850af253cebdf41437e0f83f6723e95dfff37319b4745e5d3e8
7
+ data.tar.gz: 14050002b7ce7d5930e619d4abbbc88e38639c0832dcdc98259e5bb56cb8a0d258257dd7fd0e8115ba40cbbd990615c2c8cc53806b368952f0ff05aa2d85427a
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 hugomarquez
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # Spree Paypal REST
2
+
3
+ This is a Paypal REST SDK extension for Spree
4
+ Behind the scenes, this extension uses [Paypal Ruby SDK](https://github.com/paypal/PayPal-Ruby-SDK).
5
+
6
+ ### Why?
7
+ * The Official [Spree Paypal Express](https://github.com/spree-contrib/better_spree_paypal_express) extension for Spree latest update was a year ago.
8
+ * Braintree is not available in some countries.
9
+ * Support for latest stable Spree release 3.1
10
+ *
11
+
12
+ ## Features
13
+ * Paypal Express Checkout/Payment Experience API integration.
14
+ * Support for Promotions and Adjustments.
15
+ * Let Spree handle Orders and Payments flow.
16
+ * Fixes promotion code not detected when enter key is pressed in payment form. https://github.com/spree-contrib/better_spree_paypal_express/issues/119
17
+
18
+ ## Installation
19
+ Before installing this extension please follow Spree installation Guide.
20
+
21
+ cd my_project
22
+ echo "gem 'spree_paypal_rest', '0.0.1'" >> Gemfile
23
+ bundle
24
+ rails g spree_paypal_rest:install
25
+ rails server
26
+
27
+ ## Sandbox Setup
28
+
29
+ ### Paypal
30
+
31
+ Go to [PayPal's Developer Website](https://developer.paypal.com/), sign in with your PayPal account, click "Sandbox -> Accounts" and create a new "Business" account. Once the account is created, click on "My Apps & Credentials" scroll down to REST API apps and create a new app, select your app's name and sandbox business account.
32
+
33
+ Click on your app to access Sandbox API Credentials.
34
+
35
+ You will also need a "Personal" account to test the transactions on your site. Create this in the same way, finding the account information under "Profile" as well. You may need to set a password in order to be able to log in to PayPal's sandbox for this user. **(There is no need to create a REST API App for this account)**
36
+
37
+ ### Spree Backend
38
+
39
+ In Spree, go to the admin backend, click "Configuration -> Payment Methods" and create a new payment method. Select "Spree::Gateway::PaypalExpress" as the provider, and click "Create".
40
+
41
+ Then enter the following information for your paypal **Business** Account:
42
+ * Brand Name
43
+ * Address Override
44
+ * Landing Page Type
45
+ * Temporary
46
+ * Locale Code
47
+ * Profile Name
48
+ * Logo URL
49
+ * Server
50
+ * Client ID
51
+ * Client Secret
52
+ * Test Mode
53
+ * Auto Capture
54
+
55
+ **For information on this fields and Paypal REST API in general, please take a look at the paypal REST API documentation**
56
+
57
+ * [REST API reference](https://developer.paypal.com/docs/api/)
58
+ * [Payment Experience API](https://developer.paypal.com/docs/api/payment-experience/)
59
+ * [Payments API](https://developer.paypal.com/docs/api/payments/)
60
+
61
+ ## TO-DO
62
+ * Refund action in Spree::Gateway::PaypalExpress.
63
+ * Cancel action in Spree::Gateway::PaypalExpress.
64
+ * Internationalization.
65
+ * More testing and specs always welcome.
66
+ * Follow Spree versioning style.
67
+
68
+
69
+ ## Contributing
70
+
71
+ In the spirit of [free software](1), **everyone** is encouraged to help improve this project.
72
+
73
+ Here are some ways *you* can contribute:
74
+
75
+ * by using prerelease versions
76
+ * by reporting [bugs][2]
77
+ * by suggesting new features
78
+ * by writing or editing documentation
79
+ * by writing specifications
80
+ * by writing code (*no patch is too small*: fix typos, add comments, clean up inconsistent whitespace)
81
+ * by refactoring code
82
+ * by resolving [issues][2]
83
+ * by reviewing patches
84
+
85
+ Starting point:
86
+
87
+ * Fork the repo
88
+ * Clone your repo
89
+ * Run `bundle install`
90
+ * Make your changes
91
+ * Ensure specs pass by running `bundle exec rspec spec`
92
+ * Submit your pull request
93
+
94
+ [1]: http://www.fsf.org/licensing/essays/free-sw.html
95
+ [2]: https://github.com/spree/better_spree_paypal_express/issues
96
+
97
+ ## License
98
+ Licensed under the MIT license. Full details can be found in the MIT-LICENSE file in the root of the repository.
data/Rakefile ADDED
@@ -0,0 +1,16 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
8
+ load 'rails/tasks/engine.rake'
9
+
10
+
11
+ load 'rails/tasks/statistics.rake'
12
+
13
+
14
+
15
+ Bundler::GemHelper.install_tasks
16
+
@@ -0,0 +1,59 @@
1
+ module Spree
2
+ CheckoutController.class_eval do
3
+ before_filter :paypal_rest_hook, only: :update, if: proc { params[:state].eql?('payment') }
4
+
5
+ def paypal_express
6
+ if @order.update_from_params(params, permitted_checkout_attributes, request.headers.env)
7
+ @payment_method = PaymentMethod.find(params[:order][:payments_attributes].first[:payment_method_id])
8
+ @payment = @payment_method.request_payment(@order)
9
+ if @payment.create
10
+ @redirect_url = @payment.links.find{|v| v.method == "REDIRECT" }.href
11
+ redirect_to @redirect_url
12
+ else
13
+ flash[:error] = @payment.error.inspect
14
+ render :edit
15
+ end
16
+ end
17
+ end
18
+
19
+ def paypal_express_return
20
+ paypal_checkout = Spree::PaypalRestCheckout.new(
21
+ token: params[:token],
22
+ payer_id: params[:PayerID],
23
+ transaction_id: params[:paymentId],
24
+ state: params[:state]
25
+ )
26
+ @order.payments.create!({
27
+ source: paypal_checkout,
28
+ amount: @order.total,
29
+ payment_method: @order.payments.last.payment_method
30
+ })
31
+
32
+ until @order.state == "complete"
33
+ if @order.next!
34
+ @order.update_with_updater!
35
+ end
36
+ end
37
+
38
+ flash.notice = Spree.t(:order_processed_successfully)
39
+ redirect_to completion_route
40
+ end
41
+
42
+ def paypal_express_cancel
43
+ flash[:error] = Spree.t(:payment_has_been_cancelled)
44
+ redirect_to edit_order_path(@order)
45
+ end
46
+
47
+ private
48
+
49
+ def paypal_rest_hook
50
+ return unless params[:order] && params[:order][:payments_attributes]
51
+ payment_method = PaymentMethod.find(params[:order][:payments_attributes].first[:payment_method_id])
52
+ if payment_method.kind_of?(Spree::Gateway::PaypalExpress)
53
+ paypal_express
54
+ end
55
+ end
56
+
57
+
58
+ end
59
+ end
@@ -0,0 +1,64 @@
1
+ module Spree
2
+ class Gateway::PaypalExpress < Gateway::PaypalRestBase
3
+ include Gateway::PaypalWebProfile
4
+ include Gateway::PaypalPayment
5
+
6
+ preference :brand_name, :string
7
+ preference :allow_note, :boolean, default: false
8
+ preference :no_shipping, :boolean, default: true
9
+ preference :address_override, :integer, default: 1
10
+ preference :landing_page_type, :string, default:'billing'
11
+ preference :temporary, :boolean, default: true
12
+ preference :locale_code, :string, default: 'US'
13
+ preference :profile_name, :string
14
+ preference :logo_url, :string, default: 'https://www.paypalobjects.com/webstatic/en_US/i/btn/png/blue-rect-paypal-60px.png'
15
+
16
+ alias_method :purchase, :authorize
17
+
18
+ def source_required?
19
+ true
20
+ end
21
+
22
+ def auto_capture?
23
+ true
24
+ end
25
+
26
+ def method_type
27
+ 'paypal_express'
28
+ end
29
+
30
+ def request_payment(order)
31
+ provider
32
+ payment(order, first_or_new(profile_options).id)
33
+ end
34
+
35
+ def purchase(amount, source, options)
36
+ response = payment_source_class.find(source.transaction_id)
37
+ source.update(state: response.state)
38
+ case response.state
39
+ when 'created'
40
+ ActiveMerchant::Billing::Response.new(true, 'success', {}, {})
41
+ when 'failed'
42
+ ActiveMerchant::Billing::Response.new(true, 'failed', {}, {})
43
+ end
44
+ end
45
+
46
+ def refund(order)
47
+ # TODO
48
+ end
49
+
50
+ def profile_options
51
+ {
52
+ profile_name: preferred_profile_name,
53
+ brand_name: preferred_brand_name,
54
+ allow_note: preferred_allow_note,
55
+ no_shipping: preferred_no_shipping,
56
+ locale_code: preferred_locale_code,
57
+ address_override: preferred_address_override,
58
+ landing_page_type: preferred_landing_page_type,
59
+ temporary: preferred_temporary
60
+ }
61
+ end
62
+
63
+ end
64
+ end
@@ -0,0 +1,86 @@
1
+ module Spree
2
+ module Gateway::PaypalPayment
3
+
4
+ def payment(order, web_profile_id)
5
+ payment_options = payment_payload(order, web_profile_id)
6
+ @payment = PayPal::SDK::REST::DataTypes::Payment.new(payment_options)
7
+ return @payment
8
+ end
9
+
10
+ def payment_payload(order, web_profile_id)
11
+ payload = {
12
+ intent: 'sale',
13
+ experience_profile_id: web_profile_id,
14
+ payer:{
15
+ payment_method: 'paypal',
16
+ payer_info:{
17
+ first_name: order.user.billing_address.first_name,
18
+ last_name: order.user.billing_address.last_name,
19
+ email: order.user.email,
20
+ billing_address: billing_address(order)
21
+ }
22
+ },
23
+ redirect_urls: {
24
+ return_url: 'http://localhost:3000' + Core::Engine.routes.url_helpers.paypal_express_return_order_checkout_path(order.id),
25
+ cancel_url: 'http://localhost:3000' + Core::Engine.routes.url_helpers.paypal_express_cancel_order_checkout_path(order.id),
26
+ },
27
+ transactions:[{
28
+ item_list:{
29
+ items: order_line_items(order)
30
+ },
31
+ amount: {
32
+ total: order.total.to_s,
33
+ currency: order.currency,
34
+ details:{
35
+ shipping: order.shipments.map(&:discounted_cost).sum,
36
+ subtotal: order.item_total.to_s,
37
+ tax: order.additional_tax_total.to_s
38
+ }
39
+ },
40
+ description: 'This is the sale description',
41
+ }]
42
+ }
43
+ end
44
+
45
+ def order_line_items(order)
46
+ items = []
47
+
48
+ order.line_items.map do |item|
49
+ items << {
50
+ name: item.product.name,
51
+ sku: item.product.sku,
52
+ price: item.price.to_s,
53
+ currency: item.order.currency,
54
+ quantity: item.quantity
55
+ }
56
+ end
57
+
58
+ order.all_adjustments.eligible.each do |adj|
59
+ next if adj.amount.zero?
60
+ next if adj.source_type.eql?('Spree::TaxRate')
61
+ next if adj.source_type.eql?('Spree::Shipment')
62
+ next if adj.source_type.eql?('Spree::PromotionAction')
63
+ items << {
64
+ name: adj.label,
65
+ price: adj.amount.to_s,
66
+ currency: order.currency,
67
+ quantity: 1
68
+ }
69
+ end
70
+ items
71
+ end
72
+
73
+ def billing_address(order)
74
+ {
75
+ recipient_name: order.billing_address.full_name,
76
+ line1: order.billing_address.address1 + ' ' + order.billing_address.address2,
77
+ city: order.billing_address.city,
78
+ country_code: order.billing_address.country.iso,
79
+ postal_code: order.billing_address.zipcode,
80
+ phone: order.billing_address.phone,
81
+ state: order.billing_address.state.name
82
+ }
83
+ end
84
+
85
+ end
86
+ end
@@ -0,0 +1,27 @@
1
+ module Spree
2
+ class Gateway::PaypalRestBase < Gateway
3
+ include PayPal::SDK::REST
4
+ include PayPal::SDK::Core::Logging
5
+
6
+ preference :server, :select, default: 'sandbox'
7
+ preference :client_id, :string
8
+ preference :client_secret, :string
9
+
10
+ def provider_class
11
+ PayPal::SDK::REST
12
+ end
13
+
14
+ def payment_source_class
15
+ PayPal::SDK::REST::DataTypes::Payment
16
+ end
17
+
18
+ def provider
19
+ provider_class.set_config(
20
+ mode: preferred_server,
21
+ client_id: preferred_client_id,
22
+ client_secret: preferred_client_secret
23
+ )
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,60 @@
1
+ module Spree
2
+ module Gateway::PaypalWebProfile
3
+
4
+ def web_profile_class
5
+ PayPal::SDK::REST::DataTypes::WebProfile
6
+ end
7
+
8
+ def create_profile(options)
9
+ web_profile_class.new(request_hash(options)).create
10
+ end
11
+
12
+ def update_profile(id, options)
13
+ find_profile(id).partial_update(options)
14
+ end
15
+
16
+ def delete_profile(id)
17
+ find_profile(id).delete
18
+ end
19
+
20
+ def find_profile(id)
21
+ web_profile_class.find(id)
22
+ end
23
+
24
+ def get_list
25
+ # The API is inconsistent in that it returns an array of WebProfiles
26
+ # instead of a JSON object with a property which should be a list
27
+ # of WebProfiles.
28
+ web_profile_class.get_list
29
+ end
30
+
31
+ def first_or_new(options)
32
+ list = get_list
33
+ if list.empty?
34
+ web_profile_class.new(request_hash(options))
35
+ else
36
+ list.first
37
+ end
38
+ end
39
+
40
+ def request_hash(options)
41
+ {
42
+ name: options[:profile_name],
43
+ presentation:{
44
+ brand_name: options[:brand_name],
45
+ locale_code: options[:locale_code],
46
+ },
47
+ input_fields:{
48
+ allow_note: options[:allow_note],
49
+ no_shipping: options[:no_shipping],
50
+ address_override: options[:address_override],
51
+ },
52
+ flow_config:{
53
+ landing_page_type: options[:landing_page_type],
54
+ return_uri_http_method: 'get'
55
+ }
56
+ }
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,7 @@
1
+ class Spree::PaypalRestCheckout < ActiveRecord::Base
2
+ has_many :payments, as: :source
3
+
4
+ scope :in_state, ->(state) { where(state: state) }
5
+ scope :not_in_state, ->(state) { where.not(state: state) }
6
+
7
+ end
@@ -0,0 +1,33 @@
1
+ <fieldset>
2
+ <legend>Paypal Express Checkout </legend>
3
+
4
+ <table class="index">
5
+ <tr>
6
+ <th colspan="6">Transaction</th>
7
+ </tr>
8
+ <tr>
9
+ <td>State: </td>
10
+ <td>
11
+ <%= payment.source.state %>
12
+ </td>
13
+ </tr>
14
+ <tr>
15
+ <td><label>Token: </label></td>
16
+ <td>
17
+ <%= payment.source.token %>
18
+ </td>
19
+ </tr>
20
+ <tr>
21
+ <td><label>Payer Id: </label></td>
22
+ <td>
23
+ <%= payment.source.payer_id %>
24
+ </td>
25
+ </tr>
26
+ <tr>
27
+ <td><label>Transaction Id: </label></td>
28
+ <td>
29
+ <%= payment.source.transaction_id %>
30
+ </td>
31
+ </tr>
32
+ </table>
33
+ </fieldset>
@@ -0,0 +1,3 @@
1
+ <div class="well clearfix">
2
+ <p class="field">Paypal translation of instructions here...</p>
3
+ </div>
data/config/routes.rb ADDED
@@ -0,0 +1,13 @@
1
+ Spree::Core::Engine.add_routes do
2
+
3
+ resources :orders do
4
+ resource :checkout, controller:'checkout' do
5
+ member do
6
+ get :paypal_express
7
+ get :paypal_express_cancel
8
+ get :paypal_express_return
9
+ end
10
+ end
11
+ end
12
+
13
+ end
@@ -0,0 +1,15 @@
1
+ class CreateSpreePaypalRestCheckouts < ActiveRecord::Migration
2
+ def change
3
+ create_table :spree_paypal_rest_checkouts do |t|
4
+ t.string :token
5
+ t.string :payer_id
6
+ t.string :transaction_id, index: true
7
+ t.string :refund_id, index: true
8
+ t.string :web_profile_id
9
+ t.string :refund_type
10
+ t.string :state
11
+ t.datetime :refunded_at
12
+ t.timestamps null: false
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,25 @@
1
+ module SpreePaypalRest
2
+ class Engine < ::Rails::Engine
3
+ config.generators do |g|
4
+ g.test_framework :rspec, fixture: false
5
+ g.fixture_replacement :factory_girl, dir: 'spec/factories'
6
+ g.assets false
7
+ g.helper false
8
+ end
9
+
10
+ def self.activate
11
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
12
+ Rails.configuration.cache_classes ? require(c) : load(c)
13
+ end
14
+ end
15
+
16
+ config.to_prepare &method(:activate).to_proc
17
+
18
+ initializer 'spree.paypal_rest.payment_methods', after: 'spree.register.payment_methods' do |app|
19
+ app.config.spree.payment_methods += [
20
+ Spree::Gateway::PaypalExpress
21
+ ]
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module SpreePaypalRest
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,10 @@
1
+ require 'byebug'
2
+ require 'paypal-sdk-rest'
3
+ require 'spree'
4
+ require 'spree_core'
5
+ require 'spree_auth_devise'
6
+
7
+ require 'spree_paypal_rest/engine'
8
+
9
+ module SpreePaypalRest
10
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :spree_paypal_rest do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,228 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: spree_paypal_rest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - hugomarquez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-12-18 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 4.2.7
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 4.2.7
27
+ - !ruby/object:Gem::Dependency
28
+ name: paypal-sdk-rest
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.6.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.6.0
41
+ - !ruby/object:Gem::Dependency
42
+ name: spree
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 3.1.3
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 3.1.3
55
+ - !ruby/object:Gem::Dependency
56
+ name: spree_core
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 3.1.3
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 3.1.3
69
+ - !ruby/object:Gem::Dependency
70
+ name: spree_auth_devise
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 3.1.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 3.1.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: sqlite3
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: jquery-rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '3'
104
+ - - "<"
105
+ - !ruby/object:Gem::Version
106
+ version: '5'
107
+ type: :development
108
+ prerelease: false
109
+ version_requirements: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '3'
114
+ - - "<"
115
+ - !ruby/object:Gem::Version
116
+ version: '5'
117
+ - !ruby/object:Gem::Dependency
118
+ name: sass-rails
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '4.0'
124
+ - - "<"
125
+ - !ruby/object:Gem::Version
126
+ version: '6'
127
+ type: :development
128
+ prerelease: false
129
+ version_requirements: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '4.0'
134
+ - - "<"
135
+ - !ruby/object:Gem::Version
136
+ version: '6'
137
+ - !ruby/object:Gem::Dependency
138
+ name: coffee-rails
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - '='
142
+ - !ruby/object:Gem::Version
143
+ version: 4.2.1
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - '='
149
+ - !ruby/object:Gem::Version
150
+ version: 4.2.1
151
+ - !ruby/object:Gem::Dependency
152
+ name: byebug
153
+ requirement: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ type: :development
159
+ prerelease: false
160
+ version_requirements: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ version: '0'
165
+ - !ruby/object:Gem::Dependency
166
+ name: thin
167
+ requirement: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - '='
170
+ - !ruby/object:Gem::Version
171
+ version: 1.6.4
172
+ type: :development
173
+ prerelease: false
174
+ version_requirements: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - '='
177
+ - !ruby/object:Gem::Version
178
+ version: 1.6.4
179
+ description: Adds PayPal Express as a Payment Method to Spree Commerce
180
+ email:
181
+ - hugomarquez.dev@gmail.com
182
+ executables: []
183
+ extensions: []
184
+ extra_rdoc_files: []
185
+ files:
186
+ - MIT-LICENSE
187
+ - README.md
188
+ - Rakefile
189
+ - app/controllers/spree/checkout_controller_decorator.rb
190
+ - app/models/spree/gateway/paypal_express.rb
191
+ - app/models/spree/gateway/paypal_payment.rb
192
+ - app/models/spree/gateway/paypal_rest_base.rb
193
+ - app/models/spree/gateway/paypal_web_profile.rb
194
+ - app/models/spree/paypal_rest_checkout.rb
195
+ - app/views/spree/admin/payments/source_forms/_paypal_express.html.erb
196
+ - app/views/spree/admin/payments/source_views/_paypal_express.html.erb
197
+ - app/views/spree/checkout/payment/_paypal_express.html.erb
198
+ - config/routes.rb
199
+ - db/migrate/20161212151705_create_spree_paypal_rest_checkouts.rb
200
+ - lib/spree_paypal_rest.rb
201
+ - lib/spree_paypal_rest/engine.rb
202
+ - lib/spree_paypal_rest/version.rb
203
+ - lib/tasks/spree_paypal_rest_tasks.rake
204
+ homepage: http://www.spreecommerce.com
205
+ licenses:
206
+ - MIT
207
+ metadata: {}
208
+ post_install_message:
209
+ rdoc_options: []
210
+ require_paths:
211
+ - lib
212
+ required_ruby_version: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ required_rubygems_version: !ruby/object:Gem::Requirement
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ version: '0'
222
+ requirements: []
223
+ rubyforge_project:
224
+ rubygems_version: 2.5.1
225
+ signing_key:
226
+ specification_version: 4
227
+ summary: Adds PayPal Express as a Payment Method to Spree Commerce
228
+ test_files: []