最近为一个地方土特产企业做了一个微信公众号应用,由于属于中小企业,所以暂时没有做APP,在这里笔者也需要给各位中小企业一些忠告,虽然国家倡导企业进行变革,鼓励企业进行互联网+思维发展,把传统企业由限下搬到线上,但不要盲目于APP的开发,而是根据自身情况,借助于微信公众号平台坐一些OTO项目,把web站和wap站及微信公众号结合起来,这样对于中小企业来说更实惠,更实用,言归正传现在说一下微信应用开发中如何生成现场支付活二维码。
首先:需要您的微信公众号必须已认证,而且开通了微信支付功能,否则对于一切微信支付都是空谈,如果你在认证和微信支付申请方面遇到问题也可问我。
其次:下载微信支付开发包,因为是现成支付,所以选择生成扫描支付模式一,没有时间期限限制。
最后:根据微信支付开发包和结合客户要求进行整合开发。
微信支付开发包中有phpqrcode应用插件程序,此程序插件是php语言下生成二维码工具,生成二维码就靠它,所以这里需要教大家一些phpqrcode的基本用法,其实非常简单,就是需要记住几个参数,调用生成类QRcode的静态方法png()就可以了,下面给大家说一下png()方法中的参数。
程序中找到这个png()方法(位置phpqrode文件夹phpqrode.php文件中的3091行)
public static function png(
text,
outfile = false,
level=QRECLEVELL,
size = 3,
margin=4,
saveandprint=false)
从方法中可以看到一共有6个参数,而我们需要掌握前6个参数
第一个参数: $text
是你要生成二维码展示的内容,内容是字符串,可以是一句话,一张图片,也可以是链接地址,当手机扫描二维码会显示这个内容。
第二个参数:$outfile
输出二维码的图片文件,这里主要是你生成的图片要放的位置及名字。
eg:upload/qrcode.png.
第三个参数:$level
二维码容错级别容错百分比;一共四个值供取默认为L,这个参数可传递的值分别是L(QR_ECLEVEL_L,7%),M(QR_ECLEVEL_M,15%),Q(QR_ECLEVEL_Q,25%),H(QR_ECLEVEL_H,30%)
第四个参数:$size
生成图片大小,数值类型值,默认是4. 单位大小是厘米
第五个参数:$margin
控制生成二维码的空白区域大小,这个需要根据你生成二维码图片大家进行合理配置,属于数值类型值 我是默认为2
phpqrcode介绍完之后开始我们的生成现场支付活二维码程序开发,这里先对这个小程序进行分析:
我们可以把生成的每一个二维码和商品表关联,建立一个商品现成支付二维码,只不过这个表可以对商品进行折扣处理,这样线下进行活动促销,可以根据更改参数,对每个商品进行价格更改。也可以绑定多个商品组成一个团购包裹,捆绑销售。
处于对客户程序安全考虑,这里我就不公布客户需求的表,而是简单的建立一个基础表 有产品号、价格、生成图片大小、认错度几个字段
如下:
CREATE TABLE goods_qrcode
(
id
int(11) unsigned NOT NULL auto_increment,
goods_id
varchar(50) default NULL COMMENT ‘以G开头的ID号’,
goods_money
decimal(10,2) default NULL,
goods_status
tinyint(1) default ‘1’ COMMENT ‘1表示未失效,0表示失效’,
img_size
int(4) default NULL,
error_level
char(2) default ‘L’ COMMENT ‘容错级别(共分四个等级,L-默认:可以识别已损失的7%的数据;M-可以识别已损失15%的数据;Q-可以识别已损失25%的数据;H-可以识别已损失30%的数据) ‘,
PRIMARY KEY (id
)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
而对于信息添加,修改,我这里就不做介绍,这部分不是重点,需要生成多大图片就可以更加参数添加,我这里说生成支付和二维码内容。
简单的通过GET提交,生成现场支付二维码,信息列表页点击生成二维码链接传递生成参数,你可以根据自己的需要控制参数,
如:
create_qrcode.php?sn={row["goods_id"]}&img_size={row["img_size"]}&error_level={$row[“error_level”]
create_qrcode.php中代码:
if($_GET["sn"]==""||$_GET["img_size"]==""||$_GET["error_level"]=="")
{
echo "<script language ='javascript'>alert('系统提交错误!');location.replace(\"zz_list.php\");</script>";
die();
}
$goods_code = $_GET["sn"];
require_once "sdk/lib/WxPay.Api.php";
require_once "sdk/unit/WxPay.NativePay.php";
require_once 'sdk/unit/log.php';
require_once 'sdk/unit/phpqrcode/phpqrcode.php';
$notify = new NativePay();
$goods_code_url = $notify->GetPrePayUrl($goods_code);
$errorCorrectionLevel = $_GET['error_level'];//容错级别;
$matrixPointSize = $_GET["img_size"];//生成图片大小
//生成二维码图片
$img_url = "'sdk/unit/".$goods_code."png";
QRcode::png($goods_code_url, $goods_qrcode, $errorCorrectionLevel, $matrixPointSize, 2);
echo "<img src=\"$img_url\">";
其实为了美观,你也可以把容错级别调低,然后在二维码中间copy上企业的logo,利用画图函数imagecopyresampled().这里不做介绍,
//二维码和logo都为正方形的处理方案
$logo = 'logo.png';//准备好的logo图片
$goods_rcode = 'qrcode.png';//已经生成的原始二维码图
$goods_rcode = imagecreatefromstring(file_get_contents($QR));
$logo = imagecreatefromstring(file_get_contents($logo));
$GR_width = imagesx($goods_rcode);//二维码图片宽度
$GR_height = imagesy($goods_rcode);//二维码图片高度
$logo_width = imagesx($logo);//logo图片宽度
$logo_height = imagesy($logo);//logo图片高度
$from_width = ($GR_width-$logo_width)/2;
//重新组合图片
imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $logo_width,$logo_height, $logo_width, $logo_height);
我这里的logo是固定的没有随着二维码的大小而等比例变化,其实是可以更人性化一下,那就需要设定一个比例即logo图片和二维码图片如:1:5
则计算logo位置的代码如下:
$logo = 'logo.png';//准备好的logo图片
$goods_rcode = 'qrcode.png';//已经生成的原始二维码图
$goods_rcode = imagecreatefromstring(file_get_contents($QR));
$logo =imagecreatefromstring(file_get_contents($logo));
$GR_width = imagesx($goods_rcode);//二维码图片宽度
$GR_height = imagesy($goods_rcode);//二维码图片高度
$logo_width = imagesx($logo);//logo图片宽度
$logo_height = imagesy($logo);//logo图片高度
$n_logo_weight = $GR_width/5;
$from_width = ($GR_width-$n_logo_weight)/2;
//重新组合图片
imagecopyresampled($QR, $logo, $from_width, $from_width, 0, 0, $n_logo_weight,$n_logo_weight, $logo_width, $logo_height);
微信现场支付二维码已生成完毕,接下来说说微信支付开发部分的代码,因为是供现场支付用所有需要选择NATIVE付款方式的扫描支付模式一。
注意:选择微信支付中所有选择扫描支付的开发前,商户必须在公众平台后台设置支付回调URL,登陆你的微信公众号点击左侧导航的“微信支付”,然后点击“开发配置”,配置如下图:
下面我们讲解回调URL文件中的代码,如果回调url文件是codenative_notify.php,我们需要在codenative_notify.php文件中把之前我们利用create_qrcode.php生成的现场支付活二维码的值goods_id取到然后通过goods_id查找goods_qrcode表中对应的产品价钱,确保我们这里的价格可以随时变动,如果突然有一天原材料涨价,产品价格也涨价时候,我们只需要更改后台价格即可,不需要重新更好二维码,是不是很方便而且灵活,所有我叫他微信支付活二维码。
具体codenative_notify.php代码如下:
ini_set('date.timezone','Asia/Shanghai');
error_reporting(E_ERROR);
require_once 'kphp/Data.php';
require_once "sdk/lib/WxPay.Api.php";
require_once 'sdk/lib/WxPay.Notify.php';
require_once 'log.php';
//初始化日志
$logHandler= new CLogFileHandler("../logs/".date('Y-m-d').'.log');
$log = Log::Init($logHandler, 15);
class NativeNotifyCallBack extends WxPayNotify
{
public function unifiedorder($openId, $product_id)
{
//统一下单
$input = new WxPayUnifiedOrder();
$data = new Data();
$goods_id = $product_id;
$sql="select goods_money from goods_qrcode where goods_id='$goods_id'";
$goods_money = $data->sqlValue($sql);
$subject_title = "这里写客户支付时候微信支付订单的介绍";
$new_code = $goods_id."AG".time();
//插入有微信支付订单表weixinpay_info中
$start_time = date("Y-m-d H:i:s");
$ordersql ="insert into weixinpay_info (openid,pay_money,order_code,start_time) values('$openId','$goods_money','$goods_id','$start_time')";
$data->sqlExecute($wsql);
$input->SetBody("$subject_title");
$input->SetAttach("$subject_title");
$input->SetOut_trade_no($new_code);
//注意:微信支付默认人民币单位是分,这里需要把元转化为分,要求必须是整数
$total_fee = $order_money*100;
$input->SetTotal_fee($total_fee);
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time() + 600));
$input->SetGoods_tag("$subject_title");
$input->SetNotify_url("http://你的域名/sdk/unit/codenotify.php");
$input->SetTrade_type("NATIVE");
$input->SetOpenid($openId);
$input->SetProduct_id($product_id);
$result = WxPayApi::unifiedOrder($input);
Log::DEBUG("unifiedorder:" . json_encode($result));
return $result;
}
public function NotifyProcess($data, &$msg)
{
//echo "处理回调";
Log::DEBUG("call back:" . json_encode($data));
if(!array_key_exists("openid", $data) ||
!array_key_exists("product_id", $data))
{
$msg = "回调数据异常";
return false;
}
$openid = $data["openid"];
$product_id = $data["product_id"];
//统一下单
$result = $this->unifiedorder($openid, $product_id);
if(!array_key_exists("appid", $result) ||
!array_key_exists("mch_id", $result) ||
!array_key_exists("prepay_id", $result))
{
$msg = "商品ID错误下单失败!";
return false;
}
$this->SetData("appid", $result["appid"]);
$this->SetData("mch_id", $result["mch_id"]);
$this->SetData("nonce_str", WxPayApi::getNonceStr());
$this->SetData("prepay_id", $result["prepay_id"]);
$this->SetData("result_code", "SUCCESS");
$this->SetData("err_code_des", "支付提交失败!");
return true;
}
}
Log::DEBUG("begin notify!");
$notify = new NativeNotifyCallBack();
$notify->Handle(true);
在上面代码中你会发现$input->SetNotify_url(“http://你的域名/sdk/unit/codenotify.php”);这个是微信平台和你的服务器进行异步通信,代码程序是判断订单是否支持成功,成功则返回成功的信息,完成支付,失败会提示客户支付失败,需要重新支付,这里codenotify.php的代码如下:
ini_set('date.timezone','Asia/Shanghai');
error_reporting(E_ERROR);
require_once 'kphp/Data.php';
require_once "sdk/lib/WxPay.Api.php";
require_once 'sdk/lib/WxPay.Notify.php';
require_once 'log.php';
//初始化日志
$logHandler = new CLogFileHandler("../logs/".date('Y-m-d').'.log');
$log = Log::Init($logHandler, 15);
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")
{
//处理返回值,并改变自己数据库订单状态。
//总金额total_fee time_end
//交易状态trade_state为SUCCESS表示支付成功成功
//是否关注公众账号 is_subscribe
$order_code = $result["out_trade_no"];
$total_fee = $result["total_fee"];
$data = new Data();
$end_time = date("Y-m-d H:i:s");
$order_code_arr = explode("AG",$order_code);
$order = $order_code_arr[0];
$osql = "select pay_status as order_status from weixinpay_info order_code='$order'";
$orow = $data->sqlRow($osql);
if($orow["order_status"]==1)
return false;
$payupsql = "update weixinpay_info set pay_status=1,end_time='$end_time' where order_code='$order'";
$data->sqlExecute($payupsql);
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;
}
}
Log::DEBUG("begin notify");
$notify = new PayNotifyCallBack();
$notify->Handle(false);
注意:require_once ‘kphp/Data.php’;调用的是kphp框架的数据库类。
至此kphp开源框架微信应用开发的生成现场支付活二维码的讲解就结束了,我的代码希望对使用php进行微信支付开发的朋友有帮助。
原文来自kphp开源框架:http://www.kphp.org/?faq-show-51.html