virtual_merchant 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/lib/virtual_merchant/amount.rb +5 -2
- data/lib/virtual_merchant/communication.rb +1 -1
- data/lib/virtual_merchant/credentials.rb +7 -5
- data/lib/virtual_merchant/credit_card.rb +51 -24
- data/lib/virtual_merchant/gateway.rb +15 -0
- data/lib/virtual_merchant/xml_generator.rb +50 -20
- data/lib/virtual_merchant.rb +6 -18
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
ZTFiZTM4NWFjODQ1MTlkNzE1ZWM5ZWYyZmM1YzUwZTRiMmJmMjFmZmYwMTBh
|
10
|
-
MmM0YjU2OGM2YzExOTVjMWE2Y2ZiOWQ1OGMyNjU3M2Q2YTc0YmQyMzBiZjRh
|
11
|
-
MzZkYjE4ODdiZWZlYjhiMjlkNmM3MDc5N2NmYTRmYzkwZDc5MTM=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
ZGZkMjE2NTRhNWE0NWFiMzAzMTg4YWMxNjkyY2UxNGQyZWE0ZWU0ZjcwMmI2
|
14
|
-
MDU1MDMzNmMwYzYzYzRhMjdmZDA3ZjA4NzYzNjNmYWEwNDU1NzgwMzIzODA5
|
15
|
-
MmM3YjA5YWU1NDBlOWFhMzJiMDYxNjg3MWE0MDZhYzBkOTllZjk=
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 46204446428b1622e9b110648939ae78cf76d590
|
4
|
+
data.tar.gz: fe22c7d7dcac323eabb80bbdb7667bd662db5ed7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c770b2741ab9244fc44194c59910a9eb98b50c5b6d741cac9d3094ee0d86efad994d348d4ccd20c753470274f6c7e612818d91bcf2adffbd4fb283168c188e08
|
7
|
+
data.tar.gz: 99ab5a4567ca7155aca9b60953934079e2017bea7567c973a64a4fca330269dbb8eee4c3540e404c4deedaef529892794fb78cd59951ce60b82a3d776286c34b
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module VirtualMerchant
|
2
2
|
class Amount
|
3
|
-
attr_accessor :total, :tax
|
4
|
-
|
3
|
+
attr_accessor :total, :tax, :next_payment_date, :billing_cycle, :end_of_month
|
4
|
+
|
5
5
|
def initialize(info)
|
6
6
|
@total = sprintf( "%0.02f", info[:total])
|
7
7
|
if info[:tax]
|
@@ -9,6 +9,9 @@ module VirtualMerchant
|
|
9
9
|
else
|
10
10
|
@tax = "0.00"
|
11
11
|
end
|
12
|
+
@next_payment_date = info[:next_payment_date]
|
13
|
+
@billing_cycle = info[:billing_cycle]
|
14
|
+
@end_of_month = info[:end_of_month] || 'Y'
|
12
15
|
end
|
13
16
|
end
|
14
17
|
end
|
@@ -1,12 +1,14 @@
|
|
1
1
|
module VirtualMerchant
|
2
2
|
class Credentials
|
3
|
-
attr_accessor :account_id, :user_id, :pin, :referer, :demo
|
3
|
+
attr_accessor :account_id, :user_id, :pin, :referer, :demo, :source, :ksn
|
4
4
|
def initialize(info)
|
5
5
|
@account_id = info[:account_id].to_s
|
6
|
-
@user_id
|
7
|
-
@pin
|
8
|
-
@
|
9
|
-
@
|
6
|
+
@user_id = info[:user_id].to_s
|
7
|
+
@pin = info[:pin].to_s
|
8
|
+
@source = info[:source].to_s
|
9
|
+
@ksn = info[:ksn].to_s
|
10
|
+
@referer = info[:referer].to_s
|
11
|
+
@demo = info[:demo] || false
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -1,10 +1,14 @@
|
|
1
1
|
module VirtualMerchant
|
2
2
|
class CreditCard
|
3
|
-
attr_accessor :name_on_card, :number, :expiration, :security_code, :
|
4
|
-
:
|
3
|
+
attr_accessor :name_on_card, :number, :expiration, :security_code, :swipe, :track2,
|
4
|
+
:encrypted_track_1, :encrypted_track_2, :last_four, :encrypted, :swiped
|
5
5
|
|
6
6
|
def self.from_swipe(swipe)
|
7
|
-
|
7
|
+
if swipe.class == Hash && swipe[:encrypted]
|
8
|
+
new(swipe)
|
9
|
+
else
|
10
|
+
new(swipe: swipe)
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
def self.from_manual(data)
|
@@ -12,23 +16,47 @@ module VirtualMerchant
|
|
12
16
|
end
|
13
17
|
|
14
18
|
def initialize(info)
|
15
|
-
if info[:
|
16
|
-
|
17
|
-
|
19
|
+
if info[:encrypted]
|
20
|
+
self.from_encrypted(info)
|
21
|
+
elsif info[:swipe]
|
22
|
+
self.from_swipe(info[:swipe])
|
18
23
|
else
|
19
|
-
|
20
|
-
@number = info[:number].to_s.gsub(/\s+/, "") if info[:number]
|
21
|
-
@expiration = info[:expiration].to_s if info[:expiration]
|
22
|
-
@security_code = info[:security_code].to_s if info[:security_code]
|
23
|
-
@track2 = info[:track_2] if info[:track_2]
|
24
|
+
self.from_manual(info)
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
def from_encrypted (info)
|
29
|
+
@encrypted = true
|
30
|
+
@encrypted_track_1 = info[:track_1]
|
31
|
+
@encrypted_track_2 = info[:track_2]
|
32
|
+
@last_four = info[:last_four]
|
33
|
+
end
|
34
|
+
|
35
|
+
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
|
43
|
+
end
|
44
|
+
|
45
|
+
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
|
52
|
+
end
|
53
|
+
|
54
|
+
def encrypted?
|
55
|
+
self.encrypted
|
56
|
+
end
|
57
|
+
|
58
|
+
def swiped?
|
59
|
+
self.swiped
|
32
60
|
end
|
33
61
|
|
34
62
|
def extract_card_number(swipe)
|
@@ -42,7 +70,7 @@ module VirtualMerchant
|
|
42
70
|
card_expiration_month = swipe[(secondCarrot + 3)..(secondCarrot + 4)]
|
43
71
|
card_expiration = card_expiration_month.to_s + card_expiration_year.to_s
|
44
72
|
end
|
45
|
-
|
73
|
+
|
46
74
|
def extract_name(swipe)
|
47
75
|
secondCarrot = swipe.index("^", swipe.index("^")+1)
|
48
76
|
if swipe.index('/')
|
@@ -59,24 +87,24 @@ module VirtualMerchant
|
|
59
87
|
end
|
60
88
|
name_on_card = first_name_on_card + " " + last_name_on_card
|
61
89
|
end
|
62
|
-
|
90
|
+
|
63
91
|
def extract_track_2(swipe)
|
64
92
|
# Magtek reader: Track 2 starts with a semi-colon and goes to the end
|
65
93
|
# I think that is standard for all readers, but not positive. -LQ
|
66
94
|
track2 = swipe.slice(swipe.index(";"), swipe.length)
|
67
95
|
if track2.index("+")
|
68
|
-
# Some AMEX have extra stuff at the end of track 2 that causes
|
96
|
+
# Some AMEX have extra stuff at the end of track 2 that causes
|
69
97
|
#virtual merchant to return an INVLD DATA5623 message.
|
70
|
-
#Soooo... let's slice that off
|
98
|
+
#Soooo... let's slice that off
|
71
99
|
track2 = track2.slice(0, track2.index("+"))
|
72
100
|
end
|
73
101
|
track2
|
74
102
|
end
|
75
|
-
|
76
|
-
def
|
103
|
+
|
104
|
+
def extract_last_four
|
77
105
|
self.number[(self.number.length - 4)..self.number.length]
|
78
106
|
end
|
79
|
-
|
107
|
+
|
80
108
|
def blurred_number
|
81
109
|
number = self.number.to_s
|
82
110
|
leng = number.length
|
@@ -85,6 +113,5 @@ module VirtualMerchant
|
|
85
113
|
n += number[number.length-4..number.length]
|
86
114
|
n
|
87
115
|
end
|
88
|
-
|
89
116
|
end
|
90
117
|
end
|
@@ -11,6 +11,21 @@ class Gateway
|
|
11
11
|
process(xml, amount)
|
12
12
|
end
|
13
13
|
|
14
|
+
def ccaddrecurring(card, amount)
|
15
|
+
xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, "ccaddrecurring")
|
16
|
+
process(xml, amount)
|
17
|
+
end
|
18
|
+
|
19
|
+
def cccredit(card, amount)
|
20
|
+
xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, 'cccredit')
|
21
|
+
process(xml, amount)
|
22
|
+
end
|
23
|
+
|
24
|
+
def ccvoid(transaction_id)
|
25
|
+
xml = VirtualMerchant::XMLGenerator.generateVoid(transaction_id, creds)
|
26
|
+
process(xml)
|
27
|
+
end
|
28
|
+
|
14
29
|
def process(xml, amount=0)
|
15
30
|
communication = VirtualMerchant::Communication.new(
|
16
31
|
{xml: xml, url: url(creds.demo), referer: creds.referer})
|
@@ -2,43 +2,73 @@ module VirtualMerchant
|
|
2
2
|
class XMLGenerator
|
3
3
|
def self.generateVoid(transaction_id, creds)
|
4
4
|
xml = "xmldata=<txn>
|
5
|
+
<ssl_transaction_type>ccvoid</ssl_transaction_type>
|
5
6
|
<ssl_merchant_id>#{creds.account_id}</ssl_merchant_id>
|
6
7
|
<ssl_user_id>#{creds.user_id}</ssl_user_id>
|
7
8
|
<ssl_pin>#{creds.pin}</ssl_pin>
|
8
|
-
<ssl_transaction_type>ccvoid</ssl_transaction_type>
|
9
9
|
<ssl_txn_id>#{transaction_id}</ssl_txn_id>
|
10
10
|
</txn>"
|
11
11
|
return xml
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.generate(card, amount, creds, transaction_type)
|
15
|
-
xml = "xmldata=<txn>
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
15
|
+
xml = "xmldata=<txn>"
|
16
|
+
xml += basic(card, creds, transaction_type, amount)
|
17
|
+
xml += for_recurring(amount) if transaction_type == 'ccaddrecurring'
|
18
|
+
if card.encrypted?
|
19
|
+
xml += for_encrypted(card, creds)
|
20
|
+
else
|
21
|
+
xml += for_clear_text(card)
|
22
|
+
end
|
23
|
+
xml += "</txn>"
|
24
|
+
xml
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def self.basic(card, creds, transaction_type, amount)
|
29
|
+
"<ssl_merchant_id>#{creds.account_id}</ssl_merchant_id>
|
30
|
+
<ssl_user_id>#{creds.user_id}</ssl_user_id>
|
31
|
+
<ssl_pin>#{creds.pin}</ssl_pin>
|
32
|
+
<ssl_transaction_type>#{transaction_type}</ssl_transaction_type>
|
33
|
+
<ssl_amount>#{amount.total}</ssl_amount>
|
34
|
+
<ssl_salestax>#{amount.tax}</ssl_salestax>
|
35
|
+
<ssl_customer_code>#{card.last_four}</ssl_customer_code>
|
36
|
+
<ssl_card_present>Y</ssl_card_present>
|
37
|
+
<ssl_partial_auth_indicator>0</ssl_partial_auth_indicator>"
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.for_clear_text(card)
|
41
|
+
if card.swiped?
|
42
|
+
"<ssl_track_data>#{card.track2}</ssl_track_data>"
|
27
43
|
else
|
28
|
-
|
29
|
-
xml += "<ssl_card_number>" + card.number.to_s + "</ssl_card_number>
|
30
|
-
<ssl_exp_date>" + card.expiration + "</ssl_exp_date>"
|
44
|
+
manual(card)
|
31
45
|
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.for_recurring(amount)
|
49
|
+
"<ssl_next_payment_date>#{amount.next_payment_date}</ssl_next_payment_date>
|
50
|
+
<ssl_billing_cycle>#{amount.billing_cycle}</ssl_billing_cycle>
|
51
|
+
<ssl_end_of_month>#{amount.end_of_month}</ssl_end_of_month>"
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.for_encrypted(card, creds)
|
55
|
+
"<ssl_vm_encrypted_device>003</ssl_vm_encrypted_device>
|
56
|
+
<ssl_vm_mobile_source>#{creds.source}</ssl_vm_mobile_source>
|
57
|
+
<ssl_encrypted_track1_data>#{card.encrypted_track_1}</ssl_encrypted_track1_data>
|
58
|
+
<ssl_encrypted_track2_data>#{card.encrypted_track_2}</ssl_encrypted_track2_data>
|
59
|
+
<ssl_ksn>#{creds.ksn}</ssl_ksn>"
|
60
|
+
end
|
32
61
|
|
62
|
+
def self.manual(card)
|
63
|
+
xml = "<ssl_card_number>#{card.number.to_s}</ssl_card_number>
|
64
|
+
<ssl_exp_date>#{card.expiration}</ssl_exp_date>"
|
33
65
|
if !card.security_code || card.security_code == ""
|
34
66
|
xml += "<ssl_cvv2cvc2_indicator>0</ssl_cvv2cvc2_indicator>"
|
35
67
|
else
|
36
68
|
xml += "<ssl_cvv2cvc2_indicator>1</ssl_cvv2cvc2_indicator>
|
37
|
-
|
69
|
+
<ssl_cvv2cvc2>#{card.security_code}</ssl_cvv2cvc2>"
|
38
70
|
end
|
39
|
-
|
40
|
-
xml += "</txn>"
|
41
|
-
return xml
|
71
|
+
xml
|
42
72
|
end
|
43
73
|
end
|
44
74
|
end
|
data/lib/virtual_merchant.rb
CHANGED
@@ -8,31 +8,19 @@ require 'virtual_merchant/logger'
|
|
8
8
|
require 'virtual_merchant/xml_generator'
|
9
9
|
require 'virtual_merchant/gateway'
|
10
10
|
module VirtualMerchant
|
11
|
-
|
12
11
|
def self.charge(card, amount, creds, gateway=Gateway.new(creds))
|
13
12
|
gateway.ccsale(card, amount)
|
14
|
-
#xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, "ccsale")
|
15
13
|
end
|
16
14
|
|
17
|
-
def self.
|
18
|
-
|
19
|
-
self.process(xml, creds, amount)
|
15
|
+
def self.add_recurring(card, amount, creds, gateway=Gateway.new(creds))
|
16
|
+
gateway.ccaddrecurring(card, amount)
|
20
17
|
end
|
21
18
|
|
22
|
-
def self.
|
23
|
-
|
24
|
-
self.process(xml, creds)
|
19
|
+
def self.refund(card, amount, creds, gateway=Gateway.new(creds))
|
20
|
+
gateway.cccredit(card, amount)
|
25
21
|
end
|
26
22
|
|
27
|
-
|
28
|
-
|
29
|
-
Gateway.new(creds).process(xml, amount=0)
|
30
|
-
#communication = VirtualMerchant::Communication.new(
|
31
|
-
# {xml: xml, url: self.url(creds.demo), referer: creds.referer})
|
32
|
-
#vm_response = communication.send
|
33
|
-
#response = VirtualMerchant::Response.new(vm_response)
|
34
|
-
#VirtualMerchant::Logger.new(response)
|
35
|
-
#response
|
23
|
+
def self.void(transaction_id, creds, gateway=Gateway.new(creds))
|
24
|
+
gateway.ccvoid(transaction_id)
|
36
25
|
end
|
37
|
-
|
38
26
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: virtual_merchant
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lee Quarella
|
@@ -34,12 +34,12 @@ require_paths:
|
|
34
34
|
- lib
|
35
35
|
required_ruby_version: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
|
-
- -
|
37
|
+
- - '>='
|
38
38
|
- !ruby/object:Gem::Version
|
39
39
|
version: '0'
|
40
40
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
41
41
|
requirements:
|
42
|
-
- -
|
42
|
+
- - '>='
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
version: '0'
|
45
45
|
requirements: []
|