235 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			7.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						||
 | 
						||
namespace addons\epay\controller;
 | 
						||
 | 
						||
use addons\epay\library\Service;
 | 
						||
use addons\epay\library\Wechat;
 | 
						||
use addons\third\model\Third;
 | 
						||
use app\common\library\Auth;
 | 
						||
use Exception;
 | 
						||
use think\addons\Controller;
 | 
						||
use think\Response;
 | 
						||
use think\Session;
 | 
						||
use Yansongda\Pay\Exceptions\GatewayException;
 | 
						||
use Yansongda\Pay\Pay;
 | 
						||
 | 
						||
/**
 | 
						||
 * API接口控制器
 | 
						||
 *
 | 
						||
 * @package addons\epay\controller
 | 
						||
 */
 | 
						||
class Api extends Controller
 | 
						||
{
 | 
						||
 | 
						||
    protected $layout = 'default';
 | 
						||
    protected $config = [];
 | 
						||
 | 
						||
    /**
 | 
						||
     * 默认方法
 | 
						||
     */
 | 
						||
    public function index()
 | 
						||
    {
 | 
						||
        return;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 外部提交
 | 
						||
     */
 | 
						||
    public function submit()
 | 
						||
    {
 | 
						||
        $this->request->filter('trim');
 | 
						||
        $out_trade_no = $this->request->request("out_trade_no");
 | 
						||
        $title = $this->request->request("title");
 | 
						||
        $amount = $this->request->request('amount');
 | 
						||
        $type = $this->request->request('type', $this->request->request('paytype'));
 | 
						||
        $method = $this->request->request('method', 'web');
 | 
						||
        $openid = $this->request->request('openid', '');
 | 
						||
        $auth_code = $this->request->request('auth_code', '');
 | 
						||
        $notifyurl = $this->request->request('notifyurl', '');
 | 
						||
        $returnurl = $this->request->request('returnurl', '');
 | 
						||
 | 
						||
        if (!$amount || $amount < 0) {
 | 
						||
            $this->error("支付金额必须大于0");
 | 
						||
        }
 | 
						||
 | 
						||
        if (!$type || !in_array($type, ['alipay', 'wechat'])) {
 | 
						||
            $this->error("支付类型错误");
 | 
						||
        }
 | 
						||
 | 
						||
        $params = [
 | 
						||
            'type'         => $type,
 | 
						||
            'out_trade_no' => $out_trade_no,
 | 
						||
            'title'        => $title,
 | 
						||
            'amount'       => $amount,
 | 
						||
            'method'       => $method,
 | 
						||
            'openid'       => $openid,
 | 
						||
            'auth_code'    => $auth_code,
 | 
						||
            'notifyurl'    => $notifyurl,
 | 
						||
            'returnurl'    => $returnurl,
 | 
						||
        ];
 | 
						||
        return Service::submitOrder($params);
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 微信支付(公众号支付&PC扫码支付)
 | 
						||
     */
 | 
						||
    public function wechat()
 | 
						||
    {
 | 
						||
        $config = Service::getConfig('wechat');
 | 
						||
 | 
						||
        $isWechat = stripos($this->request->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false;
 | 
						||
        $isMobile = $this->request->isMobile();
 | 
						||
        $this->view->assign("isWechat", $isWechat);
 | 
						||
        $this->view->assign("isMobile", $isMobile);
 | 
						||
 | 
						||
        //发起PC支付(Scan支付)(PC扫码模式)
 | 
						||
        if ($this->request->isAjax()) {
 | 
						||
            $pay = Pay::wechat($config);
 | 
						||
            $orderid = $this->request->post("orderid");
 | 
						||
            try {
 | 
						||
                $result = Service::isVersionV3() ? $pay->find(['out_trade_no' => $orderid]) : $pay->find($orderid, 'scan');
 | 
						||
                $this->success("", "", ['status' => $result['trade_state'] ?? 'NOTPAY']);
 | 
						||
            } catch (GatewayException $e) {
 | 
						||
                $this->error("查询失败(1001)");
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        $orderData = Session::get("wechatorderdata");
 | 
						||
        if (!$orderData) {
 | 
						||
            $this->error("请求参数错误");
 | 
						||
        }
 | 
						||
        if ($isWechat && $isMobile) {
 | 
						||
            //发起公众号(jsapi支付),openid必须
 | 
						||
 | 
						||
            //如果没有openid,则自动去获取openid
 | 
						||
            if (!isset($orderData['openid']) || !$orderData['openid']) {
 | 
						||
                $orderData['openid'] = Service::getOpenid();
 | 
						||
            }
 | 
						||
 | 
						||
            $orderData['method'] = 'mp';
 | 
						||
            $type = 'jsapi';
 | 
						||
            $payData = Service::submitOrder($orderData);
 | 
						||
            if (!isset($payData['paySign'])) {
 | 
						||
                $this->error("创建订单失败,请返回重试", "");
 | 
						||
            }
 | 
						||
        } else {
 | 
						||
            $orderData['method'] = 'scan';
 | 
						||
            $type = 'pc';
 | 
						||
            $payData = Service::submitOrder($orderData);
 | 
						||
            if (!isset($payData['code_url'])) {
 | 
						||
                $this->error("创建订单失败,请返回重试", "");
 | 
						||
            }
 | 
						||
        }
 | 
						||
        $this->view->assign("orderData", $orderData);
 | 
						||
        $this->view->assign("payData", $payData);
 | 
						||
        $this->view->assign("type", $type);
 | 
						||
 | 
						||
        $this->view->assign("title", "微信支付");
 | 
						||
        return $this->view->fetch();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 支付宝支付(PC扫码支付)
 | 
						||
     */
 | 
						||
    public function alipay()
 | 
						||
    {
 | 
						||
        $config = Service::getConfig('alipay');
 | 
						||
 | 
						||
        $isWechat = stripos($this->request->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false;
 | 
						||
        $isMobile = $this->request->isMobile();
 | 
						||
        $this->view->assign("isWechat", $isWechat);
 | 
						||
        $this->view->assign("isMobile", $isMobile);
 | 
						||
 | 
						||
        if ($this->request->isAjax()) {
 | 
						||
            $orderid = $this->request->post("orderid");
 | 
						||
            $pay = Pay::alipay($config);
 | 
						||
            try {
 | 
						||
                $result = $pay->find(['out_trade_no' => $orderid]);
 | 
						||
                if ($result['code'] == '10000' && $result['trade_status'] == 'TRADE_SUCCESS') {
 | 
						||
                    $this->success("", "", ['status' => $result['trade_status']]);
 | 
						||
                } else {
 | 
						||
                    $this->error("查询失败");
 | 
						||
                }
 | 
						||
            } catch (GatewayException $e) {
 | 
						||
                $this->error("查询失败(1001)");
 | 
						||
            }
 | 
						||
        }
 | 
						||
 | 
						||
        //发起PC支付(Scan支付)(PC扫码模式)
 | 
						||
        $orderData = Session::get("alipayorderdata");
 | 
						||
        if (!$orderData) {
 | 
						||
            $this->error("请求参数错误");
 | 
						||
        }
 | 
						||
 | 
						||
        $orderData['method'] = 'scan';
 | 
						||
        $payData = Service::submitOrder($orderData);
 | 
						||
        if (!isset($payData['qr_code'])) {
 | 
						||
            $this->error("创建订单失败,请返回重试");
 | 
						||
        }
 | 
						||
 | 
						||
        $type = 'pc';
 | 
						||
        $this->view->assign("orderData", $orderData);
 | 
						||
        $this->view->assign("payData", $payData);
 | 
						||
        $this->view->assign("type", $type);
 | 
						||
        $this->view->assign("title", "支付宝支付");
 | 
						||
        return $this->view->fetch();
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 支付成功回调
 | 
						||
     */
 | 
						||
    public function notifyx()
 | 
						||
    {
 | 
						||
        $paytype = $this->request->param('paytype');
 | 
						||
        $pay = Service::checkNotify($paytype);
 | 
						||
        if (!$pay) {
 | 
						||
            return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
 | 
						||
        }
 | 
						||
 | 
						||
        // 获取回调数据,V3和V2的回调接收不同
 | 
						||
        $data = Service::isVersionV3() ? $pay->callback() : $pay->verify();
 | 
						||
 | 
						||
        try {
 | 
						||
            //微信支付V3返回和V2不同
 | 
						||
            if (Service::isVersionV3() && $paytype === 'wechat') {
 | 
						||
                $data = $data['resource']['ciphertext'];
 | 
						||
                $data['total_fee'] = $data['amount']['total'];
 | 
						||
            }
 | 
						||
 | 
						||
            \think\Log::record($data);
 | 
						||
            //获取支付金额、订单号
 | 
						||
            $payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
 | 
						||
            $out_trade_no = $data['out_trade_no'];
 | 
						||
 | 
						||
            \think\Log::record("回调成功,订单号:{$out_trade_no},金额:{$payamount}");
 | 
						||
 | 
						||
            //你可以在此编写订单逻辑
 | 
						||
        } catch (Exception $e) {
 | 
						||
            \think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error");
 | 
						||
        }
 | 
						||
 | 
						||
        //下面这句必须要执行,且在此之前不能有任何输出
 | 
						||
        if (Service::isVersionV3()) {
 | 
						||
            return $pay->success()->getBody()->getContents();
 | 
						||
        } else {
 | 
						||
            return $pay->success()->send();
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 支付成功返回
 | 
						||
     */
 | 
						||
    public function returnx()
 | 
						||
    {
 | 
						||
        $paytype = $this->request->param('paytype');
 | 
						||
        if (Service::checkReturn($paytype)) {
 | 
						||
            echo '签名错误';
 | 
						||
            return;
 | 
						||
        }
 | 
						||
 | 
						||
        //你可以在这里定义你的提示信息,但切记不可在此编写逻辑
 | 
						||
        $this->success("恭喜你!支付成功!", addon_url("epay/index/index"));
 | 
						||
    }
 | 
						||
 | 
						||
}
 |