worldnet_tps 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+