初始化代码

This commit is contained in:
2025-08-11 10:22:05 +08:00
commit ebd8d85201
4206 changed files with 753018 additions and 0 deletions

View File

@@ -0,0 +1,201 @@
<?php
namespace app\common\pay;
use app\common\traits\ReturnTrait;
use app\common\yun\service\Des3Service;
use app\common\yun\util\RsaUtil;
use think\Db;
use think\Exception;
use think\facade\Log;
class Callback
{
use ReturnTrait;
public static function order()
{
$config = Conf::config();
$result = new RsaUtil($config);
$verify = $result->verify($_REQUEST);
if ($verify == false) {
Log::write('签名失败','yun_notify');
echo 'fail';
die;
}
// Log::info($_REQUEST);
// Log::info($_REQUEST['data']);
// Log::write($_REQUEST,'yun_notify');
// Log::write($_REQUEST['data'],'yun_notify');
$data_info = Des3Service::decode($_REQUEST['data'], $config->des3_key); #对业务数据进行解密
if (!isset($data_info['data'])) {
echo 'fail';
die;
}
$data = $data_info['data'];
Log::write($data,'yun_notify');
// Log::write($_REQUEST['data'],'yun_notify');
if (!isset($data['status'])) {
echo 'fail';
die;
}
// Log::info('xxxxxxx');
// Log::info($data);
//var_dump($data);
//根据回调数据中的status做一下订单状态的判断和业务逻辑处理
//若有用户钱包体系,则在下单同步返回成功时,将用户钱包进行相应金额的扣减冻结
$status = $data['status'];
switch ($status) {
case "1":
// 支付成功(对于支付宝和微信支付是最终状态,对于银行卡大部分情况是终态,小概率会出现"退汇现象",状态由"成功"变为"退汇"
// TODO 更新业务订单状态,提示用户提现成功
$redis = connectionRedis();
$key_name = "api:user:widthdraw:order_sn".$data['order_id'];
$redis_order_sn = redis_lock_exits($key_name,1,5);
if($redis_order_sn) {
$update_arr = [
'status' => 6,
'update_time' => time(),
'pay_time' => time(),
'pay_message' => $data['status_message'],
// 'pay_platform' => 1,
];
Db::name('user_withdrawal')->where(['order_sn' => $data['order_id'], 'status' => 4])->update($update_arr);
}
echo "success";
break;
case "2":
// 支付失败(最终状态)
// TODO 更新业务订单状态,提示用户提现失败,若有用户钱包体系,则需将提现金额退回至用户钱包
$redis = connectionRedis();
$key_name = "api:user:widthdraw:order_sn".$data['order_id'];
$redis_order_sn = redis_lock_exits($key_name,1,5);
$update_arr = [
'status' => 5,
'update_time' => time(),
'pay_message' => $data['status_message'],
'pay_time' => time(),
// 'pay_platform' => 1,
];
if($redis_order_sn) {
Db::startTrans();
try {
// $info = Db::name('user_withdrawal')->where(['order_sn' => $data['order_id'], 'status' => 4])->find();
$info = Db::name('user_withdrawal')->where(['order_sn' => $data['order_id']])->find();
if ($info) {
Db::name('user_withdrawal')->where(['order_sn' => $data['order_id']])->update($update_arr);
$reslut=model('admin/User')->change_user_money_by_uid($info['uid'], $info['money'], 1, 15, "代付失败,余额提现驳回:" . $info['order_sn'], $info['uid'], $info['wid']);
if ($reslut['code'] !=200 ) {
Db::rollback();
Log::write(['msg'=>'支付失败1!','msg1'=>$reslut['msg']],'yun_notify');
}
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
Log::write(['msg'=>'支付失败2!','msg1'=>$e->getMessage()],'yun_notify');
// Log::info($e->getMessage());
}
}
echo "success";
break;
case "4":
// 订单挂单(中间状态,挂单原因会在订单详细状态信息返回)
// TODO 提示用户提现中其他逻辑如若因余额不足导致的挂单可通知财务及时充值72小时内补足余额后可自动继续支付
echo "success";
break;
case "9":
// 退汇,(最终状态,银行卡渠道特有现象,会先收到"成功"回调,然后再收到"退汇"的回调一般以成功状态间隔24小时以上
// TODO 更新业务订单状态为“退汇”(失败),通知用户提现失败,建议用户更换其他银行卡提现,若有用户钱包体系,则需将提现金额退回至用户钱包
$update_arr = [
'status' => 5,
'update_time' => time(),
'pay_message' => $data['status_message'],
// 'pay_platform' => 1,
'pay_time' => time()
];
$redis = connectionRedis();
$key_name = "api:user:widthdraw:order_sn".$data['order_id'];
$redis_order_sn = redis_lock_exits($key_name,1,5);
if($redis_order_sn) {
Db::startTrans();
try {
// $info = Db::name('user_withdrawal')->where(['order_sn' => $data['order_id'], 'status' => 4])->find();
$info = Db::name('user_withdrawal')->where(['order_sn' => $data['order_id']])->find();
if ($info) {
Db::name('user_withdrawal')->where(['order_sn' => $data['order_id']])->update($update_arr);
$reslut=model('admin/User')->change_user_money_by_uid($info['uid'], $info['money'], 1, 15, "代付失败,余额提现驳回:" . $info['order_sn'], $info['uid'], $info['wid']);
if ($reslut['code'] !=200 ) {
Db::rollback();
// return ['code' => 201, 'msg' => "处理失败", 'data' => null];
}
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
Log::write(['msg'=>'退汇!','msg1'=>$e->getMessage()],'yun_notify');
// Log::info($e->getMessage());
}
}
echo "success";
break;
case "15":
// 订单取消,(最终状态,只有挂单的订单才可以取消)
// TODO 更新业务订单状态为“取消”(失败),通知用户提现失败,若有用户钱包体系,则需将提现金额退回至用户钱包
$update_arr = [
'status' => 5,
'update_time' => time(),
'pay_message' => $data['status_message'],
// 'pay_platform' => 1,
'pay_time' => time()
];
$redis = connectionRedis();
$key_name = "api:user:widthdraw:order_sn".$data['order_id'];
$redis_order_sn = redis_lock_exits($key_name,1,5);
if($redis_order_sn) {
Db::startTrans();
try {
// $info = Db::name('user_withdrawal')->where(['order_sn' => $data['order_id'], 'status' => 4])->find();
$info = Db::name('user_withdrawal')->where(['order_sn' => $data['order_id']])->find();
if ($info) {
Db::name('user_withdrawal')->where(['order_sn' => $data['order_id']])->update($update_arr);
$reslut=model('admin/User')->change_user_money_by_uid($info['uid'], $info['money'], 1, 15, "代付失败,余额提现驳回:" . $info['order_sn'], $info['uid'], $info['wid']);
if ($reslut['code'] !=200 ) {
Db::rollback();
}
}
Db::commit();
} catch (Exception $e) {
Db::rollback();
Log::write(['msg'=>'订单取消!','msg1'=>$e->getMessage()],'yun_notify');
// Log::info($e->getMessage());
}
}
echo "success";
break;
}
// echo "success"; //回写success终止本次回调
}
}

View File

@@ -0,0 +1,20 @@
<?php
namespace app\common\pay;
use app\common\yun\Config;
use app\common\yun\util\StringUtil;
class Conf
{
public static function config()
{
$config = new Config();
$config->mess = StringUtil::round(16);
$config->request_id = StringUtil::round(16);
$config->timestamp = time();
return $config;
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace app\common\pay;
use app\common\traits\ReturnTrait;
use app\common\yun\Base;
use app\common\yun\Router;
use app\common\yun\service\BaseService;
use think\facade\Log;
class GetData
{
use ReturnTrait;
static function getOrderInfo($order_id, $channel, $scene = 'info')
{
//单笔订单查询
$base = new Base(Router::QUERY_REALTIME_ORDER, "get"); # 单笔订单查询GET请求
$base->addParam("order_id", $order_id); # 商户订单号,由商户保持唯⼀性(必填)
$base->addParam("channel", $channel); # 银⾏卡,⽀付宝,微信(选填不填默认为银⾏卡订单查询注意填写的value是中文)
// $base->addParam("data_type", "encryption");
// # 如果为encryption则对返回的data进行加密(选填)
$config = Conf::config();
$GoQuery = new BaseService($config, $base);
$orderQuery = $GoQuery->request();
$code = $orderQuery['code'];
if ($code == '0000')
# TODO : code=0000,订单查询成功根据订单状态status判断订单状态做业务订单的处理
if ($scene == 'info') {
return self::rep_success('获取数据成功', $orderQuery['data']);
} else if ($scene == 'submit') {
return self::rep_fail('订单已存在');
} else {
return self::rep_success('获取数据成功', $orderQuery['data']);
}
else
if ($code == '2018')
if ($scene == 'submit') {
return self::rep_success('获取数据成功');
} else {
return self::rep_fail('订单不存在');
}
else
# TODO : 其他code应当做异常情况订单状态当"未知"处理可稍后重试直至获取到code=0000或2018或者是联系云账户进行人工查询
#echo "订单查询异常,请稍后重试";
return self::rep_fail('订单查询异常,请稍后重试');
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace app\common\pay;
use app\common\traits\ReturnTrait;
use app\common\yun\Base;
use app\common\yun\service\BaseService;
class SignContract
{
use ReturnTrait;
static $cart_type = [
['id' => 'idcard', 'name' => '身份证'],
['id' => 'mtphkm', 'name' => '港澳居民来往内地通行证'],
['id' => 'passport', 'name' => '护照'],
['id' => 'mtpt', 'name' => '台湾居民往来大陆通行证'],
];
/**
* 签约状态
* @param $real_name
* @param $id_card
* @return array
*/
public static function getSignStatus($real_name, $id_card)
{
$config = Conf::config();
$base = new Base('api/sign/v1/user/status', 'get');
$base->addParam("dealer_id", $config->dealer_id); # 商户代码(必填)
$base->addParam("broker_id", $config->broker_id);
$base->addParam("real_name", $real_name);
$base->addParam("id_card", $id_card);
$go_service = new BaseService($config, $base);
$result = $go_service->request();
if ($result['code'] == '0000') {
// 订单接收成功,支付结果未知,待异步通知
$data = $result['data'];
return self::rep_success('成功', $data);
} else
return self::rep_fail($result['message']);
}
/**
* 获取签约协议链接
* @return array
*/
public static function getSignContractUrl()
{
$config = Conf::config();
$base = new Base('api/sign/v1/user/contract', 'get');
$base->addParam("dealer_id", $config->dealer_id); # 商户代码(必填)
$base->addParam("broker_id", $config->broker_id);
$go_service = new BaseService($config, $base);
$result = $go_service->request();
if ($result['code'] == '0000') {
$data = $result['data'];
return self::rep_success('获取成功', $data);
} else {
return self::rep_fail($result['message']);
}
}
/**
* 签约
* @param $real_name
* @param $id_card
* @param $card_type
* @param string $phone
* @return array
*/
public static function submitSign($real_name, $id_card, $card_type, $phone = '')
{
$config = Conf::config();
$base = new Base('api/sign/v1/user/sign', 'post');
$base->addParam("dealer_id", $config->dealer_id); # 商户代码(必填)
$base->addParam("broker_id", $config->broker_id);
$base->addParam("real_name", $real_name);
$base->addParam("id_card", $id_card);
$base->addParam("phone", $phone);
$base->addParam("card_type", $card_type);
$go_service = new BaseService($config, $base);
$result = $go_service->request();
// halt($result);
if ($result['code'] == '0000') {
$data = $result['data'];
return self::rep_success('获取成功', $data);
} else {
return self::rep_fail($result['message']);
}
}
public static function release($real_name, $id_card)
{
$config = Conf::config();
$base = new Base('api/sign/v1/user/release', 'post');
$base->addParam("dealer_id", $config->dealer_id); # 商户代码(必填)
$base->addParam("broker_id", $config->broker_id);
$base->addParam("real_name", $real_name);
$base->addParam("id_card", $id_card);
$base->addParam("card_type", 'idcard');
$go_service = new BaseService($config, $base);
$result = $go_service->request();
if ($result['code'] == '0000') {
$data = $result['data'];
return self::rep_success('获取成功', $data);
} else {
return self::rep_fail($result['message']);
}
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace app\common\pay;
use app\common\traits\ReturnTrait;
use app\common\yun\Base;
use app\common\yun\Config;
use app\common\yun\Router;
use app\common\yun\service\BaseService;
use think\Route;
class YunPay
{
use ReturnTrait;
public $order_id;
public $real_name;
public $id_card;
public $card_no;
public $order_amount;
// public $notify_url = 'http://ceshi.limaoyuyin.cn/api/pay_notify/yun_notify';
public $notify_url = 'http://hmr.qixing2.top:621/api/pay_notify/yun_notify';
public $phone = '';
public $config;
public $remark = '';
public function __construct($order_id, $real_name, $id_card, $card_no, $order_amount, $phone = '')
{
$this->order_id = $order_id;
$this->real_name = $real_name;
$this->id_card = $id_card;
$this->card_no = $card_no;
$this->phone = $phone;
$this->order_amount = $order_amount;
$this->config = Conf::config();
}
private function deal_params($api_url)
{
$base = new Base($api_url, 'post');
$base->addParam("order_id", $this->order_id); # 商户订单号,由商户保持唯⼀性(必填)64个英⽂字符以内
$base->addParam("dealer_id", $this->config->dealer_id); # 商户代码(必填)
$base->addParam("broker_id", $this->config->broker_id); # 综合服务主体ID(必填)
$base->addParam("real_name", $this->real_name); # 银⾏开户姓名(必填)
$base->addParam("id_card", $this->id_card); # 身份证(必填)
$base->addParam("card_no", $this->card_no); # 银行卡号,只支持对私借记卡(必填)
$base->addParam("phone_no", $this->phone); # ⼿机号(选填)
$base->addParam("pay", $this->order_amount); # 订单⾦额参数类型是string类型单位为元,支持两位小数,必填)
$base->addParam("pay_remark", $this->remark); # 订单备注( 选填最⼤20个字符⼀个汉字占2个字符不允许特殊字符不支持特殊字符 ' " & | @% ( ) - : # + / < > ¥ \ ,
$base->addParam("notify_url", $this->notify_url); # 回调地址(选填最⼤⻓度为200)
return $base;
}
public function bank()
{
$api_url = Router::BANK_CARD;
$base = $this->deal_params($api_url);
$GoPay = new BaseService($this->config, $base);
$bankPay = $GoPay->request();
if ($bankPay['code'] == '0000') {
// 订单接收成功,支付结果未知,待异步通知
// TODO 等待异步通知或订单查询接口获取订单状态
return self::rep_success_format('接单成功');
} else
if ($bankPay['code'] == '2002') {
// 已上传过该流水
// TODO 幂等性校验,订单号已存在,具体订单结果需等待异步通知,或主动调用订单查询接口获取
// echo "订单已存在";
return self::rep_fail_format('订单已存在');
}
else
// TODO 根据返回的message处理订单请求切记若需重试请求请使用原订单号重试
// echo $bankPay['message'];
return self::rep_fail_format($bankPay['message']);
}
public function alipay()
{
$api_url = Router::ALI_PAY;
$base = $this->deal_params($api_url);
$GoPay = new BaseService($this->config, $base);
$bankPay = $GoPay->request();
if ($bankPay['code'] == '0000') {
// 订单接收成功,支付结果未知,待异步通知
// TODO 等待异步通知或订单查询接口获取订单状态
return self::rep_success_format('接单成功');
} else
if ($bankPay['code'] == '2002') {
// 已上传过该流水
// TODO 幂等性校验,订单号已存在,具体订单结果需等待异步通知,或主动调用订单查询接口获取
// echo "订单已存在";
return self::rep_fail_format('订单已存在');
}
else
// TODO 根据返回的message处理订单请求切记若需重试请求请使用原订单号重试
// echo $bankPay['message'];
return self::rep_fail_format($bankPay['message']);
}
}

View File

@@ -0,0 +1,10 @@
<?php
namespace app\common\pay\ali;

View File

@@ -0,0 +1,102 @@
<?php
namespace app\common\pay\wx;
class Wechat
{
public static $appid = 'wxaf7cb4289e79322a';
public static $mchId = '1460116002';
public static $apikey = 'r89ZM8ubLdd8sd3L998Imm2up3Mp8SHp';
public static $notifyUrl = 'https://wo.vfengs.com/merchant/v1/pay-notify';
//获取签名
static function getSign($arr, $apikey)
{
//签名步骤一:按字典序排序参数
ksort($arr);
$string = self::getStringA($arr);
//签名步骤二在string后加入KEY
$string = $string . "&key=" . $apikey;
//签名步骤三MD5加密或者HMAC-SHA256
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
//签名第一步
static function getStringA($arr)
{
$buff = "";
foreach ($arr as $k => $v) {
if ($k != "sign" && $v != "" && !is_array($v)) {
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
//转换成xml格式数据
static function arr2xml($arr)
{
$xml = "<xml>";
foreach ($arr as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}

View File

@@ -0,0 +1,68 @@
<?php
namespace app\common\pay\wx;
class WechatPay
{
public $totalFee;
public $outTradeNo;
public $attach;
public $tradeType;
public $body;
public $notifyUrl;
public function __construct($totalFee = 0, $outTradeNo = '', $attach = '', $tradeType = '', $body = '', $notifyUrl = '')
{
$this->totalFee = $totalFee * 100;
$this->outTradeNo = $outTradeNo;
$this->attach = $attach;
$this->tradeType = $tradeType;
$this->body = $body;
$this->notifyUrl = empty($notifyUrl) ? Wechat::$notifyUrl : $notifyUrl;
}
public function setPayParams()
{
$ip = request()->ip();
return [
'appid' => Wechat::$appid,
'mch_id' => Wechat::$mchId,
'spbill_create_ip' => $ip,
'nonce_str' => md5(mt_rand(1000, 9999)),
'sign_type' => 'MD5',
];
}