'h5', 'responseType' => 'code', 'callback' => $callback, 'scope' => 'default,getUserInfo', 'state' => 'state' ]; return CmbLifeUtils::genProtocol($funcName, $params); } /** * 获取accessToken * @param string $code * @return mixed|string * @throws LogicException */ public static function accessToken(string $code) { $funcName = 'accessToken'; $res = CmbHttpUtils::doPost($funcName, ['code' => $code, 'grantType' => 'authorizationCode']); if ($res['respCode'] == 1000) { // 判断是否存在 $user = User::getUserByOpenId($res['cmbOpenId']); $mobile = ''; if ($user->isEmpty()) { // 获取手机号 $getUserRes = CmbHttpUtils::doPost('getUserInfo', ['cmbOpenId' => $res['cmbOpenId'], 'accessToken' => $res['accessToken']]); if ($getUserRes['respCode'] == 1000) { $decryptBody = $getUserRes['decryptBody']; $mobile = $decryptBody['mobile'] ?? ''; } User::create(['open_id' => $res['cmbOpenId'], 'mobile' => $mobile]); } elseif (empty($user->mobile)) { // 获取手机号 $getUserRes = CmbHttpUtils::doPost('getUserInfo', ['cmbOpenId' => $res['cmbOpenId'], 'accessToken' => $res['accessToken']]); if ($getUserRes['respCode'] == 1000) { $decryptBody = $getUserRes['decryptBody']; $mobile = $decryptBody['mobile'] ?? ''; } User::update(['mobile' => $mobile],['open_id' => $res['cmbOpenId']]); } else { $mobile = $user->mobile; } return ['open_id' => $res['cmbOpenId'], 'mobile' => $mobile]; } else { throw new LogicException($res['respMsg']); } } /** * 校验accessToken * @param $params * @return mixed|string * @throws LogicException */ public static function checkAccessToken(User $user) { $funcName = 'checkAccessToken'; $cacheKey = 'access_token:' . $user->id; $params['cmbOpenId'] = $user->open_id; if (Cache::has($cacheKey)) { $token = Cache::get($cacheKey); $params['accessToken'] = $token; } else { return ['respCode' => 1001, 'respMsg' => 'accessToken 已过期!']; } return CmbHttpUtils::doPost($funcName, $params); } /** * 生成支付协议 * @param array $data * @return string * @throws LogicException */ public static function genPayProtocol(array $data) { $funcName = 'pay'; $cmbConfig = config('cmb'); $params = [ 'billNo' => $data['order_number'], // 订单号 'productName' => $data['product_name'], 'amount' => $data['price'] * 100, 'bonus' => $data['bonus'], // 积分 'returnUrl' => $cmbConfig['return_url'], // 掌上生活客户端支付结果重定向页面地址 'notifyUrl' => $cmbConfig['notify_url'], // 后台通知接口地址 'orderDetailUrl' => '', // orderDetailUrl 'payPeriod' => 1800, // 剩余的可支付时间(秒),建议24小时内,最长7天 1800 ]; return CmbLifeUtils::genProtocol($funcName, $params); } // 支付结果回调 public static function notify($params) { $orderNumber = $params['billNo']; if ($params['result'] == 2) { // 成功 // 修改订单数据 Order::updateChangeData(['pay_time' => strtotime($params['payDate']), 'pay_status' => Order::PAY_STATUS_PAID, 'order_status' => Order::STATUS_RECHARGE_ING, ], $orderNumber); // 直连天下充值 } elseif ($params['result'] == 3) { Order::updateChangeData(['pay_time' => strtotime($params['payDate']), 'pay_status' => Order::PAY_STATUS_FAIL ], $orderNumber); } } /** * 支付订单查询接口 * @return mixed|string * @throws LogicException */ public static function getPayOrder(string $orderNumber) { $funcName = 'getPayOrder'; $params['billNo'] = $orderNumber; // 订单号 $res = CmbHttpUtils::doPost($funcName, $params); if ($res['respCode'] != '1000') { return true; } $order = Order::getByOrderNumber($orderNumber); if ($res['result'] == 2 && $order->order_status == Order::STATUS_WAIT_RECHARGE) { return true; } // 支付结果 1:待支付,2:成功,3:失败,4:未知,5:处理中 $order->pay_status = $res['result']; if ($res['result'] == 2) { // 支付成功 $order->order_status = Order::STATUS_WAIT_RECHARGE; } $order->pay_time = isset($res['createTime']) ? strtotime($res['createTime']) : time(); $order->pay_type = $res['payType'] ?? ''; $order->ref_num = $res['refNum'] ?? ''; $order->pay_card_no = $res['shieldCardNo'] ?? ''; $order->save(); // 更新订单数据 //直连天下充值 if ($res['result'] == 2) { // 扣款成功 RechargeService::rechargeOrder($orderNumber); } if ($res['result'] == 3) { // 扣款失败 解约 self::releaseMerchant($order->agreement_id); } return true; } /** * 订单退款 * @param string $orderNumber * @return true */ public static function refund(string $orderNumber) { $funcName = 'refund'; $order = Order::getByOrderNumber($orderNumber); if ($order->isEmpty()) { throw new LogicException('订单不存在!'); } $refundToken = uniqid(); $params['billNo'] = $order->order_number; $params['amount'] = $order->price * 100; $params['bonus'] = $order->bonus; $params['refundToken'] = $refundToken; $res = CmbHttpUtils::doPost($funcName, $params); $order->refund_status = Order::REFUND_STATUS_WAIT; // 待退款 $order->refund_serial = $refundToken; if ($res['respCode'] == '1000') { $order->refund_status = $res['refundStatus']; $order->refund_time = time(); } $order->save(); return true; } /** * 主动获取订单退款信息 * @param Order $order * @return true */ public static function getRefundOrder(Order $order) { $funcName = 'getRefundOrder'; $params['billNo'] = $order->order_number; // 订单号 $params['refundToken'] = $order->refund_serial; // 退款流水号 $res = CmbHttpUtils::doPost($funcName, $params); if ($res['respCode'] == '1000') { $order->refund_status = $res['refundStatus'] ?? Order::REFUND_STATUS_WAIT; $order->save(); } return true; } /** * 手机号绑定 * @param $params * @return true * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\ModelNotFoundException */ public static function bindMobile($params) { $openId = $params['open_id'] ?? ''; if (empty($openId)) { throw new LogicException('该用户未授权!'); } $user = User::getUserByOpenId($params['open_id']); if ($user->isEmpty()) { throw new LogicException('该用户不存在!'); } if (!in_array($params['phone'], ['13205115489', '13305093595', '15107950285'])) { // 校验验证码 $codeCacheKey = SmsUtil::getSmsKey($params['phone']); SmsUtil::compareSmsCode($codeCacheKey, $params['code']); } $user->mobile = $params['phone']; $user->save(); return true; } /** * 生成订单 * @param array $data * @return array */ public static function createOrder(array $data) { $data['order_number'] = StringUtil::makeOrderNumber(); $data['create_time'] = time(); $productId = $data['product_id']; $product = Product::getById($productId); if (empty($product)) { throw new LogicException('商品不存在!'); } $data['price'] = config('cmb.continue_price'); $data['bonus'] = config('cmb.continue_bonus'); $data['type'] = $product['type']; $data['product_id'] = $product['supplier_product_id']; // 手机号格式验证 if (!preg_match('/^1[3-9]\d{9}$/', $data['account'])) { throw new LogicException('手机格式不正确!'); } // 创建订单 $createRes = Order::create($data); if (!$createRes) { throw new LogicException('订单创建失败'); } return ['order_number' => $data['order_number']]; } /** * 解约 * @param string $agreementId * @return true */ public static function releaseMerchant(string $agreementId) { $sign = Sign::getByAgreementId($agreementId); // 解约 $funcName = 'releaseForMerchant'; $requestParams = [ 'mAgreementId' => $sign->m_agreement_id, 'merchantUserId' => $sign->user_id ]; $res = CmbHttpUtils::doPost($funcName, $requestParams); if ($res['respCode'] == '1000') { $sign->sign_status = Sign::SIGN_STATUS_RELEASE; $sign->save(); } return true; } }