Compare commits

...

5 Commits

Author SHA1 Message Date
邹景立
1ffa938429 修改接口地址计算 2023-04-28 20:07:04 +08:00
邹景立
ac63302119 修改账单下载 2023-04-28 20:05:23 +08:00
邹景立
8630e29773 增加运行时缓存路径配置 2023-04-28 19:58:55 +08:00
邹景立
53f3dce3dd 完善更多直连商户接口 2023-04-28 19:45:43 +08:00
邹景立
200f14dba9 修改支付参数,增加证书序号配置(可选) 2023-04-28 19:06:35 +08:00
5 changed files with 136 additions and 25 deletions

View File

@ -65,12 +65,12 @@ abstract class BasicWePay
if (empty($options['mch_v3_key'])) {
throw new InvalidArgumentException("Missing Config -- [mch_v3_key]");
}
if (empty($options['cert_private'])) {
throw new InvalidArgumentException("Missing Config -- [cert_private]");
}
if (empty($options['cert_public'])) {
throw new InvalidArgumentException("Missing Config -- [cert_public]");
}
if (empty($options['cert_private'])) {
throw new InvalidArgumentException("Missing Config -- [cert_private]");
}
if (stripos($options['cert_public'], '-----BEGIN CERTIFICATE-----') === false) {
if (file_exists($options['cert_public'])) {
@ -93,11 +93,33 @@ abstract class BasicWePay
$this->config['mch_v3_key'] = $options['mch_v3_key'];
$this->config['cert_public'] = $options['cert_public'];
$this->config['cert_private'] = $options['cert_private'];
$this->config['cert_serial'] = openssl_x509_parse($this->config['cert_public'])['serialNumberHex'];
if (empty($this->config['cert_serial'])) {
throw new InvalidArgumentException("Failed to parse certificate public key");
if (empty($options['cert_serial'])) {
$this->config['cert_serial'] = openssl_x509_parse($this->config['cert_public'], true)['serialNumberHex'];
} else {
$this->config['cert_serial'] = $options['cert_serial'];
}
if (empty($this->config['cert_serial'])) {
throw new InvalidArgumentException('Failed to parse certificate public key');
}
if (!empty($options['cache_path'])) {
Tools::$cache_path = $options['cache_path'];
}
// 服务商参数支持
// if (!empty($options['sp_appid'])) {
// $this->config['sp_appid'] = $options['sp_appid'];
// }
// if (!empty($options['sp_mchid'])) {
// $this->config['sp_mchid'] = $options['sp_mchid'];
// }
// if (!empty($options['sub_appid'])) {
// $this->config['sub_appid'] = $options['sub_appid'];
// }
// if (!empty($options['sub_mch_id'])) {
// $this->config['sub_mch_id'] = $options['sub_mch_id'];
// }
}
/**
@ -117,24 +139,28 @@ abstract class BasicWePay
* @param string $method 请求访问
* @param string $pathinfo 请求路由
* @param string $jsondata 请求数据
* @param bool $verify 是否验证
* @return array
* @param boolean $verify 是否验证
* @param boolean $isjson 返回JSON
* @return array|string
* @throws \WeChat\Exceptions\InvalidResponseException
*/
public function doRequest($method, $pathinfo, $jsondata = '', $verify = false)
public function doRequest($method, $pathinfo, $jsondata = '', $verify = false, $isjson = true)
{
list($time, $nonce) = [time(), uniqid() . rand(1000, 9999)];
$signstr = join("\n", [$method, $pathinfo, $time, $nonce, $jsondata, '']);
// 生成数据签名TOKEN
$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
$this->config['mch_id'], $nonce, $time, $this->config['cert_serial'], $this->signBuild($signstr)
);
list($header, $content) = $this->_doRequestCurl($method, $this->base . $pathinfo, [
$location = (preg_match('|^https?://|', $pathinfo) ? '' : $this->base) . $pathinfo;
list($header, $content) = $this->_doRequestCurl($method, $location, [
'data' => $jsondata, 'header' => [
"Accept: application/json", "Content-Type: application/json",
'User-Agent: https://thinkadmin.top', "Authorization: WECHATPAY2-SHA256-RSA2048 {$token}",
],
]);
if ($verify) {
$headers = [];
foreach (explode("\n", $header) as $line) {
@ -153,7 +179,8 @@ abstract class BasicWePay
throw new InvalidResponseException($exception->getMessage(), $exception->getCode());
}
}
return json_decode($content, true);
return $isjson ? json_decode($content, true) : $content;
}
/**

View File

@ -22,7 +22,7 @@ use WePayV3\Contracts\BasicWePay;
use WePayV3\Contracts\DecryptAes;
/**
* 订单支付接口
* 直连商户 | 订单支付接口
* Class Order
* @package WePayV3
*/
@ -39,6 +39,7 @@ class Order extends BasicWePay
* @param array $data 支付参数
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
* @document https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml
*/
public function create($type, $data)
{
@ -73,18 +74,32 @@ class Order extends BasicWePay
/**
* 支付订单查询
* @param string $orderNo 订单单号
* @param string $tradeNo 订单单号
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
* @document https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_2.shtml
*/
public function query($orderNo)
public function query($tradeNo)
{
$pathinfo = "/v3/pay/transactions/out-trade-no/{$orderNo}";
$pathinfo = "/v3/pay/transactions/out-trade-no/{$tradeNo}";
return $this->doRequest('GET', "{$pathinfo}?mchid={$this->config['mch_id']}", '', true);
}
/**
* 支付通知
* 关闭支付订单
* @param string $tradeNo 订单单号
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
*/
public function close($tradeNo)
{
$data = ['mchid' => $this->config['mch_id']];
$path = "/v3/pay/transactions/out-trade-no/{$tradeNo}/close";
return $this->doRequest('POST', $path, json_encode($data, JSON_UNESCAPED_UNICODE), true);
}
/**
* 支付通知解析
* @return array
* @throws \WeChat\Exceptions\InvalidDecryptException
*/
@ -107,4 +122,68 @@ class Order extends BasicWePay
}
return $data;
}
/**
* 创建退款订单
* @param array $data 退款参数
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
* @document https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_9.shtml
*/
public function createRefund($data)
{
$path = '/v3/refund/domestic/refunds';
return $this->doRequest('POST', $path, json_encode($data, JSON_UNESCAPED_UNICODE), true);
}
/**
* 退款订单查询
* @param string $refundNo 退款单号
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
* @document https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_10.shtml
*/
public function queryRefund($refundNo)
{
$path = "/v3/refund/domestic/refunds/{$refundNo}";
return $this->doRequest('GET', $path, '', true);
}
/**
* 申请交易账单
* @param array|string $params
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
* @document https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_6.shtml
*/
public function tradeBill($params)
{
$path = '/v3/bill/tradebill?' . is_array($params) ? http_build_query($params) : $params;
return $this->doRequest('GET', $path, '', true);
}
/**
* 申请资金账单
* @param array|string $params
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
* @document https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_3_7.shtml
*/
public function fundflowBill($params)
{
$path = '/v3/bill/fundflowbill?' . is_array($params) ? http_build_query($params) : $params;
return $this->doRequest('GET', $path, '', true);
}
/**
* 下载账单文件
* @param string $fileurl
* @return string 二进制 Excel 内容
* @throws \WeChat\Exceptions\InvalidResponseException
* @document https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_6_1.shtml
*/
public function downloadBill($fileurl)
{
return $this->doRequest('GET', $fileurl, '', false, false);
}
}

View File

@ -25,8 +25,6 @@ use WePayV3\Contracts\BasicWePay;
*/
class ProfitSharing extends BasicWePay
{
/**
* 请求分账
* @param array $options
@ -63,9 +61,10 @@ class ProfitSharing extends BasicWePay
{
return $this->doRequest('POST', '/v3/profitsharing/orders/unfreeze', json_encode($options, JSON_UNESCAPED_UNICODE), true);
}
/**
* 查询剩余待分金额
* @param array $transactionId 微信订单号
* @param string $transactionId 微信订单号
* @return array
* @throws \WeChat\Exceptions\InvalidResponseException
*/
@ -74,6 +73,7 @@ class ProfitSharing extends BasicWePay
$pathinfo = "/v3/profitsharing/transactions/{$transactionId}/amounts";
return $this->doRequest('GET', $pathinfo, '', true);
}
/**
* 添加分账接收方
* @param array $options
@ -85,6 +85,7 @@ class ProfitSharing extends BasicWePay
$options['appid'] = $this->config['appid'];
return $this->doRequest('POST', "/v3/profitsharing/receivers/add", json_encode($options, JSON_UNESCAPED_UNICODE), true);
}
/**
* 删除分账接收方
* @param array $options

View File

@ -22,7 +22,7 @@ use WeChat\Exceptions\InvalidResponseException;
use WePayV3\Contracts\BasicWePay;
/**
* 订单退款接口
* 电商接口 | 订单退款接口
* Class Refund
* @package WePayV3
*/

View File

@ -27,14 +27,18 @@ $certPrivate = <<<CERT
CERT;
return [
// 商户绑定的公众号APPID
// 可选,公众号APPID
'appid' => '',
// 微信商户编号ID
// 必填,微信商户编号ID
'mch_id' => '',
// 微信商户V3接口密钥
// 必填,微信商户V3接口密钥
'mch_v3_key' => '',
// 微信商户证书公钥,支持证书内容或文件路径
// 可选,微信商户证书序列号,可从公钥中提取
'cert_serial' => '',
// 必填,微信商户证书公钥,支持证书内容或文件路径
'cert_public' => $certPublic,
// 微信商户证书私钥,支持证书内容或文件路径
// 必填,微信商户证书私钥,支持证书内容或文件路径
'cert_private' => $certPrivate,
// 可选,运行时的文件缓存路径
'cache_path' => ''
];