这篇文章主要介绍扫码支付场景二。

目前有两种模式,模式一比模式二稍微复杂点,至于模式一与模式二的具体内容,流程,微信开发文档都有详细介绍,这里就不多说废话,接下来赶紧上教程!

[title]下载SDK类文件[/title]

Wxpay Library

并SDK文件/lib下的几个文件放置到/ThinkPHP/Library/Vendor/

[title]修改WxPay.pub.config.php中的配置选项[/title]

	//=======【基本信息设置】=====================================
//微信公众号身份的唯一标识。审核通过后,在微信发送的邮件中查看
const APPID = '公众号表示ID';
//受理商ID,身份标识
const MCHID = '商户ID';
//商户支付密钥Key。审核通过后,在微信发送的邮件中查看
const KEY = 'KEY密匙';
//JSAPI接口中获取openid,审核后在公众平台开启开发模式后可查看
const APPSECRET = 'SECRET密匙'; //=======【JSAPI路径设置】===================================
//获取access_token过程中的跳转uri,通过跳转将code传入jsapi支付页面
const JS_API_CALL_URL = 'http://www.laoji.org'; //=======【证书路径设置】=====================================
//证书路径,注意应该填写绝对路径
const SSLCERT_PATH = "__ROOT__\paypem\\apiclient_cert.pem";
const SSLKEY_PATH = "__ROOT__\paypem\\apiclient_key.pem"; //=======【异步通知url设置】===================================
//异步通知url,商户根据实际开发过程设定
const NOTIFY_URL = 'http://www.laoji.org/wxpay/notify'; //=======【curl超时设置】===================================
//本例程通过curl使用HTTP POST方法,此处可修改其超时时间,默认为30秒
const CURL_TIMEOUT = 30;

[title]新建微信的Controller方法,目录位置为:\Application\Home\Controller\WxpayController.class.php [/title]

<?php
/**
* WxpayController.class.php
* 微信支付控制器
* 网站地址: https://www.jiloc.com/43212.html
* Author: 老季 ( admin@laoji.org )
* Date: 2017年4月18日
*/
namespace Home\Controller; class WxpayController extends HomeController {
//初始化
public function _initialize()
{
//引入类文件
vendor('Wxpay.WxPayPubHelper');
} private function makeOrder($ary){
$data = array();
$data['userid'] = session('user_auth')['uid'];
if ( !$data['userid'] ){
$this->error('用户ID错误! -> '.$data['uid'],'/my/publishlist');
}
// 检查船舶信息
$data['shipinfoid'] = $ary['id'];
$ShipInfo = M('ShipInfo')->where(array('id'=>$ary['id']))->find();
if( !$ShipInfo ){
$this->error('信息ID错误! -> '.$ary['id'],'/my/publishlist');
}
// 检查支付价格
$data['ordercatid'] = $ary['catid'];
$OrderCat = M('OrderCat')->where(array('id'=>$ary['catid']))->find();
if( !$OrderCat ){
$this->error('产品价格错误! -> '.$ary['catid'],'/my/publishlist');
} $data['ordid'] = "LJ".$ary['TYPE'].date('YmdHis',time()).rand(11,99);
$data['ordtime'] = time(); $data['ordtitle'] = $ShipInfo['title'];
$data['ordbuydays'] = $OrderCat['days'];
$data['ordfee'] = $data['ordprice'] = $OrderCat['price'];
$data['status'] = 0; M('OrderList')->add($data); return $data['ordid']; } //生成二维码
public function qrcode()
{
// 生成订单
$_POST['TYPE'] = 'W';
$out_trade_no = $this->makeOrder($_POST);
$ordtotal_fee = str_replace(".","",$_POST['ordtotal_fee']*100);
//使用统一支付接口
$unifiedOrder = new \UnifiedOrder_pub();
//设置统一支付接口参数
//设置必填参数
$unifiedOrder->setParameter("body",$_POST['ordsubject'] );//商品描述
//自定义订单号,此处仅作举例
$timeStamp = time();
$unifiedOrder->setParameter("out_trade_no",$out_trade_no);//商户订单号
$unifiedOrder->setParameter("total_fee",$ordtotal_fee);//总金额
$unifiedOrder->setParameter("notify_url", \WxPayConf_pub::NOTIFY_URL);//通知地址
$unifiedOrder->setParameter("trade_type","NATIVE");//交易类型
//非必填参数,商户可根据实际情况选填
//$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号
//$unifiedOrder->setParameter("device_info","XXXX");//设备号
//$unifiedOrder->setParameter("attach","XXXX");//附加数据
//$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间
//$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间
// $unifiedOrder->setParameter("goods_tag","");//商品标记
// $unifiedOrder->setParameter("openid","19405");//用户标识
//$unifiedOrder->setParameter("product_id","XXXX");//商品ID
//获取统一支付接口结果
$unifiedOrderResult = $unifiedOrder->getResult();
// var_dump($unifiedOrder);
//商户根据实际情况设置相应的处理流程
if ($unifiedOrderResult["return_code"] == "FAIL")
{
//商户自行增加处理流程
echo "通信出错:".$unifiedOrderResult['return_msg']."<br>";
}
elseif($unifiedOrderResult["result_code"] == "FAIL")
{
//商户自行增加处理流程
echo "错误代码:".$unifiedOrderResult['err_code']."<br>";
echo "错误代码描述:".$unifiedOrderResult['err_code_des']."<br>";
}
elseif($unifiedOrderResult["code_url"] != NULL)
{
//从统一支付接口获取到code_url
$code_url = $unifiedOrderResult["code_url"];
//商户自行增加处理流程
//......
}
$this->assign('title',$_POST['ordsubject']);
$this->assign('total_fee',$_POST['ordtotal_fee']);
$this->assign('out_trade_no',$out_trade_no);
$this->assign('code_url',urlencode($code_url));
$this->assign('unifiedOrderResult',$unifiedOrderResult); $this->display();
} public function notify()
{
//使用通用通知接口
$notify = new \Notify_pub();
//存储微信的回调
$xml = $GLOBALS['HTTP_RAW_POST_DATA'];
$notify->saveData($xml);
// var_dump($xml);
//验证签名,并回应微信。
//对后台通知交互时,如果微信收到商户的应答不是成功或超时,微信认为通知失败,
//微信会通过一定的策略(如30分钟共8次)定期重新发起通知,
//尽可能提高通知的成功率,但微信不保证通知最终能成功。
if($notify->checkSign() == FALSE){
$notify->setReturnParameter("return_code","FAIL");//返回状态码
$notify->setReturnParameter("return_msg","签名失败");//返回信息
}else{
$notify->setReturnParameter("return_code","SUCCESS");//设置返回码
}
$returnXml = $notify->returnXml();
echo $returnXml; //==商户根据实际情况设置相应的处理流程,此处仅作举例======= //以log文件形式记录回调信息
// $log_ = new Log_();
// $log_name= __ROOT__."/Public/notify_url.log";//log文件路径 // $this->log_result($log_name,"【接收到的notify通知】:\n".$xml."\n"); if($notify->checkSign() == TRUE)
{
if ($notify->data["return_code"] == "FAIL") {
//此处应该更新一下订单状态,商户自行增删操作
log_result($log_name,"【通信出错】:\n".$xml."\n");
$this->error("通信出错");
}
elseif($notify->data["result_code"] == "FAIL"){
//此处应该更新一下订单状态,商户自行增删操作
// log_result($log_name,"【业务出错】:\n".$xml."\n");
$this->error("业务出错");
}
elseif( $notify->data['return_code'] == "SUCCESS" && $notify->data['result_code'] == "SUCCESS"){
$out_trade_no = $notify->data['out_trade_no'];
$parameter = array(
"out_trade_no" => $notify->data['out_trade_no'], //商户订单编号;
"transaction_id" => $notify->data['transaction_id'], //微信支付订单号
"total_fee" => $notify->data['total_fee'], //交易金额;
"result_code" => "SUCCESS", //交易状态
"time_end" => $notify->data['time_end'], //支付完成时间
"openid" => $notify->data['openid'], //用户标识
);
if (!$this->checkorderstatus($out_trade_no)){
$this->orderhandle($parameter);
}
return true;
//$this->success("支付成功!");
}
else{
//此处应该更新一下订单状态,商户自行增删操作
// log_result($log_name,"【支付成功】:\n".$xml."\n");
$this->error("UNKNOW ERROR"); } //商户自行增加处理流程,
//例如:更新订单状态
//例如:数据库操作
//例如:推送支付完成信息
}
} //查询订单
public function orderQuery()
{
if($this->checkorderstatus( I('post.out_trade_no') )){
$this->ajaxReturn("SUCCESS");
};
$this->ajaxReturn("FAILD");
} //在线交易订单支付处理函数
//函数功能:根据支付接口传回的数据判断该订单是否已经支付成功;
//返回值:如果订单已经成功支付,返回true,否则返回false;
private function checkorderstatus($ordid){
$ordstatus=M('OrderList')->where(array('ordid'=>$ordid))->getField('ordstatus');
if($ordstatus==1){
return true;
}else{
return false;
}
} //处理订单函数
//更新订单状态,写入订单支付后返回的数据
private function orderhandle($parameter){
$ordid=$parameter['out_trade_no'];
$data['payment_trade_no'] =$parameter['transaction_id'];
$data['payment_trade_status'] =$parameter['result_code'];
$data['payment_notify_time'] =$parameter['time_end'];
$data['payment_buyer_email'] =$parameter['openid'];
$data['ordstatus'] =1;
M('OrderList')->where(array('ordid'=>$ordid))->save($data); $Order = M('OrderList')->where(array('ordid'=>$ordid))->find(); $ship_due_date = M("ShipInfo")->where(array('id'=>$Order['shipinfoid']))->find();
if( $ship_due_date['due_date'] > time() ){
$due_date = $ship_due_date['due_date']+($Order['ordbuydays']*86400);
}else{
$due_date = strtotime("+".$Order['ordbuydays']." day");
} M('ShipInfo')->where(array('id'=>$Order['shipinfoid']))->save(array('due_date'=>$due_date,'status'=>1,'top'=>1));
return ;
} }

[title]

二维码生成页面的html,目录位置\Application\Home\View\default\Wxpay\qrcode.html

[/title]

<extend name="Base/common"/>

<block name="body">
<div class="center clearfix">
<div class="bread">
<a class="link" href="/">首页&gt;</a><span class="on">支付页面</span>
</div>
<div class="pay_con_zl"> <div class="p_tit_zl">支付页面</div>
<div class="p_info_zl">
<p>标题:{$title}</p>
<p>支付金额:<span style="font-size:24px; font-weight:bold; color:#F00;">¥{$total_fee}元</span>,请使用微信扫描下方二维码完成支付<span style="padding-left:20px; color:#F00;">2小时之内,请尽快扫描支付</span></p>
<P><img alt="扫码支付" src="https://www.jiloc.com/wp-content/uploads/20170409040501NP4.jpg" style="width:150px;height:150px;"/></P>
</div> </div>
</div>
<script language="JavaScript">
function Check(){
var out_trade_no = "{$out_trade_no}";
$.post("{:U('wxpay/orderQuery')}", { out_trade_no: out_trade_no},
function(data){
if(data == "SUCCESS"){
window.location = '{:U("my/paystatus",array("ordtype"=>"payed"))}';
}
});
}
window.setInterval("Check()",3000);
</script>
</block>

表单提交以后则跳转到二维码生成页面,提交地址:/wxpay/qrcode ,效果如下图:

微信客户端支付成功以后,该页面会自动跳转到支付成功页面。

[title]回调数据库表建立[/title]

[title]微信平台配置[/title]

微信公众平台上的配置了,这里我遇到过问题,如果有在这里遇到问题的同学请留言,比如出现了access_deined或者access_notallowed等问题,这都可能是因为这里配置不对。
请看配置过程截图:

支付授权目录设置为:http://laoji.org/wxpay/

[title]注意:[/title]

微信支付订单中的totla_fee的单位为分,比如1元,传值为100(分)

ThinkPHP 整合微信支付 扫码支付 模式二 图文教程的更多相关文章

  1. Java之微信支付(扫码支付模式二)案例实战

    摘要:最近的一个项目中涉及到了支付业务,其中用到了微信支付和支付宝支付,在做的过程中也遇到些问题,所以现在总结梳理一下,分享给有需要的人,也为自己以后回顾留个思路. 一:微信支付接入准备工作: 首先, ...

  2. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_6-3.微信网站扫码支付介绍

    笔记 3.微信网站扫码支付介绍     简介:讲解微信网页扫码支付         1.扫码支付文档:https://pay.weixin.qq.com/wiki/doc/api/native.php ...

  3. Win10环境前后端分离项目基于Vue.js+Django+Python3实现微信(wechat)扫码支付流程(2021年最新攻略)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_182 之前的一篇文章:mpvue1.0+python3.7+Django2.0.4实现微信小程序的支付功能,主要介绍了微信小程序内 ...

  4. (实用篇)微信支付扫码支付php版

    本文实例为大家分享了php微信扫码支付源码,供大家参考,具体内容如下 代码中包含四个文件createUrl.php.ArrayToXML.php.returnGoodsUrl.php.notifyUr ...

  5. [支付]微信NATIVE扫码支付JAVA实现

    步骤: 1.预订单 2.接受微信返回的url 3.将url转为二维码显示到页面上 4.扫码支付 5.接收微信的异步通知,在这步修改订单的状态 6.收到异步通知的同时给微信返回指定数据,告知对方已成功处 ...

  6. .NET MVC结构框架下的微信扫码支付模式二 API接口开发测试

    直接上干货 ,我们的宗旨就是为人民服务.授人以鱼不如授人以渔.不吹毛求疵.不浮夸.不虚伪.不忽悠.一切都是为了社会共同进步,繁荣昌盛,小程序猿.大程序猿.老程序猿还是嫩程序猿,希望这个社会不要太急功近 ...

  7. ASP.NET Core Web 支付功能接入 微信-扫码支付篇

    这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入微信-扫码支付及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET Core SDK ...

  8. 【转载】ASP.NET Core Web 支付功能接入 微信-扫码支付篇

    转自:http://www.cnblogs.com/essenroc/p/8630730.html 这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入微信-扫码支付及异步 ...

  9. ASP.NET Core Web 支付功能接入 微信-扫码支付篇(转)

    原文 https://www.cnblogs.com/essenroc/p/8630730.html // 随着版本更迭,新版本可能无法完全适用,请参考仓库内的示例. 这篇文章将介绍ASP.NET C ...

随机推荐

  1. Centos7下使用yum源安装zabbix Server

    系统:Centos7 zabbix版本:4.2   一.Zabbix Server端   1.安装仓库 rpm -ivh https://repo.zabbix.com/zabbix/4.2/rhel ...

  2. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(388,5): warning MSB8028: The intermediate directory (Debug) contains files shared from another project (GU.vcxproj). T

    1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppBuild.targets(388,5): warni ...

  3. activiti 任务监听参数的配置

    public class TaskListenersImp implements TaskListener { private Expression level; private Expression ...

  4. 嵌入式GCC笔记

    GNU C Complier 查看 gcc 版本 :gcc -v 文件后缀名  .c的后缀 为C语言的文件源码 gcc  -o output gcc -o 输出文件名字 输入文件名 gcc -v -o ...

  5. python中的RE模块

    re模块(* * * * *) 就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列 ...

  6. LINUX系统软件安装和卸载的常见方法

    linux系统分很多种简单介绍几种常用的: 1.centos/redhat: 安装: rpm安装,如果有依赖,很闹心,如果使用--nodeps不检查依赖,会有问题. #rpm -ivh <XXX ...

  7. 详解Asp.Net Core 2.1+的视图缓存(响应缓存)

    响应缓存Razor 页与 ASP.NET 核心 2.0 中不支持. 此功能将支持ASP.NET 核心 2.1 版本. 在老的版本的MVC里面,有一种可以缓存视图的特性(OutputCache),可以保 ...

  8. Reduce TIME_WAIT

    see time wait number netstat -nat | awk '{print $6}' | sort | uniq -c | sort -n vi  /etc/sysctl.conf ...

  9. 工控随笔_18_西门子_WinCC的VBS脚本_07_变量作用域和传值、传址

    在vbs脚本中也存在和其他编程语言一样的概念,那就是变量的作用域,变量的作用域决 定在什么范围内可以访问. 同样的在vbs脚本中对于变量也有一个生命周期, 变量的生命周期决定了变量的存续时间 这个主要 ...

  10. 语音识别传统方法(GMM+HMM+NGRAM)概述

    春节后到现在近两个月了,没有更新博客,主要是因为工作的关注点正从传统语音(语音通信)转向智能语音(语音识别).部门起了个新项目,要用到语音识别(准备基于Kaldi来做).我们之前做的传统音频已基本成熟 ...