spree_paypal_api_checkout 0.1.0 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 53c335900fbbe782e6fc7cfa78b36f258b514a9d9b9400cef65f7fb8c7cf69c7
4
- data.tar.gz: 946f4fa867ded14d6c7f494df8d8e21377721b682df09fe7cffd312540268540
3
+ metadata.gz: b79612956a0c2a85e4e971f5967be818be56d438b7034f7cc7b7bef83a01178d
4
+ data.tar.gz: f0ef4e1ea934c9c0309401707474219acb71a99a7471ec59a0da91eb29749eae
5
5
  SHA512:
6
- metadata.gz: 0d1754cdff574bb9bbe6b798663c02686228ec3a0e7fe30281b87dea2264245d2f296e849ad44145282305766678b5956834a8a44f0ed17c38e6a644abeb0719
7
- data.tar.gz: aef76e65dae6694919ddc17f3c290de2a49be957ac913a9a0ba4863bfe0f1a576d7a10c7e7fcce1a658e087c1b48786514f21c329354094024a124b961986801
6
+ metadata.gz: a3a8b3c4673d8ce405272ee20010636c0d3ded18eccf5c446cb2ad3a4f386bd5fa696e1f9d5783de6dcf12f0ce684668c9f62f7f36d07fce46fbb7a9678bb5f8
7
+ data.tar.gz: 2fb57d527e37a19d25b92a2e9f97f7f5143294e77b12f5b369d19e96a0b5670fc6dff7e11a30f1b03af9714e4ae6726bc393cec629f681c0aa5a3b6db5af782e
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  1. Add this extension to your Gemfile with this line:
6
6
 
7
- gem 'spree_paypal_api_checkout', '~> 0.1.0'
7
+ gem 'spree_paypal_api_checkout', '~> 0.1.3'
8
8
 
9
9
  2. Install the gem using Bundler:
10
10
 
@@ -3,7 +3,7 @@
3
3
  SpreePaypalCheckout = {
4
4
  hideSettings: function(paymentMethod) {
5
5
  if (SpreePaypalCheckout.paymentMethodID && paymentMethod.val() == SpreePaypalCheckout.paymentMethodID) {
6
- $('.payment-method-settings').children().hide();
6
+ // $('.payment-method-settings').children().hide();
7
7
  $('#payment_amount').prop('disabled', 'disabled');
8
8
  $('button[type="submit"]').prop('disabled', 'disabled');
9
9
  $('#paypal-warning').show();
@@ -1,6 +1,7 @@
1
1
  module Spree
2
2
  class PaypalCheckoutController < StoreController
3
3
  skip_before_action :verify_authenticity_token
4
+
4
5
  def express
5
6
  order = current_order || raise(ActiveRecord::RecordNotFound)
6
7
  items = order.line_items.map(&method(:line_item))
@@ -27,22 +28,17 @@ module Spree
27
28
  }
28
29
  end
29
30
 
30
- pp_response = provider.create_order(order, express_checkout_request_details(order: order, items: items, tax_adjustments: tax_adjustments, promotion_adjustments: promotion_adjustments))
31
+ details = express_checkout_request_details(order: order, items: items, tax_adjustments: tax_adjustments, promotion_adjustments: promotion_adjustments)
32
+ pp_response = provider.parse_response(provider.create_order(order, details))
31
33
 
32
34
  render json: pp_response
33
35
  end
34
36
 
35
37
  def confirm
36
38
  order = current_order || raise(ActiveRecord::RecordNotFound)
37
- response = provider.capture_payment(params[:number])
38
- order.payments.create!({
39
- source: Spree::PaypalApiCheckout.create({
40
- token: response['id'],
41
- payer_id: response['payer']['payer_id']
42
- }),
43
- amount: order.total,
44
- payment_method: payment_method
45
- })
39
+
40
+ response = provider.set_payment_records(order, params[:number], payment_method)
41
+
46
42
  render json: response
47
43
  end
48
44
 
@@ -88,6 +84,7 @@ module Spree
88
84
  intent: 'CAPTURE',
89
85
  purchase_units: [
90
86
  {
87
+ invoice_id: current_order.number,
91
88
  amount: {
92
89
  currency_code: current_order.currency,
93
90
  value: order.total,
@@ -21,38 +21,24 @@ module Spree
21
21
  end
22
22
 
23
23
  def generate_access_token
24
- uri = URI.parse("https://#{preferred_server}/v1/oauth2/token")
25
- request = Net::HTTP::Post.new(uri)
26
- request.basic_auth("#{preferred_api_key}", "#{preferred_secret_key}")
27
- request.content_type = 'application/json'
28
- request.body = 'grant_type=client_credentials'
29
-
30
- req_options = { use_ssl: uri.scheme == 'https' }
31
-
32
- response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
33
- response = http.request(request)
34
- end
35
- return JSON.parse(response.read_body)['access_token']
24
+ response = post_response_without_token(api_url('v1/oauth2/token'))
25
+ return response['access_token']
36
26
  end
37
27
 
38
28
  def generate_client_token
39
- uri = URI.parse("https://#{preferred_server}/v1/identity/generate-token")
40
- return post_response(uri)
29
+ post_response(api_url('v1/identity/generate-token'))
41
30
  end
42
31
 
43
32
  def create_order order, body
44
- uri = URI.parse("https://#{preferred_server}/v2/checkout/orders")
45
- return post_response(uri, body)
33
+ post_response(api_url('v2/checkout/orders'), body)
46
34
  end
47
35
 
48
36
  def capture_payment order_id
49
- uri = URI.parse("https://#{preferred_server}/v2/checkout/orders/#{order_id}/capture")
50
- return post_response(uri)
37
+ post_response(api_url("v2/checkout/orders/#{order_id}/capture"))
51
38
  end
52
39
 
53
40
  def refund_payment id, body
54
- uri = URI.parse("https://#{preferred_server}/v2/payments/captures/#{id}/refund")
55
- return post_response(uri, body)
41
+ post_response(api_url("v2/payments/captures/#{id}/refund"), body)
56
42
  end
57
43
 
58
44
  def purchase(amount, express_checkout, gateway_options={})
@@ -78,8 +64,10 @@ module Spree
78
64
  refund_type: refund_type,
79
65
  refund_source: 'any'
80
66
  }
81
- refund_transaction_response = refund_payment(payment.source.transaction_id, refund_transaction)
82
- if refund_transaction_response['status']=='COMPLETED'
67
+ refund_entry = refund_payment(payment.source.transaction_id, refund_transaction)
68
+ refund_transaction_response = parse_response(refund_entry)
69
+
70
+ if success_response?(refund_transaction_response)
83
71
  payment.source.update({
84
72
  :refunded_at => Time.now,
85
73
  :refund_transaction_id => refund_transaction_response['id'],
@@ -87,7 +75,7 @@ module Spree
87
75
  :refund_type => refund_type
88
76
  })
89
77
 
90
- payment.class.create!(
78
+ refund_payment = payment.class.create!(
91
79
  :order => payment.order,
92
80
  :source => payment,
93
81
  :payment_method => payment.payment_method,
@@ -95,6 +83,7 @@ module Spree
95
83
  :response_code => refund_transaction_response['id'],
96
84
  :state => 'completed'
97
85
  )
86
+ refund_payment.log_entries.create!(details: refund_entry.to_yaml)
98
87
  end
99
88
  refund_transaction_response
100
89
  end
@@ -102,14 +91,84 @@ module Spree
102
91
  def post_response uri, body={}
103
92
  request = Net::HTTP::Post.new(uri)
104
93
  request['Authorization'] = "Bearer #{generate_access_token}"
94
+ request.body = body.to_json if body.present?
95
+
96
+ return hit_api(request: request, body: body, uri: uri)
97
+ end
98
+
99
+ def post_response_without_token uri, body={}
100
+ request = Net::HTTP::Post.new(uri)
101
+ request.basic_auth("#{preferred_api_key}", "#{preferred_secret_key}")
102
+ request.body = 'grant_type=client_credentials'
103
+
104
+ return parse_response(hit_api(request: request, body: body, uri: uri))
105
+ end
106
+
107
+ def hit_api request:, body:, uri:
105
108
  request.content_type = 'application/json'
106
109
  req_options = { use_ssl: uri.scheme == 'https' }
107
110
 
108
- request.body = body.to_json if body.present?
109
111
  response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
110
112
  response = http.request(request)
111
113
  end
112
- return JSON.parse(response.read_body)
114
+ response
115
+ end
116
+
117
+ def parse_response response
118
+ JSON.parse(response.read_body) rescue response
119
+ end
120
+
121
+ def api_url url
122
+ URI.parse("https://#{preferred_server}/#{url}")
123
+ end
124
+
125
+ def set_payment_records order, number, payment_method
126
+ raw_response = response = nil
127
+ success = false
128
+ begin
129
+ payment_entry = capture_payment(number)
130
+ response = parse_response(payment_entry)
131
+ success = success_response?(response)
132
+
133
+ payment = order.payments.create!({
134
+ source: Spree::PaypalApiCheckout.create({
135
+ token: response['id'],
136
+ payer_id: response['payer']['payer_id']
137
+ }),
138
+ amount: order.total,
139
+ payment_method: payment_method
140
+ })
141
+ rescue Exception => e
142
+ raw_response = e.response.body
143
+ response = response_error(raw_response)
144
+ rescue JSON::ParserError
145
+ response = json_error(raw_response)
146
+ end
147
+
148
+ payment.log_entries.create!(details: payment_entry.to_yaml)
149
+ response
150
+ end
151
+
152
+ def response_error(raw_response)
153
+ begin
154
+ parse(raw_response)
155
+ rescue JSON::ParserError
156
+ json_error(raw_response)
157
+ end
158
+ end
159
+
160
+ def json_error(raw_response)
161
+ msg = 'Invalid response. Please contact team if you continue to receive this message.'
162
+ msg += " (The raw response returned by the API was #{raw_response.inspect})"
163
+ {
164
+ "error" => {
165
+ "message" => msg
166
+ }
167
+ }
168
+ end
169
+
170
+ def success_response? response
171
+ response.key?('status') && response.key?('id') && (response['status'] == 'COMPLETED')
113
172
  end
114
173
  end
115
174
  end
@@ -0,0 +1,22 @@
1
+ module Spree
2
+ module LogEntryDecorator
3
+ def parsed_details
4
+ @details ||= YAML.safe_load(details, [ActiveMerchant::Billing::Response, Net::HTTPCreated, URI::HTTPS, URI::RFC3986_Parser, Symbol, Regexp, Object])
5
+ end
6
+
7
+ def success_parsed_details?
8
+ if parsed_details.is_a?(Net::HTTPCreated)
9
+ parsed_paypal_entry == 'COMPLETED'
10
+ elsif parsed_details.is_a?(ActiveMerchant::Billing::Response)
11
+ parsed_details.success?
12
+ else
13
+ true
14
+ end
15
+ end
16
+
17
+ def parsed_paypal_entry
18
+ JSON.parse(parsed_details.read_body)['status'] rescue parsed_details.to_json
19
+ end
20
+ end
21
+ end
22
+ ::Spree::LogEntry.prepend(Spree::LogEntryDecorator)
@@ -0,0 +1,8 @@
1
+ <% currency = ::Money::Currency.new(entry.source.currency) %>
2
+ <tr>
3
+ <td><b><%= Spree.t('paypal.status').capitalize %></b></td>
4
+ <td><%= entry.source.amount.negative? ? entry.source.source.source.state : entry.source.state %></td>
5
+ <td><%= entry.parsed_paypal_entry %></td>
6
+ <td><%= currency.symbol %><%= entry.source.amount %></td>
7
+ <td><%= entry.source.response_code %></td>
8
+ </tr>
@@ -0,0 +1,27 @@
1
+ <%= render :partial => 'spree/admin/shared/order_tabs', locals: { current: 'Payments' }%>
2
+
3
+ <% content_for :page_title do %>
4
+ <i class="icon-arrow-right"></i>
5
+ <%= I18n.t(:one, scope: "activerecord.models.spree/payment") %>
6
+ <i class="icon-arrow-right"></i>
7
+ <%= Spree.t(:log_entries) %>
8
+ <% end %>
9
+
10
+ <% content_for :page_actions do %>
11
+ <%= button_link_to Spree.t(:logs), spree.admin_order_payment_log_entries_url(@order, @payment), icon: 'file.svg' %>
12
+ <% end %>
13
+
14
+ <table class='table table-striped' id='listing_log_entries'>
15
+ <% @log_entries.each do |entry| %>
16
+ <thead>
17
+ <tr class="log_entry <%= entry.success_parsed_details? ? 'success' : 'fail' %>">
18
+ <td colspan='2'>
19
+ <i class='icon icon-<%= entry.success_parsed_details? ? 'ok-circle' : 'remove-sign' %>'></i> <%= pretty_time(entry.created_at) %>
20
+ </td>
21
+ </tr>
22
+ </thead>
23
+ <tbody>
24
+ <%= render "spree/admin/log_entries/#{@payment.payment_method.method_type.gsub(' ', '').underscore}", entry: entry %>
25
+ </tbody>
26
+ <% end %>
27
+ </table>
@@ -1,4 +1,4 @@
1
- <div id='paypal-warning' style="display:none">
1
+ <div id='paypal-warning'>
2
2
  <strong><%= Spree.t('no_payment_via_admin_backend', :scope => 'paypal') %></strong>
3
3
  </div>
4
4
  <script>
@@ -1,5 +1,5 @@
1
1
  <div id="paypal-button-container" class="paypal-button-container"></div>
2
- <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
2
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
3
3
  <script type="text/javascript" src="https://www.paypal.com/sdk/js?client-id=<%= payment_method.preferred_api_key %>&currency=<%= @order.currency %>"></script>
4
4
 
5
5
  <script type="text/javascript">
@@ -15,6 +15,7 @@ de:
15
15
  refund_unsuccessful: "PayPal Erstattung nicht erfolgreich"
16
16
  actions:
17
17
  refund: "Erstatten"
18
+ status: 'Toestand'
18
19
  flash:
19
20
  cancel: "Sie wollen PayPal doch nicht benutzen? Kein Problem."
20
21
  connection_failed: "Verbindung zu Paypal nicht erfolgreich."
@@ -15,6 +15,7 @@ en:
15
15
  refund_unsuccessful: "PayPal refund unsuccessful"
16
16
  actions:
17
17
  refund: "Refund"
18
+ status: Status
18
19
  flash:
19
20
  cancel: "Don't want to use PayPal? No problems."
20
21
  connection_failed: "Could not connect to PayPal."
@@ -15,6 +15,7 @@ es:
15
15
  refund_unsuccessful: "No se pudo rembolsar el pago de PayPal"
16
16
  actions:
17
17
  refund: "Reembolso"
18
+ status: Estado
18
19
  flash:
19
20
  cancel: "No quieres usar PayPal? No hay problema."
20
21
  connection_failed: "No se pudo conectar con PayPal."
@@ -15,6 +15,7 @@ it:
15
15
  refund_unsuccessful: "Rimborso PayPal non completato"
16
16
  actions:
17
17
  refund: "Rimborso"
18
+ status: Stato
18
19
  flash:
19
20
  cancel: "Non vuoi usare PayPal? Nessun problema."
20
21
  connection_failed: "Impossibile connettersi a PayPal."
@@ -15,6 +15,7 @@ pl:
15
15
  refund_unsuccessful: "Błąd podczas wykonywania zwrotu PayPal"
16
16
  actions:
17
17
  refund: "Zwróć Płatność"
18
+ status: Status
18
19
  flash:
19
20
  cancel: "Nie chcesz użyć PayPal? Nie ma problemu."
20
21
  connection_failed: "Nie można było połączyć się z usługą PayPal."
@@ -15,6 +15,7 @@ pt:
15
15
  refund_unsuccessful: "Não foi possível reembolsar o pagamento de PayPal"
16
16
  actions:
17
17
  refund: "Reembolso"
18
+ status: Status
18
19
  flash:
19
20
  cancel: "Não pretende usar PayPal? Não há problema."
20
21
  connection_failed: "Não foi possível estabelecer ligação com o PayPal."
@@ -1,3 +1,3 @@
1
1
  module SpreePaypalApiCheckout
2
- VERSION = '0.1.0'
2
+ VERSION = '0.1.3'
3
3
  end
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "spree_paypal_api_checkout".freeze
3
- s.version = "0.1.0"
3
+ s.version = "0.1.3"
4
4
 
5
5
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
6
6
  s.require_paths = ["lib".freeze]
@@ -8,7 +8,7 @@ Gem::Specification.new do |s|
8
8
  s.date = "2022-02-22"
9
9
  s.description = "Adds PayPal API Checkout as a Payment Method to Spree Commerce".freeze
10
10
  s.email = "gems@spreecommerce.com".freeze
11
- s.files = [".gitignore".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "app/assets/javascripts/spree/backend/spree_paypal_checkout.js".freeze, "app/assets/javascripts/spree/frontend/spree_paypal_checkout.js".freeze, "app/assets/stylesheets/spree/backend/spree_paypal_checkout.css".freeze, "app/assets/stylesheets/spree/frontend/spree_paypal_checkout.css".freeze, "app/controllers/spree/admin/payments_controller_decorator.rb".freeze, "app/controllers/spree/admin/paypal_checkout_payments_controller.rb".freeze, "app/controllers/spree/paypal_checkout_controller.rb".freeze, "app/models/spree/gateway/pay_pal_checkout.rb".freeze, "app/models/spree/paypal_api_checkout.rb".freeze, "app/views/spree/admin/payments/_paypal_checkout_complete.html.erb".freeze, "app/views/spree/admin/payments/paypal_checkout_refund.html.erb".freeze, "app/views/spree/admin/payments/source_forms/_paypal_checkout.html.erb".freeze, "app/views/spree/admin/payments/source_views/_paypal_checkout.html.erb".freeze, "app/views/spree/checkout/payment/_paypal_checkout.html.erb".freeze, "config/locales/de.yml".freeze, "config/locales/en.yml".freeze, "config/locales/es.yml".freeze, "config/locales/it.yml".freeze, "config/locales/pl.yml".freeze, "config/locales/pt.yml".freeze, "config/routes.rb".freeze, "db/migrate/20220620042734_create_spree_paypal_api_checkouts.rb".freeze, "lib/generators/spree_paypal_api_checkout/install/install_generator.rb".freeze, "lib/spree_paypal_api_checkout.rb".freeze, "lib/spree_paypal_api_checkout/engine.rb".freeze, "lib/spree_paypal_api_checkout/version.rb".freeze, "script/rails".freeze, "spree_paypal_api_checkout.gemspec".freeze]
11
+ s.files = [".gitignore".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "app/assets/javascripts/spree/backend/spree_paypal_checkout.js".freeze, "app/assets/javascripts/spree/frontend/spree_paypal_checkout.js".freeze, "app/assets/stylesheets/spree/backend/spree_paypal_checkout.css".freeze, "app/assets/stylesheets/spree/frontend/spree_paypal_checkout.css".freeze, "app/controllers/spree/admin/payments_controller_decorator.rb".freeze, "app/models/spree/log_entry_decorator.rb".freeze, "app/controllers/spree/admin/paypal_checkout_payments_controller.rb".freeze, "app/controllers/spree/paypal_checkout_controller.rb".freeze, "app/models/spree/gateway/pay_pal_checkout.rb".freeze, "app/models/spree/paypal_api_checkout.rb".freeze, "app/views/spree/admin/payments/_paypal_checkout_complete.html.erb".freeze, "app/views/spree/admin/payments/paypal_checkout_refund.html.erb".freeze, "app/views/spree/admin/payments/source_forms/_paypal_checkout.html.erb".freeze, "app/views/spree/admin/payments/source_views/_paypal_checkout.html.erb".freeze, "app/views/spree/checkout/payment/_paypal_checkout.html.erb".freeze, "app/views/spree/admin/log_entries/_paypal_checkout.html.erb".freeze, "app/views/spree/admin/log_entries/index.html.erb".freeze, "config/locales/de.yml".freeze, "config/locales/en.yml".freeze, "config/locales/es.yml".freeze, "config/locales/it.yml".freeze, "config/locales/pl.yml".freeze, "config/locales/pt.yml".freeze, "config/routes.rb".freeze, "db/migrate/20220620042734_create_spree_paypal_api_checkouts.rb".freeze, "lib/generators/spree_paypal_api_checkout/install/install_generator.rb".freeze, "lib/spree_paypal_api_checkout.rb".freeze, "lib/spree_paypal_api_checkout/engine.rb".freeze, "lib/spree_paypal_api_checkout/version.rb".freeze, "script/rails".freeze, "spree_paypal_api_checkout.gemspec".freeze]
12
12
  s.homepage = "http://www.spreecommerce.com".freeze
13
13
  s.required_ruby_version = Gem::Requirement.new(">= 2.2.2".freeze)
14
14
  s.requirements = ["none".freeze]
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_paypal_api_checkout
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Spree Commerce
@@ -362,7 +362,10 @@ files:
362
362
  - app/controllers/spree/admin/paypal_checkout_payments_controller.rb
363
363
  - app/controllers/spree/paypal_checkout_controller.rb
364
364
  - app/models/spree/gateway/pay_pal_checkout.rb
365
+ - app/models/spree/log_entry_decorator.rb
365
366
  - app/models/spree/paypal_api_checkout.rb
367
+ - app/views/spree/admin/log_entries/_paypal_checkout.html.erb
368
+ - app/views/spree/admin/log_entries/index.html.erb
366
369
  - app/views/spree/admin/payments/_paypal_checkout_complete.html.erb
367
370
  - app/views/spree/admin/payments/paypal_checkout_refund.html.erb
368
371
  - app/views/spree/admin/payments/source_forms/_paypal_checkout.html.erb