软件信息网 移动端开发 PHP:接入微信支付

PHP:接入微信支付

PHP后台调用微信支付下单
function wx_getPayRequest($openid, $orderid, $rmb, $title,$appoids)
{
    $nonce   = $orderid.mt_rand(10000,99999);
    $orderid=$orderid.'_'.$nonce;//str_replace(",","_",$appoids);
    //Log::write('\n ================'.$orderid,'notice');
    $srct='0x'.md5(config('app.environment')['paykey'].$orderid);
    $notify  = '';//回调地址,自己写,支付成功回调,在回调页面进行更改与用户金钱相关的代码
    $url= 'https://api.mch.weixin.qq.com/pay/unifiedorder';//统一接口prepay_id
    // post data
    $now  = time().'';//时间
    $appid ='';//小程序ID 写到一个类里面了 方便后期修改 当然也可以在这里直接写
    $mchid ='';//商户号
   // Log::write('\n $mchid================'.json_encode($mchid),'notice');
   // Log::write('\n $appid================'.json_encode($appid),'notice');
    $data = array(
        'appid'            => $appid,
        'mch_id'           => $mchid,
        'spbill_create_ip' => '127.0.0.1',//终端ip   Y
        'nonce_str'        => $nonce,                //随机字符串Y
        'openid'           => $openid,               //用户标识 N
        'body'             => $title,                //商品描述 Y
        // 'detail'           => $body,                 //商品详情 N
        'attach'           => $appoids,              //附加数据 N
        'out_trade_no'     => $orderid,              //商户订单号 Y
        'total_fee'        => $rmb,                  //总金额 单位分 int Y
        'notify_url'       => $notify,               //通知地址 Y
        'trade_type'       => 'JSAPI',
    );

    $data[ 'sign' ] = self::MakeSign($data);
    //echo $data[ 'sign' ];
   // Log::write('\n sign================'.json_encode($data[ 'sign' ]),'notice');

    $xml=self::wx_toXML($data);
    $ret = $this->http_request($url,$xml);
    $json = self::wx_parseXML( $ret );
    //Log::write('\n ================'.json_encode($json),'notice');
    if( !$json || !isset($json[ 'prepay_id' ]) )
    {
        return array( 'payCode'=>1,'ret' => 'fail', 'tip' => $json[ 'return_msg' ] );
    }

    $prepayid = $json[ 'prepay_id' ];
    $req = array(
        'appId'     => $appid,
        'timeStamp' => $now,
        'nonceStr'  => $nonce,
        'package'   => 'prepay_id='.$prepayid,
        'signType'  => 'MD5',
    );
    $req[ 'paySign' ] = self::wx_getPkgSign($req);
    //$req[ 'notify' ] = $notify;
    return $req;
}

///作用:格式化参数,签名过程需要使用
private function formatBizQueryParaMap($paraMap, $urlencode) {
    $buff = "";
    ksort($paraMap);
    foreach ($paraMap as $k => $v) {
        if ($urlencode) {
            $v = urlencode($v);
        }
        $buff .= $k . "=" . $v . "&";
    }
    $reqPar;
    if (strlen($buff) > 0) {
        $reqPar = substr($buff, 0, strlen($buff) - 1);
    }
    return $reqPar;
}


public function wx_getPkgSign($req )
{
    foreach ($req as $k => $v) {
        $Parameters[$k] = $v;
    }
    //签名步骤一:按字典序排序参数
    ksort($Parameters);
    $String = $this->formatBizQueryParaMap($Parameters, false);
    //签名步骤二:在string后加入KEY
    $String = $String . "&key=" . config('app.environment')['paykey'];
    //签名步骤三:MD5加密
    $String = md5($String);
    //签名步骤四:所有字符转为大写
    $result_ = strtoupper($String);
    return $result_;
}

public  function wx_toXML( $data )
{
    $xml = '<xml>';
    foreach( $data as $key => $val )
    {
        $xml .= '<' . $key . '><![CDATA[' . $val . ']]></' . $key . '>';
    }
    $xml .= '</xml>';
    return $xml;
}

/**
 * 输出xml字符
 * @param $data
 * @return string
 */
public function ToXml($data)
{
    if(!is_array($data)
        || count($data) <= 0)
    {
        throw new WxPayException("数组数据异常!");
    }

    $xml = "<xml>";
    foreach ($data as $key=>$val)
    {
        if (is_numeric($val)){
            $xml.="<".$key.">".$val."</".$key.">";
        }else{
            $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
        }
    }
    $xml.="</xml>";
    return $xml;
}

/**
 * 格式化参数格式化成url参数
 */
public function ToUrlParams($data)
{
    $buff = "";
    foreach ($data as $k => $v)
    {
        if($k != "sign" && $v != "" && !is_array($v)){
            $buff .= $k . "=" . $v . "&";
        }
    }

    $buff = trim($buff, "&");
    return $buff;
}

/**
 * 生成签名
 * @param $data
 * @return string 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
 */
public function MakeSign($data)
{
    //签名步骤一:按字典序排序参数
    ksort($data);
    $string = $this->ToUrlParams($data);
    //签名步骤二:在string后加入KEY
    $string = $string . "&key=".config('app.environment')['paykey'];
    //签名步骤三:MD5加密
    $string = md5($string);
    //签名步骤四:所有字符转为大写
    $result = strtoupper($string);
    return $result;
}

public  function wx_parseXML( $str )
{
    $rsp = array();
    $xml = @simplexml_load_string( $str );
    if( $xml && $xml->children() )
    {
        foreach( $xml->children() as $node )
        {
            if( $node->children() )
            {
                $k = $node->getName();
                $nodeXml = $node->asXML();
                $v = substr( $nodeXml, strlen($k)+2, strlen($nodeXml)-2*strlen($k)-5 );
            }
            else
            {
                $k = $node->getName();
                $v = (string)$node;
            }
            $rsp[ $k ] = $v;
        }
    }
    return $rsp;
}

public function payRefund($wxtranid,$order_childid, $ordertotalrmb,$refundrmb){
    $appid = config('environment')[config('current_environment')]['appid'];//小程序ID 写到一个类里面了 方便后期修改 当然也可以在这里直接写
    $mchid = config('environment')[config('current_environment')]['mchid'];//商户号
    $nonce   = $order_childid.mt_rand(10000,99999);

    Log::write('取消预约单申请退款中===$ordertotalrmb='.$ordertotalrmb.'=======$refundrmb='.$refundrmb,'notice');

    //统一下单退款参数构造
    $unifiedorder = array(
        'appid' => $appid,
        'mch_id' => $mchid,
        'nonce_str' => $nonce,
        'transaction_id' => $wxtranid,
        'out_refund_no' => $order_childid,
        'total_fee' => intval($ordertotalrmb),
        'refund_fee' => intval($refundrmb),
        'notify_url'=>'https://wxcon.drmpsy.com.cn/api/appo/payBackSuccess'
    );
    $unifiedorder['sign'] = self::wx_getPkgSign($unifiedorder);
    Log::write('$content111111================'.json_encode($unifiedorder),'notice');
    //请求数据
    $xmldata = self::wx_toXml($unifiedorder);
    $opUrl = "https://api.mch.weixin.qq.com/secapi/pay/refund";
    //$res = $this->http_request($opUrl, $xmldata);
    $res = $this->postXmlSSLCurl($xmldata,$opUrl);
    Log::write($res,'notice');
    if (!$res) {
        return "Can't connect the server";
    }
    $content = self::xmlToArray($res);
    Log::write('$content================'.json_encode($content),'notice');
    try{
        if (strval($content['result_code']) == 'FAIL') {
            return strval($content['err_code_des']);
        }
    }
    catch (Exception $err){

    }
    try{
        if ($content['return_code']&&strval($content['return_code']) == 'FAIL') {
            return strval($content['return_msg']);
        }
    }
    catch (Exception $err){

    }
    return $content;
}

public function xmlToArray($xml){
    $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
    return $array_data;
}

//需要使用证书的请求
private function postXmlSSLCurl($xml,$url,$second=30)
{
    $ch = curl_init();
    //超时时间
    curl_setopt($ch,CURLOPT_TIMEOUT,$second);
    //这里设置代理,如果有的话
    //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
    //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
    curl_setopt($ch,CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
    curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
    //设置header
    curl_setopt($ch,CURLOPT_HEADER,FALSE);
    //要求结果为字符串且输出到屏幕上
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE);
    //设置证书
    //使用证书:cert 与 key 分别属于两个.pem文件
    //默认格式为PEM,可以注释
    curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLCERT, '/nfs/website/wx.drmpsy.com.cn/api/cert/apiclient_cert.pem');
    //默认格式为PEM,可以注释
    curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
    curl_setopt($ch,CURLOPT_SSLKEY,'/nfs/website/wx.drmpsy.com.cn/api/cert/apiclient_key.pem');
    //post提交方式
    curl_setopt($ch,CURLOPT_POST, true);
    curl_setopt($ch,CURLOPT_POSTFIELDS,$xml);
    $data = curl_exec($ch);
    //返回结果
    if($data){
        curl_close($ch);
        return $data;
    }
    else {
        $error = curl_errno($ch);
        echo "curl出错,错误码:$error"."<br>";
        curl_close($ch);
        return false;
    }
}
//curl请求
public function http_request($url,$data = null,$headers=array())
{
    $curl = curl_init();
    if( count($headers) >= 1 ){
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
    }
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    if (!empty($data)){
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    $output = curl_exec($curl);
    curl_close($curl);
    return $output;
}

作者: 软件定制开发

李铁牛,一直致力于企业客户软件定制开发,计算机专业毕业后,一直从事于互联网产品开发到现在。系统开发,系统源码:15889726201
上一篇
下一篇
联系我们

联系我们

15889726201

在线咨询: QQ交谈

邮箱: 187395037@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部