PayController.php 12 KB

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