Pro/extend/pay/Ybf.php
2026-02-25 01:50:31 +08:00

384 lines
12 KiB
PHP

<?php
namespace pay;
use think\Cache;
use \think\Controller;
use think\Db;
class Ybf{
public function __construct()
{
$this->getConfig();
}
/**
* 获取配置信息
*/
private function getConfig()
{
// 支付地址
$this->domain = YBF_PAYMENT_GATEWAY;
// "https://test-ybf-wallet-api.dcops.cc/wallet-api"; //测试
// "https://wallet-api.yibifu.net/wallet-api"; // 正式
// 参数配置
$config = Db::name('pay_channel')->where('key','YBF')->value('value');
$config = json_decode($config,true);
$this->config = $config;
}
/**
* 参数加密
* @param $params
* @return false|string
*/
private function encryptData($params)
{
$str = json_encode($params,320);
$encryptData = base64_encode(openssl_encrypt($str,"AES-128-CBC",$this->config['aesKey'],OPENSSL_RAW_DATA,$this->config['aesKey']));
return $encryptData;
}
private function decryptData($data)
{
$data = openssl_decrypt(base64_decode($data),"AES-128-CBC",$this->config['aesKey'],OPENSSL_RAW_DATA,$this->config['aesKey']);
$data = json_decode($data,true);
return $data;
}
/**
* 生成签名
* @param $params
* @return false|string
*/
private function getSign($params)
{
$str = json_encode($params,320);
$str .= $this->config['md5Key'];
$sign = hash('sha256',$str);
return $sign;
}
/**
* 设置参数
* @param $params
* @return array
*/
private function setParams($params)
{
$data = [
'merchantCode' => $this->config['merchantCode'],
'params' => $this->encryptData($params,320),
];
$data['signature'] = $this->getSign($params,1);
return json_encode($data);
}
/**
* 设置提现验证Token
* @param $orderNo
* @return mixed
*/
private function setWithdrawToken($orderNo)
{
$token = createOrderNo('tk');
$key = "ybf_token_".$orderNo;
Cache::set($key,$token,180);
return $token;
}
/**
* 获取提现验证Token
* @param $orderNo
* @return mixed
*/
private function getWithdrawToken($orderNo)
{
$key = "ybf_token_".$orderNo;
$token = Cache::get($key);
return $token;
}
/**
* 设置返回结果
* @param $result
* @return array|mixed
*/
private function setResult($result)
{
if(!empty($result['merchantCode'])){
$data = $this->decryptData($result['params']);
$sign = $this->getSign($data);
if($sign == $result['signature']){
return $data;
}else{
return [
'code' => 0,
'data' => $result,
'msg' => '签名错误',
];
}
}else{
return [
'code' => 0,
'data' => $result,
'msg' => '请求错误',
];
}
}
/**
* 充值
* @return mixed
*/
/**
* 充值
* @param $orderNo
* @param $amount
* @return mixed
*/
public function recharge($orderNo,$amount,$currency=0,$coinType=0)
{
$key = '/depositRequest';
$requestUrl = $this->domain . $key;
$params = [
"amount"=> $amount,
"callBackUrl"=> $this->config['callBackUrl'],
"cardholderName"=> "",
"coinType"=> $coinType ?: "2",
"currency"=> $currency ?: '1',
"depositOrderId"=> $orderNo,
"merchantCode"=> '',
"merchantId"=> '',
"payType"=> "2",
"paymentType"=> "1",
"remark"=> "",
"returnUrl"=> $this->config['returnUrl'],
"telephone"=> $this->config['telephone'],
"timestamp"=> time(),
"userCode"=> $this->config['userCode']
];
$params = $this->setParams($params);
$header = ['content-type:application/json'];
addLogToFile('发送报文:'.json_encode($params),'ybf_curl','ybf');
$result = httpPost($requestUrl,$params,$header);
addLogToFile('返回结果:'.json_encode($result),'ybf_curl','ybf');
return $this->setResult($result);
}
/**
* 提币转账接口
* @param $orderNo
* @param $walletAddress
* @param $amount
* @return array|mixed
*/
public function withdraw($orderNo,$walletAddress,$amount)
{
$key = '/withdrawRequest';
$requestUrl = $this->domain . $key;
$params = [
"amount"=> $amount,
"callBackUrl"=> $this->config['callBackUrl'],
"callToken"=> $this->setWithdrawToken($orderNo),
"currency"=> '1',
"merchantCode"=> '',
"merchantId"=> '',
"remark"=> "",
"timestamp"=> time(),
"userCode"=> $this->config['userCode'],
"walletAddress" => $walletAddress,
"withdrawOrderId" => $orderNo,
"withdrawQueryUrl" => $this->config['withdrawQueryUrl'],
];
$params = $this->setParams($params);
$header = ['content-type:application/json'];
addLogToFile('发送报文:'.json_encode($params),'ybf_callback','ybf');
$result = httpPost($requestUrl,$params,$header);
addLogToFile('返回结果:'.json_encode($result),'ybf_callback','ybf');
return $this->setResult($result);
}
/**
* 回调
* @param $result
* @return string|void
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function callback($result,$logId=0)
{
$result = $this->setResult($result);
if($result['code'] == 200){
// 充值回调
$orderNo = $result['data']['depositOrderId'] ?? '';
if($orderNo){
if($logId) Db::name('pay_callback_log')->where('id',$logId)->update(['unique_no'=>$orderNo]);
return $this->recharge_callback($result);
}
// 提现回调
$orderNo = $result['data']['withdrawOrderId'] ?? '';
if($orderNo){
if($logId) Db::name('pay_callback_log')->where('id',$logId)->update(['unique_no'=>$orderNo]);
return $this->withdraw_callback($result);
}
}
}
/**
* 充值回调
* @param $result
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
private function recharge_callback($result)
{
if($result['code'] == 200){
$data = $result['data'];
$payTime = intval($result['timestamp']/1000);
$order = Db::name('user_recharge')->where('order_no',$data['depositOrderId'])->find();
if($order && $order['status'] == "WAIT"){
if($data['orderStatus'] == 1){
Db::startTrans();
// 用户上分
$userId = $order['user_id'];
$amount = $data['settlementAmount'];
$user = Db::name('user')->where('id',$userId)->lock(true)->find();
// 计算兑换比率
$system = Db::name('system')->find();
$rechargeMoney = empty($system['recharge_money']) ? 100 : $system['recharge_money'];
$money = $amount*($rechargeMoney/100);
// 上分
$userMoney = $user['money'];
$moneyAfter = $user['money'] + $money;
$res = Db::name('user')->where('id',$userId)->update([
'money' => $moneyAfter,
'last_recharge' => $money,
'last_recharge_time' => time(),
]);
if(!$res){
Db::rollback();
return;
}
// 确认成功
$updateData = [
'status' => 'SUCCESS',
'pay_time' => $payTime,
'out_trade_no' => $data['transactionId'],
'from_addr' => $data['fromAddress'],
'amount' => $amount,
'money' => $money,
'old_money' => $userMoney,
'new_money' => $moneyAfter,
];
$res = Db::name('user_recharge')->where('id',$order['id'])->update($updateData);
if(!$res){
Db::rollback();
return;
}
Db::commit();
return 'success';
}else if($order['orderStatus'] == 9){
// 确认失败
Db::name('user_recharge')->where('id',$order['id'])->update(['status' => 'FAIL','pay_time' => $payTime]);
}
}
}
}
private function withdraw_callback($result)
{
if($result['code'] == 200) {
$data = $result['data'];
$payTime = intval($result['timestamp'] / 1000);
$orderNo = $data['withdrawOrderId'];
$order = Db::name('user_withdraw')->where('order_no',$orderNo)->find();
if($order && $order['status'] == "AGREE"){
if($data['orderStatus'] == 1){
$amount = $data['amount']+$data['fee'];
if($amount == $order['amount']){
// 确认成功
$updateData = [
'status' => 'SUCCESS',
'pay_time' => $payTime,
'out_trade_no' => $data['transactionId'],
'from_address' => $data['fromAddress']
];
$res = Db::name('user_withdraw')->where('id',$order['id'])->update($updateData);
if(!$res){
return;
}
return 'success';
}
}else if($data['orderStatus'] == 9){
// 确认失败
Db::name('user_withdraw')->where('id',$order['id'])->update(['status' => 'FAIL','pay_time' => $payTime]);
}
}
}
}
/**
* 提现反查
* @param $data
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function withdraw_query($data)
{
$orderNo = $data['orderNo'];
$key = $this->getWithdrawToken($orderNo);
if($key){
$str = 'merchantId='.$data['merchantId'];
$str .= '&money='.$data['money'];
$str .= '&orderNo='.$data['orderNo'];
$str .= '&target='.$data['target'];
$str .= '&time='.$data['time'];
$str .= '&key='.$key;
$sign = md5($str);
if($sign == $data['sign']){
$order = Db::name('user_withdraw')->where(['order_no' => $orderNo, 'status' => 'AGREE'])->find();
if($order && $order['amount'] == $data['money']){
$result = [
'code' => 200,
'msg' => '该订单存在,验证通过',
'status' => 1,
];
}
}
}
if(empty($result)){
$result = [
'code' => 200,
'msg' => '该订单不存在,请勿出款,请联系客服核实',
'status' => 0,
];
}
return $result;
}
}