cardflex-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +125 -0
  4. data/cardflex.gemspec +14 -0
  5. data/lib/cardflex.rb +32 -0
  6. data/lib/cardflex/base_module.rb +34 -0
  7. data/lib/cardflex/configuration.rb +96 -0
  8. data/lib/cardflex/customer_vault.rb +35 -0
  9. data/lib/cardflex/customer_vault_gateway.rb +26 -0
  10. data/lib/cardflex/error_response.rb +18 -0
  11. data/lib/cardflex/errors.rb +11 -0
  12. data/lib/cardflex/gateway.rb +35 -0
  13. data/lib/cardflex/http.rb +68 -0
  14. data/lib/cardflex/plan.rb +22 -0
  15. data/lib/cardflex/plan_gateway.rb +23 -0
  16. data/lib/cardflex/subscription.rb +24 -0
  17. data/lib/cardflex/subscription_gateway.rb +22 -0
  18. data/lib/cardflex/success_response.rb +15 -0
  19. data/lib/cardflex/test/test_values.rb +26 -0
  20. data/lib/cardflex/three_step.rb +42 -0
  21. data/lib/cardflex/three_step_gateway.rb +41 -0
  22. data/lib/cardflex/transaction.rb +52 -0
  23. data/lib/cardflex/transaction_gateway.rb +23 -0
  24. data/lib/cardflex/version.rb +9 -0
  25. data/lib/cardflex/xml.rb +11 -0
  26. data/lib/cardflex/xml/parser.rb +48 -0
  27. data/lib/cardflex/xml/serializer.rb +70 -0
  28. data/lib/ssl/ca-certificates.ca.crt +4190 -0
  29. data/spec/integration/cardflex/http_spec.rb +72 -0
  30. data/spec/integration/cardflex/plan_spec.rb +24 -0
  31. data/spec/integration/cardflex/three_step_gateway_spec.rb +47 -0
  32. data/spec/integration/cardflex/three_step_spec.rb +37 -0
  33. data/spec/integration/spec_helper.rb +24 -0
  34. data/spec/spec.opts +4 -0
  35. data/spec/spec_helper.rb +45 -0
  36. data/spec/ssl/certificate.crt +21 -0
  37. data/spec/ssl/geotrust_global.crt +20 -0
  38. data/spec/ssl/private_key.pem +30 -0
  39. data/spec/unit/cardflex/base_module_spec.rb +34 -0
  40. data/spec/unit/cardflex/configuration_spec.rb +61 -0
  41. data/spec/unit/cardflex/customer_vault_gateway_spec.rb +10 -0
  42. data/spec/unit/cardflex/errors_spec.rb +8 -0
  43. data/spec/unit/cardflex/gateway_spec.rb +11 -0
  44. data/spec/unit/cardflex/http_spec.rb +18 -0
  45. data/spec/unit/cardflex/three_step_gateway_spec.rb +29 -0
  46. data/spec/unit/cardflex/xml_spec.rb +90 -0
  47. data/spec/unit/spec_helper.rb +1 -0
  48. metadata +103 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3ef2bceb03de84a741378a2761eb5bb7c6736316
4
+ data.tar.gz: afb94e6ff243cee5a76ec19051fdedb46b1dbfda
5
+ SHA512:
6
+ metadata.gz: 2169e2f0d1cbb395ad6099b5b66a74160270dc3de4a577d4189434fe85c61952b378119b4b6a59170f3f2792f715ae21877a52d596155ed5ce1b4ac81722341e
7
+ data.tar.gz: 7e894a100ca40369a959849ab5efb8fefef68d9f2e80bd1c2f11f038da2ce259fb61fd943e4ed1bac7e06434129d7a9fb7cbddf3a438385d9a66e421ced08a9f
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License (MIT)
2
+
3
+ Copyright (c) 2014 Tom King
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,125 @@
1
+ # Cardflex Ruby Client Library (Unofficial)
2
+
3
+ This gem provides client integration with the Cardflex API: https://secure.cardflexonline.com/gw/merchants/resources/integration/integration_portal.php. Currently, only the operations under the Three Step Integration are supported. This gem is supported by the community and is not associated with Cardflex.
4
+
5
+ ## Installation
6
+
7
+ ```shell
8
+ gem install cardflex-ruby
9
+ ```
10
+
11
+ Or add this line to your Gemfile:
12
+
13
+ ```ruby
14
+ gem "cardflex-ruby"
15
+ ```
16
+
17
+ And run a bundle install
18
+
19
+ ## Usage
20
+
21
+ Before you can perform any actions, you must set your api_key:
22
+
23
+ ```ruby
24
+ Cardflex::Configuration.api_key = "my_api_key"
25
+ ```
26
+
27
+ You can also change the logger (default is stdout):
28
+
29
+ ```ruby
30
+ Cardflex::Configuration.logger
31
+ ```
32
+
33
+ To start step 1 of a transaction, use the Three Step API to initiatialize the request process, and use the result to set the form URL for part 2:
34
+
35
+ ```ruby
36
+ # See Cardflex documentation for required parameters
37
+ step_one = Cardflex::ThreeStep.sale({
38
+ :redirect_url => "https://example.com",
39
+ :amount => 5.00
40
+ })
41
+
42
+ if step_one.success?
43
+ @form_url = step_one.three_step.form_url
44
+ else
45
+ @error_message = step_one.result_text
46
+ end
47
+ ```
48
+
49
+ During step 2, you will present to your users a form that will POST to Cardflex using the form_url you received from Cardflex in step 1. Then, the user will be redirected to the :redirect_url supplied in the initial request, with a token_id that you send back to Cardflex to complete the transaction in the query string:
50
+
51
+ ```ruby
52
+ token_id = params['token_id']
53
+
54
+ result = Cardflex::ThreeStep.complete(token_id)
55
+
56
+ if result.success?
57
+ # payment has been processed, send user the all clear
58
+ else
59
+ @error_message = step_one.result_text
60
+ end
61
+ ```
62
+
63
+ The library will automatically add your api key to each request. You can also access these methods via the ThreeStep API:
64
+
65
+ ```
66
+ # Transactional Methods
67
+ ThreeStep#sale
68
+ ThreeStep#credit
69
+ ThreeStep#auth
70
+ ThreeStep#offline
71
+ ThreeStep#validate
72
+
73
+ # Recurring Methods
74
+ ThreeStep#add_subscription
75
+ ThreeStep#update_subscription
76
+
77
+ # Customer Vault Methods
78
+ ThreeStep#add_customer
79
+ ThreeStep#update_customer
80
+ ThreeStep#add_billing
81
+ ThreeStep#update_billing
82
+ ```
83
+
84
+ The methods above exist for your convenience, and take care of adding the root level XML node to the request. If you want to control the full XML request, you can use this method to do it all yourself (api key is still added):
85
+
86
+ ```ruby
87
+ # Step One
88
+ Cardflex::ThreeStep.get_form_url(:sale => {
89
+ :redirect_url => "https://example.com",
90
+ :amount => 5.00
91
+ })
92
+ ```
93
+
94
+ ## Other Features
95
+
96
+ In addition to supporting the Three Step API, you can also perform a few other actions that do not involve sensitive information, and so you are freed from having to use the Three Step process:
97
+
98
+ ```
99
+ Plan#create
100
+ Subscription#delete
101
+ CustomerVault#sale
102
+ CustomerVault#credit
103
+ CustomerVault#auth
104
+ CustomerVault#offline
105
+ CustomerVault#delete_customer
106
+ CustomerVault#delete_billing
107
+ Transaction#void
108
+ Transaction#capture
109
+ Transaction#refund
110
+ ```
111
+
112
+ ## More Information
113
+
114
+ You can find all the Cardflex documentation here: https://secure.cardflexonline.com/gw/merchants/resources/integration/integration_portal.php
115
+
116
+ ## Tests
117
+
118
+ The tests run against the Cardflex API using the testing account. You will need an internet connection to run some of the tests.
119
+
120
+ ## Contributing
121
+
122
+ All pull requests that add tests, clean up the code, add features, or fix issues are welcome. Be sure to write tests for any and all changes to the code base, and make sure all tests pass before submitting.
123
+
124
+ ## License
125
+ MIT. See LICENSE file.
@@ -0,0 +1,14 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'cardflex/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "cardflex-ruby"
6
+ s.summary = "Cardflex gateway ruby client library"
7
+ s.version = Cardflex::Version::Full
8
+ s.license = "MIT"
9
+ s.author = "Tom King"
10
+ s.homepage = "https://github.com/twking7/cardflex-ruby"
11
+ s.has_rdoc = false
12
+ s.files = Dir.glob ["README.md", "LICENSE", "lib/**/*.{rb,crt}", "spec/**/*", "*.gemspec"]
13
+ s.add_dependency "builder", ">= 2.0.0"
14
+ end
@@ -0,0 +1,32 @@
1
+ # Libraries
2
+ require 'logger'
3
+ require 'net/http'
4
+ require 'net/https'
5
+
6
+ require 'builder'
7
+
8
+ # Test Values
9
+ require 'cardflex/test/test_values'
10
+
11
+ # Cardflex
12
+ require 'cardflex/version'
13
+ require 'cardflex/configuration'
14
+ require 'cardflex/errors'
15
+ require 'cardflex/xml/parser'
16
+ require 'cardflex/xml/serializer'
17
+ require 'cardflex/xml'
18
+ require 'cardflex/http'
19
+ require 'cardflex/base_module'
20
+ require 'cardflex/success_response'
21
+ require 'cardflex/error_response'
22
+ require 'cardflex/gateway'
23
+ require 'cardflex/transaction_gateway'
24
+ require 'cardflex/transaction'
25
+ require 'cardflex/plan_gateway'
26
+ require 'cardflex/plan'
27
+ require 'cardflex/subscription_gateway'
28
+ require 'cardflex/subscription'
29
+ require 'cardflex/customer_vault'
30
+ require 'cardflex/customer_vault_gateway'
31
+ require 'cardflex/three_step_gateway'
32
+ require 'cardflex/three_step'
@@ -0,0 +1,34 @@
1
+ module Cardflex
2
+ module BaseModule
3
+ module ClassMethods
4
+ def set_instance_variables_from_hash(hash)
5
+ hash.each do |k, v|
6
+ instance_variable_set("@#{k}", v)
7
+ end
8
+ end
9
+
10
+ def snakecase(str)
11
+ str.gsub('-', '_').downcase
12
+ end
13
+
14
+ # takes a module that contains constants with method names.
15
+ # create class methods using these names that add the root
16
+ # xml node to the request. these methods are just sugar
17
+ def create_helper_methods(type)
18
+ method_names = type.constants.map { |t| type.const_get(t) }
19
+
20
+ method_names.each do |name|
21
+ define_singleton_method(name) do |attributes|
22
+ yield(name => attributes)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ def self.included(base)
29
+ base.extend(self)
30
+ end
31
+
32
+ include ClassMethods
33
+ end
34
+ end
@@ -0,0 +1,96 @@
1
+ module Cardflex
2
+ class Configuration
3
+ API_VERSION = 3
4
+ SERVER = "secure.cardflexonline.com"
5
+ PORT = 443
6
+
7
+ class << self
8
+ attr_writer :logger, :api_key
9
+ end
10
+
11
+ attr_reader :api_key
12
+
13
+ def self.expectant_reader(*attributes)
14
+ attributes.each do |attribute|
15
+ (class << self; self; end).send(:define_method, attribute) do
16
+ value = instance_variable_get("@#{attribute}")
17
+ raise ConfigurationError.new(attribute.to_s, "needs to be set") unless value
18
+ value
19
+ end
20
+ end
21
+ end
22
+ expectant_reader :api_key, :environment
23
+
24
+ def initialize(options={})
25
+ [:environment, :api_key, :logger].each do |attr|
26
+ instance_variable_set("@#{attr}", options[attr])
27
+ end
28
+ end
29
+
30
+ def self.environment=(env)
31
+ unless [:development, :test, :production].include?(env)
32
+ raise ArgumentError, "#{env} is not a valid environment"
33
+ end
34
+
35
+ @environment = env
36
+ end
37
+
38
+ def self.gateway
39
+ Cardflex::Gateway.new(instantiate)
40
+ end
41
+
42
+ def self.instantiate
43
+ config = new(
44
+ :environment => @environment,
45
+ :logger => logger,
46
+ :api_key => api_key
47
+ )
48
+ end
49
+
50
+ def ca_file
51
+ File.expand_path(File.join(File.dirname(__FILE__), "..", "ssl", "ca-certificates.ca.crt"))
52
+ end
53
+
54
+ def http
55
+ Http.new(self)
56
+ end
57
+
58
+ def three_step_path
59
+ "/api/v2/three-step"
60
+ end
61
+
62
+ def server
63
+ SERVER
64
+ end
65
+
66
+ def protocol
67
+ "https"
68
+ end
69
+
70
+ def port
71
+ PORT
72
+ end
73
+
74
+ def ssl?
75
+ true
76
+ end
77
+
78
+ def api_version
79
+ API_VERSION
80
+ end
81
+
82
+ def logger
83
+ @logger ||= self.class._default_logger
84
+ end
85
+
86
+ def self.logger
87
+ @logger ||= _default_logger
88
+ end
89
+
90
+ def self._default_logger
91
+ logger = Logger.new(STDOUT)
92
+ logger.level = Logger::INFO
93
+ logger
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,35 @@
1
+ module Cardflex
2
+ class CustomerVault
3
+ include BaseModule
4
+
5
+ module Type
6
+ Sale = 'sale'
7
+ Auth = 'auth'
8
+ Credit = 'credit'
9
+ Offline = 'offline'
10
+ DeleteCustomer = 'delete_customer'
11
+ DeleteBilling = 'delete_billing'
12
+ end
13
+
14
+ attr_reader :config
15
+ attr_reader :result, :result_text, :result_code, :action_type
16
+ attr_reader :customer_vault_id
17
+ attr_reader :type, :billing, :shipping
18
+
19
+ def initialize(gateway, attributes)
20
+ @gateway = gateway
21
+ @config = gateway.config
22
+ @type = attributes[:action_type]
23
+
24
+ set_instance_variables_from_hash(attributes)
25
+ end
26
+
27
+ def self.request(attributes)
28
+ Configuration.gateway.customer_vault.request(attributes)
29
+ end
30
+
31
+ create_helper_methods(Type) do |attributes|
32
+ request(attributes)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ module Cardflex
2
+ class CustomerVaultGateway
3
+ attr_reader :config
4
+
5
+ def initialize(gateway)
6
+ @gateway = gateway
7
+ @config = gateway.config
8
+ end
9
+
10
+ def request(attributes)
11
+ root = attributes.keys[0]
12
+ raise ArgumentError, 'missing redirect_url' unless attributes[root][:redirect_url]
13
+ raise ArgumentError, 'missing customer_vault_id' unless attributes[root][:customer_vault_id]
14
+
15
+ @config.http.post(attributes)
16
+ end
17
+
18
+ def _handle_response(res)
19
+ if res[:response][:result] == '1'
20
+ SuccessResponse.new(:customer_vault => CustomerVault.new(@gateway, res[:response]))
21
+ else
22
+ ErrorResponse.new(@gateway, res[:response])
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ module Cardflex
2
+ class ErrorResponse
3
+ include BaseModule
4
+
5
+ attr_reader :result, :result_code, :result_text
6
+
7
+ def initialize(gateway, hash={})
8
+ @gateway = gateway
9
+ @result = hash[:result].to_i
10
+ @result_code = hash[:result_code]
11
+ @result_text = hash[:result_text]
12
+ end
13
+
14
+ def success?
15
+ false
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,11 @@
1
+ module Cardflex
2
+ class CardflexError < ::StandardError; end
3
+
4
+ class ConfigurationError < CardflexError
5
+ def initialize(setting, message)
6
+ super "Cardflex::Configuration.#{setting} #{message}"
7
+ end
8
+ end
9
+
10
+ class SSLCertificateError < CardflexError; end
11
+ end
@@ -0,0 +1,35 @@
1
+ module Cardflex
2
+ class Gateway
3
+ attr_reader :config
4
+
5
+ def initialize(config)
6
+ if config.is_a? Hash
7
+ @config = Configuration.new(config)
8
+ elsif config.is_a? Configuration
9
+ @config = config
10
+ else
11
+ raise ArgumentError, "config is an invalid type"
12
+ end
13
+ end
14
+
15
+ def transaction
16
+ TransactionGateway.new(self)
17
+ end
18
+
19
+ def plan
20
+ PlanGateway.new(self)
21
+ end
22
+
23
+ def three_step
24
+ ThreeStepGateway.new(self)
25
+ end
26
+
27
+ def customer_vault
28
+ CustomerVaultGateway.new(self)
29
+ end
30
+
31
+ def subscription
32
+ SubscriptionGateway.new(self)
33
+ end
34
+ end
35
+ end