| 
use GuzzleHttp\Client;
class RechargeFreeVoucherDemo
{
    
    protected $requestType = 1;
    
    protected $nonceStr = '5K8264ILTKCH16CQ2502SI8ZNMTM67VS';
    
    protected $signKey = '你的微信支付密钥'; 
    
    protected $mchId = '你的商户号'; 
    
    protected $sandBoxKey = '沙箱验签秘钥'; 
    
    protected $openXmlArr = true;
    
    public static function getSignContent($data): string
    {
        $buff = '';
        foreach ($data as $k => $v) {
            $buff .= ('sign' != $k && '' != $v && !is_array($v)) ? $k . '=' . $v . '&' : '';
        }
        return trim($buff, '&');
    }
    
    function arrayToXml($arr)
    {
        $xml = "<xml>";
        foreach ($arr as $key => $val) {
            if (is_numeric($val)) {
                $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
            } else
                $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
        }
        $xml .= "</xml>";
        return $xml;
    }
    
    public function xmlToArray($xml)
    {
        
        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array_data;
    }
    
    public function getsignkey($data, $box = true)
    {
        $key = $this->sandBoxKey;
        
        if (!$box) $key = $this->signKey;
        ksort($data);
        $string = md5(self::getSignContent($data) . '&key=' . $key);
        return strtoupper($string);
    }
    
    public function sign()
    {
        $data = [
            'mch_id'    => $this->mchId,
            'nonce_str' => $this->nonceStr
        ];
        $data['sign'] = $this->getsignkey($data, false);
        $url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey';
        $result = $this->post($data, $url);
        if ($this->openXmlArr) if ($this->openXmlArr) $result = $this->xmlToArray($result);
        return $result;
    }
    
    
    public function pay()
    {
        
        $data = [
            'appid'            => 'wxd678efh567hg6787',
            'body'             => '测试商品',
            'mch_id'           => $this->mchId,
            'nonce_str'        => $this->nonceStr,
            'notify_url'       => 'http://www.weixin.qq.com/wxpay/pay.php',
            'out_trade_no'     => '201208241848',
            'spbill_create_ip' => '192.168.10.10',
            'total_fee'        => '552',
            'trade_type'       => 'JSAPI'
        ];
        $url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/unifiedorder';
        $data['sign'] = $this->getsignkey($data);
        $result = $this->post($data, $url);
        if ($this->openXmlArr) $result = $this->xmlToArray($result);
        return $result;
    }
    
    public function query()
    {
        $data = [
            'appid'        => 'wxd678efh567hg6787',
            'mch_id'       => $this->mchId,
            'nonce_str'    => $this->nonceStr,
            'out_trade_no' => '201208241848',
        ];
        $url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/orderquery';
        $data['sign'] = $this->getsignkey($data);
        $result = $this->post($data, $url);
        if ($this->openXmlArr) $result = $this->xmlToArray($result);
        return $result;
    }
    
    
    public function refund()
    {
        
        $data = [
            'appid'         => 'wxd678efh567hg6787',
            'mch_id'        => $this->mchId,
            'nonce_str'     => $this->nonceStr,
            'out_trade_no'  => '201208241848',
            'out_refund_no' => 'TM201208241848',
            'refund_fee'    => '552',
            'total_fee'     => '552',
        ];
        $data['sign'] = $this->getsignkey($data);
        $url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/refund';
        $result = $this->post($data, $url);
        if ($this->openXmlArr) $result = $this->xmlToArray($result);
        return $result;
    }
    
    public function refundquery()
    {
        $data = [
            'appid'        => 'wxd678efh567hg6787',
            'mch_id'       => $this->mchId,
            'nonce_str'    => $this->nonceStr,
            'out_trade_no' => '201208241848',
        ];
        $data['sign'] = $this->getsignkey($data);
        $url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/refundquery';
        $result = $this->post($data, $url);
        if ($this->openXmlArr) $result = $this->xmlToArray($result);
        return $result;
    }
    
    public function downloadbill()
    {
        $data = [
            'appid'        => 'wxd678efh567hg6787',
            'bill_date'    => '20120824',
            'bill_type'    => 'ALL',
            'mch_id'       => $this->mchId,
            'nonce_str'    => $this->nonceStr,
            'out_trade_no' => '201208241848',
        ];
        $data['sign'] = $this->getsignkey($data);
        $url = 'https://api.mch.weixin.qq.com/sandboxnew/pay/downloadbill';
        $result = $this->post($data, $url);
        return $result;
    }
    
    public function post($data, $url)
    {
        
        if ($this->requestType === 1) {
            return $this->curlPost($data, $url);
        }
        if ($this->requestType === 2) {
            return $this->postXmlCurl($data, $url);
        }
        print_r('请求参数错误');
        exit;
    }
    
    public function postXmlCurl($data, $url)
    {
        $xml = $this->arrayToXml($data);
        $httpClient = new Client();
        $response = $httpClient->request('POST', $url, ['body' => $xml]);
        $return = $response->getBody()->getContents();
        return $return;
    }
    
    public function curlPost($data, $url)
    {
        $xmlData = $this->arrayToXml($data);
        $header[] = "Content-type: text/xml";        
        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $xmlData);
        $response = curl_exec($ch);
        if (curl_errno($ch)) {
            print curl_error($ch);
        }
        curl_close($ch);
        return $response;
    }
}
 |