zoukankan      html  css  js  c++  java
  • PHP实现微信提现(企业付款到零钱)

    怎么开通企业付款到零钱?

    有的商户号的产品中心是没有这个功能的,不过,该功能的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-x08x0b-x0cx0e-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

  • 相关阅读:
    socket
    RBAC
    CMOS和BIOS
    canvas和SVG
    兼容IE,chrome,ff的设为首页、加入收藏及保存到桌面
    HTML标签marquee实现滚动效果
    百度判断手机终端并自动跳转uaredirect.js代码及使用实例
    JavaScript中常用的事件
    解决windows server 2008 r2 登录进入桌面只显示一片蓝色背景
    ng2自定义管道
  • 原文地址:https://www.cnblogs.com/a609251438/p/11901040.html
Copyright © 2011-2022 走看看