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;
}
}
}