好几个项目都遇到了集成微信支付功能,虽然微信支付有官方的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;
}
}
如果黏贴之后缩进全部没有了,要使用的可以用编辑器自动格式化一下。