微信支付

Posted huibaoqiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了微信支付相关的知识,希望对你有一定的参考价值。

微信支付

public function pay(){
$Curl = new Curl();
//获取openid
if(input(‘code‘))
{ //用code获取openid

$url = ‘https://api.weixin.qq.com/sns/jscode2session?appid=‘.get_wx_config(‘appid‘).‘&secret=‘.get_wx_config(‘secret‘).‘&js_code=‘.input(‘code‘).‘&grant_type=authorization_code&connect_redirect=1‘;
$infos = $Curl::send($url,‘get‘);
$infos = json_decode($infos);
$openid = $infos->openid;
}else{
return ‘code错误‘;
}
//$fee = I("post.total_fee");
$fee = 0.01;//举例支付0.01
$appid = get_wx_config(‘appid‘);//appid.如果是公众号 就是公众号的appid
$body = input(‘name‘,‘YUMGYMS 源本昱健‘);
$mch_id = get_wx_config(‘mch_id‘); //商户号
$nonce_str = nonce_str();//随机字符串
$notify_url = get_wx_config(‘notify_url‘); //回调的url【自己填写】
$openid = $openid;
$out_trade_no = order_number($openid);//商户订单号
$spbill_create_ip = get_wx_config(‘hosts‘);//服务器的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 = sign($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> ‘;


// print_r($post_xml);die;
//统一接口prepay_id
$url = ‘https://api.mch.weixin.qq.com/pay/unifiedorder‘;
$xml = http_request($url,$post_xml);

$array = xml($xml);//全要大写

//print_r($array);
if($array[‘RETURN_CODE‘] == ‘SUCCESS‘ && $array[‘RESULT_CODE‘] == ‘SUCCESS‘){
$time = time();
$tmp=‘‘;//临时数组用于签名
$tmp[‘appId‘] = $appid;
$tmp[‘nonceStr‘] = $nonce_str;
$tmp[‘package‘] = ‘prepay_id=‘.$array[‘PREPAY_ID‘];
$tmp[‘signType‘] = ‘MD5‘;
$tmp[‘timeStamp‘] = "$time";
$data[‘state‘] = 200;
$data[‘timeStamp‘] = "$time";//时间戳
$data[‘nonceStr‘] = $nonce_str;//随机字符串
$data[‘signType‘] = ‘MD5‘;//签名算法,暂支持 MD5
$data[‘package‘] = ‘prepay_id=‘.$array[‘PREPAY_ID‘];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
$data[‘paySign‘] = sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
$data[‘out_trade_no‘] = $out_trade_no;
}else{
$data[‘state‘] = 0;
$data[‘text‘] = "错误";
$data[‘RETURN_CODE‘] = $array[‘RETURN_CODE‘];
$data[‘RETURN_MSG‘] = $array[‘RETURN_MSG‘];
}
echo json_encode($data);
}
//随机32位字符串
if(!function_exists(‘nonce_str‘)){
function nonce_str(){
$result = ‘‘;
$str = ‘QWERTYUIOPASDFGHJKLZXVBNMqwertyuioplkjhgfdsamnbvcxz‘;
for ($i=0;$i<32;$i++){
$result .= $str[rand(0,48)];
}
return $result;
}
}
//生成订单号
if(!function_exists(‘order_number‘)){
function order_number($openid){
//date(‘Ymd‘,time()).time().rand(10,99);//18位
return md5($openid.time().rand(10,99));//32位
}
}
//签名 $data要先排好顺序
if(!function_exists(‘sign‘)) {
function sign($data)
{
$stringA = ‘‘;
foreach ($data as $key => $value) {
if (!$value) continue;
if ($stringA) $stringA .= ‘&‘ . $key . "=" . $value;
else $stringA = $key . "=" . $value;
}
$wx_key = ‘UhY3gTUOiyTWy5ND6zvZgkcw2bJ2DLiS‘;//申请支付后有给予一个商户账号和密码,登陆后自己设置的key
$stringSignTemp = $stringA . ‘&key=‘ . $wx_key;
return strtoupper(md5($stringSignTemp));
}
}
if(!function_exists(‘xml‘)) {
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;
}
}
//curl请求
if(!function_exists(‘http_request‘)) {
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;
}
}
// 支付回调
class
ApiNotify extends Api
{
protected $SSLCERT_PATH = ‘cert/apiclient_cert.pem‘;//证书路径
protected $SSLKEY_PATH = ‘cert/apiclient_key.pem‘;//证书路径

public function pay(){
$input = file_get_contents("php://input");
if($input){
$xml = $this -> xmlToArray($input);
Log::write($xml);
if ($xml[‘return_code‘] == "SUCCESS" && $xml[‘result_code‘] == "SUCCESS") {
//获取返回的所以参数
//这里是要把微信返给我们的所有值,先删除sign的值,其他值 按ASCII从小到大排序,md5加密+‘key’;
foreach( $xml as $k=>$v) {
if($k == ‘sign‘) {
$xmlSign = $xml[$k];
unset($xml[$k]);
};
}
$sign = http_build_query($xml);
//md5处理
$sign = md5($sign.‘&key=‘.‘UhY3gTUOiyTWy5ND6zvZgkcw2bJ2DLiS‘);
//转大写
$sign = strtoupper($sign);
if ( $sign === $xmlSign) {
do something;
}
}
}
}


public function xmlToArray($xml) {
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$xmlstring = simplexml_load_string($xml, ‘SimpleXMLElement‘, LIBXML_NOCDATA);
$val = json_decode(json_encode($xmlstring), true);
return $val;
}

//微信退款

function Home_index($order_id) {
if(!$order_id){
return json_encode([‘code‘ => -99,‘msg‘ => ‘参数错误‘],JSON_UNESCAPED_UNICODE);
}
$order = Db::name(‘order‘) -> where(‘id‘,$order_id) -> find();
$data[‘appid‘] = get_wx_config(‘appid‘);
$data[‘mch_id‘] = get_wx_config(‘mch_id‘);
$data[‘nonce_str‘] = nonce_str();
$data[‘out_refund_no‘] = order_number($order[‘openid‘]);
$data[‘out_trade_no‘] = $order[‘orderNumber‘];
$data[‘refund_fee‘] = $order[‘fee‘]*100;
$data[‘total_fee‘] = $order[‘fee‘]*100;
$ref = sign($data); //sign加密MD5
$refund = array(
‘appid‘ =>$data[‘appid‘], //应用ID,固定
‘mch_id‘ => $data[‘mch_id‘], //商户号,固定
‘nonce_str‘ => $data[‘nonce_str‘], //随机字符串
‘out_refund_no‘ => $data[‘out_refund_no‘], //商户内部唯一退款单号
‘out_trade_no‘ => $data[‘out_trade_no‘], //商户订单号,pay_sn码 1.1二选一,微信生成的订单号,在支付通知中有返回
‘refund_fee‘ => $data[‘refund_fee‘], //退款金额
‘total_fee‘ => $data[‘total_fee‘], //总金额
‘sign‘ => $ref//签名
);
$post_xml = "<xml>
<appid>$data[appid]</appid>
<mch_id>$data[mch_id]</mch_id>
<nonce_str>$data[nonce_str]</nonce_str>
<out_refund_no>$data[out_refund_no]</out_refund_no>
<out_trade_no>$data[out_trade_no]</out_trade_no>
<refund_fee>$data[refund_fee]</refund_fee>
<total_fee>$data[total_fee]</total_fee>
<sign>$ref</sign>
</xml>";
$url = "https://api.mch.weixin.qq.com/secapi/pay/refund";
//微信退款地址,post请求
$xml =$this -> postXmlSSLCurl($post_xml,$url);
$xml = $this -> xmlToArray($xml);
log::write($xml);
// 返回结果0的时候能只能表明程序是正常返回不一定说明退款成功而已
if ($xml[‘return_code‘] == ‘SUCCESS‘) {
if($xml[‘result_code‘] == ‘SUCCESS‘){
return json_encode([‘code‘ => ‘SUCCESS‘ , ‘msg‘ => ‘退款成功‘],JSON_UNESCAPED_UNICODE);
}else{
return json_encode([‘code‘ => ‘FAIL‘ , ‘msg‘ => $xml[‘err_code_des‘]],JSON_UNESCAPED_UNICODE);
}
}
}


public 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, $this->SSLCERT_PATH);
//默认格式为PEM,可以注释
curl_setopt($ch, CURLOPT_SSLKEYTYPE, ‘PEM‘);
curl_setopt($ch, CURLOPT_SSLKEY, $this->SSLKEY_PATH);
//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;
}
}

 

 

public function pay(){
$Curl = new Curl();
//获取openid
if(input(‘code‘))
{ //用code获取openid

$url = ‘https://api.weixin.qq.com/sns/jscode2session?appid=‘.get_wx_config(‘appid‘).‘&secret=‘.get_wx_config(‘secret‘).‘&js_code=‘.input(‘code‘).‘&grant_type=authorization_code&connect_redirect=1‘;
$infos = $Curl::send($url,‘get‘);
$infos = json_decode($infos);
$openid = $infos->openid;
}else{
return ‘code错误‘;
}
//$fee = I("post.total_fee");
$fee = 0.01;//举例支付0.01
$appid = get_wx_config(‘appid‘);//appid.如果是公众号 就是公众号的appid
$body = input(‘name‘,‘YUMGYMS 源本昱健‘);
$mch_id = get_wx_config(‘mch_id‘); //商户号
$nonce_str = nonce_str();//随机字符串
$notify_url = get_wx_config(‘notify_url‘); //回调的url【自己填写】
$openid = $openid;
$out_trade_no = order_number($openid);//商户订单号
$spbill_create_ip = get_wx_config(‘hosts‘);//服务器的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 = sign($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> ‘;


// print_r($post_xml);die;
//统一接口prepay_id
$url = ‘https://api.mch.weixin.qq.com/pay/unifiedorder‘;
$xml = http_request($url,$post_xml);




$array = xml($xml);//全要大写


//print_r($array);
if($array[‘RETURN_CODE‘] == ‘SUCCESS‘ && $array[‘RESULT_CODE‘] == ‘SUCCESS‘){
$time = time();
$tmp=‘‘;//临时数组用于签名
$tmp[‘appId‘] = $appid;
$tmp[‘nonceStr‘] = $nonce_str;
$tmp[‘package‘] = ‘prepay_id=‘.$array[‘PREPAY_ID‘];
$tmp[‘signType‘] = ‘MD5‘;
$tmp[‘timeStamp‘] = "$time";
$data[‘state‘] = 200;
$data[‘timeStamp‘] = "$time";//时间戳
$data[‘nonceStr‘] = $nonce_str;//随机字符串
$data[‘signType‘] = ‘MD5‘;//签名算法,暂支持 MD5
$data[‘package‘] = ‘prepay_id=‘.$array[‘PREPAY_ID‘];//统一下单接口返回的 prepay_id 参数值,提交格式如:prepay_id=*
$data[‘paySign‘] = sign($tmp);//签名,具体签名方案参见微信公众号支付帮助文档;
$data[‘out_trade_no‘] = $out_trade_no;
$pay = [];
$res = $this -> request -> post();
if(isset($res[‘lei‘]) && $res[‘lei‘] == ‘pay‘){
$pay[‘fee‘] = $res[‘fee‘];
$pay[‘price‘] = $res[‘fee‘]+$res[‘give‘];
$pay[‘openid‘] = $res[‘id‘];
$pay[‘is_pay‘] = 4;
$pay[‘type‘] = ‘线上充值‘;
$pay[‘addtime‘] = time();
$pay[‘orderNumber‘] = $out_trade_no;
$status = Db::name(‘order‘)->insert($pay);
}else{
$temp = Db::name(‘paiqi‘)->where(‘id‘,input(‘id‘))->find();
$order = [];
$order[‘paiqi_id‘] = input(‘id‘);
$order[‘peopleNumber‘] = input(‘peopleNumber‘);
$order[‘teacher_id‘] = $res[‘teacherid‘];
$order[‘openid‘] = $openid;
$order[‘vid‘] = $res[‘chitid‘];
$order[‘orderNumber‘] = $out_trade_no;
$order[‘fee‘] = $fee;
$order[‘is_pay‘] = 1;
if($temp[‘course_cate_id‘] == 5){
$order[‘start_time‘] = date(‘Y-m-d H:i:s‘,time());
$order[‘end_time‘] = date(‘Y-m-d H:i:s‘,strtotime(‘+1year‘));
}elseif($temp[‘course_cate_id‘] == 2){
$_time = explode(‘-‘,$res[‘time‘]);
$order[‘start_time‘] = $res[‘date‘].‘ ‘.$_time[0];
$order[‘end_time‘] = $res[‘date‘].‘ ‘.$_time[1];
$_temp = Db::name(‘order‘)
->where(‘status‘,99)
->where(‘paiqi_id‘,$order[‘paiqi_id‘])
->where(‘teacher_id‘,$order[‘teacher_id‘])
-> where(‘start_time‘,‘like‘,‘%‘.$order[‘start_time‘].‘%‘)->find();
if($_temp){
return json_encode([‘code‘ => -99,‘msg‘ => ‘课程已约满‘],JSON_UNESCAPED_UNICODE);
}
}else{
$order[‘start_time‘] = $res[‘start_time‘];
$order[‘end_time‘] = $res[‘end_time‘];
if($order[‘peopleNumber‘] > ($temp[‘course_people_number‘] - $temp[‘old_people_number‘])){
return json_encode([‘code‘ => -99,‘msg‘ => ‘课程已约满‘],JSON_UNESCAPED_UNICODE);
}
}
$order[‘addtime‘] = time();
$status = Db::name(‘order‘)->insert($order);
if(!$status){
return json_encode($order,JSON_UNESCAPED_UNICODE);
}
}
}else{
$data[‘state‘] = 0;
$data[‘text‘] = "错误";
$data[‘RETURN_CODE‘] = $array[‘RETURN_CODE‘];
$data[‘RETURN_MSG‘] = $array[‘RETURN_MSG‘];
}
echo json_encode($data);
}

























































































































































































































































































































































































































以上是关于微信支付的主要内容,如果未能解决你的问题,请参考以下文章

微信支付——微信公众号内支付 代码

网站如何接入微信支付功能?微信支付详细教程它来了(建议收藏)

微信支付v3的demo怎么转换成thinkphp代码

微信小程序代码片段分享

spring_boot_pay支付宝,微信,银联支付详细代码案例

asp微信支付代码v4.1无需证书版,带回调入库的asp支付源码