cmbYouku_Api/app/service/CmbService.php

299 lines
10 KiB
PHP
Raw Normal View History

2024-07-01 15:57:07 +08:00
<?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;
}
}