<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Wechatpay extends CI_Controller
{
//微信支付
public function pay()
{
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE");
header('Access-Control-Allow-Headers:Origin,Content-Type,Accept,token,X-Requested-With,device');
$datas = file_get_contents('php://input'); // 接收过来的json数据
$input = json_decode($datas, true);// 转化为数组
//参数定义
$appid = 'wx0edb960656828a98';
$appsecret = '14bc1eea2904258c9517255f10f2f132';
$mch_id = '1610399092';
$notify_url = 'https://mengya.wxfzyc.com/api/Wechatpay/wechatNotify';
//获取openid
/*if(I("post.userid"))
{
$infos=M('weixin_users')->find(I("post.userid"));
$openid = $infos->openid;
}*/
$openid = $input['openid'];
// 获取订单
$order = $this->db->get_where('t_order', array('id' => $input['id']))->row_array();
//支付相关设置
$fee = 0.01;//举例支付0.01
$body = 'test';
$nonce_str = $this->nonce_str();//随机字符串
$out_trade_no = $order['sn'];//商户订单号
$spbill_create_ip = '211.149.141.92';//服务器的ip【自己填写】;
$total_fee = $fee*100;// 微信支付单位是分,所以这里需要*100
$trade_type = 'JSAPI';//交易类型 默认
//这里是按照顺序的 因为下面的签名是按照顺序 排序错误 肯定出错
$post['appid'] = $appid;
$post['body'] = $body;
$post['mch_id'] = $mch_id;
$post['nonce_str'] = $nonce_str;//随机字符串
$post['notify_url'] = $notify_url;
$post['openid'] = $openid;
$post['out_trade_no'] = $out_trade_no;
$post['spbill_create_ip'] = $spbill_create_ip;//终端的ip
$post['total_fee'] = $total_fee;//总金额
$post['trade_type'] = $trade_type;
$sign = $this->getSign($post);//签名
$post_xml = '<xml> <appid>'.$appid.'</appid>
<body>'.$body.'</body>
<mch_id>'.$mch_id.'</mch_id>
<nonce_str>'.$nonce_str.'</nonce_str>
<notify_url>'.$notify_url.'</notify_url>
<openid>'.$openid.'</openid>
<out_trade_no>'.$out_trade_no.'</out_trade_no>
<spbill_create_ip>'.$spbill_create_ip.'</spbill_create_ip>
<total_fee>'.$total_fee.'</total_fee>
<trade_type>'.$trade_type.'</trade_type>
<sign>'.$sign.'</sign></xml> ';
//统一接口prepay_id
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$xml = $this->http_request($url, $post_xml);
$array = $this->xml($xml);//全要大写
if ($array['return_code'] == 'SUCCESS' && $array['result_code'] == 'SUCCESS') {
$time = time();
$data['appId'] = $appid;
$data['timeStamp'] = strval($time);//时间戳
$data['nonceStr'] = $nonce_str;//随机字符串
$data['signType'] = 'MD5';//签名算法,暂支持 MD5
$data['package'] = 'prepay_id='.$array['prepay_id'];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
$data['paySign'] = $this->getSign($data);//签名,具体签名方案参见微信公众号支付帮助文档;
$data['state'] = 200;
$data['out_trade_no'] = $out_trade_no;
} else {
$data['state'] = 0;
$data['text'] = "错误";
$data['return_code'] = $array['return_code'];
$data['result_code'] = $array['result_code'];
}
$this->db->insert('t_test',array('data'=>json_encode($data,JSON_UNESCAPED_UNICODE)));
header('Content-Type:application/json;charset=utf-8');
echo json_encode($data,JSON_UNESCAPED_UNICODE);
}
//随机32位字符串
private function nonce_str()
{
$result = '';
$str = 'QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz';
for ($i = 0; $i < 32; $i++) {
$result .= $str[rand(0, 48)];
}
return $result;
}
//作用:生成签名
private function getSign($Obj) {
$key = "Skyabc007514419Skyabc007514419Sk";
foreach ($Obj as $k => $v) {
$Parameters[$k] = $v;
}
//签名步骤一:按字典序排序参数
ksort($Parameters);
$String = $this->formatBizQueryParaMap($Parameters, false);
//签名步骤二:在string后加入KEY
$String = $String . "&key=" . $key;
//签名步骤三:MD5加密
$String = md5($String);
//签名步骤四:所有字符转为大写
$result_ = strtoupper($String);
return $result_;
}
//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;
}
///作用:格式化参数,签名过程需要使用
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;
}
//获取xml
private function xml($xml)
{
// $p = xml_parser_create();
// xml_parse_into_struct($p, $xml, $vals, $index);
// xml_parser_free($p);
// $data = "";
// foreach ($index as $key => $value) {
// if ($key == 'xml' || $key == 'XML') continue;
// $tag = $vals[$value[0]]['tag'];
// $value = $vals[$value[0]]['value'];
// $data[$tag] = $value;
// }
// return $data;
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $values;
}
public function wechatNotify()
{
//存储微信的回调
$xml = file_get_contents("php://input");
$arr = $this->XmlToArr($xml);
$out_trade_no = $arr['out_trade_no'];
$openid = $arr['openid'];//openid
$sign = $arr['sign'];//校验码
$total_fee = $arr['total_fee'];//订单金额
$transaction_id = $arr['transaction_id'];//微信支付号
// 支付回调更改状态
$order = $this->db->get_where('t_order', array('sn' => $out_trade_no))->row_array();
// 用户更改为消费用户
$this->db->update('t_user', array('shenfen' => 2), array('id' => $order['user_id']));
// 支付状态改为已经支付 修改支付时间
$this->db->get_where('t_order',array('status'=>2,'pay_time'=>time()),array('sn'=>$out_trade_no));
echo 'success';
}
private function XmlToArr($xml)
{
if ($xml == '') return '';
libxml_disable_entity_loader(true);
$arr = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $arr;
}
//数组转换成xml
private function arrayToXml($arr) {
$xml = "<root>";
foreach ($arr as $key => $val) {
if (is_array($val)) {
$xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";
} else {
$xml .= "<" . $key . ">" . $val . "</" . $key . ">";
}
}
$xml .= "</root>";
return $xml;
}
}
网友评论