Skip to content

Commit

Permalink
merge from v3
Browse files Browse the repository at this point in the history
  • Loading branch information
yansongda committed Jun 2, 2021
2 parents d408430 + f410b28 commit 56c44b7
Show file tree
Hide file tree
Showing 8 changed files with 134 additions and 35 deletions.
22 changes: 11 additions & 11 deletions .github/workflows/Linter.yml
@@ -1,23 +1,23 @@
name: Linter
name: Coding Style
on: [push, pull_request]

jobs:
php_cs_fixer:
name: php_cs_fixer-php-${{ matrix.php }}
runs-on: ubuntu-latest
name: php_cs_fixer
runs-on: "${{ matrix.os }}"
strategy:
fail-fast: false
fail-fast: true
matrix:
php:
- 7.3
os: [ubuntu-latest]
php-version:
- 7.4
container:
image: yansongda/php-fpm:${{ matrix.php }}
steps:
- name: Install Git
run: apt-get update && apt-get install -y git
- name: Checkout Code
uses: actions/checkout@master
uses: actions/checkout@v2
- name: PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
- name: Install Dependencies
run: composer install --no-progress
- name: Run PHP-CS-Fixer
Expand Down
19 changes: 10 additions & 9 deletions .github/workflows/Tester.yml
Expand Up @@ -3,21 +3,22 @@ on: [push, pull_request]

jobs:
PHPUnit:
name: php-${{ matrix.php }}
runs-on: ubuntu-latest
name: php-${{ matrix.php-version }}
runs-on: "${{ matrix.os }}"
strategy:
fail-fast: false
fail-fast: true
matrix:
php:
os: [ ubuntu-latest ]
php-version:
- 7.3
- 7.4
container:
image: yansongda/php-fpm:${{ matrix.php }}
steps:
- name: Install Git
run: apt-get update && apt-get install -y git
- name: Checkout Code
uses: actions/checkout@master
uses: actions/checkout@v2
- name: PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
- name: Install Dependencies
run: composer install --no-progress
- name: Run PHPUnit
Expand Down
2 changes: 1 addition & 1 deletion src/Exception/Exception.php
Expand Up @@ -35,7 +35,7 @@ class Exception extends \Exception

public const INVALID_PACKER = 3001;

public const ALIPAY_PRIVATE_KEY_ERROR = 3002;
public const ALIPAY_CONFIG_ERROR = 3002;

/*
* 关于参数.
Expand Down
10 changes: 7 additions & 3 deletions src/Plugin/Alipay/FilterPlugin.php
Expand Up @@ -17,12 +17,16 @@ class FilterPlugin implements PluginInterface
public function assembly(Rocket $rocket, Closure $next): Rocket
{
$payload = $rocket->getPayload()->filter(function ($v, $k) {
return '' !== $v && !is_null($v) && 'sign' != $k && !Str::startsWith($k, '_');
return '' !== $v && !is_null($v) && 'sign' != $k;
});

$payload->set('biz_content', json_encode($payload->get('biz_content')));
$contents = array_filter($payload->get('biz_content'), function ($v, $k) {
return !Str::startsWith($k, '_');
}, ARRAY_FILTER_USE_BOTH);

$rocket->setPayload($payload);
$rocket->setPayload(
$payload->merge(['biz_content' => json_encode($contents)])
);

return $next($rocket);
}
Expand Down
93 changes: 93 additions & 0 deletions src/Plugin/Alipay/PreparePlugin.php
Expand Up @@ -6,6 +6,7 @@

use Closure;
use Yansongda\Pay\Contract\PluginInterface;
use Yansongda\Pay\Exception\InvalidConfigException;
use Yansongda\Pay\Rocket;

class PreparePlugin implements PluginInterface
Expand All @@ -14,6 +15,7 @@ class PreparePlugin implements PluginInterface
* @throws \Yansongda\Pay\Exception\ContainerDependencyException
* @throws \Yansongda\Pay\Exception\ContainerException
* @throws \Yansongda\Pay\Exception\ServiceNotFoundException
* @throws \Yansongda\Pay\Exception\InvalidConfigException
*/
public function assembly(Rocket $rocket, Closure $next): Rocket
{
Expand All @@ -26,6 +28,7 @@ public function assembly(Rocket $rocket, Closure $next): Rocket
* @throws \Yansongda\Pay\Exception\ContainerDependencyException
* @throws \Yansongda\Pay\Exception\ContainerException
* @throws \Yansongda\Pay\Exception\ServiceNotFoundException
* @throws \Yansongda\Pay\Exception\InvalidConfigException
*/
protected function getPayload(array $params): array
{
Expand All @@ -41,7 +44,97 @@ protected function getPayload(array $params): array
'version' => '1.0',
'notify_url' => get_alipay_config($params)->get('notify_url', ''),
'app_auth_token' => '',
'app_cert_sn' => $this->getAppCertSn($params),
'alipay_root_cert_sn' => $this->getAlipayRootCertSn($params),
'biz_content' => [],
];
}

/**
* @throws \Yansongda\Pay\Exception\ContainerDependencyException
* @throws \Yansongda\Pay\Exception\ContainerException
* @throws \Yansongda\Pay\Exception\ServiceNotFoundException
* @throws \Yansongda\Pay\Exception\InvalidConfigException
*/
protected function getAppCertSn(array $params): string
{
$path = get_alipay_config($params)->get('app_public_cert_path');

if (is_null($path)) {
throw new InvalidConfigException(InvalidConfigException::ALIPAY_CONFIG_ERROR, 'Missing Alipay Config -- [app_public_cert_path]');
}

$cert = file_get_contents($path);
$ssl = openssl_x509_parse($cert);

return $this->getCertSn($ssl['issuer'], $ssl['serialNumber']);
}

/**
* @throws \Yansongda\Pay\Exception\ContainerDependencyException
* @throws \Yansongda\Pay\Exception\ContainerException
* @throws \Yansongda\Pay\Exception\InvalidConfigException
* @throws \Yansongda\Pay\Exception\ServiceNotFoundException
*/
protected function getAlipayRootCertSn(array $params): string
{
$path = get_alipay_config($params)->get('alipay_root_cert_path');

if (is_null($path)) {
throw new InvalidConfigException(InvalidConfigException::ALIPAY_CONFIG_ERROR, 'Missing Alipay Config -- [alipay_root_cert_path]');
}

$sn = '';
foreach (explode("\r\n\r\n", file_get_contents($path)) as $cert) {
$detail = $this->formatCert(openssl_x509_parse($cert));

if ('sha1WithRSAEncryption' == $detail['signatureTypeLN'] || 'sha256WithRSAEncryption' == $detail['signatureTypeLN']) {
$sn .= $this->getCertSn($detail['issuer'], $detail['serialNumber']).'_';
}
}

return substr($sn, 0, -1);
}

protected function getCertSn(array $issuer, string $serialNumber): string
{
return md5(
$this->array2string(array_reverse($issuer)).$serialNumber
);
}

protected function array2string(array $array): string
{
$string = [];

foreach ($array as $key => $value) {
$string[] = $key.'='.$value;
}

return implode(',', $string);
}

protected function formatCert(array $ssl): array
{
if (0 === strpos($ssl['serialNumber'], '0x')) {
$ssl['serialNumber'] = $this->hex2dec($ssl['serialNumber']);
}

return $ssl;
}

protected function hex2dec(string $hex): string
{
$dec = 0;
$len = strlen($hex);

for ($i = 1; $i <= $len; ++$i) {
$dec = bcadd(
$dec,
bcmul(strval(hexdec($hex[$i - 1])), bcpow('16', strval($len - $i)))
);
}

return $dec;
}
}
2 changes: 1 addition & 1 deletion src/Plugin/Alipay/RadarPlugin.php
Expand Up @@ -43,7 +43,7 @@ protected function getRequest(Rocket $rocket): RequestInterface

protected function getMethod(Rocket $rocket): string
{
return $rocket->getParams()['_method'] ?? 'POST';
return strtoupper($rocket->getParams()['_method'] ?? 'POST');
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/Plugin/Alipay/Shortcut/WebShortcut.php
Expand Up @@ -11,6 +11,7 @@
use Yansongda\Pay\Contract\ShortcutInterface;
use Yansongda\Pay\Plugin\Alipay\Trade\PagePayPlugin;
use Yansongda\Pay\Rocket;
use Yansongda\Supports\Arr;
use Yansongda\Supports\Collection;

class WebShortcut implements ShortcutInterface
Expand Down Expand Up @@ -44,7 +45,7 @@ public function assembly(Rocket $rocket, Closure $next): Rocket

protected function buildRedirect(string $endpoint, Collection $payload): Response
{
$url = $endpoint.'&'.http_build_query($payload->all());
$url = $endpoint.'?'.Arr::query($payload->all());

$content = sprintf('<!DOCTYPE html>
<html lang="en">
Expand All @@ -65,7 +66,7 @@ protected function buildRedirect(string $endpoint, Collection $payload): Respons

protected function buildHtml(string $endpoint, Collection $payload): Response
{
$sHtml = "<form id='alipay_submit' name='alipay_submit' action='".$endpoint."' method='POST'>";
$sHtml = "<form id='alipay_submit' name='alipay_submit' action='".$endpoint."?charset=utf-8' method='POST'>";
foreach ($payload->all() as $key => $val) {
$val = str_replace("'", '&apos;', $val);
$sHtml .= "<input type='hidden' name='".$key."' value='".$val."'/>";
Expand Down
16 changes: 8 additions & 8 deletions src/Plugin/Alipay/SignPlugin.php
Expand Up @@ -7,9 +7,7 @@
use Closure;
use Yansongda\Pay\Contract\PluginInterface;
use Yansongda\Pay\Exception\InvalidConfigException;
use Yansongda\Pay\Logger;
use Yansongda\Pay\Rocket;
use Yansongda\Supports\Arr;
use Yansongda\Supports\Collection;
use Yansongda\Supports\Str;

Expand All @@ -30,8 +28,6 @@ public function assembly(Rocket $rocket, Closure $next): Rocket

$sign = base64_encode($sign);

Logger::debug('支付宝支付生成签名', ['params' => $payload, 'sign' => $sign]);

!is_resource($privateKey) ?: openssl_free_key($privateKey);

$rocket->mergePayload(['sign' => $sign]);
Expand All @@ -49,10 +45,10 @@ public function assembly(Rocket $rocket, Closure $next): Rocket
*/
protected function getPrivateKey(array $params)
{
$privateKey = get_alipay_config($params)->get('private_key');
$privateKey = get_alipay_config($params)->get('app_secret_cert');

if (is_null($privateKey)) {
throw new InvalidConfigException(InvalidConfigException::ALIPAY_PRIVATE_KEY_ERROR, 'Missing Alipay Config -- [private_key]');
throw new InvalidConfigException(InvalidConfigException::ALIPAY_CONFIG_ERROR, 'Missing Alipay Config -- [app_secret_cert]');
}

$privateKey = "-----BEGIN RSA PRIVATE KEY-----\n".
Expand All @@ -70,8 +66,12 @@ protected function getPrivateKey(array $params)

protected function getSignContent(Collection $payload): string
{
$payload = $payload->sortKeys();
$result = '';

foreach ($payload->sortKeys()->all() as $key => $value) {
$result .= $key.'='.$value.'&';
}

return Arr::query($payload->all());
return substr($result, 0, -1);
}
}

0 comments on commit 56c44b7

Please sign in to comment.