virtual_merchant 0.2.0 → 0.3.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.
- 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: []
|