PayController.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <?php
  2. namespace client\controllers;
  3. use biz\goods\services\CategoryRelateService;
  4. use biz\goods\services\UsageRelationService;
  5. use biz\order\services\OrderService;
  6. use biz\promote\services\CouponService;
  7. use biz\user\services\UserAssetService;
  8. use biz\weixin\services\WxSceneService;
  9. use common\components\qrCodeUtil;
  10. use common\models\xhOrder;
  11. use common\models\xhShop;
  12. use common\services\xhMerchantExtendService;
  13. use Faker\Provider\Base;
  14. use Yii;
  15. use yii\helpers\Json;
  16. use common\services\xhUserAssetService;
  17. use common\services\xhUserService;
  18. use common\services\xhCouponService;
  19. use common\services\xhPayToolService;
  20. use common\services\xhOrderService;
  21. use common\services\xhActiveService;
  22. use common\services\xhActiveTicketClassService;
  23. use common\components\util;
  24. use common\components\stringUtil;
  25. use common\components\configDict;
  26. class PayController extends BaseController
  27. {
  28. public $withoutLogin = ['get-params'];
  29. public $enableCsrfValidation = false;
  30. //创建订单 shish 2019.12.3
  31. public function actionCreateOrder()
  32. {
  33. $post = Yii::$app->request->post();
  34. //dump($post);die;
  35. $userId = $this->userId;
  36. $post['userId'] = $userId;
  37. $post['payWay'] = $this->isWeixin == true ? 0 : 1;
  38. $lat2 = $post['receiveLat'];//收货人纬度
  39. $lng2 = $post['receiveLong'];//收货人经度
  40. $lat1 = $this->merchant['shopLat'];//花店纬度
  41. $lng1 = $this->merchant['shopLong'];//花店经度
  42. $calcDistance = util::getDistance($lat1, $lng1, $lat2, $lng2);//防止别人改动,PHP计算的距离会比腾讯js算的小,但能保证有一定准确性
  43. $post['sendDistance'] = $post['sendDistance'] >= $calcDistance ? $post['sendDistance'] : $calcDistance;//二地距离
  44. $sendDistance = $post['sendDistance'];
  45. $freight = configDict::getConfig('freight');
  46. $firstDistance = $freight['firstDistance'];
  47. $firstPrice = $freight['firstPrice'];
  48. $nextDistance = $freight['nextDistance'];
  49. $nextPrice = $freight['nextPrice'];
  50. if ($sendDistance <= $firstDistance && $post['isCharge'] == 1) {
  51. $post['sendCost'] = $firstPrice;
  52. } else if ($post['isCharge'] == 1) {
  53. $subDistance = $sendDistance - $firstDistance;
  54. $addPrice = intval($subDistance / $nextDistance) * $nextPrice;
  55. $post['sendCost'] = $firstPrice + $addPrice;
  56. }
  57. if (empty($this->merchantExtend['payment'])) {
  58. util::failInfo('支付功能未开通,暂时无法购买哦~');
  59. }
  60. $couponAmount = 0;
  61. $couponId = isset($post['couponId']) ? $post['couponId'] : 0;//代金劵
  62. if (!empty($couponId)) {
  63. $coupon = xhCouponService::getById($couponId);
  64. $couponUserId = $coupon['userId'];
  65. if ($couponUserId != $userId) {
  66. util::failInfo('不是你的代金劵');
  67. }
  68. if ($coupon['useStatus'] == 1 || $coupon['deadline'] < time()) {
  69. util::failInfo('代金劵已经失效了');
  70. }
  71. $couponAmount = $coupon['amount'];
  72. }
  73. //不要将代金劵保存到订单表,付款成功后再保存进去!!!
  74. unset($post['couponId']);
  75. $post['merchantId'] = $this->merchantId;
  76. //店铺id
  77. $post['shopId'] = $this->merchant['defaultShopId'];
  78. $order = xhOrderService::add($post);//创建订单
  79. if ($order == false) {
  80. util::failInfo('创建订单失败');
  81. }
  82. $orderId = $order['id'];
  83. $oData = [];
  84. $goodsInfo = $post['goodsInfo'];
  85. $totalFee = 0;//计算总价格
  86. $goodsIdList = [];
  87. $multiPriceIdList = [];
  88. $orderName = '';
  89. $goodsNum = 0;
  90. foreach ($goodsInfo as $key => $val) {
  91. $multiPriceId = 0;//多种价格表Id
  92. $goodsId = $val['goodsId'];
  93. $num = $val['num'];
  94. $goodsNum += $num;
  95. $goods = xhGoodsService::getById($goodsId);
  96. if (empty($orderName)) {
  97. $orderName = $goods['goodsName'];
  98. }
  99. $price = $goods['price'];
  100. if ($val['multiPriceId'] != 0 && $goods['multiPrice'] != '') {
  101. $pos = strpos($goods['multiPrice'], $val['multiPriceId']);
  102. if ($pos === false) {
  103. util::failInfo('订单的商品不存在');
  104. }
  105. $goodPrice = xhGoodsPriceService::getById($val['multiPriceId']);
  106. //$price = $goodPrice['price'];
  107. $price = xhGoodsSettingService::changePrice($goods, $goodPrice['price']);//统一对商品进行价格等方面设置
  108. //多种价格规格 替换 默认(单价格)
  109. $goods['goodsName'] = $goodPrice['title'];
  110. //$goods['cover'] = $goodPrice['picture'];//后台图片上传功能未开发,暂时使用默认商品图片
  111. $multiPriceId = $val['multiPriceId'];
  112. }
  113. $totalFee += $price * $num;
  114. $goodsIdList[] = $goodsId;
  115. $multiPriceIdList[] = $multiPriceId;
  116. $data = [
  117. 'orderId' => $orderId,
  118. 'goodsId' => $goodsId,
  119. 'userId' => $userId,
  120. 'merchantId' => $this->merchantId,
  121. 'title' => $goods['goodsName'],
  122. 'cover' => $goods['cover'],
  123. 'unitPrice' => $price,
  124. 'num' => $num,
  125. 'multiPriceId' => $multiPriceId,
  126. 'createTime' => date("Y-m-d H:i:s"),
  127. ];
  128. xhOrderGoodsService::add($data);//创建订单商品列表
  129. }
  130. $sendCost = $post['sendCost'];//运费
  131. $oData['goodsNum'] = $goodsNum;//订单的商品数量类型,单个还是多个的
  132. $oData['prePrice'] = $totalFee + $sendCost;
  133. $oData['orderName'] = $goodsNum > 1 ? $orderName . '等' . $goodsNum . '件商品' : $orderName;
  134. if (isset($post['sourceType']) && $post['sourceType'] == 'cart') {
  135. if (!empty($goodsIdList)) {
  136. foreach ($goodsIdList as $key => $goodsId) {
  137. xhCartService::delByIds($userId, $goodsId, $multiPriceIdList[$key]);//删除购物车($userId, $goodsId, $goodsPriceId, $cartId)
  138. }
  139. }
  140. }
  141. $userAsset = xhUserAssetService::getByUserId($userId);
  142. $level = $userAsset['memberLevel'];
  143. if ($level > 0) {
  144. $gradeList = xhMerchantExtendService::getGradeList($this->merchantExtend);
  145. $discount = $gradeList[$level]['discount'];
  146. $discount = strlen($discount) == 1 ? $discount * 10 : $discount;
  147. $totalFee = number_format($discount * $totalFee / 100, 2);
  148. }
  149. $oData['actPrice'] = $totalFee + $sendCost - $couponAmount;
  150. xhOrderService::updateById($orderId, $oData);
  151. util::successInfo('订单创建成功', 'A0001', ['orderId' => $orderId, 'couponId' => $couponId]);
  152. }
  153. public function actionGetParams()
  154. {
  155. ini_set('date.timezone', 'Asia/Shanghai');
  156. $post = Yii::$app->request->post();
  157. $payWay = isset($post['payWay']) ? $post['payWay'] : '';
  158. $shopId = isset($post['shopId']) ? $post['shopId'] : 0;
  159. //来源 0自建商城 1门店 2微信朋友圈 3淘宝
  160. $sourceType = isset($post['sourceType']) ? $post['sourceType'] : 0;
  161. $shopInfo = xhShop::find()->where(['id' => $shopId])->one();
  162. if (empty($shopInfo) || $shopInfo->merchantId != $this->merchantId) {
  163. util::fail('门店无效');
  164. }
  165. unset($post['payWay']);
  166. $post['userId'] = $this->userId;
  167. $prePrice = round($post['prePrice'], 2);//四舍五入,保留二位小数
  168. $userAsset = xhUserAssetService::getByUserId($this->userId);
  169. $level = isset($userAsset['memberLevel']) ? $userAsset['memberLevel'] : 0;
  170. $merchantExtend = xhMerchantExtendService::getByMerchantId($this->merchantId);
  171. $memberIntegral = xhMerchantExtendService::getGradeList($merchantExtend, 'desc');
  172. Yii::info(json_encode($merchantExtend));
  173. Yii::info(json_encode($memberIntegral));
  174. //$discount = isset($memberIntegral[$level]['discount']) ? $memberIntegral[$level]['discount'] : $memberIntegral[$level]['discount'];
  175. $discount = 0;
  176. $actPrice = $prePrice;
  177. $couponId = isset($post['couponId']) && !empty($post['couponId']) ? $post['couponId'] : 0;
  178. Yii::info($this->userId . ' ' . $level . ' ' . $discount);
  179. //没有优惠券才能使用会员折扣 shish 2019.8.30
  180. if (!empty($discount) && $prePrice >= 1 && empty($couponId)) {
  181. $currentPrice = ($prePrice * $discount) / 100;
  182. $actPrice = substr(sprintf("%.3f", $currentPrice), 0, -2);
  183. }
  184. //没有优惠卷,微信朋友圈付款才给随机优惠金额 shish 2019.9.12
  185. if ($sourceType == 2 && empty($couponId)) {
  186. $discountAmount = OrderService::getRandDiscount($actPrice);
  187. //测试环境直接随机优惠0.01
  188. if (isset(Yii::$app->params['merchant'])) {
  189. $merchant = Yii::$app->params['merchant'];
  190. if ($merchant['merchantName'] == '花美灵') {
  191. $discountAmount = 0.01;
  192. }
  193. }
  194. $actPrice = stringUtil::calcSub($actPrice, $discountAmount);
  195. $post['discountType'] = 2;//优惠类型是:付款随机优惠
  196. $post['discountAmount'] = $discountAmount;
  197. }
  198. $post['actPrice'] = $actPrice;
  199. $post['payStyle'] = 0;
  200. $post['merchantId'] = $this->merchantId;
  201. $now = time();
  202. $expireTime = $now + 1800;//订单30分钟后过期
  203. $post['createTime'] = date("Y-m-d H:i:s", $now);
  204. $post['deadline'] = $expireTime;
  205. if (!empty($couponId)) {
  206. $time = time();
  207. $coupon = CouponService::getById($couponId);
  208. if ($coupon['deadline'] <= $time) {
  209. util::fail('优惠卷已经过期');
  210. }
  211. if ($coupon['status'] == 1) {
  212. util::fail('优惠卷已经使用');
  213. }
  214. if ($coupon['meetAmount'] > $post['prePrice']) {
  215. util::fail('消费金额不足' . $coupon['meetAmount'] . '元');
  216. }
  217. $post['actPrice'] = stringUtil::calcSub($post['prePrice'], $coupon['amount']);//浮点相减
  218. $post['discountAmount'] = $coupon['amount'];
  219. $post['discountType'] = 0;
  220. }
  221. if ($post['actPrice'] <= 0) {
  222. util::fail('消费金额太低');
  223. }
  224. if ($this->isWeixin) {
  225. $post['modPriceStatus'] = 1;//微信已经提交不能再修改价格
  226. }
  227. $post['sourceType'] = $sourceType;
  228. $post['id'] = stringUtil::generateOrderNo($this->merchantId, $this->userId);
  229. $payment = xhOrderService::add($post);
  230. $orderId = $payment['id'];
  231. if ($payWay == 'balance') {//余额支付
  232. util::success(['orderId' => $orderId]);
  233. }
  234. $name = '购买商品';
  235. $totalFee = $post['actPrice'];
  236. if ($this->isWeixin) {
  237. $userId = $post['userId'];
  238. $user = xhUserService::getById($userId);
  239. if ($user['merchantId'] != $this->merchantId) {
  240. util::fail('非法用户');
  241. }
  242. $openId = $user['openId'];
  243. $typeList = configDict::getConfig('capitalType');
  244. $capitalType = $typeList['xhOrder']['id'];
  245. $attach = 'capitalType=' . $capitalType . '&couponId=' . $couponId;//将流水类型、优惠卷传过去
  246. $weixin = Yii::getAlias("@vendor/weixin");
  247. require_once($weixin . '/lib/WxPay.Api.php');
  248. require_once($weixin . '/example/WxPay.JsApiPay.php');
  249. $input = new \WxPayUnifiedOrder();
  250. $input->SetBody($name);
  251. $input->SetOut_trade_no($orderId);
  252. $input->SetTotal_fee($totalFee * 100);
  253. $input->SetTime_start(date("YmdHis", $now));
  254. $input->SetAttach($attach);
  255. $input->SetTime_expire(date("YmdHis", $expireTime));//设置订单有效期5分钟
  256. $input->SetNotify_url($this->frontUrl . '/notice/weixin-callback/');
  257. $input->SetTrade_type("JSAPI");
  258. //服务商 代设置微信支付,要添加的参数设置
  259. if ($this->merchantExtend['generalMerchant'] == 1) {
  260. //$input->SetOpenid($openId);
  261. $input->SetSub_openid($openId);
  262. //自设置 微信支付
  263. } else {
  264. $input->SetOpenid($openId);
  265. }
  266. $wxOrder = \WxPayApi::unifiedOrder($input, 6, $this->merchantExtend);
  267. $tools = new \JsApiPay();
  268. $jsApiParameters = $tools->GetJsApiParameters($wxOrder, $this->merchantExtend);
  269. $newParams = json_decode($jsApiParameters, true);
  270. $newParams['orderId'] = $orderId;
  271. util::success($newParams);
  272. }
  273. util::success(['orderId' => $orderId]);
  274. }
  275. }