worldnet_tps 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 (52) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +6 -0
  5. data/Gemfile +9 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +70 -0
  8. data/Rakefile +6 -0
  9. data/lib/worldnet_tps.rb +12 -0
  10. data/lib/worldnet_tps/const.rb +42 -0
  11. data/lib/worldnet_tps/gateway.rb +71 -0
  12. data/lib/worldnet_tps/gateway.xsd +1909 -0
  13. data/lib/worldnet_tps/request/base.rb +107 -0
  14. data/lib/worldnet_tps/request/payment.rb +89 -0
  15. data/lib/worldnet_tps/request/refund.rb +59 -0
  16. data/lib/worldnet_tps/request/secure_card/registration.rb +71 -0
  17. data/lib/worldnet_tps/request/secure_card/removal.rb +46 -0
  18. data/lib/worldnet_tps/request/secure_card/search.rb +52 -0
  19. data/lib/worldnet_tps/response/error.rb +18 -0
  20. data/lib/worldnet_tps/response/invalid_hash.rb +21 -0
  21. data/lib/worldnet_tps/response/success.rb +25 -0
  22. data/lib/worldnet_tps/version.rb +3 -0
  23. data/lib/worldnet_tps/ws_object.rb +76 -0
  24. data/lib/worldnet_tps/xsd.rb +27 -0
  25. data/spec/fixtures/vcr_cassettes/payment/credit_card/failed.yml +60 -0
  26. data/spec/fixtures/vcr_cassettes/payment/credit_card/success.yml +59 -0
  27. data/spec/fixtures/vcr_cassettes/payment/secure_card/failed.yml +57 -0
  28. data/spec/fixtures/vcr_cassettes/payment/secure_card/success.yml +56 -0
  29. data/spec/fixtures/vcr_cassettes/refund/order_id/failed.yml +47 -0
  30. data/spec/fixtures/vcr_cassettes/refund/order_id/success.yml +46 -0
  31. data/spec/fixtures/vcr_cassettes/refund/unique_ref/failed.yml +47 -0
  32. data/spec/fixtures/vcr_cassettes/refund/unique_ref/success.yml +46 -0
  33. data/spec/fixtures/vcr_cassettes/secure_card/registration/registrarion_failed.yml +49 -0
  34. data/spec/fixtures/vcr_cassettes/secure_card/registration/registration_failed.yml +49 -0
  35. data/spec/fixtures/vcr_cassettes/secure_card/registration/registration_success.yml +48 -0
  36. data/spec/fixtures/vcr_cassettes/secure_card/registration/update_failed.yml +49 -0
  37. data/spec/fixtures/vcr_cassettes/secure_card/registration/update_success.yml +48 -0
  38. data/spec/fixtures/vcr_cassettes/secure_card/registration/update_success_success.yml +48 -0
  39. data/spec/fixtures/vcr_cassettes/secure_card/removal/failed.yml +45 -0
  40. data/spec/fixtures/vcr_cassettes/secure_card/removal/success.yml +44 -0
  41. data/spec/fixtures/vcr_cassettes/secure_card/search/failed.yml +44 -0
  42. data/spec/fixtures/vcr_cassettes/secure_card/search/success.yml +44 -0
  43. data/spec/gateway_spec.rb +42 -0
  44. data/spec/payment_spec.rb +117 -0
  45. data/spec/refund_spec.rb +95 -0
  46. data/spec/secure_card/registration_spec.rb +103 -0
  47. data/spec/secure_card/removal_spec.rb +57 -0
  48. data/spec/secure_card/search_spec.rb +58 -0
  49. data/spec/spec_helper.rb +58 -0
  50. data/spec/xsd_spec.rb +30 -0
  51. data/worldnet_tps.gemspec +28 -0
  52. metadata +205 -0
@@ -0,0 +1,107 @@
1
+ require 'net/http'
2
+ require 'net/https'
3
+ require 'uri'
4
+ require_relative '../response/success'
5
+ require_relative '../response/error'
6
+ require_relative '../response/invalid_hash'
7
+ require_relative '../xsd'
8
+
9
+ module WorldnetTps
10
+ module Request
11
+ class Base < WorldnetTps::WsObject
12
+
13
+ class_attribute :invoke_method, :response_keys, instance_writer: false
14
+ attr_reader :gateway, :request, :response, :date_time, :attributes
15
+
16
+ class_attribute :xsd_validation
17
+ self.xsd_validation = true
18
+
19
+ def process!(struct)
20
+ xml = build_xml(struct)
21
+ validate_xml!(xml) if xsd_validation?
22
+ uri = URI.parse(ws_url)
23
+ http = Net::HTTP.new(uri.host, 443)
24
+ http.use_ssl = true
25
+ @request = Net::HTTP::Post.new(uri.request_uri)
26
+ @request.body = xml
27
+ @response = http.request(@request)
28
+ build_response(@response)
29
+ end
30
+
31
+ def invoke!
32
+ _invoke! invoke_method
33
+ end
34
+
35
+ protected
36
+
37
+ def validate_xml!(xml)
38
+ WorldnetTps::XSD.validate!(xml)
39
+ end
40
+
41
+ def build_xml(struct)
42
+ root = struct.keys.first
43
+ data = Hash[struct[root].map { |k, v| [prepare_key(k), v.to_s] }]
44
+ data.to_xml(root: prepare_key(root))
45
+ end
46
+
47
+ def build_failed_response(code, message)
48
+ Response::Error.new(code, message)
49
+ end
50
+
51
+
52
+ def build_success_response(attributes)
53
+ Response::Success.new(attributes)
54
+ end
55
+
56
+ def build_response(http_response)
57
+ data = Hash.from_xml(http_response.body).values.first
58
+ if data.keys[0] =~ /error/i
59
+ build_failed_response(data['ERRORCODE'], data['ERRORSTRING'])
60
+ else
61
+ response_attributes = normalize_response_attributes(data)
62
+ begin
63
+ validate_hash!(response_attributes)
64
+ rescue WorldnetTps::WsObject::InvalidHashError => e
65
+ return Response::InvalidHash.new(response_attributes)
66
+ end
67
+ build_success_response(response_attributes)
68
+ end
69
+ end
70
+
71
+
72
+ def _invoke!(action)
73
+ add_check_sum!
74
+ verify_request_keys!(self.class.mandatory_attributes(self), self.attributes)
75
+ attrs = (request_attributes).inject({}) do |h, i|
76
+ h[i] = self.attributes[i]
77
+ h
78
+ end.reject { |_, v| v.nil? }
79
+ process!(action => attrs)
80
+ end
81
+
82
+ def request_attributes
83
+ self.class.mandatory_attributes(self) + self.class.optional_attributes(self)
84
+ end
85
+
86
+ def self.mandatory_attributes(_context)
87
+ []
88
+ end
89
+
90
+ def self.optional_attributes(_context)
91
+ []
92
+ end
93
+
94
+ def self.response_check_sum_keys(_context, _response)
95
+ []
96
+ end
97
+
98
+ def self.request_check_sum_keys(_context)
99
+ []
100
+ end
101
+
102
+ def ws_url
103
+ gateway.ws_url
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,89 @@
1
+ module WorldnetTps
2
+ module Request
3
+ #@see: https://docs.worldnettps.com/doku.php?id=developer:integrator_guide:5._xml_integration:5.1._request_types:5.1.1._xml_payments
4
+ class Payment < WorldnetTps::Request::Base
5
+
6
+ self.invoke_method = :payment
7
+
8
+ def self.response_check_sum_keys(_context, response)
9
+ unique_key = response[:unique_ref].present? ? :unique_ref : :order_id
10
+ [
11
+ :terminal_id,
12
+ unique_key,
13
+ :amount,
14
+ :date_time,
15
+ :response_code,
16
+ :response_text,
17
+ :shared_secret
18
+ ]
19
+ end
20
+
21
+
22
+ def self.request_check_sum_keys(_context)
23
+ [
24
+ :terminal_id,
25
+ :order_id,
26
+ :amount,
27
+ :date_time,
28
+ :shared_secret
29
+ ]
30
+ end
31
+
32
+ self.response_keys = [:unique_ref, :response_code, :response_text, :approval_code, :date_time, :avs_response, :cvv_response, :hash]
33
+
34
+ def initialize(gateway, attrs)
35
+ super
36
+ #by default TERM_INTERNET = 2 # eCommerce
37
+ assign(:terminal_type, WorldnetTps::Const::TERM_INTERNET) if attributes[:terminal_type].blank?
38
+ #by default TRANS_INTERNET = 7 #eCommerce
39
+ assign(:transaction_type, WorldnetTps::Const::TRANS_INTERNET) if attributes[:transaction_type].blank?
40
+ end
41
+
42
+ def secured_card?
43
+ WorldnetTps::Const::SECURECARD == self[:card_type]
44
+ end
45
+
46
+
47
+ def self.mandatory_attributes(context)
48
+ keys = [
49
+ :order_id,
50
+ :terminal_id,
51
+ :amount,
52
+ :date_time,
53
+ :card_number,
54
+ :card_type
55
+ ]
56
+
57
+ keys += [:card_expiry, :card_holder_name] unless context.secured_card?
58
+ keys += [:hash, :currency, :terminal_type, :transaction_type]
59
+ keys
60
+ end
61
+
62
+ def self.optional_attributes(_context)
63
+ [
64
+ :auto_ready,
65
+ :email,
66
+ :cvv,
67
+ :issue_no,
68
+ :address1,
69
+ :address2,
70
+ :post_code,
71
+ :avs_only,
72
+ :description,
73
+ :xid,
74
+ :cavv,
75
+ :mpiref,
76
+ :mobile_number,
77
+ :device_id,
78
+ :phone,
79
+ :city,
80
+ :region,
81
+ :country,
82
+ :ip_address,
83
+ :signature
84
+ ]
85
+ end
86
+ end
87
+ end
88
+
89
+ end
@@ -0,0 +1,59 @@
1
+ module WorldnetTps
2
+ module Request
3
+ class Refund < WorldnetTps::Request::Base
4
+
5
+ self.invoke_method = :refund
6
+
7
+ self.response_keys = [
8
+ :response_code,
9
+ :response_text,
10
+ :order_id,
11
+ :unique_ref,
12
+ :date_time,
13
+ :hash,
14
+ :processing_terminal
15
+ ]
16
+
17
+ def unique_key
18
+ self[:unique_ref].present? ? :unique_ref : :order_id
19
+ end
20
+
21
+ def self.request_check_sum_keys(context)
22
+ [
23
+ :terminal_id,
24
+ context.unique_key,
25
+ :amount,
26
+ :date_time,
27
+ :response_code,
28
+ :response_text,
29
+ :shared_secret
30
+ ]
31
+ end
32
+
33
+ def self.response_check_sum_keys(context, _response)
34
+ [
35
+ :terminal_id,
36
+ context.unique_key,
37
+ :amount,
38
+ :date_time,
39
+ :response_code,
40
+ :response_text,
41
+ :shared_secret
42
+ ]
43
+ end
44
+
45
+ def self.mandatory_attributes(context)
46
+ [
47
+ context.unique_key,
48
+ :terminal_id,
49
+ :amount,
50
+ :date_time,
51
+ :hash,
52
+ :operator,
53
+ :reason
54
+ ]
55
+ end
56
+
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,71 @@
1
+ require_relative '../base'
2
+ module WorldnetTps
3
+ module Request
4
+ module SecureCard
5
+ # Used for processing XML SecureCard Registrations
6
+ # through the WorldNet TPS XML Gateway.
7
+ class Registration < WorldnetTps::Request::Base
8
+
9
+ self.invoke_method = :secure_card_registration
10
+ self.response_keys = [
11
+ :merchant_ref,
12
+ :card_reference,
13
+ :date_time,
14
+ :hash
15
+ ]
16
+
17
+ def self.response_check_sum_keys(_context, _response)
18
+ [
19
+ :terminal_id,
20
+ :merchant_ref,
21
+ :card_reference,
22
+ :date_time,
23
+ :shared_secret
24
+ ]
25
+ end
26
+
27
+ def self.request_check_sum_keys(_context)
28
+ [
29
+ :terminal_id,
30
+ :merchant_ref,
31
+ :date_time,
32
+ :card_number,
33
+ :card_expiry,
34
+ :card_type,
35
+ :card_holder_name,
36
+ :shared_secret
37
+ ]
38
+ end
39
+
40
+ def self.optional_attributes(_context)
41
+ [
42
+ :dont_check_security,
43
+ :cvv,
44
+ :ussue_no
45
+ ]
46
+ end
47
+
48
+ alias :create! :invoke!
49
+ #alias_method :invoke!, :create!
50
+
51
+ def update!
52
+ _invoke! :secure_card_update
53
+ end
54
+
55
+ def self.mandatory_attributes(_context)
56
+ [
57
+ :merchant_ref,
58
+ :terminal_id,
59
+ :date_time,
60
+ :card_number,
61
+ :card_expiry,
62
+ :card_type,
63
+ :card_holder_name,
64
+ :hash
65
+ ]
66
+ end
67
+
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,46 @@
1
+ module WorldnetTps
2
+ module Request
3
+ module SecureCard
4
+ class Removal < WorldnetTps::Request::Base
5
+
6
+ def initialize(gateway, merchant_ref, card_reference)
7
+ super(gateway, {merchant_ref: merchant_ref, card_reference: card_reference})
8
+ end
9
+
10
+ self.invoke_method = :secure_card_removal
11
+ self.response_keys = [:merchant_ref, :date_time, :hash]
12
+
13
+ def self.request_check_sum_keys(_context)
14
+ [
15
+ :terminal_id,
16
+ :merchant_ref,
17
+ :date_time,
18
+ :card_reference,
19
+ :shared_secret
20
+ ]
21
+ end
22
+
23
+ def self.response_check_sum_keys(_context, _response)
24
+ [
25
+ :terminal_id,
26
+ :merchant_ref,
27
+ :date_time,
28
+ :shared_secret
29
+ ]
30
+ end
31
+
32
+
33
+ def self.mandatory_attributes(_context)
34
+ [
35
+ :merchant_ref,
36
+ :card_reference,
37
+ :terminal_id,
38
+ :date_time,
39
+ :hash
40
+ ]
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,52 @@
1
+ module WorldnetTps
2
+ module Request
3
+ module SecureCard
4
+ class Search < WorldnetTps::Request::Base
5
+
6
+ def initialize(gateway, merchant_ref)
7
+ super(gateway, { merchant_ref: merchant_ref })
8
+ end
9
+
10
+ self.invoke_method = :secure_card_search
11
+
12
+ self.response_keys = [:merchant_ref, :card_reference, :card_type,
13
+ :card_expiry, :card_holder_name, :date_time, :hash]
14
+
15
+ def self.request_check_sum_keys(_context)
16
+ [
17
+ :terminal_id,
18
+ :merchant_ref,
19
+ :date_time,
20
+ :shared_secret
21
+ ]
22
+ end
23
+
24
+ def self.response_check_sum_keys(_context, _response)
25
+ [
26
+ :terminal_id,
27
+ :merchant_ref,
28
+ :card_reference,
29
+ :card_type,
30
+ :card_expiry,
31
+ :card_holder_name,
32
+ :date_time,
33
+ :shared_secret
34
+ ]
35
+ end
36
+
37
+
38
+
39
+ def self.mandatory_attributes(_context)
40
+ [
41
+ :merchant_ref,
42
+ :terminal_id,
43
+ :date_time,
44
+ :hash
45
+ ]
46
+ end
47
+
48
+
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,18 @@
1
+ module WorldnetTps
2
+ module Response
3
+ class Error
4
+
5
+ attr_reader :code, :message
6
+
7
+ def initialize(code, message)
8
+ @code = code
9
+ @message = message
10
+ end
11
+
12
+ def success?
13
+ false
14
+ end
15
+ end
16
+ end
17
+ end
18
+