添加网站文件
This commit is contained in:
419
application/common/logic/PaymentLogic.php
Normal file
419
application/common/logic/PaymentLogic.php
Normal file
@@ -0,0 +1,419 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | likeshop100%开源免费商用商城系统
|
||||
// +----------------------------------------------------------------------
|
||||
// | 欢迎阅读学习系统程序代码,建议反馈是我们前进的动力
|
||||
// | 开源版本可自由商用,可去除界面版权logo
|
||||
// | 商业版本务必购买商业授权,以免引起法律纠纷
|
||||
// | 禁止对系统程序代码以任何目的,任何形式的再发布
|
||||
// | gitee下载:https://gitee.com/likeshop_gitee
|
||||
// | github下载:https://github.com/likeshop-github
|
||||
// | 访问官网:https://www.likeshop.cn
|
||||
// | 访问社区:https://home.likeshop.cn
|
||||
// | 访问手册:http://doc.likeshop.cn
|
||||
// | 微信公众号:likeshop技术社区
|
||||
// | likeshop团队 版权所有 拥有最终解释权
|
||||
// +----------------------------------------------------------------------
|
||||
// | author: likeshopTeam
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
namespace app\common\logic;
|
||||
|
||||
use app\common\server\AliPayServer;
|
||||
use app\common\server\WeChatPayServer;
|
||||
use app\common\model\{Client_, Order, Pay, User};
|
||||
use think\facade\Env;
|
||||
|
||||
class PaymentLogic extends LogicBase
|
||||
{
|
||||
|
||||
protected static $error = '';
|
||||
protected static $return_code = 0;
|
||||
|
||||
/**
|
||||
* Notes: 错误信息
|
||||
* @return string
|
||||
* @author 段誉(2021/2/1 11:19)
|
||||
*/
|
||||
public static function getError()
|
||||
{
|
||||
return self::$error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notes: 返回状态码
|
||||
* @return int
|
||||
* @author 段誉(2021/2/1 11:19)
|
||||
*/
|
||||
public static function getReturnCode()
|
||||
{
|
||||
return self::$return_code;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 支付
|
||||
* @param $from
|
||||
* @param $order
|
||||
* @param $order_source
|
||||
* @return array|bool|string
|
||||
* @author 段誉(2021/2/1 11:19)
|
||||
*/
|
||||
public static function pay($from, $order, $order_source)
|
||||
{
|
||||
switch ($order['pay_way']) {
|
||||
case Pay::WECHAT_PAY:
|
||||
|
||||
$res = WeChatPayServer::unifiedOrder($from, $order, $order_source);
|
||||
if (false === $res) {
|
||||
self::$error = WeChatPayServer::getError();
|
||||
}
|
||||
break;
|
||||
|
||||
case Pay::ALI_PAY:
|
||||
|
||||
$aliPay = new AliPayServer();
|
||||
$res = $aliPay->pay($from, $order, $order_source);
|
||||
if(false === $res) {
|
||||
self::$error = $aliPay->getError();
|
||||
} else {
|
||||
self::$return_code = 20001;//特殊状态码,用于前端判断
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
$ttPay = new ttPay();
|
||||
$res = $ttPay->run('order',$order);
|
||||
|
||||
// $res = self::ttpay($order);
|
||||
if(!empty($res['data'])) {
|
||||
self::$return_code = 8888;//特殊状态码,用于前端判断
|
||||
$res = $res['data'];
|
||||
}else{
|
||||
self::$error = $res['err_tips'];
|
||||
$res = false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
self::$error = '订单异常';
|
||||
$res = false;
|
||||
}
|
||||
return $res;
|
||||
}
|
||||
|
||||
//抖音支付
|
||||
public static function ttpay($data)
|
||||
{
|
||||
$url = 'https://developer.toutiao.com/api/apps/ecpay/v1/create_order';
|
||||
$params['app_id'] = 'tt0523739e9a12236501';
|
||||
$params['out_order_no'] = (string)$data['order_sn'];
|
||||
$params['total_amount'] = (int)$data['order_amount'] * 100;
|
||||
$params['subject'] = 'subject';
|
||||
$params['body'] = 'body';
|
||||
$params['valid_time'] = 3600;
|
||||
|
||||
|
||||
$params['sign'] = self::ttsign($params,'ejAuHvbI472euyhb34aVyLD92ll9tgZCqWnMi0tX');
|
||||
|
||||
|
||||
$http = self::httpPost($url, $params);
|
||||
return json_decode($http,true);
|
||||
}
|
||||
|
||||
//curl
|
||||
public static function httpPost($url, $data = null)
|
||||
{
|
||||
$curl = curl_init();
|
||||
curl_setopt($curl, CURLOPT_URL, $url);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
||||
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
||||
if (!$data) return false;
|
||||
if (is_array($data)) {
|
||||
$data = json_encode($data);
|
||||
}
|
||||
curl_setopt($curl, CURLOPT_POST, 1);
|
||||
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
||||
curl_setopt($curl, CURLOPT_HEADER, 0);
|
||||
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json; charset=utf-8',
|
||||
'Content-Length:' . strlen($data),
|
||||
'Cache-Control: no-cache',
|
||||
'Pragma: no-cache'
|
||||
));
|
||||
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
||||
$res = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
return $res;
|
||||
}
|
||||
// 签名
|
||||
public static function ttsign($map,$secret)
|
||||
{
|
||||
|
||||
$rList = [];
|
||||
foreach($map as $k =>$v) {
|
||||
if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
|
||||
continue;
|
||||
|
||||
$value = trim(strval($v));
|
||||
|
||||
$len = strlen($value);
|
||||
if ($len > 1 && substr($value, 0,1)=="\"" && substr($value, $len-1)=="\"")
|
||||
$value = substr($value,1, $len-1);
|
||||
$value = trim($value);
|
||||
if ($value == "" || $value == "null")
|
||||
continue;
|
||||
$rList[] = $value;
|
||||
}
|
||||
$rList[] = $secret;
|
||||
sort($rList, SORT_STRING);
|
||||
|
||||
|
||||
return md5(implode('&', $rList));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Notes: 是否在白名单内支付
|
||||
* @param $user_id
|
||||
* @author 段誉(2021/2/24 10:01)
|
||||
* @return bool
|
||||
*/
|
||||
public static function isPayWhiteList($user_id)
|
||||
{
|
||||
$white_list = Env::get('wechat.white_list', '');
|
||||
$white_list = explode(',', $white_list);
|
||||
if (in_array($user_id, $white_list)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Class ttPay{
|
||||
|
||||
private $api_url='https://developer.toutiao.com/api/apps/ecpay/v1/';
|
||||
private $app_id;
|
||||
private $token;
|
||||
private $salt;
|
||||
|
||||
public function __construct() {
|
||||
$this->app_id = 'tt0523739e9a12236501';
|
||||
$this->token='123qazqweeesdflomswwe';
|
||||
$this->salt='ejAuHvbI472euyhb34aVyLD92ll9tgZCqWnMi0tX';
|
||||
// $this->salt='58280e4f36d88e93d7a4be9f0e590b2302a462c5';
|
||||
}
|
||||
|
||||
public function run($action,$order){
|
||||
$action=$action?$action:'order';
|
||||
if(!in_array($action,['order','query','refund','settle','notify','set'])){
|
||||
echo '非法请求';die;
|
||||
}
|
||||
return $this->$action($order);
|
||||
}
|
||||
|
||||
//下单
|
||||
private function order($order){
|
||||
$data=[
|
||||
'out_order_no'=>$order['order_sn'],
|
||||
'total_amount'=>(int)$order['order_amount'] * 100,
|
||||
'subject'=>'购买服务',
|
||||
'body'=>'购买商品',
|
||||
'valid_time'=>3600,
|
||||
];
|
||||
return $this->post('create_order',$data);
|
||||
|
||||
}
|
||||
|
||||
//查询订单
|
||||
private function query(){
|
||||
$data=[
|
||||
'out_order_no'=>'2021110117254573565'
|
||||
];
|
||||
$res=$this->post('query_order',$data,false);
|
||||
echo json_encode($res);die;
|
||||
}
|
||||
|
||||
//订单退款
|
||||
private function refund(){
|
||||
$data=[
|
||||
'out_order_no'=>'2021110118351347832',
|
||||
'out_refund_no'=>$this->order_number(),
|
||||
'reason'=>'退款原因',
|
||||
'refund_amount'=>1,
|
||||
];
|
||||
$res=$this->post('create_refund',$data);
|
||||
echo json_encode($res);die;
|
||||
}
|
||||
|
||||
//订单分账
|
||||
private function settle(){
|
||||
$data=[
|
||||
'out_order_no'=>'2021110118301265990',
|
||||
'out_settle_no'=>$this->order_number(),
|
||||
'settle_desc'=>'分账描述',
|
||||
'settle_params'=>json_encode([]),//分润方参数 如[['merchant_uid'=>'商户号','amount'=>'10']] 可以有多个分账商户
|
||||
];
|
||||
$res=$this->post('settle',$data);
|
||||
echo json_encode($res);die;
|
||||
}
|
||||
|
||||
//支付设置回调测试
|
||||
private function set(){
|
||||
$content=file_get_contents('php://input');
|
||||
$this->log('log.txt',$content);
|
||||
}
|
||||
|
||||
//回调
|
||||
private function notify(){
|
||||
$content=file_get_contents('php://input');
|
||||
if(empty($content)) return false;
|
||||
$this->log('notify.txt',$content);
|
||||
$content=json_decode($content,true);
|
||||
$sign=$this->handler($content);
|
||||
if($sign==$content['msg_signature']){
|
||||
$msg=json_decode($content['msg'],true);
|
||||
echo '回调----'.$content['type']."\n";
|
||||
//这里更新应用业务逻辑代码,使用$msg跟应用订单比对更新订单,可以用 $content['type']判断是支付回调还是退款回调,payment支付回调 refund退款回调。
|
||||
$res=['err_no'=>0,'err_tips'=>'success'];
|
||||
echo json_encode($res);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 测试订单号,实际应用根据自己应用实际生成
|
||||
* @return string
|
||||
*/
|
||||
private function order_number(){
|
||||
return date('YmdHis').rand(10000,99999);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求小程序平台服务端
|
||||
* @param string $url 接口地址
|
||||
* @param array $data 参数内容
|
||||
* @param boolean $notify 是否有回调
|
||||
* @return array
|
||||
*/
|
||||
private function post($method,$data,$notify=true){
|
||||
$data['app_id']=$this->app_id;
|
||||
|
||||
$data['sign']=$this->sign($data);
|
||||
$url=$this->api_url.$method;
|
||||
$res=$this->http('POST',$url,json_encode($data),['Content-Type: application/json'],true);
|
||||
return json_decode($res,true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 回调验签
|
||||
* @param array $map 验签参数
|
||||
* @return stirng
|
||||
*/
|
||||
private function handler($map){
|
||||
$rList = array();
|
||||
array_push($rList, $this->token);
|
||||
foreach($map as $k =>$v) {
|
||||
if ( $k == "type" || $k=='msg_signature')
|
||||
continue;
|
||||
$value = trim(strval($v));
|
||||
if ($value == "" || $value == "null")
|
||||
continue;
|
||||
array_push($rList, $value);
|
||||
}
|
||||
sort($rList,2);
|
||||
return sha1(implode($rList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 请求签名
|
||||
* @param array $map 请求参数
|
||||
* @return stirng
|
||||
*/
|
||||
private function sign($map) {
|
||||
$rList = array();
|
||||
foreach($map as $k =>$v) {
|
||||
if ($k == "other_settle_params" || $k == "app_id" || $k == "sign" || $k == "thirdparty_id")
|
||||
continue;
|
||||
$value = trim(strval($v));
|
||||
$len = strlen($value);
|
||||
if ($len > 1 && substr($value, 0,1)=="\"" && substr($value,$len, $len-1)=="\"")
|
||||
$value = substr($value,1, $len-1);
|
||||
$value = trim($value);
|
||||
if ($value == "" || $value == "null")
|
||||
continue;
|
||||
array_push($rList, $value);
|
||||
}
|
||||
array_push($rList, $this->salt);
|
||||
sort($rList, 2);
|
||||
return md5(implode('&', $rList));
|
||||
}
|
||||
|
||||
/**
|
||||
* 写日志
|
||||
* @param string $path 日志路径
|
||||
* @param string $content 内容
|
||||
*/
|
||||
private function log($path, $content){
|
||||
$file=fopen($path, "a");
|
||||
fwrite($file, date('Y-m-d H:i:s').'-----'.$content."\n");
|
||||
fclose($file);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 网络请求
|
||||
* @param stirng $method 请求模式
|
||||
* @param stirng $url请求网关
|
||||
* @param array $params 请求参数
|
||||
* @param stirng $header 自定义头
|
||||
* @param boolean $multi 文件上传
|
||||
* @return array
|
||||
*/
|
||||
private function http( $method = 'GET', $url,$params,$header = array(), $multi = false){
|
||||
|
||||
$opts = array(
|
||||
CURLOPT_TIMEOUT => 30,
|
||||
CURLOPT_RETURNTRANSFER => 1,
|
||||
CURLOPT_SSL_VERIFYPEER => false,
|
||||
CURLOPT_SSL_VERIFYHOST => false,
|
||||
CURLOPT_HTTPHEADER => $header
|
||||
);
|
||||
/* 根据请求类型设置特定参数 */
|
||||
switch(strtoupper($method)){
|
||||
case 'GET':
|
||||
$opts[CURLOPT_URL] = $url . '?' . http_build_query($params);
|
||||
break;
|
||||
case 'POST':
|
||||
//判断是否传输文件
|
||||
$params = $multi ? $params : http_build_query($params);
|
||||
$opts[CURLOPT_URL] = $url;
|
||||
$opts[CURLOPT_POST] = 1;
|
||||
$opts[CURLOPT_POSTFIELDS] = $params;
|
||||
break;
|
||||
default:
|
||||
throw new Exception('不支持的请求方式!');
|
||||
}
|
||||
|
||||
/* 初始化并执行curl请求 */
|
||||
$ch = curl_init();
|
||||
curl_setopt_array($ch, $opts);
|
||||
$data = curl_exec($ch);
|
||||
$error = curl_error($ch);
|
||||
curl_close($ch);
|
||||
if($error) throw new Exception('请求发生错误:' . $error);
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user