/** * Process the PayPal IPN ping back. */ public function ProcessGatewayPing() { //make it only work for echeck pings if($_POST['payment_type'] != 'echeck' || $_POST['payment_status']== 'Pending') { exit; } if(!isset($_POST['custom'])) { exit; } $sessionToken = explode('_', $_REQUEST['custom'], 2); $this->SetOrderData(LoadPendingOrdersByToken($sessionToken[0])); $amount = number_format($this->GetGatewayAmount(), 2, '.', ''); if($amount == 0) { exit; } // Perform a post back to PayPal with exactly what we received in order to validate the request $queryString = array(); $queryString[] = "cmd=_notify-validate"; foreach($_POST as $k => $v) { $queryString[] = $k."=".urlencode($v); } $queryString = implode('&', $queryString); $testMode = $this->GetValue('testmode'); if($testMode == 'YES') { $verifyURL = 'http://www.sandbox.paypal.com/cgi-bin/webscr'; } else { $verifyURL = 'http://www.paypal.com/cgi-bin/webscr'; } $response = PostToRemoteFileAndGetResponse($verifyURL, $queryString); // This pingback was not valid if($response != "VERIFIED") { // Bad order details $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), GetLang('PayPalErrorInvalid'), "RESPONSE : " .$response); return false; } // If we're still here, the ping back was valid, so we check the payment status and everything else match up $paypalEmail = $this->GetValue('email'); if(!isset($_POST['receiver_email']) || !isset($_POST['mc_gross']) || !isset($_POST['payment_status'])) { // Bad order details $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), GetLang('PayPalErrorInvalid'), print_r($_POST, true)); return false; } // The values passed don't match what we expected if(($_POST['mc_gross'] != $amount && !in_array($_POST['payment_status'], array('Reversed', 'Refunded', 'Canceled_Reversed')))) { $errorMsg = sprintf(GetLang('PayPalErrorInvalidMsg'), $_POST['mc_gross'], $amount, $_POST['receiver_email'], $paypalEmail, $_POST['payment_status']); $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), GetLang('PayPalErrorInvalid'), $errorMsg); return false; } $currency = GetDefaultCurrency(); if($_POST['mc_currency'] != $currency['currencycode']) { $errorMsg = sprintf(GetLang('PayPalErrorInvalidMsg3'), $currency['currencycode'], $_POST['mc_currency']); $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), GetLang('PayPalErrorInvalid'), $errorMsg); return false; } // Has the transaction been processed before? If so, we can't process it again $transaction = GetClass('ISC_TRANSACTION'); $newTransaction = array( 'providerid' => $this->GetId(), 'transactiondate' => time(), 'transactionid' => $_POST['txn_id'], 'orderid' => array_keys($this->GetOrders()), 'message' => '', 'status' => '', 'amount' => $_POST['mc_gross'], 'extrainfo' => array() ); $orderPaymentStatus = ''; switch($_POST['payment_status']) { case "Completed": $orderPaymentStatus = 'captured'; $newTransaction['status'] = TRANS_STATUS_COMPLETED; $newOrderStatus = ORDER_STATUS_AWAITING_FULFILLMENT; break; case "Pending": if($_POST['payment_type'] != 'echeck') { $orderPaymentStatus = 'authorized'; } $newTransaction['status'] = TRANS_STATUS_PENDING; $newOrderStatus = ORDER_STATUS_AWAITING_PAYMENT; $newTransaction['extrainfo']['reason'] = $_POST['pending_reason']; break; case "Denied": $newTransaction['status'] = TRANS_STATUS_DECLINED; $newOrderStatus = ORDER_STATUS_DECLINED; break; case "Failed": $newTransaction['status'] = TRANS_STATUS_FAILED; $newOrderStatus = ORDER_STATUS_DECLINED; break; case "Refunded": $newTransaction['status'] = TRANS_STATUS_REFUND; $newOrderStatus = ORDER_STATUS_REFUNDED; break; case "Reversed": $newTransaction['status'] = TRANS_STATUS_CHARGEBACK; $newOrderStatus = ORDER_STATUS_REFUNDED; break; case "Canceled_Reversal": $newTransaction['status'] = TRANS_STATUS_CANCELLED_REVERSAL; $newOrderStatus = ORDER_STATUS_REFUNDED; break; } $previousTransaction = $transaction->LoadByTransactionId($_POST['txn_id'], $this->GetId()); // Already processed before, HALT and log error if(is_array($previousTransaction) && $previousTransaction['transactionid'] && $previousTransaction['status'] == $newTransaction['status']) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), sprintf(GetLang('PayPalTransactionAlreadyProcessed'), $_POST['txn_id'])); return false; } $newTransaction['message'] = $this->GetPayPalTransactionMessage($_POST); $transactionId = $transaction->Create($newTransaction); $oldOrderStatus = $this->GetOrderStatus(); // If the order was previously incomplete, we need to do some extra work if($oldOrderStatus == ORDER_STATUS_INCOMPLETE) { // If a customer doesn't return to the store from PayPal, their cart will never be // emptied. So what we do here, is if we can, load up the existing customers session // and empty the cart and kill the checkout process. When they next visit the store, // everything should be "hunky-dory." session_write_close(); $session = new ISC_SESSION($sessionToken[1]); EmptyCartAndKillCheckout(); } // Update the status for all orders that we've just received the payment for foreach($this->GetOrders() as $orderId => $order) { $status = $newOrderStatus; // If it's a digital order & awaiting fulfillment, automatically complete it if($order['ordisdigital'] && $status == ORDER_STATUS_AWAITING_FULFILLMENT) { $status = ORDER_STATUS_COMPLETED; } UpdateOrderStatus($orderId, $status); } $updatedOrder = array( 'ordpaymentstatus' => $orderPaymentStatus, ); $this->UpdateOrders($updatedOrder); // This was a successful order $oldStatus = GetOrderStatusById($oldOrderStatus); if(!$oldStatus) { $oldStatus = 'Incomplete'; } $newStatus = GetOrderStatusById($newOrderStatus); $extra = sprintf(GetLang('PayPalSuccessDetails'), implode(', ', array_keys($this->GetOrders())), $amount, '', $_POST['txn_id'], $_POST['payment_status'], $newStatus, $oldStatus); $successMsg = sprintf(GetLang('PayPalPaymentsProSuccess'), implode(', ', array_keys($this->GetOrders()))); $GLOBALS['ISC_CLASS_LOG']->LogSystemSuccess(array('payment', $this->GetName()), $successMsg, $extra); return true; }
/** * Completes a pending order and marks it's status as whatever it should be next. * This function will process any payments, capture amounts from gateways, increase * # sold for each product in the order, etc. * * @param string The pending order token. * @param int The status to set the completed order to. * @return boolean True if successful, false on failure. */ function CompletePendingOrder($pendingOrderToken, $status, $sendInvoice=true) { $orderData = LoadPendingOrdersByToken($pendingOrderToken, true); if($orderData === false) { return false; } $processedStoreCredit = false; $processedGiftCertificates = false; $orderStoreCredit = 0; $orderTotalAmount = 0; // Flag used to create the customer record but only if atleast one order was successful $createCustomer = false; // Sum up our total amount and store credit foreach ($orderData['orders'] as $order) { if ($order['ordstatus'] != 0) { continue; } $orderStoreCredit += $order['ordstorecreditamount']; $orderTotalAmount += $order['total_inc_tax']; } // flag to indicate if we should send notifications? only if the order was previously incomplete and the new status isn't declined/cancelled/refunded $sendNotifications = false; foreach($orderData['orders'] as $order) { $newStatus = $status; // Wait, was the order already complete? Then we don't do anything if($order['ordstatus'] != ORDER_STATUS_INCOMPLETE) { continue; } // If this order is digital, and the status is awaiting fulfillment, there's nothing // to actually fulfill, so set it to completed. if($order['ordisdigital'] && $newStatus == ORDER_STATUS_AWAITING_FULFILLMENT) { $newStatus = ORDER_STATUS_COMPLETED; } $extraInfo = @unserialize($order['extrainfo']); if(!is_array($extraInfo)) { $extraInfo = array(); } // only email and update order data (coupons, certificates, store credit etc) if it's not a declined, cancelled or refunded order if($newStatus != ORDER_STATUS_DECLINED && $newStatus != ORDER_STATUS_CANCELLED && $newStatus != ORDER_STATUS_REFUNDED) { $createCustomer = true; $sendNotifications = true; if($sendInvoice && !EmailInvoiceToCustomer($order['orderid'], $newStatus)) { $GLOBALS['HideError'] = ""; $GLOBALS['ErrorMessage'] = GetLang('ErroSendingInvoiceEmail'); $GLOBALS['HideSuccess'] = "none"; } // Are we updating the inventory levels when an order has been placed? if(GetConfig('UpdateInventoryLevels') == 1) { DecreaseInventoryFromOrder($order['orderid']); } // If this order now complete, we need to activate any gift certificates if(OrderIsComplete($newStatus)) { $GLOBALS['ISC_CLASS_GIFTCERTIFICATES'] = GetClass('ISC_GIFTCERTIFICATES'); $GLOBALS['ISC_CLASS_GIFTCERTIFICATES']->ActivateGiftCertificates($order['orderid']); } // If we've had one or more coupons been applied to this order, we now need to increment the number of uses $couponIds = array(); $query = " SELECT * FROM [|PREFIX|]order_coupons WHERE ordcouporderid='".(int)$order['orderid']."' "; $result = $GLOBALS['ISC_CLASS_DB']->Query($query); while($coupon = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) { $couponIds[] = $coupon['ordcouponid']; } if(!empty($couponIds)) { $couponsUsed = array_unique($couponIds); $couponList = implode(",", array_map("intval", $couponsUsed)); $query = " UPDATE [|PREFIX|]coupons SET couponnumuses=couponnumuses+1 WHERE couponid IN (".$couponList.") "; $GLOBALS['ISC_CLASS_DB']->Query($query); foreach ($couponIds as $cid) { getclass('ISC_COUPON')->updatePerCustomerUsage($cid); } } // If we used store credit on this order, we now need to subtract it from the users account. if($order['ordstorecreditamount'] > 0 && $processedStoreCredit == false) { $GLOBALS['ISC_CLASS_CUSTOMER'] = GetClass('ISC_CUSTOMER'); $currentCredit = $GLOBALS['ISC_CLASS_CUSTOMER']->GetCustomerStoreCredit($order['ordcustid']); $newCredit = $currentCredit - $orderStoreCredit; if($newCredit < 0) { $newCredit = 0; } $updatedCustomer = array( 'custstorecredit' => $newCredit, ); $GLOBALS['ISC_CLASS_DB']->UpdateQuery('customers', $updatedCustomer, "customerid='".(int)$order['ordcustid']."'"); $processedStoreCredit = true; } // If one or more gift certificates were used we need to apply them to this order and subtract the total if($order['ordgiftcertificateamount'] > 0 && isset($extraInfo['giftcertificates']) && !empty($extraInfo['giftcertificates']) && $processedGiftCertificates == false) { $usedCertificates = array(); $GLOBALS['ISC_CLASS_GIFT_CERTIFICATES'] = GetClass('ISC_GIFTCERTIFICATES'); $GLOBALS['ISC_CLASS_GIFT_CERTIFICATES']->ApplyGiftCertificatesToOrder($order['orderid'], $orderTotalAmount + $order['ordgiftcertificateamount'], $extraInfo['giftcertificates'], $usedCertificates); unset($extraInfo['giftcertificates']); $processedGiftCertificates = true; } // If there are one or more digital products in this order then we need to create a record in the order_downloads table // for each of them and set the expiry dates $query = " SELECT ordprodid, ordprodqty FROM [|PREFIX|]order_products WHERE orderorderid='".$order['orderid']."' AND ordprodtype='digital' "; $result = $GLOBALS['ISC_CLASS_DB']->Query($query); $digitalProductIds = array(); while($digitalProduct = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) { $digitalProductIds[$digitalProduct['ordprodid']] = $digitalProduct; } if(!empty($digitalProductIds)) { $query = " SELECT downloadid, productid, downexpiresafter, downmaxdownloads FROM [|PREFIX|]product_downloads WHERE productid IN (".implode(',', array_keys($digitalProductIds)).") "; $result = $GLOBALS['ISC_CLASS_DB']->Query($query); while($digitalDownload = $GLOBALS['ISC_CLASS_DB']->Fetch($result)) { $expiryDate = 0; // If this download has an expiry date, set it to now + expiry time if($digitalDownload['downexpiresafter'] > 0) { $expiryDate = time() + $digitalDownload['downexpiresafter']; } // If they've purchased more than one, we need to give them max downloads X quantity downloads $quantity = $digitalProductIds[$digitalDownload['productid']]['ordprodqty']; $newDownload = array( 'orderid' => $order['orderid'], 'downloadid' => $digitalDownload['downloadid'], 'numdownloads' => 0, 'downloadexpires' => $expiryDate, 'maxdownloads' => $digitalDownload['downmaxdownloads'] * $quantity ); $GLOBALS['ISC_CLASS_DB']->InsertQuery('order_downloads', $newDownload); } } } // Does a customer account need to be created? if(!empty($extraInfo['createAccount'])) { createOrderCustomerAccount($order, $extraInfo['createAccount']); unset($extraInfo['createAccount']); } // Now update the order and set the status $updatedOrder = array( "ordstatus" => $newStatus, "extrainfo" => serialize($extraInfo) ); $GLOBALS['ISC_CLASS_DB']->UpdateQuery("orders", $updatedOrder, "orderid='".$order['orderid']."'"); } if($sendNotifications) { // Trigger all active new order notification methods SendOrderNotifications($pendingOrderToken); // Do we need to add them to a Interspire Email Marketer mailing list? SubscribeCustomerToLists($pendingOrderToken); // Update the current uses of each rule $quote = getCustomerQuote(); $appliedRules = array_keys(getCustomerQuote()->getAppliedDiscountRules()); if(!empty($appliedRules)) { require_once ISC_BASE_PATH.'/lib/rule.php'; updateRuleUses($appliedRules); } } // Empty the users cart and kill the checkout process EmptyCartAndKillCheckout(); return true; }
public function ProcessGatewayPing() { /* orderID Your order reference amount Order amount (not multiplied by 100) currency Currency of the order PM Payment method ACCEPTANCE Acceptance code returned by acquirer STATUS Transaction status CARDNO Masked card number PAYID Payment reference in our system NCERROR Error code BRAND Card brand (our system derives it from the card number) or similar information for other payment methods. SHASIGN SHA signature composed by our system, if SHA-out configured by you. */ if(!isset($_REQUEST['OrderToken'])) { exit; } if (!isset($_REQUEST['orderID']) || !isset($_REQUEST['amount']) || !isset($_REQUEST['currency']) || !isset($_REQUEST['STATUS'])) { // Bad order details $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), GetLang('OgoneErrorInvalid'), print_r($_POST, true)); return false; } // ogone response data $orderId = $_REQUEST['orderID']; $amount = $_REQUEST['amount']; $currency = $_REQUEST['currency']; $status = $_REQUEST['STATUS']; $transactionId = $_REQUEST['PAYID']; $errorCode = $_REQUEST['NCERROR']; $orderToken = $_REQUEST['OrderToken']; $sessionToken = $_REQUEST['SessionToken']; $this->SetOrderData(LoadPendingOrdersByToken($orderToken)); // expected values $combinedOrderId = $this->GetCombinedOrderId(); $gateway_amount = number_format($this->GetGatewayAmount(), 2, '.', ''); $defaultcurrency = GetDefaultCurrency(); // verify the SHA Sign $shaParamsToCheck = array( 'AAVADDRESS', 'AAVCHECK', 'AAVZIP', 'ACCEPTANCE', 'ALIAS', 'AMOUNT', 'BRAND', 'CARDNO', 'CCCTY', 'CN', 'COMPLUS', 'CURRENCY', 'CVCCHECK', 'DCC_COMMPERCENTAGE', 'DCC_CONVAMOUNT', 'DCC_CONVCCY', 'DCC_EXCHRATE', 'DCC_EXCHRATESOURCE', 'DCC_EXCHRATETS', 'DCC_INDICATOR', 'DCC_MARGINPERCENTAGE', 'DCC_VALIDHOUS', 'DIGESTCARDNO', 'ECI', 'ED', 'ENCCARDNO', 'IP', 'IPCTY', 'NBREMAILUSAGE', 'NBRIPUSAGE', 'NBRIPUSAGE_ALLTX', 'NBRUSAGE', 'NCERROR', 'ORDERID', 'PAYID', 'PM', 'SCO_CATEGORY', 'SCORING', 'STATUS', 'SUBSCRIPTION_ID', 'TRXDATE', 'VC', ); $checkRequest = array_change_key_case($_REQUEST, CASE_UPPER); $signature = $this->GetValue("signature_out"); $stringToHash = ''; foreach ($shaParamsToCheck as $param) { if (!isset($checkRequest[$param]) || $checkRequest[$param] == '') { continue; } $stringToHash .= $param . '=' . $checkRequest[$param] . $signature; } $sha = strtoupper(sha1($stringToHash)); if ($sha != $_REQUEST['SHASIGN']) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), GetLang('OgoneErrorInvalid', array('orderId' => $orderId)), print_r($_POST, true)); return false; } // The values passed don't match what we expected if($orderId != $combinedOrderId || $amount != $gateway_amount || $currency != $defaultcurrency['currencycode']) { $errorMsg = GetLang('OgoneErrorDetailsNoMatch', array( "total" => $amount, "expectedTotal" => $gateway_amount, "orderId" => $orderId, "expectedOrderId" => $combinedOrderId, "currency" => $currency, "expectedCurrency" => $defaultcurrency['currencycode'], "status" => $status )); $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), GetLang('OgoneErrorInvalid', array('orderId' => $orderId)), $errorMsg); return false; } $paymentStatus = ''; $statusLang = $status; switch($status) { case '0': // incomplete case '1': // cancelled by customer $newOrderStatus = ORDER_STATUS_INCOMPLETE; break; case '2': // auth refused $newOrderStatus = ORDER_STATUS_DECLINED; break; case '5': // authorized $newOrderStatus = ORDER_STATUS_AWAITING_PAYMENT; break; case '51': // awaiting authorization case '52': // authorization unknown $newOrderStatus = ORDER_STATUS_PENDING; break; case '6': // authorized and cancelled $newOrderStatus = ORDER_STATUS_INCOMPLETE; break; case '7': // payment deleted case '74': // payment deleted $newOrderStatus = ORDER_STATUS_AWAITING_PAYMENT; break; case '8': // refund $newOrderStatus = ORDER_STATUS_REFUNDED; break; case '9': // payment authorized and captured $newOrderStatus = ORDER_STATUS_AWAITING_FULFILLMENT; break; case '91': // awaiting payment case '93': // payment refused (tech problem or expired auth) $newOrderStatus = ORDER_STATUS_AWAITING_PAYMENT; break; case '92': // unknown payment $newOrderStatus = ORDER_STATUS_PENDING; break; case '94': // payment declined by aquirer $newOrderStatus = ORDER_STATUS_DECLINED; break; default : $newOrderStatus = ORDER_STATUS_DECLINED; $statusLang = 'Unknown'; break; } // if the order is currently incomplete and the new status isn't incomplete (ie. transaction cancelled by customer), then empty the cart if($this->GetOrderStatus() == ORDER_STATUS_INCOMPLETE && $newOrderStatus != ORDER_STATUS_INCOMPLETE) { session_write_close(); $session = new ISC_SESSION($sessionToken); EmptyCartAndKillCheckout(); } // update orders with the transaction id $updatedOrder = array( 'ordpayproviderid' => $transactionId ); // if captured then update pay status in order if ($newOrderStatus == ORDER_STATUS_AWAITING_FULFILLMENT) { $updatedOrder['ordpaymentstatus'] = 'captured'; } $this->UpdateOrders($updatedOrder); // we only want to notify the customer of a successfull order $emailCustomer = false; if ($newOrderStatus != ORDER_STATUS_INCOMPLETE) { $emailCustomer = true; } // update order statuses foreach($this->GetOrders() as $orderId => $order) { // digital orders should complete right away if captured if($order['ordisdigital'] && $newOrderStatus == ORDER_STATUS_AWAITING_FULFILLMENT) { $newOrderStatus = ORDER_STATUS_COMPLETED; } UpdateOrderStatus($orderId, $newOrderStatus, $emailCustomer); } // Log this payment response $oldStatus = GetOrderStatusById($order['ordstatus']); if(!$oldStatus) { $oldStatus = 'Incomplete'; } $newStatus = GetOrderStatusById($newOrderStatus); if (!$newStatus) { $newStatus = 'Incomplete'; } $extra = GetLang('OgoneSuccessDetails', array( "orderId" => implode(', ', array_keys($this->GetOrders())), "amount" => $gateway_amount, "paymentId" => $transactionId, "paymentStatus" => $status, "paymentDesc" => GetLang('OgoneTransactionStatus' . $statusLang), "newStatus" => $newStatus, "oldStatus" => $oldStatus )); $GLOBALS['ISC_CLASS_LOG']->LogSystemSuccess(array('payment', $this->_name), GetLang('OgoneSuccess', array('orderId' => $orderId)), $extra); return true; }
/** * Create a new order in ISC based on a new-order-notification from google * * @return void **/ private function CreateOrder() { if(!$this->LoadCart($this->module->cartid)) { // Todo: What is the correct way to fail here? return; } // Ensure split shipping is disabled $this->quote->setIsSplitShipping(false); // Set the billing address for the order $billingAddress = $this->GetAddressFromResponse($this->response->data[$this->response->root]['buyer-billing-address']); $this->quote->getBillingAddress() ->setAddressByArray($billingAddress); if(!$this->quote->isDigital()) { // Set the shipping address for the order $shippingAddress = $this->GetAddressFromResponse($this->response->data[$this->response->root]['buyer-shipping-address']); $this->quote->getShippingAddress() ->setAddressByArray($shippingAddress); // Attempt to find shipping costs in the response from Google if (isset($this->response->data[$this->response->root]['order-adjustment']['shipping']['merchant-calculated-shipping-adjustment'])) { $shipping = $this->response->data[$this->response->root]['order-adjustment']['shipping']['merchant-calculated-shipping-adjustment']; } else { $shipping = array ( 'shipping-cost' => array ( 'VALUE' => 0 ), 'shipping-name' => array ( 'VALUE' => '' ), ); } $this->quote->getShippingAddress() ->setShippingMethod( $shipping['shipping-cost']['VALUE'], $shipping['shipping-name']['VALUE'], $this->getShippingProviderModuleByName($shipping['shipping-name']['VALUE']) ); } $this->handleNewOrderNotificationCouponAdjustment(); $this->handleNewOrderNotificationGiftCertificateAdjustment(); $selectedCurrency = getCurrencyById($GLOBALS['CurrentCurrency']); $newOrder = array( 'orderpaymentmodule' => 'checkout_googlecheckout', 'ordcurrencyid' => $selectedCurrency['currencyid'], 'ordcurrencyexchangerate' => $selectedCurrency['currencyexchangerate'], 'ordipaddress' => '', 'extraInfo' => array(), 'quote' => $this->quote, ); $entity = new ISC_ENTITY_ORDER(); $orderId = $entity->add($newOrder); // Failed to create the order if(!$orderId) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError($this->logtype, sprintf(GetLang('GoogleCheckoutMissingCart'), isc_html_escape($this->module->cartid))); return; } $order = getOrder($orderId); $googleid = $this->response->data['new-order-notification']['google-order-number']['VALUE']; $this->SendGoogleNewOrderId($googleid, $order['orderid']); $updatedOrder = array( 'ordpayproviderid' => $googleid, ); $orderIds = array($order['orderid']); // Update the orders in the database $GLOBALS['ISC_CLASS_DB']->UpdateQuery('orders', $updatedOrder, "orderid IN (".implode(',', $orderIds).")"); $completed = CompletePendingOrder($order['ordtoken'], ORDER_STATUS_PENDING, false); if ($this->response->data['new-order-notification']['buyer-marketing-preferences']['email-allowed']['VALUE'] == 'true') { $this->SubscribeCustomerToLists($order['orderid']); } if (!$completed) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError($this->logtype, sprintf(GetLang('GoogleCheckoutCantCompleteOrder'), isc_html_escape($pendingToken), isc_html_escape(var_export($completed, true)))); return; } EmptyCartAndKillCheckout(); $GLOBALS['ISC_CLASS_LOG']->LogSystemSuccess($this->logtype, sprintf(GetLang('GoogleCheckoutOrderCreated'), (int) $order['orderid'], isc_html_escape($googleid))); }
public function ProcessGatewayPing() { $pName = $_REQUEST['payer_name']; $pEmail = $_REQUEST['payer_email']; $qta = $_REQUEST['qta']; $thxId = $_REQUEST['thx_id']; $sessionToken = explode('_', $_REQUEST['custom'], 2); $payerId = $_REQUEST['payer_id']; $amount = $_REQUEST['amount']; $this->SetOrderData(LoadPendingOrdersByToken($sessionToken[0])); if($this->GetGatewayAmount() == 0) { exit; } if ($amount != $this->GetGatewayAmount()) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), sprintf(GetLang($this->_languagePrefix.'AmountMismatch'), $this->GetGatewayAmount(), $amount)); return false; } if (isset($_REQUEST['payer_email'])) { $updatedOrder = array( 'ordpayproviderid' => $pEmail, 'ordpaymentstatus' => 'captured', ); $this->UpdateOrders($updatedOrder); } $GLOBALS['ISC_CLASS_LOG']->LogSystemSuccess(array('payment', $this->GetName()), GetLang($this->_languagePrefix.'Success')); // If the order was previously incomplete, we need to do some extra work if($this->GetOrderStatus() == ORDER_STATUS_INCOMPLETE) { // If a customer doesn't return to the store from PayPal, their cart will never be // emptied. So what we do here, is if we can, load up the existing customers session // and empty the cart and kill the checkout process. When they next visit the store, // everything should be "hunky-dory." session_write_close(); $session = new ISC_SESSION($sessionToken[1]); EmptyCartAndKillCheckout(); } // Update the status for all orders that we've just received the payment for foreach($this->GetOrders() as $orderId => $order) { $status = ORDER_STATUS_AWAITING_FULFILLMENT; // If it's a digital order & awaiting fulfillment, automatically complete it if($order['ordisdigital'] && ORDER_STATUS_AWAITING_FULFILLMENT) { $status = ORDER_STATUS_COMPLETED; } UpdateOrderStatus($orderId, $status); } return true; }
/** * Process the NAB pingback */ public function ProcessGatewayPing() { if(!isset($_REQUEST['payment_reference']) || !isset($_REQUEST['bank_reference']) || !isset($_REQUEST['orderToken']) || !isset($_REQUEST['signature'])) { exit; } $paymentReference = $_REQUEST['payment_reference']; $paymentAmount = number_format($_REQUEST['payment_amount'], 2, '.', ''); $orderToken = $_REQUEST['orderToken']; $sessionToken = $_REQUEST['sessionToken']; $requestSignature = $_REQUEST['signature']; $transactionId = $_REQUEST['payment_number']; $bankReference = $_REQUEST['bank_reference']; $this->SetOrderData(LoadPendingOrdersByToken($orderToken)); $orders = $this->GetOrders(); list(,$order) = each($orders); $orderId = $order['orderid']; // GetGatewayAmount returns the amount from the order record, so $amount is that but formatted into #.## $amount = number_format($this->GetGatewayAmount(), 2, '.', ''); // verify that the signature matches $verifySignature = md5($amount . $orderToken . $orderId . GetConfig('EncryptionToken')); if ($verifySignature != $requestSignature) { $errorMsg = GetLang('NabSignatureMismatchDetails', array('orderId' => $orderId, 'transactionId' => $transactionId)); $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), GetLang('NabSignatureMismatch'), $errorMsg); return false; } /** @var ISC_TRANSACTION */ $transaction = GetClass('ISC_TRANSACTION'); $previousTransaction = $transaction->LoadByTransactionId($transactionId, $this->GetId()); if(is_array($previousTransaction) && $previousTransaction['transactionid']) { $GLOBALS['ISC_CLASS_LOG']->LogSystemError(array('payment', $this->GetName()), sprintf(GetLang('NabTransactionAlreadyProcessed'), $_REQUEST['payment_date'])); return false; } // Need to finish the processing of the pingback $newTransaction = array( 'providerid' => $this->GetId(), 'transactiondate' => $_REQUEST['payment_date'], 'transactionid' => $transactionId, 'orderid' => $orderId, 'message' => 'Completed', 'status' => '', 'amount' => $_REQUEST['payment_amount'], 'extrainfo' => array() ); $newTransaction['status'] = TRANS_STATUS_COMPLETED; $newOrderStatus = ORDER_STATUS_AWAITING_FULFILLMENT; $transaction->Create($newTransaction); // If the order was previously incomplete, empty the customers cart if($this->GetOrderStatus() == ORDER_STATUS_INCOMPLETE) { session_write_close(); $session = new ISC_SESSION($sessionToken); EmptyCartAndKillCheckout(); } $status = $newOrderStatus; // If it's a digital order & awaiting fulfillment, automatically complete it if($order['ordisdigital'] && $status == ORDER_STATUS_AWAITING_FULFILLMENT) { $status = ORDER_STATUS_COMPLETED; } UpdateOrderStatus($orderId, $status); $updatedOrder = array( 'ordpayproviderid' => $_REQUEST['payment_number'], 'ordpaymentstatus' => 'captured', ); $this->UpdateOrders($updatedOrder); // This was a successful order $oldStatus = GetOrderStatusById($this->GetOrderStatus()); if(!$oldStatus) { $oldStatus = 'Incomplete'; } $newStatus = GetOrderStatusById($newOrderStatus); $extra = GetLang('NabSuccessDetails', array( 'orderId' => $orderId, 'amount' => $amount, 'bankAuth' => $bankReference, 'transactionId' => $transactionId, 'paymentStatus' => 'Captured', 'newOrderStatus' => $newStatus, 'oldOrderStatus' => $oldStatus, ) ); $GLOBALS['ISC_CLASS_LOG']->LogSystemSuccess(array('payment', $this->GetName()), GetLang('NabSuccess'), $extra); return true; }