hps 2.2.5 → 2.3.2

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.
@@ -0,0 +1,133 @@
1
+ module Hps
2
+ # ===============
3
+ # = HpsGiftCard =
4
+ # ===============
5
+ class HpsGiftCard
6
+ attr_accessor :number, :track_data, :alias, :token_value,
7
+ :encryption_data, :pin
8
+
9
+ def initialize(number = nil)
10
+ self.number = number
11
+ end
12
+ end # HpsGiftCard
13
+
14
+ # =======================
15
+ # = HpsGiftCardActivate =
16
+ # =======================
17
+ class HpsGiftCardActivate < HpsTransaction
18
+ # Values used in the card activate response
19
+ attr_accessor :authorization_code, :balance_amount, :points_balance_amount
20
+
21
+ # The rewards (dollars or points) added to the account as
22
+ # a result of the transaction
23
+ attr_accessor :rewards
24
+
25
+ # Notes contain reward messages to be displayed on a receipt,
26
+ # mobile app, or web page to inform an account holder about
27
+ # special rewards or promotions available on their account
28
+ attr_accessor :notes
29
+
30
+ def self.from_response(response, txn_type, return_type = nil)
31
+ activation_response = response['Transaction'][txn_type]
32
+
33
+ activation = return_type ? return_type.constantize.new : self.new
34
+
35
+ activation.transaction_id = response['Header']['GatewayTxnId']
36
+ activation.authorization_code = activation_response['AuthCode']
37
+ activation.balance_amount = activation_response['BalanceAmt']
38
+ activation.points_balance_amount = activation_response['PointsBalanceAmt']
39
+ activation.rewards = activation_response['Rewards']
40
+ activation.notes = activation_response['Notes']
41
+ activation.response_code = activation_response['RspCode']
42
+ activation.response_text = activation_response['RspText']
43
+
44
+ return activation
45
+ end # from_response
46
+ end # HpsGiftCardActivate
47
+
48
+ # =========================
49
+ # = HpsGiftCardDeactivate =
50
+ # =========================
51
+ class HpsGiftCardDeactivate < HpsGiftCardActivate
52
+
53
+ end # HpsGiftCardDeactivate
54
+
55
+ # ======================
56
+ # = HpsGiftCardReplace =
57
+ # ======================
58
+ class HpsGiftCardReplace < HpsGiftCardActivate
59
+
60
+ end # HpsGiftCardReplace
61
+
62
+ # =======================
63
+ # = HpsGiftCardReversal =
64
+ # =======================
65
+ class HpsGiftCardReversal < HpsGiftCardActivate
66
+
67
+ end # HpsGiftCardReversal
68
+
69
+ # =====================
70
+ # = HpsGiftCardReward =
71
+ # =====================
72
+ class HpsGiftCardReward < HpsGiftCardActivate
73
+
74
+ end # HpsGiftCardReward
75
+
76
+ # ======================
77
+ # = HpsGiftCardBalance =
78
+ # ======================
79
+ class HpsGiftCardBalance < HpsGiftCardActivate
80
+
81
+ end # HpsGiftCardBalance
82
+
83
+ # =======================
84
+ # = HpsGiftCardAddValue =
85
+ # =======================
86
+ class HpsGiftCardAddValue < HpsGiftCardActivate
87
+
88
+ end # HpsGiftCardAddValue
89
+
90
+ # ===================
91
+ # = HpsGiftCardVoid =
92
+ # ===================
93
+ class HpsGiftCardVoid < HpsGiftCardActivate
94
+
95
+ end # HpsGiftCardVoid
96
+
97
+ # ===================
98
+ # = HpsGiftCardSale =
99
+ # ===================
100
+ class HpsGiftCardSale < HpsGiftCardActivate
101
+ attr_accessor :split_tender_card_amount, :split_tender_balance_due
102
+
103
+ def self.from_response(response, txn_type)
104
+ transaction = response['Transaction']
105
+
106
+ sale = self.superclass.from_response(response, txn_type, self.name)
107
+
108
+ sale.split_tender_card_amount = transaction['SplitTenderCardAmt']
109
+ sale.split_tender_balance_due = transaction['SplitTenderBalanceDueAmt']
110
+
111
+ return sale
112
+ end # from_response
113
+ end # HpsGiftCardSale
114
+
115
+ # ====================
116
+ # = HpsGiftCardAlias =
117
+ # ====================
118
+ class HpsGiftCardAlias < HpsTransaction
119
+ attr_accessor :gift_card
120
+
121
+ def self.from_response(response, txn_type)
122
+ alias_response = response['Transaction'][txn_type]
123
+
124
+ alias_item = HpsGiftCardAlias.new
125
+ alias_item.transaction_id = response['Header']['GatewayTxnId']
126
+ alias_item.gift_card = HpsGiftCard.new(alias_response['CardData'])
127
+ alias_item.response_code = alias_response['RspCode']
128
+ alias_item.response_text = alias_response['RspText']
129
+
130
+ return alias_item
131
+ end # from_response
132
+ end # HpsGiftCardAlias
133
+ end # Hps
@@ -1,7 +1,81 @@
1
1
  {
2
- "version": "1.0.0",
3
-
2
+ "version": "1.0.1",
3
+
4
4
  "exception_mappings":[
5
+ {
6
+ "object":"exception_mapping",
7
+ "category":"gift",
8
+ "exception_codes":[
9
+ "3",
10
+ "8"
11
+ ],
12
+ "mapping_type":"CardException",
13
+ "mapping_code":"invalid_card_data",
14
+ "mapping_message":"Exception_Message_InvalidCardData"
15
+ },
16
+ {
17
+ "object":"exception_mapping",
18
+ "category":"gift",
19
+ "exception_codes":[
20
+ "4"
21
+ ],
22
+ "mapping_type":"CardException",
23
+ "mapping_code":"expired_card",
24
+ "mapping_message":"Exception_Message_CardExpired"
25
+ },
26
+ {
27
+ "object":"exception_mapping",
28
+ "category":"gift",
29
+ "exception_codes":[
30
+ "5",
31
+ "12"
32
+ ],
33
+ "mapping_type":"CardException",
34
+ "mapping_code":"card_declined",
35
+ "mapping_message":"Exception_Message_CardDeclined"
36
+ },
37
+ {
38
+ "object":"exception_mapping",
39
+ "category":"gift",
40
+ "exception_codes":[
41
+ "6",
42
+ "7",
43
+ "10"
44
+ ],
45
+ "mapping_type":"CardException",
46
+ "mapping_code":"processing_error",
47
+ "mapping_message":"Exception_Message_ProcessingError"
48
+ },
49
+ {
50
+ "object":"exception_mapping",
51
+ "category":"gift",
52
+ "exception_codes":[
53
+ "9"
54
+ ],
55
+ "mapping_type":"CardException",
56
+ "mapping_code":"invalid_amount",
57
+ "mapping_message":"Exception_Message_ChargeAmount"
58
+ },
59
+ {
60
+ "object":"exception_mapping",
61
+ "category":"gift",
62
+ "exception_codes":[
63
+ "13"
64
+ ],
65
+ "mapping_type":"CardException",
66
+ "mapping_code":"partial_approval",
67
+ "mapping_message":"Exception_Message_PartialApproval"
68
+ },
69
+ {
70
+ "object":"exception_mapping",
71
+ "category":"gift",
72
+ "exception_codes":[
73
+ "14"
74
+ ],
75
+ "mapping_type":"CardException",
76
+ "mapping_code":"invalid_pin",
77
+ "mapping_message":"Exception_Message_InvalidPin"
78
+ },
5
79
  {
6
80
  "object":"exception_mapping",
7
81
  "category":"issuer",
@@ -332,6 +406,11 @@
332
406
  "mapping_type":"CardException",
333
407
  "mapping_code":"processing_error",
334
408
  "mapping_message":"Exception_Message_ProcessingError"
409
+ },
410
+ {
411
+ "object":"exception_message",
412
+ "code":"Exception_Message_PartialApproval",
413
+ "message":"The amount was partially approved."
335
414
  }
336
415
  ],
337
416
  "exception_messages":[
@@ -7,7 +7,7 @@ module Hps
7
7
 
8
8
  def initialize
9
9
  path = File.join( File.dirname(__FILE__), "exceptions.json")
10
-
10
+
11
11
  File.open(path, "r") do |f|
12
12
  @exceptions = JSON.load(f)
13
13
  end
@@ -23,22 +23,33 @@ module Hps
23
23
 
24
24
  unless mapping.nil?
25
25
  message = message_for_mapping(mapping, response_text)
26
- code = mapping["mapping_code"]
27
- return CardException.new(transaction_id, code, message)
26
+ code = mapping["mapping_code"]
27
+ return CardException.new(transaction_id, code, message)
28
28
  else
29
29
  return CardException.new(transaction_id, "unknown_card_exception", response_text)
30
30
  end
31
31
 
32
32
  end
33
33
 
34
+ def map_gift_card_exception(transaction_id, response_code, response_text)
35
+ mapping = exception_for_category_and_code("gift", response_code)
36
+ unless mapping.nil?
37
+ message = message_for_mapping(mapping, response_text)
38
+ code = mapping["mapping_code"]
39
+ return CardException.new(transaction_id, code, message)
40
+ else
41
+ return CardException.new(transaction_id, "unknown_card_exception", response_text)
42
+ end
43
+ end
44
+
34
45
  def map_gateway_exception(transaction_id, response_code, response_text)
35
46
 
36
47
  mapping = exception_for_category_and_code("gateway", response_code)
37
48
  message = message_for_mapping(mapping, response_text)
38
-
49
+
39
50
  unless mapping.nil?
40
51
 
41
- code = mapping["mapping_code"]
52
+ code = mapping["mapping_code"]
42
53
  exception_type = mapping["mapping_type"]
43
54
 
44
55
  if exception_type == "AuthenticationException"
@@ -52,10 +63,10 @@ module Hps
52
63
  elsif exception_type == "InvalidRequestException"
53
64
 
54
65
  return InvalidRequestException.new(message, mapping["param"], code)
55
-
66
+
56
67
  elsif !code.nil?
57
68
 
58
- return HpsException.new(response_text, code)
69
+ return HpsException.new(response_text, code)
59
70
 
60
71
  end
61
72
 
@@ -78,8 +89,8 @@ module Hps
78
89
  unless mapping.nil?
79
90
 
80
91
  message = message_for_mapping(mapping, response_text)
81
- code = mapping["mapping_code"]
82
- exception_type = mapping["mapping_type"]
92
+ code = mapping["mapping_code"]
93
+ exception_type = mapping["mapping_type"]
83
94
 
84
95
  if exception_type == "InvalidRequestException"
85
96
 
@@ -88,12 +99,12 @@ module Hps
88
99
  elsif exception_type == "ApiConnectionException"
89
100
 
90
101
  return ApiConnectionException.new(message, inner_exception, code)
91
-
102
+
92
103
  elsif !code.nil?
93
104
 
94
- return HpsException.new(message, code)
105
+ return HpsException.new(message, code)
95
106
 
96
- end
107
+ end
97
108
 
98
109
  end
99
110
 
@@ -111,7 +122,7 @@ module Hps
111
122
 
112
123
  unless message.nil?
113
124
 
114
- mapping_message = @exceptions["exception_messages"].detect { |m|
125
+ mapping_message = @exceptions["exception_messages"].detect { |m|
115
126
  m["code"] == message
116
127
  }
117
128
 
@@ -125,8 +136,8 @@ module Hps
125
136
 
126
137
  def exception_for_category_and_code(category, code)
127
138
 
128
- @exceptions["exception_mappings"].detect { |m|
129
- m["category"] == category and m["exception_codes"].include?(code.to_s)
139
+ @exceptions["exception_mappings"].detect { |m|
140
+ m["category"] == category and m["exception_codes"].include?(code.to_s)
130
141
  }
131
142
 
132
143
  end
@@ -2,7 +2,7 @@ module Hps
2
2
  class HpsInputValidation
3
3
  def self.check_amount(amount)
4
4
  if amount < 0 || amount == nil
5
- raise InvalidRequestException
5
+ raise InvalidRequestException.new "Amount must be greater than or equal 0."
6
6
  end
7
7
 
8
8
  return amount if amount.is_a? Float
@@ -0,0 +1,301 @@
1
+ module Hps
2
+ class HpsGiftCardService < HpsService
3
+ def activate(giftcard, amount, currency = "USD")
4
+ HpsInputValidation.check_amount(amount)
5
+ txn_type = "GiftCardActivate"
6
+
7
+ xml = Builder::XmlMarkup.new
8
+ xml.hps :Transaction do
9
+ xml.hps txn_type.to_sym do
10
+ xml.hps :Block1 do
11
+ xml.hps :Amt, amount
12
+
13
+ if giftcard.is_a? HpsTokenData
14
+ card_data = HpsGiftCard.new
15
+ card_data.token_value = giftcard.token_value
16
+ else
17
+ card_data = giftcard
18
+ end
19
+
20
+ hydrate_gift_card_data(giftcard, xml)
21
+ end
22
+ end
23
+ end
24
+ submit_transaction(xml.target!, txn_type)
25
+ end # activate
26
+
27
+ def add_value(giftcard, amount, currency = "USD")
28
+ HpsInputValidation.check_amount(amount)
29
+ txn_type = "GiftCardAddValue"
30
+
31
+ xml = Builder::XmlMarkup.new
32
+ xml.hps :Transaction do
33
+ xml.hps txn_type.to_sym do
34
+ xml.hps :Block1 do
35
+ xml.hps :Amt, amount
36
+
37
+ if giftcard.is_a? HpsTokenData
38
+ card_data = HpsGiftCard.new
39
+ card_data.token_value = giftcard.token_value
40
+ else
41
+ card_data = giftcard
42
+ end
43
+
44
+ hydrate_gift_card_data(giftcard, xml)
45
+ end
46
+ end
47
+ end
48
+ submit_transaction(xml.target!, txn_type)
49
+ end # add_value
50
+
51
+ def balance(giftcard)
52
+ txn_type = "GiftCardBalance"
53
+
54
+ xml = Builder::XmlMarkup.new
55
+ xml.hps :Transaction do
56
+ xml.hps txn_type.to_sym do
57
+ xml.hps :Block1 do
58
+
59
+ if giftcard.is_a? HpsTokenData
60
+ card_data = HpsGiftCard.new
61
+ card_data.token_value = giftcard.token_value
62
+ else
63
+ card_data = giftcard
64
+ end
65
+
66
+ hydrate_gift_card_data(giftcard, xml)
67
+ end
68
+ end
69
+ end
70
+ submit_transaction(xml.target!, txn_type)
71
+ end # balance
72
+
73
+ def deactivate(giftcard)
74
+ txn_type = "GiftCardDeactivate"
75
+
76
+ xml = Builder::XmlMarkup.new
77
+ xml.hps :Transaction do
78
+ xml.hps txn_type.to_sym do
79
+ xml.hps :Block1 do
80
+
81
+ if giftcard.is_a? HpsTokenData
82
+ card_data = HpsGiftCard.new
83
+ card_data.token_value = giftcard.token_value
84
+ else
85
+ card_data = giftcard
86
+ end
87
+
88
+ hydrate_gift_card_data(giftcard, xml)
89
+ end
90
+ end
91
+ end
92
+ submit_transaction(xml.target!, txn_type)
93
+ end # deactivate
94
+
95
+ def replace(old_card, new_card)
96
+ txn_type = "GiftCardReplace"
97
+
98
+ xml = Builder::XmlMarkup.new
99
+ xml.hps :Transaction do
100
+ xml.hps txn_type.to_sym do
101
+ xml.hps :Block1 do
102
+
103
+ hydrate_gift_card_data(old_card, xml, 'OldCardData')
104
+ hydrate_gift_card_data(new_card, xml, 'NewCardData')
105
+
106
+ end
107
+ end
108
+ end
109
+ submit_transaction(xml.target!, txn_type)
110
+ end # replace
111
+
112
+ def reward(giftcard, amount, currency = "USD", gratuity = nil, tax = nil)
113
+ HpsInputValidation.check_amount(amount)
114
+ txn_type = "GiftCardReward"
115
+
116
+ xml = Builder::XmlMarkup.new
117
+ xml.hps :Transaction do
118
+ xml.hps txn_type.to_sym do
119
+ xml.hps :Block1 do
120
+ xml.hps :Amt, amount
121
+
122
+ if giftcard.is_a? HpsTokenData
123
+ card_data = HpsGiftCard.new
124
+ card_data.token_value = giftcard.token_value
125
+ else
126
+ card_data = giftcard
127
+ end
128
+
129
+ hydrate_gift_card_data(giftcard, xml)
130
+
131
+ if ["USD", "POINTS"].include? currency.upcase
132
+ xml.hps :Currency, currency.upcase
133
+ end
134
+
135
+ if gratuity
136
+ xml.hps :GratuityAmtInfo, gratuity
137
+ end
138
+
139
+ if tax
140
+ xml.hps :TaxAmtInfo, tax
141
+ end
142
+
143
+ end
144
+ end
145
+ end
146
+ submit_transaction(xml.target!, txn_type)
147
+ end # reward
148
+
149
+ def sale(giftcard, amount, currency = "USD", gratuity = nil, tax = nil)
150
+ HpsInputValidation.check_amount(amount)
151
+ txn_type = "GiftCardSale"
152
+
153
+ xml = Builder::XmlMarkup.new
154
+ xml.hps :Transaction do
155
+ xml.hps txn_type.to_sym do
156
+ xml.hps :Block1 do
157
+ xml.hps :Amt, amount
158
+
159
+ if giftcard.is_a? HpsTokenData
160
+ card_data = HpsGiftCard.new
161
+ card_data.token_value = giftcard.token_value
162
+ else
163
+ card_data = giftcard
164
+ end
165
+
166
+ hydrate_gift_card_data(giftcard, xml)
167
+
168
+ if ["USD", "POINTS"].include? currency.upcase
169
+ xml.hps :Currency, currency.upcase
170
+ end
171
+
172
+ if gratuity
173
+ xml.hps :GratuityAmtInfo, gratuity
174
+ end
175
+
176
+ if tax
177
+ xml.hps :TaxAmtInfo, tax
178
+ end
179
+
180
+ end
181
+ end
182
+ end
183
+ submit_transaction(xml.target!, txn_type)
184
+ end # sale
185
+
186
+ def void(txn_id)
187
+ txn_type = "GiftCardVoid"
188
+
189
+ xml = Builder::XmlMarkup.new
190
+ xml.hps :Transaction do
191
+ xml.hps txn_type.to_sym do
192
+ xml.hps :Block1 do
193
+ xml.hps :GatewayTxnId, txn_id
194
+ end
195
+ end
196
+ end
197
+ submit_transaction(xml.target!, txn_type)
198
+ end # void
199
+
200
+ def reverse(giftcard, amount)
201
+ HpsInputValidation.check_amount(amount)
202
+ txn_type = "GiftCardReversal"
203
+
204
+ xml = Builder::XmlMarkup.new
205
+ xml.hps :Transaction do
206
+ xml.hps txn_type.to_sym do
207
+ xml.hps :Block1 do
208
+ xml.hps :Amt, amount
209
+
210
+ if giftcard.is_a? HpsTokenData
211
+ xml.hps :TokenValue, giftcard.token_value
212
+ elsif giftcard.is_a? HpsGiftCard
213
+ card_data = giftcard
214
+ hydrate_gift_card_data(card_data, xml)
215
+ else
216
+ xml.hps :GatewayTxnId, giftcard
217
+ end
218
+
219
+ end
220
+ end
221
+ end
222
+ submit_transaction(xml.target!, txn_type)
223
+ end # reverse
224
+
225
+ private
226
+ def hydrate_gift_card_data(gift_card, xml, element_name = 'CardData')
227
+ xml.hps element_name.to_sym do
228
+ if gift_card.number
229
+ xml.hps :CardNbr, gift_card.number
230
+ elsif gift_card.track_data
231
+ xml.hps :TrackData, gift_card.track_data
232
+ elsif gift_card.alias
233
+ xml.hps :Alias, gift_card.alias
234
+ elsif gift_card.token_value
235
+ xml.hps :TokenValue, gift_card.token_value
236
+ end
237
+
238
+ if gift_card.encryption_data
239
+ hydrate_encryption_data(gift_card.encryption_data, xml)
240
+ end
241
+
242
+ if gift_card.pin
243
+ xml.hps :PIN, gift_card.pin
244
+ end
245
+ end
246
+ end # hydrate_gift_card_data
247
+
248
+ def hydrate_encryption_data(encryption_data, xml)
249
+ xml.hps :EncryptionData do
250
+ if encryption_data.encrypted_track_number
251
+ xml.hps :EncryptedTrackNumber, encryption_data.encrypted_track_number
252
+ end
253
+ xml.hps :KSN, encryption_data.ksn
254
+ xml.hps :KTB, encryption_data.ktb
255
+ xml.hps :Version, encryption_data.version
256
+ end
257
+ end # hydrate_encryption_data
258
+
259
+ def submit_transaction(transaction, txn_type, client_txn_id = nil)
260
+ response = doTransaction(transaction, client_txn_id)
261
+
262
+ header = response['Header']
263
+ transaction_response = response["Transaction"][txn_type]
264
+
265
+ if !transaction_response["RspCode"].eql? "0"
266
+ raise @exception_mapper.map_gift_card_exception(header["GatewayTxnId"], transaction_response["RspCode"], transaction_response["RspText"])
267
+ end
268
+
269
+ if !header["GatewayRspCode"].eql? "0"
270
+ raise @exception_mapper.map_gateway_exception(header["GatewayTxnId"], header["GatewayRspCode"], header["GatewayRspMsg"])
271
+ end
272
+
273
+ rvalue = ''
274
+ case txn_type
275
+ when 'GiftCardActivate'
276
+ rvalue = HpsGiftCardActivate::from_response(response, txn_type)
277
+ when 'GiftCardAddValue'
278
+ rvalue = HpsGiftCardAddValue::from_response(response, txn_type)
279
+ when 'GiftCardAlias'
280
+ rvalue = HpsGiftCardAlias::from_response(response, txn_type)
281
+ when 'GiftCardBalance'
282
+ rvalue = HpsGiftCardBalance::from_response(response, txn_type)
283
+ when 'GiftCardDeactivate'
284
+ rvalue = HpsGiftCardDeactivate::from_response(response, txn_type)
285
+ when 'GiftCardReplace'
286
+ rvalue = HpsGiftCardReplace::from_response(response, txn_type)
287
+ when 'GiftCardReward'
288
+ rvalue = HpsGiftCardReward::from_response(response, txn_type)
289
+ when 'GiftCardSale'
290
+ rvalue = HpsGiftCardSale::from_response(response, txn_type)
291
+ when 'GiftCardVoid'
292
+ rvalue = HpsGiftCardVoid::from_response(response, txn_type)
293
+ when 'GiftCardReversal'
294
+ rvalue = HpsGiftCardReversal::from_response(response, txn_type)
295
+ end
296
+
297
+ return rvalue;
298
+ end # submit_transaction
299
+
300
+ end # HpsGiftCardService
301
+ end # Hps