virtual_merchant 0.3.8 → 0.3.9

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8ac34cc9c1554e88c53674e8bb01f2dedfb356de
4
- data.tar.gz: 343f72027befad114837e030e0cf669c92d5ab4f
3
+ metadata.gz: b66fbdd061c01dd0fe3616af2b274b50d4cf15af
4
+ data.tar.gz: ea8a7a2f2f335dfa46a052d88d39461c950e3542
5
5
  SHA512:
6
- metadata.gz: e0ad4523bdff048db0cd6edcebbbc26b8aa9f523a2c0da696f105b320ab6b69eec64419dcdd677dc568e03493f18845952d47712b9a6facbc4f9b0e70f3d5915
7
- data.tar.gz: d8fa3aa086f4edb3d5ef0c6cd2c8c7d44ee224f9607c8c024d83d7f8889d0b0f0110734492e4fdf269b5cd173e459af5dda15b00d6b913bab8d8b27491d33d4b
6
+ metadata.gz: bba7caef29bc7de60a0099180a51e5a8a323a2c851d6125b3dfa7d685e38898428658b668bd3efd98b86042e0cf6339e337a84e01e0d34e47a2e68331eb9f462
7
+ data.tar.gz: a2ba8491b977ce3dd4484f73a309bb17e07b5cd73b3bace09dcefb0d6a9480a790a2bb98a352bf96ff32b8197043dec722d0ddee50c51215cedbd22b4c223743
@@ -1,7 +1,8 @@
1
+ require 'virtual_merchant/swipe_extractor'
1
2
  module VirtualMerchant
2
3
  class CreditCard
3
4
  attr_accessor :name_on_card, :number, :expiration, :security_code, :swipe, :track2,
4
- :encrypted_track_1, :encrypted_track_2, :last_four, :encrypted, :swiped
5
+ :encrypted_track_1, :encrypted_track_2, :last_four, :encrypted, :swiped, :valid, :errors
5
6
 
6
7
  def self.from_swipe(swipe)
7
8
  if swipe.class == Hash && swipe[:encrypted]
@@ -16,6 +17,7 @@ module VirtualMerchant
16
17
  end
17
18
 
18
19
  def initialize(info)
20
+ @errors = {}
19
21
  if info[:encrypted]
20
22
  self.from_encrypted(info)
21
23
  elsif info[:swipe]
@@ -26,6 +28,7 @@ module VirtualMerchant
26
28
  end
27
29
 
28
30
  def from_encrypted (info)
31
+ @errors = {}
29
32
  @encrypted = true
30
33
  @encrypted_track_1 = info[:track_1]
31
34
  @encrypted_track_2 = info[:track_2]
@@ -33,22 +36,35 @@ module VirtualMerchant
33
36
  end
34
37
 
35
38
  def from_swipe(swipe_raw)
36
- @swiped = true
37
- @swipe = swipe_raw
38
- @track2 = extract_track_2(swipe)
39
- @number = extract_card_number(swipe)
40
- @expiration = extract_expiration(swipe)
41
- @name_on_card = extract_name(swipe)
42
- @last_four = extract_last_four
39
+ @errors = {}
40
+ if check_swipe(swipe_raw)
41
+ @valid = true
42
+ @swiped = true
43
+ @swipe = swipe_raw
44
+ @track2 = SwipeExtractor.get_track_2(swipe)
45
+ @number = SwipeExtractor.get_card_number(swipe)
46
+ @expiration = SwipeExtractor.get_expiration(swipe)
47
+ @name_on_card = SwipeExtractor.get_name(swipe)
48
+ @last_four = SwipeExtractor.get_last_four(@number)
49
+ else
50
+ @valid = false
51
+ end
43
52
  end
44
53
 
45
54
  def from_manual(info)
46
- @name_on_card = info[:name_on_card] if info[:name_on_card]
47
- @number = info[:number].to_s.gsub(/\s+/, "") if info[:number]
48
- @expiration = info[:expiration].to_s if info[:expiration]
49
- @security_code = info[:security_code].to_s if info[:security_code]
50
- @track2 = info[:track_2] if info[:track_2]
51
- @last_four = extract_last_four
55
+ @errors = {}
56
+ if info[:number] && check_luhn(info[:number].to_s.gsub(/\s+/, ""))
57
+ @name_on_card = info[:name_on_card] if info[:name_on_card]
58
+ @number = info[:number].to_s.gsub(/\s+/, "")
59
+ @expiration = info[:expiration].to_s if info[:expiration]
60
+ @security_code = info[:security_code].to_s if info[:security_code]
61
+ @track2 = info[:track_2] if info[:track_2]
62
+ @last_four = SwipeExtractor.get_last_four(@number)
63
+ @valid = true
64
+ else
65
+ errors[5000] = "The Credit Card Number supplied in the authorization request appears to be invalid."
66
+ @valid = false
67
+ end
52
68
  end
53
69
 
54
70
  def encrypted?
@@ -59,50 +75,41 @@ module VirtualMerchant
59
75
  self.swiped
60
76
  end
61
77
 
62
- def extract_card_number(swipe)
63
- card_number = swipe[2.. swipe.index('^')-1]
64
- card_number = card_number.split(' ').join('')
65
- end
66
-
67
- def extract_expiration(swipe)
68
- secondCarrot = swipe.index("^", swipe.index("^")+1)
69
- card_expiration_year = swipe[secondCarrot+1..secondCarrot+2]
70
- card_expiration_month = swipe[(secondCarrot + 3)..(secondCarrot + 4)]
71
- card_expiration = card_expiration_month.to_s + card_expiration_year.to_s
78
+ def valid?
79
+ self.valid
72
80
  end
73
81
 
74
- def extract_name(swipe)
75
- secondCarrot = swipe.index("^", swipe.index("^")+1)
76
- if swipe.index('/')
77
- first_name_on_card = swipe[swipe.index('/')+1..secondCarrot-1]
78
- last_name_on_card = swipe[swipe.index('^')+1..swipe.index('/')-1]
79
- else
80
- if !swipe.index(" ")
81
- first_name_on_card = "Gift"
82
- last_name_on_card = "Card"
83
- else
84
- first_name_on_card = swipe.slice(swipe.index('^') + 1, swipe.index(' '))
85
- last_name_on_card = swipe.slice(swipe.index(" ") + 1, secondCarrot)
86
- end
82
+ def check_swipe(swipe_raw)
83
+ if swipe_raw.index('%') == nil
84
+ @errors[5012] = "The track data sent appears to be invalid."
85
+ return false
87
86
  end
88
- name_on_card = first_name_on_card + " " + last_name_on_card
89
- end
90
-
91
- def extract_track_2(swipe)
92
- # Magtek reader: Track 2 starts with a semi-colon and goes to the end
93
- # I think that is standard for all readers, but not positive. -LQ
94
- track2 = swipe.slice(swipe.index(";"), swipe.length)
95
- if track2.index("+")
96
- # Some AMEX have extra stuff at the end of track 2 that causes
97
- #virtual merchant to return an INVLD DATA5623 message.
98
- #Soooo... let's slice that off
99
- track2 = track2.slice(0, track2.index("+"))
87
+ if swipe_raw.index(';') == nil
88
+ @errors[5013] = "Transaction requires Track2 data to be sent."
89
+ return false
100
90
  end
101
- track2
91
+ track1 = swipe_raw[1.. swipe_raw.index('?')-1]
92
+ if track1 == nil || track1 == "E"
93
+ @errors[5012] = "The track data sent appears to be invalid."
94
+ return false
95
+ end
96
+ track2 = swipe_raw[swipe_raw.index(';')+1.. swipe_raw.length-2]
97
+ if track2 == nil || track2 == "E"
98
+ @errors[5013] = "Transaction requires Track2 data to be sent."
99
+ return false
100
+ end
101
+ return true
102
102
  end
103
103
 
104
- def extract_last_four
105
- self.number[(self.number.length - 4)..self.number.length]
104
+ def check_luhn(code)
105
+ s1 = s2 = 0
106
+ code.to_s.reverse.chars.each_slice(2) do |odd, even|
107
+ s1 += odd.to_i
108
+ double = even.to_i * 2
109
+ double -= 9 if double >= 10
110
+ s2 += double
111
+ end
112
+ (s1 + s2) % 10 == 0
106
113
  end
107
114
 
108
115
  def blurred_number
@@ -6,13 +6,21 @@ class Gateway
6
6
  end
7
7
 
8
8
  def ccsale(card, amount, custom_fields)
9
- xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, custom_fields, "ccsale")
10
- process(xml, amount)
9
+ if card.valid?
10
+ xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, custom_fields, "ccsale")
11
+ process(xml, amount)
12
+ else
13
+ gen_cc_errors(card)
14
+ end
11
15
  end
12
16
 
13
17
  def ccauth(card, amount, custom_fields)
14
- xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, custom_fields, "ccauthonly")
15
- process(xml, amount)
18
+ if card.valid?
19
+ xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, custom_fields, "ccauthonly")
20
+ process(xml, amount)
21
+ else
22
+ gen_cc_errors(card)
23
+ end
16
24
  end
17
25
 
18
26
  def cccomplete(amount, transaction_id)
@@ -27,13 +35,21 @@ class Gateway
27
35
  end
28
36
 
29
37
  def ccaddrecurring(card, amount, custom_fields)
30
- xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, custom_fields, "ccaddrecurring")
31
- process(xml, amount)
38
+ if card.valid?
39
+ xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, custom_fields, "ccaddrecurring")
40
+ process(xml, amount)
41
+ else
42
+ gen_cc_errors(card)
43
+ end
32
44
  end
33
45
 
34
46
  def cccredit(card, amount, custom_fields)
35
- xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, custom_fields, 'cccredit')
36
- process(xml, amount)
47
+ if card.valid?
48
+ xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, custom_fields, 'cccredit')
49
+ process(xml, amount)
50
+ else
51
+ gen_cc_errors(card)
52
+ end
37
53
  end
38
54
 
39
55
  def ccvoid(transaction_id)
@@ -58,4 +74,13 @@ class Gateway
58
74
  'https://www.myvirtualmerchant.com/VirtualMerchant/processxml.do'
59
75
  end
60
76
  end
77
+
78
+ def gen_cc_errors(card)
79
+ card.errors.each do |code, msg|
80
+ xml = VirtualMerchant::XMLGenerator.error(code, msg)
81
+ response = VirtualMerchant::Response.new(xml)
82
+ VirtualMerchant::Logger.log_response(response)
83
+ response
84
+ end
85
+ end
61
86
  end
@@ -1,14 +1,12 @@
1
1
  module VirtualMerchant
2
2
  class Logger
3
- @@on = false
3
+ @@on = false
4
+ @@log_xml = false
4
5
 
5
- def self.on!
6
- @@on = true
7
- end
8
-
9
- def self.off!
10
- @@on = false
11
- end
6
+ def self.on!() @@on = true end
7
+ def self.off!() @@on = false end
8
+ def self.xml_on!() @@log_xml = true end
9
+ def self.xml_off!() @@log_xml = false end
12
10
 
13
11
  def self.log_response(response)
14
12
  return unless @@on
@@ -21,5 +19,12 @@ module VirtualMerchant
21
19
  p "result_message " + response.result_message
22
20
  p "!!!!!!!!!!!!!!!!!!!!!!!! End Credit Response !!!!!!!!!!!!!!!!!!!!!!!!!!!!"
23
21
  end
22
+
23
+ def self.xml(msg, xml)
24
+ return unless @@log_xml
25
+ puts msg
26
+ pp xml
27
+ end
28
+
24
29
  end
25
30
  end
@@ -8,6 +8,7 @@ module VirtualMerchant
8
8
  <ssl_pin>#{creds.pin}</ssl_pin>
9
9
  <ssl_txn_id>#{transaction_id}</ssl_txn_id>
10
10
  </txn>"
11
+ VirtualMerchant::Logger.xml('VOID OUTPUT', xml)
11
12
  return xml
12
13
  end
13
14
 
@@ -25,6 +26,7 @@ module VirtualMerchant
25
26
  xml += "<#{key}>#{value}</#{key}>"
26
27
  end
27
28
  xml += "</txn>"
29
+ VirtualMerchant::Logger.xml('NORMAL OUTPUT', xml)
28
30
  xml
29
31
  end
30
32
 
@@ -37,6 +39,7 @@ module VirtualMerchant
37
39
  xml += "<ssl_amount>#{amount.total}</ssl_amount>"
38
40
  end
39
41
  xml += "</txn>"
42
+ VirtualMerchant::Logger.xml('MODIFY TRANSACTION OUTPUT', xml)
40
43
  xml
41
44
  end
42
45
 
@@ -90,5 +93,13 @@ module VirtualMerchant
90
93
  end
91
94
  xml
92
95
  end
96
+
97
+ def self.error(code, message)
98
+ xml = "<txn>
99
+ <errorCode>#{code}</errorCode>
100
+ <errorMessage>#{message}</errorMessage>
101
+ </txn>"
102
+ xml
103
+ end
93
104
  end
94
105
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: virtual_merchant
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.8
4
+ version: 0.3.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Quarella
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-04-01 00:00:00.000000000 Z
11
+ date: 2014-06-16 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Makes it easy to charge credit cards with the VirtualMerchant API.
14
14
  email: leequarella@gmail.com
@@ -21,10 +21,10 @@ files:
21
21
  - lib/virtual_merchant/communication.rb
22
22
  - lib/virtual_merchant/credentials.rb
23
23
  - lib/virtual_merchant/credit_card.rb
24
+ - lib/virtual_merchant/gateway.rb
24
25
  - lib/virtual_merchant/logger.rb
25
26
  - lib/virtual_merchant/response.rb
26
27
  - lib/virtual_merchant/xml_generator.rb
27
- - lib/virtual_merchant/gateway.rb
28
28
  homepage: https://github.com/leequarella/VirtualMerchant-Ruby
29
29
  licenses:
30
30
  - MIT
@@ -35,17 +35,17 @@ require_paths:
35
35
  - lib
36
36
  required_ruby_version: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '>='
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  required_rubygems_version: !ruby/object:Gem::Requirement
42
42
  requirements:
43
- - - '>='
43
+ - - ">="
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
46
  requirements: []
47
47
  rubyforge_project:
48
- rubygems_version: 2.1.10
48
+ rubygems_version: 2.2.2
49
49
  signing_key:
50
50
  specification_version: 4
51
51
  summary: Virtual Merchant API