init
- 框架初始化 - 安装插件 - 修复PHP8.4报错
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay;
|
||||
|
||||
use Closure;
|
||||
use Yansongda\Pay\Contract\PluginInterface;
|
||||
use Yansongda\Pay\Direction\NoHttpRequestDirection;
|
||||
use Yansongda\Pay\Exception\ContainerException;
|
||||
use Yansongda\Pay\Exception\Exception;
|
||||
use Yansongda\Pay\Exception\InvalidConfigException;
|
||||
use Yansongda\Pay\Exception\InvalidResponseException;
|
||||
use Yansongda\Pay\Exception\ServiceNotFoundException;
|
||||
use Yansongda\Pay\Logger;
|
||||
use Yansongda\Pay\Rocket;
|
||||
use Yansongda\Supports\Collection;
|
||||
use Yansongda\Supports\Str;
|
||||
|
||||
use function Yansongda\Pay\verify_unipay_sign;
|
||||
|
||||
class CallbackPlugin implements PluginInterface
|
||||
{
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws InvalidConfigException
|
||||
* @throws ServiceNotFoundException
|
||||
* @throws InvalidResponseException
|
||||
*/
|
||||
public function assembly(Rocket $rocket, Closure $next): Rocket
|
||||
{
|
||||
Logger::debug('[unipay][CallbackPlugin] 插件开始装载', ['rocket' => $rocket]);
|
||||
|
||||
$this->formatPayload($rocket);
|
||||
|
||||
$params = $rocket->getParams();
|
||||
$signature = $params['signature'] ?? false;
|
||||
|
||||
if (!$signature) {
|
||||
throw new InvalidResponseException(Exception::INVALID_RESPONSE_SIGN, '', $params);
|
||||
}
|
||||
|
||||
verify_unipay_sign($params, $rocket->getPayload()->sortKeys()->toString(), $signature);
|
||||
|
||||
$rocket->setDirection(NoHttpRequestDirection::class)
|
||||
->setDestination($rocket->getPayload())
|
||||
;
|
||||
|
||||
Logger::info('[unipay][CallbackPlugin] 插件装载完毕', ['rocket' => $rocket]);
|
||||
|
||||
return $next($rocket);
|
||||
}
|
||||
|
||||
protected function formatPayload(Rocket $rocket): void
|
||||
{
|
||||
$payload = (new Collection($rocket->getParams()))
|
||||
->filter(fn ($v, $k) => 'signature' != $k && !Str::startsWith($k, '_'))
|
||||
;
|
||||
|
||||
$rocket->setPayload($payload);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay;
|
||||
|
||||
use Closure;
|
||||
use Psr\Http\Message\RequestInterface;
|
||||
use Yansongda\Pay\Contract\PluginInterface;
|
||||
use Yansongda\Pay\Exception\ContainerException;
|
||||
use Yansongda\Pay\Exception\ServiceNotFoundException;
|
||||
use Yansongda\Pay\Logger;
|
||||
use Yansongda\Pay\Pay;
|
||||
use Yansongda\Pay\Provider\Unipay;
|
||||
use Yansongda\Pay\Request;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
use function Yansongda\Pay\get_unipay_config;
|
||||
|
||||
abstract class GeneralPlugin implements PluginInterface
|
||||
{
|
||||
/**
|
||||
* @throws ServiceNotFoundException
|
||||
* @throws ContainerException
|
||||
*/
|
||||
public function assembly(Rocket $rocket, Closure $next): Rocket
|
||||
{
|
||||
Logger::debug('[unipay][GeneralPlugin] 通用插件开始装载', ['rocket' => $rocket]);
|
||||
|
||||
$rocket->setRadar($this->getRequest($rocket));
|
||||
$this->doSomething($rocket);
|
||||
|
||||
Logger::info('[unipay][GeneralPlugin] 通用插件装载完毕', ['rocket' => $rocket]);
|
||||
|
||||
return $next($rocket);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
protected function getRequest(Rocket $rocket): RequestInterface
|
||||
{
|
||||
return new Request(
|
||||
$this->getMethod(),
|
||||
$this->getUrl($rocket),
|
||||
$this->getHeaders(),
|
||||
);
|
||||
}
|
||||
|
||||
protected function getMethod(): string
|
||||
{
|
||||
return 'POST';
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
protected function getUrl(Rocket $rocket): string
|
||||
{
|
||||
$url = $this->getUri($rocket);
|
||||
|
||||
if (0 === strpos($url, 'http')) {
|
||||
return $url;
|
||||
}
|
||||
|
||||
$config = get_unipay_config($rocket->getParams());
|
||||
|
||||
return Unipay::URL[$config['mode'] ?? Pay::MODE_NORMAL].$url;
|
||||
}
|
||||
|
||||
protected function getHeaders(): array
|
||||
{
|
||||
return [
|
||||
'User-Agent' => 'yansongda/pay-v3',
|
||||
'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
|
||||
];
|
||||
}
|
||||
|
||||
abstract protected function doSomething(Rocket $rocket): void;
|
||||
|
||||
abstract protected function getUri(Rocket $rocket): string;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay;
|
||||
|
||||
use Closure;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use Yansongda\Pay\Contract\PluginInterface;
|
||||
use Yansongda\Pay\Logger;
|
||||
use Yansongda\Pay\Rocket;
|
||||
use Yansongda\Supports\Collection;
|
||||
|
||||
class HtmlResponsePlugin implements PluginInterface
|
||||
{
|
||||
public function assembly(Rocket $rocket, Closure $next): Rocket
|
||||
{
|
||||
/* @var Rocket $rocket */
|
||||
$rocket = $next($rocket);
|
||||
|
||||
Logger::debug('[unipay][HtmlResponsePlugin] 插件开始装载', ['rocket' => $rocket]);
|
||||
|
||||
$radar = $rocket->getRadar();
|
||||
|
||||
$response = $this->buildHtml($radar->getUri()->__toString(), $rocket->getPayload());
|
||||
|
||||
$rocket->setDestination($response);
|
||||
|
||||
Logger::info('[unipay][HtmlResponsePlugin] 插件装载完毕', ['rocket' => $rocket]);
|
||||
|
||||
return $rocket;
|
||||
}
|
||||
|
||||
protected function buildHtml(string $endpoint, Collection $payload): Response
|
||||
{
|
||||
$sHtml = "<form id='pay_form' name='pay_form' action='".$endpoint."' method='POST'>";
|
||||
foreach ($payload->all() as $key => $val) {
|
||||
$sHtml .= "<input type='hidden' name='".$key."' value='".$val."'/>";
|
||||
}
|
||||
$sHtml .= "<input type='submit' value='ok' style='display:none;'></form>";
|
||||
$sHtml .= "<script>document.forms['pay_form'].submit();</script>";
|
||||
|
||||
return new Response(200, [], $sHtml);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay;
|
||||
|
||||
use Closure;
|
||||
use Yansongda\Pay\Contract\PluginInterface;
|
||||
use Yansongda\Pay\Exception\ContainerException;
|
||||
use Yansongda\Pay\Exception\InvalidConfigException;
|
||||
use Yansongda\Pay\Exception\InvalidResponseException;
|
||||
use Yansongda\Pay\Exception\ServiceNotFoundException;
|
||||
use Yansongda\Pay\Logger;
|
||||
use Yansongda\Pay\Rocket;
|
||||
use Yansongda\Supports\Collection;
|
||||
|
||||
use function Yansongda\Pay\should_do_http_request;
|
||||
use function Yansongda\Pay\verify_unipay_sign;
|
||||
|
||||
class LaunchPlugin implements PluginInterface
|
||||
{
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws InvalidConfigException
|
||||
* @throws InvalidResponseException
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
public function assembly(Rocket $rocket, Closure $next): Rocket
|
||||
{
|
||||
/* @var Rocket $rocket */
|
||||
$rocket = $next($rocket);
|
||||
|
||||
Logger::debug('[unipay][LaunchPlugin] 插件开始装载', ['rocket' => $rocket]);
|
||||
|
||||
if (should_do_http_request($rocket->getDirection())) {
|
||||
$response = Collection::wrap($rocket->getDestination());
|
||||
$signature = $response->get('signature');
|
||||
$response->forget('signature');
|
||||
|
||||
verify_unipay_sign(
|
||||
$rocket->getParams(),
|
||||
$response->sortKeys()->toString(),
|
||||
$signature
|
||||
);
|
||||
|
||||
$rocket->setDestination($response);
|
||||
}
|
||||
|
||||
Logger::info('[unipay][LaunchPlugin] 插件装载完毕', ['rocket' => $rocket]);
|
||||
|
||||
return $rocket;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\OnlineGateway;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=755&apiservId=448&version=V2.2&bussType=0
|
||||
*/
|
||||
class CancelPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000000',
|
||||
'txnType' => '31',
|
||||
'txnSubType' => '00',
|
||||
'channelType' => '07',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\OnlineGateway;
|
||||
|
||||
use Yansongda\Pay\Direction\ResponseDirection;
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=754&apiservId=448&version=V2.2&bussType=0
|
||||
*/
|
||||
class PagePayPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/frontTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->setDirection(ResponseDirection::class)
|
||||
->mergePayload([
|
||||
'bizType' => '000201',
|
||||
'txnType' => '01',
|
||||
'txnSubType' => '01',
|
||||
'channelType' => '07',
|
||||
])
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\OnlineGateway;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=757&apiservId=448&version=V2.2&bussType=0
|
||||
*/
|
||||
class QueryPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/queryTrans.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000000',
|
||||
'txnType' => '00',
|
||||
'txnSubType' => '00',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\OnlineGateway;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=756&apiservId=448&version=V2.2&bussType=0
|
||||
*/
|
||||
class RefundPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000000',
|
||||
'txnType' => '04',
|
||||
'txnSubType' => '00',
|
||||
'channelType' => '07',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\OnlineGateway;
|
||||
|
||||
use Yansongda\Pay\Direction\ResponseDirection;
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=754&apiservId=448&version=V2.2&bussType=0
|
||||
*/
|
||||
class WapPayPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/frontTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->setDirection(ResponseDirection::class)
|
||||
->mergePayload([
|
||||
'bizType' => '000201',
|
||||
'txnType' => '01',
|
||||
'txnSubType' => '01',
|
||||
'channelType' => '08',
|
||||
])
|
||||
;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay;
|
||||
|
||||
use Closure;
|
||||
use Yansongda\Pay\Contract\PluginInterface;
|
||||
use Yansongda\Pay\Exception\ContainerException;
|
||||
use Yansongda\Pay\Exception\InvalidConfigException;
|
||||
use Yansongda\Pay\Exception\ServiceNotFoundException;
|
||||
use Yansongda\Pay\Logger;
|
||||
use Yansongda\Pay\Rocket;
|
||||
use Yansongda\Pay\Traits\GetUnipayCerts;
|
||||
use Yansongda\Supports\Str;
|
||||
|
||||
use function Yansongda\Pay\get_tenant;
|
||||
use function Yansongda\Pay\get_unipay_config;
|
||||
|
||||
class PreparePlugin implements PluginInterface
|
||||
{
|
||||
use GetUnipayCerts;
|
||||
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws ServiceNotFoundException
|
||||
* @throws InvalidConfigException
|
||||
*/
|
||||
public function assembly(Rocket $rocket, Closure $next): Rocket
|
||||
{
|
||||
Logger::debug('[unipay][PreparePlugin] 插件开始装载', ['rocket' => $rocket]);
|
||||
|
||||
$rocket->mergePayload($this->getPayload($rocket->getParams()));
|
||||
|
||||
Logger::info('[unipay][PreparePlugin] 插件装载完毕', ['rocket' => $rocket]);
|
||||
|
||||
return $next($rocket);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws ServiceNotFoundException
|
||||
* @throws InvalidConfigException
|
||||
*/
|
||||
protected function getPayload(array $params): array
|
||||
{
|
||||
$tenant = get_tenant($params);
|
||||
$config = get_unipay_config($params);
|
||||
|
||||
$init = [
|
||||
'version' => '5.1.0',
|
||||
'encoding' => 'utf-8',
|
||||
'backUrl' => $config['notify_url'] ?? '',
|
||||
'currencyCode' => '156',
|
||||
'accessType' => '0',
|
||||
'signature' => '',
|
||||
'signMethod' => '01',
|
||||
'merId' => $config['mch_id'] ?? '',
|
||||
'frontUrl' => $config['return_url'] ?? '',
|
||||
'certId' => $this->getCertId($tenant, $config),
|
||||
];
|
||||
|
||||
return array_merge(
|
||||
$init,
|
||||
array_filter($params, fn ($v, $k) => !Str::startsWith(strval($k), '_'), ARRAY_FILTER_USE_BOTH),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\QrCode;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=800&apiservId=468&version=V2.2&bussType=0
|
||||
*/
|
||||
class CancelPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000000',
|
||||
'txnType' => '31',
|
||||
'txnSubType' => '00',
|
||||
'channelType' => '08',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\QrCode;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=798&apiservId=468&version=V2.2&bussType=0
|
||||
*/
|
||||
class PosNormalPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000000',
|
||||
'txnType' => '01',
|
||||
'txnSubType' => '06',
|
||||
'channelType' => '08',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\QrCode;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=797&apiservId=468&version=V2.2&bussType=0
|
||||
*/
|
||||
class PosPreAuthPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000201',
|
||||
'txnType' => '02',
|
||||
'txnSubType' => '04',
|
||||
'channelType' => '08',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\QrCode;
|
||||
|
||||
use Yansongda\Pay\Exception\ContainerException;
|
||||
use Yansongda\Pay\Exception\ServiceNotFoundException;
|
||||
use Yansongda\Pay\Pay;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
use function Yansongda\Pay\get_unipay_config;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=792&apiservId=468&version=V2.2&bussType=0
|
||||
*/
|
||||
class QueryPlugin extends \Yansongda\Pay\Plugin\Unipay\OnlineGateway\QueryPlugin
|
||||
{
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
$config = get_unipay_config($rocket->getParams());
|
||||
|
||||
if (Pay::MODE_SANDBOX === ($config['mode'] ?? Pay::MODE_NORMAL)) {
|
||||
return 'https://101.231.204.80:5000/gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
return parent::getUri($rocket);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\QrCode;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=799&apiservId=468&version=V2.2&bussType=0
|
||||
*/
|
||||
class RefundPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000000',
|
||||
'txnType' => '04',
|
||||
'txnSubType' => '00',
|
||||
'channelType' => '08',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\QrCode;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=796&apiservId=468&version=V2.2&bussType=0
|
||||
*/
|
||||
class ScanFeePlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000601',
|
||||
'txnType' => '13',
|
||||
'txnSubType' => '08',
|
||||
'channelType' => '08',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\QrCode;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=793&apiservId=468&version=V2.2&bussType=0
|
||||
*/
|
||||
class ScanNormalPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000000',
|
||||
'txnType' => '01',
|
||||
'txnSubType' => '07',
|
||||
'channelType' => '08',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\QrCode;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=794&apiservId=468&version=V2.2&bussType=0
|
||||
*/
|
||||
class ScanPreAuthPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/backTransReq.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000000',
|
||||
'txnType' => '02',
|
||||
'txnSubType' => '05',
|
||||
'channelType' => '08',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\QrCode;
|
||||
|
||||
use Yansongda\Pay\Plugin\Unipay\GeneralPlugin;
|
||||
use Yansongda\Pay\Rocket;
|
||||
|
||||
/**
|
||||
* @see https://open.unionpay.com/tjweb/acproduct/APIList?acpAPIId=795&apiservId=468&version=V2.2&bussType=0
|
||||
*/
|
||||
class ScanPreOrderPlugin extends GeneralPlugin
|
||||
{
|
||||
protected function getUri(Rocket $rocket): string
|
||||
{
|
||||
return 'gateway/api/order.do';
|
||||
}
|
||||
|
||||
protected function doSomething(Rocket $rocket): void
|
||||
{
|
||||
$rocket->mergePayload([
|
||||
'bizType' => '000000',
|
||||
'txnType' => '01',
|
||||
'txnSubType' => '01',
|
||||
'channelType' => '08',
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay;
|
||||
|
||||
use Closure;
|
||||
use GuzzleHttp\Psr7\Utils;
|
||||
use Yansongda\Pay\Contract\PluginInterface;
|
||||
use Yansongda\Pay\Exception\ContainerException;
|
||||
use Yansongda\Pay\Exception\InvalidConfigException;
|
||||
use Yansongda\Pay\Exception\ServiceNotFoundException;
|
||||
use Yansongda\Pay\Logger;
|
||||
use Yansongda\Pay\Rocket;
|
||||
use Yansongda\Pay\Traits\GetUnipayCerts;
|
||||
use Yansongda\Supports\Collection;
|
||||
|
||||
use function Yansongda\Pay\get_unipay_config;
|
||||
|
||||
class RadarSignPlugin implements PluginInterface
|
||||
{
|
||||
use GetUnipayCerts;
|
||||
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws ServiceNotFoundException
|
||||
* @throws InvalidConfigException
|
||||
*/
|
||||
public function assembly(Rocket $rocket, Closure $next): Rocket
|
||||
{
|
||||
Logger::debug('[unipay][PreparePlugin] 插件开始装载', ['rocket' => $rocket]);
|
||||
|
||||
$this->sign($rocket);
|
||||
|
||||
$this->reRadar($rocket);
|
||||
|
||||
Logger::info('[unipay][PreparePlugin] 插件装载完毕', ['rocket' => $rocket]);
|
||||
|
||||
return $next($rocket);
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws InvalidConfigException
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
protected function sign(Rocket $rocket): void
|
||||
{
|
||||
$payload = $rocket->getPayload()->filter(fn ($v, $k) => 'signature' != $k);
|
||||
$config = $this->getConfig($rocket->getParams());
|
||||
|
||||
$rocket->mergePayload([
|
||||
'signature' => $this->getSignature($config['certs']['pkey'] ?? '', $payload),
|
||||
]);
|
||||
}
|
||||
|
||||
protected function reRadar(Rocket $rocket): void
|
||||
{
|
||||
$body = $this->getBody($rocket->getPayload());
|
||||
$radar = $rocket->getRadar();
|
||||
|
||||
if (!empty($body) && !empty($radar)) {
|
||||
$radar = $radar->withBody(Utils::streamFor($body));
|
||||
|
||||
$rocket->setRadar($radar);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws ContainerException
|
||||
* @throws InvalidConfigException
|
||||
* @throws ServiceNotFoundException
|
||||
*/
|
||||
protected function getConfig(array $params): array
|
||||
{
|
||||
$config = get_unipay_config($params);
|
||||
|
||||
if (empty($config['certs']['pkey'])) {
|
||||
$this->getCertId($params['_config'] ?? 'default', $config);
|
||||
|
||||
$config = get_unipay_config($params);
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
protected function getSignature(string $pkey, Collection $payload): string
|
||||
{
|
||||
$content = $payload->sortKeys()->toString();
|
||||
|
||||
openssl_sign(hash('sha256', $content), $sign, $pkey, 'sha256');
|
||||
|
||||
return base64_encode($sign);
|
||||
}
|
||||
|
||||
protected function getBody(Collection $payload): string
|
||||
{
|
||||
return $payload->query();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\Shortcut;
|
||||
|
||||
use Yansongda\Pay\Contract\ShortcutInterface;
|
||||
use Yansongda\Pay\Exception\Exception;
|
||||
use Yansongda\Pay\Exception\InvalidParamsException;
|
||||
use Yansongda\Pay\Plugin\Unipay\OnlineGateway\CancelPlugin;
|
||||
use Yansongda\Supports\Str;
|
||||
|
||||
class CancelShortcut implements ShortcutInterface
|
||||
{
|
||||
/**
|
||||
* @throws InvalidParamsException
|
||||
*/
|
||||
public function getPlugins(array $params): array
|
||||
{
|
||||
$typeMethod = Str::camel($params['_action'] ?? 'default').'Plugins';
|
||||
|
||||
if (method_exists($this, $typeMethod)) {
|
||||
return $this->{$typeMethod}();
|
||||
}
|
||||
|
||||
throw new InvalidParamsException(Exception::SHORTCUT_MULTI_ACTION_ERROR, "Cancel action [{$typeMethod}] not supported");
|
||||
}
|
||||
|
||||
protected function defaultPlugins(): array
|
||||
{
|
||||
return [
|
||||
CancelPlugin::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function qrCodePlugins(): array
|
||||
{
|
||||
return [
|
||||
\Yansongda\Pay\Plugin\Unipay\QrCode\CancelPlugin::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\Shortcut;
|
||||
|
||||
use Yansongda\Pay\Contract\ShortcutInterface;
|
||||
use Yansongda\Pay\Exception\Exception;
|
||||
use Yansongda\Pay\Exception\InvalidParamsException;
|
||||
use Yansongda\Pay\Plugin\Unipay\QrCode\PosNormalPlugin;
|
||||
use Yansongda\Pay\Plugin\Unipay\QrCode\PosPreAuthPlugin;
|
||||
use Yansongda\Supports\Str;
|
||||
|
||||
class PosShortcut implements ShortcutInterface
|
||||
{
|
||||
/**
|
||||
* @throws InvalidParamsException
|
||||
*/
|
||||
public function getPlugins(array $params): array
|
||||
{
|
||||
$typeMethod = Str::camel($params['_action'] ?? 'default').'Plugins';
|
||||
|
||||
if (method_exists($this, $typeMethod)) {
|
||||
return $this->{$typeMethod}();
|
||||
}
|
||||
|
||||
throw new InvalidParamsException(Exception::SHORTCUT_MULTI_ACTION_ERROR, "Pos action [{$typeMethod}] not supported");
|
||||
}
|
||||
|
||||
protected function defaultPlugins(): array
|
||||
{
|
||||
return [
|
||||
PosNormalPlugin::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function preAuthPlugins(): array
|
||||
{
|
||||
return [
|
||||
PosPreAuthPlugin::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\Shortcut;
|
||||
|
||||
use Yansongda\Pay\Contract\ShortcutInterface;
|
||||
use Yansongda\Pay\Exception\Exception;
|
||||
use Yansongda\Pay\Exception\InvalidParamsException;
|
||||
use Yansongda\Pay\Plugin\Unipay\OnlineGateway\QueryPlugin;
|
||||
use Yansongda\Supports\Str;
|
||||
|
||||
class QueryShortcut implements ShortcutInterface
|
||||
{
|
||||
/**
|
||||
* @throws InvalidParamsException
|
||||
*/
|
||||
public function getPlugins(array $params): array
|
||||
{
|
||||
$typeMethod = Str::camel($params['_action'] ?? 'default').'Plugins';
|
||||
|
||||
if (method_exists($this, $typeMethod)) {
|
||||
return $this->{$typeMethod}();
|
||||
}
|
||||
|
||||
throw new InvalidParamsException(Exception::SHORTCUT_MULTI_ACTION_ERROR, "Query action [{$typeMethod}] not supported");
|
||||
}
|
||||
|
||||
protected function defaultPlugins(): array
|
||||
{
|
||||
return [
|
||||
QueryPlugin::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function qrCodePlugins(): array
|
||||
{
|
||||
return [
|
||||
\Yansongda\Pay\Plugin\Unipay\QrCode\QueryPlugin::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\Shortcut;
|
||||
|
||||
use Yansongda\Pay\Contract\ShortcutInterface;
|
||||
use Yansongda\Pay\Exception\Exception;
|
||||
use Yansongda\Pay\Exception\InvalidParamsException;
|
||||
use Yansongda\Pay\Plugin\Unipay\OnlineGateway\RefundPlugin;
|
||||
use Yansongda\Supports\Str;
|
||||
|
||||
class RefundShortcut implements ShortcutInterface
|
||||
{
|
||||
/**
|
||||
* @throws InvalidParamsException
|
||||
*/
|
||||
public function getPlugins(array $params): array
|
||||
{
|
||||
$typeMethod = Str::camel($params['_action'] ?? 'default').'Plugins';
|
||||
|
||||
if (method_exists($this, $typeMethod)) {
|
||||
return $this->{$typeMethod}();
|
||||
}
|
||||
|
||||
throw new InvalidParamsException(Exception::SHORTCUT_MULTI_ACTION_ERROR, "Refund action [{$typeMethod}] not supported");
|
||||
}
|
||||
|
||||
protected function defaultPlugins(): array
|
||||
{
|
||||
return [
|
||||
RefundPlugin::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function qrCodePlugins(): array
|
||||
{
|
||||
return [
|
||||
\Yansongda\Pay\Plugin\Unipay\QrCode\RefundPlugin::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\Shortcut;
|
||||
|
||||
use Yansongda\Pay\Contract\ShortcutInterface;
|
||||
use Yansongda\Pay\Exception\Exception;
|
||||
use Yansongda\Pay\Exception\InvalidParamsException;
|
||||
use Yansongda\Pay\Plugin\Unipay\QrCode\ScanFeePlugin;
|
||||
use Yansongda\Pay\Plugin\Unipay\QrCode\ScanNormalPlugin;
|
||||
use Yansongda\Pay\Plugin\Unipay\QrCode\ScanPreAuthPlugin;
|
||||
use Yansongda\Pay\Plugin\Unipay\QrCode\ScanPreOrderPlugin;
|
||||
use Yansongda\Supports\Str;
|
||||
|
||||
class ScanShortcut implements ShortcutInterface
|
||||
{
|
||||
/**
|
||||
* @throws InvalidParamsException
|
||||
*/
|
||||
public function getPlugins(array $params): array
|
||||
{
|
||||
$typeMethod = Str::camel($params['_action'] ?? 'default').'Plugins';
|
||||
|
||||
if (method_exists($this, $typeMethod)) {
|
||||
return $this->{$typeMethod}();
|
||||
}
|
||||
|
||||
throw new InvalidParamsException(Exception::SHORTCUT_MULTI_ACTION_ERROR, "Scan action [{$typeMethod}] not supported");
|
||||
}
|
||||
|
||||
protected function defaultPlugins(): array
|
||||
{
|
||||
return [
|
||||
ScanNormalPlugin::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function preAuthPlugins(): array
|
||||
{
|
||||
return [
|
||||
ScanPreAuthPlugin::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function preOrderPlugins(): array
|
||||
{
|
||||
return [
|
||||
ScanPreOrderPlugin::class,
|
||||
];
|
||||
}
|
||||
|
||||
protected function feePlugins(): array
|
||||
{
|
||||
return [
|
||||
ScanFeePlugin::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\Shortcut;
|
||||
|
||||
use Yansongda\Pay\Contract\ShortcutInterface;
|
||||
use Yansongda\Pay\Plugin\Unipay\HtmlResponsePlugin;
|
||||
use Yansongda\Pay\Plugin\Unipay\OnlineGateway\WapPayPlugin;
|
||||
|
||||
class WapShortcut implements ShortcutInterface
|
||||
{
|
||||
public function getPlugins(array $params): array
|
||||
{
|
||||
return [
|
||||
WapPayPlugin::class,
|
||||
HtmlResponsePlugin::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Yansongda\Pay\Plugin\Unipay\Shortcut;
|
||||
|
||||
use Yansongda\Pay\Contract\ShortcutInterface;
|
||||
use Yansongda\Pay\Plugin\Unipay\HtmlResponsePlugin;
|
||||
use Yansongda\Pay\Plugin\Unipay\OnlineGateway\PagePayPlugin;
|
||||
|
||||
class WebShortcut implements ShortcutInterface
|
||||
{
|
||||
public function getPlugins(array $params): array
|
||||
{
|
||||
return [
|
||||
PagePayPlugin::class,
|
||||
HtmlResponsePlugin::class,
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user