complete_payment_systems 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5a30b99b8dc3c9b281274253a749868aff351cce
4
+ data.tar.gz: f365572a3c26dbc912dc1b16743853e3cc78e7b0
5
+ SHA512:
6
+ metadata.gz: afd6276737dda4f26fb571b4040997f5b17c1a50989572849af97a043c67e25614fd5366d79f44aa55e2b2093261d9c5b8b236fc1c679428b8f71f154571218e
7
+ data.tar.gz: 670de0ec274fcba92b69a817638907c2639e4dd40bcdd399e18140b09c7ab8be8de434c627decb380004eb2e8ebc8ff73eaf1345eb150e28d992edc10638efe9
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in complete_payment_systems.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Epigene
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # CompletePaymentSystems
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'complete_payment_systems'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install complete_payment_systems
18
+
19
+ ## Usage
20
+
21
+ The complete module name is CompletePaymentSystems, but the aliased shorthand CPS is recommended.
22
+
23
+ ### Configure Defaults
24
+ in */config/initializers/cps.rb*
25
+
26
+ ```ruby
27
+ CPS.configure do |config|
28
+ # Your CPS account user
29
+ config.default_user = "pasta_test_3d"
30
+
31
+ # server-to-server POST response processing route
32
+ config.default_callback_url = "http://www.app.com/cps/process"
33
+
34
+ # Url to "Thank-you"-"Retry" differ route
35
+ config.default_redirect_url = "http://www.app.com/cps/return"
36
+ config.default_product_name = "Product"
37
+ config.default_product_url = "www.test.com"
38
+ config.default_country = "US"
39
+
40
+ # Used in client data, like street and zip, if you choose not to ask for these
41
+ config.placeholder_value = "PLACEHOLDER"
42
+
43
+ config.cps_url = "https://3ds.cps.lv/GatorServo/request" # This will probably never change
44
+ config.cps_method = "sendForAuth" # This will also probably remain the same
45
+ config.cert_pass = 'pasS%123' # your cert chain password
46
+
47
+ # Your .pem format cert chain location
48
+ config.rsa_cert_path = "#{CPS.root}/lib/complete_payment_systems/certs/Pasta_test_3d.pem"
49
+ end
50
+ ```
51
+
52
+ ### Build a payment request
53
+ Instantiate a CPS::Request object, passit a hash with parameters:
54
+ ```ruby
55
+ hash = {
56
+ order: (Time.now.to_i), # Pass the unique purchase ID here
57
+ value: 100 , # Pass the purchase value in cents here (1$ purcase value = 100)
58
+ currency: "EUR", # Pass the purchase currency 3-letter code here ($ = "USD")
59
+ holder_name: "John", # Ask buyer for this in a form
60
+ holder_surname: "Doe", # Ask buyer for this in a form
61
+ card_number: "4314229999999913", # Ask buyer for this in a form
62
+ card_exp: "01/18", # Ask buyer for this in a form
63
+ card_cvv: "123", # Ask buyer for this in a form
64
+ holder_ip: "123.124.125.226", # Get this from request.remote_ip
65
+ holder_street: "NOT USED", # (Optional) Ask buyer for this in a form
66
+ holder_zip: "NOT USED", # (Optional) Ask buyer for this in a form
67
+ holder_city: "NOT USED", # (Optional) Ask buyer for this in a form
68
+ holder_country: "US", # (Optional) Ask buyer for this in a form
69
+ holder_email: "test@domain.com", # (Optional) Ask buyer for this in a form
70
+ user: "Some User" # Best defined in config and not passed
71
+ callback_url: "http://www.app.lv", # Best defined in config and not passed
72
+ redirect_url: "http://www.app.lv", # Best defined in config and not passed
73
+ product_name: "Product", # Best defined in config and not passed
74
+ product_url: "www.test.com" # Best defined in config and not passed
75
+ }
76
+ CPS::Request.new(hash)
77
+ ```
78
+ # Process response
79
+ Instantiate a CPS::Response object with an xml parameter (get the xml from server response .body)
80
+ ```ruby
81
+ @response = CPS.Response.new(request_response.body)
82
+ ```
83
+ API exposes reader methods #xml, #response_hash, #code, #message
84
+ as well as convenience methods #ok? and #signature_ok?
85
+
86
+ ```ruby
87
+ r = CPS::Response.new(valid_xml_response)
88
+ r.response_hash
89
+ => {"referenceId"=>"9095359",
90
+ "orderId"=>"1422019383",
91
+ "value"=>"100",
92
+ "currency"=>"USD",
93
+ "resultCode"=>"000",
94
+ "resultMessage"=>"Captured",
95
+ "resultText"=>"Captured",
96
+ "digiSignature"=>
97
+ "HlcnASe5fZyM7uVz4xwqp ... XGx5SVqSA=="}
98
+ r.code
99
+ => "000"
100
+ r.message
101
+ => "Captured"
102
+ r.signature_ok?
103
+ => true
104
+ r.ok?
105
+ => true
106
+ ```
107
+
108
+ ## Contributing
109
+
110
+ 1. Fork it ( https://github.com/[my-github-username]/complete_payment_systems/fork )
111
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
112
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
113
+ 4. Push to the branch (`git push origin my-new-feature`)
114
+ 5. Create a new Pull Request
115
+
116
+ ## Dev Notes
117
+
118
+ calbackUrl atbilde atnāks pirmā, jo te mēs sūtam atbildi pa tiešo no mūsu servera uz jūso noradītu URL
119
+
120
+ #### Direct-3D request example
121
+ hash = {
122
+ order: (Time.now.to_i), # Pass the unique purchase ID here
123
+ value: 166, # Pass the purchase value in cents here (1$ purcase value = 100)
124
+ currency: (params["currency"]), # Pass the purchase currency 3-letter code here ($ = "USD")
125
+ holder_name: "John", # Ask buyer for this in a form
126
+ holder_surname: "Doe", # Ask buyer for this in a form
127
+ card_number: "4314229999999913", # Ask buyer for this in a form
128
+ card_exp: "01/18", # Ask buyer for this in a form
129
+ card_cvv: "123", # Ask buyer for this in a form
130
+ holder_ip: "123.124.125.226", # Get this from request.remote_ip
131
+ holder_street: "NOT USED", # (Optional) Ask buyer for this in a form
132
+ holder_zip: "NOT USED", # (Optional) Ask buyer for this in a form
133
+ holder_city: "NOT USED", # (Optional) Ask buyer for this in a form
134
+ holder_country: "US", # (Optional) Ask buyer for this in a form
135
+ holder_email: "test@domain.com", # (Optional) Ask buyer for this in a form
136
+ user: "Some User" # Best defined in config and not passed
137
+ callback_url: "http://www.app.lv", # Best defined in config and not passed
138
+ redirect_url: "http://www.app.lv", # Best defined in config and not passed
139
+ product_name: "Product", # Best defined in config and not passed
140
+ product_url: "www.test.com" # Best defined in config and not passed
141
+ }
142
+ @request = CPS::Request.new(hash)
143
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'complete_payment_systems/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "complete_payment_systems"
8
+ spec.version = CompletePaymentSystems::VERSION
9
+ spec.date = Date.today.to_s
10
+ spec.authors = ["Epigene"]
11
+ spec.email = ["augusts.bautra@gmail.com"]
12
+ spec.summary = %q{A client for CPS (Complete Payment Systems) card payment service}
13
+ spec.description = %q{Coming soon...}
14
+ spec.homepage = ""
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0")
18
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
19
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
+ spec.require_paths = ["lib"]
21
+
22
+ spec.add_dependency 'unirest'
23
+ spec.add_dependency 'activesupport'
24
+ spec.add_dependency 'nokogiri', '~> 1.6.6'
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.6"
27
+ spec.add_development_dependency "rake"
28
+ spec.add_development_dependency 'rspec', "~> 3.1.0"
29
+ end
data/cps.xml ADDED
@@ -0,0 +1,43 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <cpsxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xsi:schemaLocation="http://www.cps.lv/xml/ns/cpsxml https://3ds.cps.lv/GatorServo/Gator_SendForAuth.xsd"
4
+ xmlns="http://www.cps.lv/xml/ns/cpsxml">
5
+ <header xmlns="">
6
+ <responsetype>direct</responsetype>
7
+ <user>pasta_test_3d</user>
8
+ <type>sendForAuth</type>
9
+ <transType>DB</transType>
10
+ <digiSignature>NP+o4wK17G3tqcTF5K2vfBjXQ4RpCLEYPoK9I99/9GPQO95fD0Xp+DueUV4c
11
+ AtgNQmQg4C2BTw0vh1fme8PQanaGF50WJOTdgXdU5ygRxkjja4EyA9cDe1cq
12
+ Ex7iqtSazv2FZXu/6RfVgwcoy4SRuNuQrsDqo6/7isJ/BpgppTI=
13
+ </digiSignature>
14
+ <callbackUrl>www.google.lv</callbackUrl>
15
+ <redirectUrl>http://www.google.lv</redirectUrl>
16
+ </header>
17
+ <request xmlns="">
18
+ <orderNumber>1422028510</orderNumber>
19
+ <cardholder>
20
+ <firstName>Test</firstName>
21
+ <lastName>User</lastName>
22
+ <street>NOT USED</street>
23
+ <zip>NOT USED</zip>
24
+ <city>NOT USED</city>
25
+ <country>LV</country>
26
+ <email>hi@creo.mobi</email>
27
+ <ip>123.124.125.226</ip>
28
+ </cardholder>
29
+ <card>
30
+ <cardNumber>4314229999999913</cardNumber>
31
+ <expires>01/18</expires>
32
+ <cvv>123</cvv>
33
+ </card>
34
+ <amount>
35
+ <value>100</value>
36
+ <currency>USD</currency>
37
+ </amount>
38
+ <product>
39
+ <productName>Product</productName>
40
+ <productUrl>www.test.com</productUrl>
41
+ </product>
42
+ </request>
43
+ </cpsxml>
@@ -0,0 +1,129 @@
1
+ require "complete_payment_systems/version"
2
+ require "complete_payment_systems/request_processing"
3
+ require "complete_payment_systems/response_processing"
4
+ #require 'rubygems'
5
+ require 'openssl'
6
+ require 'digest/sha1'
7
+ require 'base64'
8
+ require 'unirest'
9
+ require 'active_support/all'
10
+ require 'nokogiri'
11
+
12
+ module CompletePaymentSystems
13
+
14
+ CPS = CompletePaymentSystems
15
+ ROOT = File.expand_path("../..", __FILE__)
16
+
17
+ def self.root
18
+ ROOT
19
+ end
20
+
21
+ class << self
22
+ attr_accessor :config
23
+ end
24
+
25
+ def self.configure
26
+ self.config ||= Config.new
27
+ yield(config)
28
+ end
29
+
30
+ class Config
31
+ attr_accessor :default_user, :default_callback_url, :default_redirect_url, :default_product_name, :default_product_url, :default_country, :placeholder_value,
32
+ :cps_url, :cps_method, :cert_pass, :rsa_cert_path, :success_regex
33
+
34
+ def initialize
35
+ @default_user = "pasta_test_3d"
36
+ @default_callback_url = "http://www.google.com"
37
+ @default_redirect_url = "http://www.google.lv"
38
+ @default_product_name = "Product"
39
+ @default_product_url = "www.test.com"
40
+ @default_country = "US"
41
+ @placeholder_value = "PLACEHOLDER"
42
+
43
+ @cps_url = "https://3ds.cps.lv/GatorServo/request"
44
+ @cps_method = "sendForAuth"
45
+ @cert_pass = 'pasS%123'
46
+ @rsa_cert_path = "#{CPS.root}/lib/complete_payment_systems/certs/Pasta_test_3d.pem"
47
+ @success_regex = /Captured/
48
+ end
49
+
50
+ end
51
+
52
+ CPS.configure {}
53
+
54
+ # TO-DO Delete this after production checks
55
+ def self.make_xml
56
+ values = {
57
+ user: "pasta_test_3d", # "test_pasta_sign" for direct, "pasta_test_3d" for direct with 3D
58
+ callback_url: "http://www.google.lv",
59
+ redirect_url: "http://www.google.lv",
60
+ order: (Time.now.to_i),
61
+ holder_name: "Test",
62
+ holder_surname: "User",
63
+ holder_street: "NOT USED",
64
+ holder_zip: "NOT USED",
65
+ holder_city: "NOT USED",
66
+ holder_country: "LV",
67
+ holder_email: "hi@creo.mobi",
68
+ holder_ip: "123.124.125.226",
69
+ card_number: "4314229999999913", # 4012001037167778 for direct, For 3D-Secure number is 4314229999999913
70
+ card_exp: "01/18", # 06/18 for direct, 3D-sec is "01/18"
71
+ card_cvv: "123", # 999 for direct, 3D-sec is "123"
72
+ product_name: "Product",
73
+ product_url: "www.test.com"
74
+ }
75
+
76
+ values[:signature] = CPS.sign(user: values[:user], card_number: values[:card_number])
77
+
78
+ values[:signature_line] = '<digiSignature>' + values[:signature] + '</digiSignature>'
79
+
80
+ xml_path = "#{CPS.root}/cps.xml"
81
+ a = File.open(xml_path,'w') do |file|
82
+ file.write(%Q|<?xml version="1.0" encoding="UTF-8" ?>\n|)
83
+ file.write(%Q|<cpsxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n|)
84
+ file.write(%Q| xsi:schemaLocation="http://www.cps.lv/xml/ns/cpsxml https://3ds.cps.lv/GatorServo/Gator_SendForAuth.xsd"\n|)
85
+ file.write(%Q| xmlns="http://www.cps.lv/xml/ns/cpsxml">\n|)
86
+ file.write(%Q| <header xmlns="">\n|)
87
+ file.write(%Q| <responsetype>direct</responsetype>\n|)
88
+ file.write(%Q| <user>#{values[:user]}</user>\n|)
89
+ file.write(%Q| <type>sendForAuth</type>\n|)
90
+ file.write(%Q| <transType>DB</transType>\n|)
91
+ file.write(%Q| | + values[:signature_line] + "\n")
92
+ file.write(%Q| <callbackUrl>#{values[:callback_url]}</callbackUrl>\n|)
93
+ file.write(%Q| <redirectUrl>#{values[:redirect_url]}</redirectUrl>\n|)
94
+ file.write(%Q| </header>\n|)
95
+ file.write(%Q| <request xmlns="">\n|)
96
+ file.write(%Q| <orderNumber>#{values[:order]}</orderNumber>\n|)
97
+ file.write(%Q| <cardholder>\n|)
98
+ file.write(%Q| <firstName>#{values[:holder_name]}</firstName>\n|)
99
+ file.write(%Q| <lastName>#{values[:holder_surname]}</lastName>\n|)
100
+ file.write(%Q| <street>#{values[:holder_street]}</street>\n|)
101
+ file.write(%Q| <zip>#{values[:holder_zip]}</zip>\n|)
102
+ file.write(%Q| <city>#{values[:holder_city]}</city>\n|)
103
+ file.write(%Q| <country>#{values[:holder_country]}</country>\n|)
104
+ file.write(%Q| <email>#{values[:holder_email]}</email>\n|)
105
+ file.write(%Q| <ip>#{values[:holder_ip]}</ip>\n|)
106
+ file.write(%Q| </cardholder>\n|)
107
+ file.write(%Q| <card>\n|)
108
+ file.write(%Q| <cardNumber>#{values[:card_number]}</cardNumber>\n|)
109
+ file.write(%Q| <expires>#{values[:card_exp]}</expires>\n|)
110
+ file.write(%Q| <cvv>#{values[:card_cvv]}</cvv>\n|)
111
+ file.write(%Q| </card>\n|)
112
+ file.write(%Q| <amount>\n|)
113
+ file.write(%Q| <value>100</value>\n|)
114
+ file.write(%Q| <currency>USD</currency>\n|)
115
+ file.write(%Q| </amount>\n|)
116
+ file.write(%Q| <product>\n|)
117
+ file.write(%Q| <productName>#{values[:product_name]}</productName>\n|)
118
+ file.write(%Q| <productUrl>#{values[:product_url]}</productUrl>\n|)
119
+ file.write(%Q| </product>\n|)
120
+ file.write(%Q| </request>\n|)
121
+ file.write(%Q|</cpsxml>|)
122
+ end
123
+
124
+ return File.read(xml_path)
125
+ end
126
+
127
+ end
128
+
129
+ CPS = CompletePaymentSystems
@@ -0,0 +1,64 @@
1
+ Bag Attributes
2
+ localKeyID: 26 83 8E 91 1D 9E AD 51 06 F0 F3 FF 51 32 B8 F3 59 34 65 C7
3
+ friendlyName: pasta_test_3d
4
+ Key Attributes: <No Attributes>
5
+ -----BEGIN RSA PRIVATE KEY-----
6
+ MIICXQIBAAKBgQCbb+tyvaH9XEVqgf5yuCF79cFoRvAU9dJXq25KlMq7xAL4H0Hh
7
+ SR5tEdkQPPLOA5Xg4A68X9EjbRwkBhIpcfcxWnx7nCsZKGpKVByIicWgF8H71Psb
8
+ o9nRzehJhAw/kJMMa2KbWk9TQ8iwMwRQgBHl51eN6Y14/yNOGWRghPhhHwIDAQAB
9
+ AoGAJv3UWlwnnp7e6vDhG3YFMEtd0QK6hweDVGq0qBDbKm7pL8TnidQFxeaMRP6F
10
+ ChjsKBUMnUSL+g8M2ByNwcfM8jhCM3GDNn6wjatqq3bRC3miSFVzyRA1VO9wAAWS
11
+ gL54iwySrjWIHjZ12SS6dqSodP8fTxoIR5fFGvUuflQtSIECQQDSAdgceXG/MSmm
12
+ WC+9+JzBNMC4jjRQLYgAFDlKl4/jADo/S5qgcWmgur037PDmcy8wVcxZGUoz2IR+
13
+ lIEVLfFpAkEAvXqUvcC6MS35AJqB4eei4D24z3+8yOwdYZ8A0KZLAcQBDpnjEval
14
+ BMgxmf3oZW/4/rHOn6lZxX0SsbYIAZxlRwJAKEn8SPIvlUt8PxJ6DksM37AcLQvz
15
+ E1K43bMDjsDm9NjNU+lQP+miJxjMRldpm/yLGA3Nx2YnqyyltpcM8KBAyQJBAIes
16
+ kXr52JjEcWrUN7JZmY/1wjKaJcS9BSDUqNG+cTD3d0ZMPINkpq6w5ot8ev6/WcyN
17
+ 5wT+T3CQ6WTkkgENSpsCQQDEjzZVysbMwi/bbMU7awvy38YgmudFnowma57660vn
18
+ Y/zYHlg6TIKbvuUzKbDXtR1v6V/Oo8Fwz6WImu25RYMw
19
+ -----END RSA PRIVATE KEY-----
20
+ Bag Attributes
21
+ localKeyID: 26 83 8E 91 1D 9E AD 51 06 F0 F3 FF 51 32 B8 F3 59 34 65 C7
22
+ friendlyName: pasta_test_3d
23
+ subject=/CN=pasta_test_3d
24
+ issuer=/CN=AdminCA1/O=EJBCA Sample/C=SE
25
+ -----BEGIN CERTIFICATE-----
26
+ MIICbjCCAVagAwIBAgIIY2pN0FJ3p1EwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE
27
+ AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw
28
+ HhcNMTQwNTI4MTM1ODE0WhcNMTgwNTI3MTM1ODE0WjAYMRYwFAYDVQQDDA1wYXN0
29
+ YV90ZXN0XzNkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbb+tyvaH9XEVq
30
+ gf5yuCF79cFoRvAU9dJXq25KlMq7xAL4H0HhSR5tEdkQPPLOA5Xg4A68X9EjbRwk
31
+ BhIpcfcxWnx7nCsZKGpKVByIicWgF8H71Psbo9nRzehJhAw/kJMMa2KbWk9TQ8iw
32
+ MwRQgBHl51eN6Y14/yNOGWRghPhhHwIDAQABoyEwHzAdBgNVHQ4EFgQUJoOOkR2e
33
+ rVEG8PP/UTK481k0ZccwDQYJKoZIhvcNAQEFBQADggEBABLiKL9np1amPZTFdPNf
34
+ IU0b8d/oA7I/5jI04ze1en5GB4YkZbAeCxR9P/ox/+o32hJCYOw9Tiho7RabguA6
35
+ FC/weiJ6vt8lrdpJ+Vjcoq4pCzNOR6JFDRTNWqnJ6t+/rOQ5twXSisI86dXL3F1j
36
+ zHfaZgRMQ1sErab1G+Z3Bz0Px42M6+7unEBJuJVmsy1EuL40qSP68SXvl4uNsTua
37
+ 8MNmYneG7gvV6GxnQ/U1z6M5Z0HGwpY9lYD9f4M01UyrlDoqzxDmUwLsZX4KmSvT
38
+ SabDHwvcoxfGdV5TiKJBqpvMa9YgHBGV+F3Hei/4a14VLx4amzf2wuSbHRZ/sAYJ
39
+ cU4=
40
+ -----END CERTIFICATE-----
41
+ Bag Attributes
42
+ friendlyName: AdminCA1
43
+ subject=/CN=AdminCA1/O=EJBCA Sample/C=SE
44
+ issuer=/CN=AdminCA1/O=EJBCA Sample/C=SE
45
+ -----BEGIN CERTIFICATE-----
46
+ MIIDUzCCAjugAwIBAgIIBtGA8vEQJpgwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE
47
+ AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw
48
+ HhcNMTEwOTI5MTQwMTM3WhcNMjEwOTI2MTQwMTM3WjA3MREwDwYDVQQDDAhBZG1p
49
+ bkNBMTEVMBMGA1UECgwMRUpCQ0EgU2FtcGxlMQswCQYDVQQGEwJTRTCCASIwDQYJ
50
+ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAK+4uvaJ102AJZ4qXzhm2AnevjiAyZiv
51
+ /LOKb4W0bZ8ilUBd3wwj3ZsB7eGO33Nm2dVA9pyFs155JyJ68fqq01rzdwLD2Qh6
52
+ 3cFOTaX82xVxqGIR/l4uIEE5RvVhLIvufAomgMmWR6aPUry+aS5cTcqJHpc+QJi4
53
+ habRuMBhUh7gJ/rq0KncNiGAjM4LIAwf98hw9TYpVQkPCxaQlTLV5sxLDwbfdPC2
54
+ AHuu7QeA1LyycOGe37xGGbY3r5qiwW++jaDHuE7ZI6Lo+6xazO+rgVHbCczH5+H0
55
+ sig28UJ68MgZ+5QeUuiy8Gt/umffNABqdbCSWlh1QHxkJPWYu3qtOWMCAwEAAaNj
56
+ MGEwHQYDVR0OBBYEFEHzgvBlyUFi8+aVh/QbfFqpkENwMA8GA1UdEwEB/wQFMAMB
57
+ Af8wHwYDVR0jBBgwFoAUQfOC8GXJQWLz5pWH9Bt8WqmQQ3AwDgYDVR0PAQH/BAQD
58
+ AgGGMA0GCSqGSIb3DQEBBQUAA4IBAQA+JMYbNAgcBSmBsrEeFyCovy1gJtDe6kUP
59
+ a0E4GBpwb0yaF+9sndsfvvH1Y8kutySsThYA8cdDMAhaZ6TGcm1YhPHhI/pkuCJP
60
+ NBWpvWjaQsJ7WlYmsyZvrxig1T2369iHA5glYaC1ohxzDYlu6I1FPUK9cw+d5YtW
61
+ FiETlPQ4jTOSyIXnPVD7ymIS/PcWL76Yglrtx/OvSlAbhoqVEgXFzPADjis4hEvR
62
+ Xa1z4EC6VsVUjEadxK1eWSnRoENoarBr+zSW588cq6hq7vpXAcdNNkfrMzTcC+ew
63
+ 52cy0dLAIai1hP25ingiBOmQ3SdsbjkitfSCdqqYon1+YUkiiZ3g
64
+ -----END CERTIFICATE-----
@@ -0,0 +1,64 @@
1
+ Bag Attributes
2
+ localKeyID: 78 E3 3E D9 03 A9 EF 05 E9 E8 AF 7A 3D F9 BF 42 0B 06 81 16
3
+ friendlyName: test_pasta_sign
4
+ Key Attributes: <No Attributes>
5
+ -----BEGIN RSA PRIVATE KEY-----
6
+ MIICXAIBAAKBgQCqZS0lN3kCYEGO0+MsA9czB4EU/XsmFgxJkHnAM4DejFgdh7I6
7
+ jmOVGsUIv9U/tkQqDw6D+M/w4B+O6Oc98wR4mT5t1ahEuG/Ph+K2PUdd2x/rRH4A
8
+ QgTDj0g+6suAETIEVx6BgTbMmuikZjbAm0mfchNkJxAdj543OUB+gzmrEwIDAQAB
9
+ AoGATlUU2/cUejMl8DMYTDO3yo24mZ2t72RTYb45OlJy+9wo5epr1N+AiBs2WT9X
10
+ GWMBExS455KKhYGDAH+xTplZhBZRANepxMdFu5UlVe4Dzu9sbBQ13XuR6LmgSta2
11
+ BwK+TKoBwgIWHjAniIX5NpuOs8Ty/SdNRZshOT1BGAa0SIECQQDoSUuqvHUd3kUK
12
+ HOiWTekpoF5jWZ5KMXnXrgZr70qqlwyHCtJkFfPwHqn7NrHA1G2JgywpQQKCdthv
13
+ +2mDu1vXAkEAu8piIMU6/34TTcX7KwnLz9ry+ZjhWBXeWiA7kB5v7BD7AU4thIUK
14
+ pQfDYMn6SKu3ypihRI1Un8oRtrFBhkEjJQJBANRU47EPkjMaUZu77zQtxdwCNyWz
15
+ 7wi9DzaDYmVZmLQ1XQM4djd9Bb5SGWmEhpnQ1MwltsGDJoshnhlHBR2gr4MCQGNH
16
+ 5AkfPMnGhb4gZWGjlDUXtE1xHfHL3foYAGV5MgLEF2/hPP9Ktw34xLpvDftNjaV2
17
+ fAwaDBtOYX8Mx2+LEGECQHHAjsa6wSINc/RbVc7zhmUe7f1hAJg7Lna8x9BzfFuD
18
+ 1pxRm3dJ2uBikGmmt3kBZ3t1jDEUIsWPPf9OXNF+nPQ=
19
+ -----END RSA PRIVATE KEY-----
20
+ Bag Attributes
21
+ localKeyID: 78 E3 3E D9 03 A9 EF 05 E9 E8 AF 7A 3D F9 BF 42 0B 06 81 16
22
+ friendlyName: test_pasta_sign
23
+ subject=/CN=test_pasta_sign
24
+ issuer=/CN=AdminCA1/O=EJBCA Sample/C=SE
25
+ -----BEGIN CERTIFICATE-----
26
+ MIICcDCCAVigAwIBAgIIDWKDcl6OwJQwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE
27
+ AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw
28
+ HhcNMTMxMTAxMDg1NjI3WhcNMTcxMDMxMDg1NjI3WjAaMRgwFgYDVQQDDA90ZXN0
29
+ X3Bhc3RhX3NpZ24wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKplLSU3eQJg
30
+ QY7T4ywD1zMHgRT9eyYWDEmQecAzgN6MWB2HsjqOY5UaxQi/1T+2RCoPDoP4z/Dg
31
+ H47o5z3zBHiZPm3VqES4b8+H4rY9R13bH+tEfgBCBMOPSD7qy4ARMgRXHoGBNsya
32
+ 6KRmNsCbSZ9yE2QnEB2Pnjc5QH6DOasTAgMBAAGjITAfMB0GA1UdDgQWBBR44z7Z
33
+ A6nvBenor3o9+b9CCwaBFjANBgkqhkiG9w0BAQUFAAOCAQEAai+u5hY8g8h726VE
34
+ w46WcKs6A8KV+esGD6T5uyvyuwEkC0LPV5Ch+NvAuGAt+vAVaiwK/KHMMS1HZzf5
35
+ WWHWdyAGiP/+LsHsZoKamvMt6wuDVst74YnGG4o8UICi6gyClBnwwVpWaxTXLdSE
36
+ Bpu2bT4vSPAb9Rp2DAz7dawAm6+GJGHdxpNppJa84jFS+8MyKFhXU7L96qFVoE7V
37
+ ZKOy06hrTLsU02eH2/EljCtNMXIucpDQTqhJYZgo5GCK6IsvpUKAFblPDKuLKS5m
38
+ TdG+dY5wm4RfWclmliQ46s0umMAWVWddJWDp/tkByhVoy9gN4Jkkh3QHDmmGi2O+
39
+ JZI8zA==
40
+ -----END CERTIFICATE-----
41
+ Bag Attributes
42
+ friendlyName: AdminCA1
43
+ subject=/CN=AdminCA1/O=EJBCA Sample/C=SE
44
+ issuer=/CN=AdminCA1/O=EJBCA Sample/C=SE
45
+ -----BEGIN CERTIFICATE-----
46
+ MIIDUzCCAjugAwIBAgIIBtGA8vEQJpgwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE
47
+ AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw
48
+ HhcNMTEwOTI5MTQwMTM3WhcNMjEwOTI2MTQwMTM3WjA3MREwDwYDVQQDDAhBZG1p
49
+ bkNBMTEVMBMGA1UECgwMRUpCQ0EgU2FtcGxlMQswCQYDVQQGEwJTRTCCASIwDQYJ
50
+ KoZIhvcNAQEBBQADggEPADCCAQoCggEBAK+4uvaJ102AJZ4qXzhm2AnevjiAyZiv
51
+ /LOKb4W0bZ8ilUBd3wwj3ZsB7eGO33Nm2dVA9pyFs155JyJ68fqq01rzdwLD2Qh6
52
+ 3cFOTaX82xVxqGIR/l4uIEE5RvVhLIvufAomgMmWR6aPUry+aS5cTcqJHpc+QJi4
53
+ habRuMBhUh7gJ/rq0KncNiGAjM4LIAwf98hw9TYpVQkPCxaQlTLV5sxLDwbfdPC2
54
+ AHuu7QeA1LyycOGe37xGGbY3r5qiwW++jaDHuE7ZI6Lo+6xazO+rgVHbCczH5+H0
55
+ sig28UJ68MgZ+5QeUuiy8Gt/umffNABqdbCSWlh1QHxkJPWYu3qtOWMCAwEAAaNj
56
+ MGEwHQYDVR0OBBYEFEHzgvBlyUFi8+aVh/QbfFqpkENwMA8GA1UdEwEB/wQFMAMB
57
+ Af8wHwYDVR0jBBgwFoAUQfOC8GXJQWLz5pWH9Bt8WqmQQ3AwDgYDVR0PAQH/BAQD
58
+ AgGGMA0GCSqGSIb3DQEBBQUAA4IBAQA+JMYbNAgcBSmBsrEeFyCovy1gJtDe6kUP
59
+ a0E4GBpwb0yaF+9sndsfvvH1Y8kutySsThYA8cdDMAhaZ6TGcm1YhPHhI/pkuCJP
60
+ NBWpvWjaQsJ7WlYmsyZvrxig1T2369iHA5glYaC1ohxzDYlu6I1FPUK9cw+d5YtW
61
+ FiETlPQ4jTOSyIXnPVD7ymIS/PcWL76Yglrtx/OvSlAbhoqVEgXFzPADjis4hEvR
62
+ Xa1z4EC6VsVUjEadxK1eWSnRoENoarBr+zSW588cq6hq7vpXAcdNNkfrMzTcC+ew
63
+ 52cy0dLAIai1hP25ingiBOmQ3SdsbjkitfSCdqqYon1+YUkiiZ3g
64
+ -----END CERTIFICATE-----
@@ -0,0 +1,57 @@
1
+ Bag Attributes
2
+ friendlyName: test_sign
3
+ localKeyID: DE 64 9B C6 66 F2 11 9E E3 DB 46 60 FD 61 7A F8 E5 59 ED B6
4
+ Key Attributes: <No Attributes>
5
+ -----BEGIN RSA PRIVATE KEY-----
6
+ MIICXQIBAAKBgQCFykc5k38LoNOVVC7W/7NePhOc8qBMI5HPow5GtMZ4SSCcAjo2
7
+ V8wMrT9HYFE7EK3/w5DNKJDI4OvFOnZHCo3EkuU1tBtWyJBJTKtpXgx/HBFqKPZZ
8
+ b7z5Kh+qD93jQ1Oi8Pe9e7rq/d2gddM6/5RMXG/OowlBEqR56G1mKJ1u3QIDAQAB
9
+ AoGAIIa97CyEvZH6/pn5zUFbHTVgVU7TU89t+pn8tYnrmoDE0cjk2CNeM1LHSJYN
10
+ CZwTgVPNV2NeV8f+6fM9oCXbsywOxB3bjCGIpR5UFad9G7Q/wVIgb4ijxw0201we
11
+ 0CxtIFkYxV5wCt3fgpcnP5F8siKNEYGNEpPN182FW62/igECQQDgV5FT0JmAEUxd
12
+ ozksQOpt+2CeO44p2TYwcRB4NiiihQre+KvtDlDktlZdDGkqZGSEdBsbbNMbm/tw
13
+ isbGWv+BAkEAmKt+B5Ll0dOi1C4n0HKIZh0Ec1LT/w9jpfUYDxB/wPgJAO5VxpDR
14
+ FPQwIzDaJM/1OUiM2IhcBRG5E24VWR0dXQJBAMnEOAJHtCaIaEQ3Dq6MW8s6sHTf
15
+ X0aoAqKirYtQOk+glFxhDk+P9pUcoKPjC5qC3Bx8R/zsbRmBuixHw+qV4QECQE4o
16
+ ZWHdO1ibPx3e7zUQnXGhY1jiy3MlXr9kZUe5C54vnPRkD3eTReazSD2L0fHMoN8N
17
+ nEVyMaHKu/QNhFJVzGUCQQCNN2YJ1BkCtbDnNetxf3vmIbyfoZUpLEWH3mbt0aG1
18
+ bdVZ/NGS6lHGtgUPnrhDFehCgmL01kCEqqa80hZ7WTrf
19
+ -----END RSA PRIVATE KEY-----
20
+ Bag Attributes
21
+ friendlyName: test_sign
22
+ localKeyID: DE 64 9B C6 66 F2 11 9E E3 DB 46 60 FD 61 7A F8 E5 59 ED B6
23
+ subject=/CN=test_sign
24
+ issuer=/CN=Complete Payment Systems Certificates/O=EJBCA Production/C=SE
25
+ -----BEGIN CERTIFICATE-----
26
+ MIICCjCCAXOgAwIBAgIIb5GAi+59gAIwDQYJKoZIhvcNAQEFBQAwWDEuMCwGA1UE
27
+ AwwlQ29tcGxldGUgUGF5bWVudCBTeXN0ZW1zIENlcnRpZmljYXRlczEZMBcGA1UE
28
+ CgwQRUpCQ0EgUHJvZHVjdGlvbjELMAkGA1UEBhMCU0UwHhcNMTExMDExMDgzMTI4
29
+ WhcNMTUxMDEwMDgzMTI4WjAUMRIwEAYDVQQDDAl0ZXN0X3NpZ24wgZ8wDQYJKoZI
30
+ hvcNAQEBBQADgY0AMIGJAoGBAIXKRzmTfwug05VULtb/s14+E5zyoEwjkc+jDka0
31
+ xnhJIJwCOjZXzAytP0dgUTsQrf/DkM0okMjg68U6dkcKjcSS5TW0G1bIkElMq2le
32
+ DH8cEWoo9llvvPkqH6oP3eNDU6Lw9717uur93aB10zr/lExcb86jCUESpHnobWYo
33
+ nW7dAgMBAAGjITAfMB0GA1UdDgQWBBTeZJvGZvIRnuPbRmD9YXr45VnttjANBgkq
34
+ hkiG9w0BAQUFAAOBgQA9M8v8vjChuIdT7vWye5nQcwX5vJ3PkyJlnlKXM8bmCq5J
35
+ 9LinqdWRXYcGQBPEJ+DBIIDSKUhTSh5O6Emi8upRKIhGLiI+R3pSnxxveq7iYKlM
36
+ Xx0Kv1UKU6m5HjphAc2dhQckW0Fmdbla/Ma4wSIMnRTJBouU40xxT6YflCicXA==
37
+ -----END CERTIFICATE-----
38
+ Bag Attributes
39
+ friendlyName: Complete Payment Systems Certificates
40
+ subject=/CN=Complete Payment Systems Certificates/O=EJBCA Production/C=SE
41
+ issuer=/CN=Complete Payment Systems Certificates/O=EJBCA Production/C=SE
42
+ -----BEGIN CERTIFICATE-----
43
+ MIICkDCCAfmgAwIBAgIIQ/jnhZUMyZowDQYJKoZIhvcNAQEFBQAwWDEuMCwGA1UE
44
+ AwwlQ29tcGxldGUgUGF5bWVudCBTeXN0ZW1zIENlcnRpZmljYXRlczEZMBcGA1UE
45
+ CgwQRUpCQ0EgUHJvZHVjdGlvbjELMAkGA1UEBhMCU0UwHhcNMTEwOTI5MTQzMjU5
46
+ WhcNMzEwOTI0MTQzMjU5WjBYMS4wLAYDVQQDDCVDb21wbGV0ZSBQYXltZW50IFN5
47
+ c3RlbXMgQ2VydGlmaWNhdGVzMRkwFwYDVQQKDBBFSkJDQSBQcm9kdWN0aW9uMQsw
48
+ CQYDVQQGEwJTRTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxOJdeplgc+7/
49
+ eHpeZcY7SSwFbZOSOy6ytboP1sIq/ktRyI4fl9l49TfiREyBuDx62TRQenW0oWuG
50
+ I9CwI5YsciALG5jOPRXpXLjjdUzphpq77BT5zm4Br2fDl06gyGhs1P8AFUJEjXtx
51
+ fX4r84C9nawUQhhUNJr0sz+DBTNbqv0CAwEAAaNjMGEwHQYDVR0OBBYEFIiRA63u
52
+ UxDtZMpEFP7om6Z9+QPGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUiJED
53
+ re5TEO1kykQU/uibpn35A8YwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBBQUA
54
+ A4GBAJvCQa1j2xa0uFrOh+GxIBlKcieFnGProMJUMZSufd7KkrEzwcjpYiJp0Kuv
55
+ GCXdsW6YH1yDyT2V4ZhygwT05A3PwvPgwrqOt8gJ1pNtmw0EhakCfc8bZ6YqSiBo
56
+ qe3r+o0aiDEVwKVxuI3rA7oUiqyp9hobwu9rXGYSjREK6M1N
57
+ -----END CERTIFICATE-----
@@ -0,0 +1,103 @@
1
+ module CompletePaymentSystems
2
+ class Request
3
+
4
+ attr_reader :params, :xml
5
+
6
+ def initialize(params)
7
+ @params = params #|| File.read("#{CPS.root}/response.xml")
8
+ @xml = build_request_xml
9
+ end
10
+
11
+ def send!
12
+ response = Unirest.post CPS.config.cps_url,
13
+ #headers:{ "Accept" => "application/json" },
14
+ parameters:{ type: CPS.config.cps_method, xml: xml }
15
+
16
+ puts response.code # Status code
17
+ puts response.headers # Response headers
18
+ puts response.body # Parsed body
19
+
20
+ return "OK" if response.body.to_s.match(CPS.config.success_regex).present?
21
+ return "ERROR"
22
+ end
23
+
24
+ private
25
+ def self.sign(type: CPS.config.cps_method, user: CPS.config.default_user, order_id: , value: , currency: , card_number: , product: CPS.config.default_product_name)
26
+ sign_string = [type, user, order_id, value, currency, card_number, product].join()
27
+ rsa = OpenSSL::PKey::RSA.new(File.read(CPS.config.rsa_cert_path), CPS.config.cert_pass )
28
+ signed_hash = rsa.sign(OpenSSL::Digest::SHA1.new, sign_string)
29
+ Base64.encode64(signed_hash)
30
+ end
31
+
32
+ def build_request_xml
33
+ params = @params
34
+ values = {
35
+ user: (params["user"] || CPS.config.default_user), # "test_pasta_sign" for direct, "pasta_test_3d" for direct with 3D
36
+ callback_url: (params["callback_url"] || CPS.config.default_callback_url),
37
+ redirect_url: (params["redirect_url"] || CPS.config.default_redirect_url),
38
+ order: (params["order"] || Time.now.to_i), # TO-DO remove fallback
39
+ value: (params["value"]),
40
+ currency: (params["currency"]),
41
+ holder_name: params["holder_name"],
42
+ holder_surname: params["holder_surname"],
43
+ holder_street: (params["holder_street"] || CPS.config.placeholder_value),
44
+ holder_zip: (params["holder_zip"] || CPS.config.placeholder_value),
45
+ holder_city: (params["holder_city"] || CPS.config.placeholder_value),
46
+ holder_country: (params["holder_country"] || CPS.config.default_country),
47
+ holder_email: (params["holder_email"] || CPS.config.placeholder_value),
48
+ holder_ip: ( params["holder_ip"] ),
49
+ card_number: params["card_number"], # 4012001037167778 for direct, For 3D-Secure number is 4314229999999913
50
+ card_exp: params["card_exp"], # 06/18 for direct, 3D-sec is "01/18"
51
+ card_cvv: params["card_cvv"], # 999 for direct, 3D-sec is "123"
52
+ product_name: (params["product_name"] || CPS.config.default_product_name),
53
+ product_url: (params["product_url"] || CPS.config.default_product_url)
54
+ }
55
+
56
+ values[:signature] = CPS.sign(order_id: values[:order], value: values[:value], currency: values[:currency], card_number: values[:card_number]).gsub(/\n/, '')
57
+
58
+ values[:signature_line] = '<digiSignature>' + values[:signature] + '</digiSignature>'
59
+
60
+ xml_string = ""
61
+ xml_string = %Q|<?xml version="1.0" encoding="UTF-8" ?>\n| +
62
+ %Q|<cpsxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\n| +
63
+ %Q| xsi:schemaLocation="http://www.cps.lv/xml/ns/cpsxml https://3ds.cps.lv/GatorServo/Gator_SendForAuth.xsd"\n| +
64
+ %Q| xmlns="http://www.cps.lv/xml/ns/cpsxml">\n| +
65
+ %Q| <header xmlns="">\n| +
66
+ %Q| <responsetype>direct</responsetype>\n| +
67
+ %Q| <user>#{values[:user]}</user>\n| +
68
+ %Q| <type>sendForAuth</type>\n| +
69
+ %Q| <transType>DB</transType>\n| +
70
+ %Q| | + values[:signature_line] + "\n" +
71
+ %Q| <callbackUrl>#{values[:callback_url]}</callbackUrl>\n| +
72
+ %Q| <redirectUrl>#{values[:redirect_url]}</redirectUrl>\n| +
73
+ %Q| </header>\n| +
74
+ %Q| <request xmlns="">\n| +
75
+ %Q| <orderNumber>#{values[:order]}</orderNumber>\n| +
76
+ %Q| <cardholder>\n| +
77
+ %Q| <firstName>#{values[:holder_name]}</firstName>\n| +
78
+ %Q| <lastName>#{values[:holder_surname]}</lastName>\n| +
79
+ %Q| <street>#{values[:holder_street]}</street>\n| +
80
+ %Q| <zip>#{values[:holder_zip]}</zip>\n| +
81
+ %Q| <city>#{values[:holder_city]}</city>\n| +
82
+ %Q| <country>#{values[:holder_country]}</country>\n| +
83
+ %Q| <email>#{values[:holder_email]}</email>\n| +
84
+ %Q| <ip>#{values[:holder_ip]}</ip>\n| +
85
+ %Q| </cardholder>\n| +
86
+ %Q| <card>\n| +
87
+ %Q| <cardNumber>#{values[:card_number]}</cardNumber>\n| +
88
+ %Q| <expires>#{values[:card_exp]}</expires>\n| +
89
+ %Q| <cvv>#{values[:card_cvv]}</cvv>\n| +
90
+ %Q| </card>\n| +
91
+ %Q| <amount>\n| +
92
+ %Q| <value>#{values[:value]}</value>\n| +
93
+ %Q| <currency>#{values[:currency]}</currency>\n| +
94
+ %Q| </amount>\n| +
95
+ %Q| <product>\n| +
96
+ %Q| <productName>#{values[:product_name]}</productName>\n| +
97
+ %Q| <productUrl>#{values[:product_url]}</productUrl>\n| +
98
+ %Q| </product>\n| +
99
+ %Q| </request>\n| +
100
+ %Q|</cpsxml>|
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,57 @@
1
+ module CompletePaymentSystems
2
+ class Response
3
+
4
+ attr_reader :xml, :response_hash, :code, :message
5
+
6
+ def initialize(xml)
7
+ @xml = xml #|| File.read("#{CPS.root}/response.xml")
8
+ @response_hash = parse_response(@xml)
9
+ @code = @response_hash["resultCode"]
10
+ @message = @response_hash["resultMessage"]
11
+ end
12
+
13
+ def ok?
14
+ return signature_ok? && message.match(CPS.config.success_regex).present? && code == "000"
15
+ end
16
+
17
+ def signature_ok?
18
+ digi_signature = response_hash["digiSignature"]
19
+ hash_string = build_hashable_string
20
+ decoded_resp = Base64.decode64(digi_signature)
21
+ public_key = OpenSSL::X509::Certificate.new(
22
+ File.read "#{CPS.root}/lib/complete_payment_systems/certs/cps.cer").
23
+ public_key
24
+ return public_key.verify(OpenSSL::Digest::SHA1.new, decoded_resp, hash_string)
25
+ end
26
+
27
+ private
28
+
29
+ def parse_response xml
30
+ @response = Nokogiri::XML(xml) do |config|
31
+ config.strict.nonet
32
+ end
33
+
34
+ return {
35
+ "referenceId" => @response.xpath("//referenceId").text,
36
+ "orderId" => @response.xpath("//orderId").text,
37
+ "value" => @response.xpath("//value").text,
38
+ "currency" => @response.xpath("//currency").text,
39
+ "resultCode" => @response.xpath("//resultCode").text,
40
+ "resultMessage" => @response.xpath("//resultMessage").text, # Important
41
+ "resultText" => @response.xpath("//resultText").text, # Informative only
42
+ "digiSignature" => @response.xpath("//digiSignature").text
43
+ }
44
+ end
45
+
46
+ def build_hashable_string
47
+ rh = @response_hash
48
+ return "#{rh["referenceId"]}#{rh["orderId"]}#{rh["value"]}#{rh["currency"]}#{rh["resultCode"]}#{rh["resultMessage"]}#{rh["resultText"]}"
49
+ end
50
+
51
+ end
52
+
53
+ # def self.read_test_xml
54
+ # return File.read("#{CPS.root}/response.xml")
55
+ # end
56
+
57
+ end
@@ -0,0 +1,3 @@
1
+ module CompletePaymentSystems
2
+ VERSION = "0.0.1"
3
+ end
data/response.xml ADDED
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8" ?>
2
+ <cpsxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xsi:schemaLocation="http://www.cps.lv/xml/ns/cpsxml /GatorServo/Gator_Response.xsd"
4
+ xmlns="http://www.cps.lv/xml/ns/cpsxml">
5
+ <transData xmlns="">
6
+ <referenceId>9095359</referenceId>
7
+ <orderId>1422019383</orderId>
8
+ <amount>
9
+ <value>100</value>
10
+ <currency>USD</currency>
11
+ </amount>
12
+ </transData>
13
+ <result xmlns="">
14
+ <resultCode>000</resultCode>
15
+ <resultMessage>Captured</resultMessage>
16
+ <resultText>Captured</resultText>
17
+ <digiSignature>HlcnASe5fZyM7uVz4xwqpe9MF6+pHWXt0Fg9t5tbgmgsjLIzVZMvErzJYsZymiHEnyCbYdbAUcman8JfOP1/LnAvPAhpxz09wNsXBYJcK7YjR+Ktu2faraRfgVG0t8QTjUumk5ayTMIA/IYHvIy+2bDJgmqVQEIctl8mFdn/RyrOFFhSB2aNQwXFP1DA9Ul4c+UyDq1d5AqwGyuevKR3qFodco2DT8eO6PMpRZstecAib2Bjk5tkIY2iNRYTj7TFwtM2ASMXnbYWz82E389/AHTCBpKl4d7o6ewysPjvz4LI1pykvCJRrL10y7HGYKgoo/+JnCp9s9J4iFGx5SVqSA==</digiSignature>
18
+ </result>
19
+ </cpsxml>
@@ -0,0 +1,8 @@
1
+ require 'bundler/setup'
2
+ Bundler.setup
3
+
4
+ require "complete_payment_systems"
5
+
6
+ RSpec.configure do |config|
7
+ # some (optional) config here
8
+ end
@@ -0,0 +1,8 @@
1
+ # rspec spec/tests/request_spec.rb
2
+
3
+ describe "Test request" do
4
+ it "should be successful" do
5
+ expect(CPS.unirest).to eq "OK"
6
+ end
7
+
8
+ end
data/test.html ADDED
@@ -0,0 +1,55 @@
1
+ <html>
2
+ <head>
3
+ </head>
4
+ <body>
5
+ <form method="POST" action="https://3ds.cps.lv/GatorServo/request">
6
+ <input name="type" value="sendForAuth">
7
+ <textarea name="xml">
8
+ <?xml version="1.0" encoding="UTF-8" ?>
9
+ <cpsxml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10
+ xsi:schemaLocation="http://www.cps.lv/xml/ns/cpsxml https://3ds.cps.lv/GatorServo/Gator_SendForAuth.xsd"
11
+ xmlns="http://www.cps.lv/xml/ns/cpsxml">
12
+ <header xmlns="">
13
+ <responsetype>direct</responsetype>
14
+ <user>pasta_test_3d</user>
15
+ <type>sendForAuth</type>
16
+ <transType>DB</transType>
17
+ <digiSignature>NP+o4wK17G3tqcTF5K2vfBjXQ4RpCLEYPoK9I99/9GPQO95fD0Xp+DueUV4c
18
+ AtgNQmQg4C2BTw0vh1fme8PQanaGF50WJOTdgXdU5ygRxkjja4EyA9cDe1cq
19
+ Ex7iqtSazv2FZXu/6RfVgwcoy4SRuNuQrsDqo6/7isJ/BpgppTI=
20
+ </digiSignature>
21
+ <callbackUrl>www.google.com</callbackUrl>
22
+ <redirectUrl>http://www.google.lv</redirectUrl>
23
+ </header>
24
+ <request xmlns="">
25
+ <orderNumber>1422028510</orderNumber>
26
+ <cardholder>
27
+ <firstName>Test</firstName>
28
+ <lastName>User</lastName>
29
+ <street>NOT USED</street>
30
+ <zip>NOT USED</zip>
31
+ <city>NOT USED</city>
32
+ <country>LV</country>
33
+ <email>hi@creo.mobi</email>
34
+ <ip>123.124.125.226</ip>
35
+ </cardholder>
36
+ <card>
37
+ <cardNumber>4314229999999913</cardNumber>
38
+ <expires>01/18</expires>
39
+ <cvv>123</cvv>
40
+ </card>
41
+ <amount>
42
+ <value>100</value>
43
+ <currency>USD</currency>
44
+ </amount>
45
+ <product>
46
+ <productName>Product</productName>
47
+ <productUrl>www.test.com</productUrl>
48
+ </product>
49
+ </request>
50
+ </cpsxml>
51
+ </textarea>
52
+ <input type="submit" value="Send">
53
+ </form>
54
+ </body>
55
+ </html>
metadata ADDED
@@ -0,0 +1,153 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: complete_payment_systems
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Epigene
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-01-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: unirest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: nokogiri
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 1.6.6
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 1.6.6
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.6'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.6'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 3.1.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 3.1.0
97
+ description: Coming soon...
98
+ email:
99
+ - augusts.bautra@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - Gemfile
107
+ - LICENSE.txt
108
+ - README.md
109
+ - Rakefile
110
+ - complete_payment_systems.gemspec
111
+ - cps.xml
112
+ - lib/complete_payment_systems.rb
113
+ - lib/complete_payment_systems/certs/Pasta_test_3d.p12
114
+ - lib/complete_payment_systems/certs/Pasta_test_3d.pem
115
+ - lib/complete_payment_systems/certs/Test_pasta_sign.p12
116
+ - lib/complete_payment_systems/certs/Test_pasta_sign.pem
117
+ - lib/complete_payment_systems/certs/Test_sign.p12
118
+ - lib/complete_payment_systems/certs/Test_sign.pem
119
+ - lib/complete_payment_systems/certs/cps.cer
120
+ - lib/complete_payment_systems/request_processing.rb
121
+ - lib/complete_payment_systems/response_processing.rb
122
+ - lib/complete_payment_systems/version.rb
123
+ - response.xml
124
+ - spec/spec_helper.rb
125
+ - spec/tests/request_spec.rb
126
+ - test.html
127
+ homepage: ''
128
+ licenses:
129
+ - MIT
130
+ metadata: {}
131
+ post_install_message:
132
+ rdoc_options: []
133
+ require_paths:
134
+ - lib
135
+ required_ruby_version: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ required_rubygems_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 2.4.3
148
+ signing_key:
149
+ specification_version: 4
150
+ summary: A client for CPS (Complete Payment Systems) card payment service
151
+ test_files:
152
+ - spec/spec_helper.rb
153
+ - spec/tests/request_spec.rb