slince /
youzan-pay
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /* |
||
| 3 | * This file is part of the slince/youzan-pay package. |
||
| 4 | * |
||
| 5 | * (c) Slince <[email protected]> |
||
| 6 | * |
||
| 7 | * For the full copyright and license information, please view the LICENSE |
||
| 8 | * file that was distributed with this source code. |
||
| 9 | */ |
||
| 10 | |||
| 11 | namespace Slince\YouzanPay; |
||
| 12 | |||
| 13 | use GuzzleHttp\Client; |
||
| 14 | use Slince\YouzanPay\Api\QRCode; |
||
| 15 | use Slince\YouzanPay\Api\Token; |
||
| 16 | use Slince\YouzanPay\Api\Trade; |
||
| 17 | |||
| 18 | class Requestor |
||
| 19 | { |
||
| 20 | /** |
||
| 21 | * @var ApiContext |
||
| 22 | */ |
||
| 23 | protected static $apiContext; |
||
| 24 | |||
| 25 | /** |
||
| 26 | * @var Client |
||
| 27 | */ |
||
| 28 | protected static $httpClient; |
||
| 29 | |||
| 30 | /** |
||
| 31 | * @var Token |
||
| 32 | */ |
||
| 33 | protected static $token; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * 获取 access token. |
||
| 37 | * |
||
| 38 | * @var string |
||
| 39 | */ |
||
| 40 | const GET_TOKEN_ENDPOINT = 'https://open.youzan.com/oauth/token'; |
||
| 41 | |||
| 42 | /** |
||
| 43 | * 创建支付二维码 |
||
| 44 | * |
||
| 45 | * @var string |
||
| 46 | */ |
||
| 47 | const CREATE_QR_ENDPOINT = 'https://open.youzan.com/api/oauthentry/youzan.pay.qrcode/3.0.0/create'; |
||
| 48 | |||
| 49 | /** |
||
| 50 | * 获取支付二维码 |
||
| 51 | * |
||
| 52 | * @var string |
||
| 53 | */ |
||
| 54 | const GET_QR_ENDPOINT = 'https://open.youzan.com/api/oauthentry/youzan.pay.qrcode/3.0.0/get'; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * 获取qr对应的交易. |
||
| 58 | * |
||
| 59 | * @var string |
||
| 60 | */ |
||
| 61 | const GET_TRADES_ENDPOINT = 'https://open.youzan.com/api/oauthentry/youzan.trades.qr/3.0.0/get'; |
||
| 62 | |||
| 63 | /** |
||
| 64 | * 获取交易. |
||
| 65 | * |
||
| 66 | * @var string |
||
| 67 | */ |
||
| 68 | const GET_TRADE_ENDPOINT = 'https://open.youzan.com/api/oauthentry/youzan.trade/3.0.0/get'; |
||
| 69 | |||
| 70 | /** |
||
| 71 | * 获取access token. |
||
| 72 | * |
||
| 73 | * @return Token |
||
| 74 | */ |
||
| 75 | public static function getAccessToken() |
||
| 76 | { |
||
| 77 | if (static::$token) { |
||
| 78 | return static::$token; |
||
| 79 | } |
||
| 80 | $response = static::$httpClient->post(static::GET_TOKEN_ENDPOINT, [ |
||
| 81 | 'form_params' => [ |
||
| 82 | 'client_id' => static::$apiContext->getClientId(), |
||
| 83 | 'client_secret' => static::$apiContext->getClientSecret(), |
||
| 84 | 'grant_type' => 'silent', |
||
| 85 | 'kdt_id' => static::$apiContext->getKdtId(), |
||
| 86 | ] |
||
| 87 | ]); |
||
| 88 | $json = \GuzzleHttp\json_decode((string) $response->getBody(), true); |
||
| 89 | $expiresAt = new \DateTime($json['expires_in'] . ' seconds'); |
||
| 90 | |||
| 91 | return static::$token = new Token($json['access_token'], $expiresAt); |
||
| 92 | } |
||
| 93 | |||
| 94 | /** |
||
| 95 | * 持久化qrcode. |
||
| 96 | * |
||
| 97 | * @param QRCode $qrCode |
||
| 98 | */ |
||
| 99 | public static function persistQrCode(QRCode $qrCode) |
||
| 100 | { |
||
| 101 | $json = static::setRequest('post', static::CREATE_QR_ENDPOINT, [ |
||
| 102 | 'qr_name' => $qrCode->getName(), |
||
| 103 | 'qr_price' => $qrCode->getPrice(), |
||
| 104 | 'qr_type' => $qrCode->getType(), |
||
| 105 | ])['response']; |
||
| 106 | $qrCode |
||
| 107 | ->setId($json['qr_id']) |
||
| 108 | ->setCode($json['qr_code']) |
||
| 109 | ->setUrl($json['qr_url']); |
||
| 110 | } |
||
| 111 | |||
| 112 | /** |
||
| 113 | * 检查QRCode支付结果. |
||
| 114 | * |
||
| 115 | * @param int|QRCode $qrCode |
||
| 116 | * |
||
| 117 | * @return bool |
||
| 118 | */ |
||
| 119 | public static function checkQRCodePayResult($qrCode) |
||
| 120 | { |
||
| 121 | if ($qrCode instanceof QRCode) { |
||
| 122 | $qrID = $qrCode->getId(); |
||
| 123 | } else { |
||
| 124 | $qrID = $qrCode; |
||
| 125 | } |
||
| 126 | $json = static::setRequest('get', static::GET_TRADES_ENDPOINT, [ |
||
| 127 | 'qr_id' => $qrID, |
||
| 128 | 'status' => 'TRADE_RECEIVED', |
||
| 129 | ])['response']; |
||
| 130 | |||
| 131 | return $json['total_results'] > 0; |
||
| 132 | } |
||
| 133 | |||
| 134 | /** |
||
| 135 | * 获取交易. |
||
| 136 | * |
||
| 137 | * @param int $id |
||
| 138 | * |
||
| 139 | * @return Trade |
||
| 140 | */ |
||
| 141 | public static function getTrade($id) |
||
| 142 | { |
||
| 143 | $json = static::setRequest('get', static::GET_TRADE_ENDPOINT, [ |
||
| 144 | 'tid' => $id, |
||
| 145 | ])['response']['trade']; |
||
| 146 | $trade = new Trade(); |
||
| 147 | $trade->setId($id) |
||
| 148 | ->setCreated(new \DateTime($json['created'])) |
||
| 149 | ->setQrId($json['qr_id']) |
||
| 150 | ->setStatus($json['status']); |
||
| 151 | |||
| 152 | return $trade; |
||
| 153 | } |
||
| 154 | |||
| 155 | protected static function setRequest($method, $uri, $parameters) |
||
| 156 | { |
||
| 157 | $token = static::getAccessToken(); |
||
| 158 | if (!$token->isValid()) { |
||
| 159 | throw new \InvalidArgumentException(sprintf('The token "%s" is invalid', $token->getAccessToken())); |
||
| 160 | } |
||
| 161 | $parameters['access_token'] = $token->getAccessToken(); |
||
| 162 | |||
| 163 | if (strcasecmp($method, 'post') === 0) { |
||
| 164 | $options['form_params'] = $parameters; |
||
|
0 ignored issues
–
show
|
|||
| 165 | } else { |
||
| 166 | $options['query'] = $parameters; |
||
|
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$options was never initialized. Although not strictly required by PHP, it is generally a good practice to add $options = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. Loading history...
|
|||
| 167 | } |
||
| 168 | |||
| 169 | $response = static::$httpClient->request($method, $uri, $options); |
||
| 170 | |||
| 171 | $json = \GuzzleHttp\json_decode((string) $response->getBody(), true); |
||
| 172 | |||
| 173 | if (isset($json['error_response'])) { |
||
| 174 | throw new \RuntimeException(sprintf('Error request, "%d": "%s"', |
||
| 175 | $json['error_response']['code'], |
||
| 176 | $json['error_response']['msg'] |
||
| 177 | )); |
||
| 178 | } |
||
| 179 | |||
| 180 | return $json; |
||
| 181 | } |
||
| 182 | |||
| 183 | /** |
||
| 184 | * @param ApiContext $apiContext |
||
| 185 | */ |
||
| 186 | public static function setApiContext($apiContext) |
||
| 187 | { |
||
| 188 | self::$apiContext = $apiContext; |
||
| 189 | } |
||
| 190 | |||
| 191 | /** |
||
| 192 | * @param Client $httpClient |
||
| 193 | */ |
||
| 194 | public static function setHttpClient($httpClient) |
||
| 195 | { |
||
| 196 | self::$httpClient = $httpClient; |
||
| 197 | } |
||
| 198 | |||
| 199 | /** |
||
| 200 | * @param Token $token |
||
| 201 | */ |
||
| 202 | public static function setToken($token) |
||
| 203 | { |
||
| 204 | self::$token = $token; |
||
| 205 | } |
||
| 206 | } |
||
| 207 |
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.
Let’s take a look at an example:
As you can see in this example, the array
$myArrayis initialized the first time when the foreach loop is entered. You can also see that the value of thebarkey is only written conditionally; thus, its value might result from a previous iteration.This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.