buckaroo_client 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,8 @@
1
+ require 'buckaroo_client/service/credit_management'
2
+ require 'buckaroo_client/service/invoice_specification'
3
+ require 'buckaroo_client/service/pay_per_email'
4
+
5
+ module BuckarooClient
6
+ module Service
7
+ end
8
+ end
@@ -0,0 +1,71 @@
1
+ module BuckarooClient
2
+ module Service
3
+ class CreditManagement
4
+
5
+ # Source: Credit Management BPE 3.0 documentation v1.03
6
+ # Some values need 'service_creditmanagement_' prefix, some don't.
7
+ # This is based on trail-and-error and example request as given in
8
+ # document "Bestand aanbieden in BPE 3.0" v2.14 on page 16.
9
+ ATTRIBUTE_MAPPING = {
10
+ invoice_date: 'InvoiceDate',
11
+ date_due: 'DateDue',
12
+ amount_vat: 'AmountVat',
13
+ max_reminder_level: 'service_creditmanagement_MaxReminderLevel',
14
+ payment_methods_allowed: 'service_creditmanagement_PaymentMethodsAllowed',
15
+ customer_type: 'CustomerType',
16
+ customer_code: 'CustomerCode',
17
+ customer_title: 'CustomerTitle',
18
+ customer_initials: 'CustomerInitials',
19
+ customer_first_name: 'CustomerFirstName',
20
+ customer_last_name_prefix: 'CustomerLastNamePrefix',
21
+ customer_last_name: 'CustomerLastName',
22
+ customer_gender: 'CustomerGender',
23
+ customer_birth_date: 'service_creditmanagement_CustomerBirthDate',
24
+ customer_email: 'CustomerEmail',
25
+ phone_number: 'PhoneNumber',
26
+ mobile_phone_number: 'MobilePhoneNumber',
27
+ fax_number: 'FaxNumber',
28
+ street: 'Address_Street_1',
29
+ house_number: 'Address_HouseNumber_1',
30
+ house_number_suffix: 'Address_HouseNumberSuffix_1',
31
+ zip_code: 'Address_ZipCode_1',
32
+ city: 'Address_City_1',
33
+ state: 'Address_State_1',
34
+ country: 'Address_Country_1',
35
+ customer_account_number: 'service_creditmanagement_CustomerAccountNumber',
36
+ company_name: 'service_creditmanagement_CompanyName',
37
+ company_coc_registration: 'service_creditmanagement_CompanyCOCRegistration',
38
+ company_vat_applicable: 'service_creditmanagement_CompanyVATApplicable',
39
+ }
40
+
41
+ attr_accessor *ATTRIBUTE_MAPPING.keys
42
+
43
+ def initialize(args = {})
44
+ args.each do |key, value|
45
+ self.send "#{key}=", value
46
+ end
47
+ end
48
+
49
+ def servicecode
50
+ 'creditmanagement'
51
+ end
52
+
53
+ def action
54
+ 'invoice'
55
+ end
56
+
57
+ def gateway_attributes
58
+ output = { 'service_creditmanagement_action' => action }
59
+ ATTRIBUTE_MAPPING.each do |name, gateway_name|
60
+ value = self.send(name)
61
+ next if value.nil? # Ignore unspecified values to keep BuckarooClient happy
62
+ if value == true or value == false
63
+ value = value.to_s.upcase
64
+ end
65
+ output[gateway_name] = value.to_s
66
+ end
67
+ output
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,92 @@
1
+ require 'forwardable'
2
+
3
+ module BuckarooClient
4
+ module Service
5
+ class InvoiceSpecification
6
+
7
+ def servicecode
8
+ 'InvoiceSpecification'
9
+ end
10
+
11
+ def action
12
+ 'ExtraInfo'
13
+ end
14
+
15
+ def add_invoice_line(data)
16
+ invoice_lines.add_line('InvoiceLine', data)
17
+ end
18
+
19
+ def add_sub_total_line(data)
20
+ invoice_lines.add_line('SubTotalLine', data)
21
+ end
22
+
23
+ def add_total_line(data)
24
+ invoice_lines.add_line('TotalLine', data)
25
+ end
26
+
27
+ def invoice_lines
28
+ @invoice_lines ||= InvoiceLines.new
29
+ end
30
+
31
+ def gateway_attributes
32
+ output = {
33
+ 'service_InvoiceSpecification_action' => action,
34
+ }
35
+ output.merge(invoice_lines.gateway_attributes)
36
+ end
37
+
38
+ class InvoiceLines
39
+ extend Forwardable
40
+ def_delegators :@lines, :size, :each
41
+
42
+ attr_accessor :lines
43
+
44
+ def initialize
45
+ @lines = []
46
+ end
47
+
48
+ def add_line(type, data)
49
+ # Auto-increment line order value if not set by user
50
+ data[:lineordering] ||= size + 1
51
+ lines << [type, InvoiceLineData.new(data)]
52
+ end
53
+
54
+ def gateway_attributes
55
+ output = {}
56
+ line_type_count = Hash.new(0)
57
+ lines.each do |type, line_data|
58
+ output.store("service_InvoiceSpecification_#{type}_#{line_type_count[type] += 1}", line_data.gateway_string)
59
+ end
60
+ output
61
+ end
62
+ end
63
+
64
+ class InvoiceLineData
65
+ ATTRIBUTES = [
66
+ :lineordering,
67
+ :description,
68
+ :currency,
69
+ :amount,
70
+ :tax,
71
+ :numberofunits,
72
+ :unitprice,
73
+ :unitname
74
+ ]
75
+ attr_accessor *ATTRIBUTES
76
+
77
+ def initialize(args = {})
78
+ ATTRIBUTES.each do |name|
79
+ self.send "#{name}=", args.delete(name)
80
+ end
81
+ unless args.empty?
82
+ raise ArgumentError.new("Illegal attributes given: #{args.keys.join(',')}")
83
+ end
84
+ end
85
+
86
+ def gateway_string
87
+ ATTRIBUTES.map {|a| self.send(a) }.join('|')
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,40 @@
1
+ module BuckarooClient
2
+ module Service
3
+ class PayPerEmail
4
+
5
+ attr_accessor :customergender, :customeremail, :customerfirstname, :customerlastname,
6
+ :merchantsendsemail, :paymentmethodsallowed, :expirationdate
7
+
8
+ def initialize(args = {})
9
+ @customergender = args.fetch(:customergender, 0)
10
+ @customeremail = args[:customeremail]
11
+ @customerfirstname = args[:customerfirstname]
12
+ @customerlastname = args[:customerlastname]
13
+ @merchantsendsemail = args.fetch(:merchantsendsemail, false)
14
+ @paymentmethodsallowed = args[:paymentmethodsallowed]
15
+ @expirationdate = args[:expirationdate]
16
+ end
17
+
18
+ def servicecode
19
+ 'payperemail'
20
+ end
21
+
22
+ def action
23
+ 'paymentinvitation'
24
+ end
25
+
26
+ def gateway_attributes
27
+ {
28
+ 'service_payperemail_action' => action,
29
+ 'service_payperemail_customergender' => customergender.to_s,
30
+ 'service_payperemail_customeremail' => customeremail,
31
+ 'service_payperemail_customerfirstname' => customerfirstname,
32
+ 'service_payperemail_customerlastname' => customerlastname,
33
+ 'service_payperemail_merchantsendsemail' => merchantsendsemail.to_s.upcase,
34
+ 'service_payperemail_paymentmethodsallowed' => paymentmethodsallowed,
35
+ 'service_payperemail_expirationdate' => expirationdate,
36
+ }.select { |_, value| !value.nil? }
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,39 @@
1
+ module BuckarooClient
2
+ class Transaction
3
+ attr_accessor :websitekey, :amount, :culture, :currency, :description, :invoicenumber
4
+ attr_accessor :service, :additional_services
5
+
6
+ def initialize(args = {})
7
+ @websitekey = args[:websitekey]
8
+ @amount = args[:amount]
9
+ @culture = args.fetch(:culture, 'nl-NL')
10
+ @currency = args.fetch(:currency, 'EUR')
11
+ @description = args[:description]
12
+ @invoicenumber = args[:invoicenumber]
13
+ @service = args[:service]
14
+ @additional_services = args.fetch(:additional_services, [])
15
+ end
16
+
17
+ def gateway_attributes
18
+ output = {
19
+ 'websitekey' => websitekey,
20
+ 'amount' => amount,
21
+ 'culture' => culture,
22
+ 'currency' => currency,
23
+ 'description' => description,
24
+ 'invoicenumber' => invoicenumber,
25
+ }
26
+ if service
27
+ output['service'] = service.servicecode
28
+ output.merge!(service.gateway_attributes)
29
+ end
30
+ if additional_services.count > 0
31
+ output['additional_service'] = additional_services.map(&:servicecode).join(',')
32
+ additional_services.each do |a|
33
+ output.merge!(a.gateway_attributes)
34
+ end
35
+ end
36
+ output
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,3 @@
1
+ module BuckarooClient
2
+ VERSION = "0.0.1.pre"
3
+ end
@@ -0,0 +1,54 @@
1
+ require 'buckaroo_client/gateway/batch'
2
+
3
+ describe BuckarooClient::Gateway::Batch do
4
+ INPUT_HASH = {
5
+ 'websitekey' => 'xxx',
6
+ 'amount' => '10.00',
7
+ 'culture' => 'nl-NL',
8
+ 'currency' => 'EUR',
9
+ 'description' => 'test PPE 1',
10
+ 'invoicenumber' => 'test01923r4a1',
11
+ 'service' => 'payperemail',
12
+ 'service_payperemail_action' => 'paymentinvitation',
13
+ 'service_payperemail_customergender' => '1',
14
+ 'service_payperemail_customeremail' => 'support@buckaroo.nl',
15
+ 'service_payperemail_customerfirstname' => 'test',
16
+ 'service_payperemail_customerlastname' => 'Tester',
17
+ 'service_payperemail_merchantsendsemail' => 'FALSE',
18
+ 'service_payperemail_paymentmethodsallowed' => 'ideal;transfer',
19
+ 'service_payperemail_expirationdate' => '13-1-2012'
20
+ }
21
+ OUTPUT_CSV = <<CSV
22
+ websitekey;amount;culture;currency;description;invoicenumber;service;service_payperemail_action;service_payperemail_customergender;service_payperemail_customeremail;service_payperemail_customerfirstname;service_payperemail_customerlastname;service_payperemail_merchantsendsemail;service_payperemail_paymentmethodsallowed;service_payperemail_expirationdate
23
+ xxx;10.00;nl-NL;EUR;test PPE 1;test01923r4a1;payperemail;paymentinvitation;1;support@buckaroo.nl;test;Tester;FALSE;"ideal;transfer";13-1-2012
24
+ CSV
25
+
26
+ describe '#size' do
27
+ it 'defaults to 0' do
28
+ expect(subject.size).to eq 0
29
+ end
30
+ end
31
+
32
+ describe '#each' do
33
+ it 'responds to method' do
34
+ expect { subject.each }.not_to raise_error
35
+ end
36
+ end
37
+
38
+ describe '<<' do
39
+ it 'stores object in transactions' do
40
+ expect(subject.size).to eq 0
41
+ mock_transaction = double()
42
+ subject << mock_transaction
43
+ expect(subject.size).to eq 1
44
+ end
45
+ end
46
+
47
+ describe '#to_csv' do
48
+ it 'converts Gateway-prepared data to valid CSV output' do
49
+ subject << double(gateway_attributes: INPUT_HASH)
50
+ expect(subject.to_csv).to eq OUTPUT_CSV
51
+ end
52
+ end
53
+
54
+ end
@@ -0,0 +1,173 @@
1
+ require 'buckaroo_client/gateway/nvp'
2
+ require 'dotenv'
3
+
4
+ describe BuckarooClient::Gateway::NVP do
5
+
6
+ before :all do
7
+ Dotenv.load
8
+ ENV['BUCKAROO_CLIENT_WEBSITEKEY'] || raise("Please set BUCKAROO_CLIENT_WEBSITEKEY ENV variable")
9
+ ENV['BUCKAROO_CLIENT_SECRET'] || raise("Please set BUCKAROO_CLIENT_SECRET ENV variable")
10
+ end
11
+
12
+ def random_invoice_number
13
+ "TEST#{rand(100000000000000000000000000)}"
14
+ end
15
+
16
+ TRANSACTION_REQUEST_ATTRIBUTES = {
17
+ 'channel' => 'BACKOFFICE',
18
+ 'payment_method' => 'payperemail',
19
+ 'amount' => '99.99',
20
+ 'currency' => 'EUR',
21
+ 'culture' => 'nl-NL',
22
+ 'invoicenumber' => '0000',
23
+ 'description' => 'Test payperemail transaction',
24
+ 'service_payperemail_action' => 'paymentinvitation',
25
+ 'service_payperemail_customergender' => '1',
26
+ 'service_payperemail_customeremail' => 'example@example.com',
27
+ 'service_payperemail_customerfirstname' => 'Cus',
28
+ # Set value below to TRUE to skip sending e-mails.
29
+ # Otherwise, Buckaroo sends an actual mail for test transactions.
30
+ 'service_payperemail_merchantsendsemail' => 'TRUE',
31
+ 'service_payperemail_customerlastname' => 'Tomer'
32
+ }
33
+
34
+ INVOICE_INFO_ATTRIBUTES = {
35
+ 'invoicenumber' => '0000'
36
+ }
37
+
38
+ INVOICE_REQUEST_ATTRIBUTES = {
39
+ "brq_amount" => '120.9978',
40
+ "brq_culture" => "nl-NL",
41
+ "brq_currency" => "EUR",
42
+ "brq_description" => "Testfactuur",
43
+ # Don't use hard-coded invoicenumber, let spec generate random one.
44
+ # Buckaroo rejects duplicate invoicenumbers for Credit Management invoices.
45
+ # "brq_invoicenumber" => "123467898",
46
+ "brq_service" => "payperemail",
47
+ "brq_service_payperemail_action" => "paymentinvitation",
48
+ "brq_service_payperemail_customergender" => "9",
49
+ "brq_service_payperemail_customeremail" => 'example@example.com',
50
+ "brq_service_payperemail_customerfirstname" => "Cus",
51
+ "brq_service_payperemail_customerlastname" => "Tomer",
52
+ # Set value below to TRUE to skip sending e-mails.
53
+ # Otherwise, Buckaroo sends an actual mail for test transactions.
54
+ "brq_service_payperemail_merchantsendsemail" => "TRUE",
55
+ # "brq_service_payperemail_paymentmethodsallowed" => nil,
56
+ # "brq_service_payperemail_expirationdate" => nil,
57
+
58
+ "brq_additional_service" => "creditmanagement,invoicespecification",
59
+
60
+ "brq_service_InvoiceSpecification_action" => "ExtraInfo",
61
+ "brq_service_InvoiceSpecification_InvoiceLine_1" =>
62
+ "1|Factuurregelomschrijving|€|99.99|20.9979|||",
63
+ "brq_service_InvoiceSpecification_SubTotalLine_1" =>
64
+ "2|Totaal exclusief BTW|€|99.99||||",
65
+ "brq_service_InvoiceSpecification_InvoiceLine_2" =>
66
+ "3|Totaal BTW|€|20.9979||||",
67
+ "brq_service_InvoiceSpecification_TotalLine_1" =>
68
+ "4|Totaal inclusief BTW|€|120.9879||||",
69
+
70
+ "brq_service_creditmanagement_action" => "invoice",
71
+ "brq_InvoiceDate" => "2014-11-20",
72
+ "brq_DateDue" => "2014-12-04",
73
+ "brq_AmountVat" => "20.9979",
74
+ "brq_service_creditmanagement_MaxReminderLevel" => "3",
75
+ # "brq_service_creditmanagement_PaymentMethodsAllowed" => "",
76
+ "brq_CustomerType" => "2",
77
+ "brq_CustomerCode" => "14342",
78
+ "brq_CustomerTitle" => "",
79
+ "brq_CustomerInitials" => "",
80
+ "brq_CustomerFirstName" => "Cus",
81
+ "brq_CustomerLastNamePrefix" => "",
82
+ "brq_CustomerLastName" => "Tomer",
83
+ "brq_CustomerGender" => "9",
84
+ "brq_service_creditmanagement_CustomerBirthDate" => "",
85
+ "brq_CustomerEmail" => "example@example.com",
86
+ "brq_PhoneNumber" => "+31999999999",
87
+ "brq_MobilePhoneNumber" => "",
88
+ "brq_FaxNumber" => "",
89
+ "brq_Address_Street_1" => "Straatlaan",
90
+ "brq_Address_HouseNumber_1" => "999",
91
+ "brq_Address_HouseNumberSuffix_1" => "",
92
+ "brq_Address_ZipCode_1" => "9999 ZZ",
93
+ "brq_Address_City_1" => "Stad",
94
+ "brq_Address_State_1" => "",
95
+ "brq_Address_Country_1" => "NL",
96
+ "brq_service_creditmanagement_CustomerAccountNumber" => "",
97
+ "brq_service_creditmanagement_CompanyName" => "Organization1",
98
+ "brq_service_creditmanagement_CompanyCOCRegistration" => "A99",
99
+ "brq_service_creditmanagement_CompanyVATApplicable" => "TRUE"
100
+ }
101
+
102
+ describe '.websitekey' do
103
+ it 'raises error if not set' do
104
+ old_value = ENV.delete('BUCKAROO_CLIENT_WEBSITEKEY')
105
+ expect { described_class.websitekey }.to raise_error
106
+ ENV['BUCKAROO_CLIENT_WEBSITEKEY'] = old_value
107
+ end
108
+ end
109
+
110
+ describe '.secret_key' do
111
+ it 'raises error if not set' do
112
+ old_value = ENV.delete('BUCKAROO_CLIENT_SECRET')
113
+ expect { described_class.secret_key }.to raise_error
114
+ ENV['BUCKAROO_CLIENT_SECRET'] = old_value
115
+ end
116
+ end
117
+
118
+ describe '.url' do
119
+ it 'defaults to test location' do
120
+ expect(ENV['BUCKAROO_CLIENT_ENVIRONMENT']).to eq nil
121
+ expect(described_class.url.to_s).to eq 'https://testcheckout.buckaroo.nl/nvp/'
122
+ end
123
+
124
+ it 'returns live location if live mode enabled' do
125
+ expect(ENV['BUCKAROO_CLIENT_ENVIRONMENT']).to eq nil
126
+ ENV['BUCKAROO_CLIENT_ENVIRONMENT'] = 'production'
127
+ expect(described_class.url.to_s).to eq 'https://checkout.buckaroo.nl/nvp/'
128
+ ENV.delete('BUCKAROO_CLIENT_ENVIRONMENT')
129
+ end
130
+ end
131
+
132
+ describe '.transaction_request' do
133
+ it 'returns a success response' do
134
+ response = described_class.transaction_request(TRANSACTION_REQUEST_ATTRIBUTES)
135
+ # Success response code for PayPerEmail: 792 Awaiting Consumer
136
+ expect(response.body).to include('BRQ_STATUSCODE=792')
137
+ expect(response.verified?).to eq true
138
+ expect(response.success).to eq true
139
+ end
140
+
141
+ it 'returns success for valid PayPerEmail request with InvoiceSpecification and CreditManagement' do
142
+ variables = INVOICE_REQUEST_ATTRIBUTES.merge('brq_invoicenumber' => random_invoice_number)
143
+ response = described_class.transaction_request(variables)
144
+ # Success response code for PayPerEmail: 792 Awaiting Consumer
145
+ expect(response.body).to include('BRQ_STATUSCODE=792')
146
+ expect(response.verified?).to eq true
147
+ expect(response.success).to eq true
148
+ end
149
+ end
150
+
151
+ describe '.transaction_status' do
152
+ pending 'not yet implemented'
153
+ end
154
+
155
+ describe '.invoice_info' do
156
+ it 'returns a success response for an existing transaction' do
157
+ described_class.transaction_request(TRANSACTION_REQUEST_ATTRIBUTES)
158
+ response = described_class.invoice_info(INVOICE_INFO_ATTRIBUTES)
159
+ expect(response.body).to include('BRQ_APIRESULT=Success')
160
+ end
161
+ end
162
+
163
+ describe '.transaction_request_specification' do
164
+ it 'returns a succesful response' do
165
+ params = {
166
+ 'channel' => 'BACKOFFICE',
167
+ 'services' => 'payperemail'
168
+ }
169
+ response = described_class.transaction_request_specification(params)
170
+ expect(response.body).to include('BRQ_APIRESULT=Success')
171
+ end
172
+ end
173
+ end