2026-05-29 19:54:56 +08:00

291 lines
11 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
/**
* Created by PhpStorm.
* User: zn
* Date: 2017/8/9
* Time: 11:51
*/
namespace common\modules\qixunpay;
use common\modules\achievement\AchievementUtil;
use common\modules\card\CardUtil;
use common\models\User;
use common\services\UserService;
use common\modules\rebate\RebateUtil;
use common\modules\card\vo\Card;
use common\modules\dailytask\DailyTaskUtil;
use common\modules\qixunpay\vo\Pay;
use common\modules\safe\SafeUtil;
use common\modules\systemlog\SystemLogUtil;
use common\modules\vip\VipUtil;
use common\services\GameConfigServices;
use common\services\ItemServices;
use common\services\ResultStatusServices;
use common\services\StatusException;
use common\utils\MoneyUtil;
use common\utils\RedisKeyUtil;
use common\utils\YiiComponentUtil;
use Yii;
class PayUtil
{
const PAY_STATUS_WAIT = 0;//等待支付
const PAY_STATUS_COMPLETE = 1;//支付成功
const PAY_STATUS_FAIL = 2;//支付失败
const PAY_STATUS_LIST = [
self::PAY_STATUS_WAIT,
self::PAY_STATUS_COMPLETE,
self::PAY_STATUS_FAIL,
];
const PAY_TYPE_WX_INSIDE = 0;//微信内支付
const PAY_TYPE_WX_SCAN = 1;//微信扫码支付
const PAY_TYPE_LIST = [
self::PAY_TYPE_WX_INSIDE,
self::PAY_TYPE_WX_SCAN,
];
public static function pay($userID, $rmb, $gem, $payType, $configID, $configType = 0)
{
$rmb = (float)$rmb;
$gem = (int)$gem;
if (empty($userID) || $rmb <= 0 || !in_array($payType, self::PAY_TYPE_LIST))
throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
return SafeUtil::dbOperate(function ($userID, $rmb, $gem, $payType, $configID, $configType) {
if ($configType == 1) {
//周卡月卡
$card = Card::findByUserIDAndItemID($userID, $configID);
if (!empty($card) && $card->count > 0) throw new StatusException(ResultStatusServices::RS_ITEM_CAN_NOT_BY_MORE);
$config = GameConfigServices::getParamByPath('card.' . $configID);
if (empty($config)) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
} elseif($configType == 0) {
if ($gem <= 0) throw new StatusException(ResultStatusServices::RS_PARAM_ERROR);
}else{
}
$orderID = OrderCreater::createOrderID();
$payData = new Pay();
$payData->user_id = $userID;
$payData->order_id = $orderID;
$payData->price = $rmb;
$payData->gem = $gem;
$payData->status = self::PAY_STATUS_WAIT;
$payData->config_id = $configID;
$payData->config_type = $configType;
if (!$payData->save()) throw new StatusException(ResultStatusServices::RS_SAVE_DB_ERROR);
if ($configType == 0) {
$orderConfig = [
// 'trade_type' => 'JSAPI', // JSAPINATIVEAPP...
'body' => '购买钻石',
'detail' => sprintf('购买%d个钻石', $gem),
'out_trade_no' => $orderID,
'total_fee' => $rmb * 100, // 单位:分
// 'openid' => $openID, // trade_type=JSAPI此参数必传用户在商户appid下的唯一标识
];
}
elseif ($configType == 1)
{
$orderConfig = [
// 'trade_type' => 'JSAPI', // JSAPINATIVEAPP...
'body' => "购买{$config['name']}",
'detail' => "购买{$config['name']}",
'out_trade_no' => $orderID,
'total_fee' => $rmb * 100, // 单位:分
// 'openid' => $openID, // trade_type=JSAPI此参数必传用户在商户appid下的唯一标识
];
}else{
$orderConfig = [
// 'trade_type' => 'JSAPI', // JSAPINATIVEAPP...
'body' => "激活账号",
'detail' => "激活账号",
'out_trade_no' => $orderID,
'total_fee' => $rmb * 100, // 单位:分
// 'openid' => $openID, // trade_type=JSAPI此参数必传用户在商户appid下的唯一标识
];
}
return [$rmb, $orderID];
//下面是之前配置微信支付的
if ($payType == self::PAY_TYPE_WX_INSIDE) {
$wxUser = YiiComponentUtil::easywechat()->getUserInfo();
$orderConfig['trade_type'] = 'JSAPI';
$orderConfig['openid'] = $wxUser->openID;
}
if ($payType == self::PAY_TYPE_WX_SCAN) {
$orderConfig['trade_type'] = 'NATIVE';
}
$result = YiiComponentUtil::easywechat()->payApp()->order->unify($orderConfig);
Yii::warning("微信支付 " . json_encode($result));
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
$prepayId = $result['prepay_id'];
// $scanURL = $result['code_url'];
// $json = YiiComponentUtil::easywechat()->payment->configForPayment($prepayId);
$insidePayConfig = null;
if ($payType == self::PAY_TYPE_WX_INSIDE) $insidePayConfig = YiiComponentUtil::easywechat()->payApp()->jssdk->sdkConfig($prepayId);
return [$insidePayConfig, $orderID];
}
throw new StatusException(ResultStatusServices::RS_WX_PAY_ERROR, $result);
}, [$userID, $rmb, $gem, $payType, $configID, $configType]);
}
public static function payCallBack()
{
//设置时区
date_default_timezone_set('Asia/Shanghai');
//接受ISPAY通知返回的支付渠道
$Array['payChannel'] = $_POST['payChannel']; //(支付通道)
//接受ISPAY通知返回的支付金额
$Array['Money'] = $_POST['Money']; //(单位分)
//接受ISPAY通知返回的订单号
$Array['orderNumber'] = $_POST['orderNumber']; //(商户订单号)
//接受ISPAY通知返回的附加数据
$Array['attachData'] = $_POST['attachData']; //(商户自定义附加数据)
//接受ISPAY通知返回的回调签名
$Array['callbackSign'] = $_POST['callbackSign']; //(详情查看ISPAY开发文档)
file_put_contents('111111.txt',json_encode($Array));
//回调签名校验
//接受ISPAY通知返回的支付渠道
$Array['payChannel'] = 'alipay'; //(支付通道)
//接受ISPAY通知返回的支付金额
$Array['Money'] = '100'; //(单位分)
//接受ISPAY通知返回的订单号
$Array['orderNumber'] = '20190411193452562273'; //(商户订单号)
//接受ISPAY通知返回的附加数据
$Array['attachData'] = '10957'; //(商户自定义附加数据)
//接受ISPAY通知返回的回调签名
$Array['callbackSign'] = '8e8337472ca08baafe354f6969f7be58'; //(详情查看ISPAY开发文档)
if(self::callbackSignCheck($Array)){
$payData = Pay::findByOrderID($_POST['attachData']);
if (empty($payData)) return '订单不存在';
if ($payData->status != PayUtil::PAY_STATUS_WAIT) return '已经支付过';
$payData->pay_from=$_POST['payChannel'];
$payData->status = PayUtil::PAY_STATUS_COMPLETE;
if (!$payData->save()) return '保存失败';
echo "SUCCESS";
return self::doOrder($orderID);
}else{
echo "callbackSign fail!";
exit;
}
exit;
Yii::warning('支付回调');
Yii::warning(Yii::$app->request->post());
$response = YiiComponentUtil::easywechat()->payApp()->handlePaidNotify(function ($message, $fail) {
$orderID = $message['out_trade_no'];
Yii::warning('支付返回订单ID:' . $orderID);
// 用户是否支付成功
if ($message['result_code'] === 'SUCCESS') {
// 不是已经支付状态则修改为已经支付状态
return self::doOrder($orderID);
} else { // 用户支付失败
$payData = Pay::findByOrderID($orderID);
if (empty($payData)) return '订单不存在';
if ($payData->status != PayUtil::PAY_STATUS_WAIT) return '已经支付过';
$payData->status = PayUtil::PAY_STATUS_FAIL;
if (!$payData->save()) return '保存失败';
}
});
$response->send();
}
/**
* 查询订单
* @param $orderID
* @return mixed
* @throws StatusException
*/
public static function checkOrder($orderID)
{
$r = YiiComponentUtil::easywechat()->payApp()->order->queryByOutTradeNumber($orderID);
Yii::warning('支付订单查询:' . json_encode($r));
if ($r['return_code'] == 'SUCCESS' && $r['result_code'] == 'SUCCESS' && $r['trade_state'] == 'SUCCESS') {
//支付成功
return self::doOrder($orderID);
}
throw new StatusException(ResultStatusServices::RS_WX_PAY_ERROR, $r);
}
private static function callbackSignCheck($Array) {
if (self::Sign($Array) == $Array['callbackSign']) {
return true;
} else {
return false;
}
}
private static function Sign($Array) {
ksort($Array);
$stringA = "";
foreach ($Array as $k => $v) {
if ($k != "Sign" && $k != "callbackSign") {
$stringA .= $v;
}
}
$stringSignTemp = $stringA . 'efd7838b44c72e8a3633498581e32841';
$Sign = md5($stringSignTemp);
return $Sign;
}
private static function doOrder($orderID)
{
//支付成功
return SafeUtil::dbOperate(function ($orderID) {
return SafeUtil::redisLockOperate(function ($orderID) {
$payData = Pay::findByOrderID($orderID);
if ($payData->config_type == 0) {
$log = SystemLogUtil::get($payData->user_id, SystemLogUtil::TYPE_GEM, $payData->gem, 0, SystemLogUtil::FROM_TYPE_PAYPAL, ['order_id' => $orderID]);
MoneyUtil::checkAndModifyRes($payData->user_id, true, $payData->gem, ItemServices::ITEM_TYPE2_GEM, $log);
VipUtil::addVipExp($payData->user_id, $payData->gem);
} elseif ($payData->config_type == 1) {
//周卡月卡
CardUtil::buyCard($payData->user_id, $payData->config_id);
}else{
$userDbData = User::findById($payData->user_id);
$userDbData->isjihuo = 1;
//保存
$userDbData->save(true, ['isjihuo']);
}
//分销返点
//RebateUtil::addRebate($payData->user_id, $payData->price, RebateUtil::TYPE_BUY);
//成就
AchievementUtil::addCount($payData->user_id, AchievementUtil::ID_PAY_COUNT, 1);
DailyTaskUtil::addTaskCount($payData->user_id, DailyTaskUtil::TYPE_PAY_GEM, null, 1);
return true;
}, [$orderID], RedisKeyUtil::lockPayOrder($orderID));
}, [$orderID]);
}
}