vantiv 0.1.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.
Files changed (128) hide show
  1. checksums.yaml +7 -0
  2. data/.env.example +4 -0
  3. data/.gitignore +11 -0
  4. data/.rspec +2 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +5 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE.txt +21 -0
  9. data/README.md +354 -0
  10. data/Rakefile +6 -0
  11. data/bin/console +19 -0
  12. data/bin/generate_sandbox_fixtures +23 -0
  13. data/bin/paypage_server +20 -0
  14. data/bin/setup +7 -0
  15. data/cert_fixtures/L_AC_1.json +27 -0
  16. data/cert_fixtures/L_AC_1A.json +8 -0
  17. data/cert_fixtures/L_AC_2.json +27 -0
  18. data/cert_fixtures/L_AC_2A.json +8 -0
  19. data/cert_fixtures/L_AC_3.json +26 -0
  20. data/cert_fixtures/L_AC_3A.json +8 -0
  21. data/cert_fixtures/L_AC_4.json +25 -0
  22. data/cert_fixtures/L_AC_4A.json +8 -0
  23. data/cert_fixtures/L_AC_5.json +18 -0
  24. data/cert_fixtures/L_AC_5A.json +8 -0
  25. data/cert_fixtures/L_AC_6.json +27 -0
  26. data/cert_fixtures/L_AC_7.json +26 -0
  27. data/cert_fixtures/L_AC_8.json +26 -0
  28. data/cert_fixtures/L_AC_9.json +26 -0
  29. data/cert_fixtures/L_AR_1.json +27 -0
  30. data/cert_fixtures/L_AR_1A.json +9 -0
  31. data/cert_fixtures/L_AR_1B.json +8 -0
  32. data/cert_fixtures/L_AR_2.json +27 -0
  33. data/cert_fixtures/L_AR_2A.json +8 -0
  34. data/cert_fixtures/L_AR_3.json +26 -0
  35. data/cert_fixtures/L_AR_3A.json +8 -0
  36. data/cert_fixtures/L_AR_4.json +25 -0
  37. data/cert_fixtures/L_AR_4A.json +9 -0
  38. data/cert_fixtures/L_AR_4B.json +9 -0
  39. data/cert_fixtures/L_AR_5.json +17 -0
  40. data/cert_fixtures/L_AR_5A.json +9 -0
  41. data/cert_fixtures/L_EP_1.json +15 -0
  42. data/cert_fixtures/L_EP_2.json +15 -0
  43. data/cert_fixtures/L_EP_3.json +11 -0
  44. data/cert_fixtures/L_EP_4.json +15 -0
  45. data/cert_fixtures/L_EP_5.json +15 -0
  46. data/cert_fixtures/L_EP_6.json +15 -0
  47. data/cert_fixtures/L_EP_7.json +15 -0
  48. data/cert_fixtures/L_RC_1.json +27 -0
  49. data/cert_fixtures/L_RC_1A.json +8 -0
  50. data/cert_fixtures/L_RC_1B.json +8 -0
  51. data/cert_fixtures/L_RC_2.json +27 -0
  52. data/cert_fixtures/L_RC_2A.json +8 -0
  53. data/cert_fixtures/L_RC_2B.json +8 -0
  54. data/cert_fixtures/L_RC_3.json +26 -0
  55. data/cert_fixtures/L_RC_3A.json +8 -0
  56. data/cert_fixtures/L_RC_3B.json +8 -0
  57. data/cert_fixtures/L_RC_4.json +25 -0
  58. data/cert_fixtures/L_RC_4A.json +8 -0
  59. data/cert_fixtures/L_RC_4B.json +8 -0
  60. data/cert_fixtures/L_RC_5.json +18 -0
  61. data/cert_fixtures/L_RC_5A.json +8 -0
  62. data/cert_fixtures/L_RC_5B.json +8 -0
  63. data/cert_fixtures/L_RC_6.json +27 -0
  64. data/cert_fixtures/L_RC_6A.json +8 -0
  65. data/cert_fixtures/L_RC_7.json +26 -0
  66. data/cert_fixtures/L_RC_7A.json +8 -0
  67. data/cert_fixtures/L_RC_8.json +18 -0
  68. data/cert_fixtures/L_S_1.json +27 -0
  69. data/cert_fixtures/L_S_2.json +27 -0
  70. data/cert_fixtures/L_S_3.json +26 -0
  71. data/cert_fixtures/L_S_4.json +25 -0
  72. data/cert_fixtures/L_S_5.json +18 -0
  73. data/cert_fixtures/L_S_6.json +26 -0
  74. data/cert_fixtures/L_S_7.json +26 -0
  75. data/cert_fixtures/L_S_8.json +26 -0
  76. data/cert_fixtures/L_S_9.json +26 -0
  77. data/cert_fixtures/L_T_1.json +11 -0
  78. data/cert_fixtures/L_T_10.json +19 -0
  79. data/cert_fixtures/L_T_11.json +19 -0
  80. data/cert_fixtures/L_T_2.json +11 -0
  81. data/cert_fixtures/L_T_3.json +12 -0
  82. data/cert_fixtures/L_T_4.json +11 -0
  83. data/cert_fixtures/L_T_6.json +19 -0
  84. data/cert_fixtures/L_T_7.json +19 -0
  85. data/cert_fixtures/L_T_8.json +19 -0
  86. data/cert_fixtures/L_T_9.json +20 -0
  87. data/cert_fixtures/L_V_1.json +27 -0
  88. data/cert_fixtures/L_V_1A.json +8 -0
  89. data/cert_fixtures/L_V_1B.json +8 -0
  90. data/cert_fixtures/L_V_1C.json +8 -0
  91. data/cert_fixtures/L_V_2.json +27 -0
  92. data/cert_fixtures/L_V_2A.json +8 -0
  93. data/cert_fixtures/L_V_3.json +18 -0
  94. data/cert_fixtures/L_V_3A.json +8 -0
  95. data/cert_fixtures/L_V_4.json +26 -0
  96. data/cert_fixtures/L_V_4A.json +8 -0
  97. data/exe/vantiv-certify-app +23 -0
  98. data/lib/vantiv.rb +152 -0
  99. data/lib/vantiv/api.rb +10 -0
  100. data/lib/vantiv/api/capture_response.rb +26 -0
  101. data/lib/vantiv/api/endpoints.rb +15 -0
  102. data/lib/vantiv/api/live_transaction_response.rb +50 -0
  103. data/lib/vantiv/api/request.rb +75 -0
  104. data/lib/vantiv/api/request_body.rb +111 -0
  105. data/lib/vantiv/api/request_body_generator.rb +43 -0
  106. data/lib/vantiv/api/response.rb +50 -0
  107. data/lib/vantiv/api/tied_transaction_response.rb +30 -0
  108. data/lib/vantiv/api/tokenization_response.rb +45 -0
  109. data/lib/vantiv/certification/cert_request_body_compiler.rb +38 -0
  110. data/lib/vantiv/certification/paypage_driver.rb +54 -0
  111. data/lib/vantiv/certification/paypage_server.rb +70 -0
  112. data/lib/vantiv/certification/response_cache.rb +29 -0
  113. data/lib/vantiv/certification/validation_test_runner.rb +103 -0
  114. data/lib/vantiv/certification/views/index.html.erb +76 -0
  115. data/lib/vantiv/environment.rb +14 -0
  116. data/lib/vantiv/mocked_sandbox.rb +29 -0
  117. data/lib/vantiv/mocked_sandbox/api_request.rb +53 -0
  118. data/lib/vantiv/mocked_sandbox/fixture_generator.rb +48 -0
  119. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--4457002100000005.json.erb +23 -0
  120. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--4457010000000009.json.erb +23 -0
  121. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--4457010010900010.json.erb +21 -0
  122. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--5112001600000006.json.erb +23 -0
  123. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--5112001900000003.json.erb +23 -0
  124. data/lib/vantiv/paypage.rb +7 -0
  125. data/lib/vantiv/test_card.rb +94 -0
  126. data/lib/vantiv/version.rb +3 -0
  127. data/vantiv-ruby.gemspec +29 -0
  128. metadata +271 -0
@@ -0,0 +1,20 @@
1
+ {
2
+ "endpoint": "AUTHORIZATION",
3
+ "body": {
4
+ "Transaction": {
5
+ "ReferenceNumber": "1",
6
+ "TransactionAmount": "150.00",
7
+ "OrderSource": "ecommerce",
8
+ "CustomerID": "345",
9
+ "PartialApprovedFlag": "false"
10
+ },
11
+ "Card": {
12
+ "ExpirationMonth": "11",
13
+ "ExpirationYear": "16",
14
+ "CVV": "987"
15
+ },
16
+ "PaymentAccount": {
17
+ "PaymentAccountID": "#{L_T_8.litleOnlineResponse.authorizationResponse.tokenResponse.PaymentAccountID}"
18
+ }
19
+ }
20
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "endpoint": "AUTHORIZATION",
3
+ "body": {
4
+ "Transaction": {
5
+ "ReferenceNumber": "1",
6
+ "TransactionAmount": "101.00",
7
+ "OrderSource": "ecommerce",
8
+ "CustomerID": "345",
9
+ "PartialApprovedFlag": "false"
10
+ },
11
+ "Card": {
12
+ "Type": "VI",
13
+ "CardNumber": "4457010000000009",
14
+ "ExpirationMonth": "01",
15
+ "ExpirationYear": "16",
16
+ "CVV": "349"
17
+ },
18
+ "Address": {
19
+ "BillingName": "John & Mary Smith",
20
+ "BillingAddress1": "1 Main St.",
21
+ "BillingCity": "Burlington",
22
+ "BillingState": "MA",
23
+ "BillingZipcode": "01803-3747",
24
+ "BillingCountry": "US"
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "endpoint": "CAPTURE",
3
+ "body": {
4
+ "Transaction": {
5
+ "TransactionID": "#{L_V_1.litleOnlineResponse.authorizationResponse.TransactionID}"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "endpoint": "CREDIT",
3
+ "body": {
4
+ "Transaction": {
5
+ "TransactionID": "#{L_V_1A.litleOnlineResponse.captureResponse.TransactionID}"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "endpoint": "VOID",
3
+ "body": {
4
+ "Transaction": {
5
+ "TransactionID": "#{L_V_1B.litleOnlineResponse.creditResponse.TransactionID}"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "endpoint": "SALE",
3
+ "body": {
4
+ "Transaction": {
5
+ "ReferenceNumber": "1",
6
+ "TransactionAmount": "101.00",
7
+ "OrderSource": "ecommerce",
8
+ "CustomerID": "345"
9
+ },
10
+ "Card": {
11
+ "Type": "MC",
12
+ "CardNumber": "5112010000000003",
13
+ "ExpirationMonth": "02",
14
+ "ExpirationYear": "16",
15
+ "CVV": "261"
16
+ },
17
+ "Address": {
18
+ "BillingName": "Mike J. Hammer",
19
+ "BillingAddress1": "2 Main St.",
20
+ "BillingAddress2": "Apt. 222",
21
+ "BillingCity": "Riverside",
22
+ "BillingState": "RI",
23
+ "BillingZipcode": "02915",
24
+ "BillingCountry": "US"
25
+ }
26
+ }
27
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "endpoint": "VOID",
3
+ "body": {
4
+ "Transaction": {
5
+ "TransactionID": "#{L_V_2.litleOnlineResponse.saleResponse.TransactionID}"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "endpoint": "RETURN",
3
+ "body": {
4
+ "Transaction": {
5
+ "ReferenceNumber": "1",
6
+ "TransactionAmount": "101.00",
7
+ "OrderSource": "ecommerce",
8
+ "CustomerID": "345"
9
+ },
10
+ "Card": {
11
+ "Type": "VI",
12
+ "CardNumber": "4457010000000009",
13
+ "ExpirationMonth": "01",
14
+ "ExpirationYear": "16",
15
+ "CVV": "349"
16
+ }
17
+ }
18
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "endpoint": "VOID",
3
+ "body": {
4
+ "Transaction": {
5
+ "TransactionID": "#{L_V_3.litleOnlineResponse.creditResponse.TransactionID}"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "endpoint": "SALE",
3
+ "body": {
4
+ "Transaction": {
5
+ "ReferenceNumber": "1",
6
+ "TransactionAmount": "101.00",
7
+ "OrderSource": "ecommerce",
8
+ "CustomerID": "345"
9
+ },
10
+ "Card": {
11
+ "Type": "VI",
12
+ "CardNumber": "4457010100000008",
13
+ "ExpirationMonth": "06",
14
+ "ExpirationYear": "16",
15
+ "CVV": "992"
16
+ },
17
+ "Address": {
18
+ "BillingName": "Joe Green",
19
+ "BillingAddress1": "6 Main St.",
20
+ "BillingCity": "Derry",
21
+ "BillingState": "NH",
22
+ "BillingZipcode": "03038",
23
+ "BillingCountry": "US"
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "endpoint": "VOID",
3
+ "body": {
4
+ "Transaction": {
5
+ "TransactionID": "#{L_V_4.litleOnlineResponse.saleResponse.TransactionID}"
6
+ }
7
+ }
8
+ }
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'vantiv'
4
+ require 'vantiv/certification/validation_test_runner'
5
+
6
+ unless ENV['ACCEPTOR_ID'] && ENV['LICENSE_ID'] && ENV['PAYPAGE_ID']
7
+ raise "Vantiv License ID, Acceptor ID, Paypage ID and Application ID required"
8
+ end
9
+
10
+ Vantiv.configure do |config|
11
+ config.license_id = ENV["LICENSE_ID"]
12
+ config.acceptor_id = ENV["ACCEPTOR_ID"]
13
+ config.paypage_id = ENV["PAYPAGE_ID"]
14
+
15
+ config.default_report_group = '1'
16
+ end
17
+
18
+ Vantiv::Certification::ValidationTestRunner.run(
19
+ filter_by: ENV["FILTER_BY"],
20
+ save_to: "certs.txt"
21
+ )
22
+
23
+ %x(open certs.txt)
@@ -0,0 +1,152 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'vantiv/api'
4
+ require 'vantiv/test_card'
5
+ require 'vantiv/environment'
6
+ require 'vantiv/mocked_sandbox'
7
+ require 'vantiv/paypage'
8
+
9
+ module Vantiv
10
+ def self.tokenize(temporary_token:)
11
+ if temporary_token == "" or temporary_token == nil
12
+ raise ArgumentError.new("Blank temporary token (PaypageRegistrationID): \n
13
+ Check that paypage error handling is implemented correctly.")
14
+ end
15
+
16
+ body = Api::RequestBody.for_tokenization(
17
+ paypage_registration_id: temporary_token
18
+ )
19
+ Api::Request.new(
20
+ endpoint: Api::Endpoints::TOKENIZATION,
21
+ body: body,
22
+ response_object: Api::TokenizationResponse.new
23
+ ).run
24
+ end
25
+
26
+ def self.tokenize_by_direct_post(card_number:, expiry_month:, expiry_year:, cvv:)
27
+ body = Api::RequestBody.for_direct_post_tokenization(
28
+ card_number: card_number,
29
+ expiry_month: expiry_month,
30
+ expiry_year: expiry_year,
31
+ cvv: cvv
32
+ )
33
+ Api::Request.new(
34
+ endpoint: Api::Endpoints::TOKENIZATION,
35
+ body: body,
36
+ response_object: Api::TokenizationResponse.new
37
+ ).run
38
+ end
39
+
40
+ def self.auth(amount:, payment_account_id:, customer_id:, order_id:)
41
+ body = Api::RequestBody.for_auth_or_sale(
42
+ amount: amount,
43
+ order_id: order_id,
44
+ customer_id: customer_id,
45
+ payment_account_id: payment_account_id
46
+ )
47
+ Api::Request.new(
48
+ endpoint: Api::Endpoints::AUTHORIZATION,
49
+ body: body,
50
+ response_object: Api::LiveTransactionResponse.new(:auth)
51
+ ).run
52
+ end
53
+
54
+ def self.auth_reversal(transaction_id:, amount: nil)
55
+ body = Api::RequestBody.for_auth_reversal(
56
+ transaction_id: transaction_id,
57
+ amount: amount
58
+ )
59
+
60
+ Api::Request.new(
61
+ endpoint: Api::Endpoints::AUTH_REVERSAL,
62
+ body: body,
63
+ response_object: Api::TiedTransactionResponse.new(:auth_reversal)
64
+ ).run
65
+ end
66
+
67
+ def self.capture(transaction_id:, amount: nil)
68
+ body = Api::RequestBody.for_capture(
69
+ transaction_id: transaction_id,
70
+ amount: amount
71
+ )
72
+
73
+ Api::Request.new(
74
+ endpoint: Api::Endpoints::CAPTURE,
75
+ body: body,
76
+ response_object: Api::TiedTransactionResponse.new(:capture)
77
+ ).run
78
+ end
79
+
80
+ def self.auth_capture(amount:, payment_account_id:, customer_id:, order_id:)
81
+ body = Api::RequestBody.for_auth_or_sale(
82
+ amount: amount,
83
+ order_id: order_id,
84
+ customer_id: customer_id,
85
+ payment_account_id: payment_account_id
86
+ )
87
+ Api::Request.new(
88
+ endpoint: Api::Endpoints::SALE,
89
+ body: body,
90
+ response_object: Api::LiveTransactionResponse.new(:sale)
91
+ ).run
92
+ end
93
+
94
+ # NOTE: ActiveMerchant's #refund... only for use on a capture or sale it seems
95
+ # -> 'returns' are refunds too, credits are tied to a sale/capture, returns can be willy nilly
96
+ def self.credit(transaction_id:, amount:)
97
+ body = Api::RequestBody.for_credit(
98
+ amount: amount,
99
+ transaction_id: transaction_id
100
+ )
101
+ Api::Request.new(
102
+ endpoint: Api::Endpoints::CREDIT,
103
+ body: body,
104
+ response_object: Api::TiedTransactionResponse.new(:credit)
105
+ ).run
106
+ end
107
+
108
+ def self.refund(amount:, payment_account_id:, customer_id:, order_id:)
109
+ body = Api::RequestBody.for_return(
110
+ amount: amount,
111
+ customer_id: customer_id,
112
+ order_id: order_id,
113
+ payment_account_id: payment_account_id
114
+ )
115
+ Api::Request.new(
116
+ endpoint: Api::Endpoints::RETURN,
117
+ body: body,
118
+ response_object: Api::TiedTransactionResponse.new(:return)
119
+ ).run
120
+ end
121
+
122
+ # NOTE: can void credits
123
+ def self.void(transaction_id:)
124
+ Api::Request.new(
125
+ endpoint: Api::Endpoints::VOID,
126
+ body: Api::RequestBody.for_void(transaction_id: transaction_id),
127
+ response_object: Api::TiedTransactionResponse.new(:void)
128
+ ).run
129
+ end
130
+
131
+ def self.configure
132
+ yield self
133
+ end
134
+
135
+ class << self
136
+ [:environment, :license_id, :acceptor_id, :default_report_group, :order_source, :paypage_id].each do |config_var|
137
+ define_method :"#{config_var}" do
138
+ value = instance_variable_get(:"@#{config_var}")
139
+ raise "Missing Vantiv configuration: #{config_var}" unless value
140
+ value
141
+ end
142
+
143
+ define_method :"#{config_var}=" do |value|
144
+ instance_variable_set(:"@#{config_var}", value)
145
+ end
146
+ end
147
+ end
148
+
149
+ def self.root
150
+ File.dirname __dir__
151
+ end
152
+ end
@@ -0,0 +1,10 @@
1
+ require 'vantiv/api/response'
2
+ require 'vantiv/api/tied_transaction_response'
3
+ require 'vantiv/api/live_transaction_response'
4
+ require 'vantiv/api/tokenization_response'
5
+
6
+ require 'vantiv/api/request'
7
+ require 'vantiv/api/request_body_generator'
8
+ require 'vantiv/api/request_body'
9
+
10
+ require 'vantiv/api/endpoints'
@@ -0,0 +1,26 @@
1
+ module Vantiv
2
+ module Api
3
+ class CaptureResponse < Api::Response
4
+ ResponseCodes = {
5
+ transaction_received: '001',
6
+ # TODO: check this and other possible response codes for this txn,
7
+ # because currently the API _ONLY_ returns 001... :'(
8
+ invalid_amount: '209'
9
+ }
10
+
11
+ def success?
12
+ !api_level_failure? && response_code == ResponseCodes[:transaction_received]
13
+ end
14
+
15
+ def failure?
16
+ !success?
17
+ end
18
+
19
+ private
20
+
21
+ def transaction_response_name
22
+ "captureResponse"
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module Vantiv
2
+ module Api
3
+ module Endpoints
4
+ AUTHORIZATION = "payment/sp2/credit/v1/authorization"
5
+ CAPTURE = "payment/sp2/credit/v1/authorizationCompletion"
6
+ AUTH_REVERSAL = "payment/sp2/credit/v1/reversal"
7
+ SALE = "payment/sp2/credit/v1/sale"
8
+ CREDIT = "payment/sp2/credit/v1/credit"
9
+ RETURN = "payment/sp2/credit/v1/return"
10
+ TOKENIZATION = "payment/sp2/services/v1/paymentAccountCreate"
11
+ VOID = "payment/sp2/credit/v1/void"
12
+ end
13
+ end
14
+ end
15
+
@@ -0,0 +1,50 @@
1
+ module Vantiv
2
+ module Api
3
+ class LiveTransactionResponse < Api::Response
4
+ RESPONSE_CODES = {
5
+ approved: '000',
6
+ insufficient_funds: '110',
7
+ invalid_account_number: '301',
8
+ expired_card: '305',
9
+ token_not_found: '822'
10
+ }
11
+
12
+ LIVE_TRANSACTION_RESPONSE_NAMES = {
13
+ auth: "authorizationResponse",
14
+ sale: "saleResponse"
15
+ }
16
+
17
+ def initialize(transaction_name)
18
+ unless @transaction_response_name = LIVE_TRANSACTION_RESPONSE_NAMES[transaction_name]
19
+ raise "Implementation Error: Live transactions do not include #{transaction_name}"
20
+ end
21
+ end
22
+
23
+ def success?
24
+ !api_level_failure? && transaction_approved?
25
+ end
26
+
27
+ def failure?
28
+ !success?
29
+ end
30
+
31
+ def insufficient_funds?
32
+ response_code == RESPONSE_CODES[:insufficient_funds]
33
+ end
34
+
35
+ def invalid_account_number?
36
+ response_code == RESPONSE_CODES[:invalid_account_number]
37
+ end
38
+
39
+ def expired_card?
40
+ response_code == RESPONSE_CODES[:expired_card]
41
+ end
42
+
43
+ private
44
+
45
+ def transaction_approved?
46
+ response_code == RESPONSE_CODES[:approved]
47
+ end
48
+ end
49
+ end
50
+ end