1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
26:
27: 28: 29:
30: class Mage_Centinel_Model_Service extends Varien_Object
31: {
32: 33: 34:
35: const CMPI_PARES = 'centinel_authstatus';
36: const CMPI_ENROLLED = 'centinel_mpivendor';
37: const CMPI_CAVV = 'centinel_cavv';
38: const CMPI_ECI = 'centinel_eci';
39: const CMPI_XID = 'centinel_xid';
40:
41: 42: 43: 44: 45:
46: protected $_cmpiMap = array(
47: 'lookup_enrolled' => self::CMPI_ENROLLED,
48: 'lookup_eci_flag' => self::CMPI_ECI,
49: 'authenticate_pa_res_status' => self::CMPI_PARES,
50: 'authenticate_cavv' => self::CMPI_CAVV,
51: 'authenticate_eci_flag' => self::CMPI_ECI,
52: 'authenticate_xid' => self::CMPI_XID,
53: );
54:
55: 56: 57: 58: 59:
60: protected $_api;
61:
62: 63: 64: 65: 66:
67: protected $_validationState;
68:
69: 70: 71: 72: 73:
74: protected function _getSession()
75: {
76: return Mage::getSingleton('centinel/session');
77: }
78:
79: 80: 81: 82: 83: 84:
85: protected function _getConfig()
86: {
87: $config = Mage::getSingleton('centinel/config');
88: return $config->setStore($this->getStore());
89: }
90:
91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101:
102: protected function _generateChecksum($paymentMethodCode, $cardType, $cardNumber, $cardExpMonth, $cardExpYear, $amount, $currencyCode)
103: {
104: return md5(implode(func_get_args(), '_'));
105: }
106:
107: 108: 109: 110: 111: 112: 113:
114: private function _getUrl($suffix, $current = false)
115: {
116: $params = array(
117: '_secure' => true,
118: '_current' => $current,
119: 'form_key' => Mage::getSingleton('core/session')->getFormKey(),
120: 'isIframe' => true
121: );
122: if (Mage::app()->getStore()->isAdmin()) {
123: return Mage::getSingleton('adminhtml/url')->getUrl('*/centinel_index/' . $suffix, $params);
124: } else {
125: return Mage::getUrl('centinel/index/' . $suffix, $params);
126: }
127: }
128:
129: 130: 131: 132: 133:
134: protected function _getApi()
135: {
136: if (!is_null($this->_api)) {
137: return $this->_api;
138: }
139:
140: $this->_api = Mage::getSingleton('centinel/api');
141: $config = $this->_getConfig();
142: $this->_api
143: ->setProcessorId($config->getProcessorId())
144: ->setMerchantId($config->getMerchantId())
145: ->setTransactionPwd($config->getTransactionPwd())
146: ->setIsTestMode($config->getIsTestMode())
147: ->setDebugFlag($config->getDebugFlag())
148: ->setApiEndpointUrl($this->getCustomApiEndpointUrl());
149: return $this->_api;
150: }
151:
152: 153: 154: 155: 156: 157:
158: protected function _getValidationStateModel($cardType)
159: {
160: if ($modelClass = $this->_getConfig()->getStateModelClass($cardType)) {
161: return Mage::getModel($modelClass);
162: }
163: return false;
164: }
165:
166: 167: 168: 169: 170: 171:
172: protected function _getValidationState($cardType = null)
173: {
174: $type = $cardType ? $cardType : $this->_getSession()->getData('card_type');
175: if (!$this->_validationState && $type) {
176: $model = $this->_getValidationStateModel($type);
177: if (!$model) {
178: return false;
179: }
180: $model->setDataStorage($this->_getSession());
181: $this->_validationState = $model;
182: }
183: return $this->_validationState;
184: }
185:
186: 187: 188: 189:
190: protected function _resetValidationState()
191: {
192: $this->_getSession()->setData(array());
193: $this->_validationState = false;
194: }
195:
196: 197: 198: 199: 200: 201: 202:
203: protected function _initValidationState($cardType, $dataChecksum)
204: {
205: $this->_resetValidationState();
206: $state = $this->_getValidationStateModel($cardType);
207: $state->setDataStorage($this->_getSession())
208: ->setCardType($cardType)
209: ->setChecksum($dataChecksum)
210: ->setIsModeStrict($this->getIsModeStrict());
211: return $this->_getValidationState();
212: }
213:
214: 215: 216: 217: 218:
219: public function lookup($data)
220: {
221: $newChecksum = $this->_generateChecksum(
222: $data->getPaymentMethodCode(),
223: $data->getCardType(),
224: $data->getCardNumber(),
225: $data->getCardExpMonth(),
226: $data->getCardExpYear(),
227: $data->getAmount(),
228: $data->getCurrencyCode()
229: );
230:
231: $validationState = $this->_initValidationState($data->getCardType(), $newChecksum);
232:
233: $api = $this->_getApi();
234: $result = $api->callLookup($data);
235: $validationState->setLookupResult($result);
236: }
237:
238: 239: 240: 241: 242:
243: public function authenticate($data)
244: {
245: $validationState = $this->_getValidationState();
246: if (!$validationState || $data->getTransactionId() != $validationState->getLookupTransactionId()) {
247: throw new Exception('Authentication impossible: transaction id or validation state is wrong.');
248: }
249:
250: $api = $this->_getApi();
251: $result = $api->callAuthentication($data);
252: $validationState->setAuthenticateResult($result);
253: if (!$validationState->isAuthenticateSuccessful()) {
254: $this->reset();
255: }
256: }
257:
258: 259: 260: 261: 262: 263: 264: 265: 266:
267: public function validate($data)
268: {
269: $newChecksum = $this->_generateChecksum(
270: $data->getPaymentMethodCode(),
271: $data->getCardType(),
272: $data->getCardNumber(),
273: $data->getCardExpMonth(),
274: $data->getCardExpYear(),
275: $data->getAmount(),
276: $data->getCurrencyCode()
277: );
278:
279: $validationState = $this->_getValidationState($data->getCardType());
280: if (!$validationState) {
281: $this->_resetValidationState();
282: return;
283: }
284:
285:
286: if ($this->getIsPlaceOrder()) {
287: if ($validationState->getChecksum() != $newChecksum) {
288: Mage::throwException(Mage::helper('centinel')->__('Payment information error. Please start over.'));
289: }
290: if ($validationState->isAuthenticateSuccessful()) {
291: return;
292: }
293: Mage::throwException(Mage::helper('centinel')->__('Please verify the card with the issuer bank before placing the order.'));
294: } else {
295: if ($validationState->getChecksum() != $newChecksum || !$validationState->isLookupSuccessful()) {
296: $this->lookup($data);
297: $validationState = $this->_getValidationState();
298: }
299: if ($validationState->isLookupSuccessful()) {
300: return;
301: }
302: Mage::throwException(Mage::helper('centinel')->__('This card has failed validation and cannot be used.'));
303: }
304: }
305:
306: 307: 308: 309: 310:
311: public function reset()
312: {
313: $this->_resetValidationState();
314: $this->_api = null;
315: return $this;
316: }
317:
318: 319: 320: 321: 322:
323: public function getAuthenticationStartUrl()
324: {
325: return $this->_getUrl('authenticationstart');
326: }
327:
328: 329: 330: 331: 332:
333: public function getValidatePaymentDataUrl()
334: {
335: return $this->_getUrl('validatepaymentdata');
336: }
337:
338: 339: 340: 341: 342:
343: public function shouldAuthenticate()
344: {
345: $validationState = $this->_getValidationState();
346: return $validationState && $validationState->isAuthenticateAllowed();
347: }
348:
349: 350: 351: 352: 353:
354: public function getAuthenticateStartData()
355: {
356: $validationState = $this->_getValidationState();
357: if (!$validationState && $this->shouldAuthenticate()) {
358: throw new Exception('Authentication impossible: validation state is wrong.');
359: }
360: $data = array(
361: 'acs_url' => $validationState->getLookupAcsUrl(),
362: 'pa_req' => $validationState->getLookupPayload(),
363: 'term_url' => $this->_getUrl('authenticationcomplete', true),
364: 'md' => $validationState->getLookupTransactionId()
365: );
366: return $data;
367: }
368:
369: 370: 371: 372: 373:
374: public function isAuthenticateSuccessful()
375: {
376: $validationState = $this->_getValidationState();
377: return $validationState && $validationState->isAuthenticateSuccessful();
378: }
379:
380: 381: 382: 383: 384: 385: 386:
387: public function exportCmpiData($to, $map = false)
388: {
389: if (!$map) {
390: $map = $this->_cmpiMap;
391: }
392: if ($validationState = $this->_getValidationState()) {
393: $to = Varien_Object_Mapper::accumulateByMap($validationState, $to, $map);
394: }
395: return $to;
396: }
397: }
398:
399: