arrow_payments 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. data/.gitignore +25 -0
  2. data/.rspec +2 -0
  3. data/.travis.yml +3 -0
  4. data/Gemfile +3 -0
  5. data/README.md +272 -0
  6. data/Rakefile +10 -0
  7. data/arrow_payments.gemspec +25 -0
  8. data/lib/arrow_payments.rb +25 -0
  9. data/lib/arrow_payments/address.rb +11 -0
  10. data/lib/arrow_payments/client.rb +57 -0
  11. data/lib/arrow_payments/client/customers.rb +45 -0
  12. data/lib/arrow_payments/client/payment_methods.rb +90 -0
  13. data/lib/arrow_payments/client/transactions.rb +64 -0
  14. data/lib/arrow_payments/configuration.rb +7 -0
  15. data/lib/arrow_payments/connection.rb +78 -0
  16. data/lib/arrow_payments/customer.rb +38 -0
  17. data/lib/arrow_payments/entity.rb +39 -0
  18. data/lib/arrow_payments/errors.rb +13 -0
  19. data/lib/arrow_payments/line_item.rb +10 -0
  20. data/lib/arrow_payments/payment_method.rb +19 -0
  21. data/lib/arrow_payments/recurring_billing.rb +30 -0
  22. data/lib/arrow_payments/transaction.rb +74 -0
  23. data/lib/arrow_payments/version.rb +3 -0
  24. data/spec/arrow_payments_spec.rb +40 -0
  25. data/spec/client_spec.rb +42 -0
  26. data/spec/configuration_spec.rb +24 -0
  27. data/spec/customer_spec.rb +29 -0
  28. data/spec/customers_spec.rb +160 -0
  29. data/spec/entity_spec.rb +55 -0
  30. data/spec/fixtures/complete_payment_method.json +37 -0
  31. data/spec/fixtures/customer.json +25 -0
  32. data/spec/fixtures/customers.json +133 -0
  33. data/spec/fixtures/headers/payment_method_complete.yml +9 -0
  34. data/spec/fixtures/headers/payment_method_start.yml +9 -0
  35. data/spec/fixtures/line_item.json +8 -0
  36. data/spec/fixtures/start_payment_method.json +6 -0
  37. data/spec/fixtures/transaction.json +29 -0
  38. data/spec/fixtures/transaction_capture.json +5 -0
  39. data/spec/fixtures/transactions.json +68 -0
  40. data/spec/line_item_spec.rb +17 -0
  41. data/spec/payment_method_spec.rb +16 -0
  42. data/spec/payment_methods_spec.rb +181 -0
  43. data/spec/recurring_billing_spec.rb +28 -0
  44. data/spec/spec_helper.rb +19 -0
  45. data/spec/transactions_spec.rb +101 -0
  46. metadata +225 -0
data/.gitignore ADDED
@@ -0,0 +1,25 @@
1
+ *.gem
2
+ *.rbc
3
+ *.swp
4
+ *.tmproj
5
+ *~
6
+ .DS_Store
7
+ .\#*
8
+ .bundle
9
+ .config
10
+ .yardoc
11
+ Gemfile.lock
12
+ InstalledFiles
13
+ \#*
14
+ _yardoc
15
+ coverage
16
+ doc/
17
+ lib/bundler/man
18
+ pkg
19
+ rdoc
20
+ spec/reports
21
+ test/tmp
22
+ test/version_tmp
23
+ tmp
24
+ tmtags
25
+ lib/test.rb
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format=nested
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ rvm:
2
+ - 1.9.2
3
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # ArrowPayments
2
+
3
+ Ruby wrapper for Arrow Payments gateway
4
+
5
+ **Under Development**
6
+
7
+ ## Installation
8
+
9
+ In your Gemfile add a line:
10
+
11
+ ```
12
+ gem 'arrow_payments', :github => 'sosedoff/arrow_payments'
13
+ ```
14
+
15
+ ## Configuration
16
+
17
+ To configure gateway globally, add an initializer with the following:
18
+
19
+ ```ruby
20
+ ArrowPayments::Configuration.api_key = 'foo'
21
+ ArrowPayments::Configuration.mode = 'production'
22
+ ArrowPayments::Configuration.merchant_id = '1231231'
23
+ ```
24
+
25
+ Another way is to configure on the instance level:
26
+
27
+ ```ruby
28
+ client = ArrowPayments::Client.new(
29
+ :api_key => 'foo',
30
+ :mode => 'production',
31
+ :merchant_id => '123451',
32
+ :debug => true
33
+ )
34
+ ```
35
+
36
+ A set of helper methods:
37
+
38
+ ```ruby
39
+ client.production? # => true
40
+ client.sandbox? # => false
41
+ client.debug? # => true
42
+ ```
43
+
44
+ ## Usage
45
+
46
+ Check the **API reference** section for objects details.
47
+
48
+ Initialize a new client:
49
+
50
+ ```ruby
51
+ client = ArrowPayments::Client.new(
52
+ :api_key => 'foo',
53
+ :mode => 'sandbox',
54
+ :merchant_id => '12345'
55
+ )
56
+ ```
57
+
58
+ ### Customers
59
+
60
+ ```ruby
61
+ # Get all customers.
62
+ # Does not include recurring billings and payment methods.
63
+ client.customers # => [Customer, ...]
64
+
65
+ # Get customer details.
66
+ # Returns nil if not found
67
+ client.customer('12345')
68
+
69
+ # Create a new customer.
70
+ # Raises ArrowPayments::Error if unable to create.
71
+ customer = client.create_customer(
72
+ :name => 'John Doe',
73
+ :contact => 'John Doe',
74
+ :code => 'JOHN',
75
+ :email => 'john@doe.com',
76
+ :phone => '(123) 123-12-12'
77
+ )
78
+
79
+ # Update an existing customer
80
+ customer = client.customer('12345')
81
+ customer.name = 'Foo Bar'
82
+ client.update_customer(customer) # => true
83
+
84
+ # Delete an existing customer
85
+ client.delete_customer('12345') # => true
86
+ ```
87
+
88
+ ### Payment Methods
89
+
90
+ Example: Add a new payment method to an existing customer
91
+
92
+ ```ruby
93
+ client_id = '12345'
94
+
95
+ # Initialize a new billing address instance
96
+ address = ArrowPayments::Address.new(
97
+ :address => 'Some Street',
98
+ :address2 => 'Apt 1',
99
+ :city => 'Chicago',
100
+ :state => 'IL',
101
+ :zip => '60657',
102
+ :phone => '123123123'
103
+ )
104
+
105
+ # Initialize a new payment method instance
106
+ cc = ArrowPayments::PaymentMethod.new(
107
+ :first_name => 'John',
108
+ :last_name => 'Doe',
109
+ :number => '4111111111111111',
110
+ :security_code => '123',
111
+ :expiration_month => 12,
112
+ :expiration_year => 14
113
+ )
114
+
115
+ # Step 1: Provide payment method customer and billing address
116
+ url = client.start_payment_method(customer_id, address)
117
+
118
+ # Step 2: Add credit card information
119
+ token = client.setup_payment_method(url, cc)
120
+
121
+ # Step 3: Finalize payment method creation
122
+ cc = client.complete_payment_methodtoken)
123
+
124
+ # Delete an existing payment method
125
+ client.delete_payment_method('123456') # => true
126
+ ```
127
+
128
+ You can also create a payment method using a wrapper method:
129
+
130
+ ```ruby
131
+ address = ArrowPayments::Address.new( ... data ... )
132
+ cc = ArrowPayments::PaymentMethod.new( ... data ... )
133
+
134
+ # Returns a new PaymentMethod instance or raises errors
135
+ client.create_payment_method(customer_id, address, cc)
136
+ ```
137
+
138
+ ### Transactions
139
+
140
+ ```ruby
141
+ # Get list of transactions by customer.
142
+ # Only unsettled transactions will be returns as ArrowPayments does not support
143
+ # any other filters for now
144
+ client.transactions('12345')
145
+
146
+ # Get a single transaction details.
147
+ # Raises ArrowPayments::NotFound if not found
148
+ client.transaction('45678')
149
+
150
+ # Capture a transaction for a specified amount.
151
+ # Returns success result or raises ArrowPayments::Error exception
152
+ client.capture_transaction('45678', 123.00)
153
+
154
+ # Void an existing unsettled transaction
155
+ # Returns a success result or raises ArrowPayments::NotFound if not found
156
+ client.void_transaction('45678')
157
+
158
+ # Create a new transaction for an existing custromer and payment method.
159
+ # Returns a new Transaction instance if request was successfull, otherwise
160
+ # raises ArrowPayments::Error exception with error message.
161
+ transaction = client.create_transaction(
162
+ :customer_id => 'Customer ID',
163
+ :payment_method_id => 'Payment Method ID',
164
+ :transaction_type => 'sale',
165
+ :total_amount => 250,
166
+ :tax_amount => 0,
167
+ :shipping_amount => 0
168
+ )
169
+ ```
170
+
171
+ ## Reference
172
+
173
+ List of all gateway errors:
174
+
175
+ - `ArrowPayments::Error` - Raised on invalid data. Generic error.
176
+ - `ArrowPayments::NotFound` - Raised on invalid API token or non-existing object
177
+ - `ArrowPayments::NotImplemented` - Raised when API endpoint is not implemented
178
+
179
+ List of all gateway objects:
180
+
181
+ - `Customer` - Gateway customer object
182
+ - `PaymentMethod` - Gateway payment method (credit card) object
183
+ - `Transaction` - Contains all information about transaction
184
+ - `Address` - User for shipping and billing addresses
185
+ - `LineItem` - Contains information about transaction item
186
+
187
+ ### Address
188
+
189
+ - `address`
190
+ - `address2`
191
+ - `city`
192
+ - `state`
193
+ - `zip`
194
+ - `phone`
195
+ - `tag`
196
+
197
+ ### Customer
198
+
199
+ - `id`
200
+ - `name`
201
+ - `code`
202
+ - `contact`
203
+ - `phone`
204
+ - `email`
205
+ - `recurring_billings` - Array of `RecurringBilling` instances if any
206
+ - `payment_methods` - Array of PaymentMethod instances if any
207
+
208
+ ### PaymentMethod
209
+
210
+ - `id`
211
+ - `card_type`
212
+ - `last_digits`
213
+ - `first_name`
214
+ - `last_name`
215
+ - `expiration_month`
216
+ - `expiration_year`
217
+ - `address`
218
+ - `address2`
219
+ - `city`
220
+ - `state`
221
+ - `zip`
222
+
223
+ ### LineItem
224
+
225
+ - `id`
226
+ - `commodity_code`
227
+ - `description`
228
+ - `price`
229
+ - `product_code`
230
+ - `unit_of_measure`
231
+
232
+ ### Transaction
233
+
234
+ - `id`
235
+ - `account`
236
+ - `transaction_type`
237
+ - `created_at` - A `DateTime` object of creation
238
+ - `level`
239
+ - `total_amount`
240
+ - `description`
241
+ - `transaction_source`
242
+ - `status` - One of `NotSettled`, `Settled`, `Voided`, `Failed`
243
+ - `capture_amount`
244
+ - `authorization_code`
245
+ - `payment_method_id`
246
+ - `cardholder_first_name`
247
+ - `cardholder_last_name`
248
+ - `card_type`
249
+ - `card_last_digits`
250
+ - `customer_po_number`
251
+ - `tax_amount`
252
+ - `shipping_amount`
253
+ - `shipping_address_id`
254
+ - `shipping_address`
255
+ - `customer_id`
256
+ - `customer_name`
257
+ - `line_items`
258
+ - `billing_address`
259
+
260
+ ## Testing
261
+
262
+ To run a test suite:
263
+
264
+ ```
265
+ rake test
266
+ ```
267
+
268
+ ## TODO
269
+
270
+ There are multiple features that are pending implementation:
271
+
272
+ - Filter transactions by status
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require 'bundler'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:test) do |t|
6
+ t.pattern = 'spec/*_spec.rb'
7
+ t.verbose = false
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,25 @@
1
+ require File.expand_path('../lib/arrow_payments/version', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "arrow_payments"
5
+ s.version = ArrowPayments::VERSION.dup
6
+ s.summary = "Ruby wrapper for ArrowPayments gateway"
7
+ s.description = "Ruby wrapper for ArrowPayments gateway"
8
+ s.homepage = "http://github.com/sosedoff/arrow_payments"
9
+ s.authors = ["Dan Sosedoff"]
10
+ s.email = ["dan.sosedoff@gmail.com"]
11
+
12
+ s.add_development_dependency 'webmock', '~> 1.6'
13
+ s.add_development_dependency 'rake', '~> 0.9'
14
+ s.add_development_dependency 'rspec', '~> 2.12'
15
+
16
+ s.add_runtime_dependency 'faraday', '~> 0.8'
17
+ s.add_runtime_dependency 'faraday_middleware', '~> 0.8'
18
+ s.add_runtime_dependency 'hashie', '~> 2.0'
19
+ s.add_runtime_dependency 'json', '~> 1.7'
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
24
+ s.require_paths = ["lib"]
25
+ end
@@ -0,0 +1,25 @@
1
+ require 'arrow_payments/version'
2
+ require 'arrow_payments/errors'
3
+
4
+ module ArrowPayments
5
+ autoload :Configuration, 'arrow_payments/configuration'
6
+ autoload :Entity, 'arrow_payments/entity'
7
+ autoload :Customer, 'arrow_payments/customer'
8
+ autoload :PaymentMethod, 'arrow_payments/payment_method'
9
+ autoload :RecurringBilling, 'arrow_payments/recurring_billing'
10
+ autoload :Transaction, 'arrow_payments/transaction'
11
+ autoload :Address, 'arrow_payments/address'
12
+ autoload :LineItem, 'arrow_payments/line_item'
13
+ autoload :Connection, 'arrow_payments/connection'
14
+ autoload :Client, 'arrow_payments/client'
15
+
16
+ autoload :Customers, 'arrow_payments/client/customers'
17
+ autoload :PaymentMethods, 'arrow_payments/client/payment_methods'
18
+ autoload :Transactions, 'arrow_payments/client/transactions'
19
+
20
+ class << self
21
+ def client(options={})
22
+ ArrowPayments::Client.new(options)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,11 @@
1
+ module ArrowPayments
2
+ class Address < Entity
3
+ property :address, :from => 'Address1'
4
+ property :address2, :from => 'Address2'
5
+ property :city, :from => 'City'
6
+ property :state, :from => 'State'
7
+ property :zip, :from => 'Postal'
8
+ property :phone, :from => 'Phone'
9
+ property :tag, :from => 'Tag'
10
+ end
11
+ end
@@ -0,0 +1,57 @@
1
+ module ArrowPayments
2
+ class Client
3
+ include ArrowPayments::Connection
4
+ include ArrowPayments::Customers
5
+ include ArrowPayments::PaymentMethods
6
+ include ArrowPayments::Transactions
7
+
8
+ attr_reader :api_key, :mode, :merchant_id, :debug
9
+
10
+ # Initialize a new client instance
11
+ # @param [Hash] client connection options
12
+ #
13
+ # Available options:
14
+ #
15
+ # :api_key - Your API key (required)
16
+ # :mode - API mode (sandox / production)
17
+ # :merchant_id - Your merchant ID
18
+ # :debug - True for request logging
19
+ #
20
+ def initialize(options={})
21
+ @api_key = options[:api_key] || ArrowPayments::Configuration.api_key
22
+ @mode = (options[:mode] || ArrowPayments::Configuration.mode || 'production').to_s
23
+ @merchant_id = options[:merchant_id] || ArrowPayments::Configuration.merchant_id
24
+ @debug = options[:debug] == true
25
+
26
+ if api_key.to_s.empty?
27
+ raise ArgumentError, "API key required"
28
+ end
29
+
30
+ if merchant_id.to_s.empty?
31
+ raise ArgumentError, "Merchant ID required"
32
+ end
33
+
34
+ unless %(sandbox production).include?(mode)
35
+ raise ArgumentError, "Invalid mode: #{mode}"
36
+ end
37
+ end
38
+
39
+ # Check if client is in sandbox mode
40
+ # @return [Boolean]
41
+ def sandbox?
42
+ mode == 'sandbox'
43
+ end
44
+
45
+ # Check if client is in production mode
46
+ # @return [Boolean]
47
+ def production?
48
+ mode == 'production'
49
+ end
50
+
51
+ # Check if debug mode is enabled
52
+ # @return [Boolean]
53
+ def debug?
54
+ debug == true
55
+ end
56
+ end
57
+ end