微信APP支付的那点事

本文作者原版,编写人程序小白:Mason.Hu

我们这里就不说怎么申请微信APP支付

有不会的童鞋可以参照这么前辈写的文档,不过好像不用我们申请,APP端干的事情。 —— [ 微信APP支付接入 ]

本编辑器支持 Markdown Extra ,  扩展了很多好用的功能。具体请参考[Github][2].

好了那我们就开始我们的APP开发斩棘之旅吧!

文档还是要看的,先大致了解一下流程嘛! 微信开发文档

流程图(简单了解下就行了哈)
这里写图片描述

由于微信官方没有提供APP的demo,那我们就引用公众号的demo吧! 微信公众号demo
这里写图片描述

我们先填写需要的配置信息,此处略过,参数如何填写官方写的很详细。 WxPay.Config.php

然后我们就开始写微信APP支付接口吧

<?php
    //引入配置文件
	require_once(DIR_WS_MODULES . 'app/weixin/lib/WxPay.Api.php');
	require_once(DIR_WS_MODULES . 'app/weixin/lib/WxPay.Data.php');
	require_once(DIR_WS_MODULES . 'app/weixin/lib/WxPay.Config.php');
	switch($_GET['request_aciton']){
		case 'check_weChatPay':
			/*拼接签名字符串
			*return $buff将拼接好的字符串返回*/
			function ToUrlParams($data)
	        {
	            $buff = "";
	            foreach ($data as $k => $v)
	            {
	                if($k != "sign" && $v != "" && !is_array($v)){
	                    $buff .= $k . "=" . $v . "&";
	                }
	            }
	
	            $buff = trim($buff, "&");
	            return $buff;
	        }
	        /*这是为了测试方便讲价格设置为0.01*/
	        $price = 0.01;
	        $orders_id = $_POST['orders_id'] ? $_POST['orders_id'] : '';
	        /*此处的zen_get_orders_number是自己写的获取订单号的函数*/
	        $out_trade_no = zen_get_orders_number($orders_id);
	        /*为什么乘以100呢 因为1代表1分钱*/
	        $total_fee = (string)(100 * $price);
	        /*body就是商品的描述信息 此处我定义了一个常量 也可以用字符串直接写*/
	        $body = APP_WE_CHAT_PAY;
	        /*此处设置的是一个回调地址*/
	        $notify_url = 'http://回调地址的路径';
	        /*调用统一下单接口*/
	        $input = new WxPayUnifiedOrder();
	        $appid = '此处填写appid';
	        /*设置APPID*/
	        $input->SetAppid($appid);
	        /*设置描述信息*/
	        $input->SetBody($body);
	        /*设置交易订单号*/
	        $input->SetOut_trade_no($out_trade_on);
	        /*设置金额*/
	        $input->SetTotal_fee($total_fee);
	        $input->SetTime_start(date("YmdHis"));
	        $input->SetTime_expire(date("YmdHis", time() + 600));
	        /*设置回调地址*/
	        $input->SetNotify_url($notify_url);
	        /*设置交易类型*/
	        $input->SetTrade_type("APP");
	        /*设置产品金额*/
	        $input->SetProduct_id($total_fee);
			/*调用微信统一下单的方法*/
			$unifiedOrderResult = WxPayApi::unifiedOrder($input);
			$value = array(
            "appid" => $unifiedOrderResult['appid'],
            "partnerid" =>$unifiedOrderResult['mch_id'],
            "prepayid" => $unifiedOrderResult['prepay_id'],
            "noncestr" => $unifiedOrderResult['nonce_str'],
            "timestamp" => time(),
            'package' => 'Sign=WXPay'
	        );
		    /*参数名ASCII码从小到大排序(字典序)*/
		    ksort($value);
			/*调用上面写的方法*/
	        $str = ToUrlParams($value);
	        /*拼接字符串*/
	        $str = $str . "&key=".WxPayConfig::KEY;
	        /*md5加密*/
	        $str = md5($str);
			/*转化成大写*/
	        $str = strtoupper($str);
	
	        //将下单获取的信息重新签名  demo没有这一步,为出错的原因
	        $value['sign'] = $str;
	        $value["orderid"] = $out_trade_no;
	        $value["price"] = $total_fee;
	        $value["url"] = $notify_url;
	        /*successReturn是我封装的一个函数就是返回json_encode处理的数据*/
	        successReturn($value);
	        break;
	     default:
			failReturn(400); /*失败返回的json*/
			break;
	}

我们需要介绍几个参数,防止入坑!

微信规定得参数要写成这样
appIdappid
partnerIdpartnerid
prepayIdprepayid
nonceStrnoncestr
timeStamptimestamp(切记是时间戳【10位】)
packagepackage

按照上面的代码就可以调起微信了,至于怎麽调起就是APP端的操作了。或许有些人会比较好奇,为什么只签名了一次,其实在调用微信的WxPayApi::unifiedOrder已经签名了并且将数据转化成xml数组发送给服务器了。
这里写图片描述

至于他的$inputObj->SetSign();怎么来的呢?我们可以参考WxPay.Data.php这个文件,他在这个文件定义这个SetSign方法,然后她又调用了这个类文件里面的MakeSign()方法,从而实现了第一次签名!

SetSign()方法
这里写图片描述

MakeSign()方法
这里写图片描述

其实代码还可以再精简一点,后面我们也可以用SetSign()方法进行二次签名。

下面我们就开始写回调了:(这里我直接引用的它的example文件中的notify.php文件)

<?php
	ini_set('date.timezone','Asia/Shanghai'); /*设置时区*/
	/*导入所需要的配置文件*/
	require_once "../lib/WxPay.Api.php";
	require_once '../lib/WxPay.Notify.php';
	require_once 'log.php';
	/*我这个引用的是服务器的配置信息,主要是做数据库链接*/
	require_once("../../../../configure.php");
	
	/*初始化日志,这个就是我们引用的log.php,实例化其中的这个类,目的就是为了监测微信给我们返回的数据。*/
	$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
	$log = Log::Init($logHandler, 15);
	
	/*初始化数据库*/
    function connect($zf_host, $zf_user, $zf_password, $zf_database) {
	    $link = @mysql_connect($zf_host, $zf_user, $zf_password, true);
	    @mysql_select_db($zf_database, $link);
	    @mysql_query("SET NAMES '" . DB_CHARSET . "'", $link);
	    return $link;
	}
	/*连接数据库*/
	$link = connect(DB_SERVER,DB_SERVER_USERNAME,DB_SERVER_PASSWORD,DB_DATABASE);
	$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];/*我们用来接收服务器返回给我们的数据*/
	$order = $_GET; /*获取订单信息*/
	/*simplexml_load_strin()读取返回的xml数据,然后返回一个对象我们通过对象提取里面的参数*/
	$postObj = simplexml_load_string($postStr, 'SimpleXMLElement',LIBXML_NOCDATA);
	$out_trade_no = $postObj->out_trade_no;/*获取微信给我们返回的订单号*/
	$result_code = $postObj->result_code;/*获取状态码*/
	
	/*下面我们根据返回的状态就开始处理业务逻辑*/
	if($result_code){
    //如果订单号不为空
    if($out_trade_no){
		/*根据订单号查询订单是否存在*/
        $orders_number = @mysql_query("select orders_id from orders where orders_number = '$out_trade_no'");
        /*如果订单号存在,我们就更改订单状态*/
        if($orders_number){
            $row = @mysql_fetch_array($orders_number);
            $orders_id =  $row['orders_id'];
            @mysql_query("update orders set orders_status = 2,payment_method='微信支付',payment_module_code='weChatPay' where orders_id = '$orders_id'");
            @mysql_query("insert into orders_status_history set orders_id = '$orders_id',orders_status_id=2,date_added='".date('Y-m-d H:i:s')."'");
            successReturn(200);/*200 代表成功*/
        }
    }
}else{
    failReturn(400); /*失败返回的状态*/
}

	class PayNotifyCallBack extends WxPayNotify
	{
		//查询订单
		public function Queryorder($transaction_id)
		{
			$input = new WxPayOrderQuery();
			$input->SetTransaction_id($transaction_id);
			$result = WxPayApi::orderQuery($input);
			Log::DEBUG("query:" . json_encode($result));
			if(array_key_exists("return_code", $result)
				&& array_key_exists("result_code", $result)
				&& $result["return_code"] == "SUCCESS"
				&& $result["result_code"] == "SUCCESS")
			{
				return true;
			}
			return false;
		}
	
		//重写回调处理函数
		public function NotifyProcess($data, &$msg)
		{
			Log::DEBUG("call back:" . json_encode($data));
			$notfiyOutput = array();
	
			if(!array_key_exists("transaction_id", $data)){
				$msg = "输入参数不正确";
				return false;
			}
			//查询订单,判断订单真实性
			if(!$this->Queryorder($data["transaction_id"])){
				$msg = "订单查询失败";
				return false;
			}
			return true;
		}
	}
	/*获取的当前时间*/
	$date = date("Y-m-d H:i:s");
	/*调试错误用的上面有写到*/
	Log::DEBUG('支付回调测试:' . $date . '订单编号:' .$orders_number . '订单id' . $orders_id);
	$notify = new PayNotifyCallBack();
	$notify->Handle(false);

虽然微信支付很坑,但是还是不可缺少,微信、支付宝用户毕竟很大的市场,该吐槽吐槽,该用的时候还是要用的!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值