18 Commits

Author SHA1 Message Date
as2252258 693ec4fa65 Default Changelist 2023-11-07 16:48:59 +08:00
as2252258 389f5261c7 Default Changelist 2023-11-07 16:33:09 +08:00
as2252258 cf03ebd6dc Default Changelist 2023-11-07 16:31:30 +08:00
as2252258 e0d1811a00 Default Changelist 2023-11-07 16:29:44 +08:00
as2252258 1a78bdb173 Default Changelist 2023-11-07 16:26:06 +08:00
as2252258 c5f8b19a83 Default Changelist 2023-11-07 16:14:59 +08:00
as2252258 227ff1c166 Default Changelist 2023-11-07 16:14:09 +08:00
as2252258 b8960deda5 Default Changelist 2023-11-07 16:09:40 +08:00
as2252258 ac70bd3df5 Default Changelist 2023-11-07 16:07:57 +08:00
as2252258 9264f05a49 Default Changelist 2023-11-07 16:01:11 +08:00
as2252258 a2dc66ec84 Default Changelist 2023-11-07 15:59:17 +08:00
as2252258 d0a6787b85 Default Changelist 2023-11-07 15:56:53 +08:00
as2252258 7f2bdbdb4f Default Changelist 2023-11-07 15:55:50 +08:00
as2252258 459d298983 Default Changelist 2023-11-07 15:39:46 +08:00
as2252258 a876b780f5 Default Changelist 2023-11-07 15:17:59 +08:00
as2252258 885c902be8 Default Changelist 2023-11-07 15:14:25 +08:00
as2252258 43f504b2ad Default Changelist 2023-11-07 15:13:11 +08:00
as2252258 dbdae7c6c5 Default Changelist 2023-11-07 14:02:43 +08:00
25 changed files with 1010 additions and 750 deletions
+8 -1
View File
@@ -162,7 +162,14 @@ abstract class Subject extends Multiprogramming
$client = new Client($this->getHost(), 443, true); $client = new Client($this->getHost(), 443, true);
$client->withHeader(['Content-Type' => 'application/json; charset=utf-8']); $client->withHeader(['Content-Type' => 'application/json; charset=utf-8']);
$client->post($this->getUrl() . '?access_token=' . $access_token, $params);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->getUrl() . '?access_token=' . $access_token, $params);
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
+8 -1
View File
@@ -133,7 +133,14 @@ abstract class Template extends Multiprogramming
$client = new Client($this->getHost(), 443, true); $client = new Client($this->getHost(), 443, true);
$client->withHeader(['Content-Type' => 'application/json; charset=utf-8']); $client->withHeader(['Content-Type' => 'application/json; charset=utf-8']);
$client->post($this->getUrl() . '?access_token=' . $access_token, $params);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->getUrl() . '?access_token=' . $access_token, $params);
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
+620 -547
View File
File diff suppressed because it is too large Load Diff
+8 -1
View File
@@ -27,7 +27,14 @@ class Account extends SmallProgram
$client = new Client('api.q.qq.com', 443, true); $client = new Client('api.q.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$client->get('sns/jscode2session', $param);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->get('sns/jscode2session', $param);
$client->close(); $client->close();
return Result::init($client); return Result::init($client);
+7
View File
@@ -52,6 +52,13 @@ class Recharge extends SmallProgram
$client = new Client('qpay.qq.com', 443, true); $client = new Client('qpay.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/xml']); $client->withHeader(['Content-Type' => 'application/xml']);
$client->withBody($this->builder()); $client->withBody($this->builder());
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->uniformer); $client->post($this->uniformer);
$client->close(); $client->close();
+10
View File
@@ -303,6 +303,11 @@ class Redhat extends SmallProgram
$client->withSslKeyFile($this->config->getSslKey()); $client->withSslKeyFile($this->config->getSslKey());
$client->withSslCertFile($this->config->getSslCert()); $client->withSslCertFile($this->config->getSslCert());
$client->withCa($this->config->getSslCa()); $client->withCa($this->config->getSslCa());
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->sendUrl, http_build_query($this->generate())); $client->post($this->sendUrl, http_build_query($this->generate()));
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
@@ -336,6 +341,11 @@ class Redhat extends SmallProgram
$requestParam['sign'] = $this->builderSign($requestParam); $requestParam['sign'] = $this->builderSign($requestParam);
$client = new Client('qpay.qq.com', 443, true); $client = new Client('qpay.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->searchUrl, $requestParam); $client->post($this->searchUrl, $requestParam);
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
+10
View File
@@ -37,6 +37,11 @@ class SecCheck extends SmallProgram
]; ];
$client = new Client('api.q.qq.com', 443, true); $client = new Client('api.q.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'multipart/form-data']); $client->withHeader(['Content-Type' => 'multipart/form-data']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->upload($path, $data); $client->upload($path, $data);
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
@@ -64,6 +69,11 @@ class SecCheck extends SmallProgram
$client = new Client('api.q.qq.com', 443, true); $client = new Client('api.q.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($url, ['appid' => $this->config->getAppid(), 'content' => $content]); $client->post($url, ['appid' => $this->config->getAppid(), 'content' => $content]);
$client->close(); $client->close();
+5
View File
@@ -22,6 +22,11 @@ class Token extends SmallProgram
]; ];
$client = new Client('api.q.qq.com', 443, true); $client = new Client('api.q.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->get('/api/getToken', $query); $client->get('/api/getToken', $query);
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
+8 -1
View File
@@ -91,7 +91,14 @@ class Cash_Bonus extends SmallProgram
$client->withSslCertFile($this->getConfig()->getSslCert()); $client->withSslCertFile($this->getConfig()->getSslCert());
$client->withSslKeyFile($this->getConfig()->getSslKey()); $client->withSslKeyFile($this->getConfig()->getSslKey());
$client->withCa($this->getConfig()->getSslCa()); $client->withCa($this->getConfig()->getSslCa());
$client->post($this->_cash, $this->orderConfig($mch_billno, $openId, $price));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->_cash, $this->orderConfig($mch_billno, $openId, $price));
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody()); return new Result(code: 505, message: $client->getBody());
+8 -1
View File
@@ -77,7 +77,14 @@ class Enterprise_payment extends SmallProgram
$client->withSslCertFile($this->getConfig()->getSslCert()); $client->withSslCertFile($this->getConfig()->getSslCert());
$client->withSslKeyFile($this->getConfig()->getSslKey()); $client->withSslKeyFile($this->getConfig()->getSslKey());
$client->withCa($this->getConfig()->getSslCa()); $client->withCa($this->getConfig()->getSslCa());
$client->post($this->_cash, $this->orderConfig($mch_billno, $openId, $price));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->_cash, $this->orderConfig($mch_billno, $openId, $price));
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
return new Result(code: 505, message: $client->getBody()); return new Result(code: 505, message: $client->getBody());
+12
View File
@@ -30,6 +30,9 @@ class Account extends SmallProgram
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
if (!empty($this->getConfig()->getProxyHost()) && $this->getConfig()->getProxyPort() > 0) {
$client->withProxyHost("192.168.0.57")->withProxyPort(12286);
}
$client->get('sns/jscode2session', $param); $client->get('sns/jscode2session', $param);
$client->close(); $client->close();
@@ -59,6 +62,9 @@ class Account extends SmallProgram
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
if (!empty($this->getConfig()->getProxyHost()) && $this->getConfig()->getProxyPort() > 0) {
$client->withProxyHost("192.168.0.57")->withProxyPort(12286);
}
$client->get('cgi-bin/user/info', $query); $client->get('cgi-bin/user/info', $query);
$client->close(); $client->close();
@@ -112,6 +118,12 @@ class Account extends SmallProgram
$sendBody['width'] = $width; $sendBody['width'] = $width;
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($url . $this->getConfig()->getAccessToken(), $sendBody); $client->post($url . $this->getConfig()->getAccessToken(), $sendBody);
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
+10
View File
@@ -261,6 +261,11 @@ class Message extends SmallProgram
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'multipart/form-data']); $client->withHeader(['Content-Type' => 'multipart/form-data']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($url, $data); $client->post($url, $data);
$client->close(); $client->close();
@@ -297,6 +302,11 @@ class Message extends SmallProgram
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($url, $this->msgData); $client->post($url, $this->msgData);
$client->close(); $client->close();
+5
View File
@@ -148,6 +148,11 @@ class PublicTemplate extends SmallProgram
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($url, $default); $client->post($url, $default);
$client->close(); $client->close();
+15
View File
@@ -36,6 +36,11 @@ class SecCheck extends SmallProgram
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'multipart/form-data']); $client->withHeader(['Content-Type' => 'multipart/form-data']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->upload($this->_url . '?access_token=' . $access_token, [ $client->upload($this->_url . '?access_token=' . $access_token, [
'media' => new \CURLFile($path) 'media' => new \CURLFile($path)
]); ]);
@@ -66,6 +71,11 @@ class SecCheck extends SmallProgram
$requestUrl = $this->_mediaCheckAsync . $this->config->getAccessToken(); $requestUrl = $this->_mediaCheckAsync . $this->config->getAccessToken();
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($requestUrl, ['media_url' => $url, 'media_type' => $type]); $client->post($requestUrl, ['media_url' => $url, 'media_type' => $type]);
$client->close(); $client->close();
@@ -104,6 +114,11 @@ class SecCheck extends SmallProgram
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($requestUrl, ['content' => $content]); $client->post($requestUrl, ['content' => $content]);
$client->close(); $client->close();
+5
View File
@@ -22,6 +22,11 @@ class Token extends SmallProgram
]; ];
$client = new Client('api.weixin.qq.com', 443, true); $client = new Client('api.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->get('cgi-bin/token', $query); $client->get('cgi-bin/token', $query);
$client->close(); $client->close();
if (!in_array($client->getStatusCode(), [101, 200, 201])) { if (!in_array($client->getStatusCode(), [101, 200, 201])) {
+5
View File
@@ -34,6 +34,11 @@ class WxV2AppPayment extends SmallProgram
$client = new Client('api.mch.weixin.qq.com', 443, true); $client = new Client('api.mch.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->withBody($this->sign($body)); $client->withBody($this->sign($body));
$client->post($this->uniformed); $client->post($this->uniformed);
$client->close(); $client->close();
+20
View File
@@ -37,6 +37,11 @@ class WxV2PayJsApi extends SmallProgram
$client = new Client('api.mch.weixin.qq.com', 443, true); $client = new Client('api.mch.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$client->withBody($this->sign($body)); $client->withBody($this->sign($body));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->uniformed); $client->post($this->uniformed);
$client->close(); $client->close();
@@ -83,6 +88,11 @@ class WxV2PayJsApi extends SmallProgram
$client = new Client('api.mch.weixin.qq.com', 443, true); $client = new Client('api.mch.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$client->withBody($this->sign($body)); $client->withBody($this->sign($body));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->uniformed); $client->post($this->uniformed);
$client->close(); $client->close();
@@ -129,6 +139,11 @@ class WxV2PayJsApi extends SmallProgram
$client = new Client('api.mch.weixin.qq.com', 443, true); $client = new Client('api.mch.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$client->withBody($this->sign($body)); $client->withBody($this->sign($body));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->uniformed); $client->post($this->uniformed);
$client->close(); $client->close();
@@ -175,6 +190,11 @@ class WxV2PayJsApi extends SmallProgram
$client = new Client('api.mch.weixin.qq.com', 443, true); $client = new Client('api.mch.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$client->withBody($this->sign($body)); $client->withBody($this->sign($body));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->uniformed); $client->post($this->uniformed);
$client->close(); $client->close();
+5
View File
@@ -40,6 +40,11 @@ class WxV2Withdrawal extends SmallProgram
$client = new Client('api.mch.weixin.qq.com', 443, true); $client = new Client('api.mch.weixin.qq.com', 443, true);
$client->withHeader(['Content-Type' => 'application/json']); $client->withHeader(['Content-Type' => 'application/json']);
$client->withBody($body = Help::toXml($array)); $client->withBody($body = Help::toXml($array));
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post($this->transfers); $client->post($this->transfers);
$client->close(); $client->close();
+24 -18
View File
@@ -5,6 +5,7 @@ namespace wchat\wx\V3;
use Exception; use Exception;
use JetBrains\PhpStorm\ArrayShape; use JetBrains\PhpStorm\ArrayShape;
use Kiri\Client; use Kiri\Client;
use Kiri\CurlClient;
use wchat\wx\SmallProgram; use wchat\wx\SmallProgram;
class TransferBatches extends SmallProgram class TransferBatches extends SmallProgram
@@ -13,38 +14,43 @@ class TransferBatches extends SmallProgram
/** /**
* @param string $orderNo * @param TransferDetail $detail
* @param int $total
* @param string $openId
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
#[ArrayShape(['code_url' => "string"])] #[ArrayShape([])]
public function request(string $orderNo, int $total, string $openId): array public function request(TransferDetail $detail): array
{ {
$body = [];
$body['appid'] = $this->getConfig()->getAppid(); $body['appid'] = $this->getConfig()->getAppid();
$body['out_trade_no'] = $orderNo; $body['out_batch_no'] = $detail->out_detail_no;
$body["batch_name"] = $this->getConfig()->getBody(); $body["batch_name"] = $this->getConfig()->getBody();
$body["body"] = $this->getConfig()->getBody();
$body["batch_remark"] = $this->getConfig()->getBody(); $body["batch_remark"] = $this->getConfig()->getBody();
$body["total_amount"] = $total; $body["total_amount"] = $detail->transfer_amount;
$body["total_num"] = 1; $body["total_num"] = 1;
$body["transfer_detail_list"] = [ $body["transfer_detail_list"] = [$detail->toArray()];
[
"out_detail_no" => $orderNo,
"transfer_amount" => $total,
"transfer_remark" => $this->getConfig()->getBody(),
"openid" => $openId,
]
];
$sign = $this->signature('POST', '/v3/transfer/batches', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); $sign = $this->signature('POST', '/v3/transfer/batches', $json = json_encode($body, JSON_UNESCAPED_UNICODE));
$client = new Client('api.mch.weixin.qq.com', 443, TRUE); $client = new Client('api.mch.weixin.qq.com', 443, TRUE);
$client->withAddedHeader('Authorization', $sign)->withContentType('application/json') $client->withAddedHeader('Authorization', $sign)->withContentType('application/json')
->withAgent('application/json')->withBody($json) ->withAgent('application/json')->withBody($json)->withAddedHeader("Accept", "*/*");
->post('/v3/transfer/batches');
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post('/v3/transfer/batches');
$client->close(); $client->close();
return json_decode($client->getBody(), TRUE); $data = json_decode($client->getBody(), TRUE);
if (json_last_error() != JSON_ERROR_NONE) {
return ['code' => $client->getStatusCode(), 'message' => $client->getBody()];
} else {
return $data;
}
} }
} }
+31 -23
View File
@@ -7,30 +7,38 @@ use JetBrains\PhpStorm\ArrayShape;
class TransferDetail class TransferDetail
{ {
public function __construct( public function __construct(
public string $out_detail_no, public string $out_detail_no,
public int|float $transfer_amount, public int|float $transfer_amount,
public string $transfer_remark, public string $transfer_remark,
public string $openid, public string $openid,
public string $user_name public string $user_name
) )
{ {
} }
/** /**
* @return array * @return array
*/ */
#[ArrayShape(['out_detail_no' => "string", 'transfer_amount' => "float|int", 'transfer_remark' => "string", 'openid' => "string", 'user_name' => "string"])] #[ArrayShape(['out_detail_no' => "string", 'transfer_amount' => "float|int", 'transfer_remark' => "string", 'openid' => "string", 'user_name' => "string"])]
public function toArray(): array public function toArray(): array
{ {
return [ if (empty($this->user_name)) {
'out_detail_no' => $this->out_detail_no, return [
'transfer_amount' => $this->transfer_amount, 'out_detail_no' => $this->out_detail_no,
'transfer_remark' => $this->transfer_remark, 'transfer_amount' => $this->transfer_amount,
'openid' => $this->openid, 'transfer_remark' => $this->transfer_remark,
'user_name' => $this->user_name, 'openid' => $this->openid,
]; ];
} }
return [
'out_detail_no' => $this->out_detail_no,
'transfer_amount' => $this->transfer_amount,
'transfer_remark' => $this->transfer_remark,
'openid' => $this->openid,
'user_name' => $this->user_name,
];
}
} }
+32 -25
View File
@@ -10,37 +10,44 @@ class WxV3AppPayment extends SmallProgram
{ {
use WxV3PaymentTait; use WxV3PaymentTait;
/** /**
* @param $orderNo * @param $orderNo
* @param int $total * @param int $total
* @param string|null $openId * @param string|null $openId
* @param string $payer_client_ip * @param string $payer_client_ip
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function payment($orderNo, int $total, string $openId = NULL, string $payer_client_ip = '127.0.0.1'): array public function payment($orderNo, int $total, string $openId = NULL, string $payer_client_ip = '127.0.0.1'): array
{ {
$body = $this->getInitCore($orderNo, $total); $body = $this->getInitCore($orderNo, $total);
$body['scene_info'] = ['payer_client_ip' => $payer_client_ip]; $body['scene_info'] = ['payer_client_ip' => $payer_client_ip];
$sign = $this->signature('POST', '/v3/pay/transactions/components', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); $sign = $this->signature('POST', '/v3/pay/transactions/components', $json = json_encode($body, JSON_UNESCAPED_UNICODE));
$client = new Client('api.mch.weixin.qq.com', 443, TRUE); $client = new Client('api.mch.weixin.qq.com', 443, TRUE);
$client->withAddedHeader('Authorization', $sign)->withContentType('application/json') $client->withAddedHeader('Authorization', $sign)->withContentType('application/json')
->withAgent('application/json')->withBody($json) ->withAgent('application/json')->withBody($json)->withAddedHeader("Accept", "*/*");
->post('/v3/pay/transactions/components');
$client->close();
$json = json_decode($client->getBody(), TRUE); $proxyHost = $this->getConfig()->getProxyHost();
if (!isset($json['prepay_id'])) { $proxyPort = $this->getConfig()->getProxyPort();
throw new Exception('微信支付调用失败'); if (!empty($proxyHost) && $proxyPort > 0) {
} $client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
return $this->createResponse($json, $body); }
}
$client->post('/v3/pay/transactions/components');
$client->close();
$json = json_decode($client->getBody(), TRUE);
if (!isset($json['prepay_id'])) {
throw new Exception('微信支付调用失败');
}
return $this->createResponse($json, $body);
}
} }
+9 -2
View File
@@ -31,8 +31,15 @@ class WxV3NativePayment extends SmallProgram
$client = new Client('api.mch.weixin.qq.com', 443, TRUE); $client = new Client('api.mch.weixin.qq.com', 443, TRUE);
$client->withAddedHeader('Authorization', $sign)->withContentType('application/json') $client->withAddedHeader('Authorization', $sign)->withContentType('application/json')
->withAgent('application/json')->withBody($json) ->withAgent('application/json')->withBody($json)->withAddedHeader("Accept", "*/*");
->post('/v3/pay/transactions/native');
$proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post('/v3/pay/transactions/native');
$client->close(); $client->close();
$json = json_decode($client->getBody(), TRUE); $json = json_decode($client->getBody(), TRUE);
+10 -4
View File
@@ -31,10 +31,16 @@ class WxV3Payment extends SmallProgram
$client = new Client('api.mch.weixin.qq.com', 443, TRUE); $client = new Client('api.mch.weixin.qq.com', 443, TRUE);
$client->withAddedHeader('Authorization', $sign) $client->withAddedHeader('Authorization', $sign)
->withContentType('application/json') ->withContentType('application/json')->withAddedHeader('User-Agent', 'application/json')
->withAddedHeader('User-Agent', 'application/json') ->withBody($json)->withAddedHeader("Accept", "*/*");
->withBody($json)
->post('/v3/pay/transactions/jsapi'); $proxyHost = $this->getConfig()->getProxyHost();
$proxyPort = $this->getConfig()->getProxyPort();
if (!empty($proxyHost) && $proxyPort > 0) {
$client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
$client->post('/v3/pay/transactions/jsapi');
$client->close(); $client->close();
$json = json_decode($client->getBody(), TRUE); $json = json_decode($client->getBody(), TRUE);
+87 -84
View File
@@ -7,108 +7,111 @@ use wchat\common\Help;
use function Sodium\crypto_aead_aes256gcm_decrypt; use function Sodium\crypto_aead_aes256gcm_decrypt;
use function Sodium\crypto_aead_aes256gcm_is_available; use function Sodium\crypto_aead_aes256gcm_is_available;
const KEY_LENGTH_BYTE = 32; const KEY_LENGTH_BYTE = 32;
const AUTH_TAG_LENGTH_BYTE = 16; const AUTH_TAG_LENGTH_BYTE = 16;
trait WxV3PaymentTait trait WxV3PaymentTait
{ {
/** /**
* @param $orderNo * @param $orderNo
* @param $total * @param $total
* @return array * @return array
*/ */
public function getInitCore($orderNo, $total): array public function getInitCore($orderNo, $total): array
{ {
$body['appid'] = $this->getConfig()->getAppid(); $body['appid'] = $this->getConfig()->getAppid();
$body['mchid'] = $this->getConfig()->getMchId(); $body['mchid'] = $this->getConfig()->getMchId();
$body['description'] = $this->getConfig()->getBody(); $body['description'] = $this->getConfig()->getBody();
$body['out_trade_no'] = $orderNo; $body['out_trade_no'] = $orderNo;
$body['notify_url'] = $this->getConfig()->getNotifyUrl(); $body['notify_url'] = $this->getConfig()->getNotifyUrl();
$body['amount'] = ['total' => $total, 'currency' => 'CNY']; $body['amount'] = ['total' => $total, 'currency' => 'CNY'];
return $body; return $body;
} }
/** /**
* @param string $http_method * @param string $http_method
* @param string $canonical_url * @param string $canonical_url
* @param string $body * @param string $body
* @return string * @return string
* @throws Exception * @throws Exception
*/ */
public function signature(string $http_method, string $canonical_url, string $body = ''): string public function signature(string $http_method, string $canonical_url, string $body = ''): string
{ {
$message = $http_method . "\n" . $canonical_url . "\n" . ($time = time()) . "\n" . ($rand = md5(random_bytes(32))) . "\n" . $body . "\n"; $rand = md5(random_bytes(32));
$time = time();
$sign = $this->openssl_signature($message); $message = sprintf("%s\n%s\n%d\n%s\n%s\n", $http_method, $canonical_url, $time, $rand, $body);
return sprintf('%s mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $this->getConfig()->getSchema(), $sign = $this->openssl_signature($message);
$this->getConfig()->getMchId(), $rand, $time, $this->getConfig()->getSerialNo(), $sign);
} return sprintf('%s mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"', $this->getConfig()->getSchema(),
$this->getConfig()->getMchId(), $rand, $time, $this->getConfig()->getSerialNo(), $sign);
}
/** /**
* @param $body * @param $body
* @return string * @return string
*/ */
public function openssl_signature($body): string public function openssl_signature($body): string
{ {
$pem = file_get_contents($this->getConfig()->getSslCert()); $pem = file_get_contents($this->getConfig()->getMchKey());
$mch_private_key = openssl_get_privatekey($pem); $mch_private_key = openssl_get_privatekey($pem);
openssl_sign($body, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption'); openssl_sign($body, $raw_sign, $mch_private_key, 'sha256WithRSAEncryption');
return base64_encode($raw_sign); return base64_encode($raw_sign);
} }
/** /**
* @param $json * @param $json
* @param $body * @param $body
* @return array * @return array
*/ */
private function createResponse($json, $body): array private function createResponse($json, $body): array
{ {
$responseArray['appId'] = $body['appid']; $responseArray['appId'] = $body['appid'];
$responseArray['timeStamp'] = (string)time(); $responseArray['timeStamp'] = (string)time();
$responseArray['nonceStr'] = Help::random(32); $responseArray['nonceStr'] = Help::random(32);
$responseArray['package'] = "prepay_id=" . $json['prepay_id']; $responseArray['package'] = "prepay_id=" . $json['prepay_id'];
$responseBody = $responseArray['appId'] . PHP_EOL . $responseArray['timeStamp'] . PHP_EOL . $responseArray['nonceStr'] . PHP_EOL . $responseArray['package'] . PHP_EOL; $responseBody = $responseArray['appId'] . PHP_EOL . $responseArray['timeStamp'] . PHP_EOL . $responseArray['nonceStr'] . PHP_EOL . $responseArray['package'] . PHP_EOL;
$responseArray['signType'] = 'RSA'; $responseArray['signType'] = 'RSA';
$responseArray['signBody'] = $responseBody; $responseArray['signBody'] = $responseBody;
$responseArray['paySign'] = $this->openssl_signature($responseBody); $responseArray['paySign'] = $this->openssl_signature($responseBody);
$responseArray['prepay_id'] = $json['prepay_id']; $responseArray['prepay_id'] = $json['prepay_id'];
return $responseArray; return $responseArray;
} }
/** /**
* @param $associatedData * @param $associatedData
* @param $nonceStr * @param $nonceStr
* @param $ciphertext * @param $ciphertext
* @return bool|string * @return bool|string
*/ */
public function decryptToString($associatedData, $nonceStr, $ciphertext): bool|string public function decryptToString($associatedData, $nonceStr, $ciphertext): bool|string
{ {
$ciphertext = \base64_decode($ciphertext); $ciphertext = \base64_decode($ciphertext);
if (strlen($ciphertext) <= AUTH_TAG_LENGTH_BYTE) { if (strlen($ciphertext) <= AUTH_TAG_LENGTH_BYTE) {
return FALSE; return FALSE;
} }
if (function_exists('\sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) { if (function_exists('\sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) {
return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR'); return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR');
} }
if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) { if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && crypto_aead_aes256gcm_is_available()) {
return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR'); return crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR');
} }
if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) { if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) {
$ctext = substr($ciphertext, 0, -AUTH_TAG_LENGTH_BYTE); $ctext = substr($ciphertext, 0, -AUTH_TAG_LENGTH_BYTE);
$authTag = substr($ciphertext, -AUTH_TAG_LENGTH_BYTE); $authTag = substr($ciphertext, -AUTH_TAG_LENGTH_BYTE);
return \openssl_decrypt($ctext, 'aes-256-gcm', 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR', \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData); return \openssl_decrypt($ctext, 'aes-256-gcm', 'XGwwZbmMXy6sD5w0IrxfaBHLl7b7jCaR', \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData);
} }
throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php'); throw new \RuntimeException('AEAD_AES_256_GCM需要PHP 7.1以上或者安装libsodium-php');
} }
} }
+48 -42
View File
@@ -12,56 +12,62 @@ class WxV3Withdrawal extends SmallProgram
{ {
use WxV3PaymentTait; use WxV3PaymentTait;
/** /**
* @param $orderNo * @param $orderNo
* @param string $batch_name * @param string $batch_name
* @param string $batch_remark * @param string $batch_remark
* @param TransferDetail[] $details * @param TransferDetail[] $details
* @return array * @return array
* @throws Exception * @throws Exception
*/ */
public function payment($orderNo, string $batch_name, string $batch_remark, array $details): array public function payment($orderNo, string $batch_name, string $batch_remark, array $details): array
{ {
$body = $this->create($orderNo, $batch_name, $batch_remark, $details); $body = $this->create($orderNo, $batch_name, $batch_remark, $details);
$sign = $this->signature('POST', '/v3/pay/transactions/batches', $json = json_encode($body, JSON_UNESCAPED_UNICODE)); $sign = $this->signature('POST', '/v3/pay/transactions/batches', $json = json_encode($body, JSON_UNESCAPED_UNICODE));
$client = new Client('api.mch.weixin.qq.com', 443, TRUE); $client = new Client('api.mch.weixin.qq.com', 443, TRUE);
$client->withAddedHeader('Authorization', $sign) $client->withAddedHeader('Authorization', $sign)
->withContentType('application/json') ->withContentType('application/json')->withAddedHeader('User-Agent', 'application/json')
->withAddedHeader('User-Agent', 'application/json') ->withBody($json)->withAddedHeader("Accept", "*/*");
->withBody($json)
->post('/v3/pay/transactions/batches');
$client->close();
$json = json_decode($client->getBody(), TRUE); $proxyHost = $this->getConfig()->getProxyHost();
if (!isset($json['prepay_id'])) { $proxyPort = $this->getConfig()->getProxyPort();
throw new Exception('微信支付调用失败'); if (!empty($proxyHost) && $proxyPort > 0) {
} $client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
}
return $this->createResponse($json, $body); $client->post('/v3/pay/transactions/batches');
} $client->close();
$json = json_decode($client->getBody(), TRUE);
if (!isset($json['prepay_id'])) {
throw new Exception('微信支付调用失败');
}
return $this->createResponse($json, $body);
}
#[ArrayShape(['transfer_detail_list' => "array", 'total_amount' => "int", 'total_num' => "int", 'batch_remark' => "string", 'batch_name' => "string", 'out_batch_no' => ""])] #[ArrayShape(['transfer_detail_list' => "array", 'total_amount' => "int", 'total_num' => "int", 'batch_remark' => "string", 'batch_name' => "string", 'out_batch_no' => ""])]
private function create($orderNo, string $batch_name, string $batch_remark, array $details): array private function create($orderNo, string $batch_name, string $batch_remark, array $details): array
{ {
$total = 0; $total = 0;
$body = ['transfer_detail_list' => []]; $body = ['transfer_detail_list' => []];
$body['out_batch_no'] = $orderNo; $body['out_batch_no'] = $orderNo;
$body['batch_name'] = $batch_name; $body['batch_name'] = $batch_name;
$body['batch_remark'] = $batch_remark; $body['batch_remark'] = $batch_remark;
$body['total_num'] = count($details); $body['total_num'] = count($details);
foreach ($details as $detail) { foreach ($details as $detail) {
$total += $detail->transfer_amount; $total += $detail->transfer_amount;
$body['transfer_detail_list'][] = $detail->toArray(); $body['transfer_detail_list'][] = $detail->toArray();
} }
$body['total_amount'] = $total; $body['total_amount'] = $total;
return $body; return $body;
} }
} }