28 changed files with 857 additions and 355 deletions
-
97app/Constants/v3/ErrorCode.php
-
10app/Constants/v3/LogLabel.php
-
5app/Constants/v3/SsdbKeys.php
-
5app/Constants/v3/Tabs.php
-
6app/Controller/v3/OrderOnlineController.php
-
48app/Controller/v3/PaymentController.php
-
2app/Exception/ErrorCodeException.php
-
2app/Exception/Handler/ErrorCodeExceptionHandler.php
-
25app/Listener/ValidatorFactoryResolvedListener.php
-
2app/Model/v3/Coupon.php
-
4app/Model/v3/CouponRec.php
-
16app/Model/v3/CouponUse.php
-
5app/Model/v3/OrderGoods.php
-
35app/Model/v3/OrderMain.php
-
4app/Request/v3/OrderOnlineRequest.php
-
78app/Service/v3/Implementations/CouponRecService.php
-
17app/Service/v3/Implementations/CouponService.php
-
102app/Service/v3/Implementations/GoodsActivityService.php
-
11app/Service/v3/Implementations/GoodsService.php
-
532app/Service/v3/Implementations/OrderOnlineService.php
-
137app/Service/v3/Implementations/PaymentService.php
-
4app/Service/v3/Implementations/ShopCartUpdateService.php
-
11app/Service/v3/Interfaces/CouponRecServiceInterface.php
-
3app/Service/v3/Interfaces/GoodsActivityServiceInterface.php
-
2app/Service/v3/Interfaces/OrderOnlineServiceInterface.php
-
10app/Service/v3/Interfaces/PaymentServiceInterface.php
-
2config/autoload/dependencies.php
-
1config/routes.php
@ -0,0 +1,48 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Controller\v3; |
||||
|
|
||||
|
use App\Controller\BaseController; |
||||
|
use App\Model\v3\OrderMain; |
||||
|
use App\Service\v3\Interfaces\PaymentServiceInterface; |
||||
|
use Hyperf\Di\Annotation\Inject; |
||||
|
use Hyperf\Validation\ValidationException; |
||||
|
|
||||
|
class PaymentController extends BaseController |
||||
|
{ |
||||
|
|
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var PaymentServiceInterface |
||||
|
*/ |
||||
|
protected $paymentService; |
||||
|
|
||||
|
/** |
||||
|
* 微信线上订单支付 |
||||
|
* 主要用户待付款订单中的付款操作 |
||||
|
*/ |
||||
|
public function wechatpayOnline() |
||||
|
{ |
||||
|
$validator = $this->validationFactory->make( |
||||
|
$this->request->all(), |
||||
|
[ |
||||
|
'global_order_id' => 'required|nonempty', |
||||
|
'user_id' => 'required|nonempty', |
||||
|
], |
||||
|
[ |
||||
|
'global_order_id.*' => '订单号错误' |
||||
|
] |
||||
|
); |
||||
|
|
||||
|
if ($validator->fails()) { |
||||
|
throw new ValidationException($validator); |
||||
|
} |
||||
|
|
||||
|
$params = $validator->validated(); |
||||
|
$orderMain = OrderMain::query()->select('global_order_id', 'money', 'user_id') |
||||
|
->where(['global_order_id' => $params['global_order_id']])->first(); |
||||
|
$parameters = $this->paymentService->do($orderMain->global_order_id, $orderMain->money, $orderMain->user_id); |
||||
|
|
||||
|
return $this->success(['parameters' => $parameters]); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,16 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Model\v3; |
||||
|
|
||||
|
use App\Model\Model; |
||||
|
|
||||
|
class CouponUse extends Model |
||||
|
{ |
||||
|
|
||||
|
protected $table = 'lanzu_coupon_use'; |
||||
|
|
||||
|
public function coupon() |
||||
|
{ |
||||
|
return $this->hasOne(Coupon::class,'id','coupon_id'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,78 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Implementations; |
||||
|
|
||||
|
use App\Model\ShopCar; |
||||
|
use App\Model\v3\Coupon; |
||||
|
use App\Model\v3\CouponRec; |
||||
|
use App\Service\v3\Interfaces\CouponRecServiceInterface; |
||||
|
use Hyperf\DbConnection\Db; |
||||
|
use Hyperf\Redis\Redis; |
||||
|
use Hyperf\Utils\ApplicationContext; |
||||
|
|
||||
|
class CouponRecService implements CouponRecServiceInterface |
||||
|
{ |
||||
|
|
||||
|
public function do() |
||||
|
{ |
||||
|
// TODO: Implement do() method.
|
||||
|
} |
||||
|
|
||||
|
public function check() |
||||
|
{ |
||||
|
// TODO: Implement check() method.
|
||||
|
} |
||||
|
|
||||
|
public function undo() |
||||
|
{ |
||||
|
// TODO: Implement undo() method.
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取当前订单可使用的优惠券 |
||||
|
* @param $totalAmount |
||||
|
* @param $userId |
||||
|
* @param $marketId |
||||
|
* @param $type |
||||
|
* @param $storeTypeIds |
||||
|
*/ |
||||
|
public function allForOrderOlAvailable($totalAmount, $userId, $marketId, $type, $storeTypeIds = []) |
||||
|
{ |
||||
|
// 用户今日使用过的优惠券
|
||||
|
$redis = ApplicationContext::getContainer()->get(Redis::class); |
||||
|
$couponTodayUsedIds = $redis->sMembers('coupon_'.date('Ymd').'_used_'.$userId); |
||||
|
$currentTime = time(); |
||||
|
|
||||
|
$builder = Db::table('lanzu_coupon_receive as receive') |
||||
|
->join('lanzu_coupon as coupon', 'coupon.id', '=', 'receive.coupon_id', 'inner'); |
||||
|
|
||||
|
if (is_array($couponTodayUsedIds)&&!empty($couponTodayUsedIds)) { |
||||
|
$builder->whereNotIn('coupon.id', $couponTodayUsedIds); |
||||
|
} |
||||
|
|
||||
|
foreach ($storeTypeIds as $key => &$item) { |
||||
|
$item = (string)$item; |
||||
|
} |
||||
|
|
||||
|
if (!empty($storeTypeIds)) { |
||||
|
$builder->whereJsonContains('coupon.storetype_ids', $storeTypeIds); |
||||
|
} |
||||
|
|
||||
|
$builder->where(['receive.user_id' => $userId]) |
||||
|
->whereIn('receive.status', [0,1]) |
||||
|
->where('receive.number_remain', '>', 0) |
||||
|
->whereIn('coupon.type', [1,$type]) |
||||
|
->where('coupon.full_amount', '<=', $totalAmount) |
||||
|
->where('coupon.usable_start_time', '<=', $currentTime) |
||||
|
->where('coupon.usable_end_time', '>=', $currentTime) |
||||
|
->where('coupon.usable_number', '<=', Db::raw('receive.number_remain')); |
||||
|
|
||||
|
if ($marketId) { |
||||
|
$builder->whereJsonContains('coupon.market_ids', [(string)$marketId]); |
||||
|
} |
||||
|
|
||||
|
return $builder->orderByRaw('coupon.discounts DESC, coupon.full_amount DESC') |
||||
|
->get() |
||||
|
->toArray(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,137 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Implementations; |
||||
|
|
||||
|
use App\Commons\Log; |
||||
|
use App\Constants\v3\ErrorCode; |
||||
|
use App\Constants\v3\LogLabel; |
||||
|
use App\Constants\v3\OrderState; |
||||
|
use App\Exception\ErrorCodeException; |
||||
|
use App\Model\v3\OrderMain; |
||||
|
use App\Model\v3\User; |
||||
|
use App\Service\v3\Interfaces\GoodsActivityServiceInterface; |
||||
|
use App\Service\v3\Interfaces\PaymentServiceInterface; |
||||
|
use EasyWeChat\Factory; |
||||
|
use Hyperf\Guzzle\CoroutineHandler; |
||||
|
use Hyperf\Di\Annotation\Inject; |
||||
|
|
||||
|
class PaymentService implements PaymentServiceInterface |
||||
|
{ |
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var Log |
||||
|
*/ |
||||
|
protected $log; |
||||
|
|
||||
|
/** |
||||
|
* @Inject |
||||
|
* @var GoodsActivityServiceInterface |
||||
|
*/ |
||||
|
protected $goodsActivityService; |
||||
|
|
||||
|
public function do($globalOrderId, $money, $userId) |
||||
|
{ |
||||
|
|
||||
|
try { |
||||
|
|
||||
|
$config = config('wxpay'); |
||||
|
$app = Factory::payment($config); |
||||
|
$app['guzzle_handler'] = CoroutineHandler::class; |
||||
|
|
||||
|
// 待支付的,未超时(15min,900sec)的订单
|
||||
|
$orderMain = OrderMain::query() |
||||
|
->where(['state' => OrderState::UNPAID, 'global_order_id' => $globalOrderId, 'user_id' => $userId]) |
||||
|
->where('created_at', '>=', (time()-900)) |
||||
|
->first(); |
||||
|
|
||||
|
if (empty($orderMain)) { |
||||
|
throw new ErrorCodeException(ErrorCode::ORDER_NOT_AVAILABLE, '[支付订单号]'.$globalOrderId); |
||||
|
} |
||||
|
|
||||
|
$payMoney = bcmul((string)$orderMain->money, 100, 0); |
||||
|
if (env('APP_ENV') != 'prod') { |
||||
|
$payMoney = 1; |
||||
|
} |
||||
|
|
||||
|
$user = User::select('openid')->find($userId); |
||||
|
$result = $app->order->unify([ |
||||
|
'body' => '懒族生活 - 外卖下单', |
||||
|
'out_trade_no' => $orderMain->global_order_id, |
||||
|
'total_fee' => $payMoney, |
||||
|
'notify_url' => config('site_host') . '/wechat/notify/wxminionline', |
||||
|
'trade_type' => 'JSAPI', |
||||
|
'openid' => $user['openid'], |
||||
|
]); |
||||
|
|
||||
|
if ($result['return_code'] == 'FAIL') { |
||||
|
throw new ErrorCodeException(ErrorCode::PAYMENT_FAIL, '[支付失败]'.$result['return_msg']); |
||||
|
} |
||||
|
|
||||
|
// 返回支付参数给前端
|
||||
|
$parameters = [ |
||||
|
'appId' => $result['appid'], |
||||
|
'timeStamp' => '' . time() . '', |
||||
|
'nonceStr' => uniqid(), |
||||
|
'package' => 'prepay_id=' . $result['prepay_id'], |
||||
|
'signType' => 'MD5' |
||||
|
]; |
||||
|
|
||||
|
$parameters['paySign'] = $this->signture($parameters, $config['key']); |
||||
|
|
||||
|
return $parameters; |
||||
|
|
||||
|
} catch (\Exception $e) { |
||||
|
$this->log->event(LogLabel::ORDER_PAYMENT_LOG, ['payment_exception_msg' => $e->getMessage()]); |
||||
|
throw new ErrorCodeException(ErrorCode::PAYMENT_FAIL, '[支付失败]'.$e->getMessage()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public function check() |
||||
|
{ |
||||
|
// TODO: Implement check() method.
|
||||
|
} |
||||
|
|
||||
|
public function undo() |
||||
|
{ |
||||
|
// TODO: Implement undo() method.
|
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 支付参数加签 |
||||
|
* @param $parameters |
||||
|
* @param $key |
||||
|
* @return string |
||||
|
*/ |
||||
|
private function signture($parameters, $key) |
||||
|
{ |
||||
|
// 按字典序排序参数
|
||||
|
ksort($parameters); |
||||
|
|
||||
|
// http_query
|
||||
|
$queryParams = $this->http_query($parameters); |
||||
|
|
||||
|
// 加入KEY
|
||||
|
$queryParams = $queryParams . "&key=" . $key; |
||||
|
|
||||
|
// MD5加密
|
||||
|
$queryParams = md5($queryParams); |
||||
|
|
||||
|
// 字符转为大写
|
||||
|
return strtoupper($queryParams); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 参数转为http query字串 |
||||
|
* @param $parameters |
||||
|
* @return string |
||||
|
*/ |
||||
|
private function http_query($parameters) { |
||||
|
|
||||
|
$http_query = []; |
||||
|
foreach ($parameters as $key => $value) { |
||||
|
$http_query[] = $key.'='.$value; |
||||
|
} |
||||
|
|
||||
|
return implode('&', $http_query); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,11 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Interfaces; |
||||
|
|
||||
|
interface CouponRecServiceInterface |
||||
|
{ |
||||
|
public function do(); |
||||
|
public function check(); |
||||
|
public function undo(); |
||||
|
public function allForOrderOlAvailable($totalAmount,$userId,$marketId,$type,$storeTypeId); |
||||
|
} |
||||
@ -0,0 +1,10 @@ |
|||||
|
<?php |
||||
|
|
||||
|
namespace App\Service\v3\Interfaces; |
||||
|
|
||||
|
interface PaymentServiceInterface |
||||
|
{ |
||||
|
public function do($globalOrderId, $money, $userId); |
||||
|
public function check(); |
||||
|
public function undo(); |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue