00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 class Mage_AmazonPayments_Model_Payment_Asp_Notification extends Varien_Object
00035 {
00036
00037
00038
00039 protected $_payment;
00040
00041
00042
00043
00044
00045
00046
00047 public function setPayment($payment)
00048 {
00049 $this->_payment = $payment;
00050 return $this;
00051 }
00052
00053
00054
00055
00056
00057
00058 public function getPayment()
00059 {
00060 return $this->_payment;
00061 }
00062
00063
00064
00065
00066
00067
00068 public function process($requestParams)
00069 {
00070 $request = $this->getPayment()->getApi()->processNotification($requestParams);
00071
00072 if ($request->getStatus() == Mage_AmazonPayments_Model_Api_Asp_Ipn_Request::STATUS_CANCEL_TRANSACTION) {
00073 return true;
00074 }
00075
00076 $order = $this->_getRequestOrder($request);
00077 switch ($request->getStatus()) {
00078 case Mage_AmazonPayments_Model_Api_Asp_Ipn_Request::STATUS_CANCEL_CUSTOMER:
00079 $this->_processCancel($request, $order);
00080 break;
00081 case Mage_AmazonPayments_Model_Api_Asp_Ipn_Request::STATUS_RESERVE_SUCCESSFUL:
00082 $this->_processReserveSuccess($request, $order);
00083 break;
00084 case Mage_AmazonPayments_Model_Api_Asp_Ipn_Request::STATUS_PAYMENT_INITIATED:
00085 $this->_processPaymetInitiated($request, $order);
00086 break;
00087 case Mage_AmazonPayments_Model_Api_Asp_Ipn_Request::STATUS_PAYMENT_SUCCESSFUL:
00088 $this->_processPaymentSuccessful($request, $order);
00089 break;
00090 case Mage_AmazonPayments_Model_Api_Asp_Ipn_Request::STATUS_PAYMENT_FAILED:
00091 $this->_processPaymentFailed($request, $order);
00092 break;
00093 case Mage_AmazonPayments_Model_Api_Asp_Ipn_Request::STATUS_REFUND_SUCCESSFUL:
00094 $this->_processRefundSuccessful($request, $order);
00095 break;
00096 case Mage_AmazonPayments_Model_Api_Asp_Ipn_Request::STATUS_REFUND_FAILED:
00097 $this->_processRefundFailed($request, $order);
00098 break;
00099 case Mage_AmazonPayments_Model_Api_Asp_Ipn_Request::STATUS_SYSTEM_ERROR:
00100 $this->_processSystemError($request, $order);
00101 break;
00102 }
00103 $order->save();
00104 }
00105
00106
00107
00108
00109 protected function _processCancel($request, $order)
00110 {
00111 if ($order->getState() == Mage_Sales_Model_Order::STATE_CANCELED) {
00112 $order->addStatusToHistory(
00113 $order->getStatus(),
00114 Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed cancelation.')
00115 );
00116 return true;
00117 }
00118
00119 if ($order->getState() == Mage_Sales_Model_Order::STATE_NEW) {
00120 $order->addStatusToHistory(
00121 $order->getStatus(),
00122 Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed cancelation.')
00123 )->cancel();
00124 return true;
00125 }
00126
00127 $this->_errorViolationSequenceStates($request, $order);
00128 }
00129
00130
00131
00132
00133 protected function _processReserveSuccess($request, $order)
00134 {
00135 if ($order->getState() != Mage_Sales_Model_Order::STATE_NEW) {
00136 $this->_errorViolationSequenceStates($request, $order);
00137 }
00138
00139 $order->getPayment()->setCcTransId($request->getTransactionId());
00140
00141 $order->setState(
00142 Mage_Sales_Model_Order::STATE_PENDING_PAYMENT,
00143 'pending_amazon_asp',
00144 Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed amount authorization.'),
00145 $notified = false
00146 );
00147
00148 return true;
00149 }
00150
00151
00152
00153
00154 protected function _processPaymetInitiated($request, $order)
00155 {
00156 if ($order->getState() != Mage_Sales_Model_Order::STATE_NEW &&
00157 $order->getState() != Mage_Sales_Model_Order::STATE_PENDING_PAYMENT) {
00158 $this->_errorViolationSequenceStates($request, $order);
00159 }
00160
00161 $order->setState(
00162 Mage_Sales_Model_Order::STATE_PENDING_PAYMENT,
00163 'pending_amazon_asp',
00164 Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed capture initiation.'),
00165 $notified = false
00166 );
00167
00168 return true;
00169 }
00170
00171
00172
00173
00174 protected function _processPaymentSuccessful($request, $order)
00175 {
00176 if ($order->getState() != Mage_Sales_Model_Order::STATE_NEW &&
00177 $order->getState() != Mage_Sales_Model_Order::STATE_PENDING_PAYMENT &&
00178 $order->getState() != Mage_Sales_Model_Order::STATE_PROCESSING) {
00179 $this->_errorViolationSequenceStates($request, $order);
00180 }
00181
00182 $msg = '';
00183
00184 if (!$invoice = $this->_getOrderInvoice($order)) {
00185
00186 $orderAmount = Mage::app()->getStore()->roundPrice($order->getBaseGrandTotal());
00187 $requestAmount = Mage::app()->getStore()->roundPrice($request->getAmount());
00188 if ($orderAmount != $requestAmount) {
00189 $this->_error(
00190 Mage::helper('amazonpayments')->__('Amazon Simple Pay service capture confirmation error: confirmation request amount not equal to the amount of order.'),
00191 $request,
00192 $order
00193 );
00194 }
00195
00196 $invoice = $order->prepareInvoice();
00197 $invoice->register()->pay();
00198 $invoice->addComment(Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed payment capture. Invoice created automatically.'));
00199 $invoice->setTransactionId($request->getTransactionId());
00200
00201 $transactionSave = Mage::getModel('core/resource_transaction')
00202 ->addObject($invoice)
00203 ->addObject($invoice->getOrder())
00204 ->save();
00205
00206 $msg = $msg . Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed payment capture. Invoice %s was automatically created after confirmation.', $invoice->getIncrementId());
00207
00208 } else {
00209
00210 if ($invoice->getTransactionId() != $request->getTransactionId()) {
00211 $this->_error(
00212 Mage::helper('amazonpayments')->__('Amazon Simple Pay service capture confirmation error: existing transaction ID doesn\'t match transaction ID in the confirmation request.'),
00213 $request,
00214 $order
00215 );
00216 }
00217
00218 $invoiceAmount = Mage::app()->getStore()->roundPrice($invoice->getGrandTotal());
00219 $requestAmount = Mage::app()->getStore()->roundPrice($request->getAmount());
00220 if ($invoiceAmount != $requestAmount) {
00221 $this->_error(
00222 Mage::helper('amazonpayments')->__('Amazon Simple Pay service capture confirmation error: amount in the existing invoice doensn\'t match the amount in confirmation request.'),
00223 $request,
00224 $order
00225 );
00226 }
00227
00228 switch ($invoice->getState())
00229 {
00230 case Mage_Sales_Model_Order_Invoice::STATE_OPEN:
00231 $invoice->addComment(Mage::helper('amazonpayments')->__('Amazon Simple Pay service capture confirmation. Invoice was captured automatically.'));
00232 $invoice->setState(Mage_Sales_Model_Order_Invoice::STATE_PAID)->save();
00233 $msg = $msg . Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed capture for invoice %s. Invoice automatically captured.', $invoice->getIncrementId());
00234 break;
00235
00236 case Mage_Sales_Model_Order_Invoice::STATE_PAID:
00237 $invoice->addComment(Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed capture'));
00238 $msg = $msg . Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed capture for invoice %s', $invoice->getIncrementId());
00239 break;
00240 }
00241
00242 }
00243
00244 $order->getPayment()->getLastTransId($request->getTransactionId());
00245 $order->addStatusToHistory($order->getStatus(), $msg);
00246 $order->setState(
00247 Mage_Sales_Model_Order::STATE_PROCESSING,
00248 true,
00249 Mage::helper('amazonpayments')->__('Payment was authorized and captured successfully'),
00250 $notified = true
00251 );
00252
00253 return true;
00254 }
00255
00256
00257
00258
00259 protected function _processPaymentFailed($request, $order)
00260 {
00261 if ($order->getState() != Mage_Sales_Model_Order::STATE_NEW &&
00262 $order->getState() != Mage_Sales_Model_Order::STATE_PENDING_PAYMENT) {
00263 $this->_errorViolationSequenceStates($request, $order);
00264 }
00265
00266 $order->setState(
00267 Mage_Sales_Model_Order::STATE_CANCELED,
00268 true,
00269 Mage::helper('amazonpayments')->__('Amazon Simple Pay service payment confirmation failed'),
00270 $notified = false
00271 );
00272
00273 return true;
00274 }
00275
00276
00277
00278
00279 protected function _processRefundSuccessful($request, $order)
00280 {
00281 if ($order->getState() != Mage_Sales_Model_Order::STATE_PROCESSING &&
00282 $order->getState() != Mage_Sales_Model_Order::STATE_CLOSED &&
00283 $order->getState() != Mage_Sales_Model_Order::STATE_COMPLETE) {
00284 $this->_errorViolationSequenceStates($request, $order);
00285 }
00286
00287 $msg = '';
00288
00289 if (!$creditmemo = $this->_getOrderCreditmemo($order)) {
00290
00291 $orderAmount = Mage::app()->getStore()->roundPrice($order->getBaseGrandTotal());
00292 $requestAmount = Mage::app()->getStore()->roundPrice($request->getAmount());
00293 if ($orderAmount != $requestAmount || $order->getBaseTotalRefunded() > 0) {
00294 $this->_error(
00295 Mage::helper('amazonpayments')->__('Amazon Simple Pay service refund confirmation error: confirmation request amount doesn\'t match the order amount.'),
00296 $request,
00297 $order
00298 );
00299 }
00300
00301 if ($creditmemo = $this->_initCreditmemo($order)) {
00302 $creditmemo->setTransactionId($request->getTransactionId());
00303 $creditmemo->addComment(Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed payment refund. Creditmemo %s was automatically created after confirmation.', $creditmemo->getIncrementId()));
00304 $creditmemo->register();
00305
00306 $transactionSave = Mage::getModel('core/resource_transaction')
00307 ->addObject($creditmemo)
00308 ->addObject($creditmemo->getOrder());
00309 if ($creditmemo->getInvoice()) {
00310 $transactionSave->addObject($creditmemo->getInvoice());
00311 }
00312 $transactionSave->save();
00313
00314 $msg = $msg . Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed payment refund. Credit memo created automatically.', $creditmemo->getIncrementId());
00315 }
00316
00317 } else {
00318
00319 if ($creditmemo->getTransactionId() != $request->getTransactionId()) {
00320 $this->_error(
00321 Mage::helper('amazonpayments')->__('Amazon Simple Pay service refund confirmation error: transaction ID in the existing creditmemo doesn\'t match the transaction ID in the confirmation request.'),
00322 $request,
00323 $order
00324 );
00325 }
00326
00327 $creditmemoAmount = Mage::app()->getStore()->roundPrice($creditmemo->getBaseGrandTotal());
00328 $requestAmount = Mage::app()->getStore()->roundPrice($request->getAmount());
00329 if ($creditmemoAmount != $requestAmount) {
00330 $this->_error(
00331 Mage::helper('amazonpayments')->__('Amazon Simple Pay service refund confirmation error: amount in the existing creditmemo doensn\'t match the amount in confirmation request.'),
00332 $request,
00333 $order
00334 );
00335 }
00336
00337 switch ($creditmemo->getState())
00338 {
00339 case Mage_Sales_Model_Order_Creditmemo::STATE_OPEN:
00340 $creditmemo->addComment(Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed refund. Creditmemo processed automatically.'));
00341 $creditmemo->setState(Mage_Sales_Model_Order_Creditmemo::STATE_REFUNDED)->save();
00342 $msg = $msg . Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed refunded creditmemo %s. Creditmemo processed automatically.', $creditmemo->getIncrementId());
00343 break;
00344
00345 case Mage_Sales_Model_Order_Creditmemo::STATE_REFUNDED:
00346 $creditmemo->addComment(Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed refund.'));
00347 $msg = $msg . Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmed refund for creditmemo %s.', $creditmemo->getIncrementId());
00348 break;
00349 }
00350
00351 }
00352
00353 $order->addStatusToHistory($order->getStatus(), $msg);
00354
00355 return true;
00356 }
00357
00358
00359
00360
00361 protected function _processRefundFailed($request, $order)
00362 {
00363 $order->setState(
00364 $order->getState(),
00365 true,
00366 Mage::helper('amazonpayments')->__('Amazon Simple Pay service payment confirmation failed'),
00367 $notified = false
00368 );
00369
00370 return true;
00371 }
00372
00373
00374
00375
00376 protected function _processSystemError($request, $order)
00377 {
00378 $order->setState(
00379 Mage_Sales_Model_Order::STATE_CANCELED,
00380 true,
00381 Mage::helper('amazonpayments')->__('Amazon Simple Pay service is not available. Payment was not processed.'),
00382 $notified = false
00383 );
00384
00385 return true;
00386 }
00387
00388
00389
00390
00391
00392
00393
00394 protected function _getRequestOrder($request)
00395 {
00396 $order = Mage::getModel('sales/order');
00397 $order->loadByIncrementId($request->getReferenceId());
00398
00399 if ($order->isEmpty()) {
00400 $this->_error(
00401 Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmation error: order specified in the IPN request can not be found'),
00402 $request
00403 );
00404 }
00405
00406 if ($order->getPayment()->getMethodInstance()->getCode() != $this->getPayment()->getCode()) {
00407 $this->_error(
00408 Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmation error: payment method in the order is not Amazon Simple Pay'),
00409 $request
00410 );
00411 }
00412
00413 if ($order->getBaseCurrency()->getCurrencyCode() != $request->getCurrencyCode()) {
00414 $this->_error(
00415 Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmation error: order currency does not match the currency of the IPN request'),
00416 $request
00417 );
00418 }
00419
00420 return $order;
00421 }
00422
00423
00424
00425
00426
00427
00428
00429 protected function _getOrderInvoice($order)
00430 {
00431 foreach ($order->getInvoiceCollection() as $orderInvoice) {
00432 if ($orderInvoice->getState() == Mage_Sales_Model_Order_Invoice::STATE_PAID ||
00433 $orderInvoice->getState() == Mage_Sales_Model_Order_Invoice::STATE_OPEN) {
00434 return $orderInvoice;
00435 }
00436 }
00437
00438 return false;
00439 }
00440
00441
00442
00443
00444
00445
00446
00447 protected function _initCreditMemo($order)
00448 {
00449 $invoice = $this->_getOrderInvoice($order);
00450
00451 if (!$invoice) {
00452 return false;
00453 }
00454
00455 $convertor = Mage::getModel('sales/convert_order');
00456 $creditmemo = $convertor->toCreditmemo($order)->setInvoice($invoice);
00457
00458 foreach ($invoice->getAllItems() as $invoiceItem) {
00459 $orderItem = $invoiceItem->getOrderItem();
00460 $item = $convertor->itemToCreditmemoItem($orderItem);
00461 $item->setQty($orderItem->getQtyToRefund());
00462 $creditmemo->addItem($item);
00463 }
00464
00465 $creditmemo->setShippingAmount($invoice->getShippingAmount());
00466 $creditmemo->collectTotals();
00467 Mage::register('current_creditmemo', $creditmemo);
00468
00469 return $creditmemo;
00470 }
00471
00472
00473
00474
00475
00476
00477
00478 protected function _getOrderCreditmemo($order)
00479 {
00480 foreach ($order->getCreditmemosCollection() as $orderCreditmemo) {
00481 if ($orderCreditmemo->getState() == Mage_Sales_Model_Order_Creditmemo::STATE_REFUNDED ||
00482 $orderCreditmemo->getState() == Mage_Sales_Model_Order_Creditmemo::STATE_OPEN) {
00483 return $orderCreditmemo;
00484 }
00485 }
00486
00487 return false;
00488 }
00489
00490
00491
00492
00493
00494
00495
00496 protected function _errorViolationSequenceStates($request, $order)
00497 {
00498 $this->_error(
00499 Mage::helper('amazonpayments')->__('Amazon Simple Pay service confirmation error: order states sequence violation'),
00500 $request,
00501 $order
00502 );
00503 }
00504
00505
00506
00507
00508
00509
00510
00511
00512 protected function _error($comment, $request, $order = null)
00513 {
00514 $message = $comment . Mage::helper('amazonpayments')->__('<br/>Trace confirmation request:<br/>%s', $request->toString());
00515
00516 if (!is_null($order)) {
00517 $order->addStatusToHistory(
00518 $order->getStatus(),
00519 $message
00520 )->save();
00521 }
00522
00523 Mage::throwException($comment);
00524 }
00525 }