PHP-微信提现到零钱
哈喽大家好,在原来做的微信支付的各种接口里总会不经意的就踩个地雷,虽然都是小问题,但是还是会浪费一些时间,于是乎,今儿个心血来潮就写一个关于微信提现到零钱【俗称企业付款到零钱】互相探讨,大佬轻喷哈
一.使用条件
切记切记不要在用到提现的时候再去开通
二:程序
先做一个调用支付的类
class WxpayService
{
protected $mchid;
protected $appid;
protected $appKey;
protected $apiKey;
public $data = null;
public function __construct($mchid, $appid, a p p K e y , appKey, appKey,key)
{
$this->mchid = $mchid;
$this->appid = $appid;
$this->appKey = $appKey;
$this->apiKey = $key;
}
获取OpenId,用于后续的给对应的用户进行提现
/**
- 通过跳转获取用户的openid,跳转流程如下:
- 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize
- 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code
- @return 用户的openid
*/
public function GetOpenid()
{
//通过code获得openid
if (!isset($_GET[‘code’])){
//触发微信返回code码
$scheme = $_SERVER[‘HTTPS’]==‘on’ ? ‘https://’ : ‘http://’;
b a s e U r l = u r l e n c o d e ( baseUrl = urlencode( baseUrl=urlencode(scheme. S E R V E R [ ′ H T T P H O S T ′ ] . _SERVER['HTTP_HOST']. SERVER[′HTTPHOST′]._SERVER[‘PHP_SELF’].$_SERVER[‘QUERY_STRING’]);
$url = KaTeX parse error: Expected group after '_' at position 7: this->_̲_CreateOauthUrl…baseUrl);
Header(“Location: $url”);
exit();
} else {
//获取code码,以获取openid
$code = $_GET[‘code’];
$openid = t h i s − > g e t O p e n i d F r o m M p ( this->getOpenidFromMp( this−>getOpenidFromMp(code);
return $openid;
}
}
/**
- 通过code从工作平台获取openid机器access_token
- @param string $code 微信跳转回来带上的code
- @return openid
/
public function GetOpenidFromMp($code)
{
$url = KaTeX parse error: Expected group after '_' at position 7: this->_̲_CreateOauthUrl…code);
r e s = s e l f : : c u r l G e t ( res = self::curlGet( res=self::curlGet(url);
//取出openid
d a t a = j s o n d e c o d e ( data = json_decode( data=jsondecode(res,true);
$this->data = $data;
$openid = $data[‘openid’];
return $openid;
}
/*
- 构造获取open和access_toke的url地址
- @param string $code,微信跳转带回的code
- @return 请求的url
*/
private function __CreateOauthUrlForOpenid($code)
{
$urlObj[“appid”] = $this->appid;
$urlObj[“secret”] = $this->appKey;
$urlObj[“code”] = $code;
$urlObj[“grant_type”] = “authorization_code”;
$bizString = t h i s − > T o U r l P a r a m s ( this->ToUrlParams( this−>ToUrlParams(urlObj);
return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
}
/**
- 构造获取code的url连接
- @param string $redirectUrl 微信服务器回跳的url,需要url编码
- @return 返回构造好的url
*/
private function __CreateOauthUrlForCode($redirectUrl)
{
$urlObj[“appid”] = $this->appid;
u r l O b j [ " r e d i r e c t u r i " ] = " urlObj["redirect_uri"] = " urlObj["redirecturi"]="redirectUrl";
$urlObj[“response_type”] = “code”;
$urlObj[“scope”] = “snsapi_base”;
$urlObj[“state”] = “STATE”."#wechat_redirect";
$bizString = t h i s − > T o U r l P a r a m s ( this->ToUrlParams( this−>ToUrlParams(urlObj);
return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
}
/**
- 拼接签名字符串
- @param array $urlObj
- @return 返回已经拼接好的字符串
*/
private function ToUrlParams($urlObj)
{
b u f f = " " ; f o r e a c h ( buff = ""; foreach ( buff="";foreach(urlObj as $k => KaTeX parse error: Expected '}', got 'EOF' at end of input: v) { if(k != “sign”) $buff .= $k . “=” . $v . “&”;
}
b u f f = t r i m ( buff = trim( buff=trim(buff, “&”);
return $buff;
}
进行付款,将获取的openId与其他参数代入这个方法
/**
- 企业付款
- @param string $openid 调用【网页授权获取用户信息】接口获取到用户在该公众号下的Openid
- @param float $totalFee 收款总费用 单位元
- @param string $outTradeNo 唯一的订单号
- @param string $orderName 订单名称
- @param string $notifyUrl 支付结果通知url 不要有问号
- @param string $timestamp 支付时间
- @return string
*/
public function createJsBizPackage($openid, $totalFee, o u t T r a d e N o , outTradeNo, outTradeNo,trueName)
{
$config = array(
‘mch_id’ => $this->mchid,
‘appid’ => $this->appid,
‘key’ => $this->apiKey,
);
$unified = array(
‘mch_appid’ => $config[‘appid’],
‘mchid’ => $config[‘mch_id’],
‘nonce_str’ => self::createNonceStr(),
‘openid’ => o p e n i d , ′ c h e c k n a m e ′ = > ′ F O R C E C H E C K ′ , / / 校 验 用 户 姓 名 选 项 。 N O C H E C K : 不 校 验 真 实 姓 名 , F O R C E C H E C K : 强 校 验 真 实 姓 名 ′ r e u s e r n a m e ′ = > openid, 'check_name'=>'FORCE_CHECK', //校验用户姓名选项。NO_CHECK:不校验真实姓名,FORCE_CHECK:强校验真实姓名 're_user_name'=> openid,′checkname′=>′FORCECHECK′,//校验用户姓名选项。NOCHECK:不校验真实姓名,FORCECHECK:强校验真实姓名′reusername′=>trueName, //收款用户真实姓名(不支持给非实名用户打款)
‘partner_trade_no’ => o u t T r a d e N o , ′ s p b i l l c r e a t e i p ′ = > ′ 127.0.0. 1 ′ , ′ a m o u n t ′ = > i n t v a l ( outTradeNo, 'spbill_create_ip' => '127.0.0.1', 'amount' => intval( outTradeNo,′spbillcreateip′=>′127.0.0.1′,′amount′=>intval(totalFee * 100), //单位 转为分
‘desc’=>‘付款’, //企业付款操作说明信息
);
u n i f i e d [ ′ s i g n ′ ] = s e l f : : g e t S i g n ( unified['sign'] = self::getSign( unified[′sign′]=self::getSign(unified, $config[‘key’]);
$responseXml = t h i s − > c u r l P o s t ( ′ h t t p s : / / a p i . m c h . w e i x i n . q q . c o m / m m p a y m k t t r a n s f e r s / p r o m o t i o n / t r a n s f e r s ′ , s e l f : : a r r a y T o X m l ( this->curlPost('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers', self::arrayToXml( this−>curlPost(′https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers′,self::arrayToXml(unified));
u n i f i e d O r d e r = s i m p l e x m l l o a d s t r i n g ( unifiedOrder = simplexml_load_string( unifiedOrder=simplexmlloadstring(responseXml, ‘SimpleXMLElement’, LIBXML_NOCDATA);
if ( u n i f i e d O r d e r = = = f a l s e ) d i e ( ′ p a r s e x m l e r r o r ′ ) ; i f ( unifiedOrder === false) { die('parse xml error'); } if ( unifiedOrder===false)die(′parsexmlerror′);if(unifiedOrder->return_code != ‘SUCCESS’) {
die(KaTeX parse error: Expected 'EOF', got '}' at position 30: …return_msg); }̲ if (unifiedOrder->result_code != ‘SUCCESS’) {
die($unifiedOrder->err_code);
}
return true;
}
public static function curlGet($url = ‘’, $options = array())
{
c h = c u r l i n i t ( ch = curl_init( ch=curlinit(url);
curl_setopt( c h , C U R L O P T R E T U R N T R A N S F E R , 1 ) ; c u r l s e t o p t ( ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt( ch,CURLOPTRETURNTRANSFER,1);curlsetopt(ch, CURLOPT_TIMEOUT, 30);
if (!empty(KaTeX parse error: Expected '}', got 'EOF' at end of input: …l_setopt_array(ch, KaTeX parse error: Expected 'EOF', got '}' at position 13: options); }̲ //https请求 不验…ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
d a t a = c u r l e x e c ( data = curl_exec( data=curlexec(ch);
curl_close($ch);
return $data;
}
这里去拿自己在商户号中拿到的证书,要注意的是,php拿到的是以.pem结尾的证书
public function curlPost($url = ‘’, $postData = ‘’, KaTeX parse error: Expected '}', got 'EOF' at end of input: … if (is_array(postData)) {
p o s t D a t a = h t t p b u i l d q u e r y ( postData = http_build_query( postData=httpbuildquery(postData);
}
c h = c u r l i n i t ( ) ; c u r l s e t o p t ( ch = curl_init(); curl_setopt( ch=curlinit();curlsetopt(ch, CURLOPT_URL, u r l ) ; c u r l s e t o p t ( url); curl_setopt( url);curlsetopt(ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt( c h , C U R L O P T P O S T , 1 ) ; c u r l s e t o p t ( ch, CURLOPT_POST, 1); curl_setopt( ch,CURLOPTPOST,1);curlsetopt(ch, CURLOPT_POSTFIELDS, p o s t D a t a ) ; c u r l s e t o p t ( postData); curl_setopt( postData);curlsetopt(ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数
if (!empty(KaTeX parse error: Expected '}', got 'EOF' at end of input: …l_setopt_array(ch, KaTeX parse error: Expected 'EOF', got '}' at position 13: options); }̲ //https请求 不验…ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
//第一种方法,cert 与 key 分别属于两个.pem文件
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/cert/apiclient_cert.pem');
//默认格式为PEM,可以注释
curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/cert/apiclient_key.pem');
//第二种方式,两个文件合成一个.pem文件
// curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
public static function createNonceStr($length = 16)
{
$chars = ‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789’;
s t r = ′ ′ ; f o r ( str = ''; for ( str=′′;for(i = 0; $i < $length; $i++) {
s t r . = s u b s t r ( str .= substr( str.=substr(chars, mt_rand(0, strlen($chars) - 1), 1);
}
return KaTeX parse error: Expected 'EOF', got '}' at position 7: str; }̲ public static…arr)
{
x m l = " " ; f o r e a c h ( xml = ""; foreach ( xml="";foreach(arr as $key => KaTeX parse error: Expected '}', got 'EOF' at end of input: …if (is_numeric(val)) {
$xml .= “<” . $key . “>” . $val . “” . $key . “>”;
} else
$xml .= “<” . $key . “>” . $key . “>”;
}
$xml .= “”;
return $xml;
}
public static function getSign($params, KaTeX parse error: Expected '}', got 'EOF' at end of input: …ey) { ksort(params, SORT_STRING);
u n S i g n P a r a S t r i n g = s e l f : : f o r m a t Q u e r y P a r a M a p ( unSignParaString = self::formatQueryParaMap( unSignParaString=self::formatQueryParaMap(params, false);
s i g n S t r = s t r t o u p p e r ( m d 5 ( signStr = strtoupper(md5( signStr=strtoupper(md5(unSignParaString . “&key=” . $key));
return KaTeX parse error: Expected 'EOF', got '}' at position 11: signStr; }̲ protected stat…paraMap, $urlEncode = false)
{
b u f f = " " ; k s o r t ( buff = ""; ksort( buff="";ksort(paraMap);
foreach ($paraMap as $k => $v) {
if (null != $v && “null” != KaTeX parse error: Expected '}', got 'EOF' at end of input: v) { if (urlEncode) {
v = u r l e n c o d e ( v = urlencode( v=urlencode(v);
}
$buff .= $k . “=” . $v . “&”;
}
}
r e q P a r = ′ ′ ; i f ( s t r l e n ( reqPar = ''; if (strlen( reqPar=′′;if(strlen(buff) > 0) {
r e q P a r = s u b s t r ( reqPar = substr( reqPar=substr(buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
}
调取类文件进行提现
至此,大功告成~~~~~~ ~~~~~~