cmbYouku_Api/app/service/CmbService.php

299 lines
10 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\service;
use app\exception\LogicException;
use app\model\Order;
use app\model\Product;
use app\model\Sign;
use app\model\User;
use app\service\util\BlueBrothersClientUtil;
use app\service\util\CmbLifeUtils;
use app\service\util\SmsUtil;
use app\util\CmbHttpUtils;
use app\util\StringUtil;
use think\facade\Cache;
use think\facade\Log;
class CmbService extends BaseService
{
/**
* 生成登录授权协议
* @param $params
* @return string
* @throws LogicException
*/
public static function genApprovalProtocol($params): string
{
$callback = $params['callback'] ?? '';
$funcName = 'approval';
$params = [
'clientType' => '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;
}
}