$xmlResponse, 'dir' => 'in');
if (empty($xmlResponse)) {
$this->getApi()->debugData($debugData);
return false;
}
list($root, $data) = $this->getGResponse()->GetParsedXML($xmlResponse);
$this->getGResponse()->SetMerchantAuthentication($this->getMerchantId(), $this->getMerchantKey());
$status = $this->getGResponse()->HttpAuthentication();
if (!$status || empty($data[$root])) {
exit;
}
$this->setRootName($root)->setRoot($data[$root]);
$serialNumber = $this->getData('root/serial-number');
$this->getGResponse()->setSerialNumber($serialNumber);
/*
* Prevent multiple notification processing
*/
$notification = Mage::getModel('googlecheckout/notification')
->setSerialNumber($serialNumber)
->loadNotificationData();
if ($notification->getStartedAt()) {
if ($notification->isProcessed()) {
$this->getGResponse()->SendAck();
return;
}
if ($notification->isTimeout()) {
$notification->updateProcess();
} else {
$this->getGResponse()->SendServerErrorStatus();
return;
}
} else {
$notification->startProcess();
}
$method = '_response' . uc_words($root, '', '-');
if (method_exists($this, $method)) {
ob_start();
try {
$this->$method();
$notification->stopProcess();
} catch (Exception $e) {
$this->getGResponse()->log->logError($e->__toString());
}
$debugData['result'] = ob_get_flush();
$this->getApi()->debugData($debugData);
} else {
$this->getGResponse()->SendBadRequestStatus("Invalid or not supported Message");
}
return $this;
}
/**
* Load quote from request and make sure the proper payment method is set
*
* @return Mage_Sales_Model_Quote
*/
protected function _loadQuote()
{
$quoteId = $this->getData('root/shopping-cart/merchant-private-data/quote-id/VALUE');
$storeId = $this->getData('root/shopping-cart/merchant-private-data/store-id/VALUE');
$quote = Mage::getModel('sales/quote')
->setStoreId($storeId)
->load($quoteId);
if ($quote->isVirtual()) {
$quote->getBillingAddress()->setPaymentMethod('googlecheckout');
} else {
$quote->getShippingAddress()->setPaymentMethod('googlecheckout');
}
return $quote;
}
protected function _getApiUrl()
{
return null;
}
protected function getGoogleOrderNumber()
{
return $this->getData('root/google-order-number/VALUE');
}
protected function _responseRequestReceived()
{
}
protected function _responseError()
{
}
protected function _responseDiagnosis()
{
}
protected function _responseCheckoutRedirect()
{
}
/**
* Calculate available shipping amounts and taxes
*/
protected function _responseMerchantCalculationCallback()
{
$merchantCalculations = new GoogleMerchantCalculations($this->getCurrency());
$quote = $this->_loadQuote();
$billingAddress = $quote->getBillingAddress();
$address = $quote->getShippingAddress();
$googleAddress = $this->getData('root/calculate/addresses/anonymous-address');
$googleAddresses = array();
if ( isset( $googleAddress['id'] ) ) {
$googleAddresses[] = $googleAddress;
} else {
$googleAddresses = $googleAddress;
}
$methods = Mage::getStoreConfig('google/checkout_shipping_merchant/allowed_methods', $this->getStoreId());
$methods = unserialize($methods);
$limitCarrier = array();
foreach ($methods['method'] as $method) {
if ($method) {
list($carrierCode, $methodCode) = explode('/', $method);
$limitCarrier[$carrierCode] = $carrierCode;
}
}
$limitCarrier = array_values($limitCarrier);
foreach($googleAddresses as $googleAddress) {
$addressId = $googleAddress['id'];
$regionCode = $googleAddress['region']['VALUE'];
$countryCode = $googleAddress['country-code']['VALUE'];
$regionModel = Mage::getModel('directory/region')->loadByCode($regionCode, $countryCode);
$regionId = $regionModel->getId();
$address->setCountryId($countryCode)
->setRegion($regionCode)
->setRegionId($regionId)
->setCity($googleAddress['city']['VALUE'])
->setPostcode($googleAddress['postal-code']['VALUE'])
->setLimitCarrier($limitCarrier);
$billingAddress->setCountryId($countryCode)
->setRegion($regionCode)
->setRegionId($regionId)
->setCity($googleAddress['city']['VALUE'])
->setPostcode($googleAddress['postal-code']['VALUE'])
->setLimitCarrier($limitCarrier);
$billingAddress->collectTotals();
$shippingTaxClass = $this->_getTaxClassForShipping($quote);
$gRequestMethods = $this->getData('root/calculate/shipping/method');
if ($gRequestMethods) {
// Make stable format of $gRequestMethods for convenient usage
if (array_key_exists('VALUE', $gRequestMethods)) {
$gRequestMethods = array($gRequestMethods);
}
// Form list of mapping Google method names to applicable address rates
$rates = array();
$address->setCollectShippingRates(true)
->collectShippingRates();
foreach ($address->getAllShippingRates() as $rate) {
if ($rate instanceof Mage_Shipping_Model_Rate_Result_Error) {
continue;
}
$methodName = sprintf('%s - %s', $rate->getCarrierTitle(), $rate->getMethodTitle());
$rates[$methodName] = $rate;
}
foreach ($gRequestMethods as $method) {
$result = new GoogleResult($addressId);
$methodName = $method['name'];
if (isset($rates[$methodName])) {
$rate = $rates[$methodName];
$address->setShippingMethod($rate->getCode())
->setLimitCarrier($rate->getCarrier())
->setCollectShippingRates(true)
->collectTotals();
$shippingRate = $address->getBaseShippingAmount() - $address->getBaseShippingDiscountAmount();
$result->SetShippingDetails($methodName, $shippingRate, 'true');
if ($this->getData('root/calculate/tax/VALUE') == 'true') {
$taxAmount = $address->getBaseTaxAmount();
$taxAmount += $billingAddress->getBaseTaxAmount();
$result->setTaxDetails($taxAmount);
}
} else {
if ($shippingTaxClass &&
$this->getData('root/calculate/tax/VALUE') == 'true') {
$i = 1;
$price = Mage::getStoreConfig(
'google/checkout_shipping_flatrate/price_'.$i,
$quote->getStoreId()
);
$price = number_format($price, 2, '.','');
$price = (float) Mage::helper('tax')->getShippingPrice($price, false, false);
$address->setShippingMethod(null);
$address->setCollectShippingRates(true)->collectTotals();
$billingAddress->setCollectShippingRates(true)->collectTotals();
$address->setBaseShippingAmount($price);
$address->setShippingAmount(
$this->_reCalculateToStoreCurrency($price, $quote)
);
$this->_applyShippingTaxClass($address, $shippingTaxClass);
$taxAmount = $address->getBaseTaxAmount();
$taxAmount += $billingAddress->getBaseTaxAmount();
$result->SetShippingDetails(
$methodName,
$price - $address->getBaseShippingDiscountAmount(),
'true'
);
$result->setTaxDetails($taxAmount);
$i++;
} else {
$result->SetShippingDetails($methodName, 0, 'false');
}
}
$merchantCalculations->AddResult($result);
}
} else if ($this->getData('root/calculate/tax/VALUE') == 'true') {
$address->setShippingMethod(null);
$address->setCollectShippingRates(true)->collectTotals();
$billingAddress->setCollectShippingRates(true)->collectTotals();
if (!Mage::helper('googlecheckout')->isShippingCarrierActive($this->getStoreId())) {
$this->_applyShippingTaxClass($address, $shippingTaxClass);
}
$taxAmount = $address->getBaseTaxAmount();
$taxAmount += $billingAddress->getBaseTaxAmount();
$result = new GoogleResult($addressId);
$result->setTaxDetails($taxAmount);
$merchantCalculations->addResult($result);
}
}
$this->getGResponse()->ProcessMerchantCalculations($merchantCalculations);
}
/**
* Apply shipping tax class
*
* @param Varien_Object $qAddress
* @param mixed $shippingTaxClass
*/
protected function _applyShippingTaxClass($qAddress, $shippingTaxClass)
{
if (!$shippingTaxClass) {
return;
}
$quote = $qAddress->getQuote();
$taxCalculationModel = Mage::getSingleton('tax/calculation');
$request = $taxCalculationModel->getRateRequest($qAddress);
$rate = $taxCalculationModel->getRate($request->setProductClassId($shippingTaxClass));
if (!Mage::helper('tax')->shippingPriceIncludesTax()) {
$shippingTax = $qAddress->getShippingAmount() * $rate/100;
$shippingBaseTax= $qAddress->getBaseShippingAmount() * $rate/100;
} else {
$shippingTax = $qAddress->getShippingTaxAmount();
$shippingBaseTax= $qAddress->getBaseShippingTaxAmount();
}
$shippingTax = $quote->getStore()->roundPrice($shippingTax);
$shippingBaseTax= $quote->getStore()->roundPrice($shippingBaseTax);
$qAddress->setTaxAmount($qAddress->getTaxAmount() + $shippingTax);
$qAddress->setBaseTaxAmount($qAddress->getBaseTaxAmount() + $shippingBaseTax);
}
/**
* Process new order creation notification from google.
* Convert customer quote to order
*/
protected function _responseNewOrderNotification()
{
$this->getGResponse()->SendAck();
// LOOK FOR EXISTING ORDER TO AVOID DUPLICATES
$orders = Mage::getModel('sales/order')->getCollection()
->addAttributeToFilter('ext_order_id', $this->getGoogleOrderNumber());
if (count($orders)) {
return;
}
// IMPORT GOOGLE ORDER DATA INTO QUOTE
/* @var $quote Mage_Sales_Model_Quote */
$quote = $this->_loadQuote();
$quote->setIsActive(true)->reserveOrderId();
Mage::dispatchEvent('googlecheckout_create_order_before', array('quote' => $quote));
if ($quote->getErrorMessage()) {
$this->getGRequest()->SendCancelOrder($this->getGoogleOrderNumber(),
$this->__('Order creation error'),
$quote->getErrorMessage()
);
return;
}
$storeId = $quote->getStoreId();
Mage::app()->setCurrentStore(Mage::app()->getStore($storeId));
if ($quote->getQuoteCurrencyCode() != $quote->getBaseCurrencyCode()) {
Mage::app()->getStore()->setCurrentCurrencyCode($quote->getQuoteCurrencyCode());
}
$billing = $this->_importGoogleAddress($this->getData('root/buyer-billing-address'));
$quote->setBillingAddress($billing);
$shipping = $this->_importGoogleAddress($this->getData('root/buyer-shipping-address'));
$quote->setShippingAddress($shipping);
$this->_importGoogleTotals($quote->getShippingAddress());
$quote->getPayment()->importData(array('method'=>'googlecheckout'));
$taxMessage = $this->_applyCustomTax($quote->getShippingAddress());
// CONVERT QUOTE TO ORDER
$convertQuote = Mage::getSingleton('sales/convert_quote');
/* @var $order Mage_Sales_Model_Order */
$order = $convertQuote->toOrder($quote);
if ($quote->isVirtual()) {
$convertQuote->addressToOrder($quote->getBillingAddress(), $order);
} else {
$convertQuote->addressToOrder($quote->getShippingAddress(), $order);
}
$order->setExtOrderId($this->getGoogleOrderNumber());
$order->setExtCustomerId($this->getData('root/buyer-id/VALUE'));
if (!$order->getCustomerEmail()) {
$order->setCustomerEmail($billing->getEmail())
->setCustomerPrefix($billing->getPrefix())
->setCustomerFirstname($billing->getFirstname())
->setCustomerMiddlename($billing->getMiddlename())
->setCustomerLastname($billing->getLastname())
->setCustomerSuffix($billing->getSuffix());
}
$order->setBillingAddress($convertQuote->addressToOrderAddress($quote->getBillingAddress()));
if (!$quote->isVirtual()) {
$order->setShippingAddress($convertQuote->addressToOrderAddress($quote->getShippingAddress()));
}
#$order->setPayment($convertQuote->paymentToOrderPayment($quote->getPayment()));
foreach ($quote->getAllItems() as $item) {
$orderItem = $convertQuote->itemToOrderItem($item);
if ($item->getParentItem()) {
$orderItem->setParentItem($order->getItemByQuoteItemId($item->getParentItem()->getId()));
}
$order->addItem($orderItem);
}
/*
* Adding transaction for correct transaction information displaying on order view at back end.
* It has no influence on api interaction logic.
*/
$payment = Mage::getModel('sales/order_payment')
->setMethod('googlecheckout')
->setTransactionId($this->getGoogleOrderNumber())
->setIsTransactionClosed(false);
$order->setPayment($payment);
$payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH);
$order->setCanShipPartiallyItem(false);
$emailAllowed = ($this->getData('root/buyer-marketing-preferences/email-allowed/VALUE') === 'true');
$emailStr = $emailAllowed ? $this->__('Yes') : $this->__('No');
$message = $this->__('Google Order Number: %s', '' . $this->getGoogleOrderNumber() . '
')
. $this->__('Google Buyer ID: %s', '' . $this->getData('root/buyer-id/VALUE') . '
')
. $this->__('Is Buyer Willing to Receive Marketing Emails: %s', '' . $emailStr . '');
if ($taxMessage) {
$message .= $this->__('
Warning: %s
', $taxMessage);
}
$order->addStatusToHistory($order->getStatus(), $message);
$order->place();
$order->save();
$order->sendNewOrderEmail();
Mage::dispatchEvent('googlecheckout_save_order_after', array('order' => $order));
$quote->setIsActive(false)->save();
if ($emailAllowed) {
$customer = $quote->getCustomer();
if ($customer && $customer->getId()) {
$customer->setIsSubscribed(true);
Mage::getModel('newsletter/subscriber')->subscribeCustomer($customer);
} else {
Mage::getModel('newsletter/subscriber')->subscribe($order->getCustomerEmail());
}
}
Mage::dispatchEvent('checkout_submit_all_after', array('order' => $order, 'quote' => $quote));
$this->getGRequest()->SendMerchantOrderNumber($order->getExtOrderId(), $order->getIncrementId());
}
/**
* If tax value differs tax which is setted on magento,
* apply Google tax and recollect quote
*
* @param Varien_Object $qAddress
* @return string | false
*/
protected function _applyCustomTax($qAddress)
{
$quote = $qAddress->getQuote();
$qTaxAmount = $qAddress->getBaseTaxAmount();
$newTaxAmount = $this->getData('root/order-adjustment/total-tax/VALUE');
if ($qTaxAmount != $newTaxAmount) {
$taxQuotient = (int) $qTaxAmount ? $newTaxAmount/$qTaxAmount : $newTaxAmount;
$qAddress->setTaxAmount(
$this->_reCalculateToStoreCurrency($newTaxAmount, $quote)
);
$qAddress->setBaseTaxAmount($newTaxAmount);
$grandTotal = $qAddress->getBaseGrandTotal() - $qTaxAmount + $newTaxAmount;
$qAddress->setGrandTotal(
$this->_reCalculateToStoreCurrency($grandTotal, $quote)
);
$qAddress->setBaseGrandTotal($grandTotal);
$subtotalInclTax = $qAddress->getSubtotalInclTax() - $qTaxAmount + $newTaxAmount;
$qAddress->setSubtotalInclTax($subtotalInclTax);
foreach ($quote->getAllVisibleItems() as $item) {
if ($item->getParentItem()) {
continue;
}
if ($item->getTaxAmount()) {
$item->setTaxAmount($item->getTaxAmount()*$taxQuotient);
$item->setBaseTaxAmount($item->getBaseTaxAmount()*$taxQuotient);
$taxPercent = round(($item->getTaxAmount()/$item->getRowTotal())*100);
$item->setTaxPercent($taxPercent);
}
}
$grandTotal = $quote->getBaseGrandTotal() - $qTaxAmount + $newTaxAmount;
$quote->setGrandTotal(
$this->_reCalculateToStoreCurrency($grandTotal, $quote)
);
$quote->setBaseGrandTotal($grandTotal);
$message = $this->__('The tax amount has been applied based on the information received from Google Checkout, because tax amount received from Google Checkout is different from the calculated tax amount');
return $message;
}
return false;
}
/**
* Import address data from google request to address object
*
* @param array | Varien_Object $gAddress
* @param Varien_Object $qAddress
* @return Varien_Object
*/
protected function _importGoogleAddress($gAddress, Varien_Object $qAddress=null)
{
if (is_array($gAddress)) {
$gAddress = new Varien_Object($gAddress);
}
if (!$qAddress) {
$qAddress = Mage::getModel('sales/quote_address');
}
$nameArr = $gAddress->getData('structured-name');
if ($nameArr) {
$qAddress->setFirstname($nameArr['first-name']['VALUE'])
->setLastname($nameArr['last-name']['VALUE']);
} else {
$nameArr = explode(' ', $gAddress->getData('contact-name/VALUE'), 2);
$qAddress->setFirstname($nameArr[0]);
if (!empty($nameArr[1])) {
$qAddress->setLastname($nameArr[1]);
}
}
$region = Mage::getModel('directory/region')->loadByCode(
$gAddress->getData('region/VALUE'),
$gAddress->getData('country-code/VALUE')
);
$qAddress->setCompany($gAddress->getData('company-name/VALUE'))
->setEmail($gAddress->getData('email/VALUE'))
->setStreet(trim($gAddress->getData('address1/VALUE') . "\n" . $gAddress->getData('address2/VALUE')))
->setCity($gAddress->getData('city/VALUE'))
->setRegion($gAddress->getData('region/VALUE'))
->setRegionId($region->getId())
->setPostcode($gAddress->getData('postal-code/VALUE'))
->setCountryId($gAddress->getData('country-code/VALUE'))
->setTelephone($gAddress->getData('phone/VALUE'))
->setFax($gAddress->getData('fax/VALUE'));
return $qAddress;
}
/**
* Returns array of possible shipping methods combinations
* Includes internal GoogleCheckout shipping methods, that can be created
* after successful Google Checkout
*
* @return array
*/
protected function _getShippingInfos($storeId = null)
{
$cacheKey = ($storeId === null) ? 'nofilter' : $storeId;
if (!isset($this->_cachedShippingInfo[$cacheKey])) {
/* @var $shipping Mage_Shipping_Model_Shipping */
$shipping = Mage::getModel('shipping/shipping');
$carriers = Mage::getStoreConfig('carriers', $storeId);
$infos = array();
foreach (array_keys($carriers) as $carrierCode) {
$carrier = $shipping->getCarrierByCode($carrierCode);
if (!$carrier) {
continue;
}
if ($carrierCode == 'googlecheckout') {
// Add info about internal google checkout methods
$methods = array_merge($carrier->getAllowedMethods(), $carrier->getInternallyAllowedMethods());
$carrierName = 'Google Checkout';
} else {
$methods = $carrier->getAllowedMethods();
$carrierName = Mage::getStoreConfig('carriers/' . $carrierCode . '/title', $storeId);
}
foreach ($methods as $methodCode => $methodName) {
$code = $carrierCode . '_' . $methodCode;
$name = sprintf('%s - %s', $carrierName, $methodName);
$infos[$code] = array(
'code' => $code,
'name' => $name, // Internal name for google checkout api - to distinguish it in google requests
'carrier' => $carrierCode,
'carrier_title' => $carrierName,
'method' => $methodCode,
'method_title' => $methodName
);
}
}
$this->_cachedShippingInfo[$cacheKey] = $infos;
}
return $this->_cachedShippingInfo[$cacheKey];
}
/**
* Return shipping method code by shipping method name received from Google
*
* @param string $name
* @param int|string|Mage_Core_Model_Store $storeId
* @return string|false
*/
protected function _getShippingMethodByName($name, $storeId = null)
{
$code = false;
$infos = $this->_getShippingInfos($storeId);
foreach ($infos as $info) {
if ($info['name'] == $name) {
$code = $info['code'];
break;
}
}
return $code;
}
/**
* Creates rate by method code
* Sets shipping rate's accurate description, titles and so on,
* so it will get in order description properly
*
* @param string $code
* @return Mage_Sales_Model_Quote_Address_Rate
*/
protected function _createShippingRate($code, $storeId = null)
{
$rate = Mage::getModel('sales/quote_address_rate')
->setCode($code);
$infos = $this->_getShippingInfos($storeId);
if (isset($infos[$code])) {
$info = $infos[$code];
$rate->setCarrier($info['carrier'])
->setCarrierTitle($info['carrier_title'])
->setMethod($info['method'])
->setMethodTitle($info['method_title']);
}
return $rate;
}
/**
* Import totals information from google request to quote address
*
* @param Varien_Object $qAddress
*/
protected function _importGoogleTotals($qAddress)
{
$quote = $qAddress->getQuote();
$qAddress->setTaxAmount(
$this->_reCalculateToStoreCurrency($this->getData('root/order-adjustment/total-tax/VALUE'), $quote)
);
$qAddress->setBaseTaxAmount($this->getData('root/order-adjustment/total-tax/VALUE'));
$method = null;
$prefix = 'root/order-adjustment/shipping/';
if (null !== ($shipping = $this->getData($prefix . 'carrier-calculated-shipping-adjustment'))) {
$method = 'googlecheckout_carrier';
} else if (null !== ($shipping = $this->getData($prefix . 'merchant-calculated-shipping-adjustment'))) {
$method = 'googlecheckout_merchant';
} else if (null !== ($shipping = $this->getData($prefix . 'flat-rate-shipping-adjustment'))) {
$method = 'googlecheckout_flatrate';
} else if (null !== ($shipping = $this->getData($prefix . 'pickup-shipping-adjustment'))) {
$method = 'googlecheckout_pickup';
}
if ($method) {
Mage::getSingleton('tax/config')->setShippingPriceIncludeTax(false);
$rate = $this->_createShippingRate($method)
->setMethodTitle($shipping['shipping-name']['VALUE'])
->setPrice($shipping['shipping-cost']['VALUE']);
$qAddress->addShippingRate($rate)
->setShippingMethod($method)
->setShippingDescription($shipping['shipping-name']['VALUE']);
// We get from Google price with discounts applied via merchant calculations
$qAddress->setShippingAmountForDiscount(0);
/*if (!Mage::helper('tax')->shippingPriceIncludesTax($quote->getStore())) {
$includingTax = Mage::helper('tax')->getShippingPrice(
$excludingTax, true, $qAddress, $quote->getCustomerTaxClassId()
);
$shippingTax = $includingTax - $excludingTax;
$qAddress->setShippingTaxAmount($this->_reCalculateToStoreCurrency($shippingTax, $quote))
->setBaseShippingTaxAmount($shippingTax)
->setShippingInclTax($includingTax)
->setBaseShippingInclTax($this->_reCalculateToStoreCurrency($includingTax, $quote));
} else {
if ($method == 'googlecheckout_carrier') {
$qAddress->setShippingTaxAmount(0)
->setBaseShippingTaxAmount(0);
}
}*/
} else {
$qAddress->setShippingMethod(null);
}
$qAddress->setGrandTotal(
$this->_reCalculateToStoreCurrency($this->getData('root/order-total/VALUE'), $quote)
);
$qAddress->setBaseGrandTotal($this->getData('root/order-total/VALUE'));
}
/**
* Order getter
*
* @return Mage_Sales_Model_Order
*/
public function getOrder()
{
if (!$this->hasData('order')) {
$order = Mage::getModel('sales/order')
->loadByAttribute('ext_order_id', $this->getGoogleOrderNumber());
if (!$order->getId()) {
Mage::throwException('Invalid Order: ' . $this->getGoogleOrderNumber());
}
$this->setData('order', $order);
}
return $this->getData('order');
}
protected function _responseRiskInformationNotification()
{
$this->getGResponse()->SendAck();
$order = $this->getOrder();
$payment = $order->getPayment();
$order
->setRemoteIp($this->getData('root/risk-information/ip-address/VALUE'));
$payment
->setCcLast4($this->getData('root/risk-information/partial-cc-number/VALUE'))
->setCcAvsStatus($this->getData('root/risk-information/avs-response/VALUE'))
->setCcCidStatus($this->getData('root/risk-information/cvn-response/VALUE'));
$msg = $this->__('Google Risk Information:');
$msg .= '
' . $this->__('IP Address: %s', '' . $order->getRemoteIp() . '');
$msg .= '
' . $this->__('CC Partial: xxxx-%s', '' . $payment->getCcLast4() . '');
$msg .= '
' . $this->__('AVS Status: %s', '' . $payment->getCcAvsStatus() . '');
$msg .= '
' . $this->__('CID Status: %s', '' . $payment->getCcCidStatus() . '');
$msg .= '
' . $this->__('Eligible for Protection: %s', '' . ($this->getData('root/risk-information/eligible-for-protection/VALUE')=='true' ? 'Yes' : 'No') . '');
$msg .= '
' . $this->__('Buyer Account Age: %s days', '' . $this->getData('root/risk-information/buyer-account-age/VALUE') . '');
$order->addStatusToHistory($order->getStatus(), $msg);
$order->save();
}
/**
* Process authorization notification
*/
protected function _responseAuthorizationAmountNotification()
{
$this->getGResponse()->SendAck();
$order = $this->getOrder();
$payment = $order->getPayment();
$payment->setAmountAuthorized($this->getData('root/authorization-amount/VALUE'));
$expDate = $this->getData('root/authorization-expiration-date/VALUE');
$expDate = new Zend_Date($expDate);
$msg = $this->__('Google Authorization:');
$msg .= '
' . $this->__('Amount: %s', '' . $this->_formatAmount($payment->getAmountAuthorized()) . '');
$msg .= '
' . $this->__('Expiration: %s', '' . $expDate->toString() . '');
$order->addStatusToHistory($order->getStatus(), $msg);
$order->setPaymentAuthorizationAmount($payment->getAmountAuthorized());
$timestamp = Mage::getModel('core/date')->gmtTimestamp(
$this->getData('root/authorization-expiration-date/VALUE')
);
$order->setPaymentAuthorizationExpiration(
$timestamp ? $timestamp : Mage::getModel('core/date')->gmtTimestamp()
);
$order->save();
}
/**
* Process charge notification
*
*/
protected function _responseChargeAmountNotification()
{
$this->getGResponse()->SendAck();
$order = $this->getOrder();
$payment = $order->getPayment();
$latestCharged = $this->getData('root/latest-charge-amount/VALUE');
$totalCharged = $this->getData('root/total-charge-amount/VALUE');
$payment->setAmountCharged($totalCharged);
$order->setIsInProcess(true);
$msg = $this->__('Google Charge:');
$msg .= '
' . $this->__('Latest Charge: %s', '' . $this->_formatAmount($latestCharged) . '');
$msg .= '
' . $this->__('Total Charged: %s', '' . $this->_formatAmount($totalCharged) . '');
if (!$order->hasInvoices() && abs($order->getBaseGrandTotal() - $latestCharged) < .0001) {
$invoice = $this->_createInvoice();
$msg .= '
' . $this->__('Invoice Auto-Created: %s', '' . $invoice->getIncrementId() . '');
}
$this->_addChildTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
$open = Mage_Sales_Model_Order_Invoice::STATE_OPEN;
foreach ($order->getInvoiceCollection() as $orderInvoice) {
if ($orderInvoice->getState() == $open && $orderInvoice->getBaseGrandTotal() == $latestCharged) {
$orderInvoice->setState(Mage_Sales_Model_Order_Invoice::STATE_PAID)
->setTransactionId($this->getGoogleOrderNumber())
->save();
break;
}
}
$order->addStatusToHistory($order->getStatus(), $msg);
$order->save();
}
protected function _createInvoice()
{
$order = $this->getOrder();
$invoice = $order->prepareInvoice()
->setTransactionId($this->getGoogleOrderNumber())
->addComment(Mage::helper('googlecheckout')->__('Auto-generated from GoogleCheckout Charge'))
->register()
->pay();
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($invoice)
->addObject($invoice->getOrder());
$transactionSave->save();
return $invoice;
}
protected function _createShipment()
{
$order = $this->getOrder();
$shipment = $order->prepareShipment();
if ($shipment) {
$shipment->register();
$order->setIsInProcess(true);
$transactionSave = Mage::getModel('core/resource_transaction')
->addObject($shipment)
->addObject($shipment->getOrder())
->save();
}
return $shipment;
}
/**
* Process chargeback notification
*/
protected function _responseChargebackAmountNotification()
{
$this->getGResponse()->SendAck();
$latestChargeback = $this->getData('root/latest-chargeback-amount/VALUE');
$totalChargeback = $this->getData('root/total-chargeback-amount/VALUE');
$order = $this->getOrder();
if ($order->getBaseGrandTotal() == $totalChargeback) {
$creditmemo = Mage::getModel('sales/service_order', $order)
->prepareCreditmemo()
->setPaymentRefundDisallowed(true)
->setAutomaticallyCreated(true)
->register();
$creditmemo->addComment($this->__('Credit memo has been created automatically'));
$creditmemo->save();
}
$msg = $this->__('Google Chargeback:');
$msg .= '
' . $this->__('Latest Chargeback: %s', '' . $this->_formatAmount($latestChargeback) . '');
$msg .= '
' . $this->__('Total Chargeback: %s', '' . $this->_formatAmount($totalChargeback) . '');
$this->_addChildTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND,
Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
$order->addStatusToHistory($order->getStatus(), $msg);
$order->save();
}
/**
* Process refund notification
*/
protected function _responseRefundAmountNotification()
{
$this->getGResponse()->SendAck();
$latestRefunded = $this->getData('root/latest-refund-amount/VALUE');
$totalRefunded = $this->getData('root/total-refund-amount/VALUE');
$order = $this->getOrder();
$amountRefundLeft = $order->getBaseGrandTotal() - $order->getBaseTotalRefunded()
- $order->getBaseAdjustmentNegative();
if (abs($amountRefundLeft) < .0001) {
return;
}
if ($amountRefundLeft < $latestRefunded) {
$latestRefunded = $amountRefundLeft;
$totalRefunded = $order->getBaseGrandTotal();
}
if ($order->getBaseTotalRefunded() > 0) {
$adjustment = array('adjustment_positive' => $latestRefunded);
} else {
$adjustment = array('adjustment_negative' => $order->getBaseGrandTotal() - $latestRefunded);
}
$creditmemo = Mage::getModel('sales/service_order', $order)
->prepareCreditmemo($adjustment)
->setPaymentRefundDisallowed(true)
->setAutomaticallyCreated(true)
->register()
->addComment($this->__('Credit memo has been created automatically'))
->save();
$msg = $this->__('Google Refund:');
$msg .= '
' . $this->__('Latest Refund: %s', '' . $this->_formatAmount($latestRefunded) . '');
$msg .= '
' . $this->__('Total Refunded: %s', '' . $this->_formatAmount($totalRefunded) . '');
$this->_addChildTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_REFUND,
Mage_Sales_Model_Order_Payment_Transaction::TYPE_CAPTURE);
$order->addStatusToHistory($order->getStatus(), $msg);
$order->save();
}
protected function _responseOrderStateChangeNotification()
{
$this->getGResponse()->SendAck();
$prevFinancial = $this->getData('root/previous-financial-order-state/VALUE');
$newFinancial = $this->getData('root/new-financial-order-state/VALUE');
$prevFulfillment = $this->getData('root/previous-fulfillment-order-state/VALUE');
$newFulfillment = $this->getData('root/new-fulfillment-order-state/VALUE');
$msg = $this->__('Google Order Status Change:');
if ($prevFinancial!=$newFinancial) {
$msg .= "
" . $this->__('Financial: %s -> %s', '' . $prevFinancial . '', '' . $newFinancial . '');
}
if ($prevFulfillment!=$newFulfillment) {
$msg .= "
" . $this->__('Fulfillment: %s -> %s', '' . $prevFulfillment . '', '' . $newFulfillment . '');
}
$this->getOrder()
->addStatusToHistory($this->getOrder()->getStatus(), $msg)
->save();
$method = '_orderStateChangeFinancial' . uc_words(strtolower($newFinancial), '', '_');
if (method_exists($this, $method)) {
$this->$method();
}
$method = '_orderStateChangeFulfillment' . uc_words(strtolower($newFulfillment), '', '_');
if (method_exists($this, $method)) {
$this->$method();
}
}
/**
* Add transaction to payment with defined type
*
* @param string $typeTarget
* @param string $typeParent
* @return Mage_GoogleCheckout_Model_Api_Xml_Callback
*/
protected function _addChildTransaction(
$typeTarget,
$typeParent = Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH)
{
$payment = $this->getOrder()->getPayment();
$googleOrderId = $this->getGoogleOrderNumber();
$parentTransactionId = $googleOrderId;
if ($typeParent != Mage_Sales_Model_Order_Payment_Transaction::TYPE_AUTH) {
$parentTransactionId .= '-' . $typeParent;
} else {
$payment->setIsTransactionClosed(false);
}
$parentTransaction = $payment->getTransaction($parentTransactionId);
if ($parentTransaction) {
$payment->setParentTransactionId($parentTransactionId)
->setTransactionId($googleOrderId . '-' . $typeTarget)
->addTransaction($typeTarget);
if ($this->getOrder()->getTotalDue() < .0001) {
$parentTransaction->setIsClosed(true)
->save();
}
}
return $this;
}
protected function _orderStateChangeFinancialReviewing()
{
}
protected function _orderStateChangeFinancialChargeable()
{
#$this->getGRequest()->SendProcessOrder($this->getGoogleOrderNumber());
#$this->getGRequest()->SendChargeOrder($this->getGoogleOrderNumber(), '');
}
protected function _orderStateChangeFinancialCharging()
{
}
protected function _orderStateChangeFinancialCharged()
{
}
protected function _orderStateChangeFinancialPaymentDeclined()
{
}
protected function _orderStateChangeFinancialCancelled()
{
$this->getOrder()->setBeingCanceledFromGoogleApi(true)->cancel()->save();
}
protected function _orderStateChangeFinancialCancelledByGoogle()
{
$this
->getOrder()
->setBeingCanceledFromGoogleApi(true)
->cancel()
->save();
$this
->getGRequest()
->SendBuyerMessage($this->getGoogleOrderNumber(), "Sorry, your order is cancelled by Google", true);
}
protected function _orderStateChangeFulfillmentNew()
{
}
protected function _orderStateChangeFulfillmentProcessing()
{
}
protected function _orderStateChangeFulfillmentDelivered()
{
$shipment = $this->_createShipment();
if (!is_null($shipment))
$shipment->save();
}
protected function _orderStateChangeFulfillmentWillNotDeliver()
{
}
/**
* Format amount to be displayed
*
* @param mixed $amount
* @return string
*/
protected function _formatAmount($amount)
{
// format currency in currency format, but don't enclose it into
return Mage::helper('core')->currency($amount, true, false);
}
}