rocketgate-ruby 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e174cdc0ab9153dd12a64e537d7f49da9e44b49d
4
+ data.tar.gz: 64b9018aa9f8c1266aa234e638c18772a563d147
5
+ SHA512:
6
+ metadata.gz: a1cbd4b6a8ebc773c8c3847ad26619e69624fd268703ff23f741b6b2440be5fe919605db38dafd7c51eef12cfb177e80af48e008aa0e74458b4d3bd29778bb8c
7
+ data.tar.gz: 3c1695751188219814e250c6966ee38052205fbfaf79c82dc91ffe95f485def41eb263c8bc3c9bc2e4aaba7f61c271e7986cc5f03e6fadf2983621a93179d100
@@ -0,0 +1 @@
1
+ service_name: travis-ci
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
@@ -0,0 +1,20 @@
1
+ language: ruby
2
+ cache: bundler
3
+
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.1
8
+ - jruby-19mode
9
+ - jruby-head
10
+ - rbx-2
11
+ - ruby-head
12
+
13
+ script: 'bundle exec rake'
14
+
15
+ notifications:
16
+ email:
17
+ recipients:
18
+ - ccashwell@gmail.com
19
+ on_failure: change
20
+ on_success: never
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,11 @@
1
+ guard 'rspec' do
2
+ # watch /lib/ files
3
+ watch(%r{^lib/(.+).rb$}) do |m|
4
+ "spec/#{m[1]}_spec.rb"
5
+ end
6
+
7
+ # watch /spec/ files
8
+ watch(%r{^spec/(.+).rb$}) do |m|
9
+ "spec/#{m[1]}.rb"
10
+ end
11
+ end
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Chris Cashwell
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.
@@ -0,0 +1,161 @@
1
+ # rocketgate-ruby
2
+
3
+ [![Build Status](https://travis-ci.org/ccashwell/rocketgate-ruby.svg?branch=master)](https://travis-ci.org/ccashwell/rocketgate-ruby)
4
+ [![Coverage Status](https://coveralls.io/repos/ccashwell/rocketgate-ruby/badge.png)](https://coveralls.io/r/ccashwell/rocketgate-ruby)
5
+ [![Code Climate](https://codeclimate.com/github/ccashwell/rocketgate-ruby/badges/gpa.svg)](https://codeclimate.com/github/ccashwell/rocketgate-ruby)
6
+
7
+ RocketGate's Payment Gateway, minus the painful integration.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ ```ruby
14
+ gem 'rocketgate-ruby'
15
+ ```
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ Or install it yourself as:
22
+
23
+ $ gem install rocketgate-ruby
24
+
25
+ ## Usage
26
+
27
+ ### Configuration
28
+
29
+ Before you can jump in, you need to configure the gem with your RocketGate credentials:
30
+
31
+ ```ruby
32
+ RocketGate.configure do |config|
33
+ config.merchant_id = 'rocketgate_merchant_id'
34
+ config.merchant_password = 'rocketgate_merchant_password'
35
+ end
36
+ ```
37
+
38
+ You can also supply other configuration settings:
39
+
40
+ ```ruby
41
+ RocketGate.configure do |config|
42
+ config.merchant_id = 'rocketgate_merchant_id'
43
+ config.merchant_password = 'rocketgate_merchant_password'
44
+ config.currency = 'USD'
45
+ config.request_host = 'special-gateway.rocketgate.com'
46
+ config.request_path = '/specialServlet'
47
+ config.request_port = 8080
48
+ config.request_timeout = 5
49
+ config.request_version = 'R2.0'
50
+ config.require_avs = false
51
+ config.require_cvv = false
52
+ config.require_scrub = false
53
+ config.require_ssl = false
54
+ end
55
+ ```
56
+
57
+ And if you want to test something against the sandbox gateway:
58
+
59
+ ```ruby
60
+ RocketGate.configuration.testing!
61
+ ```
62
+
63
+ ### Making an Authorization Request
64
+
65
+ In order to get an authorization, you'll need to send a request to the gateway.
66
+
67
+ 1. Build a [`Customer`](https://github.com/ccashwell/rocketgate-ruby/blob/master/lib/rocketgate/customer.rb) and [`CreditCard`](https://github.com/ccashwell/rocketgate-ruby/blob/master/lib/rocketgate/credit_card.rb) so we know who and how to charge:
68
+
69
+ ```ruby
70
+ customer = RocketGate::Customer.new('John', 'Doe', '123 Main St', 'Beverly Hills', 'CA', '90210')
71
+ credit_card = RocketGate::CreditCard.new('4111-1111-1111-1111', '08', '2042', '012')
72
+ ```
73
+
74
+ 1. Build a [`Transaction`](https://github.com/ccashwell/rocketgate-ruby/blob/master/lib/rocketgate/transaction.rb)
75
+
76
+ ```ruby
77
+ transaction = RocketGate::Transaction.new(9.99, customer, credit_card)
78
+ ```
79
+
80
+ 1. Set the transaction type
81
+
82
+ ```ruby
83
+ transaction.type = RocketGate::Transaction::TYPE[:purchase]
84
+ ```
85
+
86
+ 1. Optionally, add an identifier that ties the transaction and customer to something relevant for you, like a `User` or `Invoice`. (A UUID will be generated if not.)
87
+
88
+ ```ruby
89
+ credit_card.id = User.id
90
+ transaction.id = Invoice.id
91
+ ```
92
+
93
+ 1. Build a [`Request`](https://github.com/ccashwell/rocketgate-ruby/blob/master/lib/rocketgate/request.rb)
94
+
95
+ ```ruby
96
+ request = RocketGate::Request.new(transaction)
97
+ ```
98
+
99
+ 1. Send the request to the gateway
100
+
101
+ ```ruby
102
+ response = RocketGate.send_request!(request)
103
+ ```
104
+
105
+ 1. Check the [`Response`](https://github.com/ccashwell/rocketgate-ruby/blob/master/lib/rocketgate/response.rb)
106
+
107
+ ```ruby
108
+ response.authorized? # => true (authorization OK)
109
+ response.success? # => true (authorization + gateway response OK)
110
+ ```
111
+
112
+ 1. Confirm receipt of the transaction response (**Note: RocketGate will cancel your transaction if you don't confirm it!**)
113
+
114
+ ```ruby
115
+ response.confirm! # => returns a Response like the original request
116
+ ```
117
+
118
+ ### Authorizations
119
+
120
+ In the section above you created and sent a request, then looked at the response. The response's [`Authorization`](https://github.com/ccashwell/rocketgate-ruby/blob/master/lib/rocketgate/authorization.rb) has lots of great information, too.
121
+
122
+ ```ruby
123
+ authorization = response.authorization
124
+
125
+ authorization.avs_ok? # => AVS check OK or disabled
126
+ authorization.cvv_ok? # => CVV check OK or disabled
127
+ authorization.success? # => AVS check + CVV check + reason code OK
128
+ authorization.declined? # => opposite of success?
129
+ authorization.auth_code # => authorization code from gateway, may be blank
130
+ authorization.reason_code # => descriptive(ish) reason for the response
131
+ authorization.approved_amount # => dollar amount of authorization (should match transaction)
132
+ authorization.approved_currency # => currency the authorization settled in (should match transaction)
133
+ authorization.card_hash # => unique hash of the card data which can be used later
134
+ authorization.card_expiration # => 4-digit representation of the card expiration
135
+ authorization.card_last_four # => the last four digits of the card charged
136
+ authorization.reference_id # => unique reference ID used to confirm, void or reverse the request
137
+ ```
138
+
139
+ ## Not Yet Implemented (Future Plans)
140
+
141
+ - Rebill functionality
142
+
143
+ ## Compatibility
144
+
145
+ This library supports Ruby >= 1.9.3 on a variety of platforms.
146
+
147
+ [Travis CI](https://travis-ci.org/ccashwell/rocketgate-ruby) builds every commit under [these environments](https://github.com/ccashwell/rocketgate-ruby/blob/master/.travis.yml):
148
+
149
+ - MRI 1.9.3, 2.0.0, 2.1.1 and HEAD
150
+ - JRuby 1.7.11 (1.9 mode) and HEAD
151
+ - Rubinius 2.2.1
152
+
153
+ Other interpreters and earlier versions of MRI, JRuby and RBX are not supported.
154
+
155
+ ## Contributing
156
+
157
+ 1. Fork it ( https://github.com/ccashwell/rocketgate-ruby/fork )
158
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
159
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
160
+ 4. Push to the branch (`git push origin my-new-feature`)
161
+ 5. Create a new Pull Request
@@ -0,0 +1,14 @@
1
+ require 'rspec/core/rake_task'
2
+ require 'bundler/gem_tasks'
3
+
4
+ # Default directory to look in is `/specs`
5
+ # Run with `rake spec`
6
+ RSpec::Core::RakeTask.new(:spec) do |task|
7
+ task.rspec_opts = ['--color', '--format', 'documentation', '--tag', '~integration']
8
+ end
9
+
10
+ RSpec::Core::RakeTask.new(:integration) do |task|
11
+ task.rspec_opts = ['--color', '--format', 'documentation', '--tag', 'integration']
12
+ end
13
+
14
+ task :default => :spec
@@ -0,0 +1,52 @@
1
+ module RocketGate
2
+ autoload :VERSION, 'rocketgate/version'
3
+
4
+ autoload :Authorization, 'rocketgate/authorization'
5
+ autoload :Configuration, 'rocketgate/configuration'
6
+ autoload :Connection, 'rocketgate/connection'
7
+ autoload :CreditCard, 'rocketgate/credit_card'
8
+ autoload :Customer, 'rocketgate/customer'
9
+ autoload :Request, 'rocketgate/request'
10
+ autoload :Response, 'rocketgate/response'
11
+ autoload :ResponseCode, 'rocketgate/response_code'
12
+ autoload :Transaction, 'rocketgate/transaction'
13
+
14
+ autoload :Hashable, 'rocketgate/hashable'
15
+ autoload :Validatable, 'rocketgate/validatable'
16
+
17
+ AuthorizationError = Class.new(StandardError)
18
+ ValidationError = Class.new(StandardError)
19
+ GatewayRequestError = Class.new(StandardError)
20
+ GatewayResponseError = Class.new(StandardError)
21
+
22
+ class << self
23
+ def configuration
24
+ @configuration ||= Configuration.new
25
+ end
26
+
27
+ def configure
28
+ yield(configuration)
29
+ end
30
+
31
+ def connection
32
+ configuration.validate!
33
+ @connection ||= Connection.new(configuration.request_host,
34
+ configuration.request_port,
35
+ configuration.request_path)
36
+ end
37
+
38
+ def reset!
39
+ @configuration, @connection = nil, nil
40
+ end
41
+
42
+ def send_request!(request)
43
+ response = connection.make_request!(request.build_gateway_request)
44
+
45
+ if response.code.to_i == 200
46
+ return Response.from_xml(response.body)
47
+ else
48
+ raise GatewayRequestError.new("Unexpected status code in gateway response: #{response.code}")
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,31 @@
1
+ module RocketGate
2
+ class Authorization
3
+ attr_accessor :auth_code, :avs_response, :cvv_response, :reason_code,
4
+ :approved_amount, :approved_currency, :card_hash,
5
+ :card_expiration, :card_last_four, :reference_id
6
+
7
+ def avs_ok?
8
+ if RocketGate.configuration.require_avs
9
+ RocketGate::ResponseCode::AVS_SUCCESSES.include?(avs_response)
10
+ else
11
+ true
12
+ end
13
+ end
14
+
15
+ def cvv_ok?
16
+ if RocketGate.configuration.require_cvv
17
+ RocketGate::ResponseCode::CVV_SUCCESSES.include?(cvv_response)
18
+ else
19
+ true
20
+ end
21
+ end
22
+
23
+ def declined?
24
+ !success?
25
+ end
26
+
27
+ def success?
28
+ avs_ok? && cvv_ok? && reason_code == :success
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,53 @@
1
+ module RocketGate
2
+ class Configuration
3
+ include Validatable
4
+
5
+ attr_accessor :currency,
6
+ :merchant_id,
7
+ :merchant_password,
8
+ :request_timeout,
9
+ :request_host,
10
+ :request_path,
11
+ :request_port,
12
+ :request_version,
13
+ :require_avs,
14
+ :require_cvv,
15
+ :require_scrub,
16
+ :require_ssl
17
+
18
+ validatable :currency, :merchant_id, :merchant_password, :request_host,
19
+ :request_path, :request_port, :request_timeout, :request_version,
20
+ :require_avs, :require_cvv, :require_scrub, :require_ssl
21
+
22
+ GATEWAY_LIVE_HOST = 'gw-16.rocketgate.com'
23
+ GATEWAY_TEST_HOST = 'dev-gw.rocketgate.com'
24
+ GATEWAY_PORT = 443
25
+ GATEWAY_SERVLET = '/gateway/servlet/ServiceDispatcherAccess'
26
+ GATEWAY_VERSION = 'R1.2'
27
+ DEFAULT_TIMEOUT = 10
28
+ DEFAULT_CURRENCY = 'USD'
29
+ USER_AGENT_STRING = "rocketgate-ruby/#{RocketGate::VERSION}"
30
+
31
+ def initialize
32
+ @currency = DEFAULT_CURRENCY
33
+ @request_host = GATEWAY_LIVE_HOST
34
+ @request_path = GATEWAY_SERVLET
35
+ @request_port = GATEWAY_PORT
36
+ @request_timeout = DEFAULT_TIMEOUT
37
+ @request_version = GATEWAY_VERSION
38
+ @require_avs = true
39
+ @require_cvv = true
40
+ @require_scrub = true
41
+ @require_ssl = true
42
+ end
43
+
44
+ def testing!
45
+ @request_host = GATEWAY_TEST_HOST
46
+ @request_port = GATEWAY_PORT
47
+ @merchant_id = '1'
48
+ @merchant_password = 'testpassword'
49
+
50
+ self
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,30 @@
1
+ require 'net/http'
2
+
3
+ module RocketGate
4
+ class Connection
5
+ def initialize(server, port, path)
6
+ @server, @port, @path = server, port, path
7
+ @client = Net::HTTP.new(server, port)
8
+
9
+ @client.open_timeout = RocketGate.configuration.request_timeout
10
+ @client.read_timeout = RocketGate.configuration.request_timeout
11
+
12
+ if RocketGate.configuration.require_ssl
13
+ @client.use_ssl = true
14
+ @client.verify_mode = OpenSSL::SSL::VERIFY_NONE
15
+ end
16
+ end
17
+
18
+ def make_request!(request_body)
19
+ request = Net::HTTP::Post.new(@path, {
20
+ 'Accept' => 'text/xml',
21
+ 'Content-Type' => 'text/xml',
22
+ 'User-Agent' => "rocketgate-ruby/#{RocketGate::VERSION}"
23
+ })
24
+
25
+ request.body = request_body
26
+
27
+ @client.request(request)
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,42 @@
1
+ module RocketGate
2
+ class CreditCard
3
+ include Hashable, Validatable
4
+
5
+ attr_accessor :cvv, :exp_month, :exp_year, :number, :card_hash
6
+
7
+ validatable :number, :exp_month, :exp_year
8
+
9
+ hashable({
10
+ cardNo: :number,
11
+ expireMonth: :exp_month,
12
+ expireYear: :exp_year,
13
+ cvv2: :cvv
14
+ })
15
+
16
+ def initialize(*args)
17
+ @number, @exp_month, @exp_year, @cvv = *args
18
+
19
+ clean_number! if @number
20
+ end
21
+
22
+ def self.from_card_hash(card_hash)
23
+ new.tap do |cc|
24
+ cc.card_hash = card_hash
25
+ end
26
+ end
27
+
28
+ def to_hash
29
+ card_hash ? { cardHash: card_hash } : super
30
+ end
31
+
32
+ def valid?
33
+ !card_hash.nil? || super
34
+ end
35
+
36
+ private
37
+
38
+ def clean_number!
39
+ @number.delete!("^0-9")
40
+ end
41
+ end
42
+ end