vantiv 0.1.0 → 0.2.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 (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +64 -0
  3. data/README.md +20 -4
  4. data/cert_fixtures/L_EP_1.json +3 -1
  5. data/cert_fixtures/L_EP_2.json +3 -1
  6. data/cert_fixtures/L_EP_3.json +3 -1
  7. data/cert_fixtures/L_EP_4.json +4 -0
  8. data/cert_fixtures/L_EP_5.json +4 -0
  9. data/cert_fixtures/L_EP_6.json +3 -1
  10. data/cert_fixtures/L_EP_7.json +3 -1
  11. data/exe/vantiv-certify-app +1 -0
  12. data/lib/vantiv.rb +13 -7
  13. data/lib/vantiv/api/live_transaction_response.rb +3 -1
  14. data/lib/vantiv/api/request_body.rb +28 -8
  15. data/lib/vantiv/api/response.rb +16 -5
  16. data/lib/vantiv/api/tokenization_response.rb +4 -0
  17. data/lib/vantiv/mocked_sandbox/api_request.rb +31 -3
  18. data/lib/vantiv/mocked_sandbox/dynamic_response_body.rb +40 -0
  19. data/lib/vantiv/mocked_sandbox/fixture_generator.rb +171 -19
  20. data/lib/vantiv/mocked_sandbox/fixtures/auth--4457002100000005.json.erb +26 -0
  21. data/lib/vantiv/mocked_sandbox/fixtures/auth--4457010000000009.json.erb +27 -0
  22. data/lib/vantiv/mocked_sandbox/fixtures/auth--5112001600000006.json.erb +26 -0
  23. data/lib/vantiv/mocked_sandbox/fixtures/auth--5112001900000003.json.erb +26 -0
  24. data/lib/vantiv/mocked_sandbox/fixtures/auth_capture--4457002100000005.json.erb +26 -0
  25. data/lib/vantiv/mocked_sandbox/fixtures/auth_capture--4457010000000009.json.erb +27 -0
  26. data/lib/vantiv/mocked_sandbox/fixtures/auth_capture--5112001600000006.json.erb +26 -0
  27. data/lib/vantiv/mocked_sandbox/fixtures/auth_capture--5112001900000003.json.erb +26 -0
  28. data/lib/vantiv/mocked_sandbox/fixtures/auth_reversal.json.erb +21 -0
  29. data/lib/vantiv/mocked_sandbox/fixtures/capture.json.erb +21 -0
  30. data/lib/vantiv/mocked_sandbox/fixtures/credit.json.erb +21 -0
  31. data/lib/vantiv/mocked_sandbox/fixtures/refund--4457002100000005.json.erb +22 -0
  32. data/lib/vantiv/mocked_sandbox/fixtures/refund--4457010000000009.json.erb +22 -0
  33. data/lib/vantiv/mocked_sandbox/fixtures/refund--5112001600000006.json.erb +22 -0
  34. data/lib/vantiv/mocked_sandbox/fixtures/refund--5112001900000003.json.erb +22 -0
  35. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--4457002100000005.json.erb +4 -4
  36. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--4457010000000009.json.erb +2 -2
  37. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--4457010010900010.json.erb +3 -4
  38. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--5112001600000006.json.erb +4 -4
  39. data/lib/vantiv/mocked_sandbox/fixtures/tokenize_by_direct_post--5112001900000003.json.erb +2 -2
  40. data/lib/vantiv/mocked_sandbox/fixtures/void.json.erb +21 -0
  41. data/lib/vantiv/test_card.rb +25 -1
  42. data/lib/vantiv/version.rb +1 -1
  43. metadata +20 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 923cb51d4a0626d8b63cb9139ff3961ea5bbbd96
4
- data.tar.gz: 5ce0a976b96f07c76e1251d5c4de9b453b26b56f
3
+ metadata.gz: 4eafce70c91d564dbbab06586a1fc13f0a7f1458
4
+ data.tar.gz: b5abe4e788d601c489d882db8ac0b9f32dbacf59
5
5
  SHA512:
6
- metadata.gz: 4209143635bf22f01654e50a1dbddd61b331a1329b0a9d5a4fb26b74da986260a2e3c7c6cfee33667cfec3ef6b200fc862ae2724cf4fe85b903a255d3e7dd2f3
7
- data.tar.gz: 3b61c32775ed45e78a0cd3f1454acd7729b56abbf9e7bb6743ff7e8f20a60bdfc524c15c49bb15fb843a487517f1c061bd3216ef447723e4dd63c8ffd67239e1
6
+ metadata.gz: b85dc5bc03b74980e17ab655bd63b0999931a3e512ac4a28ef8a1bd3ee635b26d04e5a5f386930ac7fe722f573c7dac037c86415da70baf3bd484f1014969ae4
7
+ data.tar.gz: 97b171c491f1503d1e5eb259d1140ce1e64487297eb8173588450a69eeed428c6a302c3e2a1c6760282143b7c6f70611e247c00fe4f16d80fa2e3cf800ce45e4
@@ -0,0 +1,64 @@
1
+ Vantiv Ruby Changes
2
+
3
+ 0.2.0
4
+ -----------
5
+
6
+ NOTE: API change occurs in this version bump on:
7
+
8
+ 1. `Vantiv.auth` and `Vantiv.auth_capture` now require `expiry_month`
9
+ and `expiry_year` to be passed. Merchants are responsible for persisting
10
+ this data.
11
+ 2. `Vantiv.credit`'s `amount` argument is now optional.
12
+
13
+ - Send expiration data on live transactions
14
+ - Major miscommunication from Vantiv during development that sending
15
+ expiration data on authorizations and auth_captures (Sale) was
16
+ not necessary.
17
+ - Expiration data is required for card-not-present transactions
18
+ - In actuality, majority of transactions will work without expiry
19
+ data but a significant number of them will fail with "Invalid Transaction"
20
+ and "Do No Honor" response codes.
21
+ - Make amount in credit endpoint optional; with no amount passed, Vantiv
22
+ credits full amount of original transaction
23
+ - Strip non-numeric characters from credit card numbers:
24
+ - Numbers input with spaces or delimeters are acceptable for direct
25
+ tokenization as a result
26
+ - Cast arguments accepted to strings in Request Bodies
27
+ - Retry requests when Vantiv doesn't respond with JSON
28
+ - Sometimes, Vantiv's API doesn't respond with JSON (typically, when
29
+ a service is down or something)
30
+ - It seems safe to retry requests in that case, up to 3 times.
31
+ - Add mocked sandbox responses for all other endpoints:
32
+ - Auth
33
+ - Capture
34
+ - Auth Reversal
35
+ - Credit
36
+ - Refund
37
+ - Void
38
+
39
+ 0.1.0
40
+ -----------
41
+
42
+ - Add a mocked sandbox structure for gem to operate in test:
43
+ - Allows gem to operate in a test environment without making real
44
+ network requests, while still behaving identically to certification
45
+ Environment
46
+ - Only difference is that mocked sandbox has consistent payment account
47
+ IDs per card number, available on TestCard object
48
+ #mocked_sandbox_payment_account_id
49
+ - Intially only for direct tokenization endpoint
50
+ - Implement direct tokenization, allowing merchants to both use eProtect or
51
+ tokenize with Vantiv directly.
52
+ - Implement auth reversal
53
+ - Implement refunds
54
+ - Implement credits
55
+ - Implement voids
56
+ - Add TravisCI for CI
57
+ - Add paypage server and paypage driver, objects to run a basic version of
58
+ an eProtect page. Enables retrieving paypageRegistrationIDs in order to test
59
+ usage to tokenize via eProtect.
60
+ - Add script to run all Devhub certification environment validation tests
61
+ via script:
62
+ - Allows merchants to install gem and certify quickly, rather than manually
63
+
64
+
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  Add this line to your application's Gemfile:
7
7
 
8
8
  ```ruby
9
- gem 'vantiv-ruby'
9
+ gem 'vantiv'
10
10
  ```
11
11
 
12
12
  And then execute:
@@ -15,7 +15,7 @@ And then execute:
15
15
 
16
16
  Or install it yourself as:
17
17
 
18
- $ gem install vantiv-ruby
18
+ $ gem install vantiv
19
19
 
20
20
  ## Configuration
21
21
 
@@ -53,7 +53,7 @@ Navigate to your application's page in DevHub's developer portal (apideveloper.v
53
53
 
54
54
  ## Usage
55
55
 
56
- The vantiv-ruby gem provides a simple ruby client for interacting with Vantiv's DevHub API. This API wraps their Litle/XML API and provides an API that uses json. This gem provides a way for a merchant to:
56
+ The vantiv gem provides a simple ruby client for interacting with Vantiv's DevHub API. This API wraps their Litle/XML API and provides an API that uses json. This gem provides a way for a merchant to:
57
57
 
58
58
  1. Use Vantiv's eProtect feature to tokenize sensitive card information directly to Vantiv's servers.
59
59
  2. Run the following transactions on customers' accounts:
@@ -181,7 +181,23 @@ In the server, once a temporary token has been received, a permanent token can b
181
181
  Vantiv.tokenize(temporary_token: 'temporary-token-here')
182
182
  ```
183
183
 
184
- This will return a TokenizationResponse object, which responds to `success?` and `failure?`, and which returns the `payment_account_id` retrieved from Vantiv. The merchant should save this token for use on future transactions.
184
+ This will return a TokenizationResponse object, which responds to `success?` and `failure?`, and which returns a `card_type` and the `payment_account_id` retrieved from Vantiv. The merchant should save this token for use on future transactions.
185
+
186
+ The `card_type` corresponds with the type of account that was used in the transaction and has the following enumerations:
187
+
188
+ | Enumeration | Description |
189
+ | ------------- | ------------- |
190
+ | MC | MasterCard |
191
+ | VI | Visa |
192
+ | AX | American Express |
193
+ | DC | Diner’s Club |
194
+ | DI | Discover |
195
+ | PP | PayPal |
196
+ | JC | JCB (Japanese Credit Bureau) |
197
+ | BL | PayPal Credit |
198
+ | EC | eCheck |
199
+ | GC | Gift Card |
200
+ | “” | (empty) Card type unknown or undefined |
185
201
 
186
202
  NOTES: There are a few gotchas with tokenization, namely:
187
203
 
@@ -9,7 +9,9 @@
9
9
  "PartialApprovedFlag": "false"
10
10
  },
11
11
  "Card": {
12
- "PaypageRegistrationID": "${eProtect.4457010000000009}"
12
+ "PaypageRegistrationID": "${eProtect.4457010000000009}",
13
+ "ExpirationMonth": "01",
14
+ "ExpirationYear": "16"
13
15
  }
14
16
  }
15
17
  }
@@ -9,7 +9,9 @@
9
9
  "PartialApprovedFlag": "false"
10
10
  },
11
11
  "Card": {
12
- "PaypageRegistrationID": "${eProtect.5435101234510196}"
12
+ "PaypageRegistrationID": "${eProtect.5435101234510196}",
13
+ "ExpirationMonth": "01",
14
+ "ExpirationYear": "16"
13
15
  }
14
16
  }
15
17
  }
@@ -2,7 +2,9 @@
2
2
  "endpoint": "TOKENIZATION",
3
3
  "body": {
4
4
  "Card": {
5
- "PaypageRegistrationID": "${eProtect.6011010140000004}"
5
+ "PaypageRegistrationID": "${eProtect.6011010140000004}",
6
+ "ExpirationMonth": "01",
7
+ "ExpirationYear": "16"
6
8
  },
7
9
  "Transaction": {
8
10
  "CustomerID": "123"
@@ -10,6 +10,10 @@
10
10
  },
11
11
  "PaymentAccount": {
12
12
  "PaymentAccountID": "#{L_EP_1.litleOnlineResponse.authorizationResponse.tokenResponse.PaymentAccountID}"
13
+ },
14
+ "Card": {
15
+ "ExpirationMonth": "01",
16
+ "ExpirationYear": "16"
13
17
  }
14
18
  }
15
19
  }
@@ -10,6 +10,10 @@
10
10
  },
11
11
  "PaymentAccount": {
12
12
  "PaymentAccountID": "#{L_EP_2.litleOnlineResponse.saleResponse.tokenResponse.PaymentAccountID}"
13
+ },
14
+ "Card": {
15
+ "ExpirationMonth": "01",
16
+ "ExpirationYear": "16"
13
17
  }
14
18
  }
15
19
  }
@@ -9,7 +9,9 @@
9
9
  "PartialApprovedFlag": "false"
10
10
  },
11
11
  "Card": {
12
- "PaypageRegistrationID": "cDZJcmd1VjNlYXNaSlRMTGpocVZQY1NWVXE4ZW5UTko4NU9KK3p1L1p1Vzg4YzVPQVlSUHNITG1JN2I0NzlyTg=="
12
+ "PaypageRegistrationID": "cDZJcmd1VjNlYXNaSlRMTGpocVZQY1NWVXE4ZW5UTko4NU9KK3p1L1p1Vzg4YzVPQVlSUHNITG1JN2I0NzlyTg==",
13
+ "ExpirationMonth": "01",
14
+ "ExpirationYear": "16"
13
15
  }
14
16
  }
15
17
  }
@@ -9,7 +9,9 @@
9
9
  "PartialApprovedFlag": "false"
10
10
  },
11
11
  "Card": {
12
- "PaypageRegistrationID": "RGFQNCt6U1d1M21SeVByVTM4dHlHb1FsVkUrSmpnWXhNY0o5UkMzRlZFanZiUHVnYjN1enJXbG1WSDF4aXlNcA=="
12
+ "PaypageRegistrationID": "RGFQNCt6U1d1M21SeVByVTM4dHlHb1FsVkUrSmpnWXhNY0o5UkMzRlZFanZiUHVnYjN1enJXbG1WSDF4aXlNcA==",
13
+ "ExpirationMonth": "01",
14
+ "ExpirationYear": "16"
13
15
  }
14
16
  }
15
17
  }
@@ -11,6 +11,7 @@ Vantiv.configure do |config|
11
11
  config.license_id = ENV["LICENSE_ID"]
12
12
  config.acceptor_id = ENV["ACCEPTOR_ID"]
13
13
  config.paypage_id = ENV["PAYPAGE_ID"]
14
+ config.environment = Vantiv::Environment::CERTIFICATION
14
15
 
15
16
  config.default_report_group = '1'
16
17
  end
@@ -37,12 +37,14 @@ module Vantiv
37
37
  ).run
38
38
  end
39
39
 
40
- def self.auth(amount:, payment_account_id:, customer_id:, order_id:)
40
+ def self.auth(amount:, payment_account_id:, customer_id:, order_id:, expiry_month:, expiry_year:)
41
41
  body = Api::RequestBody.for_auth_or_sale(
42
42
  amount: amount,
43
43
  order_id: order_id,
44
44
  customer_id: customer_id,
45
- payment_account_id: payment_account_id
45
+ payment_account_id: payment_account_id,
46
+ expiry_month: expiry_month,
47
+ expiry_year: expiry_year
46
48
  )
47
49
  Api::Request.new(
48
50
  endpoint: Api::Endpoints::AUTHORIZATION,
@@ -77,12 +79,14 @@ module Vantiv
77
79
  ).run
78
80
  end
79
81
 
80
- def self.auth_capture(amount:, payment_account_id:, customer_id:, order_id:)
82
+ def self.auth_capture(amount:, payment_account_id:, customer_id:, order_id:, expiry_month:, expiry_year:)
81
83
  body = Api::RequestBody.for_auth_or_sale(
82
84
  amount: amount,
83
85
  order_id: order_id,
84
86
  customer_id: customer_id,
85
- payment_account_id: payment_account_id
87
+ payment_account_id: payment_account_id,
88
+ expiry_month: expiry_month,
89
+ expiry_year: expiry_year
86
90
  )
87
91
  Api::Request.new(
88
92
  endpoint: Api::Endpoints::SALE,
@@ -93,7 +97,7 @@ module Vantiv
93
97
 
94
98
  # NOTE: ActiveMerchant's #refund... only for use on a capture or sale it seems
95
99
  # -> 'returns' are refunds too, credits are tied to a sale/capture, returns can be willy nilly
96
- def self.credit(transaction_id:, amount:)
100
+ def self.credit(transaction_id:, amount: nil)
97
101
  body = Api::RequestBody.for_credit(
98
102
  amount: amount,
99
103
  transaction_id: transaction_id
@@ -105,12 +109,14 @@ module Vantiv
105
109
  ).run
106
110
  end
107
111
 
108
- def self.refund(amount:, payment_account_id:, customer_id:, order_id:)
112
+ def self.refund(amount:, payment_account_id:, customer_id:, order_id:, expiry_month:, expiry_year:)
109
113
  body = Api::RequestBody.for_return(
110
114
  amount: amount,
111
115
  customer_id: customer_id,
112
116
  order_id: order_id,
113
- payment_account_id: payment_account_id
117
+ payment_account_id: payment_account_id,
118
+ expiry_month: expiry_month,
119
+ expiry_year: expiry_year
114
120
  )
115
121
  Api::Request.new(
116
122
  endpoint: Api::Endpoints::RETURN,
@@ -5,8 +5,10 @@ module Vantiv
5
5
  approved: '000',
6
6
  insufficient_funds: '110',
7
7
  invalid_account_number: '301',
8
+ pick_up_card: '303',
8
9
  expired_card: '305',
9
- token_not_found: '822'
10
+ token_not_found: '822',
11
+ token_invalid: '823'
10
12
  }
11
13
 
12
14
  LIVE_TRANSACTION_RESPONSE_NAMES = {
@@ -1,13 +1,17 @@
1
1
  module Vantiv
2
2
  module Api
3
3
  module RequestBody
4
- def self.for_auth_or_sale(amount:, customer_id:, order_id:, payment_account_id:)
4
+ def self.for_auth_or_sale(amount:, customer_id:, order_id:, payment_account_id:, expiry_month:, expiry_year:)
5
5
  RequestBodyGenerator.run(
6
6
  transaction_element(
7
7
  amount: amount,
8
8
  order_id: order_id,
9
9
  customer_id: customer_id
10
10
  ),
11
+ card_element_for_live_transactions(
12
+ expiry_month: expiry_month,
13
+ expiry_year: expiry_year
14
+ ),
11
15
  payment_account_element(payment_account_id: payment_account_id)
12
16
  )
13
17
  end
@@ -30,7 +34,7 @@ module Vantiv
30
34
  )
31
35
  end
32
36
 
33
- def self.for_return(amount:, customer_id:, order_id:, payment_account_id:)
37
+ def self.for_return(amount:, customer_id:, order_id:, payment_account_id:, expiry_month:, expiry_year:)
34
38
  transaction = transaction_element(
35
39
  amount: amount,
36
40
  order_id: order_id,
@@ -39,6 +43,10 @@ module Vantiv
39
43
  transaction["Transaction"].delete("PartialApprovedFlag")
40
44
  RequestBodyGenerator.run(
41
45
  transaction,
46
+ card_element_for_live_transactions(
47
+ expiry_month: expiry_month,
48
+ expiry_year: expiry_year
49
+ ),
42
50
  payment_account_element(payment_account_id: payment_account_id)
43
51
  )
44
52
  end
@@ -53,10 +61,10 @@ module Vantiv
53
61
  RequestBodyGenerator.run(
54
62
  {
55
63
  "Card" => {
56
- "AccountNumber" => card_number,
57
- "ExpirationMonth" => expiry_month,
58
- "ExpirationYear" => expiry_year,
59
- "CVV" => cvv
64
+ "AccountNumber" => card_number.to_s.gsub(/\D*/, ""),
65
+ "ExpirationMonth" => format_expiry(expiry_month),
66
+ "ExpirationYear" => format_expiry(expiry_year),
67
+ "CVV" => cvv.to_s
60
68
  }
61
69
  }
62
70
  )
@@ -74,6 +82,15 @@ module Vantiv
74
82
  }
75
83
  end
76
84
 
85
+ def self.card_element_for_live_transactions(expiry_month:, expiry_year:)
86
+ {
87
+ "Card" => {
88
+ "ExpirationMonth" => format_expiry(expiry_month),
89
+ "ExpirationYear" => format_expiry(expiry_year)
90
+ }
91
+ }
92
+ end
93
+
77
94
  def self.tied_transaction_element(transaction_id:, amount: nil)
78
95
  res = {
79
96
  "Transaction" => {
@@ -89,7 +106,7 @@ module Vantiv
89
106
  def self.transaction_element(amount:, customer_id:, order_id:)
90
107
  {
91
108
  "Transaction" => {
92
- "ReferenceNumber" => order_id,
109
+ "ReferenceNumber" => order_id.to_s,
93
110
  "TransactionAmount" => '%.2f' % (amount / 100.0),
94
111
  "OrderSource" => Vantiv.order_source,
95
112
  "CustomerID" => customer_id,
@@ -105,7 +122,10 @@ module Vantiv
105
122
  }
106
123
  }
107
124
  end
108
- end
109
125
 
126
+ def self.format_expiry(raw_value)
127
+ raw_value.to_s.reverse[0..1].reverse.rjust(2, "0")
128
+ end
129
+ end
110
130
  end
111
131
  end
@@ -15,17 +15,17 @@ module Vantiv
15
15
  end
16
16
 
17
17
  def api_level_failure?
18
- !httpok ||
19
- # NOTE: this kind of sucks, but at the commit point, the DevHub
20
- # Api sometimes gives 200OK when litle had a parse issue and returns
21
- # 'Error validating xml data...' instead of an actual error
22
- @body["litleOnlineResponse"]["@message"].match(/error/i)
18
+ !httpok || litle_response_has_error?
23
19
  end
24
20
 
25
21
  def message
26
22
  litle_transaction_response["message"]
27
23
  end
28
24
 
25
+ def error_message
26
+ api_level_failure? ? api_level_error_message : message
27
+ end
28
+
29
29
  def response_code
30
30
  litle_transaction_response["response"]
31
31
  end
@@ -36,6 +36,17 @@ module Vantiv
36
36
 
37
37
  private
38
38
 
39
+ def litle_response_has_error?
40
+ # NOTE: this kind of sucks, but at the commit point, the DevHub
41
+ # Api sometimes gives 200OK when litle had a parse issue and returns
42
+ # 'Error validating xml data...' instead of an actual error
43
+ !!@body["litleOnlineResponse"]["@message"].match(/error/i)
44
+ end
45
+
46
+ def api_level_error_message
47
+ body["errormsg"]
48
+ end
49
+
39
50
  attr_reader :transaction_response_name
40
51
 
41
52
  def litle_response
@@ -26,6 +26,10 @@ module Vantiv
26
26
  success? ? litle_transaction_response["PaymentAccountID"] : nil
27
27
  end
28
28
 
29
+ def card_type
30
+ success? ? litle_transaction_response["Type"] : nil
31
+ end
32
+
29
33
  def invalid_card_number?
30
34
  response_code == RESPONSE_CODES[:credit_card_number_invalid]
31
35
  end
@@ -1,6 +1,7 @@
1
1
  module Vantiv
2
2
  module MockedSandbox
3
3
  class ApiRequest
4
+ class EndpointNotMocked < StandardError; end
4
5
  class FixtureNotFound < StandardError; end
5
6
 
6
7
  def self.run(endpoint:, body:)
@@ -17,6 +18,22 @@ module Vantiv
17
18
  if direct_post?
18
19
  load_fixture("tokenize_by_direct_post", card_number)
19
20
  end
21
+ elsif endpoint == Api::Endpoints::SALE
22
+ load_fixture("auth_capture", card_number_from_payment_account_id)
23
+ elsif endpoint == Api::Endpoints::AUTHORIZATION
24
+ load_fixture("auth", card_number_from_payment_account_id)
25
+ elsif endpoint == Api::Endpoints::CAPTURE
26
+ load_fixture("capture")
27
+ elsif endpoint == Api::Endpoints::AUTH_REVERSAL
28
+ load_fixture("auth_reversal")
29
+ elsif endpoint == Api::Endpoints::CREDIT
30
+ load_fixture("credit")
31
+ elsif endpoint == Api::Endpoints::RETURN
32
+ load_fixture("refund", card_number_from_payment_account_id)
33
+ elsif endpoint == Api::Endpoints::VOID
34
+ load_fixture("void")
35
+ else
36
+ raise EndpointNotMocked.new("#{endpoint} is not mocked!")
20
37
  end
21
38
  {
22
39
  httpok: fixture["httpok"],
@@ -37,11 +54,22 @@ module Vantiv
37
54
  request_body["Card"]["AccountNumber"]
38
55
  end
39
56
 
40
- def load_fixture(api_method, card_number)
57
+ def card_number_from_payment_account_id
58
+ TestCard.find_by_payment_account_id(
59
+ request_body["PaymentAccount"]["PaymentAccountID"]
60
+ ).card_number
61
+ end
62
+
63
+ def load_fixture(api_method, card_number = nil)
64
+ fixture_file_name = card_number ? "#{api_method}--#{card_number}" : api_method
41
65
  begin
42
- self.fixture = File.open("#{MockedSandbox.fixtures_directory}#{api_method}--#{card_number}.json.erb", 'r') do |f|
66
+ self.fixture = File.open("#{MockedSandbox.fixtures_directory}#{fixture_file_name}.json.erb", 'r') do |f|
43
67
  raw_fixture = JSON.parse(f.read)
44
- raw_fixture["response_body"] = raw_fixture["response_body"].to_json
68
+ # Prevent rails overridden version of to_json from encoding erb sepcial characters
69
+ raw_fixture["response_body"] = JSON::Ext::Generator::GeneratorMethods::Hash
70
+ .instance_method(:to_json)
71
+ .bind(raw_fixture["response_body"])
72
+ .call
45
73
  raw_fixture
46
74
  end
47
75
  rescue Errno::ENOENT