网站接入微信支付详细步骤

微信开发文档:https://pay.weixin.qq.com/wiki/doc/api/index.html

1、注册微信支付商家

2、PC站申请【Native支付】、手机站申请【H5支付】;自适应网站2个都申请

3、下载微信支付demo

Native支付:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=11_1

H5支付:没找到官方demo,可以用Native的demo改

4、Native的demo目录下example目录就是示例,native.php 扫码支付页,native_notify.php 异步回调页。

配置页 WxPay.Config.php

//APPID:绑定支付的APPID(必须配置,开户邮件中可查看)
public function GetAppId()
{
	return '';
}

//MCHID:商户号(必须配置,开户邮件中可查看)
public function GetMerchantId()
{
	return '';
}

//KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置), 请妥善保管, 避免密钥泄露
//设置地址:https://pay.weixin.qq.com/index.php/account/api_cert
public function GetKey()
{
    return '';
}

模式二显示二维码 native.php页

/**
 * 流程:
 * 1、调用统一下单,取得code_url,生成二维码
 * 2、用户扫描二维码,进行支付
 * 3、支付完成之后,微信服务器会通知支付成功
 * 4、在支付成功通知中需要查单确认是否真正支付成功(见:notify.php)
 */
$input = new WxPayUnifiedOrder();
//商品描述
$input->SetBody($title);
//订单号
$input->SetOut_trade_no($out_trade_no);
//金额
$input->SetTotal_fee($total_fee);
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis",time()+600));
//支付回调设置
$input->SetNotify_url("http://xxxxxx.com/weixin_pc/example/native_notify.php");
//支付类型 扫码支付
$input->SetTrade_type("NATIVE");
//商品ID
$input->SetProduct_id($product_id);

$notify = new NativePay();
$result = $notify->GetPayUrl($input);

//var_dump($result);

$url2 = $result["code_url"];

定时获取是否付款

$(function(){
	var miao=600;
	var rs;
    timess();
	
	function timess()
	{
		$.ajax({
			url: '获取是否付款数据',
			type: 'get',
			dataType: 'json',
			async:false,
			success: function (data) {
				rs=data;
				console.log(rs);
			}
		});
		
		if(rs.status==1)
		{
			alert("付款成功,即将跳转!")
			window.location.href='跳转结果页';
		}
		else
		{
			miao--;
			$(".weixinbox .tit .ttt span").html(miao);
			if(miao==0)
			{
				clearInterval(timer);
				alert("二维码过期,即将刷新二维码!")
				window.location.reload();
			}
			setTimeout(function() {
    			timess();
    		},1000)
		}
	}
});

异步通知页 native_notify.php

public function NotifyProcess($objData, $config, &$msg)
{
	$data = $objData->GetValues();
	//echo "处理回调";
	Log::DEBUG("call back:" . json_encode($data));
	//TODO 1、进行参数校验
    //DEMO中的这行注释,不判断产品ID,获取不到
	//if(!array_key_exists("openid", $data) || !array_key_exists("product_id", $data))
	if(!array_key_exists("openid", $data))
	{
		$msg = "回调数据异常";
		Log::DEBUG($msg  . json_encode($data));
		return false;
	}

    //...略

	//==========================业务=========================
	$number=$data["out_trade_no"];//订单号
	$transaction_id=$data["transaction_id"];//交易号
	
	$GLOBALS["number"]=$number;
	$GLOBALS["platform_number"]=$transaction_id;
	//=======================================================
    
    return false
}

$config = new WxPayConfig();
Log::DEBUG("begin notify!");
$notify = new NativeNotifyCallBack();
$notify->Handle($config, true);

if(isset($GLOBALS["number"]) && isset($GLOBALS["platform_number"]) && $GLOBALS["number"] && $GLOBALS["platform_number"])
{
   //业务代码
}

 

注:if(!array_key_exists("openid", $data) || !array_key_exists("product_id", $data)) 这行修改为if(!array_key_exists("openid", $data)) 获取不到product_id这个值。

5、H5支付,将Native的demo复制一份

先在微信支付产品中心 H5支付中配置域名 就是下面的 XXXXXX.COM

原来的native.php页删除,新建native.php页,代码如下

$title="标题标题标题";
$money=100; //充值金额 微信支付单位为分
$product_id=1;//产品id
             
$userip = get_client_ip();     //获得用户设备 IP
$appid  = "";                  //应用 APPID
$mch_id = "";                  //微信支付商户号
$key    = "";                 //微信商户 API 密钥
$out_trade_no="123456789000"; //平台内部订单号
$nonce_str = createNoncestr();//随机字符串
$body = $title;//内容
$total_fee = $money; //金额
$spbill_create_ip = $userip; //IP
$notify_url = "http://xxxxxx.com/weixin_h5/pay/native_notify.php"; //回调地址
$trade_type = 'MWEB';//交易类型 具体看 API 里面有详细介绍
$scene_info ='{"h5_info":{"type":"Wap","wap_url":"http://xxxxxx.com","wap_name":"支付"}}';//场景信息 必要参数
$signA ="appid=$appid&attach=$out_trade_no&body=$body&mch_id=$mch_id&nonce_str=$nonce_str&notify_url=$notify_url&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type";
$strSignTmp = $signA."&key=$key"; //拼接字符串  注意顺序微信有个测试网址 顺序按照他的来 直接点下面的校正测试 包括下面 XML  是否正确
$sign = strtoupper(MD5($strSignTmp)); // MD5 后转换成大写
$post_data = "<xml>
                    <appid>$appid</appid>
                    <mch_id>$mch_id</mch_id>
                    <body>$body</body>
                    <out_trade_no>$out_trade_no</out_trade_no>
                    <total_fee>$total_fee</total_fee>
                    <spbill_create_ip>$spbill_create_ip</spbill_create_ip>
                    <notify_url>$notify_url</notify_url>
                    <trade_type>$trade_type</trade_type>
                    <scene_info>$scene_info</scene_info>
                    <attach>$out_trade_no</attach>
                    <nonce_str>$nonce_str</nonce_str>
                    <sign>$sign</sign>
            </xml>";//拼接成 XML 格式
$url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信传参地址
$dataxml = postXmlCurl($post_data,$url); //后台 POST 微信传参地址  同时取得微信返回的参数 
$objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //将微信返回的 XML 转换成数组
function createNoncestr( $length = 32 ){
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    $str ="";
    for ( $i = 0; $i < $length; $i++ )  {
        $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
    }
    return $str;
}
function postXmlCurl($xml,$url,$second = 30){
    $ch = curl_init();
    //设置超时
    curl_setopt($ch, CURLOPT_TIMEOUT, $second);
    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);
    //post 提交方式
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    //运行 curl
    $data = curl_exec($ch);
    //返回结果
    if($data){
        curl_close($ch);
        return $data;
    }else{
        $error = curl_errno($ch);
        curl_close($ch);
        echo "curl 出错,错误码:$error"."<br>";
    }
}
function get_client_ip($type = 0) {
    $type       =  $type ? 1 : 0;
    $ip         =   'unknown';
    if ($ip !== 'unknown') return $ip[$type];
    if($_SERVER['HTTP_X_REAL_IP']){//nginx 代理模式下,获取客户端真实 IP
        $ip=$_SERVER['HTTP_X_REAL_IP'];
    }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {//客户端的 ip
        $ip     =   $_SERVER['HTTP_CLIENT_IP'];
    }elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {//浏览当前页面的用户计算机的网关
        $arr    =   explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $pos    =   array_search('unknown',$arr);
        if(false !== $pos) unset($arr[$pos]);
        $ip     =   trim($arr[0]);
    }elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip     =   $_SERVER['REMOTE_ADDR'];//浏览当前页面的用户计算机的 ip 地址
    }else{
        $ip=$_SERVER['REMOTE_ADDR'];
    }
    // IP 地址合法验证
    $long = sprintf("%u",ip2long($ip));
    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}

 <a class="pay" href="<?php echo $objectxml['mweb_url'] ?>"><button class="pay">确认支付</button></a> 

异步通知页 native_notify.php 修改NotifyProcess方法

public function NotifyProcess($objData, $config, &$msg)
{
	$data = $objData->GetValues();
	//echo "处理回调";
	Log::DEBUG("call back:" . json_encode($data));
	//TODO 1、进行参数校验
	//if(!array_key_exists("openid", $data) || !array_key_exists("product_id", $data))
	if(!array_key_exists("openid", $data))
	{
		$msg = "回调数据异常";
		Log::DEBUG($msg  . json_encode($data));
		return false;
	}

	//TODO 2、进行签名验证
	try {
		$checkResult = $objData->CheckSign($config);
		if($checkResult == false){
			//签名错误
			Log::ERROR("签名错误...");
			return false;
		}
	} catch(Exception $e) {
		Log::ERROR(json_encode($e));
	}

	//==========================业务=========================
	$number=$data["out_trade_no"];//订单号
	$transaction_id=$data["transaction_id"];//交易号
	
	$GLOBALS["number"]=$number;
	$GLOBALS["platform_number"]=$transaction_id;
	//=======================================================
	return true;
}

$config = new WxPayConfig();
Log::DEBUG("begin notify!");
$notify = new NativeNotifyCallBack();
$notify->Handle($config, true);

if(isset($GLOBALS["number"]) && isset($GLOBALS["platform_number"]) && $GLOBALS["number"] && $GLOBALS["platform_number"])
{
   //业务代码
}

异步通知页 native_notify.php 如果不用官方的demo 代码如下:

$xml = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");

if (empty($xml)) 
{
    return false;
}

//将 xml 格式转换成数组
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;
}

$attr = xmlToArray($xml);

$total_fee = $attr['total_fee'];
$open_id = $attr['openid'];
$out_trade_no = $attr['out_trade_no'];
$time = $attr['time_end'];

//业务代码

//在异步回调取值的时候,异步回调一直在调用(如果微信收到商户的应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。 (通知频率为 15/15/30/180/1800/1800/1800/1800/3600,单位:秒))

exit('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');

 

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值