获取商户号和开发者ID,并开启分账
<?php
$fileurl = 'payment/wxpay_jsapi.php';
include_once($fileurl);
require_once( 'payment/wxpay/WxPay.JsApiPay.php');
require_once( 'acount.php');
$tools = new JsApiPay();
$result_openid = $tools->GetOpenid();
$open_id = $result_openid['openid'];//获取openid,必须是可以直接访问的页面,没有post的数据
$new = new profits();
$da=$new->addProfit($open_id );//成为分账方
if($da){
$receivers = [
[
"type" => "PERSONAL_OPENID", // 分账接收方类型
"account" => $open_id, // 分账接收方账号,一次可添加50个
"amount" => $teacherMoney * 100, // 分账金额 分
"description" => "分钱了" // 分账描述
]
];
$transaction_id='4200002295202407187404008583';
sleep(5);//如果是支付后立即分账的建议 延迟几秒再分账,否则可能会返回“订单处理中,暂时无法分账,请稍后再试”
$new->profitsharing($receivers,$transaction_id);//分账
}
<?php
/**
* 微信分账类
*/
class profits{
/**
* 分账(必须先成为分账方以后才可以分账),分账金额不可超过总金额的百分之三十
* @param $receivers
* @param $transaction_id
* @return int
* @throws WxPayException
*/
public function profitsharing($receivers,$transaction_id)
{
$aData = [
"mch_id" => "166643434", //商户号
"appid" => "wx1b36900831943434f", //微信appid
"nonce_str" => $this->getNonceStr(), // 随机字符串
"transaction_id" => $transaction_id, // 微信订单号:根据你的业务场景来获取
"out_order_no" => $this->get_order_sn(), // 商户分账单号
"receivers" => json_encode($receivers)// 分账接收方列表 json格式 中文不转码
];
// 签名
ksort($aData);
$aData['sign'] = $this->MakeSign($aData);
// 请求单次分账
//$url = 'https://api.mch.weixin.qq.com/secapi/pay/profitsharing';//单次分账
$url="https://api.mch.weixin.qq.com/secapi/pay/multiprofitsharing"; //多次分账
// 参数转ml
$postXML = $this->ToXml($aData);
// 结果
$timeOut = 6;
$response = self::postXmlCurl($postXML, $url, true, $timeOut);
//var_dump($response);
// 结果转数组
$ret = $this->FromXml($response);
//var_dump($ret);
file_put_contents('receivers.txt', json_encode($receivers), FILE_APPEND | LOCK_EX);
file_put_contents('fenzhang.txt', $response, FILE_APPEND | LOCK_EX);
// 保存分账订单状态或者别的操作
if ($ret["return_code"] == "SUCCESS" && $ret["result_code"] == "SUCCESS") {
return 1;
} else {
return 2;
}
}
/**
* 添加分账方(一次只能加一个,很鸡肋)
* @param $open_id
* @return int
* @throws WxPayException
*/
public function addProfit($open_id)
{
// 添加分账接收方
$url = 'https://api.mch.weixin.qq.com/pay/profitsharingaddreceiver';
// 接收方信息
$receiver = [
// 分账接收方类型
"type" => "PERSONAL_OPENID",
// 分账接收方账号 (个人:openid)
"account" => $open_id,
// 关系
"relation_type" => 'PARTNER',
];
// 公共参数
$oValues = [
"mch_id" => "166643434",
"appid" => "wx1b36900831943434f",
"nonce_str" => $this->getNonceStr(), // 随机字符串
"receiver" => json_encode($receiver),// 接收方信息
];
// 产生签名
ksort($oValues);
$oValues["sign"] = $this->MakeSign($oValues);
// 参数转ml
$postXML = $this->ToXml($oValues);
// 请求
$timeOut = 6;
$response = self::postXmlCurl($postXML, $url, true, $timeOut);
// 结果转数组
$ret = $this->FromXml($response);
if ($ret["return_code"] == "SUCCESS" && $ret["result_code"] == "SUCCESS") {
// 添加分账接收方成功
return 1;
} else {
return 2;
}
}
/**
*
* 产生随机字符串,不长于32位
* @param int $length
* @return 产生的随机字符串
*/
public static function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
/**
* 输出xml字符
**/
public function ToXml($values)
{
if (!is_array($values) || count($values) <= 0) {
return "数组数据异常!";
}
$xml = "<xml>";
foreach ($values as $key => $val) {
if (is_numeric($val)) {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
} else {
$xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
}
}
$xml .= "</xml>";
return $xml;
}
/**
* 将xml转为array
* @param string $xml
* @throws WxPayException
*/
public function FromXml($xml)
{
if (!$xml) {
return "xml数据异常!";
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$res = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $res;
}
/**
* 生成签名
* @param bool $needSignType 是否需要补signtype
* @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
public function MakeSign($values, $needSignType = true)
{
if ($needSignType) {
// $this->SetSignType($config->GetSignType());
$sSignType = "HMAC-SHA256";
}
$sKey = "gUAcBjXMHoEzLG9duUffU0s7nUhWwO17";
// 签名步骤一:按字典序排序参数
ksort($values);
$string = $this->ToUrlParams($values);
// 签名步骤二:在string后加入KEY
$string = $string . "&key=" . $sKey;
// 签名步骤三:MD5加密或者HMAC-SHA256
if ($sSignType == "MD5") {
$string = md5($string);
} else if ($sSignType == "HMAC-SHA256") {
$string = hash_hmac("sha256", $string, $sKey);
} else {
return "签名类型不支持!";
}
// 签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 拼接参数
* @param $values
* @return string
*/
public function ToUrlParams($values)
{
$buff = "";
foreach ($values as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
* 以post方式提交xml到对应的接口url
*
* @param WxPayConfigInterface $config 配置对象
* @param string $xml 需要post的xml数据
* @param string $url url
* @param bool $useCert 是否需要证书,默认不需要
* @param int $second url执行超时时间,默认30s
*/
private function postXmlCurl($xml, $url, $useCert = false, $second = 30)
{
$ch = curl_init();
$curlVersion = curl_version();
//$ua = "WXPaySDK/" . self::VERSION . " (" . PHP_OS . ") PHP/" . PHP_VERSION . " CURL/" . $curlVersion['version'] . " " . $aWxpayParam['mchid'];
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, $second);
$proxyHost = "0.0.0.0";
$proxyPort = 0;
// 如果有配置代理这里就设置代理
if ($proxyHost != "0.0.0.0" && $proxyPort != 0) {
curl_setopt($ch, CURLOPT_PROXY, $proxyHost);
curl_setopt($ch, CURLOPT_PROXYPORT, $proxyPort);
}
curl_setopt($ch, CURLOPT_URL, $url);
// curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,TRUE);
// curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2);//严格校验
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //严格校验
//curl_setopt($ch, CURLOPT_USERAGENT, $ua);
// 设置header
curl_setopt($ch, CURLOPT_HEADER, FALSE);
// 要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if ($useCert == true) {
// 设置证书
// 使用证书:cert 与 key 分别属于两个.pem文件
// 证书文件请放入服务器的非web目录下
$sslCertPath = './payment/cert/apiclient_cert.pem'; // 证书路径
$sslKeyPath = './payment/cert/apiclient_key.pem'; // 证书路径
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLCERT, $sslCertPath);
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
curl_setopt($ch, CURLOPT_SSLKEY, $sslKeyPath);
}
// post提交方式
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
// 运行curl
$data = curl_exec($ch);
// 返回结果
if ($data) {
curl_close($ch);
return $data;
} else {
$error = curl_errno($ch);
curl_close($ch);
throw new WxPayException("curl出错,错误码:$error");
}
}
function get_order_sn()
{
mt_srand((double) microtime() * 1000000);
return date('Ymd') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT);
}
}
分账完成后会收取万分之五四的手续费