PHPは微信の現金引き出しを実現する(企業が小銭を支払う)

6516 ワード

https://pay.weixin.qq.com/index.php/public/product/detail?pid=5&productType=0
どのように企業を開通して小銭を支払いますか?
商家号の製品センターにはこの機能がないものもありますが、この機能のpid(product id)は5で、ある製品に勝手に入って、住所欄でpidを5に変更します.
この機能ページにアクセスして開通しますが、条件を満たしてください.
ユーザ提示コード:
//      
 private function withdrawals_weixin($id){
        $falg = M('withdrawals')->where(['id'=>$id])->find();
        $openid = M('users')->where('user_id', $falg['user_id'])->value('openid');
        $data['openid'] = $openid;
        $data['pay_code'] = $falg['id'].$falg['user_id'];
        $data['desc'] = '  ID'.$falg['id'];
        if($falg['taxfee'] >= $falg['money']){
            return array('status'=>1, 'msg'=>"           !" );
        }else{
            $data['money'] = bcsub($falg['money'], $falg['taxfee'], 2);
        }
        include_once PLUGIN_PATH . "payment/weixin/weixin.class.php";
        $weixin_obj = new \weixin();
        $result = $weixin_obj->transfer($data);
     
        return $result;
  }

ここでpay_コードは商家番号での現金化機能が唯一なので、再生攻撃を防ぐために、この値は決して乱数ではなく、IDで現金化記録が唯一あることが望ましい.
論理コードの抽出:
//       
    function transfer($data){
        
        header("Content-type: text/html; charset=utf-8");
        //CA       
    	$wxchat['appid'] = WxPayConfig::$appid;
    	$wxchat['mchid'] = WxPayConfig::$mchid;

    	$wxchat['api_cert'] = PLUGIN_PATH.'/payment/weixin/cert/apiclient_cert.pem';
        $wxchat['api_key'] = PLUGIN_PATH.'/payment/weixin/cert/apiclient_key.pem';
        
        // $wxchat['api_ca'] = '/plugins/payment/weixin/cert/rootca.pem';
    	$webdata = array(
    			'mch_appid' => $wxchat['appid'],
    			'mchid'     => $wxchat['mchid'],
    			'nonce_str' => md5(time()),
    			//'device_info' => '1000',
    			'partner_trade_no'=> $data['pay_code'], //     ,    
    			'openid' => $data['openid'],//     openid
    			'check_name'=> 'NO_CHECK', //OPTION_CHECK         , FORCE_CHECK:   NO_CHECK:
    			//'re_user_name' => 'jorsh', //       
    			'amount' => $data['money'] * 100, //        
    			'desc'   => $data['desc'],
    			'spbill_create_ip' => request()->ip(),
        );
    
    	foreach ($webdata as $k => $v) {
    		$tarr[] =$k.'='.$v;
        }

    	sort($tarr);
    	$sign = implode($tarr, '&');
    	$sign .= '&key='.WxPayConfig::$key;
        $webdata['sign']=strtoupper(md5($sign));
        
        $wget = $this->array2xml($webdata);
       
        $pay_url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers';

        $res = $this->http_post($pay_url, $wget, $wxchat);

    	if(!$res){
    		return array('status'=>1, 'msg'=>"Can't connect the server" );
    	}
        $content = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
        
    	if(strval($content->return_code) == 'FAIL'){
    		return array('status'=>1, 'msg'=>strval($content->return_msg));
    	}
    	if(strval($content->result_code) == 'FAIL'){
    		return array('status'=>1, 'msg'=>strval($content->err_code),':'.strval($content->err_code_des));
        }

    	$rdata = array(
    			'mch_appid'        => strval($content->mch_appid),
    			'mchid'            => strval($content->mchid),
    			'device_info'      => strval($content->device_info),
    			'nonce_str'        => strval($content->nonce_str),
    			'result_code'      => strval($content->result_code),
    			'partner_trade_no' => strval($content->partner_trade_no),
    			'payment_no'       => strval($content->payment_no),
    			'payment_time'     => strval($content->payment_time),
    	);
    	return $rdata;

    }
   

ここでPLUGIN_PATHは定数です
define('PLUGIN_PATH', __DIR__ . '/plugins/');

プラグインディレクトリの定義
 
    /**
     *          XML       
     * @param array $arr       
     * @param int $level     , 1   Root.
     * @return string XML       
     */
    function array2xml($arr, $level = 1) {
    	$s = $level == 1 ? "" : '';
    	foreach($arr as $tagname => $value) {
    		if (is_numeric($tagname)) {
    			$tagname = $value['TagName'];
    			unset($value['TagName']);
    		}
    		if(!is_array($value)) {
    			$s .= "".(!is_numeric($value) ? '' : '')."{$tagname}>";
    		} else {
    			$s .= "" . $this->array2xml($value, $level + 1)."{$tagname}>";
    		}
    	}
    	$s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s);
    	return $level == 1 ? $s."" : $s;
    }
    
    function http_post($url, $param, $wxchat) {
    	$oCurl = curl_init();
    	if (stripos($url, "https://") !== FALSE) {
    		curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
    		curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
    	}
    	if (is_string($param)) {
    		$strPOST = $param;
    	} else {
    		$aPOST = array();
    		foreach ($param as $key => $val) {
    			$aPOST[] = $key . "=" . urlencode($val);
    		}
    		$strPOST = join("&", $aPOST);
    	}
    	curl_setopt($oCurl, CURLOPT_URL, $url);
    	curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
    	curl_setopt($oCurl, CURLOPT_POST, true);
    	curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
    	if($wxchat){
    		curl_setopt($oCurl,CURLOPT_SSLCERT,$wxchat['api_cert']);
    		curl_setopt($oCurl,CURLOPT_SSLKEY,$wxchat['api_key']);
    		curl_setopt($oCurl,CURLOPT_CAINFO,$wxchat['api_ca']);
    	}
    	$sContent = curl_exec($oCurl);
    	$aStatus = curl_getinfo($oCurl);
        curl_close($oCurl);
        
    	if (intval($aStatus["http_code"]) == 200) {
    		return $sContent;
    	} else {
    		return false;
    	}
    }