virtual_merchant 0.0.1

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,8 @@
1
+ class VMAmount
2
+ attr_accessor :total, :tax
3
+
4
+ def initialize(info)
5
+ @total = info[:total].to_s
6
+ @tax = info[:tax].to_s || "0.00"
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ class VMCredentials
2
+ attr_accessor :account_id, :user_id, :pin, :referer, :demo
3
+ def initialize(info)
4
+ @account_id = info[:account_id].to_s
5
+ @user_id = info[:user_id].to_s
6
+ @pin = info[:pin].to_s
7
+ @referer = info[:referer.to_s] || false
8
+ @demo = info[:demo] || false
9
+ end
10
+ end
@@ -0,0 +1,79 @@
1
+ class CreditCard
2
+ attr_accessor :name_on_card, :number, :expiration, :security_code, :last_four,
3
+ :swipe, :track2
4
+
5
+ def initialize(info)
6
+ if info[:swipe]
7
+ @swipe = info[:swipe]
8
+ self.from_swipe(swipe)
9
+ else
10
+ @name_on_card = info[:name_on_card] if info[:name_on_card]
11
+ @number = info[:number].to_s.gsub(/\s+/, "") if info[:number]
12
+ @expiration = info[:expiration].to_s if info[:expiration]
13
+ @security_code = info[:security_code].to_s if info[:security_code]
14
+ end
15
+ end
16
+
17
+ def from_swipe(swipe)
18
+ self.track2 = self.extract_track_2(swipe)
19
+ self.card_number = self.extract_card_number(swipe)
20
+ self.expiration = self.extract_expiration(swipe)
21
+ self.name_on_card = self.extract_name(swipe)
22
+ end
23
+
24
+ def self.extract_card_number(swipe)
25
+ card_number = swipe[2.. swipe.index('^')-1]
26
+ card_number = card_number.split(' ').join('')
27
+ end
28
+
29
+ def self.extract_expiration(swipe)
30
+ secondCarrot = swipe.index("^", swipe.index("^")+1)
31
+ card_expiration_year = swipe[secondCarrot+1..secondCarrot+2]
32
+ card_expiration_month = swipe[(secondCarrot + 3)..(secondCarrot + 4)]
33
+ card_expiration = card_expiration_month.to_s + card_expiration_year.to_s
34
+ end
35
+
36
+ def self.extract_name(swipe)
37
+ secondCarrot = swipe.index("^", swipe.index("^")+1)
38
+ if swipe.index('/')
39
+ first_name_on_card = swipe[swipe.index('/')+1..secondCarrot-1]
40
+ last_name_on_card = swipe[swipe.index('^')+1..swipe.index('/')-1]
41
+ else
42
+ if !swipe.index(" ")
43
+ first_name_on_card = "Gift"
44
+ last_name_on_card = "Card"
45
+ else
46
+ first_name_on_card = swipe.slice(swipe.index('^') + 1, swipe.index(' '))
47
+ last_name_on_card = swipe.slice(swipe.index(" ") + 1, secondCarrot)
48
+ end
49
+ end
50
+ name_on_card = first_name_on_card + " " + last_name_on_card
51
+ end
52
+
53
+ def self.extract_track_2(swipe)
54
+ # Magtek reader: Track 2 starts with a semi-colon and goes to the end
55
+ # I think that is standard for all readers, but not positive. -LQ
56
+ track2 = swipe.slice(swipe.index(";"), swipe.length)
57
+ if track2.index("+")
58
+ # Some AMEX have extra stuff at the end of track 2 that causes
59
+ #virtual merchant to return an INVLD DATA5623 message.
60
+ #Soooo... let's slice that off
61
+ track2 = track2.slice(0, track2.index("+"))
62
+ end
63
+ track2
64
+ end
65
+
66
+ def last_four
67
+ self.number[(self.number.length - 4)..self.number.length]
68
+ end
69
+
70
+ def blurred_number
71
+ number = self.card_number.to_s
72
+ leng = number.length
73
+ n = number[0..1]
74
+ (leng-6).times {n+= "*"}
75
+ n += number[number.length-4..number.length]
76
+ n
77
+ end
78
+
79
+ end
@@ -0,0 +1,117 @@
1
+ class VirtualMerchant
2
+ require "rexml/document"
3
+ require 'net/http'
4
+ require 'virtual_merchant/amount'
5
+ require 'virtual_merchant/credentials'
6
+ require 'virtual_merchant/credit_card'
7
+
8
+ def self.hi
9
+ puts "Hello"
10
+ end
11
+
12
+ def self.charge(card, amount, creds)
13
+ xml = self.generateXMLforVirtualMerchant(card, amount, creds)
14
+ vm_response = self.sendXMLtoVirtualMerchant(xml, creds)
15
+ response = self.generateResponse(vm_response)
16
+ self.printResponse(response)
17
+ response
18
+ end
19
+
20
+ def self.generateXMLforVirtualMerchant(card, amount, creds)
21
+ if amount.total.to_f > 0
22
+ #if the amount to be processed is a positive number, this is a sale
23
+ transactionType = 'ccsale'
24
+ else
25
+ #if the amount to be processed is a negative number, this is a return
26
+ transactionType = 'cccredit'
27
+ end
28
+
29
+ xml = "xmldata=<txn>
30
+ <ssl_merchant_id>" + creds.account_id + "</ssl_merchant_id>
31
+ <ssl_user_id>" + creds.user_id + "</ssl_user_id>
32
+ <ssl_pin>" + creds.pin + "</ssl_pin>
33
+ <ssl_transaction_type>" + transactionType + "</ssl_transaction_type>
34
+ <ssl_amount>" + amount.total + "</ssl_amount>
35
+ <ssl_salestax>" + amount.tax + "</ssl_salestax>
36
+ <ssl_customer_code>" + card.last_four + "</ssl_customer_code>
37
+ <ssl_card_present>Y</ssl_card_present>
38
+ <ssl_partial_auth_indicator>0</ssl_partial_auth_indicator>"
39
+ if card.track2
40
+ xml += "<ssl_track_data>" + card.track2 + " </ssl_track_data>"
41
+ else
42
+ #Manual Entry
43
+ xml += "<ssl_card_number>" + card.number.to_s + "</ssl_card_number>
44
+ <ssl_exp_date>" + card.expiration + "</ssl_exp_date>"
45
+ end
46
+
47
+ if !card.security_code || card.security_code == ""
48
+ xml += "<ssl_cvv2cvc2_indicator>0</ssl_cvv2cvc2_indicator>"
49
+ else
50
+ xml += "<ssl_cvv2cvc2_indicator>1</ssl_cvv2cvc2_indicator>
51
+ <ssl_cvv2cvc2>" + card.security_code + "</ssl_cvv2cvc2>"
52
+ end
53
+
54
+ xml += "</txn>"
55
+ return xml
56
+ end
57
+
58
+ def self.sendXMLtoVirtualMerchant(xml, creds)
59
+ if creds.referer
60
+ headers = {
61
+ 'Referer' => creds.referer#"https://rms.lucidfrog.com"
62
+ }
63
+ end
64
+ if creds.demo
65
+ uri=URI.parse('https://demo.myvirtualmerchant.com/VirtualMerchantDemo/processxml.do')
66
+ else
67
+ uri=URI.parse('https://www.myvirtualmerchant.com/VirtualMerchant/processxml.do')
68
+ end
69
+
70
+ http = Net::HTTP.new(uri.host, uri.port)
71
+ http.use_ssl = true
72
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
73
+ body = http.post(uri.request_uri, xml, headers).body
74
+ return body
75
+ end
76
+
77
+ def self.generateResponse(vm_response)
78
+ #decode XML sent back by virtualMerchant
79
+ response = {}
80
+ doc = REXML::Document.new(vm_response)
81
+ REXML::XPath.each(doc, "txn") do |xml|
82
+ if xml.elements["errorCode"]
83
+ #Something was wrong with the transaction so an errorCode and errorMessage were sent back
84
+ response = {
85
+ error: xml.elements["errorCode"].text,
86
+ result_message: xml.elements["errorMessage"].text
87
+ }
88
+ else
89
+ #a clean transaction has taken place
90
+ response = {
91
+ result_message: xml.elements["ssl_result_message"].text,
92
+ result: xml.elements["ssl_result"].text,
93
+ cardNumBlurred: xml.elements["ssl_card_number"].text,
94
+ exp_date: xml.elements["ssl_exp_date"].text,
95
+ approval_code: xml.elements["ssl_approval_code"].text,
96
+ cvv2_response: xml.elements["ssl_cvv2_response"].text,
97
+ transaction_id: xml.elements["ssl_txn_id"].text,
98
+ transaction_time: xml.elements["ssl_txn_time"].text
99
+ }
100
+ end
101
+ end
102
+ response
103
+ end
104
+
105
+ def self.printResponse(response)
106
+ p "!!!!!!!!!!!!!!!!!!!!!!!! Credit Response !!!!!!!!!!!!!!!!!!!!!!!!!!!!"
107
+ if response[:result]
108
+ p "ssl_result " + response[:result]
109
+ p "ssl_result_message " + response[:result_message]
110
+ p "ssl_transaction_time " + response[:transaction_time]
111
+ elsif response[:error]
112
+ p "error " + response[:error]
113
+ p "error_message " + response[:error_message] if response[:error_message]
114
+ end
115
+ p "!!!!!!!!!!!!!!!!!!!!!!!! End Credit Response !!!!!!!!!!!!!!!!!!!!!!!!!!!!"
116
+ end
117
+ end
metadata ADDED
@@ -0,0 +1,48 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: virtual_merchant
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Lee Quarella
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-07 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Makes it easy to charge credit cards with the VirtualMerchant API.
15
+ email: lee@lucidfrog.com
16
+ executables: []
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - lib/virtual_merchant.rb
21
+ - lib/virtual_merchant/amount.rb
22
+ - lib/virtual_merchant/credentials.rb
23
+ - lib/virtual_merchant/credit_card.rb
24
+ homepage: http://rubygems.org/gems/virtual_merchant_ruby
25
+ licenses: []
26
+ post_install_message:
27
+ rdoc_options: []
28
+ require_paths:
29
+ - lib
30
+ required_ruby_version: !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ! '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 1.8.24
45
+ signing_key:
46
+ specification_version: 3
47
+ summary: Virtual Merchant API
48
+ test_files: []