test_lgq/niucloud/core/pay/Alipay.php

379 lines
12 KiB
PHP
Raw Permalink Normal View History

2024-01-24 17:36:08 +08:00
<?php
namespace core\pay;
use app\dict\pay\OnlinePayDict;
use app\dict\pay\RefundDict;
use app\dict\pay\TransferDict;
use core\exception\PayException;
use Psr\Http\Message\ResponseInterface;
use Throwable;
use Yansongda\Pay\Exception\ContainerException;
use Yansongda\Pay\Exception\InvalidParamsException;
use Yansongda\Pay\Exception\ServiceNotFoundException;
use Yansongda\Pay\Pay;
use Yansongda\Supports\Collection;
/**
* 文件管理驱动类
* Class FileDriver
* @package core\file
*/
class Alipay extends BasePay
{
/**
* @param array $config
* @return void
* @throws ContainerException
*/
protected function initialize(array $config = [])
{
parent::initialize($config);
$config['app_public_cert_path'] = url_to_path($config['app_public_cert_path'] ?? '');
$config['alipay_public_cert_path'] = url_to_path($config['alipay_public_cert_path'] ?? '');
$config['alipay_root_cert_path'] = url_to_path($config['alipay_root_cert_path'] ?? '');
$this->config = $this->payConfig($config, 'alipay');
Pay::config($this->config);
}
public function mp(array $params)
{
}
/**
* 网页支付
* @param array $params
* @return array
*/
public function web(array $params)
{
return $this->returnUrl(Pay::alipay()->web([
'out_trade_no' => $params['out_trade_no'],
'total_amount' => $params['money'],
'subject' => $params['boby'],
]));
}
/**
* 手机网页支付
* @param array $params
* @return array
*/
public function wap(array $params)
{
return $this->returnUrl(Pay::alipay()->wap([
'out_trade_no' => $params['out_trade_no'],
'total_amount' => $params['money'],
'subject' => $params['boby'],
'quit_url' => $params['quit_url'] ?? '',//用户付款中途退出返回商户网站的地址, 一般是商品详情页或购物车页
'_method' => 'get',
]));
}
/**
* app支付
* @param array $params
* @return array
*/
public function app(array $params)
{
return $this->returnUrl(Pay::alipay()->app([
'out_trade_no' => $params['out_trade_no'],
'total_amount' => $params['money'],
'subject' => $params['boby'],//用户付款中途退出返回商户网站的地址, 一般是商品详情页或购物车页
]));
}
/**
* 小程序支付
* @param array $params
* @return Collection
*/
public function mini(array $params)
{
return Pay::alipay()->mini([
'out_trade_no' => $params['out_trade_no'],
'total_amount' => $params['money'],
'subject' => $params['boby'],
'buyer_id' => $params['buyer_id'],//买家支付宝用户ID 注:交易的买家与卖家不能相同。
]);
}
/**
* 付款码支付
* @param array $params
* @return Collection
*/
public function pos(array $params)
{
return Pay::alipay()->pos([
'out_trade_no' => $params['out_trade_no'],
'auth_code' => $params['auth_code'],//付授权码。 当面付场景传买家的付款码25~30开头的长度为16~24位的数字实际字符串长度以开发者获取的付款码长度为准或者刷脸标识串fp开头的35位字符串
'total_amount' => $params['money'],
'subject' => $params['boby'],
]);
}
/**
* 扫码支付
* @param array $params
* @return Collection
*/
public function scan(array $params)
{
return Pay::alipay()->scan([
'out_trade_no' => $params['out_trade_no'],
'total_amount' => $params['money'],
'subject' => $params['boby'],
]);
}
/**
* 转账
* @param array $params
* @return array
*/
public function transfer(array $params)
{
$result = $this->returnFormat(Pay::alipay()->transfer([
'out_biz_no' => $params['transfer_no'],
'trans_amount' => $params['money'],
'product_code' => $params['product_code'] ?: 'TRANS_ACCOUNT_NO_PWD',//业务产品码,单笔无密转账到支付宝账户固定为 : TRANS_ACCOUNT_NO_PWD 收发现金红包固定为 : STD_RED_PACKET
'biz_scene' => $params['scene'] ?: 'DIRECT_TRANSFER',//描述特定的业务场景可传的参数如下DIRECT_TRANSFER单笔无密转账到支付宝B2C现金红包;PERSONAL_COLLECTIONC2C现金红包-领红包
'payee_info' => [//收款方信息
'identity' => $params['to_no'],//参与方的唯一标识
'identity_type' => $params['to_type'] ?: 'ALIPAY_LOGON_ID',//参与方的标识类型目前支持如下类型1、ALIPAY_USER_ID 支付宝的会员ID2、ALIPAY_LOGON_ID支付宝登录号支持邮箱和手机号格式3、ALIPAY_OPEN_ID支付宝openid
'name' => $params['to_name'],//参与方真实姓名如果非空将校验收款支付宝账号姓名一致性。当identity_type=ALIPAY_LOGON_ID时本字段必填。
],
]));
if (!empty($result['msg']) && $result['msg'] != 'Success') {
throw new PayException($result['sub_msg']);
} else {
$status = $result['status'];
$status_array = array(
'SUCCESS' => TransferDict::SUCCESS,
'WAIT_PAY' => TransferDict::WAIT,
'CLOSED' => TransferDict::FAIL,
'FAIL' => TransferDict::FAIL
);
$res = array(
'status' => $status_array[$status],
);
if ($status == 'FAIL') {
$res['fail_reason'] = $result['fail_reason'];
}
}
return $res;
}
/**
* 支付关闭
* @param string $out_trade_no
* @return bool
* @throws ContainerException
* @throws InvalidParamsException
* @throws ServiceNotFoundException
*/
public function close(string $out_trade_no)
{
$result = $this->returnFormat(Pay::alipay()->close([
'out_trade_no' => $out_trade_no,
]));
//todo 支付宝关闭异步回调
if (!empty($result['msg']) && $result['msg'] == 'Success') {
return true;
} else {
return false;
}
}
/**
* 退款
* @param array $params
* @return array|false
* @throws ContainerException
* @throws InvalidParamsException
* @throws ServiceNotFoundException
*/
public function refund(array $params)
{
$out_trade_no = $params['out_trade_no'];
$money = $params['money'];
// $total = $params['total'];
$refund_no = $params['refund_no'];
$result = $this->returnFormat(Pay::alipay()->refund([
'out_trade_no' => $out_trade_no,
'refund_amount' => $money,
'out_request_no' => $refund_no
]));
if (!empty($result['msg']) && $result['msg'] == 'Success') {
$fund_change = $result['fund_change'];//退款是否成功可以根据同步响应的 fund_change 参数来判断fund_change 表示本次退款是否发生了资金变化,返回 Y 表示退款成功,返回 N 则表示本次退款未发生资金变动 。
if ($fund_change == 'Y') {
$status = RefundDict::SUCCESS;
} else {
$status = RefundDict::DEALING;
}
return [
'status' => $status,
'refund_no' => $refund_no,
'out_trade_no' => $out_trade_no
];
} else {
//todo 这儿可以抛出错误
return false;
}
}
/**
* 支部异步回调
* @param string $action
* @param callable $callback
* @return ResponseInterface|string
*/
public function notify(string $action, callable $callback)
{
try {
$result = Pay::alipay()->callback();
//通过返回的值
if (!empty($result)) {//成功
if ($action == 'pay') {
//todo 这儿需要具体设计
$temp_data = array(
'mchid' => $result['seller_id'],
'trade_no' => $result['trade_no'],
'result' => $result,
'status' => OnlinePayDict::getAliPayStatus($result['trade_status'])
);
$callback_result = $callback($result['out_trade_no'], $temp_data);
if (is_bool($callback_result) && $callback_result) {
return Pay::alipay()->success();
}
}
}
return $this->fail();
} catch ( Throwable $e ) {
return $this->fail();
}
}
/**
* 查询普通支付订单
* @param array $params
* @return array
* @throws ContainerException
* @throws InvalidParamsException
* @throws ServiceNotFoundException
*/
public function getOrder(array $params = [])
{
$out_trade_no = $params['out_trade_no'];
$order = [
'out_trade_no' => $out_trade_no,
];
$result = $this->returnFormat(Pay::alipay()->find($order));
if (!empty($result['msg']) && $result['msg'] == 'Success') {
return [
'status' => OnlinePayDict::getAliPayStatus($result['trade_status'])
];
} else {
if (!empty($result['sub_code']) && $result['sub_code'] == 'ACQ.ACQ.SYSTEM_ERROR') {
throw new PayException($result['msg']);
} else {
return [];
}
}
}
/**
* 查询退款单据
* @param string $out_trade_no
* @param string|null $refund_no
* @return array
* @throws ContainerException
* @throws InvalidParamsException
* @throws ServiceNotFoundException
*/
public function getRefund(string $out_trade_no, ?string $refund_no)
{
$order = [
'out_trade_no' => $out_trade_no,
'out_request_no' => $refund_no,
'_type' => 'refund',
];
$result = $this->returnFormat(Pay::alipay()->find($order));
if (!empty($result['msg']) && $result['msg'] == 'Success') {
$refund_status = $result['refund_status'] ?? '';
if ($refund_status == 'REFUND_SUCCESS') {
$status = RefundDict::SUCCESS;
} else {
$status = RefundDict::DEALING;
}
return [
'status' => $status,
'refund_no' => $refund_no,
'out_trade_no' => $out_trade_no
];
} else {
if (!empty($result['sub_code']) && $result['sub_code'] == 'ACQ.ACQ.SYSTEM_ERROR') {
throw new PayException($result['msg']);
} else {
return [];
}
}
}
/**
* 获取转账订单
* @param string $transfer_no
* @return array
* @throws ContainerException
* @throws InvalidParamsException
* @throws ServiceNotFoundException
*/
public function getTransfer(string $transfer_no)
{
$order = [
'out_biz_no' => $transfer_no,
'_type' => 'transfer'
];
$result = $this->returnFormat(Pay::alipay()->find($order));
if (!empty($result['msg']) && $result['msg'] == 'Success') {
$status = $result['SUCCESS'] ?? '';
$status_array = array(
'SUCCESS' => TransferDict::SUCCESS,
'WAIT_PAY' => TransferDict::WAIT,
'CLOSED' => TransferDict::FAIL,
'FAIL' => TransferDict::FAIL
);
return [
'status' => $status_array[$status],
'transfer_no' => $transfer_no
];
} else {
if (!empty($result['sub_code']) && $result['sub_code'] == 'ACQ.ACQ.SYSTEM_ERROR') {
throw new PayException($result['msg']);
} else {
return [];
}
}
}
public function fail()
{
return 'fail';
}
public function returnUrl($params)
{
return ['url' => $params->getHeader('Location')[0]];
}
}