wirecard_checkout_page 0.0.1 → 0.1.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +2 -1
  4. data/Gemfile +2 -0
  5. data/README.md +4 -0
  6. data/Rakefile +1 -2
  7. data/VERSION +1 -1
  8. data/lib/wirecard_checkout_page.rb +6 -2
  9. data/lib/wirecard_checkout_page/errors.rb +2 -0
  10. data/lib/wirecard_checkout_page/fingerprint.rb +0 -0
  11. data/lib/wirecard_checkout_page/gateway.rb +26 -12
  12. data/lib/wirecard_checkout_page/init_request.rb +71 -0
  13. data/lib/wirecard_checkout_page/init_response.rb +12 -2
  14. data/lib/wirecard_checkout_page/request.rb +85 -0
  15. data/lib/wirecard_checkout_page/response_checksum.rb +15 -45
  16. data/lib/wirecard_checkout_page/toolkit/recur_payment.rb +66 -0
  17. data/lib/wirecard_checkout_page/toolkit/request.rb +55 -0
  18. data/lib/wirecard_checkout_page/toolkit/response.rb +50 -0
  19. data/lib/wirecard_checkout_page/version.rb +1 -1
  20. data/spec/spec_helper.rb +12 -8
  21. data/spec/wirecard_checkout_page/gateway_spec.rb +86 -28
  22. data/spec/wirecard_checkout_page/init_request_spec.rb +62 -0
  23. data/spec/wirecard_checkout_page/request_spec.rb +88 -0
  24. data/spec/wirecard_checkout_page/response_checksum_spec.rb +70 -116
  25. data/spec/wirecard_checkout_page/toolkit/recur_payment_spec.rb +125 -0
  26. data/spec/wirecard_checkout_page/toolkit/request_spec.rb +79 -0
  27. data/spec/wirecard_checkout_page/toolkit/response_spec.rb +36 -0
  28. data/wirecard_checkout_page.gemspec +9 -12
  29. metadata +40 -45
  30. data/lib/wirecard_checkout_page/request_checksum.rb +0 -88
  31. data/lib/wirecard_checkout_page/value_handling.rb +0 -19
  32. data/lib/wirecard_checkout_page/value_missing.rb +0 -1
  33. data/spec/wirecard_checkout_page/request_checksum_spec.rb +0 -96
  34. data/spec/wirecard_checkout_page/response_spec.rb +0 -42
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dc51edcaa21801adf0d37957f3990226d9184b66
4
- data.tar.gz: 2a97377d4cee7c220213c2b46f16f0929082b3bf
3
+ metadata.gz: e9938c8656716ad478ae1decf6e699af89c27a21
4
+ data.tar.gz: 234cfd69101fb4cd77c68113ff76506b9828a0a4
5
5
  SHA512:
6
- metadata.gz: 17df65f469ef1335cd5d70617d5922a138a4c860d439774de221b59c57a53fa329292ef74580374258b84239d11340c6581cf933fa0157a3c20d3ca27f10c0c7
7
- data.tar.gz: edfea03e52cbb6efd033c0699ca99b8c24802fb31cd24fbc86f6433352d93cd98799d9f7520b85e7e7b4d7804390178e64858fc1a87225309b07411f8fb1ab2a
6
+ metadata.gz: 46bb266f885eaf7b2b4e02fc158cb4c4c228ee07adce3a6340c3c6d27eca484b7ec83c3c0f8075b6c01cd7c1b6bee1e9aa3a76603b4f8718ddc284ea0e8f78ff
7
+ data.tar.gz: c707323a6264a864130258e842108c39df9f04084d4495be6ccd9f4dc24e9eb84e40a1eb0b883bf57f3c4a40d2a7818c864fad8111667b96853886d75db0c333
data/.gitignore CHANGED
@@ -1,6 +1,7 @@
1
1
  .*.sw[pon]
2
2
  .AppleDouble
3
3
  .DS_Store
4
+ .envrc
4
5
  .rvmrc
5
6
  Gemfile.lock
6
7
  coverage
@@ -1,6 +1,7 @@
1
1
  rvm:
2
- - 2.0.0
2
+ - 2.0
3
3
  - 2.1
4
+ - 2.2
4
5
  - ruby-head
5
6
  - jruby-head
6
7
  matrix:
data/Gemfile CHANGED
@@ -5,3 +5,5 @@ source 'https://rubygems.org'
5
5
  gemspec
6
6
 
7
7
  gem "codeclimate-test-reporter", group: :test, require: nil
8
+
9
+ gem 'byebug', group: :test, platforms: :mri
data/README.md CHANGED
@@ -41,3 +41,7 @@ puts response.params
41
41
  [![Code Climate](https://codeclimate.com/github/flori/wirecard_checkout_page/badges/gpa.svg)](https://codeclimate.com/github/flori/wirecard_checkout_page)
42
42
 
43
43
  [![Test Coverage](https://codeclimate.com/github/flori/wirecard_checkout_page/badges/coverage.svg)](https://codeclimate.com/github/flori/wirecard_checkout_page)
44
+
45
+
46
+ ## TODOS
47
+ [] Document the toolkit features
data/Rakefile CHANGED
@@ -10,7 +10,7 @@ GemHadar do
10
10
  summary 'Library for using Wirecard Checkout Page'
11
11
  description 'This library allows you to use the Wirecard Checkout Page service.'
12
12
  test_dir 'tests'
13
- ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', 'coverage', '.rvmrc', '.AppleDouble', '.DS_Store'
13
+ ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', 'coverage', '.rvmrc', '.AppleDouble', '.DS_Store', '.envrc'
14
14
  readme 'README.md'
15
15
  title "#{name.camelize} -- Wirecard Checkout Page implementation"
16
16
  licenses << 'Apache-2.0'
@@ -19,7 +19,6 @@ GemHadar do
19
19
  development_dependency 'rake'
20
20
  development_dependency 'simplecov'
21
21
  development_dependency 'rspec'
22
- development_dependency 'byebug'
23
22
  end
24
23
 
25
24
  task :default => :spec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.1
1
+ 0.1.0
@@ -1,13 +1,17 @@
1
1
  require 'digest/md5'
2
- require 'uri'
3
2
  require 'typhoeus'
4
3
  require 'wirecard_checkout_page/errors'
5
4
  require 'wirecard_checkout_page/gateway'
6
5
  require 'wirecard_checkout_page/utils'
7
- require 'wirecard_checkout_page/request_checksum'
8
6
  require 'wirecard_checkout_page/response_checksum'
7
+ require 'wirecard_checkout_page/request'
8
+ require 'wirecard_checkout_page/init_request'
9
9
  require 'wirecard_checkout_page/init_response'
10
10
  require 'wirecard_checkout_page/checked_response'
11
+ require 'wirecard_checkout_page/fingerprint'
12
+ require 'wirecard_checkout_page/toolkit/request'
13
+ require 'wirecard_checkout_page/toolkit/response'
14
+ require 'wirecard_checkout_page/toolkit/recur_payment'
11
15
 
12
16
  module WirecardCheckoutPage
13
17
  end
@@ -2,4 +2,6 @@ module WirecardCheckoutPage
2
2
  class WirecardCheckoutPageError < StandardError; end
3
3
 
4
4
  class ValueMissing < WirecardCheckoutPageError; end
5
+ class NotImplementedError < WirecardCheckoutPageError; end
6
+ class InvalidResponseFingerPrintOrder < WirecardCheckoutPageError; end
5
7
  end
@@ -1,30 +1,44 @@
1
1
  module WirecardCheckoutPage
2
2
  class Gateway
3
- DEFAULT_INIT_URL = 'https://checkout.wirecard.com/page/init.php'
4
3
 
5
- attr_accessor :customerId, :secret, :init_url
4
+ attr_accessor :customer_id, :secret, :toolkit_password, :shop_id
6
5
 
7
- def initialize(customerId: nil, secret: nil, init_url: nil)
8
- @customerId = customerId
9
- @secret = secret
10
- @init_url = init_url || DEFAULT_INIT_URL
6
+ def initialize(customer_id: nil, secret: nil, toolkit_password: nil, shop_id: nil)
7
+ @customer_id = customer_id
8
+ @secret = secret
9
+ @toolkit_password = toolkit_password
10
+ @shop_id = shop_id
11
11
  end
12
12
 
13
13
  def init(params = {})
14
- checksum = WirecardCheckoutPage::RequestChecksum.new(params.merge(authentication_params))
15
- InitResponse.new Typhoeus.post(init_url, body: checksum.request_parameters)
14
+ params = params.merge(authentication_params).merge( transactionIdentifier: 'SINGLE' )
15
+ InitRequest.new(params: params).call
16
+ end
17
+
18
+ def recurring_init(params = {})
19
+ params = params.merge(authentication_params).merge( transactionIdentifier: 'INITIAL' )
20
+ InitRequest.new(params: params).call
21
+ end
22
+
23
+ def recurring_process(params = {})
24
+ params = params.merge(toolkit_authentication_params)
25
+ Toolkit::RecurPayment.new(params: params).call
16
26
  end
17
27
 
18
28
  def check_response(params = {})
19
- WirecardCheckoutPage::CheckedResponse.new(
20
- params.merge(authentication_params)
21
- )
29
+ CheckedResponse.new params.merge(authentication_params)
22
30
  end
23
31
 
24
32
  private
25
33
 
26
34
  def authentication_params
27
- { secret: secret, customerId: customerId }
35
+ params = { secret: secret, customerId: customer_id }
36
+ params[:shopId] = shop_id if shop_id
37
+ params
38
+ end
39
+
40
+ def toolkit_authentication_params
41
+ authentication_params.merge( toolkitPassword: toolkit_password )
28
42
  end
29
43
 
30
44
  end
@@ -0,0 +1,71 @@
1
+ module WirecardCheckoutPage
2
+ class InitRequest < Request
3
+
4
+ DEFAULT_URL = 'https://checkout.wirecard.com/page/init.php'
5
+
6
+ def initialize(url: nil, params: {})
7
+ super url: url || DEFAULT_URL, params: params
8
+ self.transactionIdentifier ||= 'SINGLE'
9
+ end
10
+
11
+ # Parameter Within fingerprint Data type Short description
12
+ # customerId Required Alphanumeric with a fixed length of 7. Unique ID of merchant.
13
+ # language Required Alphabetic with a fixed length of 2. Language for displayed texts on payment page.
14
+ # paymentType Optional Enumeration Selected payment method of your consumer.
15
+ # amount Required Amount Amount of payment.
16
+ # currency required Alphabetic with a fixed length of 3 or numeric with a fixed length of 3. Currency code of amount.
17
+ # orderDescription Required Alphanumeric with a variable length of up to 255. Unique description of the consumer's order in a human readable form.
18
+ # successUrl Required Alphanumeric with special characters. URL of your online shop when payment process was successful.
19
+ # cancelUrl Optional Alphanumeric with special characters. URL of your online shop when payment process has been canceled.
20
+ # failureUrl Optional Alphanumeric with special characters. URL of your online shop when an error occured within payment process.
21
+ # serviceUrl Optional Alphanumeric with special characters and a variable length of up to 255. URL of your service page containing contact information.
22
+
23
+ param :secret, required: true
24
+ param :customerId, required: true
25
+ param :language, required: true
26
+ param :paymentType, required: true
27
+ param :amount, required: true
28
+ param :currency, required: true
29
+ param :orderDescription, required: true
30
+ param :successUrl, required: true
31
+ param :cancelUrl, required: true # Seems to be required even if the docs say otherwise
32
+ param :failureUrl, required: true # Seems to be required even if the docs say otherwise
33
+ param :serviceUrl, required: true # Seems to be required even if the docs say otherwise
34
+
35
+ # Parameter Within fingerprint Data type Short description
36
+ # pendingUrl Optional Alphanumeric with special characters. URL of your online shop when result of payment process could not be determined yet.
37
+ # confirmUrl Required if used. Alphanumeric with special characters. URL of your online shop where Wirecard sends a server-to-server confirmation.
38
+ # noScriptInfoUrl Optional Alphanumeric with special characters. URL of your online shop where your information page regarding de-activated JavaScript resides.
39
+ # orderNumber Required if used. Numeric with a variable length of up to 9. Order number of payment.
40
+ # windowName Optional Alphanumeric Window name of browser window where payment page is opened.
41
+ # duplicateRequestCheck Required if used. Boolean (“yes” or “no”). Check for duplicate requests done by your consumer.
42
+ # customerStatement Required if used. Alphanumeric with a variable length of up to 254 characters, but may differ for specific payment methods. Text displayed on invoice of financial institution of your consumer.
43
+ # orderReference Required if used. Alphanumeric with a variable length up to 128 characters, but may differ for specific payment methods. Unique order reference ID sent from merchant to financial institution.
44
+ # transactionIdentifier Required if used. Enumeration Possible values are SINGLE (for one-off transactions) or INITIAL (for the first transaction of a series of recurring transactions).
45
+
46
+ param :pendingUrl
47
+ param :confirmUrl, required: true # Seems to be required even if the docs say otherwise
48
+ param :noScriptInfoUrl
49
+ param :orderNumber
50
+ param :windowName
51
+ param :duplicateRequestCheck
52
+ param :customerStatement
53
+ param :orderReference
54
+ param :transactionIdentifier
55
+ param :shopId
56
+
57
+ def fingerprint_order
58
+ super + [:requestFingerprintOrder]
59
+ end
60
+
61
+ def requestFingerprintOrder
62
+ fingerprint_order * ','
63
+ end
64
+
65
+ def call
66
+ raise WirecardCheckoutPage::ValueMissing, errors.join(', ') unless valid?
67
+ InitResponse.from_typhoeus_response Typhoeus.post(DEFAULT_URL, body: body)
68
+ end
69
+
70
+ end
71
+ end
@@ -3,10 +3,20 @@
3
3
 
4
4
  module WirecardCheckoutPage
5
5
  class InitResponse
6
- def initialize(response)
7
- @original_response = response
6
+
7
+ def self.from_typhoeus_response(response)
8
+ new(response.body, original_response: response)
9
+ end
10
+
11
+ def initialize(body, original_response: nil)
12
+ @body = body
13
+ @original_response = original_response
8
14
  end
9
15
 
16
+ attr_reader :original_response
17
+
18
+ attr_reader :body
19
+
10
20
  def params
11
21
  {
12
22
  payment_url: @original_response.headers['Location']
@@ -0,0 +1,85 @@
1
+ module WirecardCheckoutPage
2
+ class Request
3
+ def self.param(name, options = {})
4
+ name = name.to_sym
5
+ params_order << name
6
+ params[name] = options
7
+ attr_accessor name
8
+ end
9
+
10
+ def self.params
11
+ @params ||= {}
12
+ end
13
+
14
+ def self.params_order
15
+ @params_order ||= []
16
+ end
17
+
18
+ def initialize(url: nil, params: {})
19
+ @url = url
20
+ params.each { |param, value| send "#{param}=", value }
21
+ end
22
+
23
+ attr_reader :url
24
+
25
+ attr_reader :params
26
+
27
+ attr_reader :errors
28
+
29
+ def valid?
30
+ @errors = []
31
+ attributes.each do |param, options|
32
+ next unless options[:required] == true
33
+ val = send param
34
+ @errors << "#{param} is required" if val.nil? || val == ''
35
+ end
36
+ @errors.empty?
37
+ end
38
+
39
+ def body
40
+ fingerprinted_request_params
41
+ end
42
+
43
+ def call
44
+ raise NotImplementedError, '#call not implemented'
45
+ end
46
+
47
+ def fingerprint_string
48
+ fingerprint_order.each_with_object('') { |param, str| str << send(param).to_s }
49
+ end
50
+
51
+ def fingerprint
52
+ Digest::MD5.hexdigest fingerprint_string
53
+ end
54
+
55
+ def fingerprint_order
56
+ self.class.params_order.select do |param|
57
+ attributes[param][:required] || send(param).to_s != ''
58
+ end
59
+ end
60
+
61
+ def request_params
62
+ rp = {}
63
+ attributes.keys.each do |param|
64
+ next if param == :secret
65
+ val = send(param).to_s
66
+ next if val == ''
67
+ rp[param.to_s] = val
68
+ end
69
+ rp
70
+ end
71
+
72
+ def fingerprinted_request_params
73
+ request_params.merge(
74
+ 'requestFingerprint' => fingerprint,
75
+ 'requestFingerprintOrder' => fingerprint_order.join(',')
76
+ )
77
+ end
78
+
79
+ private
80
+
81
+ def attributes
82
+ self.class.params
83
+ end
84
+ end
85
+ end
@@ -1,64 +1,34 @@
1
1
  # encoding: utf-8
2
2
 
3
- require 'wirecard_checkout_page/value_handling'
4
-
5
3
  module WirecardCheckoutPage
6
4
  class ResponseChecksum
7
5
  include WirecardCheckoutPage::Utils
8
- include WirecardCheckoutPage::ValueHandling
9
-
10
- def initialize(values = {})
11
- @values = stringify_keys(values)
12
- @secret = @values.delete('secret') or
13
- raise WirecardCheckoutPage::ValueMissing, 'value "secret" is missing'
14
- # This rails form value is escaped as an html entity by
15
- # WirecardCheckoutPage, so set it back to the original UTF-8 here if it
16
- # exists:
17
- @values['utf8'] and @values['utf8'] = '✓'
18
- @values.freeze
19
- reset_missing_keys
20
- end
21
-
22
- attr_reader :values
23
-
24
- attr_reader :expected_fingerprint
25
-
26
- attr_reader :computed_fingerprint
27
6
 
28
- def fingerprint
29
- values = @values.dup
30
- values['secret'] ||= @secret
31
- if seed = responseFingerprintSeed(responseFingerprintOrder(values), values)
32
- Digest::MD5.hexdigest seed
7
+ def initialize(params)
8
+ @params = stringify_keys(params)
9
+ unless response_fingerprint_order_parts.include? 'secret'
10
+ raise InvalidResponseFingerPrintOrder, 'Missing :secret as a part of the responseFingerprintOrder'
33
11
  end
34
12
  end
35
13
 
14
+ attr_reader :params
15
+
36
16
  def valid?
37
- reset_missing_keys
38
- @expected_fingerprint = values.fetch('responseFingerprint') do |k|
39
- add_missing_key k
40
- end
41
- @computed_fingerprint = fingerprint
42
- !missing_keys? && computed_fingerprint == @expected_fingerprint
17
+ params['responseFingerprint'] == computed_fingerprint
43
18
  end
44
19
 
45
20
  private
46
21
 
47
- def responseFingerprintOrder(values)
48
- order = values.fetch('responseFingerprintOrder') do |k|
49
- add_missing_key k
50
- return []
51
- end
52
- order.split(',')
22
+ def response_fingerprint_order_parts
23
+ params['responseFingerprintOrder'].to_s.split(',')
24
+ end
25
+
26
+ def fingerprint_string
27
+ response_fingerprint_order_parts.map {|key| params[key.to_s] }.join
53
28
  end
54
29
 
55
- def responseFingerprintSeed(keys, values)
56
- fingerprint = keys.map do |k|
57
- values.fetch(k) do
58
- add_missing_key k
59
- end
60
- end * ''
61
- fingerprint unless missing_keys?
30
+ def computed_fingerprint
31
+ Digest::MD5.hexdigest fingerprint_string
62
32
  end
63
33
  end
64
34
  end
@@ -0,0 +1,66 @@
1
+ module WirecardCheckoutPage
2
+ module Toolkit
3
+ class RecurPayment < Request
4
+
5
+ def initialize(params: {})
6
+ super
7
+ self.command = 'recurPayment'
8
+ end
9
+
10
+ # Which request parameters are required for all operations?
11
+ # To start an operation you have to set all required parameters to their corresponding values.
12
+ # If one or more of these required parameters are missing you will get an error message.
13
+
14
+ # Parameter Data type Short description
15
+ # customerId Alphanumeric with a fixed length of 7. Unique ID of merchant.
16
+ # shopId Alphanumeric with a variable length of 16. Unique ID of your online shop if several
17
+ # toolkitPassword Alphanumeric with special characters. Your password for Toolkit light operations.
18
+ # command Enumeration Operation to be executed.
19
+ # language Alphabetic with a fixed length of 2. Language for returned texts and error messages,
20
+ # currently only “en” is supported; we are able
21
+ # to integrate other languages upon request.
22
+ # requestFingerprint Alphanumeric with a fixed length of 32. Computed fingerprint of the parameter
23
+ # values and the secret.
24
+ param :customerId, required: true
25
+ param :shopId
26
+ param :toolkitPassword, required: true
27
+ param :secret, required: true
28
+ param :command, required: true
29
+ param :language, required: true
30
+
31
+ # Additional required request parameters
32
+ #
33
+ # Parameter Data type Short description
34
+ # amount Amount Debit amount.
35
+ # currency Alphabetic with a fixed length of 3 Currency code of amount.
36
+ # or numeric with a fixed length of 3.
37
+ # orderDescription Alphanumeric with a variable length Textual description of order.
38
+ # of up to 255 characters.
39
+ # sourceOrderNumber Numeric with a variable length of Original order number used for new payment.
40
+ # up to 9 digits.
41
+
42
+ # Additional optional request parameters
43
+ #
44
+ # Parameter Data type Short description
45
+ # autoDeposit Enumeration Possible values are Yes and No.
46
+ # Yes is used for enabling and No for
47
+ # disabling automated deposit and
48
+ # day-end closing of payments.
49
+ # customerStatement Alphanumeric with a variable length Text displayed on invoice of
50
+ # of up to 254 characters. financial institution of your consumer.
51
+ # orderNumber Numeric with a variable length Order number of payment.
52
+ # of up to 9 digits.
53
+ # orderReference Alphanumeric with a variable length Unique order reference ID sent from
54
+ # of up to 128 characters. merchant to financial institution.
55
+ param :orderNumber
56
+ param :sourceOrderNumber, required: true
57
+ param :autoDeposit
58
+ param :orderDescription, required: true
59
+ param :amount, required: true
60
+ param :currency, required: true
61
+ param :orderReference
62
+ param :customerStatement
63
+
64
+ end
65
+ end
66
+ end