virtual_merchant 0.3.8 → 0.3.9

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.
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