首选需要给微信商户的运营账户充钱,保证账户有钱
首选需要给微信商户的运营账户充钱,保证账户有钱
首选需要给微信商户的运营账户充钱,保证账户有钱
protected $mch_id = '16xxx'; //商户号
protected $appid = 'wxxxx'; //商户号Appid
protected $cert_pem = '/www/wwwroot/xxxx/public/cert/apiclient_cert_10002.pem'; //V3 商户证书在服务器位置
protected $key_pem = '/www/wwwroot/xxxx/public/cert/apiclient_key_10002.pem';
//调用这个方法
//$money 金额
//$out_bill_no 订单号
public function payOrder($money,$out_bill_no){
$userInfo=self::userInfo();
$appInfo=self::appInfo();
//按转账场景发起转账
//文档https://pay.weixin.qq.com/doc/v3/merchant/4012711988
$params = [
"appid" => $this->appid,
"out_bill_no" => $out_bill_no,
"transfer_scene_id" => "1005",
"openid" => $userInfo['openid'],
"transfer_amount" => $money*100,
"transfer_remark" => "佣金报酬",
"notify_url" => "https://xxxxx/api/user.withdraw/update_do",
"user_recv_perception" => "劳务报酬",
"transfer_scene_report_infos" => [
[
"info_type" => "岗位类型",
"info_content" => "外卖员"
],
[
"info_type" => "报酬说明",
"info_content" => "7月份配送费,高温补贴"
]
]
];
// // 商家转账没有要求参数排序,可写可不写
// $params = $this->param_filter($params); // 过滤参数
// $params = $this->param_sort($params); // 参数排序
$url = 'https://api.mch.weixin.qq.com/v3/fund-app/mch-transfer/transfer-bills';
$params = json_encode($params);
$timestamp =(string)Formatter::timestamp();
$token = $this->getToken($url, $timestamp, $params);
$res_xml = $this->https_request($url, $params, $token);
$resArr = json_decode($res_xml, true);
$message = [];
//商户转账接口调用成功后返回的package_info
if(isset($resArr['package_info'])){
$message['mchId'] = $this->mch_id;
$message['appId'] = $this->appid;
$message['package'] = $resArr['package_info'];
$message['data'] = $resArr;
}else {
$message['data'] = $resArr;
}
returnSuccess($message);
}
//商家批次单号
public function generateBatchNo($merchantId) {
// 获取当前日期
$date = date('Ymd');
// 生成自增序列,这里假设有一个全局的自增序列存储机制,例如数据库或文件
// 这里简单示例使用文件存储
$incrementFile = 'batch_increment.txt';
if (!file_exists($incrementFile)) {
file_put_contents($incrementFile, '00000000');
}
$increment = str_pad((int)file_get_contents($incrementFile) + 1, 8, '0', STR_PAD_LEFT);
file_put_contents($incrementFile, str_pad((int)$increment, 8, '0', STR_PAD_LEFT));
// 拼接批次单号
$batchNo = $merchantId . $date . $increment;
return $batchNo;
}
/**
*请求接口
*/
public function https_request($url, $data = null, $token = '')
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, (string)$url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)) {
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
//添加请求头
$headers = [
'Authorization:WECHATPAY2-SHA256-RSA2048 ' . $token,
'Accept: application/json',
'Content-Type: application/json; charset=utf-8',
'User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
];
if (!empty($headers)) {
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
}
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
public function getToken($url, $timestamp, $body = '', $http_method = 'POST')
{
$url_parts = parse_url($url); //获取请求的绝对URL
$nonce = $this->nonce(); //请求随机串
$stream_opts = [
"ssl" => [
"verify_peer" => false,
"verify_peer_name" => false,
]
];
$apiclient_cert_path = $this->cert_pem;
$apiclient_key_path = $this->key_pem;
$apiclient_cert_arr = openssl_x509_parse(file_get_contents($apiclient_cert_path, false, stream_context_create($stream_opts)));
$serial_no = $apiclient_cert_arr['serialNumberHex']; // 证书序列号(忽略)
$mch_private_key = file_get_contents($apiclient_key_path, false, stream_context_create($stream_opts)); // 密钥
$merchant_id = $this->mch_id; // 商户id
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
$message = $http_method . "\n" .
$canonical_url . "\n" .
$timestamp . "\n" .
$nonce . "\n" .
$body . "\n";
openssl_sign($message, $raw_sign, $mch_private_key, OPENSSL_ALGO_SHA256);
$sign = base64_encode($raw_sign); // 签名
return sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
$merchant_id, $nonce, $timestamp, $serial_no, $sign); // 微信返回token
}
// 过滤参数
public function param_filter($para)
{
$paraFilter = [];
foreach ($para as $key => $val) {
if ($val === '' || $val === null) {
continue;
}
if (!is_array($para[$key])) {
if (!is_numeric($para[$key])){
$para[$key] = is_bool($para[$key]) ? $para[$key] : trim($para[$key]);
}
}
$paraFilter[$key] = $para[$key];
}
return $paraFilter;
}
// 参数排序
public function param_sort(array $param)
{
ksort($param);
reset($param);
return $param;
}
// 随机数
public function nonce(int $size = 32)
{
if ($size < 1) {
throw new InvalidArgumentException('Size must be a positive integer.');
}
return implode('', array_map(static function(string $c): string {
return '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'[ord($c) % 62];
}, str_split(random_bytes($size))));
}
1422

被折叠的 条评论
为什么被折叠?



