figpay_gateway 1.0.0

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.
@@ -0,0 +1,330 @@
1
+ #!/usr/bin/env ruby
2
+ require "pry"
3
+ require 'bundler/setup'
4
+ require 'figpay_gateway'
5
+ require 'dotenv'
6
+ Dotenv.load
7
+
8
+ # Use demo credentials if not set
9
+ ENV['NMI_SECURITY_KEY'] ||= '6457Thfj624V5r7WUwc5v6a68Zsd6YEm'
10
+
11
+ puts "=" * 80
12
+ puts "FigPay Gateway - Comprehensive Method Test"
13
+ puts "=" * 80
14
+ puts "Using Security Key: #{ENV['NMI_SECURITY_KEY'][0..10]}..."
15
+ puts "=" * 80
16
+ puts
17
+
18
+ # Store results
19
+ results = {}
20
+ customer_vault_id = nil
21
+ subscription_id = nil
22
+ transaction_id = nil
23
+ auth_transaction_id = nil
24
+
25
+ # Helper method to display results
26
+ def display_result(name, result)
27
+ puts "\n#{'-' * 80}"
28
+ puts "Test: #{name}"
29
+
30
+ if result.success?
31
+ puts "Status: ✓ SUCCESS"
32
+ puts "Response Code: #{result.response_code}" if result.respond_to?(:response_code)
33
+ puts "Response Message: #{result.response_message}" if result.respond_to?(:response_message) && result.response_message
34
+ puts "Transaction ID: #{result.transactionid}" if result.respond_to?(:transactionid) && result.transactionid
35
+ puts "Customer Vault ID: #{result.customer_vault_id}" if result.respond_to?(:customer_vault_id) && result.customer_vault_id
36
+ puts "Subscription ID: #{result.subscription_id}" if result.respond_to?(:subscription_id) && result.subscription_id
37
+ puts "Auth Code: #{result.authcode}" if result.respond_to?(:authcode) && result.authcode
38
+ puts "Response: #{result.response}" if result.respond_to?(:response) && result.response
39
+ else
40
+ puts "Status: ✗ FAILED"
41
+ puts "Error: #{result.response_text}" if result.respond_to?(:response_text)
42
+ puts "Response Code: #{result.response_code}" if result.respond_to?(:response_code)
43
+ puts "Response Message: #{result.response_message}" if result.respond_to?(:response_message) && result.response_message
44
+ puts "Response: #{result.response}" if result.respond_to?(:response) && result.response
45
+ end
46
+
47
+ puts "-" * 80
48
+ result
49
+ end
50
+
51
+ puts "\n### TRANSACTION TESTS ###\n"
52
+
53
+ # Test 1: Validate Card
54
+ puts "\n1. Testing Card Validation..."
55
+ result = FigpayGateway::Transaction.new.validate(
56
+ ccnumber: '4111111111111111',
57
+ ccexp: '1225',
58
+ first_name: 'John',
59
+ last_name: 'Doe',
60
+ email: 'john@example.com'
61
+ )
62
+ results[:validate] = display_result("Card Validation", result)
63
+
64
+ # Test 2: Sale Transaction
65
+ puts "\n2. Testing Sale Transaction..."
66
+ result = FigpayGateway::Transaction.new.sale(
67
+ ccnumber: '4111111111111111',
68
+ ccexp: '1225',
69
+ cvv: '999',
70
+ amount: 10.00,
71
+ first_name: 'John',
72
+ last_name: 'Doe',
73
+ address1: '123 Main St',
74
+ city: 'Beverly Hills',
75
+ state: 'CA',
76
+ zip: '90210',
77
+ country: 'US',
78
+ email: 'john@example.com'
79
+ )
80
+ results[:sale] = display_result("Sale Transaction", result)
81
+ transaction_id = result.transactionid if result.success? && result.respond_to?(:transactionid)
82
+
83
+ # Test 3: Authorization
84
+ puts "\n3. Testing Authorization..."
85
+ result = FigpayGateway::Transaction.new.authorize(
86
+ ccnumber: '4111111111111111',
87
+ ccexp: '1225',
88
+ amount: 25.00,
89
+ first_name: 'John',
90
+ last_name: 'Doe',
91
+ email: 'john@example.com'
92
+ )
93
+ results[:authorize] = display_result("Authorization", result)
94
+ auth_transaction_id = result.transactionid if result.success? && result.respond_to?(:transactionid)
95
+
96
+ # Test 4: Capture (if authorization succeeded)
97
+ if auth_transaction_id
98
+ puts "\n4. Testing Capture..."
99
+ result = FigpayGateway::Transaction.new.capture(
100
+ transactionid: auth_transaction_id,
101
+ amount: 25.00
102
+ )
103
+ results[:capture] = display_result("Capture", result)
104
+ else
105
+ puts "\n4. Skipping Capture (no auth transaction ID)"
106
+ end
107
+
108
+ # Test 5: Credit (Standalone)
109
+ puts "\n5. Testing Standalone Credit..."
110
+ result = FigpayGateway::Transaction.new.credit(
111
+ ccnumber: '4111111111111111',
112
+ ccexp: '1225',
113
+ amount: 5.00,
114
+ first_name: 'John',
115
+ last_name: 'Doe',
116
+ email: 'john@example.com'
117
+ )
118
+ results[:credit] = display_result("Standalone Credit", result)
119
+
120
+ # Test 6: Find Transaction (if we have a transaction ID)
121
+ if transaction_id
122
+ puts "\n6. Testing Transaction Query..."
123
+ result = FigpayGateway::Transaction.new.find(
124
+ transactionid: transaction_id
125
+ )
126
+ results[:find_transaction] = display_result("Transaction Query", result)
127
+ else
128
+ puts "\n6. Skipping Transaction Query (no transaction ID)"
129
+ end
130
+
131
+ # Test 7: Update Transaction (if we have a transaction ID)
132
+ if transaction_id
133
+ puts "\n7. Testing Transaction Update..."
134
+ result = FigpayGateway::Transaction.new.update(
135
+ transactionid: transaction_id,
136
+ orderid: 'TEST-ORDER-123',
137
+ order_description: 'Test order updated'
138
+ )
139
+ results[:update_transaction] = display_result("Transaction Update", result)
140
+ else
141
+ puts "\n7. Skipping Transaction Update (no transaction ID)"
142
+ end
143
+
144
+ # Test 8: Refund (if we have a transaction ID)
145
+ if transaction_id
146
+ puts "\n8. Testing Refund..."
147
+ result = FigpayGateway::Transaction.new.refund(
148
+ transactionid: transaction_id,
149
+ amount: 5.00
150
+ )
151
+ results[:refund] = display_result("Refund", result)
152
+ else
153
+ puts "\n8. Skipping Refund (no transaction ID)"
154
+ end
155
+
156
+ # Test 9: Void (create a new transaction to void)
157
+ puts "\n9. Testing Void..."
158
+ void_result = FigpayGateway::Transaction.new.sale(
159
+ ccnumber: '4111111111111111',
160
+ ccexp: '1225',
161
+ amount: 1.00,
162
+ first_name: 'John',
163
+ last_name: 'Doe',
164
+ email: 'john@example.com'
165
+ )
166
+ if void_result.success? && void_result.respond_to?(:transactionid)
167
+ result = FigpayGateway::Transaction.new.void(
168
+ transactionid: void_result.transactionid
169
+ )
170
+ results[:void] = display_result("Void Transaction", result)
171
+ else
172
+ puts "Skipping Void (could not create transaction to void)"
173
+ end
174
+
175
+ puts "\n\n### CUSTOMER VAULT TESTS ###\n"
176
+
177
+ # Test 10: Create Customer
178
+ puts "\n10. Testing Customer Vault Create..."
179
+ result = FigpayGateway::CustomerVault.new.create(
180
+ ccnumber: '4111111111111111',
181
+ ccexp: '1225',
182
+ cvv: '999',
183
+ first_name: 'Jane',
184
+ last_name: 'Smith',
185
+ address1: '456 Oak Ave',
186
+ city: 'Los Angeles',
187
+ state: 'CA',
188
+ zip: '90001',
189
+ email: 'jane@example.com'
190
+ )
191
+ results[:create_customer] = display_result("Create Customer", result)
192
+ customer_vault_id = result.customer_vault_id if result.success? && result.respond_to?(:customer_vault_id)
193
+
194
+ # Test 11: Update Customer (if we have a customer vault ID)
195
+ if customer_vault_id
196
+ puts "\n11. Testing Customer Vault Update..."
197
+ result = FigpayGateway::CustomerVault.new.update(
198
+ customer_vault_id: customer_vault_id,
199
+ first_name: 'Jane',
200
+ last_name: 'Doe-Smith',
201
+ email: 'jane.smith@example.com'
202
+ )
203
+ results[:update_customer] = display_result("Update Customer", result)
204
+ else
205
+ puts "\n11. Skipping Customer Update (no customer vault ID)"
206
+ end
207
+
208
+ # Test 12: Find Customer (if we have a customer vault ID)
209
+ if customer_vault_id
210
+ puts "\n12. Testing Customer Vault Query..."
211
+ result = FigpayGateway::CustomerVault.new.find(
212
+ customer_vault_id: customer_vault_id
213
+ )
214
+ results[:find_customer] = display_result("Find Customer", result)
215
+ else
216
+ puts "\n12. Skipping Customer Query (no customer vault ID)"
217
+ end
218
+
219
+ # Test 13: Charge Vaulted Customer (if we have a customer vault ID)
220
+ if customer_vault_id
221
+ puts "\n13. Testing Charge Vaulted Customer..."
222
+ result = FigpayGateway::Transaction.new.sale(
223
+ customer_vault_id: customer_vault_id,
224
+ amount: 15.00,
225
+ orderid: 'VAULT-ORDER-456'
226
+ )
227
+ results[:charge_vaulted] = display_result("Charge Vaulted Customer", result)
228
+ else
229
+ puts "\n13. Skipping Charge Vaulted Customer (no customer vault ID)"
230
+ end
231
+
232
+ puts "\n\n### RECURRING BILLING TESTS ###\n"
233
+
234
+ # Test 14: Create Billing Plan
235
+ puts "\n14. Testing Create Billing Plan..."
236
+ result = FigpayGateway::Recurring.new.create_plan(
237
+ plan_id: "test-plan-#{Time.now.to_i}",
238
+ plan_name: 'Test Monthly Plan',
239
+ plan_amount: 29.99,
240
+ month_frequency: 1,
241
+ day_of_month: 1
242
+ )
243
+ results[:create_plan] = display_result("Create Billing Plan", result)
244
+ plan_id = result.plan_id if result.success? && result.respond_to?(:plan_id)
245
+
246
+ # Test 15: Add Subscription to Plan (if we have both plan and customer)
247
+ if plan_id && customer_vault_id
248
+ puts "\n15. Testing Subscribe Customer to Plan..."
249
+ result = FigpayGateway::Recurring.new.add_subscription_to_plan(
250
+ plan_id: plan_id,
251
+ customer_vault_id: customer_vault_id
252
+ )
253
+ results[:add_subscription] = display_result("Subscribe to Plan", result)
254
+ subscription_id = result.subscription_id if result.success? && result.respond_to?(:subscription_id)
255
+ elsif !plan_id
256
+ puts "\n15. Skipping Subscribe to Plan (no plan ID)"
257
+ elsif !customer_vault_id
258
+ puts "\n15. Skipping Subscribe to Plan (no customer vault ID)"
259
+ end
260
+
261
+ # Test 16: Create Custom Subscription (if we have customer vault ID)
262
+ if customer_vault_id && !subscription_id
263
+ puts "\n16. Testing Create Custom Subscription..."
264
+ result = FigpayGateway::Recurring.new.add_custom_subscription(
265
+ customer_vault_id: customer_vault_id,
266
+ plan_amount: 19.99,
267
+ month_frequency: 1,
268
+ day_of_month: 15
269
+ )
270
+ results[:custom_subscription] = display_result("Create Custom Subscription", result)
271
+ subscription_id = result.subscription_id if result.success? && result.respond_to?(:subscription_id)
272
+ else
273
+ puts "\n16. Skipping Custom Subscription (no customer or already subscribed)"
274
+ end
275
+
276
+ # Test 17: Update Subscription (if we have subscription ID)
277
+ if subscription_id
278
+ puts "\n17. Testing Update Subscription..."
279
+ result = FigpayGateway::Recurring.new.update_subscription(
280
+ subscription_id: subscription_id,
281
+ plan_amount: 24.99
282
+ )
283
+ results[:update_subscription] = display_result("Update Subscription", result)
284
+ else
285
+ puts "\n17. Skipping Update Subscription (no subscription ID)"
286
+ end
287
+
288
+ # Test 18: Cancel Subscription (if we have subscription ID)
289
+ if subscription_id
290
+ puts "\n18. Testing Cancel Subscription..."
291
+ result = FigpayGateway::Recurring.new.delete_subscription(
292
+ subscription_id: subscription_id
293
+ )
294
+ results[:delete_subscription] = display_result("Cancel Subscription", result)
295
+ else
296
+ puts "\n18. Skipping Cancel Subscription (no subscription ID)"
297
+ end
298
+
299
+ # Test 19: Delete Customer (if we have customer vault ID)
300
+ if customer_vault_id
301
+ puts "\n19. Testing Delete Customer..."
302
+ result = FigpayGateway::CustomerVault.new.destroy(
303
+ customer_vault_id: customer_vault_id
304
+ )
305
+ results[:delete_customer] = display_result("Delete Customer", result)
306
+ else
307
+ puts "\n19. Skipping Delete Customer (no customer vault ID)"
308
+ end
309
+
310
+ # Summary
311
+ puts "\n\n"
312
+ puts "=" * 80
313
+ puts "TEST SUMMARY"
314
+ puts "=" * 80
315
+
316
+ successful = results.select { |k, v| v.success? }.count
317
+ total = results.count
318
+
319
+ puts "Total Tests Run: #{total}"
320
+ puts "Successful: #{successful}"
321
+ puts "Failed: #{total - successful}"
322
+ puts "\nSuccess Rate: #{(successful.to_f / total * 100).round(2)}%"
323
+
324
+ puts "\nDetailed Results:"
325
+ results.each do |name, result|
326
+ status = result.success? ? "✓ PASS" : "✗ FAIL"
327
+ puts " #{status} - #{name}"
328
+ end
329
+
330
+ puts "=" * 80
Binary file
@@ -0,0 +1,47 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'figpay_gateway/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "figpay_gateway"
8
+ spec.version = FigpayGateway::VERSION
9
+ spec.authors = ["Ben Eggett"]
10
+ spec.email = ["beneggett@gmail.com"]
11
+
12
+ spec.summary = %q{ FigPay Gateway (NMI) Api }
13
+ spec.description = %q{ Ruby wrapper for interacting with FigPay Gateway. FigPay is a white label gateway for NMI. Built with portability in mind for other NMI white-label providers. }
14
+ spec.homepage = "https://github.com/beneggett/figpay_gateway"
15
+ spec.license = "MIT"
16
+
17
+ spec.required_ruby_version = ">= 3.0.0"
18
+
19
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
20
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
21
+ if spec.respond_to?(:metadata)
22
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
23
+ else
24
+ raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
25
+ end
26
+
27
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_development_dependency "bundler", ">= 2.0"
33
+ spec.add_development_dependency "rake", ">= 13.0"
34
+ spec.add_development_dependency "minitest", "~> 5.0"
35
+ spec.add_development_dependency "vcr"
36
+ spec.add_development_dependency "webmock"
37
+ spec.add_development_dependency "pry"
38
+ spec.add_development_dependency "guard"
39
+ spec.add_development_dependency "guard-minitest"
40
+ spec.add_development_dependency "coveralls"
41
+ spec.add_development_dependency "simplecov"
42
+ spec.add_development_dependency "minitest-focus"
43
+ spec.add_development_dependency "dotenv"
44
+ spec.add_dependency "httparty", ">= 0.14.0"
45
+ spec.add_dependency "activesupport"
46
+
47
+ end
@@ -0,0 +1,3 @@
1
+ module FigpayGateway
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,3 @@
1
+ # FigPay Gateway is a wrapper around the NMI Gateway
2
+ # This allows the gem to be portable across different NMI white-label providers
3
+ require "nmi_gateway"
@@ -0,0 +1,195 @@
1
+ module NMIGateway
2
+ class Api
3
+ TRANSACTION_URL = ENV.fetch("NMI_TRANSACTION_URL", "https://figpay.transactiongateway.com/api/transact.php")
4
+ QUERY_URL = ENV.fetch("NMI_QUERY_URL", "https://figpay.transactiongateway.com/api/query.php")
5
+ include HTTParty
6
+
7
+ attr_accessor :security_key, :query
8
+
9
+ def initialize(options = {})
10
+ @security_key = options[:security_key] || ENV["NMI_SECURITY_KEY"]
11
+ end
12
+
13
+ def get(options={})
14
+ response = self.class.get(QUERY_URL, query: options.merge(credentials), timeout: 30, headers: headers)
15
+ api_type = options[:type] || options[:report_type]
16
+ handle_response(response, api_type)
17
+ end
18
+
19
+ def post(options={})
20
+ response = self.class.get(TRANSACTION_URL, query: options.merge(credentials), timeout: 30, headers: headers)
21
+ api_type = options[:type] || options[:customer_vault]
22
+ handle_response(response, api_type)
23
+ end
24
+
25
+ private
26
+
27
+ def handle_response(response, api_type)
28
+ if response.success?
29
+ NMIGateway::Response.new(response, api_type)
30
+ else
31
+ NMIGateway::Error.new(response.code, response.message, response)
32
+ end
33
+ end
34
+
35
+ def headers
36
+ {'Content-Type' => "application/xml", 'Accept' => "application/xml"}
37
+ end
38
+
39
+ def credentials
40
+ creds = {security_key: security_key}
41
+ creds[:test_mode] = ENV['NMI_TEST_MODE'] if ENV['NMI_TEST_MODE']
42
+ creds
43
+ end
44
+
45
+ def set_query(options = {})
46
+ query = {}
47
+ query[:customer_vault] = options[:customer_vault] # add_customer or update_customer
48
+ query[:customer_vault_id] = options[:customer_vault_id]
49
+ query[:transactionid] = options[:transactionid]
50
+ query[:billing_id] = options[:billing_id]
51
+
52
+ # Query params
53
+ query[:condition] = options[:condition] # pending, pendingsettlement, failed, canceled, complete, unknown. Can be stringed together.
54
+ query[:transaction_type] = options[:transaction_type] # cc, ck
55
+ query[:action_type] = options[:action_type] # sale, refund, credit, auth, capture, void, return
56
+
57
+ query[:transaction_id] = options[:transaction_id] # can me multiple together
58
+ query[:cc_number] = options[:cc_number] # You can use either the full number or the last 4 digits of the credit card number.
59
+ query[:end_date] = options[:end_date] # YYYYMMDDhhmmss
60
+ query[:report_type] = options[:report_type] # receipt or customer_vault
61
+ query[:mobile_device_license] = options[:mobile_device_license]
62
+ query[:mobile_device_nickname] = options[:mobile_device_nickname]
63
+
64
+
65
+ # Credit Cards
66
+ query[:ccnumber] = options[:ccnumber]
67
+ query[:ccexp] = options[:ccexp] # FORMAT MMYY
68
+ query[:cvv] = options[:cvv] # Recommended
69
+
70
+ # Payment
71
+ query[:amount] = options[:amount]
72
+ query[:currency] = options[:currency] || 'USD'
73
+ query[:payment] = options[:payment] || 'creditcard' # creditcard or check
74
+ query[:processor_id] = options[:processor_id]
75
+ query[:dup_seconds] = options[:dup_seconds]
76
+ query[:billing_method] = options[:billing_method] # recurring
77
+ query[:customer_receipt] = options[:customer_receipt] # true, false
78
+
79
+ # Advanced Payment
80
+ query[:tax] = options[:tax]
81
+ query[:shipping] = options[:shipping]
82
+
83
+ # Recurring Billing
84
+ query[:recurring] = options[:recurring ] # add_subscription
85
+ query[:plan_id] = options [:plan_id]
86
+ query[:plan_name] = options [:plan_name]
87
+ query[:plan_payments] = options [:plan_payments] # 0 until canceled
88
+ query[:plan_amount] = options [:plan_amount]
89
+ query[:day_frequency] = options [:day_frequency]
90
+ query[:month_frequency] = options [:month_frequency] # 1-24
91
+ query[:day_of_month] = options [:day_of_month] # 1-31
92
+ query[:start_date] = options [:start_date] #YYYYMMDD
93
+ query[:subscription_id] = options [:subscription_id]
94
+
95
+
96
+ # Customer Billing
97
+ query[:first_name] = options[:first_name]
98
+ query[:last_name] = options[:last_name]
99
+ query[:company] = options[:company]
100
+ query[:address1] = options[:address1]
101
+ query[:address2] = options[:address2]
102
+ query[:city] = options[:city]
103
+ query[:state] = options[:state]
104
+ query[:zip] = options[:zip]
105
+ query[:country] = options[:country]
106
+ query[:phone] = options[:phone]
107
+ query[:fax] = options[:fax]
108
+ query[:email] = options[:email]
109
+ query[:ipaddress] = options[:ipaddress] # Recommended
110
+
111
+ # Additional Customer Info
112
+ query[:social_security_number] = options[:social_security_number]
113
+ query[:drivers_license_number] = options[:drivers_license_number]
114
+ query[:drivers_license_dob] = options[:drivers_license_dob]
115
+ query[:drivers_license_state] = options[:drivers_license_state]
116
+
117
+ # Customer Shipping
118
+ query[:shipping_id] = options[:shipping_id]
119
+ query[:shipping_first_name] = options[:shipping_first_name]
120
+ query[:shipping_last_name] = options[:shipping_last_name]
121
+ query[:shipping_company] = options[:shipping_company]
122
+ query[:shipping_address1] = options[:shipping_address1]
123
+ query[:shipping_address2] = options[:shipping_address2]
124
+ query[:shipping_city] = options[:shipping_city]
125
+ query[:shipping_state] = options[:shipping_state]
126
+ query[:shipping_zip] = options[:shipping_zip]
127
+ query[:shipping_country] = options[:shipping_country]
128
+ query[:shipping_phone] = options[:shipping_phone]
129
+ query[:shipping_fax] = options[:shipping_fax]
130
+ query[:shipping_email] = options[:shipping_email]
131
+
132
+ # For ACH
133
+ query[:checkname] = options[:check_name]
134
+ query[:checkaba] = options[:check_routing_number] # routing_number
135
+ query[:checkaccount] = options[:check_account_number]
136
+ query[:account_holder_type] = options[:account_holder_type] # personal or 'business'
137
+ query[:account_type] = options[:account_type] # checking or savings
138
+ query[:sec_code] = options[:sec_code] # 'PPD', 'WEB', 'TEL', or 'CCD'
139
+
140
+ # Optional order fields
141
+ query[:orderid] = options[:orderid]
142
+ query[:order_description] = options[:order_description]
143
+ query[:order_date] = options[:order_date]
144
+ query[:ponumber] = options[:ponumber]
145
+ query[:tracking_number] = options[:tracking_number]
146
+
147
+ # order update fields
148
+ query[:shipping_carrier] = options[:shipping_carrier] # ups, fedex, dhl, or usps
149
+ query[:shipping_postal] = options[:shipping_postal]
150
+ query[:ship_from_postal] = options[:ship_from_postal]
151
+ query[:shipping_date] = options[:shipping_date]
152
+ query[:summary_commodity_code] = options[:summary_commodity_code]
153
+ query[:duty_amount] = options[:duty_amount]
154
+ query[:discount_amount] = options[:discount_amount]
155
+ query[:tax] = options[:tax]
156
+ query[:national_tax_amount] = options[:national_tax_amount]
157
+ query[:alternate_tax_amount] = options[:alternate_tax_amount]
158
+ query[:alternate_tax_id] = options[:alternate_tax_id]
159
+ query[:vat_tax_amount] = options[:vat_tax_amount]
160
+ query[:vat_tax_rate] = options[:vat_tax_rate] # 1% = 1.00.
161
+ query[:vat_invoice_reference_number] = options[:vat_invoice_reference_number]
162
+ query[:merchant_vat_registration] = options[:merchant_vat_registration]
163
+ # merchant_defined_field_# Merchant Defined Fields.
164
+
165
+
166
+
167
+ # Descriptor fields
168
+ query[:descriptor] = options[:descriptor]
169
+ query[:descriptor_phone] = options[:descriptor_phone]
170
+ query[:descriptor_address] = options[:descriptor_address]
171
+ query[:descriptor_city] = options[:descriptor_city]
172
+ query[:descriptor_state] = options[:descriptor_state]
173
+ query[:descriptor_postal] = options[:descriptor_postal]
174
+ query[:descriptor_country] = options[:descriptor_country]
175
+ query[:descriptor_mcc] = options[:descriptor_mcc]
176
+ query[:descriptor_merchant_id] = options[:descriptor_merchant_id]
177
+ query[:descriptor_url] = options[:descriptor_url]
178
+
179
+ 1..20.to_a.each do |i|
180
+ query["merchant_defined_field_#{i}".to_sym] = options["merchant_defined_field_#{i}".to_sym]
181
+ end if options.select {|k,v| k.to_s.starts_with? 'merchant_defined_field' }.any?
182
+
183
+ @query = query.select {|k,v| !v.nil?}
184
+
185
+ end
186
+
187
+ def require_fields(*fields)
188
+ if query.values_at(*fields).include?(nil)
189
+ missing_fields = fields - query.keys
190
+ raise Error::MissingParameters.new("Missing required keys: #{missing_fields.to_s.gsub(']', '').gsub('[', '')}") if missing_fields.any?
191
+ end
192
+ end
193
+ end
194
+ end
195
+
@@ -0,0 +1,38 @@
1
+ module NMIGateway
2
+ class CustomerVault < Api
3
+
4
+ # NMIGateway::CustomerVault.new.create ccnumber: '4111111111111111', ccexp: "0219", first_name: "John", last_name: "Doe"
5
+ def create(options = {})
6
+ query = set_query(options)
7
+ query[:customer_vault] = 'add_customer'
8
+
9
+ require_fields(:ccnumber, :ccexp)
10
+ post query
11
+ end
12
+
13
+ # NMIGateway::CustomerVault.new.update customer_vault_id: 481397475, ccnumber: '4111111111111111', ccexp: "0220", first_name: "Jane", last_name: "Doe"
14
+ def update(options = {})
15
+ query = set_query(options)
16
+ query[:customer_vault] = 'update_customer'
17
+ require_fields(:customer_vault_id)
18
+ post query
19
+ end
20
+
21
+ # NMIGateway::CustomerVault.new.destroy customer_vault_id: 481397475
22
+ def destroy(options = {})
23
+ query = set_query(options)
24
+ query[:customer_vault] = 'delete_customer'
25
+ require_fields(:customer_vault_id)
26
+ post query
27
+ end
28
+
29
+ # NMIGateway::CustomerVault.new.find customer_vault_id: 481397475
30
+ def find(options = {})
31
+ query = set_query(options)
32
+ query[:report_type] = 'customer_vault'
33
+ require_fields(:customer_vault_id)
34
+ get query
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ module NMIGateway
2
+ class Data
3
+
4
+ # Attributes that have a value
5
+ def attributes
6
+ all_attributes.select {|x| !self.send(x).nil? }
7
+ end
8
+
9
+ def all_attributes
10
+ self.instance_variables.map{|attribute| attribute.to_s.gsub('@', '').to_sym }
11
+ end
12
+
13
+ end
14
+
15
+ end
@@ -0,0 +1,20 @@
1
+ module NMIGateway
2
+ class Error
3
+ class AuthenticationError < StandardError; end
4
+ class NoApiKey < AuthenticationError; end
5
+ class InvalidResponseFormat < TypeError; end
6
+ class MissingParameters < TypeError; end
7
+ class Timeout < Timeout::Error ; end
8
+ class NoData < EOFError; end
9
+
10
+ attr_reader :message, :code, :response
11
+
12
+ def initialize( code, message, response)
13
+ @code = response_code
14
+ @message = response_message
15
+ @response = response
16
+ end
17
+
18
+ end
19
+ end
20
+