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 CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZWRkYmEzZDFhMTBlZmIzNjgyMzYxZGYwYTIxYTJlNzU3MWQ3YjJmOQ==
5
- data.tar.gz: !binary |-
6
- N2ZjYzllMDY5OTYxZWU2NzIwMDE0NjUzNDFiNGFiNzgzODdlMjA4Nw==
7
- !binary "U0hBNTEy":
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
@@ -18,7 +18,7 @@ module VirtualMerchant
18
18
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
19
19
  begin
20
20
  http.post(uri.request_uri, xml, header).body
21
- rescue
21
+ rescue Exception => e
22
22
  false
23
23
  end
24
24
  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 = info[:user_id].to_s
7
- @pin = info[:pin].to_s
8
- @referer = info[:referer].to_s
9
- @demo = info[:demo] || false
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, :last_four,
4
- :swipe, :track2
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
- new(swipe: swipe)
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[:swipe]
16
- @swipe = info[:swipe]
17
- self.from_swipe(swipe)
19
+ if info[:encrypted]
20
+ self.from_encrypted(info)
21
+ elsif info[:swipe]
22
+ self.from_swipe(info[:swipe])
18
23
  else
19
- @name_on_card = info[:name_on_card] if info[:name_on_card]
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 from_swipe(swipe)
28
- self.track2 = extract_track_2(swipe)
29
- self.number = extract_card_number(swipe)
30
- self.expiration = extract_expiration(swipe)
31
- self.name_on_card = extract_name(swipe)
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 last_four
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
- <ssl_merchant_id>" + creds.account_id + "</ssl_merchant_id>
17
- <ssl_user_id>" + creds.user_id + "</ssl_user_id>
18
- <ssl_pin>" + creds.pin + "</ssl_pin>
19
- <ssl_transaction_type>" + transaction_type + "</ssl_transaction_type>
20
- <ssl_amount>" + amount.total + "</ssl_amount>
21
- <ssl_salestax>" + amount.tax + "</ssl_salestax>
22
- <ssl_customer_code>" + card.last_four + "</ssl_customer_code>
23
- <ssl_card_present>Y</ssl_card_present>
24
- <ssl_partial_auth_indicator>0</ssl_partial_auth_indicator>"
25
- if card.track2
26
- xml += "<ssl_track_data>" + card.track2 + " </ssl_track_data>"
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
- #Manual Entry
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
- <ssl_cvv2cvc2>" + card.security_code + "</ssl_cvv2cvc2>"
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
@@ -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.refund(card, amount, creds)
18
- xml = VirtualMerchant::XMLGenerator.generate(card, amount, creds, 'cccredit')
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.void(transaction_id, creds)
23
- xml = VirtualMerchant::XMLGenerator.generateVoid(transaction_id, creds)
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
- private
28
- def self.process(xml, creds, amount=0)
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.2.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: []