buckaruby 1.2.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,12 +8,13 @@ module Buckaruby
8
8
  "BUNQNL2A" => "bunq",
9
9
  "HANDNL2A" => "Handelsbanken",
10
10
  "INGBNL2A" => "ING",
11
- "KNABNL2H" => "Knab bank",
11
+ "KNABNL2H" => "Knab",
12
12
  "MOYONL21" => "Moneyou",
13
13
  "RABONL2U" => "Rabobank",
14
- "RBRBNL21" => "RegioBank",
14
+ "RBRBNL21" => "Regiobank",
15
+ "REVOLT21" => "Revolut",
15
16
  "SNSBNL2A" => "SNS Bank",
16
- "TRIONL2U" => "Triodos Bank",
17
+ "TRIONL2U" => "Triodos",
17
18
  "FVLBNL22" => "Van Lanschot"
18
19
  }.freeze
19
20
  end
@@ -4,6 +4,7 @@ module Buckaruby
4
4
  module Operation
5
5
  TRANSACTION_REQUEST = "TransactionRequest"
6
6
  TRANSACTION_STATUS = "TransactionStatus"
7
+ TRANSACTION_REQUEST_SPECIFICATION = "TransactionRequestSpecification"
7
8
  REFUND_INFO = "RefundInfo"
8
9
  CANCEL_TRANSACTION = "CancelTransaction"
9
10
  end
@@ -8,11 +8,13 @@ module Buckaruby
8
8
  SEPA_DIRECT_DEBIT = "sepadirectdebit"
9
9
  PAYPAL = "paypal"
10
10
  BANCONTACT_MISTER_CASH = "bancontactmrcash"
11
+ SOFORT = "sofortueberweisung"
11
12
  TRANSFER = "transfer"
12
13
 
13
14
  # Credit cards
14
15
  VISA = "visa"
15
16
  MASTER_CARD = "mastercard"
16
17
  MAESTRO = "maestro"
18
+ AMERICAN_EXPRESS = "amex"
17
19
  end
18
20
  end
@@ -159,6 +159,30 @@ module Buckaruby
159
159
  end
160
160
  end
161
161
 
162
+ # Request for a creating a transaction specification.
163
+ class TransactionSpecificationRequest < Request
164
+ def execute(options)
165
+ super(options.merge(operation: Operation::TRANSACTION_REQUEST_SPECIFICATION))
166
+ end
167
+
168
+ def build_request_params(options)
169
+ params = {}
170
+
171
+ if options[:payment_method]
172
+ if options[:payment_method].respond_to?(:join)
173
+ params[:brq_services] = options[:payment_method].join(",")
174
+ else
175
+ params[:brq_services] = options[:payment_method]
176
+ end
177
+ end
178
+
179
+ params[:brq_latestversiononly] = "true"
180
+ params[:brq_culture] = options[:culture] || Language::DUTCH
181
+
182
+ params
183
+ end
184
+ end
185
+
162
186
  # Request for a creating a recurrent transaction.
163
187
  class RecurrentTransactionRequest < TransactionRequest
164
188
  def build_transaction_request_params(options)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative 'support/case_insensitive_hash'
4
+
3
5
  require 'cgi'
4
6
  require 'date'
5
7
 
@@ -20,19 +22,7 @@ module Buckaruby
20
22
  end
21
23
 
22
24
  def status
23
- # See http://support.buckaroo.nl/index.php/Statuscodes
24
- case params[:brq_statuscode]
25
- when '190'
26
- TransactionStatus::SUCCESS
27
- when '490', '491', '492'
28
- TransactionStatus::FAILED
29
- when '690'
30
- TransactionStatus::REJECTED
31
- when '790', '791', '792', '793'
32
- TransactionStatus::PENDING
33
- when '890', '891'
34
- TransactionStatus::CANCELLED
35
- end
25
+ TransactionStatus.parse(params[:brq_statuscode])
36
26
  end
37
27
 
38
28
  def timestamp
@@ -83,7 +73,7 @@ module Buckaruby
83
73
  end
84
74
 
85
75
  def verify_signature!(response, config)
86
- if params[:brq_apiresult] != "Fail"
76
+ if params[:brq_apiresult].nil? || params[:brq_apiresult].casecmp("fail") != 0
87
77
  sent_signature = params[:brq_signature]
88
78
  generated_signature = Signature.generate_signature(response, config)
89
79
 
@@ -174,27 +164,7 @@ module Buckaruby
174
164
  end
175
165
 
176
166
  def transaction_type
177
- if params[:brq_transaction_type] && !params[:brq_transaction_type].empty?
178
- # See http://support.buckaroo.nl/index.php/Transactietypes
179
- case params[:brq_transaction_type]
180
- when 'C001', 'C002', 'C004', 'C021', 'C043', 'C044', 'C046', 'C089', 'C090', 'C192', 'C251', 'V001', 'V002', 'V010', 'V021', 'V032', 'V034', 'V043', 'V044', 'V046', 'V089', 'V090', 'V192', 'V245'
181
- # Check the recurring flag to detect a normal or recurring transaction.
182
- if params[:brq_recurring] && params[:brq_recurring].casecmp("true").zero?
183
- TransactionType::PAYMENT_RECURRENT
184
- else
185
- TransactionType::PAYMENT
186
- end
187
- when 'C005', 'V014', 'V031', 'V094'
188
- TransactionType::PAYMENT_RECURRENT
189
- when 'C079', 'C080', 'C082', 'C092', 'C101', 'C102', 'C121', 'C194', 'C197', 'C252', 'C500', 'V067', 'V068', 'V070', 'V079', 'V080', 'V082', 'V092', 'V101', 'V102', 'V110', 'V149', 'V194', 'V197', 'V246'
190
- TransactionType::REFUND
191
- when 'C501', 'C502', 'C546', 'C551', 'C553', 'C554', 'C562', 'C589', 'C593', 'V111', 'V131', 'V132', 'V134', 'V143', 'V144', 'V146', 'V543', 'V544', 'V545', 'V546', 'V589', 'V592'
192
- TransactionType::REVERSAL
193
- end
194
- else
195
- # Fallback when transaction type is not known (cancelling credit card)
196
- TransactionType::PAYMENT
197
- end
167
+ TransactionType.parse(params[:brq_transaction_type], params[:brq_recurring])
198
168
  end
199
169
 
200
170
  def transaction_status
@@ -299,4 +269,19 @@ module Buckaruby
299
269
  class CallbackResponse < Response
300
270
  include TransactionResponse
301
271
  end
272
+
273
+ # Response when retrieving the specification for a transaction.
274
+ class TransactionSpecificationResponse < ApiResponse
275
+ def services
276
+ @services ||= FieldMapper.map_fields(params, :brq_services)
277
+ end
278
+
279
+ def basic_fields
280
+ @basic_fields ||= FieldMapper.map_fields(params, :brq_basicfields)
281
+ end
282
+
283
+ def custom_parameters
284
+ @custom_parameters ||= FieldMapper.map_fields(params, :brq_customparameters)
285
+ end
286
+ end
302
287
  end
@@ -5,8 +5,10 @@ require 'digest'
5
5
  module Buckaruby
6
6
  # Calculate a signature based on the parameters of the payment request or response.
7
7
  # -> see BPE 3.0 Gateway NVP, chapter 4 'Digital Signature'
8
- class Signature
9
- def self.generate_signature(params, config)
8
+ module Signature
9
+ module_function
10
+
11
+ def generate_signature(params, config)
10
12
  case config.hash_method
11
13
  when :sha1
12
14
  Digest::SHA1.hexdigest(generate_signature_string(params, config.secret))
@@ -19,11 +21,27 @@ module Buckaruby
19
21
  end
20
22
  end
21
23
 
22
- def self.generate_signature_string(params, secret)
24
+ def generate_signature_string(params, secret)
23
25
  sign_params = params.select { |key, _value| key.to_s.upcase.start_with?("BRQ_", "ADD_", "CUST_") && key.to_s.casecmp("BRQ_SIGNATURE").nonzero? }
24
- string = sign_params.sort_by { |p| p.first.downcase }.map { |param| "#{param[0]}=#{param[1]}" }.join
26
+ sign_params = order_signature_params(sign_params)
27
+
28
+ string = sign_params.map { |param| "#{param[0]}=#{param[1]}" }.join
25
29
  string << secret
26
30
  string
27
31
  end
32
+
33
+ # Excerpt from the Buckaroo documentation, chapter 4 'Digital Signature':
34
+ # In the payment engine, the used lexical sort algorithm uses the following order:
35
+ # symbols first, then numbers, then case insensitive letters. Also, a shorter string
36
+ # that is identical to the beginning of a longer string, comes before the longer string.
37
+ # Take for example the following, comma separated, list which has been sorted:
38
+ # a_a, a0, a0a, a1a, aaA, aab, aba, aCa
39
+ CHAR_ORDER = "_01234567890abcdefghijklmnopqrstuvwxyz"
40
+
41
+ def order_signature_params(params)
42
+ params.sort_by do |key, _value|
43
+ key.to_s.downcase.each_char.map { |c| CHAR_ORDER.index(c) }
44
+ end
45
+ end
28
46
  end
29
47
  end
@@ -1,11 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Buckaruby
4
+ # Parses the transaction status code from Buckaroo.
4
5
  module TransactionStatus
5
6
  SUCCESS = 1
6
7
  FAILED = 2
7
8
  REJECTED = 3
8
9
  CANCELLED = 4
9
10
  PENDING = 5
11
+
12
+ module_function
13
+
14
+ # See https://support.buckaroo.nl/categorie%C3%ABn/transacties/status
15
+ def parse(brq_statuscode)
16
+ case brq_statuscode
17
+ when '190'
18
+ TransactionStatus::SUCCESS
19
+ when '490', '491', '492'
20
+ TransactionStatus::FAILED
21
+ when '690'
22
+ TransactionStatus::REJECTED
23
+ when '790', '791', '792', '793'
24
+ TransactionStatus::PENDING
25
+ when '890', '891'
26
+ TransactionStatus::CANCELLED
27
+ end
28
+ end
10
29
  end
11
30
  end
@@ -1,10 +1,89 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Buckaruby
4
+ # Parses the transaction type from Buckaroo.
4
5
  module TransactionType
5
6
  PAYMENT = 1
6
7
  PAYMENT_RECURRENT = 2
7
8
  REFUND = 3
8
9
  REVERSAL = 4
10
+
11
+ module_function
12
+
13
+ # See https://support.buckaroo.nl/categorie%C3%ABn/integratie/transactietypes-overzicht
14
+ def parse(brq_transaction_type, brq_recurring)
15
+ if brq_transaction_type && !brq_transaction_type.empty?
16
+ case brq_transaction_type
17
+ when 'C021', 'V021', # iDEAL
18
+ 'C002', 'C004', 'C005', # (SEPA) Direct Debit
19
+ 'V010', 'V014', # PayPal
20
+ 'C090', 'V090', # Bancontact
21
+ 'N074', 'C075', # Sofort
22
+ 'C001', # Transfer
23
+
24
+ 'C044', 'C192', 'C283', 'C293', 'C318', 'C345',
25
+ 'C880', 'C963', 'V002', 'V032', 'V038', 'V044',
26
+ 'V192', 'V283', 'V293', 'V313', 'V318', 'V345',
27
+ 'V696', # Visa
28
+
29
+ 'C043', 'C089', 'C273', 'C303', 'C328', 'C355',
30
+ 'C876', 'C969', 'V001', 'V031', 'V037', 'V043',
31
+ 'V089', 'V273', 'V303', 'V328', 'V355', 'V702', # MasterCard
32
+
33
+ 'C046', 'C251', 'C288', 'C308', 'C333', 'C872',
34
+ 'C972', 'V034', 'V040', 'V046', 'V094', 'V245',
35
+ 'V288', 'V308', 'V333', 'V705', # Maestro
36
+
37
+ 'V003', 'V030', 'V036', 'V042' # American Express
38
+
39
+ # Check the recurring flag to detect a normal or recurring transaction.
40
+ if brq_recurring && brq_recurring.casecmp("true").zero?
41
+ TransactionType::PAYMENT_RECURRENT
42
+ else
43
+ TransactionType::PAYMENT
44
+ end
45
+ when 'C121', # iDEAL
46
+ 'C102', 'C500', # (SEPA) Direct Debit
47
+ 'V110', # PayPal
48
+ 'C092', 'V092', # Bancontact
49
+ 'N540', 'C543', # Sofort
50
+ 'C101', # Transfer
51
+
52
+ 'C080', 'C194', 'C281', 'C290', 'C315', 'C342',
53
+ 'C881', 'C961', 'V068', 'V074', 'V080', 'V102',
54
+ 'V194', 'V281', 'V290', 'V315', 'V342', 'V694', # Visa
55
+
56
+ 'C079', 'C197', 'C300', 'C325', 'C352', 'C371',
57
+ 'C877', 'C967', 'V067', 'V073', 'V079', 'V101',
58
+ 'V149', 'V197', 'V300', 'V325', 'V352', 'V371',
59
+ 'V700', # MasterCard
60
+
61
+ 'C082', 'C252', 'C286', 'C305', 'C330', 'C873',
62
+ 'C970', 'V070', 'V076', 'V082', 'V246', 'V286',
63
+ 'V305', 'V330', 'V703', # Maestro
64
+
65
+ 'V066', 'V072', 'V078', 'V103' # American Express
66
+ TransactionType::REFUND
67
+ when 'C501', 'C502', 'C562', # (SEPA) Direct Debit
68
+ 'V111', # PayPal
69
+ 'C544', # Sofort
70
+
71
+ 'C554', 'C593', 'C882', 'V132', 'V138', 'V144',
72
+ 'V544', 'V592', # Visa
73
+
74
+ 'C553', 'C589', 'C878', 'V131', 'V137', 'V143',
75
+ 'V543', 'V589', # MasterCard
76
+
77
+ 'C546', 'C551', 'C874', 'V134', 'V140', 'V146',
78
+ 'V545', 'V546', # Maestro
79
+
80
+ 'V130', 'V136', 'V142' # American Express
81
+ TransactionType::REVERSAL
82
+ end
83
+ else
84
+ # Fallback when transaction type is not known (e.g. cancelling credit card)
85
+ TransactionType::PAYMENT
86
+ end
87
+ end
9
88
  end
10
89
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Buckaruby
4
- VERSION = "1.2.0"
4
+ VERSION = "1.6.0"
5
5
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Buckaruby::FieldMapper do
6
+ describe '.map_fields' do
7
+ let(:fields) do
8
+ {
9
+ brq_services_1_description: "iDEAL",
10
+ brq_services_1_name: "ideal",
11
+ brq_services_1_version: "2",
12
+ brq_services_1_supportedcurrencies_1_code: "EUR",
13
+ brq_services_1_supportedcurrencies_1_isonumber: "978",
14
+ brq_services_1_supportedcurrencies_1_name: "Euro",
15
+ brq_services_2_description: "Visa",
16
+ brq_services_2_name: "visa",
17
+ brq_services_2_version: "1",
18
+ brq_services_2_supportedcurrencies_1_code: "GBP",
19
+ brq_services_2_supportedcurrencies_1_isonumber: "826",
20
+ brq_services_2_supportedcurrencies_1_name: "Pond",
21
+ brq_services_2_supportedcurrencies_2_code: "USD",
22
+ brq_services_2_supportedcurrencies_2_isonumber: "840",
23
+ brq_services_2_supportedcurrencies_2_name: "US Dollar"
24
+ }
25
+ end
26
+
27
+ it 'maps NVP fields to arrays and hashes' do
28
+ services = Buckaruby::FieldMapper.map_fields(fields, :brq_services)
29
+ expect(services).to be_an_instance_of(Array)
30
+ expect(services.count).to eq(2)
31
+
32
+ ideal = services.first
33
+ expect(ideal).to be_an_instance_of(Buckaruby::Support::CaseInsensitiveHash)
34
+ expect(ideal[:description]).to eq("iDEAL")
35
+ expect(ideal[:name]).to eq("ideal")
36
+ expect(ideal[:version]).to eq("2")
37
+
38
+ visa = services.last
39
+ expect(visa).to be_an_instance_of(Buckaruby::Support::CaseInsensitiveHash)
40
+ expect(visa[:description]).to eq("Visa")
41
+ expect(visa[:name]).to eq("visa")
42
+ expect(visa[:version]).to eq("1")
43
+ end
44
+
45
+ it 'maps NVP subfields to arrays and hashes' do
46
+ services = Buckaruby::FieldMapper.map_fields(fields, :brq_services)
47
+
48
+ currencies = services.first[:supportedcurrencies]
49
+ expect(currencies).to be_an_instance_of(Array)
50
+ expect(currencies.count).to eq(1)
51
+
52
+ currency = currencies.first
53
+ expect(currency).to be_an_instance_of(Buckaruby::Support::CaseInsensitiveHash)
54
+ expect(currency[:code]).to eq("EUR")
55
+ expect(currency[:isonumber]).to eq("978")
56
+ expect(currency[:name]).to eq("Euro")
57
+
58
+ currencies = services.last[:supportedcurrencies]
59
+ expect(currencies).to be_an_instance_of(Array)
60
+ expect(currencies.count).to eq(2)
61
+
62
+ currency = currencies.first
63
+ expect(currency).to be_an_instance_of(Buckaruby::Support::CaseInsensitiveHash)
64
+ expect(currency[:code]).to eq("GBP")
65
+ expect(currency[:isonumber]).to eq("826")
66
+ expect(currency[:name]).to eq("Pond")
67
+ end
68
+ end
69
+ end
@@ -29,6 +29,17 @@ RSpec.describe Buckaruby::Gateway do
29
29
 
30
30
  it { expect(subject).to be_an_instance_of(Buckaruby::Gateway) }
31
31
 
32
+ describe '#payment_methods' do
33
+ before do
34
+ stub_request(:post, "https://testcheckout.buckaroo.nl/nvp/?op=TransactionRequestSpecification").to_return(body: File.read("spec/fixtures/responses/specify_transaction_success.txt"))
35
+ end
36
+
37
+ it 'returns the payment methods enabled by Buckaroo and supported by this library' do
38
+ payment_methods = subject.payment_methods
39
+ expect(payment_methods).to eq([Buckaruby::PaymentMethod::IDEAL, Buckaruby::PaymentMethod::VISA])
40
+ end
41
+ end
42
+
32
43
  describe '#issuers' do
33
44
  context 'when no or false parameters are passed' do
34
45
  it 'raises an ArgumentError' do
@@ -207,6 +218,16 @@ RSpec.describe Buckaruby::Gateway do
207
218
  expect(response.to_h).to be_an_instance_of(Hash)
208
219
  end
209
220
 
221
+ it 'initiates a transaction for payment method sofort' do
222
+ response = subject.setup_transaction(amount: 10, payment_method: Buckaruby::PaymentMethod::SOFORT, invoicenumber: "12345", return_url: "http://www.return.url/")
223
+ expect(response).to be_an_instance_of(Buckaruby::SetupTransactionResponse)
224
+ expect(response.transaction_id).to eq("41C48B55FA9164E123CC73B1157459E840BE5D24")
225
+ expect(response.transaction_status).to eq(Buckaruby::TransactionStatus::PENDING)
226
+ expect(response.redirect_url).not_to be nil
227
+ expect(response.timestamp).to be_an_instance_of(Time)
228
+ expect(response.to_h).to be_an_instance_of(Hash)
229
+ end
230
+
210
231
  context 'with custom variables' do
211
232
  it 'sends the custom variables with the request' do
212
233
  response = subject.setup_transaction(amount: 10, payment_method: Buckaruby::PaymentMethod::IDEAL, payment_issuer: "ABNANL2A", invoicenumber: "12345", return_url: "http://www.return.url/", custom: { foo: :bar, quux: "42" })
@@ -215,7 +236,7 @@ RSpec.describe Buckaruby::Gateway do
215
236
  expect(response.custom[:quux]).to eq("42")
216
237
 
217
238
  expect(WebMock).to have_requested(:post, "https://testcheckout.buckaroo.nl/nvp/?op=TransactionRequest")
218
- .with(body: "brq_websitekey=12345678&brq_payment_method=ideal&brq_culture=nl-NL&brq_currency=EUR&brq_amount=10.0&brq_invoicenumber=12345&brq_service_ideal_action=Pay&brq_service_ideal_issuer=ABNANL2A&brq_service_ideal_version=2&brq_return=http%3A%2F%2Fwww.return.url%2F&cust_foo=bar&cust_quux=42&add_buckaruby=Buckaruby+#{Buckaruby::VERSION}&brq_signature=0fb3ff3c1f140b5aede33a0fdacbc5675830120d")
239
+ .with(body: "brq_websitekey=12345678&brq_payment_method=ideal&brq_culture=nl-NL&brq_currency=EUR&brq_amount=10.0&brq_invoicenumber=12345&brq_service_ideal_action=Pay&brq_service_ideal_issuer=ABNANL2A&brq_service_ideal_version=2&brq_return=http%3A%2F%2Fwww.return.url%2F&cust_foo=bar&cust_quux=42&add_buckaruby=Buckaruby+#{Buckaruby::VERSION}&brq_signature=f2c060e624faf02aabf8958d2a1898e2cbcfeac7")
219
240
  end
220
241
  end
221
242
 
@@ -227,7 +248,7 @@ RSpec.describe Buckaruby::Gateway do
227
248
  expect(response.additional[:myreference]).to eq("12345")
228
249
 
229
250
  expect(WebMock).to have_requested(:post, "https://testcheckout.buckaroo.nl/nvp/?op=TransactionRequest")
230
- .with(body: "brq_websitekey=12345678&brq_payment_method=ideal&brq_culture=nl-NL&brq_currency=EUR&brq_amount=10.0&brq_invoicenumber=12345&brq_service_ideal_action=Pay&brq_service_ideal_issuer=ABNANL2A&brq_service_ideal_version=2&brq_return=http%3A%2F%2Fwww.return.url%2F&add_myreference=12345&add_buckaruby=Buckaruby+#{Buckaruby::VERSION}&brq_signature=f7996840436bdd55dada28b80c62ed88af10cd23")
251
+ .with(body: "brq_websitekey=12345678&brq_payment_method=ideal&brq_culture=nl-NL&brq_currency=EUR&brq_amount=10.0&brq_invoicenumber=12345&brq_service_ideal_action=Pay&brq_service_ideal_issuer=ABNANL2A&brq_service_ideal_version=2&brq_return=http%3A%2F%2Fwww.return.url%2F&add_myreference=12345&add_buckaruby=Buckaruby+#{Buckaruby::VERSION}&brq_signature=d9f8aebb207f8694ce819b6a84b557839cdbc69f")
231
252
  end
232
253
  end
233
254
  end
@@ -402,6 +423,36 @@ RSpec.describe Buckaruby::Gateway do
402
423
  end
403
424
  end
404
425
 
426
+ describe '#specify_transaction' do
427
+ before do
428
+ stub_request(:post, "https://testcheckout.buckaroo.nl/nvp/?op=TransactionRequestSpecification").to_return(body: File.read("spec/fixtures/responses/specify_transaction_success.txt"))
429
+ end
430
+
431
+ it 'retrieves the specification for setting up a transaction' do
432
+ response = subject.specify_transaction
433
+ expect(response).to be_an_instance_of(Buckaruby::TransactionSpecificationResponse)
434
+
435
+ services = response.services
436
+ expect(services).to be_an_instance_of(Array)
437
+ expect(services.length).to eq(2)
438
+
439
+ service = services.last
440
+ expect(service).to be_an_instance_of(Buckaruby::Support::CaseInsensitiveHash)
441
+ expect(service[:name]).to eq(Buckaruby::PaymentMethod::VISA)
442
+ expect(service[:description]).to eq("Visa")
443
+ expect(service[:version]).to eq("1")
444
+
445
+ currencies = service[:supportedcurrencies]
446
+ expect(currencies).to be_an_instance_of(Array)
447
+ expect(currencies.length).to eq(21)
448
+
449
+ currency = currencies.last
450
+ expect(currency).to be_an_instance_of(Buckaruby::Support::CaseInsensitiveHash)
451
+ expect(currency[:name]).to eq("US Dollar")
452
+ expect(currency[:code]).to eq(Buckaruby::Currency::US_DOLLAR)
453
+ end
454
+ end
455
+
405
456
  describe '#callback' do
406
457
  it 'raises an exception when parameters are missing' do
407
458
  expect {
@@ -573,6 +624,48 @@ RSpec.describe Buckaruby::Gateway do
573
624
  expect(response.timestamp).to be_an_instance_of(Time)
574
625
  expect(response.to_h).to be_an_instance_of(Hash)
575
626
  end
627
+
628
+ it 'sets the transaction type to payment and payment method to VISA for visa callback' do
629
+ params = File.read("spec/fixtures/responses/callback_payment_visa.txt")
630
+
631
+ response = subject.callback(params)
632
+ expect(response.transaction_status).to eq(Buckaruby::TransactionStatus::SUCCESS)
633
+ expect(response.transaction_type).to eq(Buckaruby::TransactionType::PAYMENT)
634
+ expect(response.payment_method).to eq(Buckaruby::PaymentMethod::VISA)
635
+ expect(response.transaction_id).to eq("41C48B55FA9164E123CC73B1157459E840BE5D24")
636
+ expect(response.payment_id).to eq("E86256B2787EE7FF0C33D0D4C6159CD922227B79")
637
+ expect(response.invoicenumber).to eq("12345")
638
+ expect(response.timestamp).to be_an_instance_of(Time)
639
+ expect(response.to_h).to be_an_instance_of(Hash)
640
+ end
641
+
642
+ it 'sets the transaction type to payment and payment method to American Express for amex callback' do
643
+ params = File.read("spec/fixtures/responses/callback_payment_amex.txt")
644
+
645
+ response = subject.callback(params)
646
+ expect(response.transaction_status).to eq(Buckaruby::TransactionStatus::SUCCESS)
647
+ expect(response.transaction_type).to eq(Buckaruby::TransactionType::PAYMENT)
648
+ expect(response.payment_method).to eq(Buckaruby::PaymentMethod::AMERICAN_EXPRESS)
649
+ expect(response.transaction_id).to eq("41C48B55FA9164E123CC73B1157459E840BE5D24")
650
+ expect(response.payment_id).to eq("E86256B2787EE7FF0C33D0D4C6159CD922227B79")
651
+ expect(response.invoicenumber).to eq("12345")
652
+ expect(response.timestamp).to be_an_instance_of(Time)
653
+ expect(response.to_h).to be_an_instance_of(Hash)
654
+ end
655
+
656
+ it 'sets the transaction type to payment and payment method to Sofrt for sort callback' do
657
+ params = File.read("spec/fixtures/responses/callback_payment_sofort.txt")
658
+
659
+ response = subject.callback(params)
660
+ expect(response.transaction_status).to eq(Buckaruby::TransactionStatus::PENDING)
661
+ expect(response.transaction_type).to eq(Buckaruby::TransactionType::PAYMENT)
662
+ expect(response.payment_method).to eq(Buckaruby::PaymentMethod::SOFORT)
663
+ expect(response.transaction_id).to eq("41C48B55FA9164E123CC73B1157459E840BE5D24")
664
+ expect(response.payment_id).to eq("E86256B2787EE7FF0C33D0D4C6159CD922227B79")
665
+ expect(response.invoicenumber).to eq("12345")
666
+ expect(response.timestamp).to be_an_instance_of(Time)
667
+ expect(response.to_h).to be_an_instance_of(Hash)
668
+ end
576
669
  end
577
670
 
578
671
  context 'when callback is a payment recurrent response' do
@@ -635,6 +728,21 @@ RSpec.describe Buckaruby::Gateway do
635
728
  expect(response.timestamp).to be_an_instance_of(Time)
636
729
  expect(response.to_h).to be_an_instance_of(Hash)
637
730
  end
731
+
732
+ it 'recognizes an amex refund response' do
733
+ params = File.read("spec/fixtures/responses/callback_refund_amex.txt")
734
+
735
+ response = subject.callback(params)
736
+ expect(response.transaction_status).to eq(Buckaruby::TransactionStatus::SUCCESS)
737
+ expect(response.transaction_type).to eq(Buckaruby::TransactionType::REFUND)
738
+ expect(response.payment_method).to eq(Buckaruby::PaymentMethod::AMERICAN_EXPRESS)
739
+ expect(response.transaction_id).to eq("B51118F58785274E117EFE1BF99D4D50CCB96949")
740
+ expect(response.payment_id).to be nil
741
+ expect(response.invoicenumber).to eq("12345")
742
+ expect(response.refund_transaction_id).to eq("41C48B55FA9164E123CC73B1157459E840BE5D24")
743
+ expect(response.timestamp).to be_an_instance_of(Time)
744
+ expect(response.to_h).to be_an_instance_of(Hash)
745
+ end
638
746
  end
639
747
 
640
748
  context 'when callback is a reversal response' do