不用SDK实现微信支付PHP代码

好几个项目都遇到了集成微信支付功能,虽然微信支付有官方的SDK,但是有些时候不是很好集成,于是参考官方SDK自己写了一份,期间也踩了不少坑,希望能帮助到后来人。

先是微信支付统一下单接口部分代码:

public function unifiedorder($wx_order_id, $totalPrice){
    //获取当前服务器IP
    if (isset($_SERVER)) {
        if ($_SERVER['SERVER_ADDR']) {
            $server_ip = $_SERVER['SERVER_ADDR'];
        } else {
            $server_ip = $_SERVER['LOCAL_ADDR'];
        }
    } else {
        $server_ip = getenv('SERVER_ADDR');
    }

    $unifiedorder_data = array(
        "appid" => $this->config->item('wxpay_appid'), //微信支付APP ID
        'mch_id' => $this->config->item('wxpay_mch_id'), //微信支付商家ID
// 'device_info'=>"WEB",
        'nonce_str' => strtoupper(substr(md5(time()), 1, 11)),
        'body' => '订单描述', //本地订单描述
        'out_trade_no' => $wx_order_id, //传入本地系统生成好的订单ID
        'total_fee' => $totalPrice * 100, //商品总价 以分为单位
        'spbill_create_ip' => $server_ip,
        'notify_url' => "http://" . $_SERVER['HTTP_HOST'] . "/weixin/wxpay_callback",
        'trade_type' => "JSAPI",
        'openid' => $this->getOpenId(), //用户的OpenId 调用这个统一下单接口之前要先获取到
    );

    ksort($unifiedorder_data);
    //签名
    $unifiedorder_str = '';
    foreach ($unifiedorder_data as $key => $value) {
        $unifiedorder_str .= $key . "=" . $value . "&";
    }
    $unifiedorder_str_to_md5 = $unifiedorder_str . "key=" . $this->config->item('wxpay_key'); //微信支付key
    $unifiedorder_data['sign'] = strtoupper(md5($unifiedorder_str_to_md5));
    //拼合成xml
    $unifiedorder_xml = "<xml>";
    foreach ($unifiedorder_data as $key => $value) {
        $unifiedorder_xml .= "<" . $key . ">" . $value . "</" . $key . ">";
    }
    $unifiedorder_xml = $unifiedorder_xml . "</xml>";

// 用curl发送上面组装到的数据到微信接口
    $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; //接收XML地址
    $ch = curl_init(); //初始化curl
    curl_setopt($ch, CURLOPT_URL, $url); //设置链接
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //设置是否返回信息
    curl_setopt($ch, CURLOPT_POST, 1); //设置为POST方式
    curl_setopt($ch, CURLOPT_POSTFIELDS, $unifiedorder_xml); //POST数据
    $response = curl_exec($ch); //接收返回信息
// dd($response);
    $error = curl_errno($ch);
    if ($error > 0) {
        dd("curl出错,错误码:$error");
    }
    curl_close($ch); //关闭curl链接
    $response_array = (array)simplexml_load_string($response, "SimpleXMLElement", LIBXML_NOCDATA);

    //将结果输出给前端 由前端拉起微信支付界面
    if ($response_array['result_code'] == 'SUCCESS') {
        $wx_data = $this->convert_wxdata($response_array);
        OutputData($wx_data);
// OutputData($response_array);
    } else {
        OutputError('微信下单失败!');
    }
    //微信统一下单接口部分结束
}

微信支付回调:

/*
* 微信支付回调
*/
public function wxpay_callback()
{
    $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
    $callback_data = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
    $callback_data = json_decode(json_encode((array)$callback_data), TRUE);

    if (($callback_data['result_code'] == 'SUCCESS')) {
        //业务代码

    }

    //告诉微信支付接口 商户后台系统接收回调信息成功 防止微信支付回调系统再次调用本接口
    echo "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
}

/*
* 校验微信返回数据是否合法
* Done
* 时间:2016-10-10 16:53:18
*/
private function wxpay_check($data)
{
    $sign = $data['sign'];
    unset($data['sign']);
    ksort($data);
// $wxpayment = $this->get_wxpayment();
    $str = '';
    foreach ($data as $key => $value) {
        $str .= $key . "=" . $value . "&";
    }
    $str = substr($str, 0, strlen($str) - 1);
    $str_to_md5 = $str . "&key=" . $this->config->item('wxpay_key'); //微信支付key
    $check = strtoupper(md5($str_to_md5));
    if ($check == $sign) {
        return true;
    } else {
        return false;
    }
}

如果黏贴之后缩进全部没有了,要使用的可以用编辑器自动格式化一下。