怎么开通企业付款到零钱?
有的商户号的产品中心是没有这个功能的,不过,该功能的pid(product id)是5,只要随便进去某一个产品,在地址栏把pid改为5。
即可进入该功能页面,进行开通,不过要满足条件。
用户提现代码:
1 //用户微信提现 2 private function withdrawals_weixin($id){ 3 $falg = M(\'withdrawals\')->where([\'id\'=>$id])->find(); 4 $openid = M(\'users\')->where(\'user_id\', $falg[\'user_id\'])->value(\'openid\'); 5 $data[\'openid\'] = $openid; 6 $data[\'pay_code\'] = $falg[\'id\'].$falg[\'user_id\']; 7 $data[\'desc\'] = \'提现ID\'.$falg[\'id\']; 8 if($falg[\'taxfee\'] >= $falg[\'money\']){ 9 return array(\'status\'=>1, \'msg\'=>"提现额度必须大于手续费!" ); 10 }else{ 11 $data[\'money\'] = bcsub($falg[\'money\'], $falg[\'taxfee\'], 2); 12 } 13 include_once PLUGIN_PATH . "payment/weixin/weixin.class.php"; 14 $weixin_obj = new \weixin(); 15 $result = $weixin_obj->transfer($data); 16 17 return $result; 18 }
其中pay_code在商户号的提现功能是唯一的,所以为了防重放攻击,这个值千万不能用随机数,最好用ID,具有提现记录唯一。
提现逻辑代码:
1 // 微信提现转账 2 function transfer($data){ 3 4 header("Content-type: text/html; charset=utf-8"); 5 //CA证书及支付信息 6 $wxchat[\'appid\'] = WxPayConfig::$appid; 7 $wxchat[\'mchid\'] = WxPayConfig::$mchid; 8 9 $wxchat[\'api_cert\'] = PLUGIN_PATH.\'/payment/weixin/cert/apiclient_cert.pem\'; 10 $wxchat[\'api_key\'] = PLUGIN_PATH.\'/payment/weixin/cert/apiclient_key.pem\'; 11 12 // $wxchat[\'api_ca\'] = \'/plugins/payment/weixin/cert/rootca.pem\'; 13 $webdata = array( 14 \'mch_appid\' => $wxchat[\'appid\'], 15 \'mchid\' => $wxchat[\'mchid\'], 16 \'nonce_str\' => md5(time()), 17 //\'device_info\' => \'1000\', 18 \'partner_trade_no\'=> $data[\'pay_code\'], //商户订单号,需要唯一 19 \'openid\' => $data[\'openid\'],//转账用户的openid 20 \'check_name\'=> \'NO_CHECK\', //OPTION_CHECK不强制校验真实姓名, FORCE_CHECK:强制 NO_CHECK: 21 //\'re_user_name\' => \'jorsh\', //收款人用户姓名 22 \'amount\' => $data[\'money\'] * 100, //付款金额单位为分 23 \'desc\' => $data[\'desc\'], 24 \'spbill_create_ip\' => request()->ip(), 25 ); 26 27 foreach ($webdata as $k => $v) { 28 $tarr[] =$k.\'=\'.$v; 29 } 30 31 sort($tarr); 32 $sign = implode($tarr, \'&\'); 33 $sign .= \'&key=\'.WxPayConfig::$key; 34 $webdata[\'sign\']=strtoupper(md5($sign)); 35 36 $wget = $this->array2xml($webdata); 37 38 $pay_url = \'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers\'; 39 40 $res = $this->http_post($pay_url, $wget, $wxchat); 41 42 if(!$res){ 43 return array(\'status\'=>1, \'msg\'=>"Can\'t connect the server" ); 44 } 45 $content = simplexml_load_string($res, \'SimpleXMLElement\', LIBXML_NOCDATA); 46 47 if(strval($content->return_code) == \'FAIL\'){ 48 return array(\'status\'=>1, \'msg\'=>strval($content->return_msg)); 49 } 50 if(strval($content->result_code) == \'FAIL\'){ 51 return array(\'status\'=>1, \'msg\'=>strval($content->err_code),\':\'.strval($content->err_code_des)); 52 } 53 54 $rdata = array( 55 \'mch_appid\' => strval($content->mch_appid), 56 \'mchid\' => strval($content->mchid), 57 \'device_info\' => strval($content->device_info), 58 \'nonce_str\' => strval($content->nonce_str), 59 \'result_code\' => strval($content->result_code), 60 \'partner_trade_no\' => strval($content->partner_trade_no), 61 \'payment_no\' => strval($content->payment_no), 62 \'payment_time\' => strval($content->payment_time), 63 ); 64 return $rdata; 65 66 }
其中 PLUGIN_PATH 是一个常量
1 define(\'PLUGIN_PATH\', __DIR__ . \'/plugins/\'); 2 定义插件目录 3 4 5 /** 6 * 将一个数组转换为 XML 结构的字符串 7 * @param array $arr 要转换的数组 8 * @param int $level 节点层级, 1 为 Root. 9 * @return string XML 结构的字符串 10 */ 11 function array2xml($arr, $level = 1) { 12 $s = $level == 1 ? "<xml>" : \'\'; 13 foreach($arr as $tagname => $value) { 14 if (is_numeric($tagname)) { 15 $tagname = $value[\'TagName\']; 16 unset($value[\'TagName\']); 17 } 18 if(!is_array($value)) { 19 $s .= "<{$tagname}>".(!is_numeric($value) ? \'<![CDATA[\' : \'\').$value.(!is_numeric($value) ? \']]>\' : \'\')."</{$tagname}>"; 20 } else { 21 $s .= "<{$tagname}>" . $this->array2xml($value, $level + 1)."</{$tagname}>"; 22 } 23 } 24 $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", \' \', $s); 25 return $level == 1 ? $s."</xml>" : $s; 26 } 27 28 function http_post($url, $param, $wxchat) { 29 $oCurl = curl_init(); 30 if (stripos($url, "https://") !== FALSE) { 31 curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE); 32 curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE); 33 } 34 if (is_string($param)) { 35 $strPOST = $param; 36 } else { 37 $aPOST = array(); 38 foreach ($param as $key => $val) { 39 $aPOST[] = $key . "=" . urlencode($val); 40 } 41 $strPOST = join("&", $aPOST); 42 } 43 curl_setopt($oCurl, CURLOPT_URL, $url); 44 curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1); 45 curl_setopt($oCurl, CURLOPT_POST, true); 46 curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST); 47 if($wxchat){ 48 curl_setopt($oCurl,CURLOPT_SSLCERT,$wxchat[\'api_cert\']); 49 curl_setopt($oCurl,CURLOPT_SSLKEY,$wxchat[\'api_key\']); 50 curl_setopt($oCurl,CURLOPT_CAINFO,$wxchat[\'api_ca\']); 51 } 52 $sContent = curl_exec($oCurl); 53 $aStatus = curl_getinfo($oCurl); 54 curl_close($oCurl); 55 56 if (intval($aStatus["http_code"]) == 200) { 57 return $sContent; 58 } else { 59 return false; 60 } 61 }
很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的加群(点击→)677079770