/** * Executes actions associated with selected page. */ public function action() { $cart = $this->cartService->getCurrent(); if ($cart->isEmpty()) { $this->messages->addWarning(__('Your cart is empty, please add products before proceeding.', 'jigoshop')); $this->wp->redirectTo($this->options->getPageId(Pages::SHOP)); } if (!$this->isAllowedToEnterCheckout()) { $this->messages->addError(__('You need to log in before processing to checkout.', 'jigoshop')); $this->wp->redirectTo($this->options->getPageId(Pages::CART)); } if (isset($_POST['action']) && $_POST['action'] == 'purchase') { try { $allowRegistration = $this->options->get('shopping.allow_registration'); if ($allowRegistration && !$this->wp->isUserLoggedIn()) { $this->createUserAccount(); } if (!$this->isAllowedToCheckout($cart)) { if ($allowRegistration) { throw new Exception(__('You need either to log in or create account to purchase.', 'jigoshop')); } throw new Exception(__('You need to log in before purchasing.', 'jigoshop')); } if ($this->options->get('advanced.pages.terms') > 0 && (!isset($_POST['terms']) || $_POST['terms'] != 'on')) { throw new Exception(__('You need to accept terms & conditions!', 'jigoshop')); } $this->cartService->validate($cart); $this->customerService->save($cart->getCustomer()); if (!Country::isAllowed($cart->getCustomer()->getBillingAddress()->getCountry())) { $locations = array_map(function ($location) { return Country::getName($location); }, $this->options->get('shopping.selling_locations')); throw new Exception(sprintf(__('This location is not supported, we sell only to %s.'), join(', ', $locations))); } $shipping = $cart->getShippingMethod(); if ($this->isShippingRequired($cart) && (!$shipping || !$shipping->isEnabled())) { throw new Exception(__('Shipping is required for this order. Please select shipping method.', 'jigoshop')); } $payment = $cart->getPaymentMethod(); $isPaymentRequired = $this->isPaymentRequired($cart); $this->wp->doAction('jigoshop\\checkout\\payment', $payment); if ($isPaymentRequired && (!$payment || !$payment->isEnabled())) { throw new Exception(__('Payment is required for this order. Please select payment method.', 'jigoshop')); } $order = $this->orderService->createFromCart($cart); /** @var Order $order */ $order = $this->wp->applyFilters('jigoshop\\checkout\\order', $order); $this->orderService->save($order); $this->cartService->remove($cart); $url = ''; if ($isPaymentRequired) { $url = $payment->process($order); } else { $order->setStatus(\Jigoshop\Helper\Order::getStatusAfterCompletePayment($order)); $this->orderService->save($order); } // Redirect to thank you page if (empty($url)) { $url = $this->wp->getPermalink($this->wp->applyFilters('jigoshop\\checkout\\redirect_page_id', $this->options->getPageId(Pages::THANK_YOU))); $url = $this->wp->getHelpers()->addQueryArg(array('order' => $order->getId(), 'key' => $order->getKey()), $url); } $this->wp->wpRedirect($url); exit; } catch (Exception $e) { $this->messages->addError($e->getMessage()); } } }
public function processResponse() { if ($this->isResponseValid()) { $posted = $this->wp->getHelpers()->stripSlashesDeep($_POST); // 'custom' holds post ID (Order ID) if (!empty($posted['custom']) && !empty($posted['txn_type']) && !empty($posted['invoice'])) { $accepted_types = array('cart', 'instant', 'express_checkout', 'web_accept', 'masspay', 'send_money', 'subscr_payment'); /** @var \Jigoshop\Service\OrderService $service */ $service = $this->di->get('jigoshop.service.order'); $order = $service->find((int) $posted['custom']); // Sandbox fix if (isset($posted['test_ipn']) && $posted['test_ipn'] == 1 && strtolower($posted['payment_status']) == 'pending') { $posted['payment_status'] = 'completed'; } $merchant = $this->settings['test_mode'] ? $this->settings['test_email'] : $this->settings['email']; if ($order->getStatus() !== Order\Status::COMPLETED) { // We are here so lets check status and do actions switch (strtolower($posted['payment_status'])) { case 'completed': if (!in_array(strtolower($posted['txn_type']), $accepted_types)) { // Put this order on-hold for manual checking $order->setStatus(Order\Status::ON_HOLD, sprintf(__('PayPal Validation Error: Unknown "txn_type" of "%s" for Order ID: %s.', 'jigoshop'), $posted['txn_type'], $posted['custom'])); break; } if ($order->getNumber() !== $posted['invoice']) { // Put this order on-hold for manual checking $order->setStatus(Order\Status::ON_HOLD, sprintf(__('PayPal Validation Error: Order Invoice Number does NOT match PayPal posted invoice (%s) for Order ID: .', 'jigoshop'), $posted['invoice'], $posted['custom'])); $service->save($order); exit; } // Validate Amount if (number_format($order->getTotal(), $this->decimals, '.', '') != $posted['mc_gross']) { // Put this order on-hold for manual checking $order->setStatus(Order\Status::ON_HOLD, sprintf(__('PayPal Validation Error: Payment amounts do not match initial order (gross %s).', 'jigoshop'), $posted['mc_gross'])); $service->save($order); exit; } if (strcasecmp(trim($posted['business']), trim($merchant)) != 0) { // Put this order on-hold for manual checking $order->setStatus(Order\Status::ON_HOLD, sprintf(__('PayPal Validation Error: Payment Merchant email received does not match PayPal Gateway settings. (%s)', 'jigoshop'), $posted['business'])); $service->save($order); exit; } if ($posted['mc_currency'] != $this->options->get('general.currency')) { // Put this order on-hold for manual checking $order->setStatus(Order\Status::ON_HOLD, sprintf(__('PayPal Validation Error: Payment currency received (%s) does not match Shop currency.', 'jigoshop'), $posted['mc_currency'])); $service->save($order); exit; } $order->setStatus(OrderHelper::getStatusAfterCompletePayment($order), __('PayPal payment completed', 'jigoshop')); break; case 'denied': case 'expired': case 'failed': case 'voided': // Failed order $order->setStatus(Order\Status::ON_HOLD, sprintf(__('Payment %s via PayPal.', 'jigoshop'), strtolower($posted['payment_status']))); break; case 'refunded': case 'reversed': case 'chargeback': // TODO: Implement refunds break; default: // No action break; } $service->save($order); } } } }