spree_komoju 0.1.1 → 0.1.2

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
  SHA1:
3
- metadata.gz: 21abae67fb8b374366ad61cf72c45969898be777
4
- data.tar.gz: 1923dec1e5eab2a456da1eba0b3ac96bdbb174ad
3
+ metadata.gz: f7784a1ce8862a8139658dc03f4f3eba3e788870
4
+ data.tar.gz: 07274b9b8e58ff08405341faf8dad83b697caa95
5
5
  SHA512:
6
- metadata.gz: 309fecf25f6cbc7231af46ed1de8db34bcbdfc9744e998a01595d407ba40f6772f8d74c33a4324c220406f98aaca077eb9dc3dfeab78db27f1c6bc7bf027015e
7
- data.tar.gz: 1757199d33f762c0cff7709edf50015c5af939789028a06401dc68c2c8f1cdbbd5a6bf60e49dfc1dcc936c30d5f963d358838d305ad5c09767d73bf38dc5f5ad
6
+ metadata.gz: e8e12916f9d44f2d40eab8e8629d48db94d37f14de5157816968605685c4a1c96f214c6a58afeb039407bd89f786b88e0d485acb18beddd3fd9ffda1df981f70
7
+ data.tar.gz: 54eb2fc4776fa52c987b507f89d0fd419a9973f922d66c21bce88bc6abcf8f2334b69d23b66ea842bddbe294b1c83fc6435f4c242556681187c2f91488ad04c5
@@ -7,9 +7,9 @@ module Spree
7
7
 
8
8
  case params[:type]
9
9
  when "payment.captured"
10
- order_number = extract_payment_number(params[:data][:external_order_num])
11
- payment = Spree::Payment.find_by_number!(order_number)
12
- payment.complete! unless payment.completed?
10
+ SpreeKomoju::Callbacks::Captured.new(params).process!
11
+ when "payment.refunded"
12
+ SpreeKomoju::Callbacks::Refunded.new(params).process!
13
13
  end
14
14
 
15
15
  head 200
@@ -17,10 +17,6 @@ module Spree
17
17
 
18
18
  private
19
19
 
20
- def extract_payment_number(external_order_num)
21
- external_order_num.split('-').try(:last)
22
- end
23
-
24
20
  def callback_verified?
25
21
  request_body = request.body.read
26
22
  signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), SpreeKomoju.komoju_webhook_secret_token.to_s, request_body)
@@ -0,0 +1,3 @@
1
+ Spree::Payment::GatewayOptions.class_eval do
2
+ prepend SpreeKomoju::GatewayOptionsWithHeaders
3
+ end
@@ -2,6 +2,10 @@ require 'spree_core'
2
2
  require 'spree_komoju/engine'
3
3
  require 'spree_komoju/errors'
4
4
  require 'spree_komoju/controller_helpers'
5
+ require 'spree_komoju/gateway_options_with_headers'
6
+ require 'spree_komoju/callbacks/callback'
7
+ require 'spree_komoju/callbacks/captured'
8
+ require 'spree_komoju/callbacks/refunded'
5
9
 
6
10
  # This extension adds HTTP PATCH to ssl_request.
7
11
  # This is needed for WebMoney multi-card in Komoju.
@@ -0,0 +1,29 @@
1
+ module SpreeKomoju
2
+ module Callbacks
3
+ class Callback
4
+ attr_reader :params
5
+
6
+ def initialize(callback_params)
7
+ @params = callback_params
8
+ end
9
+
10
+ protected
11
+
12
+ def order_number
13
+ params[:data][:external_order_num].split("-").try(:first)
14
+ end
15
+
16
+ def payment_number
17
+ params[:data][:external_order_num].split("-").try(:last)
18
+ end
19
+
20
+ def order
21
+ @order ||= Spree::Order.find_by_number!(order_number)
22
+ end
23
+
24
+ def payment
25
+ @payment ||= order.payments.find_by_number!(payment_number)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,9 @@
1
+ module SpreeKomoju
2
+ module Callbacks
3
+ class Captured < Callback
4
+ def process!
5
+ payment.complete! unless payment.completed?
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ module SpreeKomoju
2
+ module Callbacks
3
+ class Refunded < Callback
4
+ def process!
5
+ return unless payment.completed?
6
+
7
+ refunds.each do |refund_params|
8
+ process_refund!(refund_params)
9
+ end
10
+
11
+ order.updater.update
12
+ end
13
+
14
+ private
15
+
16
+ def process_refund!(refund_params)
17
+ raise SpreeKomoju::Errors::IncorrectCurrency.new unless refund_params[:currency] == payment.currency
18
+
19
+ refund_amount = ::Money.new(refund_params[:amount], refund_params[:currency]).to_f
20
+ return if refund_amount > payment.credit_allowed
21
+
22
+ refund_description = refund_params[:description].blank? ? "Komoju refund" : refund_params[:description]
23
+ reason = Spree::RefundReason.find_or_create_by!(name: refund_description)
24
+ payment.refunds.create!(amount: refund_amount, reason: reason, transaction_id: refund_params[:id])
25
+ end
26
+
27
+ def refunds
28
+ params[:data][:refunds]
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,11 @@
1
1
  module SpreeKomoju
2
2
  module ControllerHelpers
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ before_action :add_request_env_to_payments, only: :update
7
+ end
8
+
3
9
  def permitted_source_attributes
4
10
  super.push(permitted_komoju_konbini_attributes)
5
11
  super.push(permitted_komoju_banktransfer_attributes)
@@ -25,5 +31,9 @@ module SpreeKomoju
25
31
  def permitted_komoju_web_money_attributes
26
32
  [:email, :prepaid_number]
27
33
  end
34
+
35
+ def add_request_env_to_payments
36
+ @order.payments.each {|payment| payment.request_env = request.headers.env }
37
+ end
28
38
  end
29
39
  end
@@ -1,5 +1,6 @@
1
1
  module SpreeKomoju
2
2
  module Errors
3
3
  class UnsupportedCurrency < StandardError; end
4
+ class IncorrectCurrency < StandardError; end
4
5
  end
5
6
  end
@@ -0,0 +1,16 @@
1
+ module SpreeKomoju
2
+ module GatewayOptionsWithHeaders
3
+ def browser_language
4
+ @payment.request_env.nil? ? "" : @payment.request_env["HTTP_ACCEPT_LANGUAGE"]
5
+ end
6
+
7
+ def browser_user_agent
8
+ @payment.request_env.nil? ? "" : @payment.request_env["HTTP_USER_AGENT"]
9
+ end
10
+
11
+ # Prepended method
12
+ def hash_methods
13
+ super + [:browser_language, :browser_user_agent]
14
+ end
15
+ end
16
+ end
@@ -18,6 +18,101 @@ describe Spree::KomojuController, type: :controller do
18
18
  end
19
19
  end
20
20
 
21
+ context 'when type is payment.refunded' do
22
+ let(:payment) { order.payments.first! }
23
+ let(:refund_currency) { "USD" }
24
+
25
+ let(:refund_params) do
26
+ {
27
+ "type" => "payment.refunded",
28
+ "data" => {
29
+ "external_order_num" => "#{order.number}-#{payment.number}",
30
+ "refunds" => [{
31
+ "id" => "REFUND_ID",
32
+ "description" => "My description",
33
+ "amount" => 100*payment.amount, # cents
34
+ "currency" => refund_currency
35
+ }]
36
+ }
37
+ }
38
+ end
39
+
40
+ context 'when payment has not been completed yet' do
41
+ let(:order) { create :completed_order_with_pending_payment }
42
+
43
+ it 'does nothing' do
44
+ expect { post :callback, refund_params }.not_to change {payment.refunds.count}
45
+ end
46
+ end
47
+
48
+ context 'when payment has already been completed' do
49
+ let(:order) { create :order_ready_to_ship }
50
+
51
+ context 'incorrect currency' do
52
+ let(:refund_currency) { "CAD" }
53
+ it 'raises SpreeKomoju::Errors::IncorrectCurrency error' do
54
+ expect { post :callback, refund_params }.to raise_error(SpreeKomoju::Errors::IncorrectCurrency)
55
+ end
56
+ end
57
+
58
+ context 'single refund' do
59
+ it 'adds refund and updates order' do
60
+ expect(order.shipment_state).to eq "ready"
61
+ expect(order.payment_state).to eq "paid"
62
+
63
+ expect { post :callback, refund_params }.to change { payment.refunds.count }.from(0).to(1)
64
+ expect(response.status).to eq 200
65
+
66
+ order.reload
67
+ expect(order.shipment_state).to eq "pending"
68
+ expect(order.payment_state).to eq "balance_due"
69
+
70
+ refund = payment.refunds.first
71
+ expect(refund.amount).to eq payment.amount
72
+ expect(refund.reason.name).to eq "My description"
73
+ expect(payment.credit_allowed).to eq 0
74
+
75
+ # Does nothing anymore
76
+ expect { post :callback, refund_params }.not_to change { payment.refunds.count }
77
+ end
78
+ end
79
+
80
+ context 'multiple individual refunds' do
81
+ let(:refund_params) do
82
+ {
83
+ "type" => "payment.refunded",
84
+ "data" => {
85
+ "external_order_num" => "#{order.number}-#{payment.number}",
86
+ "refunds" => [
87
+ {
88
+ "id" => "REFUND_ID1",
89
+ "amount" => 50*payment.amount,
90
+ "currency" => "USD"
91
+ },
92
+ {
93
+ "id" => "REFUND_ID2",
94
+ "amount" => 50*payment.amount,
95
+ "currency" => "USD"
96
+ }
97
+ ]
98
+ }
99
+ }
100
+ end
101
+
102
+ it 'adds refund and updates order' do
103
+ expect(order.shipment_state).to eq "ready"
104
+ expect(order.payment_state).to eq "paid"
105
+
106
+ expect { post :callback, refund_params }.to change { payment.refunds.count }.from(0).to(2)
107
+
108
+ order.reload
109
+ expect(order.shipment_state).to eq "pending"
110
+ expect(order.payment_state).to eq "balance_due"
111
+ end
112
+ end
113
+ end
114
+ end
115
+
21
116
  context 'when type is payment.captured' do
22
117
  let(:payment) { double Spree::Payment, complete!: true, completed?: completed }
23
118
  let(:capture_params) do
@@ -34,24 +129,24 @@ describe Spree::KomojuController, type: :controller do
34
129
  let(:completed) { true }
35
130
 
36
131
  it 'does nothing' do
37
- allow(Spree::Payment).to receive(:find_by_number!) { payment }
132
+ allow_any_instance_of(SpreeKomoju::Callbacks::Captured).to receive(:payment) { payment }
38
133
 
39
134
  post :callback, capture_params
40
135
 
41
136
  expect(payment).to_not have_received(:complete!)
42
- end
137
+ end
43
138
  end
44
139
 
45
140
  context 'when payment has not been completed yet' do
46
141
  let(:completed) { false }
47
142
 
48
143
  it 'marks a payment as complete' do
49
- allow(Spree::Payment).to receive(:find_by_number!) { payment }
144
+ allow_any_instance_of(SpreeKomoju::Callbacks::Captured).to receive(:payment) { payment }
50
145
 
51
146
  post :callback, capture_params
52
147
 
53
148
  expect(payment).to have_received(:complete!)
54
- end
149
+ end
55
150
  end
56
151
  end
57
152
 
@@ -60,23 +155,23 @@ describe Spree::KomojuController, type: :controller do
60
155
  expect {
61
156
  post :callback, capture_params
62
157
  }.to raise_error(ActiveRecord::RecordNotFound)
63
- end
158
+ end
64
159
  end
65
160
  end
66
161
 
67
162
  context 'when type is not recognized' do
68
163
  it 'returns an 200 status code' do
69
- post :callback, {type: "bad_type"}
164
+ post :callback, {type: "bad_type"}
70
165
  expect(response.status).to eq(200)
71
- end
166
+ end
72
167
  end
73
- end
168
+ end
74
169
 
75
170
  context 'when callback is unverified' do
76
171
  it 'returns head unauthorized' do
77
172
  post :callback
78
173
  expect(response.status).to eq(401)
79
- end
174
+ end
80
175
  end
81
176
  end
82
177
  end
@@ -2,7 +2,7 @@
2
2
  Gem::Specification.new do |s|
3
3
  s.platform = Gem::Platform::RUBY
4
4
  s.name = 'spree_komoju'
5
- s.version = '0.1.1'
5
+ s.version = '0.1.2'
6
6
  s.summary = 'Spree Komoju Payment Gateway'
7
7
  s.description = 'Spree Payment gateway for Komoju payment gateway'
8
8
  s.authors = ['Masahiro Saito', 'Chris Salzberg', 'Richard Ramsden']
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: spree_komoju
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masahiro Saito
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-04-18 00:00:00.000000000 Z
13
+ date: 2016-12-22 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: spree_core
@@ -195,6 +195,7 @@ files:
195
195
  - app/models/spree/komoju_gateway.rb
196
196
  - app/models/spree/konbini.rb
197
197
  - app/models/spree/pay_easy.rb
198
+ - app/models/spree/payment/gateway_options_decorator.rb
198
199
  - app/models/spree/web_money.rb
199
200
  - app/models/spree/web_money_decorator.rb
200
201
  - app/overrides/add_instruction_to_order_show.rb
@@ -238,10 +239,14 @@ files:
238
239
  - lib/generators/spree_komoju/install/images/webmoney.png
239
240
  - lib/generators/spree_komoju/install/install_generator.rb
240
241
  - lib/spree_komoju.rb
242
+ - lib/spree_komoju/callbacks/callback.rb
243
+ - lib/spree_komoju/callbacks/captured.rb
244
+ - lib/spree_komoju/callbacks/refunded.rb
241
245
  - lib/spree_komoju/controller_helpers.rb
242
246
  - lib/spree_komoju/engine.rb
243
247
  - lib/spree_komoju/errors.rb
244
248
  - lib/spree_komoju/factories.rb
249
+ - lib/spree_komoju/gateway_options_with_headers.rb
245
250
  - spec/controllers/spree/checkout_controller_spec.rb
246
251
  - spec/controllers/spree/komoju_controller_spec.rb
247
252
  - spec/models/spree/bank_transfer_spec.rb