diff --git a/app/appserver/config/modules/Checkout.php b/app/appserver/config/modules/Checkout.php index 610e10c71e69963f057d3d0c31945da473c055e0..9fdc69731a6289782dd295edde2a4d9b6ed27a14 100644 --- a/app/appserver/config/modules/Checkout.php +++ b/app/appserver/config/modules/Checkout.php @@ -10,6 +10,7 @@ return [ 'checkout' => [ 'class' => '\fecshop\app\appserver\modules\Checkout\Module', 'params'=> [ + 'guestOrder' => true, // 是否支持游客下单 ], ] ]; \ No newline at end of file diff --git a/app/appserver/config/modules/Payment.php b/app/appserver/config/modules/Payment.php new file mode 100644 index 0000000000000000000000000000000000000000..e52780aea73382176738a1e1ecb2431c6a4103ba --- /dev/null +++ b/app/appserver/config/modules/Payment.php @@ -0,0 +1,15 @@ + [ + 'class' => '\fecshop\app\appserver\modules\Payment\Module', + 'params'=> [ + ], + ] +]; \ No newline at end of file diff --git a/app/appserver/modules/Checkout/block/onepage/Index.php b/app/appserver/modules/Checkout/block/onepage/Index.php new file mode 100644 index 0000000000000000000000000000000000000000..5fc9378d535eb8723c09487981a4c2a2d45b4981 --- /dev/null +++ b/app/appserver/modules/Checkout/block/onepage/Index.php @@ -0,0 +1,583 @@ + + * @since 1.0 + */ +class Index +{ + protected $_payment_method; + protected $_shipping_method; + //protected $_address_view_file; + protected $_address_id; + protected $_address_list; + protected $_country; + protected $_state; + protected $stateArr; + //protected $_stateHtml; + protected $_cartAddress; + protected $_cart_address; + protected $_cart_info; + + public function getLastData() + { + $cartInfo = Yii::$service->cart->getCartInfo(); + + if (!isset($cartInfo['products']) || !is_array($cartInfo['products']) || empty($cartInfo['products'])) { + return [ + 'code' => 401, + 'content' => 'cart is empty', + ]; + } + $currency_info = Yii::$service->page->currency->getCurrencyInfo(); + $this->initAddress(); + $this->initCountry(); + //$this->initState(); + $shippings = $this->getShippings(); + $last_cart_info = $this->getCartInfo($this->_shipping_method, $this->_country, $this->_state); + $isGuest = 1; + if(!Yii::$app->user->isGuest){ + $isGuest = 0; + } + return [ + 'code' => 200, + 'payments' => $this->getPayment(), + 'shippings' => $shippings, + 'current_payment_method' => $this->_payment_method, + 'cart_info' => $last_cart_info, + 'currency_info' => $currency_info, + //'address_view_file' => $this->_address_view_file, + + 'isGuest' => $isGuest, + 'address_list' => $this->_address_list, + + 'cart_address' => $this->_address, + 'cart_address_id' => $this->_address_id, + 'countryArr' => $this->_countrySelect, + 'country' => $this->_country, + //'state_select' => $this->_stateSelect, + //'stateArr' => $this->stateArr, + //'state' => $this->_state, + ]; + } + + /** + * 初始化地址信息,首先从当前用户里面取值,然后从cart表中取数据覆盖 + * 1. 初始化 $this->_address,里面保存的各个地址信息。 + * 2. 如果是登录用户,而且. + */ + public function initAddress() + { + //$this->_cart_address = Yii::$service->cart->quote->getCartAddress(); + + $cart = Yii::$service->cart->quote->getCart(); + $address_id = $cart['customer_address_id']; + + $address_info = []; + if (!Yii::$app->user->isGuest) { + $identity = Yii::$app->user->identity; + $address_info['email'] = $identity['email']; + $address_info['first_name'] = $identity['firstname']; + $address_info['last_name'] = $identity['lastname']; + } + if (isset($cart['customer_email']) && !empty($cart['customer_email'])) { + $address_info['email'] = $cart['customer_email']; + } + + if (isset($cart['customer_firstname']) && !empty($cart['customer_firstname'])) { + $address_info['first_name'] = $cart['customer_firstname']; + } + + if (isset($cart['customer_lastname']) && !empty($cart['customer_lastname'])) { + $address_info['last_name'] = $cart['customer_lastname']; + } + + if (isset($cart['customer_telephone']) && !empty($cart['customer_telephone'])) { + $address_info['telephone'] = $cart['customer_telephone']; + } + + if (isset($cart['customer_address_country']) && !empty($cart['customer_address_country'])) { + $address_info['country'] = $cart['customer_address_country']; + $this->_country = $address_info['country']; + } + + if (isset($cart['customer_address_state']) && !empty($cart['customer_address_state'])) { + $address_info['state'] = $cart['customer_address_state']; + } + + if (isset($cart['customer_address_city']) && !empty($cart['customer_address_city'])) { + $address_info['city'] = $cart['customer_address_city']; + } + + if (isset($cart['customer_address_zip']) && !empty($cart['customer_address_zip'])) { + $address_info['zip'] = $cart['customer_address_zip']; + } + + if (isset($cart['customer_address_street1']) && !empty($cart['customer_address_street1'])) { + $address_info['street1'] = $cart['customer_address_street1']; + } + + if (isset($cart['customer_address_street2']) && !empty($cart['customer_address_street2'])) { + $address_info['street2'] = $cart['customer_address_street2']; + } + $this->_address = $address_info; + $this->_address_list = Yii::$service->customer->address->currentAddressList(); + if(empty($this->_address_list)){ + $this->_address_list = ''; + } + //var_dump($this->_address_list); + // 如果购物车存在customer_address_id,而且用户地址中也存在customer_address_id + // 则执行if{}内代码。 + if ($address_id && isset($this->_address_list[$address_id]) && !empty($this->_address_list[$address_id])) { + $this->_address_id = $address_id; + //$this->_address_view_file = 'checkout/onepage/index/address_select.php'; + $addressModel = Yii::$service->customer->address->getByPrimaryKey($this->_address_id); + if ($addressModel['country']) { + $this->_country = $addressModel['country']; + $this->_address['country'] = $this->_country; + } + if ($addressModel['state']) { + $this->_state = $addressModel['state']; + $this->_address['state'] = $this->_state; + } + if ($addressModel['first_name']) { + $this->_address['first_name'] = $addressModel['first_name']; + } + + if ($addressModel['last_name']) { + $this->_address['last_name'] = $addressModel['last_name']; + } + + if ($addressModel['email']) { + $this->_address['email'] = $addressModel['email']; + } + + if ($addressModel['telephone']) { + $this->_address['telephone'] = $addressModel['telephone']; + } + + if ($addressModel['street1']) { + $this->_address['street1'] = $addressModel['street1']; + } + if ($addressModel['street2']) { + $this->_address['street2'] = $addressModel['street2']; + } + if ($addressModel['city']) { + $this->_address['city'] = $addressModel['city']; + } + if ($addressModel['zip']) { + $this->_address['zip'] = $addressModel['zip']; + } + } elseif (is_array($this->_address_list) && !empty($this->_address_list)) { + // 用户存在地址列表,但是,cart中没有customer_address_id + // 这种情况下,从用户地址列表中取出来默认地址,然后设置成当前的地址。 + foreach ($this->_address_list as $adss_id => $info) { + if ($info['is_default'] == 1) { + $this->_address_id = $adss_id; + //$this->_address_view_file = 'checkout/onepage/index/address_select.php'; + $addressModel = Yii::$service->customer->address->getByPrimaryKey($this->_address_id); + if ($addressModel['country']) { + $this->_country = $addressModel['country']; + $this->_address['country'] = $this->_country; + } + if ($addressModel['state']) { + $this->_state = $addressModel['state']; + $this->_address['state'] = $this->_state; + } + if ($addressModel['first_name']) { + $this->_address['first_name'] = $addressModel['first_name']; + } + + if ($addressModel['last_name']) { + $this->_address['last_name'] = $addressModel['last_name']; + } + + if ($addressModel['email']) { + $this->_address['email'] = $addressModel['email']; + } + + if ($addressModel['telephone']) { + $this->_address['telephone'] = $addressModel['telephone']; + } + + if ($addressModel['street1']) { + $this->_address['street1'] = $addressModel['street1']; + } + if ($addressModel['street2']) { + $this->_address['street2'] = $addressModel['street2']; + } + if ($addressModel['city']) { + $this->_address['city'] = $addressModel['city']; + } + if ($addressModel['zip']) { + $this->_address['zip'] = $addressModel['zip']; + } + break; + } + } + } else { + //$this->_address_view_file = 'checkout/onepage/index/address.php'; + // 从购物车里面取出来数据。 $_cartAddress + //$cart_info = Yii::$service->cart->getCartInfo(); + } + if (!$this->_country) { + $this->_country = Yii::$service->helper->country->getDefaultCountry(); + $this->_address['country'] = $this->_country; + } + } + + /** + * 初始化国家下拉条。 + */ + public function initCountry() + { + $this->_countrySelect = Yii::$service->helper->country->getAllCountryArray(); + } + + /** + * 初始化省市 + */ + public function initState($country = '') + { + + $state = isset($this->_address['state']) ? $this->_address['state'] : ''; + if (!$country) { + $country = $this->_country; + } + $stateArr = Yii::$service->helper->country->getStateByContryCode($country, $state); + if(empty($stateArr)){ + $stateArr = ''; + } + $this->stateArr = $stateArr; + + //if (!$stateArr) { + // $stateHtml = ''; + //} else { + // $stateHtml = ''; + //} + //$this->_stateHtml = $stateHtml; + } + + /** + * 当改变国家的时候,ajax获取省市信息. + */ + public function ajaxChangecountry() + { + $country = Yii::$app->request->get('country'); + $country = \Yii::$service->helper->htmlEncode($country); + $state = $this->initState($country); + return [ + 'code' => 200, + 'stateArr' => $this->stateArr, + ]; + } + + /** + * @return $cart_info | Array + * 本函数为从数据库中得到购物车中的数据,然后结合产品表 + * 在加入一些产品数据,最终补全所有需要的信息。 + */ + public function getCartInfo($shipping_method, $country, $state) + { + if (!$this->_cart_info) { + $cart_info = Yii::$service->cart->getCartInfo($shipping_method, $country, $state); + if (isset($cart_info['products']) && is_array($cart_info['products'])) { + foreach ($cart_info['products'] as $k=>$product_one) { + // 设置名字,得到当前store的语言名字。 + $cart_info['products'][$k]['name'] = Yii::$service->store->getStoreAttrVal($product_one['product_name'], 'name'); + // 设置图片 + if (isset($product_one['product_image']['main']['image'])) { + $image = $product_one['product_image']['main']['image']; + $cart_info['products'][$k]['imgUrl'] = Yii::$service->product->image->getResize($image,[100,100],false); + } + // 产品的url + //$cart_info['products'][$k]['url'] = Yii::$service->url->getUrl($product_one['product_url']); + $custom_option = isset($product_one['custom_option']) ? $product_one['custom_option'] : ''; + $custom_option_sku = $product_one['custom_option_sku']; + // 将在产品页面选择的颜色尺码等属性显示出来。 + $custom_option_info_arr = $this->getProductOptions($product_one, $custom_option_sku); + $cart_info['products'][$k]['custom_option_info'] = $custom_option_info_arr; + // 设置相应的custom option 对应的图片 + $custom_option_image = isset($custom_option[$custom_option_sku]['image']) ? $custom_option[$custom_option_sku]['image'] : ''; + if ($custom_option_image) { + $cart_info['products'][$k]['image'] = $custom_option_image; + } + } + } + $this->_cart_info = $cart_info; + } + + return $this->_cart_info; + } + + /** + * 将产品页面选择的颜色尺码等显示出来,包括custom option 和spu options部分的数据. + */ + public function getProductOptions($product_one, $custom_option_sku) + { + $custom_option_info_arr = []; + $custom_option = isset($product_one['custom_option']) ? $product_one['custom_option'] : ''; + $custom_option_sku = $product_one['custom_option_sku']; + if (isset($custom_option[$custom_option_sku]) && !empty($custom_option[$custom_option_sku])) { + $custom_option_info = $custom_option[$custom_option_sku]; + foreach ($custom_option_info as $attr=>$val) { + if (!in_array($attr, ['qty', 'sku', 'price', 'image'])) { + $attr = str_replace('_', ' ', $attr); + $attr = ucfirst($attr); + $custom_option_info_arr[$attr] = $val; + } + } + } + + $spu_options = $product_one['spu_options']; + if (is_array($spu_options) && !empty($spu_options)) { + foreach ($spu_options as $label => $val) { + $custom_option_info_arr[$label] = $val; + } + } + + return $custom_option_info_arr; + } + + /** + * @property $current_shipping_method | String 当前选择的货运方式 + * @return Array,数据格式为: + * [ + * 'method'=> $method, + * 'label' => $label, + * 'name' => $name, + * 'cost' => $symbol.$currentCurrencyCost, + * 'check' => $check, + * 'shipping_i' => $shipping_i, + * ] + * 根据选择的货运方式,得到费用等信息。 + */ + public function getShippings($custom_shipping_method = '') + { + $country = $this->_country; + if (!$this->_state) { + $region = '*'; + } else { + $region = $this->_state; + } + $cartProductInfo = Yii::$service->cart->quoteItem->getCartProductInfo(); + //echo $country ; + $product_weight = $cartProductInfo['product_weight']; + // 传递当前的货运方式,这个需要从cart中选取, + // 如果cart中没有shipping_method,那么该值为空 + //var_dump($this->_cart_info); + $cartShippingMethod = $this->_cart_info['shipping_method']; + //echo "$custom_shipping_method,$cartShippingMethod"; + $current_shipping_method = Yii::$service->shipping->getCurrentShippingMethod($custom_shipping_method, $cartShippingMethod); + + $this->_shipping_method = $current_shipping_method; + $shippingArr = $this->getShippingArr($product_weight, $current_shipping_method, $country, $region); + + return $shippingArr; + } + + /** + * @return 得到所有的支付方式 + * 在获取的同时,判断$this->_payment_method 是否存在,不存在则取 + * 第一个支付方式,作为$this->_payment_method的值。 + */ + public function getPayment() + { + $paymentArr = Yii::$service->payment->getStandardPaymentArr(); + $pArr = []; + if (!$this->_payment_method) { + if (isset($this->_cart_info['payment_method']) && !empty($this->_cart_info['payment_method'])) { + $this->_payment_method = $this->_cart_info['payment_method']; + } + //echo $this->_payment_method; + if (!$this->_payment_method) { + $i = 0; + foreach ($paymentArr as $k => $v) { + $i++; + if ($i == 1) { + $this->_payment_method = $k; + $v['checked'] = true; + } + $pArr[$k] = $v; + } + } else { + $checked_payment = 0; + foreach ($paymentArr as $k => $v) { + if ($this->_payment_method == $k) { + $v['checked'] = true; + $checked_payment = 1; + } + $pArr[$k] = $v; + } + if (!$checked_payment) { + foreach ($paymentArr as $k => $v) { + $this->_payment_method = $k; + $pArr[$k]['checked'] = true; + break; + } + } + //var_dump($paymentArr); + } + } + + return $pArr; + } + + /** + * @property $weight | Float , 总量 + * @property $shipping_method | String $shipping_method key + * @property $country | String 国家 + * @return array , 通过上面的三个参数,得到各个运费方式对应的运费等信息。 + */ + public function getShippingArr($weight, $current_shipping_method, $country, $region = '*') + { + $allshipping = Yii::$service->shipping->getShippingMethod(); + $sr = ''; + $shipping_i = 1; + $arr = []; + if (is_array($allshipping)) { + foreach ($allshipping as $method=>$shipping) { + $label = $shipping['label']; + $name = $shipping['name']; + // 得到运费的金额 + //echo "$method,$weight,$country,$region"; + // getShippingCostWithSymbols + $cost = Yii::$service->shipping->getShippingCost($method, $weight, $country, $region); + //var_dump($cost); + //echo "##" + $currentCurrencyCost = $cost['currCost']; + $symbol = Yii::$service->page->currency->getCurrentSymbol(); + if ($current_shipping_method == $method) { + $checked = true; + } else { + $checked = ''; + } + $arr[] = [ + 'method'=> $method, + 'label' => $label, + 'name' => $name, + 'cost' => $currentCurrencyCost, + 'symbol' => $symbol, + 'checked' => $checked, + 'shipping_i' => $shipping_i, + ]; + + $shipping_i++; + } + } + + return $arr; + } + + /** + * js函数 ajaxreflush() 执行后,就会执行这个函数 + * 在 + * 1.切换address list, + * 2.取消coupon, + * 3.切换国家和省市信息, + * 4.更改货运方式等 + * 集中情况下,就会触发执行当前函数, + * 该函数会根据传递的参数,重新计算shipping 和order 部分信息,返回 + * 给前端。 + * @proeprty Array, + * @return json_encode(Array),Array格式如下: + * [ + * 'status' => 'success', + * 'shippingHtml' => $shippingHtml, + * 'reviewOrderHtml' => $reviewOrderHtml, + * ] + * 返回给js后,js根据数据将信息更新到相应的部分。 + */ + public function ajaxUpdateOrderAndShipping() + { + $country = Yii::$app->request->get('country'); + $shipping_method = Yii::$app->request->get('shipping_method'); + $address_id = Yii::$app->request->get('address_id'); + $state = Yii::$app->request->get('state'); + $country = \Yii::$service->helper->htmlEncode($country); + $shipping_method = \Yii::$service->helper->htmlEncode($shipping_method); + $address_id = \Yii::$service->helper->htmlEncode($address_id); + $state = \Yii::$service->helper->htmlEncode($state); + if ($address_id) { + $this->_address_id = $address_id; + $addressModel = Yii::$service->customer->address->getByPrimaryKey($this->_address_id); + if ($addressModel['country']) { + $country = $addressModel['country']; + $this->_country = $addressModel['country']; + } + if ($addressModel['state']) { + $state = $addressModel['state']; + $this->_state = $addressModel['state']; + } + } elseif ($country) { + $this->_country = $country; + if (!$state) { + $state = '*'; + } + $this->_state = $state; + } + if ($this->_country && $this->_state) { + $shippings = $this->getShippings($shipping_method); + $payments = $this->getPayment(); + /** + * 下面是Fecshop的widget,通过一个一个数据数组+第一个view文件 + * 组合得到对应的html代码,返回给$shippingHtml + * 由于fecshop多多模板系统,预先从高级别的模板路径中依次查找view文件,存在则使用该view文件. + */ + $shippingView = [ + 'view' => 'checkout/onepage/index/shipping.php', + ]; + $shippingParam = [ + 'shippings' => $shippings, + ]; + $shippingHtml = Yii::$service->page->widget->render($shippingView, $shippingParam); + /** + * 先通过item计算出来重量,得到运费 然后setShippingCost($shippingCost),将当前根据传递参数计算 + * 出来的运费结果set到quote.shippingCost中, + * 原因:这里是用户勾选切换国家地址进行的运费计算反馈给用户,但是该信息不更新到数据库,仅仅显示出来 + * 相应的费用给用户看,因此,shippingCost通过传递的参数计算出来设置到quote中,而不是通过数据库中保存 + * 的信息计算。 + */ + $quoteItem = Yii::$service->cart->quoteItem->getCartProductInfo(); + $product_weight = $quoteItem['product_weight']; + $shippingCost = Yii::$service->shipping->getShippingCost($shipping_method, $product_weight, $country, $state); + Yii::$service->cart->quote->setShippingCost($shippingCost); + + /** + * 下面通过当前的货币,购物车信息等数组数据,+上view文件 + * 返回order部分的html内容。 + */ + // 得到当前货币 + $currency_info = Yii::$service->page->currency->getCurrencyInfo(); + $reviewOrderView = [ + 'view' => 'checkout/onepage/index/review_order.php', + ]; + $cart_info = $this->getCartInfo($shipping_method, $this->_country, $this->_state); + + $reviewOrderParam = [ + 'cart_info' => $cart_info, + 'currency_info' => $currency_info, + ]; + $reviewOrderHtml = Yii::$service->page->widget->render($reviewOrderView, $reviewOrderParam); + echo json_encode([ + 'status' => 'success', + 'shippingHtml' => $shippingHtml, + 'reviewOrderHtml' => $reviewOrderHtml, + ]); + exit; + } + } +} diff --git a/app/appserver/modules/Checkout/block/onepage/Placeorder.php b/app/appserver/modules/Checkout/block/onepage/Placeorder.php new file mode 100644 index 0000000000000000000000000000000000000000..3a193ab444ffdeb9b78ccef21d526a71ba5078fe --- /dev/null +++ b/app/appserver/modules/Checkout/block/onepage/Placeorder.php @@ -0,0 +1,286 @@ + + * @since 1.0 + */ +class Placeorder +{ + /** + * 用户的账单地址信息,通过用户传递的信息计算而来。 + */ + public $_billing; + + public $_address_id; + /** + * 用户的货运方式. + */ + public $_shipping_method; + /** + * 用户的支付方式. + */ + public $_payment_method; + + public function getLastData() + { + $post = Yii::$app->request->post(); + if (is_array($post) && !empty($post)) { + /** + * 对传递的数据,去除掉非法xss攻击部分内容(通过\Yii::$service->helper->htmlEncode()). + */ + $post = \Yii::$service->helper->htmlEncode($post); + // 如果是支付宝,那么更改货币为人民币 + $alipay_payment_key = Yii::$service->payment->alipay->getAlipayHandle(); + if($post['payment_method'] == $alipay_payment_key){ + Yii::$service->page->currency->setCurrentCurrency2CNY(); + } + // 检查前台传递的数据的完整 + if ($this->checkOrderInfoAndInit($post)) { + // 如果游客用户勾选了注册账号,则注册,登录,并把地址写入到用户的address中 + $gus_status = $this->guestCreateAndLoginAccount($post); + $save_address_status = $this->updateAddress($post); + if ($gus_status && $save_address_status) { + // 更新Cart信息 + //$this->updateCart(); + // 设置checkout type + $serviceOrder = Yii::$service->order; + $checkout_type = $serviceOrder::CHECKOUT_TYPE_STANDARD; + $serviceOrder->setCheckoutType($checkout_type); + // 将购物车数据,生成订单。 + $innerTransaction = Yii::$app->db->beginTransaction(); + try { + # 生成订单,扣除库存,但是,不清空购物车。 + $genarateStatus = Yii::$service->order->generateOrderByCart($this->_billing, $this->_shipping_method, $this->_payment_method,false); + if ($genarateStatus) { + // 得到当前的订单信息 + //$orderInfo = Yii::$service->order->getCurrentOrderInfo(); + // 发送新订单邮件 + //Yii::$service->email->order->sendCreateEmail($orderInfo); + // 得到支付跳转前的准备页面。 + $startUrl = Yii::$service->payment->getStandardStartUrl(); + $innerTransaction->commit(); + Yii::$service->url->redirect($startUrl); + + return true; + } else { + $innerTransaction->rollBack(); + } + } catch (Exception $e) { + $innerTransaction->rollBack(); + } + } + } else { + } + } + //echo 333;exit; + Yii::$service->page->message->addByHelperErrors(); + + return false; + } + + /** + * @property $post|Array,前台传递参数数组。 + * 如果游客选择了创建账户,并且输入了密码,则使用address email作为账号, + * 进行账号的注册和登录。 + */ + public function guestCreateAndLoginAccount($post) + { + $create_account = $post['create_account']; + $billing = $post['billing']; + if (!is_array($billing) || empty($billing)) { + Yii::$service->helper->errors->add('billing must be array and can not empty'); + + return false; + } + if ($create_account) { + $customer_password = $billing['customer_password']; + $confirm_password = $billing['confirm_password']; + if ($customer_password != $confirm_password) { + Yii::$service->helper->errors->add('the passwords are inconsistent'); + + return false; + } + $passMin = Yii::$service->customer->getRegisterPassMinLength(); + $passMax = Yii::$service->customer->getRegisterPassMaxLength(); + if (strlen($customer_password) < $passMin) { + Yii::$service->helper->errors->add('password must Greater than '.$passMin); + + return false; + } + if (strlen($customer_password) > $passMax) { + Yii::$service->helper->errors->add('password must less than '.$passMax); + + return false; + } + $param['email'] = $billing['email']; + $param['password'] = $billing['customer_password']; + $param['firstname'] = $billing['first_name']; + $param['lastname'] = $billing['last_name']; + if (!Yii::$service->customer->register($param)) { + return false; + } else { + Yii::$service->customer->Login([ + 'email' => $billing['email'], + 'password' => $billing['customer_password'], + ]); + } + } + + return true; + } + + /** + * @property $post | Array + * 登录用户,保存货运地址到customer address ,然后把生成的 + * address_id 写入到cart中。 + * shipping method写入到cart中 + * payment method 写入到cart中 updateCart + */ + public function updateAddress($post) + { + if (!Yii::$app->user->isGuest) { + $billing = $post['billing']; + $address_id = $post['address_id']; + if (!$address_id) { + $identity = Yii::$app->user->identity; + $customer_id = $identity['id']; + $one = [ + 'first_name' => $billing['first_name'], + 'last_name' => $billing['last_name'], + 'email' => $billing['email'], + 'company' => '', + 'telephone' => $billing['telephone'], + 'fax' => '', + 'street1' => $billing['street1'], + 'street2' => $billing['street2'], + 'city' => $billing['city'], + 'state' => $billing['state'], + 'zip' => $billing['zip'], + 'country' => $billing['country'], + 'customer_id' => $customer_id, + 'is_default' => 1, + ]; + $address_id = Yii::$service->customer->address->save($one); + $this->_address_id = $address_id; + if (!$address_id) { + Yii::$service->helper->errors->add('new customer address save fail'); + + return false; + } + //echo "$address_id,$this->_shipping_method,$this->_payment_method"; + } + + return Yii::$service->cart->updateLoginCart($this->_address_id, $this->_shipping_method, $this->_payment_method); + } else { + return Yii::$service->cart->updateGuestCart($this->_billing, $this->_shipping_method, $this->_payment_method); + } + + return true; + } + + /** + * 如果是游客,那么保存货运地址到购物车表。 + */ + /* + public function updateCart(){ + if(Yii::$app->user->isGuest){ + return Yii::$service->cart->updateGuestCart($this->_billing,$this->_shipping_method,$this->_payment_method); + }else{ + return Yii::$service->cart->updateLoginCart($this->_address_id,$this->_shipping_method,$this->_payment_method); + } + } + */ + + /** + * @property $post | Array + * @return bool + * 检查前台传递的信息是否正确。同时初始化一部分类变量 + */ + public function checkOrderInfoAndInit($post) + { + $address_one = ''; + $address_id = isset($post['address_id']) ? $post['address_id'] : ''; + $billing = isset($post['billing']) ? $post['billing'] : ''; + if ($address_id) { + $this->_address_id = $address_id; + if (Yii::$app->user->isGuest) { + Yii::$service->helper->errors->add('address id can not use for guest'); + + return false; // address_id 这种情况,必须是登录用户。 + } else { + $customer_id = Yii::$app->user->identity->id; + if (!$customer_id) { + Yii::$service->helper->errors->add('customer id is empty'); + + return false; + } else { + $address_one = Yii::$service->customer->address->getAddressByIdAndCustomerId($address_id, $customer_id); + if (!$address_one) { + Yii::$service->helper->errors->add('current address id is not belong to current user'); + + return false; + } else { + // 从address_id中取出来的字段,查看是否满足必写的要求。 + if (!Yii::$service->order->checkRequiredAddressAttr($address_one)) { + return false; + } + $arr['customer_id'] = $customer_id; + foreach ($address_one as $k=>$v) { + $arr[$k] = $v; + } + $this->_billing = $arr; + } + } + } + } elseif ($billing && is_array($billing)) { + // 检查address的必写字段是否都存在 + //var_dump($billing);exit; + if (!Yii::$service->order->checkRequiredAddressAttr($billing)) { + return false; + } + $this->_billing = $billing; + } + $shipping_method = isset($post['shipping_method']) ? $post['shipping_method'] : ''; + $payment_method = isset($post['payment_method']) ? $post['payment_method'] : ''; + // 验证货运方式 + if (!$shipping_method) { + Yii::$service->helper->errors->add('shipping method can not empty'); + + return false; + } else { + if (!Yii::$service->shipping->ifIsCorrect($shipping_method)) { + Yii::$service->helper->errors->add('shipping method is not correct'); + + return false; + } + } + // 验证支付方式 + if (!$payment_method) { + Yii::$service->helper->errors->add('payment method can not empty'); + + return false; + } else { + if (!Yii::$service->payment->ifIsCorrectStandard($payment_method)) { + Yii::$service->helper->errors->add('payment method is not correct'); + + return false; + } + } + $this->_shipping_method = $shipping_method; + $this->_payment_method = $payment_method; + Yii::$service->payment->setPaymentMethod($this->_payment_method); + + return true; + } +} diff --git a/app/appserver/modules/Checkout/controllers/OnepageController.php b/app/appserver/modules/Checkout/controllers/OnepageController.php new file mode 100644 index 0000000000000000000000000000000000000000..5962b955af03f0657617ed76898bf2946231eaf6 --- /dev/null +++ b/app/appserver/modules/Checkout/controllers/OnepageController.php @@ -0,0 +1,75 @@ + + * @since 1.0 + */ +class OnepageController extends AppserverController +{ + public $enableCsrfValidation = false; + + //public function init(){ + // Yii::$service->page->theme->layoutFile = 'one_step_checkout.php'; + + //} + + public function actionIndex() + { + $guestOrder = Yii::$app->controller->module->params['guestOrder']; + if(!$guestOrder && Yii::$app->user->isGuest){ + return [ + 'code' => 400, + 'content' => 'you must login your account' + ]; + } + + return $this->getBlock()->getLastData(); + } + + public function actionSubmitorder(){ + $guestOrder = Yii::$app->controller->module->params['guestOrder']; + if(!$guestOrder && Yii::$app->user->isGuest){ + return [ + 'code' => 400, + 'content' => 'you must login your account' + ]; + } + $submitOrder = Yii::$app->request->post('submitOrder'); + $status = $this->getBlock('placeorder')->getLastData(); + if (!$status) { + return [ + 'code' => '401', + 'content' => 'generate order fail' + ]; + }else{ + return [ + 'code' => '200', + 'content' => 'generate order success' + ]; + } + + + } + + public function actionChangecountry() + { + return $this->getBlock('index')->ajaxChangecountry(); + } + + public function actionAjaxupdateorder() + { + $this->getBlock('index')->ajaxUpdateOrderAndShipping(); + } +} diff --git a/app/appserver/modules/Payment/Module.php b/app/appserver/modules/Payment/Module.php new file mode 100644 index 0000000000000000000000000000000000000000..7c9191380274e55fd500a5b0c844c886d8e83ba9 --- /dev/null +++ b/app/appserver/modules/Payment/Module.php @@ -0,0 +1,44 @@ + + * @since 1.0 + */ +class Module extends AppserverModule +{ + public $blockNamespace; + + public function init() + { + // 以下代码必须指定 + $nameSpace = __NAMESPACE__; + // web controller + if (Yii::$app instanceof \yii\web\Application) { + $this->controllerNamespace = $nameSpace . '\\controllers'; + $this->blockNamespace = $nameSpace . '\\block'; + // console controller + //} elseif (Yii::$app instanceof \yii\console\Application) { + // $this->controllerNamespace = $nameSpace . '\\console\\controllers'; + // $this->blockNamespace = $nameSpace . '\\console\\block'; + } + //$this->_currentDir = __DIR__ ; + //$this->_currentNameSpace = __NAMESPACE__; + + // 指定默认的man文件 + //$this->layout = "home.php"; + //Yii::$service->page->theme->layoutFile = 'main.php'; + parent::init(); + } +} diff --git a/app/appserver/modules/Payment/block/paypal/express/Start.php b/app/appserver/modules/Payment/block/paypal/express/Start.php new file mode 100644 index 0000000000000000000000000000000000000000..908eb830d8c79aea772defc4c4e052a2174f786f --- /dev/null +++ b/app/appserver/modules/Payment/block/paypal/express/Start.php @@ -0,0 +1,95 @@ + + * @since 1.0 + */ +class Start +{ + + public $_errors; + + public function startExpress() + { + $checkStatus = $this->checkStockQty(); + if(!$checkStatus){ + return [ + 'code' => 401, + 'content' => $this->_errors, + ]; + } + $methodName_ = 'SetExpressCheckout'; + $nvpStr_ = Yii::$service->payment->paypal->getExpressTokenNvpStr(); + //echo $nvpStr_;exit; + $SetExpressCheckoutReturn = Yii::$service->payment->paypal->PPHttpPost5($methodName_, $nvpStr_); + //var_dump($SetExpressCheckoutReturn); + if (strtolower($SetExpressCheckoutReturn['ACK']) == 'success') { + $token = $SetExpressCheckoutReturn['TOKEN']; + # ɶֻid,increment_id,token ֵֶ + if($token){ + if(!Yii::$service->order->generatePPExpressOrder($token)){ + return [ + 'code' => 402, + 'content' => 'generate order fail', + ]; + } + $redirectUrl = Yii::$service->payment->paypal->getSetExpressCheckoutUrl($token); + return [ + 'code' => 200, + 'content' => $redirectUrl, + ]; + } + } elseif (strtolower($SetExpressCheckoutReturn['ACK']) == 'failure') { + return [ + 'code' => 403, + 'content' => $SetExpressCheckoutReturn['L_LONGMESSAGE0'], + ]; + echo $SetExpressCheckoutReturn['L_LONGMESSAGE0']; + } else { + return [ + 'code' => 403, + 'content' => $SetExpressCheckoutReturn, + ]; + } + } + + // 鹺ﳵвƷĿ档˲ֻdz飬ڿ֧ɷվʱɶʱ򣬻ҪһƷ棬 + // Ϊ֧ĹУƷܱߡ + public function checkStockQty(){ + $stockCheck = Yii::$service->product->stock->checkItemsQty(); + + //var_dump($stockCheck);exit; + if(!$stockCheck){ + //Yii::$service->url->redirectByUrlKey('checkout/cart'); + $this->_errors .= 'cart products is empty'; + return false; + }else{ + if(isset($stockCheck['stockStatus'])){ + if($stockCheck['stockStatus'] == 2){ + $outStockProducts = $stockCheck['outStockProducts']; + if(is_array($outStockProducts) && !empty($outStockProducts)){ + foreach($outStockProducts as $outStockProduct){ + $product_name = Yii::$service->store->getStoreAttrVal($outStockProduct['product_name'], 'name'); + $this->_errors .= 'product: ['.$product_name.'] is stock out.'; + } + + return false; + } + } + } + } + + return true; + } +} diff --git a/app/appserver/modules/Payment/controllers/paypal/ExpressController.php b/app/appserver/modules/Payment/controllers/paypal/ExpressController.php new file mode 100644 index 0000000000000000000000000000000000000000..378116957a58cda663bd63e781259ff58fbbb422 --- /dev/null +++ b/app/appserver/modules/Payment/controllers/paypal/ExpressController.php @@ -0,0 +1,61 @@ + + * @since 1.0 + */ +class ExpressController extends AppserverController +{ + public $enableCsrfValidation = false; + + public function actionStart() + { + return $this->getBlock()->startExpress(); + } + + // 2.Review 从paypal确认后返回 + public function actionReview() + { + $_csrf = Yii::$app->request->post('_csrf'); + if ($_csrf) { + $status = $this->getBlock('placeorder')->getLastData(); + if ($status) { + return; + } + } + $data = $this->getBlock()->getLastData(); + if (is_array($data) && !empty($data)) { + return $this->render($this->action->id, $data); + } else { + return $data; + } + } + + public function actionIpn() + { + \Yii::info('paypal ipn begin', 'fecshop_debug'); + + $post = Yii::$app->request->post(); + if (is_array($post) && !empty($post)) { + $post = \Yii::$service->helper->htmlEncode($post); + ob_start(); + ob_implicit_flush(false); + var_dump($post); + $post_log = ob_get_clean(); + \Yii::info($post_log, 'fecshop_debug'); + //Yii::$service->payment->paypal->receiveIpn($post); + } + } +} diff --git a/services/Customer.php b/services/Customer.php index 6bcef0994b922ae6aa4ae381798b762db34bad0f..9ca2e08cb58543daf82e5d07c0e54c464be8eb92 100644 --- a/services/Customer.php +++ b/services/Customer.php @@ -602,6 +602,9 @@ class Customer extends Service $identity->save(); } return $identity; + }else{ + $this->logoutByAccessToken(); + return false; } } }