buckaroo_client 0.0.1.pre

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.
@@ -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