147 lines
4.7 KiB
PHP
147 lines
4.7 KiB
PHP
<?php
|
|
|
|
|
|
namespace wchat\qq\pay;
|
|
|
|
|
|
use Exception;
|
|
use wchat\common\Help;
|
|
use wchat\common\Result;
|
|
use wchat\qq\SmallProgram;
|
|
|
|
/**
|
|
* Class Enterprise_payment
|
|
* @package wchat\qq\pay
|
|
*/
|
|
class Enterprise_payment extends SmallProgram
|
|
{
|
|
public string $_cash = '/cgi-bin/epay/qpay_epay_b2c.cgi';
|
|
|
|
private array $_errors = [
|
|
'SYSTEMERROR' => '系统错误',
|
|
'PARAM_ERROR' => '请求参数未按指引进行填写',
|
|
'SIGNERROR' => '参数签名结果不正确',
|
|
'OP_USER_PASSWD_ERROR' => '操作员密码校验失败',
|
|
'OP_USER_AUTH_ERROR' => '操作员权限错误',
|
|
'TRANSFER_FEE_LIMIT_ERROR' => '转账限额错误',
|
|
'TRANSFER_FAIL' => '收款用户的账户不支持收款,收款失败',
|
|
'NOTENOUGH' => '商户营销账户的余额不足',
|
|
'ORDERNOTEXIST' => '转账订单不存在',
|
|
'APPID_OR_OPENID_ERR' => 'appid 或 openid 非法',
|
|
'TOTAL_FEE_OUT_OF_LIMIT' => '单笔限额检查失败',
|
|
'SPID_NOT_ALLOW' => '当前商户不支持企业付款',
|
|
'REALNAME_CHECK_ERROR' => '实名检查失败',
|
|
'RE_USER_NAME_CHECK_ERROR' => '用户真实姓名校验失败',
|
|
'INVALID_CERTIFICATE' => '证书非法',
|
|
];
|
|
|
|
private array $_requestParams = [];
|
|
|
|
/**
|
|
* @param string $value
|
|
*/
|
|
public function setOpUserId(string $value): void
|
|
{
|
|
$this->_requestParams['op_user_id'] = $value;
|
|
}
|
|
|
|
/**
|
|
* @param string $value
|
|
*/
|
|
public function setOpUserPassword(string $value): void
|
|
{
|
|
$this->_requestParams['op_user_passwd'] = $value;
|
|
}
|
|
|
|
/**
|
|
* @param string $value
|
|
*/
|
|
public function setSpbillCreateIp(string $value): void
|
|
{
|
|
$this->_requestParams['spbill_create_ip'] = $value;
|
|
}
|
|
|
|
/**
|
|
* @param string $mch_billno
|
|
* @param string $openId
|
|
* @param float $price
|
|
* @return Result
|
|
*/
|
|
public function mch_send(string $mch_billno, string $openId, float $price): Result
|
|
{
|
|
$client = $this->createClient($this->_cash, $this->orderConfig($mch_billno, $openId, $price));
|
|
if (!in_array($client->getStatusCode(), [101, 200, 201])) {
|
|
return new Result(code: 505, message: $client->getBody());
|
|
}
|
|
$json = json_decode($client->getBody(), true);
|
|
if (isset($json['return_code']) && $json['return_code'] != 'SUCCESS') {
|
|
return new Result(code: 500, data: $json['return_msg'] ?? $json['retmsg']);
|
|
} else if ($json['result_code'] != 'SUCCESS') {
|
|
return new Result(code: 500, data: $this->_errors[$json['err_code']] ?? $json['err_code_desc']);
|
|
} else {
|
|
return new Result(code: 0, data: $json);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $mch_billno
|
|
* @param string $openId
|
|
* @param float $price
|
|
* @return array
|
|
*/
|
|
private function orderConfig(string $mch_billno, string $openId, float $price): array
|
|
{
|
|
$requestParam['input_charset'] = 'UTF-8';
|
|
$requestParam['nonce_str'] = Help::random(32);
|
|
$requestParam['out_trade_no'] = $mch_billno;
|
|
$requestParam['mch_id'] = $this->payConfig->pay->qq->mchId;
|
|
$requestParam['appid'] = $this->payConfig->pay->qq->mchSecret;
|
|
$requestParam['openid'] = $openId;
|
|
$requestParam['fee_type'] = 'CNY';
|
|
$requestParam['total_fee'] = $price * 100;
|
|
$requestParam['memo'] = $this->payConfig->getBody();
|
|
$requestParam['notify_url'] = $this->payConfig->getNotifyUrl();
|
|
$requestParam['spbill_create_ip'] = $this->payConfig->getNotifyUrl();
|
|
if (!empty($this->_requestParams) && is_array($this->_requestParams)) {
|
|
$requestParam = array_merge($requestParam, $this->_requestParams);
|
|
}
|
|
$requestParam['sign'] = Help::sign($requestParam, $this->payConfig->pay->qq->mchSecret, 'MD5');
|
|
return $requestParam;
|
|
}
|
|
|
|
|
|
/**
|
|
* @return string
|
|
* @throws Exception
|
|
*/
|
|
public function mchOrderNo(): string
|
|
{
|
|
return implode([
|
|
$this->payConfig->pay->qq->mchId,
|
|
date('Ymd'),
|
|
random_int(11, 99),
|
|
date('His'),
|
|
random_int(11, 99)
|
|
]);
|
|
}
|
|
|
|
|
|
/**
|
|
* @param array $requestParams
|
|
* @return bool
|
|
*/
|
|
public function validator(array $requestParams): bool
|
|
{
|
|
$notifySign = $requestParams['sign'];
|
|
unset($requestParams['sign']);
|
|
$sign = Help::sign($requestParams, $this->payConfig->pay->qq->mchSecret, 'MD5');
|
|
|
|
if ($sign !== $notifySign) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
}
|