2014-03-14 15:55:17 u013802231 阅读数 2978
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27809 人正在学习 去看看 秦子恒

微信开发视频教程-深入浅出微信公众平台实战开发(微网站、LBS云、Api接口调用、服务号高级接口)

一、微信开发实例视频教程总目录:


微信开发实例视频教程

讲师介绍:

易伟,现广东合桓律师事务所专职律师。业余程序开发爱好者,2013年编著的《微信公众平台搭建与开发揭秘》一书出版后,市场引起极大的反响,短短几个月销量过万。

二、为什么需要微信开发实例视频教程这么套课程?

2.1、用户需要什么?

微信公众平台已经成为企业的标配,个人自媒体的发展也越来越重视微信公众平台。随着微信公众平台开发系统的报价水涨船高(微信支付20万起),一些企业希望企业内部人员能够学习开发微信公众平台,便于日后维护和节约成本。

2.2、微信开发实例视频教程学习目标(我们提供什么?)

目标一. 可以让学员快速上手掌握微信公众平台的特点。

目标二. 可以让学员迅速了解微信公众平台常用API的调用。

目标三. 可以让学员迅速掌握微信公众平台与html5的结合。

目标四. 可以让学员熟练使用微信公众平台的高级接口。

目标五. 了解ajax技术。

目标六. 了解LBS云开发。

目标七. 了解360全景图。

目标八. 通过微信开发实例视频教程的学习,可以制作出完整功能的订阅号和服务号微信平台。

2.3、微信开发实例视频教程课程特色

特点一、讲师为业余程序开发爱好者,短时间内通过自学掌握微信公众平台开发技术,可以提供快速学习的方法和介绍学习经验,特别适合零基础学员。

特点二、微信公众平台各功能都是在客户需求基础上开发,实用性强。

特点三、在微信官方示例代码上进行修改,适合基础学员学习,避免讲解过于复杂的类的封装和继承。

2.4、微信开发实例视频教程课程亮点

亮点一、紧跟最新微信公众平台接口更新内容,对各个接口讲解全面。

亮点二、云平台开发,兼顾主流的BAE和SAE云平台,降低学习成本。

亮点三、Dw6微网站开发,快速上手,所见所得,减少代码录入。

亮点四、单客服、多客服、手机留言客服系统,多种客服解决方案,解决企业需求。

亮点五、刮刮卡、会员卡、大转盘、一站到底微信流行游戏悉数介绍。

三、微信开发实例视频教程真心不错,我可以学吗?

微信开发实例视频教程针对零基础学员,如果具有一定的php和jquery基础将更快速的学习。

四、我该怎么学,如何才能学好微信开发实例视频教程这门课程,给些建议。

4.1、微信开发实例视频教程在时间上的安排建议

微信开发实例视频教程共100讲,如果您时间上充分,可以按照课程顺序逐一学习。

如果您是上班族或您已经有一定的基础了,可以挑选有兴趣的课程直接学习,每小节课程4-10分钟,特别适合碎片化学习。

4.2、微信开发实例视频教程学习要求

如果您没有基础,建议还是中规中矩的按照课程进度一点一点仔细观看学习,并一定要把看完的视频中的代码自己手敲一遍,以加深理解和记忆

如果您有基础,可不必按步就搬进行,可以拿你感兴趣的部分去学习,但一定要注意实践,并学会举一反三

4.3、微信开发实例视频教程讲师建议

1.最好看完视频之后,抛开视频,独立自己去把上课中的示例写一遍,看自己是否理解,如果不正确,可以回过头看再看下视频,如果反复,达到真正理解和熟练掌握的目的。

2. 一定不要过于依赖视频,要学会看API和使用百度,学会思考,学会举一反三。

3.先把功能实现,再去简化代码,不要拘泥于一两个封装好的代码。

五、学完微信开发实例视频教程这门课程后能做什么?

学会微信开发实例视频教程后,您可以结合用户微信公众平台建立成熟的运营方案,可以从事微信公众平台技术维护相关工作。

六、学习微信开发实例视频教程常见问题:

常见问题一:学习该教程使用什么软件?

讲师回答:php的IDE都可以,建议使用Dreamweaver6,方便微网站开发。至少要做到代码错误提示

常见问题二:学这个课程需要什么基础?

讲师回答:不需要基础。

常见问题三:自己的服务器是否可以?BAE收费怎么办?

讲师回答:可以使用php服务器或其他云服务,BAE收费后可使用SAE,有免费的云豆。

微信开发实例视频教程-深入浅出微信公众平台实战开发(微网站、LBS云、Api接口调用、服务号高级接口)地址:http://www.ibeifeng.com/goods-383.html


2017-04-23 16:39:43 Penge_ 阅读数 6922
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27809 人正在学习 去看看 秦子恒

PHP微信支付开发实例


这篇文章主要为大家详细介绍了PHP微信支付开发过程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

PHP微信支付开发过程,分享给大家,供大家参考,具体内容如下

1.开发环境
Thinkphp 3.2.3
微信:服务号,已认证
开发域名:http://test.paywechat.com (自定义的域名,外网不可访问)

2.需要相关文件和权限
微信支付需申请开通
微信公众平台开发者文档:http://mp.weixin.qq.com/wiki/home/index.html
微信支付开发者文档:https://pay.weixin.qq.com/wiki/doc/api/index.html
微信支付SDK下载地址:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

3.开发
下载好微信支付PHP版本的SDK,文件目录为下图:

这里写图片描述

这里写图片描述 

把微信支付SDK的Cert和Lib目录放入Thinkphp,目录为

这里写图片描述 

现在介绍微信支付授权目录问题,首先是微信支付开发配置里面的支付授权目录填写,

这里写图片描述

然后填写JS接口安全域。

这里写图片描述

最后设置网页授权

这里写图片描述

这里写图片描述

这些设置完,基本完成一半,注意设置的目录和我thinkphp里面的目录。

这里写图片描述

4.微信支付配置

这里写图片描述

把相关配置填写正确。

/**
* 配置账号信息
*/

class WxPayConfig
{
 //=======【基本信息设置】=====================================
 //
 /**
 * TODO: 修改这里配置为您自己申请的商户信息
 * 微信公众号信息配置
 * 
 * APPID:绑定支付的APPID(必须配置,开户邮件中可查看)
 * 
 * MCHID:商户号(必须配置,开户邮件中可查看)
 * 
 * KEY:商户支付密钥,参考开户邮件设置(必须配置,登录商户平台自行设置)
 * 设置地址:https://pay.weixin.qq.com/index.php/account/api_cert
 * 
 * APPSECRET:公众帐号secert(仅JSAPI支付的时候需要配置, 登录公众平台,进入开发者中心可设置),
 * 获取地址:https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
 * @var string
 */
 const APPID = '';
 const MCHID = '';
 const KEY = '';
 const APPSECRET = '';

 //=======【证书路径设置】=====================================
 /**
 * TODO:设置商户证书路径
 * 证书路径,注意应该填写绝对路径(仅退款、撤销订单时需要,可登录商户平台下载,
 * API证书下载地址:https://pay.weixin.qq.com/index.php/account/api_cert,下载之前需要安装商户操作证书)
 * @var path
 */
 const SSLCERT_PATH = '../cert/apiclient_cert.pem';
 const SSLKEY_PATH = '../cert/apiclient_key.pem';

 //=======【curl代理设置】===================================
 /**
 * TODO:这里设置代理机器,只有需要代理的时候才设置,不需要代理,请设置为0.0.0.0和0
 * 本例程通过curl使用HTTP POST方法,此处可修改代理服务器,
 * 默认CURL_PROXY_HOST=0.0.0.0和CURL_PROXY_PORT=0,此时不开启代理(如有需要才设置)
 * @var unknown_type
 */
 const CURL_PROXY_HOST = "0.0.0.0";//"10.152.18.220";
 const CURL_PROXY_PORT = 0;//8080;

 //=======【上报信息配置】===================================
 /**
 * TODO:接口调用上报等级,默认紧错误上报(注意:上报超时间为【1s】,上报无论成败【永不抛出异常】,
 * 不会影响接口调用流程),开启上报之后,方便微信监控请求调用的质量,建议至少
 * 开启错误上报。
 * 上报等级,0.关闭上报; 1.仅错误出错上报; 2.全量上报
 * @var int
 */
 const REPORT_LEVENL = 1;
}

现在开始贴出代码:

namespace Wechat\Controller;
use Think\Controller;
/**
 * 父类控制器,需要继承
 * @file ParentController.class.php
 * @author Gary <lizhiyong2204@sina.com>
 * @date 2015年8月4日
 * @todu
 */
class ParentController extends Controller { 
 protected $options = array (
 'token' => '', // 填写你设定的key
 'encodingaeskey' => '', // 填写加密用的EncodingAESKey
 'appid' => '', // 填写高级调用功能的app id
 'appsecret' => '', // 填写高级调用功能的密钥
 'debug' => false,
 'logcallback' => ''
 ); 
 public $errCode = 40001; 
 public $errMsg = "no access"; 

 /**
 * 获取access_token
 * @return mixed|boolean|unknown
 */
 public function getToken(){
 $cache_token = S('exp_wechat_pay_token');
 if(!empty($cache_token)){
 return $cache_token;
 }
 $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s';
 $url = sprintf($url,$this->options['appid'],$this->options['appsecret']); 
 $result = $this->http_get($url);
 $result = json_decode($result,true); 
 if(empty($result)){
 return false;
 } 
 S('exp_wechat_pay_token',$result['access_token'],array('type'=>'file','expire'=>3600));
 return $result['access_token'];
 }

 /**
 * 发送客服消息
 * @param array $data 消息结构{"touser":"OPENID","msgtype":"news","news":{...}}
 */
 public function sendCustomMessage($data){
 $token = $this->getToken();
 if (empty($token)) return false; 
 $url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s';
 $url = sprintf($url,$token);
 $result = $this->http_post($url,self::json_encode($data));
 if ($result)
 {
 $json = json_decode($result,true);
 if (!$json || !empty($json['errcode'])) {
 $this->errCode = $json['errcode'];
 $this->errMsg = $json['errmsg'];
 return false;
 }
 return $json;
 }
 return false;
 }

 /**
 * 发送模板消息
 * @param unknown $data
 * @return boolean|unknown
 */
 public function sendTemplateMessage($data){
 $token = $this->getToken();
 if (empty($token)) return false;
 $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
 $url = sprintf($url,$token);
 $result = $this->http_post($url,self::json_encode($data));
 if ($result)
 {
 $json = json_decode($result,true);
 if (!$json || !empty($json['errcode'])) {
 $this->errCode = $json['errcode'];
 $this->errMsg = $json['errmsg'];
 return false;
 }
 return $json;
 }
 return false;
 }


 public function getFileCache($name){
 return S($name);
 }

 /**
 * 微信api不支持中文转义的json结构
 * @param array $arr
 */
 static function json_encode($arr) {
 $parts = array ();
 $is_list = false;
 //Find out if the given array is a numerical array
 $keys = array_keys ( $arr );
 $max_length = count ( $arr ) - 1;
 if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //See if the first key is 0 and last key is length - 1
 $is_list = true;
 for($i = 0; $i < count ( $keys ); $i ++) { //See if each key correspondes to its position
 if ($i != $keys [$i]) { //A key fails at position check.
  $is_list = false; //It is an associative array.
  break;
 }
 }
 }
 foreach ( $arr as $key => $value ) {
 if (is_array ( $value )) { //Custom handling for arrays
 if ($is_list)
  $parts [] = self::json_encode ( $value ); /* :RECURSION: */
 else
  $parts [] = '"' . $key . '":' . self::json_encode ( $value ); /* :RECURSION: */
 } else {
 $str = '';
 if (! $is_list)
  $str = '"' . $key . '":';
 //Custom handling for multiple data types
 if (!is_string ( $value ) && is_numeric ( $value ) && $value<2000000000)
  $str .= $value; //Numbers
 elseif ($value === false)
 $str .= 'false'; //The booleans
 elseif ($value === true)
 $str .= 'true';
 else
  $str .= '"' . addslashes ( $value ) . '"'; //All other things
 // :TODO: Is there any more datatype we should be in the lookout for? (Object?)
 $parts [] = $str;
 }
 }
 $json = implode ( ',', $parts );
 if ($is_list)
 return '[' . $json . ']'; //Return numerical JSON
 return '{' . $json . '}'; //Return associative JSON
 }

 /**
 +----------------------------------------------------------
 * 生成随机字符串
 +----------------------------------------------------------
 * @param int $length 要生成的随机字符串长度
 * @param string $type 随机码类型:0,数字+大小写字母;1,数字;2,小写字母;3,大写字母;4,特殊字符;-1,数字+大小写字母+特殊字符
 +----------------------------------------------------------
 * @return string
 +----------------------------------------------------------
 */
 static public function randCode($length = 5, $type = 2){
 $arr = array(1 => "0123456789", 2 => "abcdefghijklmnopqrstuvwxyz", 3 => "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 4 => "~@#$%^&*(){}[]|");
 if ($type == 0) {
 array_pop($arr);
 $string = implode("", $arr);
 } elseif ($type == "-1") {
 $string = implode("", $arr);
 } else {
 $string = $arr[$type];
 }
 $count = strlen($string) - 1;
 $code = '';
 for ($i = 0; $i < $length; $i++) {
 $code .= $string[rand(0, $count)];
 }
 return $code;
 } 


 /**
 * GET 请求
 * @param string $url
 */
 private function http_get($url){
 $oCurl = curl_init();
 if(stripos($url,"https://")!==FALSE){
 curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
 curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
 curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
 }
 curl_setopt($oCurl, CURLOPT_URL, $url);
 curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
 $sContent = curl_exec($oCurl);
 $aStatus = curl_getinfo($oCurl);
 curl_close($oCurl);
 if(intval($aStatus["http_code"])==200){
 return $sContent;
 }else{
 return false;
 }
 }

 /**
 * POST 请求
 * @param string $url
 * @param array $param
 * @param boolean $post_file 是否文件上传
 * @return string content
 */
 private function http_post($url,$param,$post_file=false){
 $oCurl = curl_init();
 if(stripos($url,"https://")!==FALSE){
 curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
 curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
 curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
 }
 if (is_string($param) || $post_file) {
 $strPOST = $param;
 } else {
 $aPOST = array();
 foreach($param as $key=>$val){
 $aPOST[] = $key."=".urlencode($val);
 }
 $strPOST = join("&", $aPOST);
 }
 curl_setopt($oCurl, CURLOPT_URL, $url);
 curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
 curl_setopt($oCurl, CURLOPT_POST,true);
 curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
 $sContent = curl_exec($oCurl);
 $aStatus = curl_getinfo($oCurl);
 curl_close($oCurl);
 if(intval($aStatus["http_code"])==200){
 return $sContent;
 }else{
 return false;
 }
 }
}

namespace Wechat\Controller;
use Wechat\Controller\ParentController;
/**
 * 微信支付测试控制器
 * @file TestController.class.php
 * @author Gary <lizhiyong2204@sina.com>
 * @date 2015年8月4日
 * @todu
 */
class TestController extends ParentController {
 private $_order_body = 'xxx';
 private $_order_goods_tag = 'xxx';
 public function __construct(){
 parent::__construct();
 require_once ROOT_PATH."Api/lib/WxPay.Api.php";
 require_once ROOT_PATH."Api/lib/WxPay.JsApiPay.php";
 }

 public function index(){
 //①、获取用户openid
 $tools = new \JsApiPay();
 $openId = $tools->GetOpenid(); 
 //②、统一下单
 $input = new \WxPayUnifiedOrder(); 
 //商品描述
 $input->SetBody($this->_order_body);
 //附加数据,可以添加自己需要的数据,微信回异步回调时会附加这个数据
 $input->SetAttach('xxx');
 //商户订单号
 $out_trade_no = \WxPayConfig::MCHID.date("YmdHis");
 $input->SetOut_trade_no($out_trade_no);
 //总金额,订单总金额,只能为整数,单位为分 
 $input->SetTotal_fee(1);
 //交易起始时间
 $input->SetTime_start(date("YmdHis"));
 //交易结束时间
 $input->SetTime_expire(date("YmdHis", time() + 600));
 //商品标记
 $input->SetGoods_tag($this->_order_goods_tag);
 //通知地址,接收微信支付异步通知回调地址 SITE_URL=http://test.paywechat.com/Charge
 $notify_url = SITE_URL.'/index.php/Test/notify.html';
 $input->SetNotify_url($notify_url);
 //交易类型
 $input->SetTrade_type("JSAPI");
 $input->SetOpenid($openId);
 $order = \WxPayApi::unifiedOrder($input);
 $jsApiParameters = $tools->GetJsApiParameters($order);
 //获取共享收货地址js函数参数
 $editAddress = $tools->GetEditAddressParameters();

 $this->assign('openId',$openId);
 $this->assign('jsApiParameters',$jsApiParameters);
 $this->assign('editAddress',$editAddress);
 $this->display(); 
 }

 /**
 * 异步通知回调方法
 */
 public function notify(){
 require_once ROOT_PATH."Api/lib/notify.php";
 $notify = new \PayNotifyCallBack();
 $notify->Handle(false);
 //这里的IsSuccess是我自定义的一个方法,后面我会贴出这个文件的代码,供参考。
 $is_success = $notify->IsSuccess(); 
 $bdata = $is_success['data']; 
 //支付成功
 if($is_success['code'] == 1){ 
 $news = array(
  'touser' => $bdata['openid'],
  'msgtype' => 'news',
  'news' => array (
  'articles'=> array (
   array(
   'title' => '订单支付成功',
   'description' => "支付金额:{$bdata['total_fee']}\n".
   "微信订单号:{$bdata['transaction_id']}\n"
   'picurl' => '',
   'url' => '' 
   )

  )
  )
 );
 //发送微信支付通知
 $this->sendCustomMessage($news); 
 }else{//支付失败

 }
 }

 /**
 * 支付成功页面
 * 不可靠的回调
 */
 public function ajax_PaySuccess(){
 //订单号
 $out_trade_no = I('post.out_trade_no');
 //支付金额
 $total_fee = I('post.total_fee');
 /*相关逻辑处理*/

 }

贴上模板HTML

<html>
<head>
 <meta http-equiv="content-type" content="text/html;charset=utf-8"/>
 <meta name="viewport" content="width=device-width, initial-scale=1"/> 
 <title>微信支付样例-支付</title>
 <script type="text/javascript">
 //调用微信JS api 支付
 function jsApiCall()
 {
 WeixinJSBridge.invoke(
 'getBrandWCPayRequest',
 {$jsApiParameters},
 function(res){
 WeixinJSBridge.log(res.err_msg);
 //取消支付
 if(res.err_msg == 'get_brand_wcpay_request:cancel'){
 //处理取消支付的事件逻辑
 }else if(res.err_msg == "get_brand_wcpay_request:ok"){
 /*使用以上方式判断前端返回,微信团队郑重提示:
 res.err_msg将在用户支付成功后返回 ok,但并不保证它绝对可靠。
 这里可以使用Ajax提交到后台,处理一些日志,如Test控制器里面的ajax_PaySuccess方法。
 */
 }
 alert(res.err_code+res.err_desc+res.err_msg);
 }
 );
 }

 function callpay()
 {
 if (typeof WeixinJSBridge == "undefined"){
 if( document.addEventListener ){
 document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
 }else if (document.attachEvent){
 document.attachEvent('WeixinJSBridgeReady', jsApiCall); 
 document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
 }
 }else{
 jsApiCall();
 }
 }
 //获取共享地址
 function editAddress()
 {
 WeixinJSBridge.invoke(
 'editAddress',
 {$editAddress},
 function(res){
 var value1 = res.proviceFirstStageName;
 var value2 = res.addressCitySecondStageName;
 var value3 = res.addressCountiesThirdStageName;
 var value4 = res.addressDetailInfo;
 var tel = res.telNumber; 
 alert(value1 + value2 + value3 + value4 + ":" + tel);
 }
 );
 }

 window.onload = function(){
 if (typeof WeixinJSBridge == "undefined"){
 if( document.addEventListener ){
 document.addEventListener('WeixinJSBridgeReady', editAddress, false);
 }else if (document.attachEvent){
 document.attachEvent('WeixinJSBridgeReady', editAddress); 
 document.attachEvent('onWeixinJSBridgeReady', editAddress);
 }
 }else{
 editAddress();
 }
 };

 </script>
</head>
<body>
 <br/>
 <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px">1分</span>钱</b></font><br/><br/>
 <div align="center">
 <button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" >立即支付</button>
 </div>
</body>
</html>

notify.php文件代码,这里有在官方文件里新添加的一个自定义方法。

require_once ROOT_PATH."Api/lib/WxPay.Api.php";
require_once ROOT_PATH.'Api/lib/WxPay.Notify.php';
require_once ROOT_PATH.'Api/lib/log.php';

//初始化日志
$logHandler= new \CLogFileHandler(ROOT_PATH."/logs/".date('Y-m-d').'.log');
$log = \Log::Init($logHandler, 15);

class PayNotifyCallBack extends WxPayNotify
{
 protected $para = array('code'=>0,'data'=>'');
 //查询订单
 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;
 }
 $this->para['code'] = 0;
 $this->para['data'] = '';
 return false;
 }

 //重写回调处理函数
 public function NotifyProcess($data, &$msg)
 {
 \Log::DEBUG("call back:" . json_encode($data));
 $notfiyOutput = array();

 if(!array_key_exists("transaction_id", $data)){
 $msg = "输入参数不正确";
 $this->para['code'] = 0;
 $this->para['data'] = '';
 return false;
 }
 //查询订单,判断订单真实性
 if(!$this->Queryorder($data["transaction_id"])){
 $msg = "订单查询失败";
 $this->para['code'] = 0;
 $this->para['data'] = '';
 return false;
 }

 $this->para['code'] = 1;
 $this->para['data'] = $data;
 return true;
 }

 /**
 * 自定义方法 检测微信端是否回调成功方法
 * @return multitype:number string
 */
 public function IsSuccess(){
 return $this->para;
 }
}

到这里基本上完成,可以在微信端打开http://test.paywechat.com/Charge/index.php/Test/index/
我的环境,HTTP服务器没有重写url,微信支付继续探索中,有些地方可能写的有问题或不足,望大家谅解,互相学习。

2016-09-04 22:17:55 weixin_36050378 阅读数 30911
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27809 人正在学习 去看看 秦子恒
所有微信开发的相关内容,都需要参考官方文档。

[微信公众平台|开发文档] http://mp.weixin.qq.com/wiki/home/

一、通过网页授权,可以获取用户微信的基本信息。

二、总共有5个步骤:

1 :用户同意授权,获取code

2 :通过code换取网页授权access_token

3 :刷新access_token(如果需要)

4 :拉取用户信息(需scope为 snsapi_userinfo)

5 附:检验授权凭证(access_token)是否有效

三、每一个步骤的实现。

1 :用户同意授权,获取code

/**
     * @explain
     * 获取code,用于获取openid和access_token
     * @remark
     * code只能使用一次,当获取到之后code失效,再次获取需要重新进入
     * 不会弹出授权页面,适用于关注公众号后自定义菜单跳转等,如果不关注,那么只能获取openid
     **/
    public function getCode()
    {
        if (isset($_GET["code"])) {
            return $_GET["code"];
        } else {
            $str = "location: https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->appid . "&redirect_uri=" . $this->index_url . "&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
            header($str);
            exit;
        }
    }

2 :通过code换取网页授权access_token

/**
     * @explain
     * 用于获取access_token,返回的<span style="font-family: Arial, Helvetica, sans-serif;">$access_token_array中也包含有用户的openid信息。</span>

     **/
    public function getOpenId()
    {
        $access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->appid . "&secret=" . $this->appsecret . "&code=" . $this->code . "&grant_type=authorization_code";
        $access_token_json = $this->https_request($access_token_url);
        $access_token_array = json_decode($access_token_json, TRUE);
        return $access_token_array;
    }

3 :刷新access_token(如果需要)

这一步直接略过。

4 :拉取用户信息(需scope为 snsapi_userinfo)

/**
     * @explain
     * 获取到用户的openid之后可以判断用户是否有数据,可以直接跳过获取access_token,也可以继续获取access_token
     **/
    public function getUserInfo()
    {
        
        $userinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token=".$this->access_token['access_token'] ."&openid=" . $this->access_token['openid']."&lang=zh_CN";
        $userinfo_json = $this->https_request($userinfo_url);
        $userinfo_array = json_decode($userinfo_json, TRUE);
        return $userinfo_array;
    }
至此四个步骤全部完成。


四、完整代码。实际项目使用TP3.2.3。

<?php

namespace Wechat\Controller;

use Think\Controller;

//微信接口基础类,其他微信类都继承这个基础类。可以自动判断用户状态,获取用户信息。
class WxbaseController extends Controller
{

    public $appid = 'wxba09d9f0fed4b84b';                   //微信APPID,公众平台获取
    public $appsecret = '332c2b1fc1eb282c0136b73723db4237'; //微信APPSECREC,公众平台获取
    public $index_url = "http://www.你的域名.cn/项目目录/index.php?m=分组&c=控制器&a=方法";  //微信回调地址,要跟公众平台的配置域名相同
    public $code;
    public $openid;

    /**
     *检测有无$_SESSION。<span style="font-family: Arial, Helvetica, sans-serif;">如果有,直接忽略。</span>
     *如果没有$<span style="font-family:Arial, Helvetica, sans-serif;">_SESSION</span>,就依次执行getCode、getOpenId、getUserInfo来获取用户信息。目的是解决CODE只能获取一次,刷新页面openid会丢失的问题。
     *再判断是否在数据库中,没有则写入数据库。最后将open_id写入session。
<span style="white-space:pre">	</span>*/
    public function _initialize()
    {
            if (!$_SESSION['openid']) {                             //如果$_SESSION中没有openid,说明用户刚刚登陆,就执行getCode、getOpenId、getUserInfo获取他的信息
                $this->code = $this->getCode();
                $this->access_token = $this->getOpenId();
                $userInfo = $this->getUserInfo();
                if ($userInfo) {
                    $ins = M('Wechat_user_info');<span style="white-space:pre">		</span>    //其他框架请自行调整方法。
                    $map['openid'] = $userInfo['openid'];
                    $result = $ins->where($map)->find();            //根据OPENID查找数据库中是否有这个用户,如果没有就写数据库。继承该类的其他类,用户都写入了数据库中。
                    if (!$result) {
                        $ins->add($userInfo);
                    }
                    session('openid', $userInfo['openid']);         //写到$_SESSION中。微信缓存很坑爹,调试时请及时清除缓存再试。
                }
            }

    }

    /**
     * @explain
     * 获取code,用于获取openid和access_token
     * @remark
     * code只能使用一次,当获取到之后code失效,再次获取需要重新进入
     * 不会弹出授权页面,适用于关注公众号后自定义菜单跳转等,如果不关注,那么只能获取openid
     **/
    public function getCode()
    {
        if (isset($_GET["code"])) {
            return $_GET["code"];
        } else {
            $str = "location: https://open.weixin.qq.com/connect/oauth2/authorize?appid=" . $this->appid . "&redirect_uri=" . $this->index_url . "&response_type=code&scope=snsapi_userinfo&state=1#wechat_redirect";
            header($str);
            exit;
        }
    }

    /**
     * @explain
     * 用于获取用户openid
     **/
    public function getOpenId()
    {
        $access_token_url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" . $this->appid . "&secret=" . $this->appsecret . "&code=" . $this->code . "&grant_type=authorization_code";
        $access_token_json = $this->https_request($access_token_url);
        $access_token_array = json_decode($access_token_json, TRUE);
        return $access_token_array;
    }

    /**
     * @explain
     * 通过code获取用户openid以及用户的微信号信息
     * @return
     * @remark
     * 获取到用户的openid之后可以判断用户是否有数据,可以直接跳过获取access_token,也可以继续获取access_token
     * access_token每日获取次数是有限制的,access_token有时间限制,可以存储到数据库7200s. 7200s后access_token失效
     **/
    public function getUserInfo()
    {

        $userinfo_url = "https://api.weixin.qq.com/sns/userinfo?access_token=".$this->access_token['access_token'] ."&openid=" . $this->access_token['openid']."&lang=zh_CN";
        $userinfo_json = $this->https_request($userinfo_url);
        $userinfo_array = json_decode($userinfo_json, TRUE);
        return $userinfo_array;
    }


    /**
     * @explain
     * 发送http请求,并返回数据
     **/
    public function https_request($url, $data = null)
    {
        $curl = curl_init();
        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;
    }
}



2015-08-21 11:09:34 NIT_3Dnn 阅读数 6176
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27809 人正在学习 去看看 秦子恒

前端

<div>
    <img class="preview" src="{$ig'}" style="width: 250px;"/>
    <button class="uploadImage" type="button" id="vt">点击上传</button>
    <input id="ig" type="hidden" name="media_id" value="{$ig}">
</div>
<script type="text/javascript" src="/jweixin-1.0.0.js"></script>
<script>
  wx.config({
    debug: false,
    appId: '<?php echo $signPackage["appId"];?>',
    timestamp: <?php echo $signPackage["timestamp"];?>,
    nonceStr: '{$signPackage["nonceStr"]}',
    signature: '{$signPackage["signature"]}',
    jsApiList: [
      /* 所有要调用的 API 都要加到这个列表中*/
	  'chooseImage',
	  'previewImage',
	  'uploadImage',
	  'downloadImage'
    ]
  });
  wx.ready(function() {
    //手机相册选图或拍照
    var images = {
        localId: [],
        serverId: []
    };
    //上传图片
    $(".uploadImage").click(function() {
        var that = $(this);
        images.localId = [];
        wx.chooseImage({
            success: function(res) {
                images.localId = res.localIds;// 返回选定照片的本地ID列表,localId可以作为img标签的src属性显示图片
                if (images.localId.length == 0) {
                    alert('请先使用 chooseImage 接口选择图片');
                    return;
                }
                if (images.localId.length > 1) {
                    alert('目前仅支持单张图片上传,请重新上传');
                    images.localId = [];
                    return;
                }
                var i = 0,
                length = images.localId.length;
                images.serverId = [];
                function upload() {
                    wx.uploadImage({
                        localId: images.localId[i],
                        success: function(res) {
                            i++;
  		            var media_id = res.serverId; /*返回图片的服务器端ID,serverId 即 media_id*/                                                                    that.siblings('img.preview').attr('src', images.localId[0]);
			    that.siblings("input[name='media_id']").val(media_id);//对隐藏域赋值传到后台处理
                            images.serverId.push(res.serverId);
                            if (i < length) {//现在只能单张
                                upload();
                            }
                        },
                        fail: function(res) {
                            alert(JSON.stringify(res));
                        }
                    });
                }
                upload();
            }
        });
    });
});
</script>

后台

        /*
	 * 获取media_id
	 */
        public function add(){
		if(IS_POST){
		    $serverId = I('post.media_id');
		    if(!empty($serverId)){
		        $data['imgpath'] = $this->doWechatPic( $serverId );
		    }
	}
	
	/*
	 * 从微信服务器获取图片流
	 */
	public function doWechatPic($serverId){//media_id=jlJs_iQIOA-TKLuhk4nCdPEdXnJ6paIeToO8vr-WUGvz05-6i5n498EzI232xSxn
               $media_id = $serverId;//提交过来的serverId即$media_id	
	        $access_token = $this->access_token;
 	        $pic_url = "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token={$access_token}&media_id={$media_id}";
 	        $filebody = file_get_contents($pic_url);//通过接口获取图片流
                $filename = uniqid().'.jpg';            //定义图片名字及格式
	        return $this->saveFile($filename, $filebody);
	}
	
	/*
	 * 定义文件路径,写入图片流
	 */
	public function saveFile($filename, $filecontent){
	    $upload_dir = "./image/".date("Ymd");//保存路径,以时间作目录分层
            $mkpath = $upload_dir;        
	    if(!is_dir($mkpath)){
	        if(!mkdir($mkpath)){
	            die('no mkdir power');
	        }
	        if(!chmod($mkpath,0755)){//若服务器在阿里云上不建议使用0644
	            die('no chmod power');
	        }
	    }	    
	    $savepath = $upload_dir.'/'.$filename;	    
	    if(file_put_contents($savepath, $filecontent)){//写入图片流生成图片
	        return $upload."/".$filename;//返回图片路径
	    }else{
	        die('save failed');
	    }
	    
	}

2018-03-14 11:15:46 qq_20313115 阅读数 1277
  • 微信支付开发-微信公众号开发12-微信开发php

    微信公众平台开发之微信支付开发是子恒老师《微信公众平台开发》视频教程的第12部。详细讲解了用php进行微信支付的开发。内容包含获取支付密钥,微信公众号支付开发,扫码支付,微信刷卡支付,异步处理支付结果等等。欢迎反馈,微信/QQ:68183131

    27809 人正在学习 去看看 秦子恒

一、注册小程序账号

1.进入微信公众平台(https://mp.weixin.qq.com/,注册小程序账号,根据提示填写对应的信息即可。
2.注册成功后进入首页,在 小程序发布流程->小程序开发与管理->配置服务器中,点击“开发者设置”。
3.会获得一个AppID,记录AppID,后面创建项目时会用到。

注意:如果要以非管理员微信号在手机上体验该小程序,那么我们还需要操作“绑定开发者”。即在“用户身份”-“开发者”模块,绑定上需要体验该小程序的微信号。本教程默认注册帐号、体验都是使用管理员微信号

二、下载微信web开发者工具

为了帮助开发者简单和高效地开发,微信小程序推出了全新的开发者工具 ,集成了开发调试、代码编辑及程序发布等功能。
1.下载页面:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=201715
根据系统,选择对应的工具版本下载
2.工具包含编辑、调试和项目三个页卡:
(1)编辑区可以对当前项目进行代码编写和文件的添加、删除以及重命名等基本操作
(2)程序调试主要有三大功能区:模拟器、调试工具和小程序操作区
(3)项目页卡主要有三大功能:显示当前项目细节、提交预览和提交上传和项目配置

注意:启动工具时,开发者需要使用已在后台绑定成功的微信号扫描二维码登录,后续所有的操作都会基于这个微信帐号

三、编写小程序实例

1.实例目录结构


  test
    ├─ page
    │   └─ index
    │        ├─ index.js
    │        ├─ index.json
    │        ├─ index.wxml
    │        └─ index.wxss
    ├─ app.js
    ├─ app.json
    └─ app.wxss

2.实例文件说明及源码
一个小程序包含一个app(主体部分)和多个page(页面)
(1)app是用来描述整体程序的,由三个文件组成,.js后缀的是脚本文件,.json后缀的文件是配置文件,.wxss后缀的是样式表文件,必须放在项目的根目录。
app.js是小程序的脚本代码(必须),可以在这个文件中监听并处理小程序的生命周期函数、声明全局变量,调用框架提供的丰富的 API。


App({
    onLaunch: function () {
        console.log('App Launch')
    },
    onShow: function () {
        console.log('App Show')
    },
    onHide: function () {
        console.log('App Hide')
    },
    globalData: {
        hasLogin: false
    }
})

app.json是对整个小程序的全局配置(必须),用来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多tab等。接受一个数组,每一项都是字符串,来指定小程序由哪些页面组成。微信小程序中的每一个页面的【路径+页面名】都需要写在app.json的pages中,且pages中的第一个页面是小程序的首页。


{
    "pages":[
        "page/index/index"
    ],
    "window":{
        "navigationBarTextStyle": "black",
        "navigationBarTitleText": "欢迎页",
        "navigationBarBackgroundColor": "#fbf9fe",
        "backgroundColor": "#fbf9fe"
    },
    "debug": true
}

app.wxss是整个小程序的公共样式表(非必须)。


page {
    background-color: #fbf9fe;
    height: 100%;
}
.container {
    display: flex;
    flex-direction: column;
    min-height: 100%;
    justify-content: space-between;
}

(2)page是用来描述页面,一个页面由四个文件组成,这里以首页index为例,每一个小程序页面是由同路径下同名的四个不同后缀文件的组成,如:index.js、index.wxml、index.wxss、index.json。.js后缀的文件是脚本文件,.json后缀的文件是配置文件,.wxss后缀的是样式表文件,.wxml后缀的文件是页面结构文件。
index.js 是页面的脚本文件(必须),在这个文件中我们可以监听并处理页面的生命周期函数、获取小程序实例,声明并处理数据,响应页面交互事件等。


Page({
    data: {
        title:'小程序',
        desc:'Hello World!'
    }
})

index.wxml是页面结构文件(必须)。


<view class="container">
    <view class="header">
        <view class="title">标题:{{title}}</view>
        <view class="desc">描述:{{desc}}</view>
    </view>
</view>

index.wxss是页面样式表文件(非必须),当有页面样式表时,页面的样式表中的样式规则会层叠覆盖app.wxss中的样式规则。如果不指定页面的样式表,也可以在页面的结构文件中直接使用app.wxss中指定的样式规则。


.header {
    padding: 80rpx;
    line-height: 1;
}
.title {
    font-size: 52rpx;
}
.desc {
    margin-top: 10rpx;
    color: #888888;
    font-size: 28rpx;
}

index.json是页面配置文件(非必须),当有页面的配置文件时,配置项在该页面会覆盖app.json的window中相同的配置项。如果没有指定的页面配置文件,则在该页面直接使用app.json中的默认配置。这里无需指定。
Tips:
a.为了方便开发者减少配置项,小程序规定描述页面的这四个文件必须具有相同的路径与文件名
b.小程序提供了丰富的API,可以根据自己需求选择(https://mp.weixin.qq.com/debug/wxadoc/dev/api/?t=201715

四、测试小程序实例

1.打开微信web开发者工具,选择“本地小程序项目”。
2.填写小程序的AppID,项目名称,选择第三步写好的小程序实例文件夹,点击“添加项目”。
3.如果出现如下效果,那么恭喜你,你的第一个小程序项目已经编写成功了!点击左侧边栏“编辑”,还可以在右侧编辑窗口直接对代码进行修改,保存(CTRL+S)后刷新(F5)即可生效。

4.如果想看小程序项目在手机上的效果,点击左侧边栏“项目”,点击“预览”生成二维码,打开微信扫描,就可以看到了。

微信asp回复消息开发实例

博文 来自: rcy5211314
没有更多推荐了,返回首页