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: 31: 32: 33:
34: class Mage_Paypal_Model_Info
35: {
36: 37: 38: 39: 40:
41: const PAYER_ID = 'payer_id';
42: const PAYER_EMAIL = 'email';
43: const PAYER_STATUS = 'payer_status';
44: const ADDRESS_ID = 'address_id';
45: const ADDRESS_STATUS = 'address_status';
46: const PROTECTION_EL = 'protection_eligibility';
47: const FRAUD_FILTERS = 'collected_fraud_filters';
48: const CORRELATION_ID = 'correlation_id';
49: const AVS_CODE = 'avs_result';
50: const CVV2_MATCH = 'cvv2_check_result';
51: const CENTINEL_VPAS = 'centinel_vpas_result';
52: const CENTINEL_ECI = 'centinel_eci_result';
53:
54:
55: const BUYER_TAX_ID = 'buyer_tax_id';
56: const BUYER_TAX_ID_TYPE = 'buyer_tax_id_type';
57:
58: const PAYMENT_STATUS = 'payment_status';
59: const PENDING_REASON = 'pending_reason';
60: const IS_FRAUD = 'is_fraud_detected';
61: const PAYMENT_STATUS_GLOBAL = 'paypal_payment_status';
62: const PENDING_REASON_GLOBAL = 'paypal_pending_reason';
63: const IS_FRAUD_GLOBAL = 'paypal_is_fraud_detected';
64:
65: 66: 67:
68: const BUYER_TAX_ID_TYPE_CPF = 'BR_CPF';
69: const BUYER_TAX_ID_TYPE_CNPJ = 'BR_CNPJ';
70:
71: 72: 73: 74: 75:
76: protected $_paymentMap = array(
77: self::PAYER_ID => 'paypal_payer_id',
78: self::PAYER_EMAIL => 'paypal_payer_email',
79: self::PAYER_STATUS => 'paypal_payer_status',
80: self::ADDRESS_ID => 'paypal_address_id',
81: self::ADDRESS_STATUS => 'paypal_address_status',
82: self::PROTECTION_EL => 'paypal_protection_eligibility',
83: self::FRAUD_FILTERS => 'paypal_fraud_filters',
84: self::CORRELATION_ID => 'paypal_correlation_id',
85: self::AVS_CODE => 'paypal_avs_code',
86: self::CVV2_MATCH => 'paypal_cvv2_match',
87: self::CENTINEL_VPAS => self::CENTINEL_VPAS,
88: self::CENTINEL_ECI => self::CENTINEL_ECI,
89: self::BUYER_TAX_ID => self::BUYER_TAX_ID,
90: self::BUYER_TAX_ID_TYPE => self::BUYER_TAX_ID_TYPE,
91: );
92:
93: 94: 95: 96: 97:
98: protected $_systemMap = array(
99: self::PAYMENT_STATUS => self::PAYMENT_STATUS_GLOBAL,
100: self::PENDING_REASON => self::PENDING_REASON_GLOBAL,
101: self::IS_FRAUD => self::IS_FRAUD_GLOBAL,
102: );
103:
104: 105: 106: 107: 108:
109: const PAYMENTSTATUS_NONE = 'none';
110: const PAYMENTSTATUS_COMPLETED = 'completed';
111: const PAYMENTSTATUS_DENIED = 'denied';
112: const PAYMENTSTATUS_EXPIRED = 'expired';
113: const PAYMENTSTATUS_FAILED = 'failed';
114: const PAYMENTSTATUS_INPROGRESS = 'in_progress';
115: const PAYMENTSTATUS_PENDING = 'pending';
116: const PAYMENTSTATUS_REFUNDED = 'refunded';
117: const PAYMENTSTATUS_REFUNDEDPART = 'partially_refunded';
118: const PAYMENTSTATUS_REVERSED = 'reversed';
119: const PAYMENTSTATUS_UNREVERSED = 'canceled_reversal';
120: const PAYMENTSTATUS_PROCESSED = 'processed';
121: const PAYMENTSTATUS_VOIDED = 'voided';
122:
123: 124: 125: 126: 127:
128: protected $_paymentPublicMap = array(
129: 'paypal_payer_email',
130: self::BUYER_TAX_ID,
131: self::BUYER_TAX_ID_TYPE
132: );
133:
134: 135: 136: 137: 138:
139: protected $_paymentMapFull = array();
140:
141: 142: 143: 144: 145: 146: 147:
148: public function getPaymentInfo(Mage_Payment_Model_Info $payment, $labelValuesOnly = false)
149: {
150:
151: $result = $this->_getFullInfo(array_values($this->_paymentMap), $payment, $labelValuesOnly);
152:
153:
154: $label = Mage::helper('paypal')->__('Last Transaction ID');
155: $value = $payment->getLastTransId();
156: if ($labelValuesOnly) {
157: $result[$label] = $value;
158: } else {
159: $result['last_trans_id'] = array('label' => $label, 'value' => $value);
160: }
161:
162: return $result;
163: }
164:
165: 166: 167: 168: 169: 170: 171:
172: public function getPublicPaymentInfo(Mage_Payment_Model_Info $payment, $labelValuesOnly = false)
173: {
174: return $this->_getFullInfo($this->_paymentPublicMap, $payment, $labelValuesOnly);
175: }
176:
177: 178: 179: 180: 181: 182:
183: public function importToPayment($from, Mage_Payment_Model_Info $payment)
184: {
185: $fullMap = array_merge($this->_paymentMap, $this->_systemMap);
186: if (is_object($from)) {
187: $from = array($from, 'getDataUsingMethod');
188: }
189: Varien_Object_Mapper::accumulateByMap($from, array($payment, 'setAdditionalInformation'), $fullMap);
190: }
191:
192: 193: 194: 195: 196: 197: 198: 199:
200: public function &exportFromPayment(Mage_Payment_Model_Info $payment, $to, array $map = null)
201: {
202: $fullMap = array_merge($this->_paymentMap, $this->_systemMap);
203: Varien_Object_Mapper::accumulateByMap(array($payment, 'getAdditionalInformation'), $to,
204: $map ? $map : array_flip($fullMap)
205: );
206: return $to;
207: }
208:
209: 210: 211: 212: 213: 214:
215: public static function isPaymentReviewRequired(Mage_Payment_Model_Info $payment)
216: {
217: $paymentStatus = $payment->getAdditionalInformation(self::PAYMENT_STATUS_GLOBAL);
218: if (self::PAYMENTSTATUS_PENDING === $paymentStatus) {
219: $pendingReason = $payment->getAdditionalInformation(self::PENDING_REASON_GLOBAL);
220: return !in_array($pendingReason, array('authorization', 'order'));
221: }
222: return false;
223: }
224:
225: 226: 227: 228: 229: 230:
231: public static function isFraudReviewAllowed(Mage_Payment_Model_Info $payment)
232: {
233: return self::isPaymentReviewRequired($payment)
234: && 1 == $payment->getAdditionalInformation(self::IS_FRAUD_GLOBAL);
235: }
236:
237: 238: 239: 240: 241: 242:
243: public static function isPaymentCompleted(Mage_Payment_Model_Info $payment)
244: {
245: $paymentStatus = $payment->getAdditionalInformation(self::PAYMENT_STATUS_GLOBAL);
246: return self::PAYMENTSTATUS_COMPLETED === $paymentStatus;
247: }
248:
249: 250: 251: 252: 253: 254:
255: public static function isPaymentSuccessful(Mage_Payment_Model_Info $payment)
256: {
257: $paymentStatus = $payment->getAdditionalInformation(self::PAYMENT_STATUS_GLOBAL);
258: if (in_array($paymentStatus, array(
259: self::PAYMENTSTATUS_COMPLETED, self::PAYMENTSTATUS_INPROGRESS, self::PAYMENTSTATUS_REFUNDED,
260: self::PAYMENTSTATUS_REFUNDEDPART, self::PAYMENTSTATUS_UNREVERSED, self::PAYMENTSTATUS_PROCESSED,
261: ))) {
262: return true;
263: }
264: $pendingReason = $payment->getAdditionalInformation(self::PENDING_REASON_GLOBAL);
265: return self::PAYMENTSTATUS_PENDING === $paymentStatus
266: && in_array($pendingReason, array('authorization', 'order'));
267: }
268:
269: 270: 271: 272: 273: 274:
275: public static function isPaymentFailed(Mage_Payment_Model_Info $payment)
276: {
277: $paymentStatus = $payment->getAdditionalInformation(self::PAYMENT_STATUS_GLOBAL);
278: return in_array($paymentStatus, array(
279: self::PAYMENTSTATUS_DENIED, self::PAYMENTSTATUS_EXPIRED, self::PAYMENTSTATUS_FAILED,
280: self::PAYMENTSTATUS_REVERSED, self::PAYMENTSTATUS_VOIDED,
281: ));
282: }
283:
284: 285: 286: 287: 288: 289: 290: 291:
292: public static function explainPendingReason($code)
293: {
294: switch ($code) {
295: case 'address':
296: return Mage::helper('paypal')->__('Customer did not include a confirmed address.');
297: case 'authorization':
298: case 'order':
299: return Mage::helper('paypal')->__('The payment is authorized but not settled.');
300: case 'echeck':
301: return Mage::helper('paypal')->__('The payment eCheck is not yet cleared.');
302: case 'intl':
303: return Mage::helper('paypal')->__('Merchant holds a non-U.S. account and does not have a withdrawal mechanism.');
304: case 'multi-currency':
305: case 'multi_currency':
306: case 'multicurrency':
307: return Mage::helper('paypal')->__('The payment curency does not match any of the merchant\'s balances currency.');
308: case 'paymentreview':
309: return Mage::helper('paypal')->__('The payment is pending while it is being reviewed by PayPal for risk.');
310: case 'unilateral':
311: return Mage::helper('paypal')->__('The payment is pending because it was made to an email address that is not yet registered or confirmed.');
312: case 'verify':
313: return Mage::helper('paypal')->__('The merchant account is not yet verified.');
314: case 'upgrade':
315: return Mage::helper('paypal')->__('The payment was made via credit card. In order to receive funds merchant must upgrade account to Business or Premier status.');
316: case 'none':
317: case 'other':
318: default:
319: return Mage::helper('paypal')->__('Unknown reason. Please contact PayPal customer service.');
320: }
321: }
322:
323: 324: 325: 326: 327: 328: 329: 330:
331: public static function explainReasonCode($code)
332: {
333: switch ($code) {
334: case 'chargeback':
335: return Mage::helper('paypal')->__('Chargeback by customer.');
336: case 'guarantee':
337: return Mage::helper('paypal')->__('Customer triggered a money-back guarantee.');
338: case 'buyer-complaint':
339: return Mage::helper('paypal')->__('Customer complaint.');
340: case 'refund':
341: return Mage::helper('paypal')->__('Refund issued by merchant.');
342: case 'adjustment_reversal':
343: return Mage::helper('paypal')->__('Reversal of an adjustment.');
344: case 'chargeback_reimbursement':
345: return Mage::helper('paypal')->__('Reimbursement for a chargeback.');
346: case 'chargeback_settlement':
347: return Mage::helper('paypal')->__('Settlement of a chargeback.');
348: case 'none':
349: case 'other':
350: default:
351: return Mage::helper('paypal')->__('Unknown reason. Please contact PayPal customer service.');
352: }
353: }
354:
355: 356: 357: 358: 359: 360:
361: public static function isReversalDisputable($code)
362: {
363: switch ($code) {
364: case 'none':
365: case 'other':
366: case 'chargeback':
367: case 'buyer-complaint':
368: case 'adjustment_reversal':
369: return true;
370: case 'guarantee':
371: case 'refund':
372: case 'chargeback_reimbursement':
373: case 'chargeback_settlement':
374: default:
375: return false;
376: }
377: }
378:
379: 380: 381: 382: 383: 384: 385:
386: protected function _getFullInfo(array $keys, Mage_Payment_Model_Info $payment, $labelValuesOnly)
387: {
388: $result = array();
389: foreach ($keys as $key) {
390: if (!isset($this->_paymentMapFull[$key])) {
391: $this->_paymentMapFull[$key] = array();
392: }
393: if (!isset($this->_paymentMapFull[$key]['label'])) {
394: if (!$payment->hasAdditionalInformation($key)) {
395: $this->_paymentMapFull[$key]['label'] = false;
396: $this->_paymentMapFull[$key]['value'] = false;
397: } else {
398: $value = $payment->getAdditionalInformation($key);
399: $this->_paymentMapFull[$key]['label'] = $this->_getLabel($key);
400: $this->_paymentMapFull[$key]['value'] = $this->_getValue($value, $key);
401: }
402: }
403: if (!empty($this->_paymentMapFull[$key]['value'])) {
404: if ($labelValuesOnly) {
405: $result[$this->_paymentMapFull[$key]['label']] = $this->_paymentMapFull[$key]['value'];
406: } else {
407: $result[$key] = $this->_paymentMapFull[$key];
408: }
409: }
410: }
411: return $result;
412: }
413:
414: 415: 416: 417: 418:
419: protected function _getLabel($key)
420: {
421: switch ($key) {
422: case 'paypal_payer_id':
423: return Mage::helper('paypal')->__('Payer ID');
424: case 'paypal_payer_email':
425: return Mage::helper('paypal')->__('Payer Email');
426: case 'paypal_payer_status':
427: return Mage::helper('paypal')->__('Payer Status');
428: case 'paypal_address_id':
429: return Mage::helper('paypal')->__('Payer Address ID');
430: case 'paypal_address_status':
431: return Mage::helper('paypal')->__('Payer Address Status');
432: case 'paypal_protection_eligibility':
433: return Mage::helper('paypal')->__('Merchant Protection Eligibility');
434: case 'paypal_fraud_filters':
435: return Mage::helper('paypal')->__('Triggered Fraud Filters');
436: case 'paypal_correlation_id':
437: return Mage::helper('paypal')->__('Last Correlation ID');
438: case 'paypal_avs_code':
439: return Mage::helper('paypal')->__('Address Verification System Response');
440: case 'paypal_cvv2_match':
441: return Mage::helper('paypal')->__('CVV2 Check Result by PayPal');
442: case self::BUYER_TAX_ID :
443: return Mage::helper('paypal')->__('Buyer\'s Tax ID');
444: case self::BUYER_TAX_ID_TYPE :
445: return Mage::helper('paypal')->__('Buyer\'s Tax ID Type');
446: case self::CENTINEL_VPAS:
447: return Mage::helper('paypal')->__('PayPal/Centinel Visa Payer Authentication Service Result');
448: case self::CENTINEL_ECI:
449: return Mage::helper('paypal')->__('PayPal/Centinel Electronic Commerce Indicator');
450: }
451: return '';
452: }
453:
454: 455: 456: 457: 458: 459: 460:
461: protected function _getValue($value, $key)
462: {
463: $label = '';
464: switch ($key) {
465: case 'paypal_avs_code':
466: $label = $this->_getAvsLabel($value);
467: break;
468: case 'paypal_cvv2_match':
469: $label = $this->_getCvv2Label($value);
470: break;
471: case self::CENTINEL_VPAS:
472: $label = $this->_getCentinelVpasLabel($value);
473: break;
474: case self::CENTINEL_ECI:
475: $label = $this->_getCentinelEciLabel($value);
476: break;
477: case self::BUYER_TAX_ID_TYPE :
478: $value = $this->_getBuyerIdTypeValue($value);
479: default:
480: return $value;
481: }
482: return sprintf('#%s%s', $value, $value == $label ? '' : ': ' . $label);
483: }
484:
485: 486: 487: 488: 489: 490: 491:
492: protected function _getAvsLabel($value)
493: {
494: switch ($value) {
495:
496: case 'A':
497: case 'YN':
498: return Mage::helper('paypal')->__('Matched Address only (no ZIP)');
499: case 'B':
500: return Mage::helper('paypal')->__('Matched Address only (no ZIP). International');
501: case 'N':
502: return Mage::helper('paypal')->__('No Details matched');
503: case 'C':
504: return Mage::helper('paypal')->__('No Details matched. International');
505: case 'X':
506: return Mage::helper('paypal')->__('Exact Match. Address and nine-digit ZIP code');
507: case 'D':
508: return Mage::helper('paypal')->__('Exact Match. Address and Postal Code. International');
509: case 'F':
510: return Mage::helper('paypal')->__('Exact Match. Address and Postal Code. UK-specific');
511: case 'E':
512: return Mage::helper('paypal')->__('N/A. Not allowed for MOTO (Internet/Phone) transactions');
513: case 'G':
514: return Mage::helper('paypal')->__('N/A. Global Unavailable');
515: case 'I':
516: return Mage::helper('paypal')->__('N/A. International Unavailable');
517: case 'Z':
518: case 'NY':
519: return Mage::helper('paypal')->__('Matched five-digit ZIP only (no Address)');
520: case 'P':
521: case 'NY':
522: return Mage::helper('paypal')->__('Matched Postal Code only (no Address)');
523: case 'R':
524: return Mage::helper('paypal')->__('N/A. Retry');
525: case 'S':
526: return Mage::helper('paypal')->__('N/A. Service not Supported');
527: case 'U':
528: return Mage::helper('paypal')->__('N/A. Unavailable');
529: case 'W':
530: return Mage::helper('paypal')->__('Matched whole nine-didgit ZIP (no Address)');
531: case 'Y':
532: return Mage::helper('paypal')->__('Yes. Matched Address and five-didgit ZIP');
533:
534: case '0':
535: return Mage::helper('paypal')->__('All the address information matched');
536: case '1':
537: return Mage::helper('paypal')->__('None of the address information matched');
538: case '2':
539: return Mage::helper('paypal')->__('Part of the address information matched');
540: case '3':
541: return Mage::helper('paypal')->__('N/A. The merchant did not provide AVS information');
542: case '4':
543: return Mage::helper('paypal')->__('N/A. Address not checked, or acquirer had no response. Service not available');
544: default:
545: return $value;
546: }
547: }
548:
549: 550: 551: 552: 553: 554: 555:
556: protected function _getCvv2Label($value)
557: {
558: switch ($value) {
559:
560: case 'M':
561: return Mage::helper('paypal')->__('Matched (CVV2CSC)');
562: case 'N':
563: return Mage::helper('paypal')->__('No match');
564: case 'P':
565: return Mage::helper('paypal')->__('N/A. Not processed');
566: case 'S':
567: return Mage::helper('paypal')->__('N/A. Service not supported');
568: case 'U':
569: return Mage::helper('paypal')->__('N/A. Service not available');
570: case 'X':
571: return Mage::helper('paypal')->__('N/A. No response');
572:
573: case '0':
574: return Mage::helper('paypal')->__('Matched (CVV2)');
575: case '1':
576: return Mage::helper('paypal')->__('No match');
577: case '2':
578: return Mage::helper('paypal')->__('N/A. The merchant has not implemented CVV2 code handling');
579: case '3':
580: return Mage::helper('paypal')->__('N/A. Merchant has indicated that CVV2 is not present on card');
581: case '4':
582: return Mage::helper('paypal')->__('N/A. Service not available');
583: default:
584: return $value;
585: }
586: }
587:
588: 589: 590: 591: 592: 593: 594:
595: private function _getCentinelVpasLabel($value)
596: {
597: switch ($value) {
598: case '2':
599: case 'D':
600: return Mage::helper('paypal')->__('Authenticated, Good Result');
601: case '1':
602: return Mage::helper('paypal')->__('Authenticated, Bad Result');
603: case '3':
604: case '6':
605: case '8':
606: case 'A':
607: case 'C':
608: return Mage::helper('paypal')->__('Attempted Authentication, Good Result');
609: case '4':
610: case '7':
611: case '9':
612: return Mage::helper('paypal')->__('Attempted Authentication, Bad Result');
613: case '':
614: case '0':
615: case 'B':
616: return Mage::helper('paypal')->__('No Liability Shift');
617: default:
618: return $value;
619: }
620: }
621:
622: 623: 624: 625: 626: 627: 628:
629: private function _getCentinelEciLabel($value)
630: {
631: switch ($value) {
632: case '01':
633: case '07':
634: return Mage::helper('paypal')->__('Merchant Liability');
635: case '02':
636: case '05':
637: case '06':
638: return Mage::helper('paypal')->__('Issuer Liability');
639: default:
640: return $value;
641: }
642: }
643:
644: 645: 646: 647: 648: 649:
650: protected function _getBuyerIdTypeValue($code)
651: {
652: $value = '';
653: switch ($code) {
654: case self::BUYER_TAX_ID_TYPE_CNPJ :
655: $value = Mage::helper('paypal')->__('CNPJ');
656: break;
657: case self::BUYER_TAX_ID_TYPE_CPF :
658: $value = Mage::helper('paypal')->__('CPF');
659: break;
660: }
661: return $value;
662: }
663: }
664: