sifangpay/app/ServicePay/WeixinAlipayServices.php

393 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\ServicePay;
use App\Models\Merchant;
use App\Models\Order;
use Illuminate\Support\Facades\Log;
use Yansongda\Pay\Pay;
use Yansongda\Pay\Gateways\Wechat\Support;
use Illuminate\Support\Collection;
use Illuminate\Http\Request;
use Ixudra\Curl\Facades\Curl;
class WeixinAlipayServices implements PayApiInterface
{
use PayTrait;
public $gateway_list;//当前类型的支付通道列表
public $pay_type;//支付类型
public $pay_method;//支付方法
public $pay_gateway;//当前的支付通道实例
public $pay_config;//这个通道的支付配置信息
public $pay_model;//支付接口实例模型
public $order;
public $request;
public $gateway_id;
public $pay_data;
public $log_name;
public static $result;
/**
* 检查通道是否存在错误
*/
public function checkGatewayConfig()
{
$pay_method = $this->pay_method;
if (count($this->gateway_list) <= 0) {
self::addError(['msg' => '通道支付不存在']);
}
if (!isset($this->gateway_list[$pay_method])) {
self::addError(['msg' => '通道支付类型不存在']);
}
}
/**
* 支付包配置实列化
* @param $type
* @param array $setConfig
* @return $this
*/
public function payConfig($type, $setConfig = [])
{
$config = $this->getPayAccount($type);
$extend_config = [
'log' => [ // optional
'file' => to_linux_path(base_path()) . '/paylogs/' . $type . '_pay.log',
'level' => 'info', // 建议生产环境等级调整为 info开发环境为 debug
'type' => 'daily', // optional, 可选 daily.
'max_file' => 30, // optional, 当 type 为 daily 时有效,默认 30 天
],
'return_url' => action('Pay\PayController@returnNotify', ['type' => $type]),
'notify_url' => action('Pay\PayController@notify', ['type' => $type]),
'http' => [ // optional
'timeout' => 5.0,
'connect_timeout' => 5.0,
// 更多配置项请参考 [Guzzle](https://guzzle-cn.readthedocs.io/zh_CN/latest/request-options.html)
]
];
if ($this->pay_gateway['is_dev'] == 1) {
$extend_config['mode'] = 'dev';//沙箱
}
$this->pay_config = $setConfig + $extend_config + $config;
Log::info(json_encode($this->pay_config));
switch ($type) {
case 'alipay':
$this->pay_model = Pay::alipay($this->pay_config);
//dump('我用了支付宝');
break;
case 'weixin':
$this->pay_model = Pay::wechat($this->pay_config);
break;
}
return $this;
}
//回调指定通道配置信息gateway
public function getConfig($gateway_id, $pay_method)
{
$this->pay_method = $pay_method;
return $this->pay_model = config('gateway.config')[$gateway_id];
}
public function getPayConfig()
{
return $this->pay_config;
}
public function pay($pay_data)
{
$method = $this->pay_method;
$pay = $this->pay_model->$method($pay_data);
if (in_array($method, ['web', 'wap', 'app'])) {
return $pay->send();//直接发送支付
} else {
//扫码返回
return $pay;
}
}
/*
* 验证签名
*/
public function verify()
{
return $this->pay_model->verify();
}
/**
* 支付账号信息
* @param $type
* @return array
*/
public function getPayAccount($type)
{
$config = [];
switch ($type) {
//支付宝配置
case 'alipay':
$config = [
'app_id' => $this->pay_gateway['app_id'],
'ali_public_key' => trim($this->pay_gateway['cert_pub']),
'private_key' => trim($this->pay_gateway['cert_key'])
];
break;
//微信
case 'weixin':
$config = [
'app_id' => $this->pay_gateway['app_id'],
'mch_id' => $this->pay_gateway['mch_id'],
'key' => $this->pay_gateway['app_key']
];
break;
//小程序
case 'mini':
$config = [
'miniapp_id' => $this->pay_gateway['app_id'],
'mch_id' => $this->pay_gateway['mch_id'],
'key' => $this->pay_gateway['app_key']
];
break;
}
return $config;
}
public function setLogName($pay_type)
{
$name = '';
switch ($pay_type) {
case 'alipay':
$name = 'alipay_';
break;
case 'weixin':
$name = 'weixin_';
break;
}
$this->log_name = $name;
}
public function notify($return = 1, $pay_type, $request)
{
$this->request = $request;
$this->pay_type = $pay_type;
$this->setLogName($this->pay_type);
switch ($this->pay_type) {
case 'alipay':
//取得支付宝类型的订单
$this->getOrder($this->request->input('out_trade_no'));
if ($return) {
return $this->returnAlipay();
}
return $this->alipayNotify();
break;
case 'weixin':
if ($return) {
return $this->returnWeixin();
}
return $this->weixinNotify();
break;
}
}
/**
* 支付宝同步回调
*
*/
public function returnAlipay()
{
//判断是否是商户id
if ($this->order->merchant_id == 0) {
return redirect()->route('web.user.index');
}
//
return $this->merchantReturnSend();
}
/**
* 同步回调给微信支付
* @return \Illuminate\Http\RedirectResponse
*/
public function returnWeixin()
{
$this->getOrder($this->request->input('out_trade_no'));//取得微信类型的订单
//判断是否是商户id
if ($this->order->merchant_id == 0) {
return redirect()->route('web.user.index');
}
//
return $this->merchantReturnSend();
}
public function weixinNotify()
{
//$this->getOrder($this->request->input('out_trade_no'));
$content = $content ?? $this->request->createFromGlobals()->getContent();
$data = Support::fromXml($content);
$order_sn = $data['out_trade_no'];
$data = new Collection($data);
Log::info('微信过来参数' . json_encode($data->toArray()));
$this->getOrder($order_sn);
$this->commonNotify();
}
/**
* 支付宝异步回调
*/
public function alipayNotify()
{
$this->commonNotify();
}
/**
* 取得订单,支付宝和微信返回的订单号都有差异,需要分开处理
* @param $order_sn
*/
public function getOrder($order_sn)
{
$this->order = Order::where('order_sn', $order_sn)->first();
$this->pay_method = $this->order->gateway_method;//支付方法
$this->gateway_id = $this->order->gateway_id;//通道ID
$this->merchant = Merchant::find($this->order->merchant_id);
}
/**
* 支付宝统一设置参数
* @param $data
* @return bool
*/
public function alipayHandle($data)
{
$result = [
'order_sn' => $data->out_trade_no,
'pay_order_sn' => $data->trade_no,
'pay_money' => $data->total_amount,
'pay_type' => 'alipay',
'account' => $data->buyer_logon_id
];
$this->setResult($result);
Log::channel('pay_success')->info('支付宝支付成功', ['pay_type' => 'alipay', 'pay_money' => $data->total_amount, 'account' => $data->buyer_logon_id, 'order_sn' => $data->out_trade_no, 'pay_order_sn' => $data->trade_no]);
}
public function wechatHandle($data)
{
$data = $data->toArray();
$result = [
'order_sn' => $data['out_trade_no'],
'pay_order_sn' => $data['transaction_id'],//微信订单号
'pay_money' => $data['total_fee'] / 100,//订单金额,单位分/100=元
'pay_type' => 'weixin',
'account' => $data['openid'] //openid
];
$this->setResult($result);
Log::channel('pay_success')->info('微信支付成功', ['pay_type' => 'weixin', 'pay_money' => $result['pay_money'], 'account' => $result['account'], 'order_sn' => $result['order_sn'], 'pay_order_sn' => $result['pay_order_sn']]);
// Log::channel('pay_success')->info('小程序支付成功',['total'=>$data->total_fee,'openid'=>$data->openid,'out_trade_no'=>$data->out_trade_no,'order_type'=>$data->attach]);
}
public function commonNotify()
{
//取得通道信息内容
$this->gateway = $this->pay_gateway = config('gateway.config')[$this->gateway_id];
//加载通道的支付配置信息
//这里取得支付实例化$this->pay_model
$this->payConfig($this->pay_type);
//验证签名
$data = $this->verify();
$this->debugLog('-------------' . $this->order->order_sn . '--选择----' . $this->pay_type . '----' . $this->pay_method . '----开始回调处理-------------------------');
if (empty($data)) {
return $this->debugLog('验证签名失败', $this->request->all());
}
try {
$pay_cn_name = '';
switch ($this->pay_type) {
case 'alipay':
//支付宝异步回掉也是会未支付
if (!in_array($data->trade_status, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
return false;
exit();//终止
}
$this->alipayHandle($data);
$pay_cn_name = '支付宝';
break;
case 'weixin':
$pay_cn_name = '微信';
$this->wechatHandle($data);
break;
}
$this->debugLog('验证签名成功,准备订单更新');
//支付返回信息
$this->pay_data = $data;
$this->debugLog('验证签名成功,数据', $data);
//更新订单
$this->updateOrder();
$this->debugLog('updateOrder Ok');
} catch (\Exception $exception) {
$this->debugLog('失败异常内容:' . $exception->getMessage());
if ($this->pay_type == 'alipay') {
//支付宝异步回调也是会有未支付需要这2个判断
if (!in_array($data->trade_status, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
return false;
}
}
$this->order->notify_status = 1;//支付回调成功
$this->order->pay_status = 1;//支付状态
$this->order->pay_ok_at = date('Y-m-d H:i:s');
$this->order->save();//保存
Log::channel('pay_success')->info($pay_cn_name . '支付成功,但处理订单失败', ['data' => json_encode($data)]);
}
}
/**
* 更新订单操作
* @return mixed|void
*/
public function updateOrder()
{
$order = $this->order;
//判断是否本站
if ($order->merchant_id == 0) {
//本地订单处理
return $this->locationOrder();
} else {
//外站订单处理
//支付宝会异步发送未支付的操作
if ($this->pay_type == 'alipay') {
$this->debugLog('alipay');
//支付宝异步回调也是会有未支付需要这2个判断
if (!in_array($this->pay_data->trade_status, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
return false;
}
}
return $this->outOrder();
}
}
//成功完成异步回调返回给支付商
public function success()
{
$this->pay_model->success()->send();
}
}