/** * IPN_Handler * * This trigger is invoked whenever a new notification needs to be processed, * and will call the IPN API * * */ private function ipn () { // ERP mode turns off all automated authorization and capture functionality // as well as IPN reception and / or polling, and disables any admin UI functionality that may trigger //If the authorization is done by ERP then the IPN URL set in amazon should not be this one. // we keep it anyway, for testing purposes if ($this->isERPModeEnabled() and $this->isAuthorizationDoneByErp()) { return; } // Fetch all HTTP request headers $headers = getallheaders(); $body = file_get_contents('php://input'); $this->debugLog($headers, 'AMAZON IPN HEADERS debug', 'debug'); $this->debugLog($body, 'AMAZON IPN BODY debug', 'debug'); $this->loadAmazonClass('OffAmazonPaymentsNotifications_Client'); $this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); try { $client = new OffAmazonPaymentsNotifications_Client(); $notification = $client->parseRawMessage($headers, $body); } catch (OffAmazonPaymentsNotifications_InvalidMessageException $e) { $this->debugLog($e->getMessage() . __FUNCTION__ . ' $body', 'error'); header("HTTP/1.1 503 Service Unavailable"); exit(0); } $notificationType = $notification->getNotificationType(); $this->debugLog($notificationType, 'ipn', 'debug'); if (!$this->isValidNotificationtype($notificationType)) { $this->debugLog($notificationType, 'ipn NOT isValidNotificationtype', 'error'); return; } $notificationClass = 'amazonHelper' . $notificationType; $notificationFile = JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'helpers' . DS . strtolower($notificationType . '.php'); if (!file_exists($notificationFile)) { $this->debugLog("Unknown notification Type: " . $notificationType, __FUNCTION__, 'error'); return false; } if (!class_exists($notificationClass)) { require(JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'helpers' . DS . 'helper.php'); require($notificationFile); } $this->debugLog($notificationType, 'ipn', 'debug'); $notificationResponse = new $notificationClass($notification, $this->_currentMethod); $this->debugLog("<pre>" . var_export($notificationResponse->amazonData, true) . "</pre>", __FUNCTION__, 'debug'); if (!($order_number = $notificationResponse->getReferenceId())) { $this->debugLog('no ReferenceId IPN received', $notificationClass, 'error'); return true; } if (!($virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($order_number))) { $this->debugLog('Received a ' . $notificationClass . ' with order number ' . $order_number . ' but no order in DB with that number', $notificationClass, 'error'); return true; } $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($virtuemart_order_id); if (!($payments = $this->getDatasByOrderId($virtuemart_order_id))) { // we ignore it because we receive also notification when refund/capture is done in the Amazon BE, and there is no valid reference //$this->debugLog('Received a ' . $newClass . ' with order number ' . $order_number . 'but no order in DB with that number in AMAZON payment table', $newClass, 'error'); return true; } $amazonState = $notificationResponse->onNotificationUpdateOrderHistory($order, $payments); $this->storeAmazonInternalData($order, NULL, NULL, $notification, NULL, $notificationResponse->getStoreInternalData()); $nextOperation = $notificationResponse->onNotificationNextOperation($order, $payments, $amazonState); if ($nextOperation === false) { return; } if (!function_exists($nextOperation)) { //$this->debugLog('Trying to call ' . $nextOperation . ' but the function does not exists: Programming error', $notificationClass, 'error'); } $this->$nextOperation($payments, $order); }
* This file is invoked whenever a new notification needs to be processed, * and will call the IPN API * * Note that if the IPN Client throws an exception, the IPH_Handler routine is * expected to throw a HTTP error response to signal that there has been an issue * with the message * * This class logs information to an error logs, * and places the last received notification * into the session context as a way to pass to other pages * */ $headers = getallheaders(); $body = file_get_contents('php://input'); try { $client = new OffAmazonPaymentsNotifications_Client(); $result = $client->parseRawMessage($headers, $body); } catch (OffAmazonPaymentsNotifications_InvalidMessageException $ex) { error_log($ex->getMessage()); header("HTTP/1.1 503 Service Unavailable"); exit(0); } try { logNotification($result); } catch (Exception $ex) { error_log($ex->getMessage()); } /** * Return the identifier for this notification * * @param OffAmazonPaymentsNotifications_Notification $notification to extract
/** * IPN_Handler * * This trigger is invoked whenever a new notification needs to be processed, * and will call the IPN API * * */ private function ipn() { // ERP mode turns off all automated authorization and capture functionality // as well as IPN reception and / or polling, and disables any admin UI functionality that may trigger //If the authorization is done by ERP then the IPN URL set in amazon should not be this one. // we keep it anyway, for testing purposes if ($this->isERPModeEnabled() and $this->isAuthorizationDoneByErp()) { return; } // Fetch all HTTP request headers $headers = $this->getallheaders(); $body = file_get_contents('php://input'); $this->debugLog($headers, 'AMAZON IPN HEADERS debug', 'debug'); $this->debugLog($body, 'AMAZON IPN BODY debug', 'debug'); /* $fp = fopen("/Applications/MAMP/htdocs/VM2/VM2024/AMAZON-ipnhandler.php", 'a+'); fwrite($fp, var_export($headers, true)); fwrite($fp, var_export($body, true)); fclose($fp); $headers=array ( 'x-amz-sns-message-type' => 'Notification', 'x-amz-sns-message-id' => '2c9311b0-7bb2-58e9-9fcb-5cfdf71809aa', 'x-amz-sns-topic-arn' => 'arn:aws:sns:eu-west-1:291180941288:A3M3RRFO9XDT2GAA3KB5JD2CWIH', 'x-amz-sns-subscription-arn' => 'arn:aws:sns:eu-west-1:291180941288:A3M3RRFO9XDT2GAA3KB5JD2CWIH:cf4843ce-a0e5-4f7f-892e-c013c91c4402', 'Content-Length' => '2701', 'Content-Type' => 'text/plain; charset=UTF-8', 'Host' => 'joomla-virtuemart.org', 'Connection' => 'Keep-Alive', 'User-Agent' => 'Amazon Simple Notification Service Agent', 'Cookie' => '53369989722c841763ad3ab697b54ad2=ba355be2a8b664b26fe73fff94c42d58', 'Cookie2' => '$Version=1', 'Accept-Encoding' => 'gzip,deflate', ); $body='{ "Type" : "Notification", "MessageId" : "2c9311b0-7bb2-58e9-9fcb-5cfdf71809aa", "TopicArn" : "arn:aws:sns:eu-west-1:291180941288:A3M3RRFO9XDT2GAA3KB5JD2CWIH", "Message" : "{\\"NotificationReferenceId\\":\\"f7d81c82-4cfa-4cdf-b9f2-1c0a41189698\\",\\"MarketplaceID\\":\\"136291\\",\\"NotificationType\\":\\"PaymentAuthorize\\",\\"SellerId\\":\\"AA3KB5JD2CWIH\\",\\"ReleaseEnvironment\\":\\"Sandbox\\",\\"Version\\":\\"2013-01-01\\",\\"NotificationData\\":\\"<?xml version=\\\\\\"1.0\\\\\\" encoding=\\\\\\"UTF-8\\\\\\"?><AuthorizationNotification xmlns=\\\\\\"https://mws.amazonservices.com/ipn/OffAmazonPayments/2013-01-01\\\\\\">\\\\n <AuthorizationDetails>\\\\n <AmazonAuthorizationId>S02-5813777-8476477-A004132<\\\\/AmazonAuthorizationId>\\\\n <AuthorizationReferenceId>9a0f027<\\\\/AuthorizationReferenceId>\\\\n <AuthorizationAmount>\\\\n <Amount>445.74<\\\\/Amount>\\\\n <CurrencyCode>GBP<\\\\/CurrencyCode>\\\\n <\\\\/AuthorizationAmount>\\\\n <CapturedAmount>\\\\n <Amount>445.74<\\\\/Amount>\\\\n <CurrencyCode>GBP<\\\\/CurrencyCode>\\\\n <\\\\/CapturedAmount>\\\\n <AuthorizationFee>\\\\n <Amount>0.0<\\\\/Amount>\\\\n <CurrencyCode>GBP<\\\\/CurrencyCode>\\\\n <\\\\/AuthorizationFee>\\\\n <IdList>\\\\n <Id>S02-5813777-8476477-C004132<\\\\/Id>\\\\n <\\\\/IdList>\\\\n <CreationTimestamp>2015-02-05T15:16:38.719Z<\\\\/CreationTimestamp>\\\\n <ExpirationTimestamp>2015-03-07T15:16:38.719Z<\\\\/ExpirationTimestamp>\\\\n <AuthorizationStatus>\\\\n <State>Closed<\\\\/State>\\\\n <LastUpdateTimestamp>2015-02-05T15:21:13.685Z<\\\\/LastUpdateTimestamp>\\\\n <ReasonCode>MaxCapturesProcessed<\\\\/ReasonCode>\\\\n <\\\\/AuthorizationStatus>\\\\n <OrderItemCategories/>\\\\n <CaptureNow>false<\\\\/CaptureNow>\\\\n <SoftDescriptor/>\\\\n <\\\\/AuthorizationDetails>\\\\n<\\\\/AuthorizationNotification>\\",\\"Timestamp\\":\\"2015-02-05T03:21:14Z\\"}", "Timestamp" : "2015-02-05T15:21:14.625Z", "SignatureVersion" : "1", "Signature" : "r1L77iTDBFZelBurw3K1jR9zmXqknxtPv/e7zVWu85GiHn+pB3T4pbZVkoeOnwiNDsdkviNSwqWWVyrVsQM/6lilUbWMo8lFrkIgyRrwWObTLxAOpIgPtjIqGjVzrThSIlmJrcmrrIjr4FrCfqflqsmxoxFbVUJKzs3n9IQjTGUS18vBmH/Zc/VgqFjpm1VbyKSJUyPoYQwXBNSim+A5IaP8sKJ/qlOfuAOuV/EjPN1CBrSTiuFz5IGybEHYkzdebtuIi9s4zO/z2YQYHchgkSoaM5zmgwL50yYT7Hy7kmIriok3OCb5k9wWLVwA1iUDBDaTDI8lRlS8JglsZ1D3Yg==", "SigningCertURL" : "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-d6d679a1d18e95c2f9ffcf11f4f9e198.pem", "UnsubscribeURL" : "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:291180941288:A3M3RRFO9XDT2GAA3KB5JD2CWIH:cf4843ce-a0e5-4f7f-892e-c013c91c4402" }'; */ $this->loadAmazonClass('OffAmazonPaymentsNotifications_Client'); $this->loadVmClass('VirtueMartModelOrders', JPATH_VM_ADMINISTRATOR . DS . 'models' . DS . 'orders.php'); try { $client = new OffAmazonPaymentsNotifications_Client(); $notification = $client->parseRawMessage($headers, $body); } catch (OffAmazonPaymentsNotifications_InvalidMessageException $e) { $this->debugLog($e->getMessage() . __FUNCTION__ . ' $body', 'error'); header("HTTP/1.1 503 Service Unavailable"); exit(0); } $notificationType = $notification->getNotificationType(); $this->debugLog($notificationType, 'ipn', 'debug'); if (!$this->isValidNotificationtype($notificationType)) { $this->debugLog($notificationType, 'ipn NOT isValidNotificationtype', 'error'); return; } $notificationClass = 'amazonHelper' . $notificationType; $notificationFile = JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'helpers' . DS . strtolower($notificationType . '.php'); if (!file_exists($notificationFile)) { $this->debugLog("Unknown notification Type: " . $notificationType, __FUNCTION__, 'error'); return false; } if (!class_exists($notificationClass)) { require JPATH_SITE . DS . 'plugins' . DS . 'vmpayment' . DS . 'amazon' . DS . 'helpers' . DS . 'helper.php'; require $notificationFile; } $this->debugLog($notificationType, 'ipn', 'debug'); $notificationResponse = new $notificationClass($notification, $this->_currentMethod); $this->debugLog("<pre>" . var_export($notificationResponse->amazonData, true) . "</pre>", __FUNCTION__, 'debug'); if (!($order_number = $notificationResponse->getReferenceId())) { /* // it is not really an error, orderReferenceNotification do not send a ReferenceId if ($amazonReferenceId=$notificationResponse->getAmazonReferenceId()) { $payments=$this->getDatasByAmazonReferenceId($amazonReferenceId); if (!$payments) { $this->debugLog('no ReferenceId IPN received', $notificationClass, 'error'); } $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($payments[0]->virtuemart_order_id); $this->storeAmazonInternalData($order, NULL, NULL, $notification, NULL, $notificationResponse->getStoreInternalData()); } */ $this->debugLog('no ReferenceId IPN received', $notificationClass, 'error'); return true; } if (!($virtuemart_order_id = VirtueMartModelOrders::getOrderIdByOrderNumber($order_number))) { $this->debugLog('Received a ' . $notificationClass . ' with order number ' . $order_number . ' but no order in DB with that number', $notificationClass, 'error'); return true; } $orderModel = VmModel::getModel('orders'); $order = $orderModel->getOrder($virtuemart_order_id); if (!($payments = $this->getDatasByOrderId($virtuemart_order_id))) { // we ignore it because we receive also notification when refund/capture is done in the Amazon BE, and there is no valid reference //$this->debugLog('Received a ' . $newClass . ' with order number ' . $order_number . 'but no order in DB with that number in AMAZON payment table', $newClass, 'error'); return true; } $amazonState = $notificationResponse->onNotificationUpdateOrderHistory($order, $payments); $this->storeAmazonInternalData($order, NULL, NULL, $notification, NULL, $notificationResponse->getStoreInternalData()); $nextOperation = $notificationResponse->onNotificationNextOperation($order, $payments, $amazonState); if ($nextOperation === false) { return; } if (!function_exists($nextOperation)) { //$this->debugLog('Trying to call ' . $nextOperation . ' but the function does not exists: Programming error', $notificationClass, 'error'); } $this->{$nextOperation}($payments, $order); }