Files
yusheng-php/application/api/controller/Payment.php
2025-08-07 20:21:47 +08:00

303 lines
12 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\api\controller;
use think\Controller;
use think\Db;
use think\Loader;
use think\Log;
use Yzh\YunPay;
class Payment extends Controller
{
//生成订单号
private function createOrderSn() {
$orderSn = strtoupper(date('Ymd', time())).substr(time(), -5).substr(microtime(), 2, 5).sprintf('%02d',
rand(0, 99));
return $orderSn;
}
/**
* APP支付
*/
public function app_pay() {
$type = input('type', 0); //1-微信 2-支付宝 4-通联支付宝 5-通联微信
$user_id = input('user_id', 0);
$money = input('money', 0);
$coin = input('coin', 0);
if(!$coin){
$coin = $money * get_system_config_value('rmb_coin_ratio');
}
if (!$user_id) {
return V(0, '请选择充值用户', null);
}
if (!is_numeric($money) || floor($money) != $money || $money <= 0 || $money >= 2000) {
return V(0, '请选择正确的充值金额', null);
}
$user_code = db::name('user')->where(["id" => $user_id])->value('user_code');
$title = "APP充值到用户 " . ($user_code ?? "") . " 余额!";
$order_number = $this->createOrderSn();
$data['order_sn'] = $order_number;
$data['money'] = $money;
$data['coin'] = $coin;
$data['user_id'] = $user_id;
$data['pay_type'] = $type;
$data['createtime'] = time();
$data['remarke'] = '充值到app用户'.($user_code ?? "") ."余额!";;
$re = db::name('vs_user_recharge')->insert($data);
if (!$re) {
return V(0, '充值失败', null);
}
if($type == 2){
//引用支付宝sdk
Loader::import('AliPayV2.AliPay', EXTEND_PATH, '.php');
$ali = new \AliPay();
$result['ali'] = $ali->aliAppPays($order_number, $money, $title);
}elseif($type == 1){
//引用微信sdk
Loader::import('WxPay.WxPay', EXTEND_PATH, '.php');
$wx = new \WxPay();
$result['wx'] = $wx->WxPayApp($data);
}elseif($type == 4 || $type == 5){
//引用通联sdk
Loader::import('TongLian.TongLian', EXTEND_PATH, '.php');
$tonglian = new \TongLian();
$result['tl'] = $tonglian->TongLianPay($data, $type);
}
return V(1, 'app支付', $result);
}
//支付宝回调
public function notify_ali() {
//引用支付宝sdk
Loader::import('AliPayV2.AliPay', EXTEND_PATH, '.php');
$ali = new \AliPay();
$verify_result = $ali->verify($_POST);
Log::record("支付宝回调信息".json_encode($_POST),"info");
if($verify_result) {//验证成功
//商户订单号
$out_trade_no = $_POST['out_trade_no'];
//支付宝交易号
$trade_no = $_POST['trade_no'];
if ($_POST['trade_status'] == 'TRADE_SUCCESS') {
$where['order_sn']=$out_trade_no;
$where['order_type']=1;
$where['pay_type']=2;
$data=[
'trade_no'=>$trade_no
];
$res = handelCharge($where,$data);
if($res==0){
echo "fail";
return;
}
echo "success"; //请不要修改或删除
return;
}
echo "fail";
}else {
//验证失败
echo "fail";
//写入日志文件
Log::record("支付宝回调验签失败","info");
}
}
//微信回调地址 示例
public function notify_wx() {
//引用微信sdk
Loader::import('WxPay.WxPay', EXTEND_PATH, '.php');
$wx = new \WxPay();
//验证是否是微信发送且数据完整
$flag = $wx->WxPayNotifyCheck();
if ($flag['status']) {
if ($flag['data']['return_code'] == 'SUCCESS' && $flag['data']['result_code'] == 'SUCCESS') {
$out_trade_no = $flag['data']['out_trade_no'];//订单号
// $payType = $flag['data']['attach']; //商家数据包
// $time_end = strtotime($flag['data']['time_end']); //支付完成时间
$transaction_id = $flag['data']['transaction_id']; //微信支付订单号
//成功后的业务逻辑处理
$where['order_sn']=$out_trade_no;
$where['order_type']=1;//1 充值
$where['pay_type']=1;//1微信2支付宝 3通联支付宝 4通联微信
$data=[
'trade_no'=>$transaction_id
];
$res = handelCharge($where,$data);
if($res==0){
$r_arr['return_code'] = 'FAIL';
$r_arr['return_msg'] = '回调失败';
echo $wx->arrayToXml($r_arr);
die;
}
$r_arr['return_code'] = 'SUCCESS';
$r_arr['return_msg'] = '回调成功';
echo $wx->arrayToXml($r_arr);
die;
}
}
$r_arr['return_code'] = 'FAIL';
$r_arr['return_msg'] = '回调失败';
echo $wx->arrayToXml($r_arr);
die;
}
//通联支付回调地址 示例
public function allinpayNotify() {
$params = array();
foreach($_POST as $key=>$val) {//动态遍历获取所有收到的参数,此步非常关键,因为收银宝以后可能会加字段,动态获取可以兼容由于收银宝加字段而引起的签名异常
$params[$key] = $val;
}
if(count($params)<1){//如果参数为空,则不进行处理
echo "error";
exit();
}
//引用通联sdk
Loader::import('TongLian.TongLian', EXTEND_PATH, '.php');
$tonglian = new \TongLian();
$ree = $tonglian->ValidSign($params);
// Log::record("通联支付回调信息".json_encode($ree),"info");
if($tonglian->ValidSign($params)){//验签成功
Log::record("通联支付回调信息验签成功".json_encode($params),"info");
//此处进行业务逻辑处理
$pay_type =trim($params['trxreserved']);//备注信息remark
$out_trade_no = trim($params['cusorderid']); //商户订单号
$trade_no = trim($params['trxid']); // 交易号
// $gmt_payment = strtotime(trim($_POST['paytime'])); //交易付款时间
//成功后的业务逻辑处理
$where['order_sn']=$out_trade_no;
$where['order_type']=1;//1 充值
$where['pay_type']=$pay_type;//1微信2支付宝 3通联支付宝 4通联微信
$data=[
'trade_no'=>$trade_no
];
$res = handelCharge($where,$data);
if($res==0){
echo "erro";
return;
}
echo "success";
}else{
Log::record("通联支付回调信息验签失败".json_encode($params),"info");
echo "erro";
}
}
/*
* 云账户回调(提现)
*/
public function yun_callback(){
$data = input("data", "");
$mess = input("mess", "");
$timestamp = input("timestamp", "");
$sign = input("sign", "");
Log::record("云账户回调信息".json_encode($_POST),"info");
$yun_pay = new YunPay();
$result = $yun_pay->yun_callback($data,$mess,$timestamp,$sign);
if($result['code']==1){
$data = $result['data']['data'];
if($data){
$status = $data['status'];
if(!isset($data['status'])){
echo 'fail';
die;
}
switch ($status){
case "1":
// 支付成功(对于支付宝和微信支付是最终状态,对于银行卡大部分情况是终态,小概率会出现"退汇现象",状态由"成功"变为"退汇"
db::name('vs_user_withdrawal')
->where('order_sn',$data['order_id'])
->where('status',4)
->update([
'status' => 6,
'pay_message' => $data['status_message'],
'pay_time' => time(),
'updatetime' => time()
]);
echo "success";
break;
case "2":
// 支付失败(最终状态)
// TODO 更新业务订单状态,提示用户提现失败,若有用户钱包体系,则需将提现金额退回至用户钱包
db::name('vs_user_withdrawal')
->where('order_sn',$data['order_id'])
->where('status',4)
->update([
'status' => 5,
'pay_message' => $data['status_message'],
'pay_time' => time(),
'updatetime' => time()
]);
//支付失败资金退回
$res = model('/UserWithdrawal')->withdrawal_fail($data['order_id']);
echo "success";
break;
break;
case "4":
// 订单挂单(中间状态,挂单原因会在订单详细状态信息返回)
// TODO 提示用户提现中其他逻辑如若因余额不足导致的挂单可通知财务及时充值72小时内补足余额后可自动继续支付
echo "success";
break;
case "9":
// 退汇,(最终状态,银行卡渠道特有现象,会先收到"成功"回调,然后再收到"退汇"的回调一般以成功状态间隔24小时以上
// TODO 更新业务订单状态为“退汇”(失败),通知用户提现失败,建议用户更换其他银行卡提现,若有用户钱包体系,则需将提现金额退回至用户钱包
db::name('vs_user_withdrawal')
->where('order_sn',$data['order_id'])
->where('status',4)
->update([
'status' => 5,
'pay_message' => $data['status_message'],
'pay_time' => time(),
'updatetime' => time()
]);
//支付失败资金退回
$res = model('/UserWithdrawal')->withdrawal_fail($data['order_id']);
echo "success";
break;
case "15":
// 订单取消,(最终状态,只有挂单的订单才可以取消)
// TODO 更新业务订单状态为“取消”(失败),通知用户提现失败,若有用户钱包体系,则需将提现金额退回至用户钱包
db::name('vs_user_withdrawal')
->where('order_sn',$data['order_id'])
->where('status',4)
->update([
'status' => 5,
'pay_message' => $data['status_message'],
'pay_time' => time(),
'updatetime' => time()
]);
//支付失败资金退回
$res = model('/UserWithdrawal')->withdrawal_fail($data['order_id']);
echo "success";
break;
}
}
}else{
echo "fail";
}
}
}