
CSDN博客技术专家。已出版《微信公众平台开发最佳实践》第一版、第二版及第三版,《企业微信公众平台开发实战》等书籍。
8 月 12 日,阿拉丁数据统计平台发布了国内第一份小程序 TOP100 榜单,摩拜单车成为全榜第一! 该榜单数据来源于阿拉丁小程序统计平台检测、合作、如有赞等,并经过企业电话调研和实地走访企业等校准,选取人气、搜索、使用、分享四大指标来衡量一款小程序的活跃度。 目前阿拉丁收录了超过 10000 个小程序,前 5 名小程序分别是摩拜单车、王卡申请助手、腾讯视频、拼多多、蘑菇街女装特卖。 监测数据显示,小程序指数 TOP100 中小程序数量前三位为工具、零售、生活服务,其中工具类占比 36%,后两者各占 10% 左右。三者超过小程序总数的一半。 此外,在小程序指数 TOP100 中,互联网企业占比 73.6%,传统企业占比 21.9%,另有政府和个人参与。 值得一提的是,TOP100 中,共享类小程序占 8 个,其中 4 款挤入 TOP30,共享类小程序整体流量仍属于上升态势。
一、 API接口介绍 alibaba.aliqin.fc.sms.num.send (短信发送) 向指定手机号码发送模板短信,模板内可设置部分变量。使用前需要在阿里大于管理中心添加短信签名与短信模板。测试时请直接使用正式环境HTTP请求地址。 【重要】批量发送(一次传递多个号码eg:1381111111,1382222222)会产生相应的延迟,触达时间要求高的建议单条发送 公共参数 请求地址: 环境 HTTP请求地址 HTTPS请求地址 正式环境 http://gw.api.taobao.com/router/rest https://eco.taobao.com/router/rest 沙箱环境 http://gw.api.tbsandbox.com/router/rest https://gw.api.tbsandbox.com/router/rest 公共请求参数: 名称 类型 是否必须 描述 method String 是 API接口名称。 app_key String 是 TOP分配给应用的AppKey。 target_app_key String 否 被调用的目标AppKey,仅当被调用的API为第三方ISV提供时有效。 sign_method String 是 签名的摘要算法,可选值为:hmac,md5。 sign String 是 API输入参数签名结果,签名算法介绍请点击这里。 session String 否 用户登录授权成功后,TOP颁发给应用的授权信息,详细介绍请点击这里。当此API的标签上注明:“需要授权”,则此参数必传;“不需要授权”,则此参数不需要传;“可选授权”,则此参数为可选。 timestamp String 是 时间戳,格式为yyyy-MM-dd HH:mm:ss,时区为GMT+8,例如:2015-01-01 12:00:00。淘宝API服务端允许客户端请求最大时间误差为10分钟。 format String 否 响应格式。默认为xml格式,可选值:xml,json。 v String 是 API协议版本,可选值:2.0。 partner_id String 否 合作伙伴身份标识。 simplify Boolean 否 是否采用精简JSON返回格式,仅当format=json时有效,默认值为:false。 请求参数 名称 类型 是否必须 示例值 更多限制 描述 extend String 可选 123456 公共回传参数,在“消息返回”中会透传回该参数;举例:用户可以传入自己下级的会员ID,在消息返回时,该会员ID会包含在内,用户可以根据该会员ID识别是哪位会员使用了你的应用 sms_type String 必须 normal 短信类型,传入值请填写normal sms_free_sign_name String 必须 阿里大于 短信签名,传入的短信签名必须是在阿里大于“管理中心-验证码/短信通知/推广短信-配置短信签名”中的可用签名。如“阿里大于”已在短信签名管理中通过审核,则可传入”阿里大于“(传参时去掉引号)作为短信签名。短信效果示例:【阿里大于】欢迎使用阿里大于服务。 sms_param Json 可选 {"code":"1234","product":"alidayu"} 短信模板变量,传参规则{"key":"value"},key的名字须和申请模板中的变量名一致,多个变量之间以逗号隔开。示例:针对模板“验证码${code},您正在进行${product}身份验证,打死不要告诉别人哦!”,传参时需传入{"code":"1234","product":"alidayu"} rec_num String 必须 13000000000 短信接收号码。支持单个或多个手机号码,传入号码为11位手机号码,不能加0或+86。群发短信需传入多个号码,以英文逗号分隔,一次调用最多传入200个号码。示例:18600000000,13911111111,13322222222 sms_template_code String 必须 SMS_585014 短信模板ID,传入的模板必须是在阿里大于“管理中心-短信模板管理”中的可用模板。示例:SMS_585014 响应参数 名称 类型 示例值 描述 result BizResult 0 返回值 └ err_code String 0 错误码 └ model String 134523^4351232 返回结果 └ success Boolean false true表示成功,false表示失败 └ msg String 成功 返回信息描述 二、SDK实现 三、调用方法 header('Content-Type: text/html; charset=UTF-8'); $sms = new Alidayu; $sms->appkey = "24535123"; $sms->secretKey = '1d7ed250f68e3c096f9b18a434765456'; $code = strval(rand(100000,999999)); $requestMethod = "alibaba.aliqin.fc.sms.num.send"; $apiParams = array(); $apiParams["extend"] = "123456"; $apiParams["sms_type"] = "normal"; $apiParams["sms_free_sign_name"] = "方倍工作室"; $apiParams["sms_param"] = json_encode(array("code"=>$code)); $apiParams["rec_num"] = "15889386666"; $apiParams["sms_template_code"] = "SMS_75835210"; $resp = $sms->execute($requestMethod, $apiParams); var_dump($resp); 四、代码下载 扫描关注下文二维码,回复 “1245” 获取
1. 域名 在万网购买,略 2. 云服务器 阿里云购买,略 3. 安装lnmp 使用lnmp.org程序,略 4. 申请证书 阿里云-管理控制台-安全(云盾)-证书服务-购买证书证书类型: 免费型DV SSL选择品牌: Symantec 购买成功后,绑定域名,配置DNS解析记录生效 5. 配置HTTPS服务器 Nginx的安装目录下创建cert目录下载证书,放到cert目录修改nginx.conf文件,加入443端口及证书目录 server { listen 80; listen 443 ssl; #listen [::]:80; server_name cet.fangbei.org; index index.html index.htm index.php default.html default.htm default.php; root /home/wwwroot/cet.fangbei.org; include none.conf; #error_page 404 /404.html; include enable-php.conf; ssl_certificate /usr/local/nginx/cert/214130435490250.pem; ssl_certificate_key /usr/local/nginx/cert/214130435490250.key; location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 12h; } location ~ /\. { deny all; } access_log off; } 重启lnmp即可。 6. 使用https访问网站 支持80端口和443访问 http://cet.fangbei.org/ https://cet.fangbei.org/ https访问时,可以看到证书
在这篇微信小程序开发教程中,我们将介绍如何使用微信小程序开发2048小游戏。 本文主要分为两个部分,小程序主体部分及小游戏页面部分 一、小程序主体部分 一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下: 1. 小程序逻辑 App({ onLaunch: function() { // Do something initial when launch. }, onShow: function() { // Do something when show. }, onHide: function() { // Do something when hide. }, globalData: 'I am global data' }) 2. 小程序公共设置 主要注册一个页面,即2048游戏主页 { "pages":[ "pages/index/index" ], "window":{ "navigationBarBackgroundColor":"#ffffff", "navigationBarTextStyle":"#1AAD16", "navigationBarTitleText":"2048游戏", "backgroundColor":"#eeeeee", "backgroundTextStyle":"light" }, "networkTimeout": { "request": 10000, "downloadFile": 10000 }, "debug": false } 二、小游戏页面部分 2048游戏小程序页面主要由以下文件组成。 1. 页面结构 其页面结构代码如下 <view class="container"> <view class="game-body"> <loading hidden="{{hidden}}"> 加载中... </loading> <view class="heading"> <text class="title">2048</text> <view class="scores-container"> <view class="score-container">{{score}}</view> <view class="best-container">{{highscore}}</view> </view> </view> <view class="above-game"> <text class="game-intro">你能拿到2048吗?</text> <text class="restart-button" bindtap="restart">新游戏</text> </view> <view class="game-container"> <view class="game-message game-{{over ? (win ? 'won' : 'over') : ''}}"> <text class="over-msg">{{overMsg}}</text> <view class="lower"> <!-- <text class="keep-playing-button">继续</text> --> <text class="retry-button" bindtap="restart">再试一次</text> </view> </view> <view class="grid-container" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd"> <view wx:for="{{grids}}" wx:for-index="rowIdx" wx:for-item="row" class="grid-row"> <view wx:for="{{row}}" wx:for-index="colIdx" wx:for-item="cell" class="grid-cell"> <view class="tile tile-{{cell.value}}"> <view wx:if="{{cell}}" class="tile-inner"> {{cell.value}} </view> </view> </view> </view> </view> </view> <!-- <view class="game-explanation"> <view class="important">如何开始:</view> 手指上下左右滑动 </view> --> </view> </view> 2. 样式表 样式代码如下所示 .container { margin: 0; padding: 20px 0; background: #faf8ef; color: #776e65; font-family: "Helvetica Neue", Arial, sans-serif; font-size: 18px; } .heading:after { content: ""; display: block; clear: both; } .title { font-size: 80px; font-weight: bold; margin: 0; display: block; float: left; } .scores-container { float: right; text-align: right; } .score-container, .best-container { position: relative; display: inline-block; background: #bbada0; padding: 15px 25px; font-size: 25px; height: 25px; line-height: 47px; font-weight: bold; border-radius: 3px; color: white; text-align: center; margin: 8px 0 0 8px; } .score-container:after, .best-container:after { position: absolute; width: 100%; top: 10px; left: 0; text-transform: uppercase; font-size: 13px; line-height: 13px; text-align: center; color: #eee4da; } .score-container .score-addition, .best-container .score-addition { position: absolute; right: 30px; color: red; font-size: 25px; line-height: 25px; font-weight: bold; color: rgba(119, 110, 101, 0.9); z-index: 100; } .score-container:after { content: "Score"; } .best-container:after { content: "Best"; } p { margin-top: 0; margin-bottom: 10px; line-height: 1.65; } a { color: #776e65; font-weight: bold; text-decoration: underline; cursor: pointer; } strong.important { text-transform: uppercase; } hr { border: none; border-bottom: 1px solid #d8d4d0; margin-top: 20px; margin-bottom: 30px; } .game-container { margin-top: 40px; position: relative; padding: 15px; cursor: default; -webkit-touch-callout: none; -ms-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -ms-touch-action: none; touch-action: none; background: #bbada0; border-radius: 6px; width: 500px; height: 500px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .game-container .game-message { /*display: none;*/ position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: rgba(238, 228, 218, 0.5); z-index: 100; text-align: center; } .game-container .game-message p { font-size: 60px; font-weight: bold; height: 60px; line-height: 60px; margin-top: 222px; } .game-container .game-message .lower { display: block; margin-top: 59px; } .game-container .game-message a { display: inline-block; background: #8f7a66; border-radius: 3px; padding: 0 20px; text-decoration: none; color: #f9f6f2; height: 40px; line-height: 42px; margin-left: 9px; } .game-container .game-message .keep-playing-button { display: none; } .game-container .game-message.game-won { background: rgba(237, 194, 46, 0.5); color: #f9f6f2; } .game-container .game-message.game-won .keep-playing-button { display: inline-block; } .game-container .game-message.game-won, .game-container .game-message.game-over { display: block; } .grid-container { position: absolute; z-index: 1; } .grid-row { margin-bottom: 15px; } .grid-row:last-child { margin-bottom: 0; } .grid-row:after { content: ""; display: block; clear: both; } .grid-cell { width: 106.25px; height: 106.25px; margin-right: 15px; float: left; border-radius: 3px; background: rgba(238, 228, 218, 0.35); } .grid-cell:last-child { margin-right: 0; } .tile-container { position: absolute; z-index: 2; } .tile, .tile .tile-inner { width: 107px; height: 107px; line-height: 107px; } .tile.tile-position-1-1 { -webkit-transform: translate(0px, 0px); -moz-transform: translate(0px, 0px); -ms-transform: translate(0px, 0px); transform: translate(0px, 0px); } .tile.tile-position-1-2 { -webkit-transform: translate(0px, 121px); -moz-transform: translate(0px, 121px); -ms-transform: translate(0px, 121px); transform: translate(0px, 121px); } .tile.tile-position-1-3 { -webkit-transform: translate(0px, 242px); -moz-transform: translate(0px, 242px); -ms-transform: translate(0px, 242px); transform: translate(0px, 242px); } .tile.tile-position-1-4 { -webkit-transform: translate(0px, 363px); -moz-transform: translate(0px, 363px); -ms-transform: translate(0px, 363px); transform: translate(0px, 363px); } .tile.tile-position-2-1 { -webkit-transform: translate(121px, 0px); -moz-transform: translate(121px, 0px); -ms-transform: translate(121px, 0px); transform: translate(121px, 0px); } .tile.tile-position-2-2 { -webkit-transform: translate(121px, 121px); -moz-transform: translate(121px, 121px); -ms-transform: translate(121px, 121px); transform: translate(121px, 121px); } .tile.tile-position-2-3 { -webkit-transform: translate(121px, 242px); -moz-transform: translate(121px, 242px); -ms-transform: translate(121px, 242px); transform: translate(121px, 242px); } .tile.tile-position-2-4 { -webkit-transform: translate(121px, 363px); -moz-transform: translate(121px, 363px); -ms-transform: translate(121px, 363px); transform: translate(121px, 363px); } .tile.tile-position-3-1 { -webkit-transform: translate(242px, 0px); -moz-transform: translate(242px, 0px); -ms-transform: translate(242px, 0px); transform: translate(242px, 0px); } .tile.tile-position-3-2 { -webkit-transform: translate(242px, 121px); -moz-transform: translate(242px, 121px); -ms-transform: translate(242px, 121px); transform: translate(242px, 121px); } .tile.tile-position-3-3 { -webkit-transform: translate(242px, 242px); -moz-transform: translate(242px, 242px); -ms-transform: translate(242px, 242px); transform: translate(242px, 242px); } .tile.tile-position-3-4 { -webkit-transform: translate(242px, 363px); -moz-transform: translate(242px, 363px); -ms-transform: translate(242px, 363px); transform: translate(242px, 363px); } .tile.tile-position-4-1 { -webkit-transform: translate(363px, 0px); -moz-transform: translate(363px, 0px); -ms-transform: translate(363px, 0px); transform: translate(363px, 0px); } .tile.tile-position-4-2 { -webkit-transform: translate(363px, 121px); -moz-transform: translate(363px, 121px); -ms-transform: translate(363px, 121px); transform: translate(363px, 121px); } .tile.tile-position-4-3 { -webkit-transform: translate(363px, 242px); -moz-transform: translate(363px, 242px); -ms-transform: translate(363px, 242px); transform: translate(363px, 242px); } .tile.tile-position-4-4 { -webkit-transform: translate(363px, 363px); -moz-transform: translate(363px, 363px); -ms-transform: translate(363px, 363px); transform: translate(363px, 363px); } .tile { position: absolute; -webkit-transition: 100ms ease-in-out; -moz-transition: 100ms ease-in-out; transition: 100ms ease-in-out; -webkit-transition-property: -webkit-transform; -moz-transition-property: -moz-transform; transition-property: transform; } .tile .tile-inner { border-radius: 3px; background: #eee4da; text-align: center; font-weight: bold; z-index: 10; font-size: 55px; } .tile.tile-2 .tile-inner { background: #eee4da; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0), inset 0 0 0 1px rgba(255, 255, 255, 0); } .tile.tile-4 .tile-inner { background: #ede0c8; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0), inset 0 0 0 1px rgba(255, 255, 255, 0); } .tile.tile-8 .tile-inner { color: #f9f6f2; background: #f2b179; } .tile.tile-16 .tile-inner { color: #f9f6f2; background: #f59563; } .tile.tile-32 .tile-inner { color: #f9f6f2; background: #f67c5f; } .tile.tile-64 .tile-inner { color: #f9f6f2; background: #f65e3b; } .tile.tile-128 .tile-inner { color: #f9f6f2; background: #edcf72; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.2381), inset 0 0 0 1px rgba(255, 255, 255, 0.14286); font-size: 45px; } @media screen and (max-width:520px) { .tile.tile-128 .tile-inner { font-size: 25px; } } .tile.tile-256 .tile-inner { color: #f9f6f2; background: #edcc61; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.31746), inset 0 0 0 1px rgba(255, 255, 255, 0.19048); font-size: 45px; } @media screen and (max-width:520px) { .tile.tile-256 .tile-inner { font-size: 25px; } } .tile.tile-512 .tile-inner { color: #f9f6f2; background: #edc850; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.39683), inset 0 0 0 1px rgba(255, 255, 255, 0.2381); font-size: 45px; } @media screen and (max-width:520px) { .tile.tile-512 .tile-inner { font-size: 25px; } } .tile.tile-1024 .tile-inner { color: #f9f6f2; background: #edc53f; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.47619), inset 0 0 0 1px rgba(255, 255, 255, 0.28571); font-size: 35px; } @media screen and (max-width:520px) { .tile.tile-1024 .tile-inner { font-size: 15px; } } .tile.tile-2048 .tile-inner { color: #f9f6f2; background: #edc22e; box-shadow: 0 0 30px 10px rgba(243, 215, 116, 0.55556), inset 0 0 0 1px rgba(255, 255, 255, 0.33333); font-size: 35px; } @media screen and (max-width:520px) { .tile.tile-2048 .tile-inner { font-size: 15px; } } .tile.tile-super .tile-inner { color: #f9f6f2; background: #3c3a32; font-size: 30px; } @media screen and (max-width:520px) { .tile.tile-super .tile-inner { font-size: 10px; } } .tile-merged .tile-inner { z-index: 20; } .above-game:after { content: ""; display: block; clear: both; } .game-intro { float: left; line-height: 42px; margin-bottom: 0; } .restart-button { display: inline-block; background: #8f7a66; border-radius: 3px; padding: 0 20px; text-decoration: none; color: #f9f6f2; height: 40px; line-height: 42px; display: block; text-align: center; float: right; } .game-explanation { margin-top: 50px; } @media screen and (max-width:520px) { html, body { font-size: 15px; } body { margin: 20px 0; padding: 0 20px; } .title { font-size: 27px; margin-top: 15px; } /*.container { width: 280px; margin: 0 auto; }*/ .score-container, .best-container { margin-top: 0; padding: 15px 10px; min-width: 40px; } .heading { margin-bottom: 10px; } .game-intro { width: 55%; display: block; box-sizing: border-box; line-height: 1.65; } .restart-button { width: 42%; padding: 0; display: block; box-sizing: border-box; margin-top: 2px; } .game-container { margin-top: 17px; position: relative; padding: 10px; cursor: default; -webkit-touch-callout: none; -ms-touch-callout: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -ms-touch-action: none; touch-action: none; background: #bbada0; border-radius: 6px; width: 280px; height: 280px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } .game-container .game-message { display: none; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: rgba(238, 228, 218, 0.5); z-index: 100; text-align: center; } .game-container .game-message .over-msg { display: block; font-size: 30px; font-weight: bold; height: 30px; line-height: 30px; /*margin-top: 222px;*/ margin-top: 59px; } .game-container .game-message .lower { display: block; margin-top: 59px; } .game-container .game-message .retry-button { display: inline-block; background: #8f7a66; border-radius: 3px; padding: 0 20px; text-decoration: none; color: #f9f6f2; height: 40px; line-height: 42px; margin-left: 9px; } .game-container .game-message .keep-playing-button { display: none; } .game-container .game-message.game-won { background: rgba(237, 194, 46, 0.5); color: #f9f6f2; } .game-container .game-message.game-won .keep-playing-button { display: inline-block; } .game-container .game-message.game-won, .game-container .game-message.game-over { display: block; } .grid-container { position: absolute; z-index: 1; } .grid-row { margin-bottom: 10px; } .grid-row:last-child { margin-bottom: 0; } .grid-row:after { content: ""; display: block; clear: both; } .grid-cell { width: 57.5px; height: 57.5px; margin-right: 10px; float: left; border-radius: 3px; background: rgba(238, 228, 218, 0.35); } .grid-cell:last-child { margin-right: 0; } .tile, .tile .tile-inner { width: 58px; height: 58px; line-height: 58px; } .tile.tile-position-1-1 { -webkit-transform: translate(0px, 0px); -moz-transform: translate(0px, 0px); -ms-transform: translate(0px, 0px); transform: translate(0px, 0px); } .tile.tile-position-1-2 { -webkit-transform: translate(0px, 67px); -moz-transform: translate(0px, 67px); -ms-transform: translate(0px, 67px); transform: translate(0px, 67px); } .tile.tile-position-1-3 { -webkit-transform: translate(0px, 135px); -moz-transform: translate(0px, 135px); -ms-transform: translate(0px, 135px); transform: translate(0px, 135px); } .tile.tile-position-1-4 { -webkit-transform: translate(0px, 202px); -moz-transform: translate(0px, 202px); -ms-transform: translate(0px, 202px); transform: translate(0px, 202px); } .tile.tile-position-2-1 { -webkit-transform: translate(67px, 0px); -moz-transform: translate(67px, 0px); -ms-transform: translate(67px, 0px); transform: translate(67px, 0px); } .tile.tile-position-2-2 { -webkit-transform: translate(67px, 67px); -moz-transform: translate(67px, 67px); -ms-transform: translate(67px, 67px); transform: translate(67px, 67px); } .tile.tile-position-2-3 { -webkit-transform: translate(67px, 135px); -moz-transform: translate(67px, 135px); -ms-transform: translate(67px, 135px); transform: translate(67px, 135px); } .tile.tile-position-2-4 { -webkit-transform: translate(67px, 202px); -moz-transform: translate(67px, 202px); -ms-transform: translate(67px, 202px); transform: translate(67px, 202px); } .tile.tile-position-3-1 { -webkit-transform: translate(135px, 0px); -moz-transform: translate(135px, 0px); -ms-transform: translate(135px, 0px); transform: translate(135px, 0px); } .tile.tile-position-3-2 { -webkit-transform: translate(135px, 67px); -moz-transform: translate(135px, 67px); -ms-transform: translate(135px, 67px); transform: translate(135px, 67px); } .tile.tile-position-3-3 { -webkit-transform: translate(135px, 135px); -moz-transform: translate(135px, 135px); -ms-transform: translate(135px, 135px); transform: translate(135px, 135px); } .tile.tile-position-3-4 { -webkit-transform: translate(135px, 202px); -moz-transform: translate(135px, 202px); -ms-transform: translate(135px, 202px); transform: translate(135px, 202px); } .tile.tile-position-4-1 { -webkit-transform: translate(202px, 0px); -moz-transform: translate(202px, 0px); -ms-transform: translate(202px, 0px); transform: translate(202px, 0px); } .tile.tile-position-4-2 { -webkit-transform: translate(202px, 67px); -moz-transform: translate(202px, 67px); -ms-transform: translate(202px, 67px); transform: translate(202px, 67px); } .tile.tile-position-4-3 { -webkit-transform: translate(202px, 135px); -moz-transform: translate(202px, 135px); -ms-transform: translate(202px, 135px); transform: translate(202px, 135px); } .tile.tile-position-4-4 { -webkit-transform: translate(202px, 202px); -moz-transform: translate(202px, 202px); -ms-transform: translate(202px, 202px); transform: translate(202px, 202px); } .tile .tile-inner { font-size: 35px; } .game-message p { font-size: 30px !important; height: 30px !important; line-height: 30px !important; margin-top: 90px !important; } .game-message .lower { margin-top: 30px !important; } } 3、 页面逻辑处理 var app = getApp(); var Grid = require('./grid.js'); var Tile = require('./tile.js'); var GameManager = require('./game_manager.js'); var config = { data: { hidden: false, // 游戏数据可以通过参数控制 grids: [], over: false, win: false, score: 0, highscore: 0, overMsg: '游戏结束' }, onLoad: function() { this.GameManager = new GameManager(4); this.setData({ grids: this.GameManager.setup(), highscore: wx.getStorageSync('highscore') || 0 }); }, onReady: function() { var that = this; // 页面渲染完毕隐藏loading that.setData({ hidden: true }); }, onShow: function() { // 页面展示 }, onHide: function() { // 页面隐藏 }, onUnload: function() { // 页面关闭 }, // 更新视图数据 updateView: function(data) { // 游戏结束 if(data.over){ data.overMsg = '游戏结束'; } // 获胜 if(data.win){ data.overMsg = '恭喜'; } this.setData(data); }, // 重新开始 restart: function() { this.updateView({ grids: this.GameManager.restart(), over: false, won: false, score: 0 }); }, touchStartClienX: 0, touchStartClientY: 0, touchEndClientX: 0, touchEndClientY: 0, isMultiple: false, // 多手指操作 touchStart: function(events) { // 多指操作 this.isMultiple = events.touches.length > 1; if (this.isMultiple) { return; } var touch = events.touches[0]; this.touchStartClientX = touch.clientX; this.touchStartClientY = touch.clientY; }, touchMove: function(events) { var touch = events.touches[0]; this.touchEndClientX = touch.clientX; this.touchEndClientY = touch.clientY; }, touchEnd: function(events) { if (this.isMultiple) { return; } var dx = this.touchEndClientX - this.touchStartClientX; var absDx = Math.abs(dx); var dy = this.touchEndClientY - this.touchStartClientY; var absDy = Math.abs(dy); if (Math.max(absDx, absDy) > 10) { var direction = absDx > absDy ? (dx > 0 ? 1 : 3) : (dy > 0 ? 2 : 0); var data = this.GameManager.move(direction) || { grids: this.data.grids, over: this.data.over, won: this.data.won, score: this.data.score }; var highscore = wx.getStorageSync('highscore') || 0; if(data.score > highscore){ wx.setStorageSync('highscore', data.score); } this.updateView({ grids: data.grids, over: data.over, won: data.won, score: data.score, highscore: Math.max(highscore, data.score) }); } } }; Page(config); 除此之外,还引用了原Web版2048游戏的一些js文件。 包括 游戏管理 game_manager.js 格子管理 grid.js 本地存储管理 local_storage_manager.js 瓦片管理 tile.js 三、程序效果图 四、源代码下载 扫描下方二维码并关注公众账号,回复 “1239” 获取 源代码使用方法,请参考 微信小程序开发入门教程
在这篇微信小程序开发教程中,我们将介绍如何使用微信小程序开发企业内部宣传展示等功能。 一、小程序主体部分 一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下: 1. 小程序逻辑 App({ onLaunch: function() { // Do something initial when launch. }, onShow: function() { // Do something when show. }, onHide: function() { // Do something when hide. }, globalData: 'fangbei' }) 2. 小程序公共设置 主要注册五个页面,设置窗口,以及显示在tabbar中显示三个页面 { "pages": [ "pages/index/index", "pages/news/news", "pages/news/news-details", "pages/product/product", "pages/contact/contact" ], "window": { "navigationBarTextStyle": "black", "navigationBarTitleText": "盛世华安", "navigationBarBackgroundColor": "#fbf9fe", "backgroundColor": "#fbf9fe" }, "tabBar": { "color": "#dddddd", "selectedColor": "#459ae9", "borderStyle": "black", "backgroundColor": "#ffffff", "list": [{ "pagePath": "pages/index/index", "iconPath": "images/index.png", "selectedIconPath": "images/index_selected.png", "text": "公司盛况" }, { "pagePath": "pages/product/product", "iconPath": "images/product.png", "selectedIconPath": "images/product_selected.png", "text": "产品服务" }, { "pagePath": "pages/contact/contact", "iconPath": "images/contact.png", "selectedIconPath": "images/contact_selected.png", "text": "联系我们" }] }, "networkTimeout": { "request": 10000, "connectSocket": 10000, "uploadFile": 10000, "downloadFile": 10000 }, "debug": true } 3. 公用样式表 @import 'style/weui.wxss'; @import "/utils/wxParse/wxParse.wxss"; page { background-color: #fbf9fe; height: 100%; } .container { display: flex; flex-direction: column; min-height: 100%; justify-content: space-between; } .page-header { display: flex; font-size: 32rpx; color: #aaa; margin-top: 50rpx; flex-direction: column; align-items: center; } .page-header-text { padding: 20rpx 40rpx; } .page-header-line { width: 150rpx; height: 1px; border-bottom: 1px solid #ccc; } .page-body { width: 100%; display: flex; flex-direction: column; align-items: center; flex-grow: 1; overflow-x: hidden; } .page-body-wrapper { margin-top: 100rpx; display: flex; flex-direction: column; align-items: center; width: 100%; } .page-body-wrapper form { width: 100%; } .page-body-wording { text-align: center; padding: 200rpx 100rpx; } .page-body-info { display: flex; flex-direction: column; align-items: center; background-color: #fff; margin-bottom: 50rpx; width: 100%; padding: 50rpx 0 150rpx 0; } .page-body-title { margin-bottom: 100rpx; font-size: 32rpx; } .page-body-text { font-size: 30rpx; line-height: 26px; color: #ccc; } .page-body-text-small { font-size: 24rpx; color: #000; margin-bottom: 100rpx; } .page-body-form { width: 100%; background-color: #fff; display: flex; flex-direction: column; width: 100%; border: 1px solid #eee; } .page-body-form-item { display: flex; align-items: center; margin-left: 30rpx; border-bottom: 1px solid #eee; height: 88rpx; font-size: 34rpx; } .page-body-form-key { width: 180rpx; color: #000; } .page-body-form-value { flex-grow: 1; } .page-body-form-value .input-placeholder { color: #b2b2b2; } .page-body-form-picker { display: flex; justify-content: space-between; height: 100rpx; align-items: center; font-size: 36rpx; margin-left: 20rpx; padding-right: 20rpx; border-bottom: 1px solid #eee; } .page-body-form-picker-value { color: #ccc; } .page-body-buttons { width: 100%; } .page-body-button { margin: 25rpx; } .page-body-button image { width: 150rpx; height: 150rpx; } .page-footer { text-align: center; color: #1aad19; font-size: 24rpx; margin: 20rpx 0; } .green{ color: #09BB07; } .red{ color: #F76260; } .blue{ color: #10AEFF; } .yellow{ color: #FFBE00; } .gray{ color: #C9C9C9; } .strong{ font-weight: bold; } .bc_green{ background-color: #09BB07; } .bc_red{ background-color: #F76260; } .bc_blue{ background-color: #10AEFF; } .bc_yellow{ background-color: #FFBE00; } .bc_gray{ background-color: #C9C9C9; } .tc{ text-align: center; } .page input{ padding: 20rpx 30rpx; background-color: #fff; } checkbox, radio{ margin-right: 10rpx; } .btn-area{ padding: 10px 30px; } .btn-area button{ margin-top: 20rpx; margin-bottom: 20rpx; } .page { min-height: 100%; flex: 1; background-color: #FBF9FE; font-size: 32rpx; font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif; overflow: hidden; } .page__hd{ padding: 50rpx 50rpx 100rpx 50rpx; text-align: center; } .page__title{ display: inline-block; padding: 20rpx 40rpx; font-size: 32rpx; color: #AAAAAA; border-bottom: 1px solid #CCCCCC; } .page__desc{ display: none; margin-top: 20rpx; font-size: 26rpx; color: #BBBBBB; } page{ background-color: #F8F8F8; font-size: 16px; font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif; } .page__hd { padding: 40px; } .page__bd { padding-bottom: 40px; } .page__bd_spacing { padding-left: 15px; padding-right: 15px; } .page__ft{ padding-bottom: 10px; text-align: center; } .page__title { text-align: left; font-size: 20px; font-weight: 400; } .page__desc { margin-top: 5px; color: #888888; text-align: left; font-size: 14px; } .swiper { width: 100%; height: 400rpx; } .slide-image { width: 100%; } .news { padding: 26rpx 40rpx 26rpx 40rpx; } .news-title { color: #AAAAAA; } .news-item { margin: 10rpx 0 10rpx 0; background-color: #fff; } .news-item-pic { padding: 20rpx 0 10rpx 20rpx; width: 160rpx; float: left; } .news-item-image { width: 100%; } .news-item-words { width: 450rpx; height: 65px; float: right; overflow-y: hidden; padding: 20rpx 10rpx; } .news-item-title { font-size: 11pt; word-break: keep-all; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .news-item-content { font-size: 8pt; line-height: 13pt; text-overflow:ellipsis; color: #a9a9a9; } .news-more { color: #AAAAAA; font-size: 14px; } .news-more-line { padding-left: -26rpx important; } .news-details-content { padding: 0 40rpx 100rpx 40rpx; } .video { } .video-input { border: 1px solid #CCCCCC; } .contact { padding: 40rpx 40rpx 40rpx 40rpx; } image { height: auto; } 二、业务页面部分 小程序页面主要由以下文件组成。 本项目程序分为4个页面:主页、新闻详情页、产品服务页、联系我们页。 主页部分 主页效果图如下 1. 页面结构 上方是一个图片轮播图,中间是新闻列表,下文有一个查看更多导航 其页面结构代码如下 <!--index.wxml--> <view class="index"> <view class="slider"> <swiper class="swiper" indicator-dots="{{indicatorDots}}" autoplay="{{autoplay}}" interval="{{interval}}" duration="{{duration}}"> <block wx:for="{{swipers}}"> <swiper-item> <navigator url="/pages/news/news-details?id={{item.id}}" class="widget"> <image mode="widthFix" src="{{item.thumbnail_images.medium_large.url}}" class="slide-image" width="" height=""></image> </navigator> </swiper-item> </block> </swiper> </view> <view class="news"> <text class="news-title">新闻动态</text> <block wx:for="{{news}}"> <navigator url="/pages/news/news-details?id={{item.id}}"> <view class="news-item line"> <view class="news-item-pic"> <image mode="widthFix" src="{{item.thumbnail}}" class="news-item-image" width="" height=""></image> </view> <view class="news-item-words"> <view class="news-item-title"><text>{{item.title_plain}}</text></view> <view class="news-item-content"><text>{{item.excerpt_plain}}</text></view> </view> </view> </navigator> </block> <view class="widgets__list widgets__list_show"> <navigator url="/pages/news/news?cat={{cat}}" class="widget_more"> <text class="news-more">查看更多</text> <image class="widget__arrow" src="/images/arrowright.png" mode="aspectFill" /> <view class="widget__line widget__line_first"></view> </navigator> </view> </view> </view> 2. 样式表 样式代码如下所示 .index{ background-color: #FBF9FE; font-family: -apple-system-font,Helvetica Neue,Helvetica,sans-serif; flex: 1; min-height: 100%; font-size: 32rpx; } .head{ padding: 80rpx; line-height: 1; } .body{ padding-left: 30rpx; padding-right: 30rpx; overflow: hidden; } .title{ font-size: 52rpx; } .desc{ margin-top: 10rpx; color: #888888; font-size: 28rpx; } .widgets__item{ margin-top: 20rpx; margin-bottom: 20rpx; background-color: #FFFFFF; overflow: hidden; border-radius: 4rpx; cursor: pointer; } .widgets__info{ display: flex; padding: 40rpx; align-items: center; flex-direction: row; } .widgets__info_show{ } .widgets__info_show .widgets__info-img{ transform: rotate(-90deg); } .widgets__info-name{ flex: 1; } .widgets__info-img{ width: 32rpx; height: 32rpx; transition: transform .4s; transform: rotate(90deg); } .widgets__list{ display: none; } .widgets__list_show{ display: block; } .widget{ position: relative; padding-top: 26rpx; padding-bottom: 26rpx; padding-left: 40rpx; padding-right: 40rpx; } .widget_more{ position: relative; padding-top: 26rpx; padding-bottom: 26rpx; padding-left: 0rpx; padding-right: 40rpx; } .widget__arrow{ position: absolute; top: 28rpx; right: 44rpx; width: 32rpx; height: 32rpx; } .widget__line{ content: " "; position: absolute; left: 40rpx; top: 0; right: 0; height: 2rpx; background-color: #F0F0F0; } .widget__line_first{ left: 0; right: 0; background-color: #D8D8D8; } 3、 页面逻辑处理 页面逻辑也是通过接口取网站的数据,并且存到swipet,news等数据中,供前端显示 var CONFIG = require('../../utils/config.js') Page({ data: { indicatorDots: true, autoplay: true, interval: 5000, duration: 1000, swipers: [], news: [], cat: '17', }, onLoad: function () { var that = this; wx.request({ url: CONFIG.API_URL.GET_INDEX, method: 'GET', data: {}, header: { 'Accept': 'application/json' }, success: function(res) { console.log(res); if (res.statusCode == 200 && res.data.status == 'ok') { var data = res.data; var swipers = []; var news = []; console.log(data); for (var i = 0; i < data.count; i++) { if (i < 3) { swipers.push(data.posts[i]); } else { var excerpt_plain = data.posts[i].excerpt.replace(/<[^>].*?>/g, ""); data.posts[i].excerpt_plain = excerpt_plain.replace(/\[[^\]].*?\]/g, ""); news.push(data.posts[i]); } } that.setData({swipers: swipers}); that.setData({news: news}); } else { } } }) }, onShareAppMessage: function () { // return custom share data when user share. console.log('onShareAppMessage') return { title: '盛世华安', desc: '小程序', path: '/pages/index/index' } }, }); 产品服务页部分 产品服务页和主页的新闻列表页类似 1. 页面结构 其页面结构代码如下 <view class="news"> <text class="news-title">产品服务</text> <block wx:for="{{news}}"> <navigator url="/pages/news/news-details?id={{item.id}}"> <view class="news-item line"> <view class="news-item-pic"> <image mode="widthFix" src="{{item.thumbnail}}" class="news-item-image" width="" height=""></image> </view> <view class="news-item-words"> <view class="news-item-title"><text>{{item.title_plain}}</text></view> <view class="news-item-content"><text>{{item.excerpt_plain}}</text></view> </view> </view> </navigator> </block> </view> 2. 样式表 使用公共样式表。 3、 页面逻辑处理 请求官网接口数据并显示 var CONFIG = require('../../utils/config.js') Page({ data: { }, onLoad: function () { var that = this; wx.request({ url: CONFIG.API_URL.GET_CATEGORY + '14', method: 'GET', data: {}, header: { 'Accept': 'application/json' }, success: function(res) { console.log(res); if (res.statusCode == 200 && res.data.status == 'ok') { var data = res.data; var news = []; console.log(data); for (var i = 0; i < data.count; i++) { var excerpt_plain = data.posts[i].excerpt.replace(/<[^>].*?>/g, ""); data.posts[i].excerpt_plain = excerpt_plain.replace(/\[[^\]].*?\]/g, ""); news.push(data.posts[i]); } that.setData({news: news}); } else { } } }) }, onReady:function(){ // 页面渲染完成 }, onShow:function(){ // 页面显示 }, onHide:function(){ // 页面隐藏 }, onUnload:function(){ // 页面关闭 }, go: function(event) { wx.navigateTo({ url: '/pages/news/news-details?id=' + event.currentTarget.dataset.type }) } }) 联系我们页部分 1. 页面结构 其页面结构代码如下. <import src="../../utils/wxParse/wxParse.wxml"/> <view class="page"> <view class="page__hd"> <text class="page__title"></text> <text class="page__desc"></text> </view> <view class="news-details-content wxParse"> <template is="wxParse" data="{{wxParseData:content.nodes}}"/> </view> </view> 2. 样式表 使用公共样式表。 3、 页面逻辑处理 请求官网接口数据并显示 var CONFIG = require('../../utils/config.js') var WxParse = require('../../utils/wxParse/wxParse.js'); Page({ data: { }, onLoad: function () { var that = this; wx.request({ url: CONFIG.API_URL.GET_PAGE + '36', method: 'GET', data: {}, header: { 'Accept': 'application/json' }, success: function(res) { console.log(res); if (res.statusCode == 200 && res.data.status == 'ok') { var data = res.data; that.setData({page: data.page}); WxParse.wxParse('content', 'html', data.page.content, that, 25) } else { } } }) }, onReady:function(){ // 页面渲染完成 }, onShow:function(){ // 页面显示 }, onHide:function(){ // 页面隐藏 }, onUnload:function(){ // 页面关闭 }, go: function(event) { wx.navigateTo({ url: '/pages/news/news-details?id=' + event.currentTarget.dataset.type }) } }) 三、程序效果图 四、源代码下载 扫描下方二维码并关注公众账号,回复 “1238” 获取 源代码使用方法,请参考 微信小程序开发入门教程
在这篇微信小程序开发教程中,我们将介绍如何使用微信小程序开发热门电影及预览功能。 本文主要分为两个部分,小程序主体部分及电影主页和详情页页面部分 一、小程序主体部分 一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下: 1. 小程序逻辑 App({ onLaunch: function() { // Do something initial when launch. }, onShow: function() { // Do something when show. }, onHide: function() { // Do something when hide. }, globalData: 'I am global data' }) 2. 小程序公共设置 主要注册两个页面,热门电影的主页及详情页 { "pages":[ "pages/index/index", "pages/details/details" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#FF4D64", "navigationBarTitleText": "热门电影", "backgroundColor":"#FFF", "navigationBarTextStyle":"white" } } 二、电影页面部分 小程序页面主要由以下文件组成。 本项目程序分为两个页面:主页及详情页。 主页部分 主页效果图如下 1. 页面结构 其页面结构代码如下 <loading hidden="{{loading}}"> 加载中... </loading> <scroll-view class="container img-content" style="height: {{windowHeight}}px; width: {{windowWidth}}px; " scroll-y="true" bindscrolltoupper="pullDownRefresh" bindscrolltolower="pullUpLoad" lower-threshold="800"> <navigator class="list flex-box" wx:for="{{films}}" url="../details/details?title=navigate&id={{item.id}}&titles={{item.nm}}"> <view class="list-img"><image class="img" src="{{item.img}}"></image><image class="list-play" src="../../images/i-play.png"></image></view> <view class="list-main flex-btn"> <view class="list-title list-brief"> <text>{{item.nm}}</text> <test class="i-imax" wx:if="{{item.imax && item['3d']}}" src="../../tests/i-imax.png">3Dimax</test> <test class="i-imax" wx:elif="{{item['3d']}}" src="../../images/i-play.png">3d</test> <test class="i-imax" wx:elif="{{item['imax']}}" src="../../tests/i-star.png">imax</test> <test class="i-imax" wx:else="{{item['imax']}}" src="../../images/i-stars.png">2d</test> </view> <view class="list-size" wx:if="{{!item.preSale}}"><view class="star"><view style="width: {{item.sc * 10}}%" class="stars"></view></view>{{item.sc}}</view> <view class="list-brief" wx:if="{{item.preSale}}"><text class="wish">{{item.wish}}人想看</text>{{item.showInfo}}</view> <view class="list-brief">{{item.scm}}</view> <view class="list-brief">{{item.dir}} {{item.star}}</view> <view class="list-sale"><text wx:if="{{!item.preSale}}" class="sales">购票</text><text wx:if="{{item.preSale}}" class="pre-sale">预售</text></view> </view> </navigator> </scroll-view> 2. 样式表 样式代码如下所示 /**index.wxss**/ .flex-box{ display: flex; } .flex-btn{ flex: 1; } .list{ border-bottom: 1rpx solid #e5e5e5; padding: 30rpx; } .list-img{ width: 130rpx; height: 180rpx; margin-right: 20rpx; position: relative; } .list-img .img{ width: 130rpx; height: 180rpx; } .list-play{ position: absolute; left: 45rpx; top: 70rpx; width: 40rpx; height: 40rpx; } .list-title{ height: 52rpx; } .list-title text{ font-size: 18px; line-height: 52rpx; color: #000; } .i-imax{ width: 52rpx; height: 28rpx; margin-left: 10rpx; } .list-size{ height: 40rpx; font-size: 14px; color: #8a869e; } .list-size .star{ width: 100rpx; height: 20rpx; background: url(../../images/i-star.png) no-repeat; background-size: 100rpx; display: inline-block; margin-right: 10rpx; } .stars{ width: 100rpx; height: 20rpx; background: url(../../images/i-stars.png) no-repeat; background-size: 100rpx; float: left; margin-right: 10rpx; } .list-brief{ font-size: 12px; line-height: 48rpx; color: #666; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 400rpx; } .list-brief .wish{ color: #108ee9; border-right: 1rpx solid #666; padding-right: 10rpx; margin-right: 10rpx; } .list-main{ position: relative; } .list-sale{ position: absolute; right: 10rpx; top: 70rpx; } .list-sale text{ padding: 10rpx 18rpx; border: 1rpx solid #37b7ff; font-size: 14px; color: #37b7ff; border-radius: 6rpx; } .list-sale .pre-sale{ border: 1rpx solid #fea54c; color: #fea54c; } 3、 页面逻辑处理 //index.js Page({ data: { films: [], limit: 6, loading: false, windowHeight: 0, windowWidth: 0 }, onLoad: function () { this.setData({ loading: false }) }, onShow: function(){ var that = this wx.request({ url: 'http://m.maoyan.com/movie/list.json', //仅为示例,并非真实的接口地址 data: { offset: 0, type: 'hot', limit: that.data.limit }, header: { 'Content-Type': 'application/json' }, success: function(res) { console.log(res.data) that.setData({ films: res.data.data.movies, loading: true }) } }) wx.getSystemInfo({ success: (res) => { that.setData({ windowHeight: res.windowHeight, windowWidth: res.windowWidth }) } }) }, pullDownRefresh: function(e) { this.onLoad() }, pullUpLoad: function(e) { var limit = this.data.limit + 6 console.log(limit) this.setData({ limit: limit }) this.onShow() } }) 这里使用是的猫眼电影的api 其接口为 http://m.maoyan.com/movie/list.json 返回数据如下所示: { "control":{ "expires":1800 }, "status":0, "data":{ "hasNext":true, "movies":[ { "showInfo":"今天64家影院放映1083场", "cnms":0, "sn":0, "late":false, "img":"http://p0.meituan.net/165.220/movie/fbe5f97c016c9f4520109dc70f458d4d83363.jpg", "sc":9.1, "ver":"2D/3D/IMAX 3D/中国巨幕", "rt":"本周五上映", "dur":136, "nm":"银河护卫队2", "showDate":"", "src":"", "vd":"", "dir":"詹姆斯·古恩", "star":"克里斯·帕拉特,佐伊·索尔达娜,戴夫·巴蒂斯塔", "cat":"动作,冒险,科幻", "wish":154543, "3d":true, "pn":188, "scm":"星爵身世迷,终于见爹地", "preSale":0, "imax":true, "snum":41866, "time":"", "id":248683 }, { "showInfo":"今天62家影院放映335场", "cnms":0, "sn":0, "late":false, "img":"http://p0.meituan.net/165.220/movie/aeb864fa21d578d845b9cefc056e40cb2874891.jpg", "sc":9.8, "ver":"2D", "rt":"本周五上映", "dur":140, "nm":"摔跤吧!爸爸", "showDate":"", "src":"", "vd":"", "dir":"尼特什·提瓦瑞", "star":"阿米尔·汗,萨卡诗·泰瓦,法缇玛·萨那·纱卡", "cat":"喜剧,动作,家庭", "wish":27412, "3d":false, "pn":54, "scm":"为圆摔跤梦,女儿不心疼", "preSale":0, "imax":false, "snum":19166, "time":"", "id":588362 }, { "showInfo":"今天63家影院放映256场", "cnms":0, "sn":0, "late":false, "img":"http://p1.meituan.net/165.220/movie/cc50791238502ae1fa08df764c5f5c97223987.jpg", "sc":9.1, "ver":"2D/中国巨幕", "rt":"2017-04-28上映", "dur":120, "nm":"拆弹·专家", "showDate":"", "src":"", "vd":"", "dir":"邱礼涛", "star":"刘德华,姜武,宋佳", "cat":"动作,悬疑,犯罪", "wish":49007, "3d":false, "pn":167, "scm":"爆炸袭击案,拆弹反恐难", "preSale":0, "imax":false, "snum":95491, "time":"", "id":346103 }, { "showInfo":"今天48家影院放映156场", "cnms":0, "sn":0, "late":false, "img":"http://p1.meituan.net/165.220/movie/af297f59e363ce96290dfea22f6fea0c153020.jpg", "sc":9.4, "ver":"2D/3D/IMAX 3D/中国巨幕/全景声", "rt":"2017-04-14上映", "dur":136, "nm":"速度与激情8", "showDate":"", "src":"", "vd":"", "dir":"F·加里·格雷", "star":"范·迪塞尔,杰森·斯坦森,道恩·强森", "cat":"动作,惊悚,犯罪", "wish":320713, "3d":true, "pn":226, "scm":"车王要黑化,家族被击垮", "preSale":0, "imax":true, "snum":899592, "time":"", "id":248700 }, { "showInfo":"今天46家影院放映133场", "cnms":0, "sn":0, "late":false, "img":"http://p1.meituan.net/165.220/movie/ea0131b3e9e40f226c7c2664f6185a3792752.jpg", "sc":8.9, "ver":"2D", "rt":"2017-04-27上映", "dur":107, "nm":"喜欢·你", "showDate":"", "src":"", "vd":"", "dir":"许宏宇", "star":"金城武,周冬雨,孙艺洲", "cat":"喜剧,爱情", "wish":30224, "3d":false, "pn":216, "scm":"美食嘉年华,爱情甜掉牙", "preSale":0, "imax":false, "snum":68306, "time":"", "id":672175 } ] } } 详情页部分 1. 页面结构 页面结构用一个视图显示电影的常用信息,以及一个预览视频的功能。 其页面结构代码如下 <loading hidden="{{loading}}"> 加载中... </loading> <view class="detail flex-box" url=""> <view class="detail-img"><image class="img" src="{{films.MovieDetailModel.img}}"></image><image bindtap="vShow" class="detail-play" src="../../images/i-play.png"></image></view> <view class="detail-main flex-btn"> <view class="detail-title detail-brief"> <text>{{films.MovieDetailModel.nm}}</text> <image class="i-imax" wx:if="{{films.MovieDetailModel.imax}}" src="../../images/i-imax.png"></image> <image class="i-imax" wx:if="{{films.MovieDetailModel.preSale}}" src="../../images/i-imax.png"></image> </view> <view class="detail-brief">{{films.MovieDetailModel.scm}}</view> <view class="detail-brief">{{films.MovieDetailModel.cat}}</view> <view class="detail-brief">{{films.MovieDetailModel.src}} / {{films.MovieDetailModel.dur}}分钟</view> <view class="detail-brief">{{films.MovieDetailModel.rt}}</view> <view class="detail-brief" wx:if="{{films.MovieDetailModel.preSale}}"><text class="wish">{{films.MovieDetailModel.wish}}人想看</text>{{films.MovieDetailModel.showInfo}}</view> <view class="detail-size" wx:if="{{!films.MovieDetailModel.preSale}}"><view class="star"><view style="width: {{films.MovieDetailModel.sc * 10}}%" class="stars"></view></view>{{films.MovieDetailModel.sc}}</view> </view> <image class="bg" src="https://gw.alicdn.com/tps/i4/TB1pa7pJFXXXXX6XFXXwwg20FXX-640-448.png"></image> <video class="{{video}}" autoplay="false" bindended="vHid" src="{{films.MovieDetailModel.vd}}" controls></video> </view> <scroll-view class="details-dra"><view>{{details}}</view></scroll-view> <button type="primary" size="{{primarySize}}" plain="{{plain}}" disabled="{{disabled}}" bindtap="pay">立即购票 </button> 2. 样式表 样式代码如下所示 /**index.wxss**/ .flex-box{ display: flex; } .flex-btn{ flex: 1; } .detail{ border-bottom: 1rpx solid #e5e5e5; padding: 30rpx 30rpx 0 30rpx; overflow: hidden; position: relative; } .video-hide{ display: none; } .video-show{ display: block; position: absolute; width: 750rpx; height: 406rpx; top: 0; left: 0; } .bg{ position: absolute; left: 0; top: 0; width: 750rpx; height: 1048rpx; z-index: -1; } .detail-img{ width: 236rpx; height: 376rpx; margin-right: 20rpx; position: relative; } .detail-img .img{ width: 236rpx; height: 376rpx; } .detail-play{ position: absolute; left: 70rpx; top: 130rpx; width: 80rpx; height: 80rpx; } .detail-title{ height: 70rpx; } .detail-title text{ font-size: 18px; line-height: 70rpx; color: #FFF; } .i-imax{ width: 52rpx; height: 28rpx; margin-left: 10rpx; } .detail-size{ height: 40rpx; font-size: 14px; color: #FFF; } .detail-size .star{ width: 100rpx; height: 20rpx; background: url(../../images/i-star.png) no-repeat; background-size: 100rpx; display: inline-block; margin-right: 10rpx; } .stars{ width: 100rpx; height: 20rpx; background: url(../../images/i-stars.png) no-repeat; background-size: 100rpx; float: left; margin-right: 10rpx; } .detail-brief{ font-size: 14px; line-height: 50rpx; color: #FFF; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; width: 400rpx; } .detail-brief .wish{ color: #FFF; border-right: 1rpx solid #666; padding-right: 10rpx; margin-right: 10rpx; } .detail-main{ position: relative; } .detail-sale{ position: absolute; right: 10rpx; top: 70rpx; } .detail-sale text{ padding: 10rpx 18rpx; border: 1rpx solid #37b7ff; font-size: 14px; color: #37b7ff; border-radius: 6rpx; } .detail-sale .pre-sale{ border: 1rpx solid #fea54c; color: #fea54c; } .details-dra view{ margin: 23rpx; color: #333; font-size: 14px; line-height: 20px; } 3、 页面逻辑处理 //index.js Page({ data: { films: [], loading: false, title: '正在热映', video: 'video-hide', datails: '', windowWidth: 0 }, onLoad: function (options) { var id = 'http://m.maoyan.com/movie/' + options.id + '.json' this.setData({ title: options.titles }) var that = this wx.request({ url: id, //仅为示例,并非真实的接口地址 data: { }, header: { 'Content-Type': 'application/json' }, success: function(res) { console.log(res.data) that.setData({ films: res.data.data, loading: true }) var pages = that.data.films.MovieDetailModel.dra pages = pages.replace(/<.*?>/ig,"") that.setData({ details: pages }) console.log(pages) } }) }, onReady: function(){ var that = this wx.setNavigationBarTitle({ title: that.data.title }) wx.getSystemInfo({ success: (res) => { that.setData({ windowHeight: res.windowHeight, windowWidth: res.windowWidth }) } }) }, pay: function(){ console.log('pay'); wx.requestPayment({ 'timeStamp': '', 'nonceStr': '', 'package': '', 'signType': 'MD5', 'paySign': '', 'success':function(res){ console.log('success'); }, 'fail':function(res){ console.log('fail'); } }) }, vShow: function(){ this.setData({ video: 'video-show' }) }, vHid: function(){ this.setData({ video: 'video-hide' }) } }) 这里使用是的猫眼电影详情的api 其接口为 http://m.maoyan.com/movie/248683.json 其中248683为电影ID 返回数据如下所示: { "control":{ "expires":3600 }, "status":0, "data":{ "MovieDetailModel":{ "cat":"动作,冒险,科幻", "dealsum":0, "dir":"詹姆斯·古恩 ", "dra":"<p>以全新的发烧音乐为背景,银河护卫队将继续他们的冒险,并解开“星爵”彼得·奎尔(克里斯·帕拉特 饰)身世之谜,同时护卫队成员们必须共同作战,守护彼此,保卫护卫队这个大家庭。</p>", "dur":136, "id":248683, "imax":true, "img":"http://p0.meituan.net/165.220/movie/fbe5f97c016c9f4520109dc70f458d4d83363.jpg", "isShowing":true, "late":false, "mk":0, "nm":"银河护卫队2", "photos":[ "http://p0.meituan.net/w.h/mmdb/8c0f7925dc5eac7725b31ebe3d43bfcb4096.jpeg", "http://p1.meituan.net/w.h/mmdb/91cfef170d8d6a8fc12eab5a20b590f36144.jpeg", "http://p1.meituan.net/w.h/mmdb/c49ddd3bcd2bfae834149de5ae937cc66144.jpeg", "http://p0.meituan.net/w.h/mmdb/f013e2d55285caab02873ec5a1947c796144.jpeg", "http://p0.meituan.net/w.h/mmdb/a16addab2c993eed9ec39a344df59c856144.jpeg", "http://p1.meituan.net/w.h/mmdb/62a5468f1062d0a5770e950946e72c4f6144.jpeg", "http://p0.meituan.net/w.h/mmdb/4f34d56d9b319bf4c502a043d682ee276144.jpeg", "http://p0.meituan.net/w.h/mmdb/5705531218da628cff533c316d22b6be8192.jpeg", "http://p1.meituan.net/w.h/mmdb/e67687ad91308b720e8fbba82dab11bf8192.jpeg", "http://p0.meituan.net/w.h/mmdb/27b52dba6932a94f7a06dd4bc645c1818192.jpeg", "http://p1.meituan.net/w.h/mmdb/cf43bd1f446b2871b06aad952e4e21156144.jpeg", "http://p1.meituan.net/w.h/mmdb/5132bc175e4d0655949fd4c11f3e606c6144.jpeg", "http://p0.meituan.net/w.h/mmdb/db3a390c46806873cb896f7a8185e9ac10240.jpeg", "http://p0.meituan.net/w.h/mmdb/a6d2b54c3b4677adbfa4b5144f8967b16144.jpeg", "http://p0.meituan.net/w.h/mmdb/d2951058ecb7d99562baf2cea24521d76144.jpeg", "http://p1.meituan.net/w.h/mmdb/700a0e47b8377f3b97a063543503987c8192.jpeg", "http://p0.meituan.net/w.h/mmdb/3480a419b83b4cce2e5348eeac99c60a10240.jpeg", "http://p1.meituan.net/w.h/mmdb/5314fd2fb5aee9f4b9ae2973189bb0b44096.jpeg", "http://p0.meituan.net/w.h/mmdb/a191b5903f8472a1f453a62c20ce21ff4096.jpeg", "http://p0.meituan.net/w.h/mmdb/ed4bb3e125ba3be4f3fb854706d0734d16384.png" ], "pn":188, "preSale":0, "rt":"本周五上映", "sc":9.1, "scm":"星爵身世迷,终于见爹地", "showSnum":true, "snum":45359, "src":"美国", "star":"克里斯·帕拉特 佐伊·索尔达娜 戴夫·巴蒂斯塔 范·迪塞尔 布莱德利·库珀 迈克尔·鲁克 凯伦·吉兰 庞·克莱门捷夫 西尔维斯特·史泰龙 库尔特·拉塞尔 伊丽莎白·德比齐 克里斯·沙利文 肖恩·冈 汤米·弗拉纳根 劳拉·哈德克 艾伦·史瓦兹 汉娜·戈特斯曼 希尔提·伯恩 本·布劳德 亚历克斯·克莱因 卢克·库克 埃文·琼斯 乔·弗里亚 特伦斯·罗斯摩尔 吉米·尤因 史蒂芬·布莱克哈特 史提夫·阿吉 布隆迪·巴鲁蒂 理查·克里斯帝 罗布·赞比 塞拉·拉乌 Kendra Staub Milynn Sarley 赛斯·格林 莫莉·奎恩 迈克尔·罗森巴姆 罗达·格里菲斯 麦莉·赛勒斯 斯坦·李 大卫·哈塞尔霍夫 Mac Wells Elizabeth Ludlow 瓦耶特·奥莱夫 格雷格·亨利 Damita Jane Howard 杰夫·高布伦 文·瑞姆斯 杨紫琼 弗莱德·加勒 ", "vd":"http://maoyan.meituan.net/movie/videos/854x4807011e019c4ef46239c91f6636435051b.mp4", "ver":"2D/3D/IMAX 3D/中国巨幕", "vnum":47, "wish":154543, "wishst":0 } } } 三、程序效果图 四、源代码下载 扫描下方二维码并关注公众账号,回复 “1237” 获取 源代码使用方法,请参考 微信小程序开发入门教程
什么是小程序?小程序的实质就是webapp,最典型的案例是接入微信的“滴滴打车”。虽然没有下载安装APP,但通过微信完全可以正常使用滴滴打车的服务,需要的定位、支付等底层能力,微信都可以提供。 张小龙希望微信小程序对用户来说,应该是“无处不在、触手可及、随时可用、用完即走”的一种“小应用”,重点在一个“小”字上。那么,低频,非刚需,轻量级、功能单一,不需要调动太多系统级能力的应用似乎更适合小程序。 如图D和H,许多付费的O2O类、生活服务类、桌面工具类、聊天增强工具类以及群管理业务等使用频率不高,功能单一、使用频率低的领域也许会成为一个不错的切入口。这些长尾服务需求频次小又不具备独立成APP的能力,因此选择背靠微信这棵大树才能更好的乘凉。
在这篇微信小程序开发教程中,我们将介绍如何使用微信小程序开发计算器功能。 本文主要分为两个部分,小程序主体部分及计算器业务页面部分 一、小程序主体部分 一个小程序主体部分由三个文件组成,必须放在项目的根目录,如下: 1. 小程序逻辑 App({ onLaunch: function() { // Do something initial when launch. }, onShow: function() { // Do something when show. }, onHide: function() { // Do something when hide. }, globalData: 'I am global data' }) 2. 小程序公共设置 { "pages": [ "page/index/index" ], "window": { "navigationBarBackgroundColor": "#000", "backgroundColor": "#000", "navigationBarBackgroundColor": "#000" }, "networkTimeout": { "request": 10000, "connectSocket": 10000, "uploadFile": 10000, "downloadFile": 10000 }, "debug": true } 二、计算器页面部分 计算器页面主要由以下文件组成。 1. 计算器页面结构 页面结构分为2个主要部分:显示区和键盘区 其中键盘区又分功能键、数字键,及运算键,页面结构如下 <template name="calculator-key"> <button hover-start-time="{{5}}" hover-stay-time="{{20}}" hover-class="calculator-key-hover" data-key="{{className}}" class="calculator-key {{className}}">{{display}}</button> </template> <view class="calculator"> <view class="calculator-display"> <view class="calculator-display-text">{{displayValue}}</view> </view> <view class="calculator-keypad"> <view class="input-keys"> <view class="function-keys" catchtap="onTapFunction"> <template is="calculator-key" data="{{className: 'key-clear', display: clearDisplay ? 'C' : 'AC'}}"/> <template is="calculator-key" data="{{className: 'key-sign', display: '±'}}"/> <template is="calculator-key" data="{{className: 'key-percent', display: '%'}}"/> </view> /*sdf*/ <view class="digit-keys" catchtap="onTapDigit"> <template is="calculator-key" data="{{className: 'key-0', display: '0'}}"/> <template is="calculator-key" data="{{className: 'key-dot', display: '●'}}"/> <template is="calculator-key" data="{{className: 'key-1', display: '1'}}"/> <template is="calculator-key" data="{{className: 'key-2', display: '2'}}"/> <template is="calculator-key" data="{{className: 'key-3', display: '3'}}"/> <template is="calculator-key" data="{{className: 'key-4', display: '4'}}"/> <template is="calculator-key" data="{{className: 'key-5', display: '5'}}"/> <template is="calculator-key" data="{{className: 'key-6', display: '6'}}"/> <template is="calculator-key" data="{{className: 'key-7', display: '7'}}"/> <template is="calculator-key" data="{{className: 'key-8', display: '8'}}"/> <template is="calculator-key" data="{{className: 'key-9', display: '9'}}"/> </view> </view> <view class="operator-keys" catchtap="onTapOperator"> <template is="calculator-key" data="{{className: 'key-divide', display: '÷'}}"/> <template is="calculator-key" data="{{className: 'key-multiply', display: '×'}}"/> <template is="calculator-key" data="{{className: 'key-subtract', display: '−'}}"/> <template is="calculator-key" data="{{className: 'key-add', display: '+'}}"/> <template is="calculator-key" data="{{className: 'key-equals', display: '='}}"/> </view> </view> </view> 2. 计算器样式表 样式代码如下所示 @import "reset.wxss"; page { font: 100 14px 'Roboto'; } .calculator { width: 100%; height: 100vh; background: black; position: relative; box-shadow: 0px 0px 20px 0px #aaa; display: flex; flex-direction: column; box-sizing: border-box; } .calculator-display { background: #1c191c; flex: 1; } /*TODO:解决文本垂直居中问题*/ .calculator-display-text { padding: 0 30px; font-size: 6em; color: white; text-align: right; } .calculator-keypad { display: flex; } .calculator .function-keys { display: flex; } .calculator .digit-keys { background: #e0e0e7; display: flex; flex-direction: row; flex-wrap: wrap-reverse; } .calculator-key-hover { box-shadow: inset 0px 0px 25vw 0px rgba(0,0,0,0.25); } .calculator-key { display: block; width: 25vw; height: 25vw; line-height: 25vw; border-top: 1px solid #777; border-right: 1px solid #666; text-align: center; box-sizing: border-box; } .calculator .function-keys .calculator-key { font-size: 2em; } .calculator .digit-keys .calculator-key { font-size: 2.25em; } .calculator .digit-keys .key-0 { width: 50vw; text-align: left; padding-left: 9vw; } .calculator .digit-keys .key-dot { padding-top: 1em; font-size: 0.75em; } .calculator .operator-keys .calculator-key { color: white; border-right: 0; font-size: 3em; } .calculator .function-keys { background: linear-gradient(to bottom, rgba(202,202,204,1) 0%, rgba(196,194,204,1) 100%); } .calculator .operator-keys { background: linear-gradient(to bottom, rgba(252,156,23,1) 0%, rgba(247,126,27,1) 100%); } .input-keys { width: 75%; } .operator-keys { width: 25%; } 3、 计算器页面逻辑处理 Page({ data: { value: null, // 上次计算后的结果,null表示没有上次计算的结果 displayValue: '0', // 显示数值 operator: null, // 上次计算符号,null表示没有未完成的计算 waitingForOperand: false // 前一按键是否为计算符号 }, onLoad: function(options) { this.calculatorOperations = { 'key-divide': (prevValue, nextValue) => prevValue / nextValue, 'key-multiply': (prevValue, nextValue) => prevValue * nextValue, 'key-add': (prevValue, nextValue) => prevValue + nextValue, 'key-subtract': (prevValue, nextValue) => prevValue - nextValue, 'key-equals': (prevValue, nextValue) => nextValue } }, /* AC操作,一下回到解放前 */ clearAll() { this.setData({ value: null, displayValue: '0', operator: null, waitingForOperand: false }) }, /* 仅清空当前显示的输入值 */ clearDisplay() { this.setData({ displayValue: '0' }) }, onTapFunction: function(event) { const key = event.target.dataset.key; switch(key) { case 'key-clear': if (this.data.displayValue !== '0') { this.clearDisplay(); } else { this.clearAll(); } break; case 'key-sign': var newValue = parseFloat(this.data.displayValue) * -1 this.setData({ displayValue: String(newValue) }) break; case 'key-percent': const fixedDigits = this.data.displayValue.replace(/^-?\d*\.?/, '') var newValue = parseFloat(this.data.displayValue) / 100 this.setData({ displayValue: String(newValue.toFixed(fixedDigits.length + 2)) }); break; default: break; } }, onTapOperator: function(event) { const nextOperator = event.target.dataset.key; const inputValue = parseFloat(this.data.displayValue); if (this.data.value == null) { this.setData({ value: inputValue }); } else if (this.data.operator) { const currentValue = this.data.value || 0; const newValue = this.calculatorOperations[this.data.operator](currentValue, inputValue); this.setData({ value: newValue, displayValue: String(newValue) }); } this.setData({ waitingForOperand: true, operator: nextOperator }); }, onTapDigit: function(event) { const key = event.target.dataset.key; // 根据data-key标记按键 if(key == 'key-dot') { // 按下点号 if (!(/\./).test(this.data.displayValue)) { this.setData({ displayValue: this.data.displayValue + '.', waitingForOperand: false }) } } else { // 按下数字键 const digit = key[key.length-1]; if (this.data.waitingForOperand) { this.setData({ displayValue: String(digit), waitingForOperand: false }) } else { this.setData({ displayValue: this.data.displayValue === '0' ? String(digit) : this.data.displayValue + digit }) } } } }) 三、程序效果图 四、源代码下载 扫描下方二维码并关注公众账号,回复 “1236” 获取 源代码使用方法,请参考 微信小程序开发入门教程
本文介绍如何使用微信小程序开发天气预报功能。 一、项目文件列表 二、小程序配置 使用app.json文件来对微信小程序进行全局配置,决定页面文件的路径、窗口表现、设置网络超时时间、设置多 tab 等。 { "pages":[ "pages/index/index" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "天气预报", "navigationBarTextStyle":"black" }, "networkTimeout": { "request": 10000 }, "debug": true } 由于项目只有一个页面,所以不需要底部tab。另外设置网络请求时间为10秒,并且启用调试模式。 三、小程序逻辑层 首先在common.js中使用获取用户当前地理位置接口获取用户的坐标地址,坐标类型选择gcj02。//获取当前位置坐标 function getLocation(callback) { wx.getLocation({ type: 'gcj02', success: function(res) { callback(true, res.latitude, res.longitude); }, fail: function() { callback(false); } }) } Wx.getlocation调用成功之后,将坐标信息返回给callback函数。失败时将false传给callback函数。获取到坐标之后,再使用百度接口查询天气。相应的查询代码如下所示。 function getWeather(latitude, longitude, callback) { var ak = "";//换成自己的ak,不要用方倍工作室的 var url = "https://api.map.baidu.com/telematics/v3/weather?location=" + longitude + "," + latitude + "&output=json&ak=" + ak; wx.request({ url: url, success: function(res){ console.log(res); callback(res.data); } }); } 在上述代码中,先定义百度接口的ak,再通过拼接参数构造url的其他部分。然后调用 wx.request 请求天气预报数据。接下来把上述接口组合起来,组成给应用层的接口,相应代码如下所示。 function loadWeatherData(callback) { getLocation(function(success, latitude, longitude){ getWeather(latitude, longitude, function(weatherData){ callback(weatherData); }); }); } 最后通过 module.exports对外暴露该接口。代码如下所示。 module.exports = { loadWeatherData: loadWeatherData } 四、小程序页面与视图 在页面文件中,使用 require 将公共代码引入。代码如下所示。 //index.js var common = require('common.js') Page({ data: { weather: {} }, onLoad: function () { var that = this; common.loadWeatherData(function(data){ that.setData({ weather: data }); }); } }) 在页面的Page函数中, data定义为天气的初始化数据,该数据将会以 JSON 的形式由逻辑层传至渲染层。在 onLoad 方法中,使用common中的 loadWeatherData 方法获取天气数据并设置到 UI 上,并将取到的数据使用 setData 方法将它设置到数据层中。在页面的界面实现中,相应的代码如下所示。 <!--index.wxml--> <view class="container"> <view class="header"> <view class="title">{{weather.results[0].currentCity}}</view> <view class="desc">{{weather.date}}</view> </view> <view class="menu-list"> <view class="menu-item" wx:for="{{weather.results[0].weather_data}}" wx:key="*this"> <view class="menu-item-main"> <text class="menu-item-name">{{item.date}} {{item.weather}} {{item.wind}} {{item.temperature}}</text> <image class="menu-item-arrow" src="{{item.dayPictureUrl}}"></image> </view> </view> </view> </view> 最外层是一个 class 为 container 的 View,它的里面放了2个子 View,分别用于存放页面头和页面列表。页面头中存放城市名称和时间。页面列表用于存放最近几天的天气情况。页面的样式表实现如下所示。 .header { padding: 30rpx; line-height: 1; } .title { font-size: 52rpx; } .desc { margin-top: 10rpx; color: #888888; font-size: 28rpx; } .menu-list { display: flex; flex-direction: column; background-color: #fbf9fe; margin-top: 10rpx; } .menu-item { color: #000000; display: flex; background-color: #fff; margin: 10rpx 30rpx; flex-direction: column; } .menu-item-main { display: flex; padding: 40rpx; border-radius: 10rpx; align-items: center; font-size: 32rpx; justify-content: space-between; } .menu-item-arrow { width: 96rpx; height: 96rpx; transition: 400ms; } 上述页面文件和样式表,都是从微信官方Demo中移植而来。最终实现的天气预报小程序效果如图所示。 五、源码下载 扫描下方二维码并关注公众账号,回复 “1235” 获取 源代码使用方法,请参考 微信小程序开发入门教程
在这篇微信小程序开发教程中,我们将向你介绍快速试用和体验微信小程序开发工具和官方示例Demo。 本系列教程将引导你完成如下任务: 下载微信web开发者工具和小程序官方Demo。 添加小程序示例Demo到项目 体验小程序常用组件及接口 第一部分 下载开发者工具和官方Demo 微信小程序开发者工具 为了帮助开发者简单和高效地开发微信小程序,微信官方推出了全新的微信小程序开发者工具,该工具集成了开发调试、代码编辑及程序发布等功能。 下载地址为 windows 64 、 windows 32 、 mac 开发者工具根据操作系统类型选择相应的下载地址 微信小程序官方示例Demo 下载地址 https://mp.weixin.qq.com/debug/wxadoc/dev/demo/demo.zip demo下载后解压即可。 第二章 添加小程序Demo项目 启动开发者工具后,如下图所示 使用微信扫描二维码登录 点击确认登录后,调试类型选择“本地小程序项目” 点再击添加项目 项目配置时 APPID点击“无AppID” 项目名称,可以填“方倍工作室小程序开发入门教程” 项目目录选择官方Demo解压后的地址 最后点击“添加项目”按钮。 第三章 体验官方Demo组件和接口 在上方的手机类型中,将手机型号选择成适合屏幕分辨率大小或自己喜欢的类型,比如iPhone5 在底部的小程序预览窗口中查看点击各组件查看官方自带的类型,以及在接口中体验各种接口的接口能力。 比如在“接口”->"开放接口"->“获取用户信息”中,可以获得当前登录用户的昵称和头像。 第四章 总结 入门教程就这样简单?是的,做为入门来讲,就只有这些东西。但其实里面已经包括很多了。 1. 下载了微信小程序开发者工具,后续开发小程序都要使用这个。 2. 创建了小程序项目,虽然是本地的,但真实的也和这一样。 3. 体验了官方的Demo,并且使用接口获得了用户的个人信息。 接下来该做什么呢?你可以购买微信小程序开发视频,书中包括了微信小程序开发几乎所有的接口讲解,总共内容有40多G,以及为0基础初学者准备的前端开发视频教程。 地址为 https://item.taobao.com/item.htm?id=546144853276 。
获取自己的二维码海报,并推广获得新用户,可获得现金红包。长期有效,每天可领取一次。积分可累计。 当前兑换红包需要积分22分,需要推荐10个新人关注。 一、扫码关注公众账号, 二、在菜单中点击“推广海报赚积分”,将生成一个和自己相关的推广海报 三、将海报保存下来,转发到微信群或朋友圈中 四、朋友通过该二维码关注,你将获得积分,点击菜单“我的积分可以查询” 五、回复“积分换红包”,将获取微信红包兑换资格,审核通过后,将获得一个现金红包。
关键字:微信支付 微信支付v3 沙箱密钥 getsignkey作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3-signkey.html 一、仿真测试系统 为降低商户测试门槛,微信支付团队开发了一套独立的仿真测试系统。该系统根据验收用例金额的不同返回不同的响应报文,以满足商户正常功能测试、安全/异常测试及性能测试的需求。 图1 微信支付仿真测试系统 图1为微信支付仿真测试系统(后简称仿真系统)的简化原理图。仿真系统的API协议与正式API完全相同。商户开发者只需将正式API的调用URL增加一层sandboxnew路径,即可对接到仿真系统。 例如,刷卡支付URL:https://api.mch.weixin.qq.com/pay/micropay 变更为:https://api.mch.weixin.qq.com/sandboxnew/pay/micropay。 仿真系统与生产环境完全独立,包括存储层。商户在仿真系统所做的所有交易(如下单、支付、查询)均为无资金流的假数据,即:用户无需真实扣款,商户也不会有资金入账。代金券同理,沙箱环境中无需商户真实制券与发券,亦不会出现真实扣券情况。验收仿真测试系统的API验签密钥需从API获取: 获取验签秘钥API: 请求Url https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey 是否需要证书 否 请求方式 POST 请求参数: 字段名 字段 必填 示例值 类型 说明 商户号 mch_id 是 1305638280 String(32) 微信支付分配的微信商户号 随机字符串 nonce_str 是 5K8264ILTKCH16CQ2502SI8ZNMTM67VS String(32) 随机字符串,不长于32位 签名 sign 是 5K8264ILTKCH16CQ2502SI8ZNMTM67VS String(32) 签名值 返回参数: 字段名 字段 必填 示例值 类型 说明 返回状态码 return_code 是 SUCCESS String(16) SUCCESS/FAIL 此字段是通信标识,非交易标识 返回信息 return_msg 否 签名失败 String(128) 返回信息,如非空,为错误原因 ,签名失败 ,参数格式校验错误 以下字段在return_code 为SUCCESS的时有返回。 字段名 字段 必填 示例值 类型 说明 商户号 mch_id 是 1305638280 String(32) 微信支付分配的微信商户号 沙箱密钥 sandbox_signkey 否 013467007045764 String(32) 返回的沙箱密钥 商户接入仿真系统的交互流程示例: 1. 商户发起刷卡支付请求,使用POST方式调用 https://api.mch.weixin.qq.com/sandboxnew/pay/micropay 2. 带sandboxnew 的https请求会被nginx路由到仿真系统。仿真系统根据支付金额(total_fee字段)返回预期报文给商户。同时,落地该笔请求数据; 3. 商户发起查单,调用 https://api.mch.weixin.qq.com/sandboxnew/pay/orderquery,带上微信订单号(transaction_id)或商户内部单号(out_trade_no); 4. 仿真系统收到查单请求后,根据单号及金额返回预期的查单结果给商户; 5. 商户下载对账单,调用 https://api.mch.weixin.qq.com/sandboxnew/pay/downloadbill,仿真系统返回固定的账单格式给商户。注:账单内容不一定与商户在仿真系统产生的交易完全相同。 二、沙箱密钥实现代码 使用方倍工作室微信支付全能接口类,几行代码即可实现 返回结果如下
如果用户曾经在该公众号有支付行为,关注的时候EventKey中将包含上次交易订单号,如 last_trade_no_4002752001201704258347703919 <xml> <ToUserName><![CDATA[gh_fcc4da210ff0]]></ToUserName> <FromUserName><![CDATA[oiPuduCHIBb2aHvZoqSm1t7KbXtw]]></FromUserName> <CreateTime>1493702623</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[subscribe]]></Event> <EventKey><![CDATA[last_trade_no_4002752001201704258347703919]]></EventKey> </xml>
方倍工作室在和几千家企业及个人用户软件外包需求的沟通交流中,发现大部分用户都不明白自己的需要什么,也不知道如何来提出自己的需求,现在我们以某企业开发优秀员工评比投票及转发分享得红包功能为例,介绍如何写一份简单易懂的软件外包需求说明书。 一、明确已经有什么 首先自己要知道自己已经有了什么,这是第一步。主要包括公众账号、服务器信息、现有的数据等内容。比如: 公众账号:方倍工作室,类型:服务号,已申请微信认证,已申请微信支付,已申请微信红包及企业付款 [不同的账号类型及功能意味着是否有相应的权限,有权限才能进行相应的开发,没有权限就开发不了,程序不能创建出公众号的权限,只能在已有的权限上开发功能] 服 务 器:新浪云,运行环境:PHP5.3,MySQL5.6 。<不了解这些信息,或者没有服务器的则不填,要求方倍工作室提供即可,报价中则包含服务器费用> 已有数据:公司员工数据,包括员工姓名、手机号、工号、职务名称等。以Excel形式提供。<对于需求和现有数据关联的,必须提供已有的数据信息,并且告知对方提供形式,是以Excel,SQL脚本还是API接口等形式提供。如果没有数据,则开发过程中创建数据库,然后需求方自己录入数据。> 二、明确自己需要什么 分为以下部分。 1. 管理员要有什么功能 功能点1: 功能简介:上传员工数据。 详细说明:管理员登录管理后台之后,可以将Excel导入后台数据库中。 功能点2: 功能简介:创建月评比活动。 详细说明:管理员可以创建下个月的评比活动,并且选择候选员工。 功能点3: 功能简介:查看投票结果。 详细说明:管理员可以查看每月的投票结果。 功能点4: 功能简介:其他基本功能。 详细说明:包括修改后台管理密码等。 2. 公众号接口部分 功能点1: 功能简介:生成菜单。 详细说明:底部菜单按钮中,员工可以点击进入。 功能点2: 功能简介:关键字回复。 详细说明:发送某个关键字,比如“10月”,可以查询该月的评比结果排名。 3. 用户要有什么功能 功能点1: 功能简介:查看当月候选员工列表。 详细说明:员工可以看到当月候选员工列表。 功能点2: 功能简介:投票。 详细说明:员工可以给某个员工进行投票。 功能点3: 功能简介:转发得红包。 详细说明:员工分享投票页面到朋友圈,将得到一个1元钱的微信现金红包。 【上述这些功能,并不需要写得多么详细,但将各种功能类别理清,并且提取出来,是非常重要的个人水平能力,也是一种高效沟通能力的体现】 【另外,如果能做好功能的整理,那么开发方的报价会比较合理,如果自己的功能都无法理清,那么开发方会觉得后续沟通修改的成本可能会较高,从而提高报价。】 三、明确预算 分析出上述需求以后,就需要自己有一个预算。如果是公司项目,就直接问领导大概可以提供多少经费支持。如果是个人项目,就直接估算出一个自己可以出得起的最高价钱。 如何估算外包需求的价值呢? 这需要以一线城市高级程序员工资为参考标准(因为他们代表了被市场认可的高水平与高质量,如果不想被坑的话,就不要找小白),他们的工资在1万~3万之间。日工资在500~1500左右,一个项目无论大小,总有前期的需求沟通、开发实现、调试测试等过程,所以中小型项目在1000~10000是个合理的报价区间,复杂的在项目在几万到几十万也是正常的。对方并没有漫天要价。你的预算不要低于这个最低值。 切忌 不要以自己也是开发人员觉得对方报价贵,然后砍价一半以上,对方觉得你不仅开发能力有问题,而且人品道德有问题,直接将你拉黑。 或者不要说自己是学生没钱,只能出个零头的钱,学生不是不可以找外包,但也需要尊重对方的时间及劳动。
方倍工作室微信公众账号提供网页版定位型漂流瓶功能,可以精确定位到打开标瓶的用户坐标地址。 一位中年男子因和老婆吵架,老婆一气之下离家出走,电话不接,每天发微信也不回,他想通过微信知道老婆在哪。 一位阔太太的老公说在外应酬生意,经常很晚才回来,太太想通过微信知道老公当时到底在哪里,她担心他在外面养了人。 一位年轻的美女为变心不理他的初恋男友付出了很多宝贵的东西,她她不想放弃这段感情,想通过微信定位对方位置,然后去找他。 这是我们曾经碰到的三个真实场景。 1. 关注“方倍工作室”微信公众账号,回复“123”获得定位型漂流瓶创建链接。 2. 选择自己隐私选项,对方信息获取选项,填写信件内容,选择漂流瓶有效时间。 3. 提交订单,确认付款 4. 支付成功后,将收到方倍工作室发来的漂流瓶链接地址。 5. 打开地址,将弹出是否允许公众账号获得地址。 6. 只有“允许”后才能打开漂流瓶,查看到信件内容。以下是显示和不显示自己隐私的信件图。 7. 将其分享给好友或分享到朋友圈,是以下是显示和不显示自己隐私的分享图。 8. 对方打开该信件时,将显示步骤5和步骤6中的页面。 漂流瓶创建者同时收到打开者的位置信息。如图所示,点击个人头像还可以在地图上看到位置。 说明:实际地址与真实地址有一定误差,范围在几十米到数百米左右,这是由手机本身决定的。软件无法控制。
微信web协议分析(微信网页版 wx2.qq.com) 1.打开首页,分配一个随机uuid,2.根据该uuid获取二维码图片。3.微信客户端扫描该图片,在客户端确认登录。4.浏览器不停的调用一个接口,如果返回登录成功,则调用登录接口5.此时可以获取联系人列表,可以发送消息。然后不断调用同步接口。6.如果同步接口有返回,则可以获取新消息,然后继续调用同步接口。 源码地址:https://github.com/biezhi/wechat-robot 执行流程 +--------------+ +---------------+ +---------------+ | | | | | | | Get UUID | | Get Contact | | Status Notify | | | | | | | +-------+------+ +-------^-------+ +-------^-------+ | | | | +-------+ +--------+ | | | +-------v------+ +-----+--+------+ +--------------+ | | | | | | | Get QRCode | | Weixin Init +------> Sync Check <----+ | | | | | | | +-------+------+ +-------^-------+ +-------+------+ | | | | | | | +-----------+ | | | +-------v------+ +-------+--------+ +-------v-------+ | | Confirm Login | | | | +------> Login +---------------> New Login Page | | Weixin Sync | | | | | | | | | +------+-------+ +----------------+ +---------------+ | | |QRCode Scaned| +-------------+ WebWechat API 1. 获取UUID(参考方法 getUUID) API 获取 UUID url https://login.weixin.qq.com/jslogin method GET data URL Encode params appid : wx782c26e4c19acffb fun : new lang: zh_CN _ : 时间戳 返回数据(String): window.QRLogin.code = 200; window.QRLogin.uuid = "xxx" 2. 显示二维码(参考方法 showQrCode) API 显示二维码 url https://login.weixin.qq.com/qrcode/{uuid} method POST params t : webwx <br/> _ : 时间戳 3. 等待登录(参考方法 waitForLogin)这里是微信确认登录 API 二维码扫描登录 url https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login method GET params tip : 1:未扫描 0:已扫描 uuid : 获取到的uuid _ : 时间戳 返回数据(String): window.code=xxx; xxx: 408 登陆超时 201 扫描成功 200 确认登录 当返回200时,还会有 window.redirect_uri="https://wx.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket=xxx&uuid=xxx&lang=xxx&scan=xxx"; 4. 登录获取Cookie(参考方法 login) API webwxnewloginpage url https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage method GET params ticket : xxx uuid : xxx lang : zh_CN scan : xxx fun : new 返回数据(XML): <error> <ret>0</ret> <message>OK</message> <skey>xxx</skey> <wxsid>xxx</wxsid> <wxuin>xxx</wxuin> <pass_ticket>xxx</pass_ticket> <isgrayscale>1</isgrayscale> </error> 在这一步获取xml中的 skey, wxsid, wxuin, pass_ticket 5. 微信初始化(参考方法 wxInit) API webwxinit url https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit method POST data JSON header Content-Type: application/json; charset=UTF-8 params { BaseRequest: { Uin: xxx, Sid: xxx, Skey: xxx, DeviceID: xxx, } } 返回数据(JSON): { "BaseResponse": { "Ret": 0, "ErrMsg": "" }, "Count": 11, "ContactList": [...], "SyncKey": { "Count": 4, "List": [ { "Key": 1, "Val": 635705559 }, ... ] }, "User": { "Uin": xxx, "UserName": xxx, "NickName": xxx, "HeadImgUrl": xxx, "RemarkName": "", "PYInitial": "", "PYQuanPin": "", "RemarkPYInitial": "", "RemarkPYQuanPin": "", "HideInputBarFlag": 0, "StarFriend": 0, "Sex": 1, "Signature": "Apt-get install B", "AppAccountFlag": 0, "VerifyFlag": 0, "ContactFlag": 0, "WebWxPluginSwitch": 0, "HeadImgFlag": 1, "SnsFlag": 17 }, "ChatSet": xxx, "SKey": xxx, "ClientVersion": 369297683, "SystemTime": 1453124908, "GrayScale": 1, "InviteStartCount": 40, "MPSubscribeMsgCount": 2, "MPSubscribeMsgList": [...], "ClickReportInterval": 600000 } 这一步中获取 SyncKey, User 后面的消息监听用。 6. 开启微信状态通知(参考方法 wxStatusNotify) API webwxstatusnotify url https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxstatusnotify method POST data JSON header Content-Type: application/json; charset=UTF-8 params { BaseRequest: { Uin: xxx, Sid: xxx, Skey: xxx, DeviceID: xxx }, Code: 3, FromUserName: 自己的ID, ToUserName: 自己的ID, ClientMsgId: 时间戳 } 返回数据(JSON): { "BaseResponse": { "Ret": 0, "ErrMsg": "" }, ... } 7. 获取联系人列表(参考方法 getContact) API webwxgetcontact url https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxgetcontact method POST data JSON header ContentType: application/json; charset=UTF-8 params { BaseRequest: { Uin: xxx, Sid: xxx, Skey: xxx, DeviceID: xxx, } } 返回数据(JSON): { "BaseResponse": { "Ret": 0, "ErrMsg": "" }, "MemberCount": 334, "MemberList": [ { "Uin": 0, "UserName": xxx, "NickName": "Urinx", "HeadImgUrl": xxx, "ContactFlag": 3, "MemberCount": 0, "MemberList": [], "RemarkName": "", "HideInputBarFlag": 0, "Sex": 0, "Signature": "我是二蛋", "VerifyFlag": 8, "OwnerUin": 0, "PYInitial": "URINX", "PYQuanPin": "Urinx", "RemarkPYInitial": "", "RemarkPYQuanPin": "", "StarFriend": 0, "AppAccountFlag": 0, "Statues": 0, "AttrStatus": 0, "Province": "", "City": "", "Alias": "Urinxs", "SnsFlag": 0, "UniFriend": 0, "DisplayName": "", "ChatRoomId": 0, "KeyWord": "gh_", "EncryChatRoomId": "" }, ... ], "Seq": 0 } 8.消息检查(参考方法 syncCheck) API synccheck url https://webpush2.weixin.qq.com/cgi-bin/mmwebwx-bin/synccheck method GET data JSON header ContentType: application/json; charset=UTF-8 params { BaseRequest: { Uin: xxx, Sid: xxx, Skey: xxx, DeviceID: xxx, } } 返回数据(String): window.synccheck={retcode:"xxx",selector:"xxx"} retcode: 0 正常 1100 失败/登出微信 selector: 0 正常 2 新的消息 7 进入/离开聊天界面 9. 获取最新消息(参考方法 webwxsync) API webwxsync url https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsync?sid=xxx&skey=xxx&pass_ticket=xxx method POST data JSON header ContentType: application/json; charset=UTF-8 params { BaseRequest: { Uin: xxx, Sid: xxx, Skey: xxx, DeviceID: xxx }, SyncKey: xxx, rr: 时间戳取反 } 返回数据(JSON): { 'BaseResponse': {'ErrMsg': '', 'Ret': 0}, 'SyncKey': { 'Count': 7, 'List': [ {'Val': 636214192, 'Key': 1}, ... ] }, 'ContinueFlag': 0, 'AddMsgCount': 1, 'AddMsgList': [ { 'FromUserName': '', 'PlayLength': 0, 'RecommendInfo': {...}, 'Content': "", 'StatusNotifyUserName': '', 'StatusNotifyCode': 5, 'Status': 3, 'VoiceLength': 0, 'ToUserName': '', 'ForwardFlag': 0, 'AppMsgType': 0, 'AppInfo': {'Type': 0, 'AppID': ''}, 'Url': '', 'ImgStatus': 1, 'MsgType': 51, 'ImgHeight': 0, 'MediaId': '', 'FileName': '', 'FileSize': '', ... }, ... ], 'ModChatRoomMemberCount': 0, 'ModContactList': [], 'DelContactList': [], 'ModChatRoomMemberList': [], 'DelContactCount': 0, ... } 10. 发送消息(参考方法 webwxsendmsg) API webwxsendmsg url https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxsendmsg?pass_ticket=xxx method POST data JSON header ContentType: application/json; charset=UTF-8 params { BaseRequest: { Uin: xxx, Sid: xxx, Skey: xxx, DeviceID: xxx }, Msg: { Type: 1 文字消息, Content: 要发送的消息, FromUserName: 自己的ID, ToUserName: 好友的ID, LocalID: 与clientMsgId相同, ClientMsgId: 时间戳左移4位随后补上4位随机数 } } 返回数据(JSON): { "BaseResponse": { "Ret": 0, "ErrMsg": "" }, ... } 更多资料:https://github.com/xiangzhai/qwxhttps://github.com/Urinx/WeixinBothttp://www.07net01.com/2016/01/1201188.htmlhttp://www.cnblogs.com/xiaozhi_5638/p/4923811.html
1. 微信小程序开发视频教程 最新最热门的微信开发创业赚钱技术 微信小程序是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用。小程序所使用的语言是自己的视图层描述语言WXML和WXSS,以及JavaScript。其实WXML和WXSS就是由HTML和CSS衍生出来的语言,只是把前缀换成了WX(微信的拼音首字母)而已,可以说小程序的开发本质上就是前端开发。 根据互联网招聘平台-创猎网发布数据,在北京上海等一级城市、2年工作经验的前端开发工程师,薪水将近1~2.5万。 本视频内容包括前端开发基础视频(适合0基础),及多份小程序开发视频教程。 购买方法:扫描二维码关注后,自动弹出视频列表,然后进入购买 2. 微信公众平台开发视频教程 适合所有人,特别是需要完整学习微信接口开发的人。 内容包括 基础消息原理、各种消息的接收回复,自定义菜单、用户信息、网页授权、参数二维码、群发接口等。使用PHP语言实现。 购买方法:扫描二维码关注后,自动弹出视频列表,然后进入购买 3. 微信商城开发视频教程 适合需要开发微信商城的人,包含PHP框架开发,微信支付等内容。 购买方法:扫描二维码关注后,自动弹出视频列表,然后进入购买 4. 微信商城开发视频教程 适合需要开发微信商城的人,包含PHP框架开发,微信支付等内容。 购买方法:扫描二维码关注后,自动弹出视频列表,然后进入购买
一、书名 这是一本可以解决你90%微信开发问题的书! 本书原名《微信公众平台开发最佳实践(第3版)》,由于新广告法中不允许“最”字,新书名为《微信公众平台开发(从零基础到ThinkPHP5高性能框架实践)》,由三本微信开发畅销书《微信公众平台开发最佳实践(第1版)》、《微信公众平台开发最佳实践(第2版)》、《企业微信公众平台开发》的作者方倍工作室编写。 目前电子版发布在国内专业的电子出版托管平台——看云上,支持微信支付和支付宝支付在线购买。 二、内容 本书分为25章,共计480多节,是IT领域为数不多的宏篇巨著。与前2版相比,内容增加了一倍多不止,并且为初学者准备了程序开发基础的章节,以及为框架开发开发者增加ThinkPHP5的部分。 章节方面,包括微信收发基础消息原理、自定义菜单、用户信息、网页授权和微信WeUI、参数二维码、客服接口与群发接口、微信小店和模板消息、微信JS SDK、微信门店、微信卡券和会员卡、微信支付与微信红包、微信连Wi-Fi、微信摇一摇、微信企业号、微信小程序、微信开放平台以及微信开发实用技巧等所有知识等。 案例选取,我们选择了微信开发项目中最常用以及最难处理的商业项目功能做为案例。很多案例在之前的开发项目中价值数千元。 三、专家推荐 本书是微信技术领域的集大成之作。 本书作者在微信起步之初就紧紧跟随微信技术的发展,通过撰写技术文章提供了详细的技术讲解及疑难分析等获得了千万级的访问量,并因帮助无数开发人员填坑而获得赞誉,作者代码之简洁、理解力之深刻、技术栈之完备令人惊叹。其后相继出版了《微信公众平台开发最佳实践》《微信公众平台开发最佳实践(第2版)》《企业微信公众平台开发实战》等畅销著作蜚声业界,堪称微信开发的“导师”。 本书具备宽宏的视野,从最基础的初学者开发起步及环境配置开始,然后到微信各种消息的接收发送,再囊括了微信各种接口的开发实现及案例实践,最后使用最新最流行的ThinkPHP 5高性能框架与微信项目开发结合做为点晴之笔。以源于文档、高于文档的视角,将各种行业经典案例及常用开发技术和微信完备而科学地联系在一起,全景展示了微信开发的技术脉络及变迁。 本书也是业界最有前瞻性的著作之一,它是第一本介绍微信卡券及会员卡开发的图书、第一本介绍微信小店和微信快递接口的图书、第一本介绍微信连WiFi及微信摇一摇周边的图书、第一本介绍微信企业号和企业微信的图书、第一本介绍微信H5支付及微信红包开发的图书、第一本介绍微信小程序开发的图书之一、第一本介绍ThinkPHP5开发的图书之一。 这部杰出的著作彰显微信在移动互联网领域的重要作用,也见证了微信开发的研究从一个以二次开发技术为主的应用开发,跃迁成为互联网技术研究中的一个主要领域,小程序开发平台的独立就是一个很好的例证。过去已经证明,曾经看轻微信趋势的人已被势不可挡的移动互联网浪潮拍打在岸边上;而未来,顺势而为、拥抱变化,为用户创造价值才能大有所为,我们拭目以待。 四、购买方式 在电脑上,访问看云注册网址,https://www.kancloud.cn/auth/register,页面如下 建议直接使用QQ邮箱注册。 注册成功后,访问本书的主页地址 http://www.kancloud.cn/fangbei/weixin,点击图中的购买按钮 在弹出的页面中,选择支付方式,可选微信支付或支付宝支付 然后在弹出的二维码页面中扫码购买。 购买成功后,就返回http://www.kancloud.cn/fangbei/weixin,阅读即可。 五、源码下载、技术支持、内容更新 本书源码在每章的最后一节中,按照下载地址下载即可。 本书提供技术支持,请在相应章节后方评论片留言。 本书内容将保持更新,一次购买,永久享有。 六、部分购买记录截图
方倍工作室开发了一系列的微信公众平台工具集。 微信基础消息调试器 地址:http://www.fangbei.org/tool/message 功能:调试微信基础消息,包括文本、图文、语音、多图文、位置、菜单、链接等消息的收发。 微信公众号类型检测器 地址:http://www.fangbei.org/tool/typecheck 功能:获取Access Token,并检测是订阅号还是服务号,以及是否认证。 微信自定义菜单生成器 地址:http://www.fangbei.org/tool/menu 功能:一键生成所有类型的菜单。 微信OpenID列表获取器 地址:http://www.fangbei.org/tool/openidlist 功能:获取公众号用户的OpenID列表 微信参数二维码生成器 地址:http://www.fangbei.org/tool/qrcode 功能:生成各种类型的参数二维码 微信短链接生成器 地址:http://www.fangbei.org/tool/shorturl 功能:将长的链接转成短的链接,支持微信支付url转换。 微信消息无限群发器 地址:http://www.fangbei.org/tool/customsend 功能:使用接口给48小时互动用户无限发送消息。 微信素材列表获取器 地址:http://www.fangbei.org/tool/material 功能:获取微信图文素材列表。 微信图片素材转换器 地址:http://www.fangbei.org/tool/image2media 功能:将图片转成MediaID。 微信素材消息群发器 地址:http://www.fangbei.org/tool/masssend 功能:给所有用户群发文本信息。 微信图文编辑器 地址:http://www.fangbei.org/tool/editor 功能:图文素材编辑器,编辑后复制到图文中。 Emoji表情对照表 地址:http://www.fangbei.org/tool/emoji 功能:Emoji表情编码及字符,常用于文本消息回复及菜单名称中。
一、什么是SSL证书? 首先说明SSL(安全套接层,Secure Sockets Layer)是一种安全协议,目的是为互联网通信,提供安全及数据完整性保障。SSL证书遵循SSL协议,可安装在服务器上,实现数据传输加密。 CA(数字证书认证,Certificate Authority)机构,是承担公钥合法性检验的第三方权威机构,负责指定政策、步骤来验证用户的身份,并对SSL证书进行签名,确保证书持有者的身份和公钥的所有权。CA机构为每个使用公开密钥的用户发放一个SSL证书,SSL证书的作用是证明证书中列出的个人/企业合法拥有证书中列出的公开密钥。CA机构的数字签名使得攻击者不能伪造和篡改证书。 SSL证书实际上就是CA机构对用户公钥的认证,内容包括电子签证机关的信息、公钥用户信息、公钥、权威机构的签字和有效期等。 二、SSL数字证书类型及区别 用于网站HTTPS化的SSL数字证书,当前主要分为DV SSL、OV SSL、EV SSL三种类型的证书。 DV SSL数字证书部署在服务器上后,用户浏览器访问网站时,展示如下, OV SSL数字证书部署在服务器上后,用户浏览器访问网站时,展示如下, EV SSL数字证书部署在服务器上后,用户浏览器访问网站时,展示如下, 区别简述如下, 数字证书 DV SSL OV SSL EV SSL 用户建议 个人 组织、企业 大型企业、金融机构 公信等级 一般 高 强 认证强度 网站真实性 组织及企业真实性 严格认证 安全性 一般 中 高 可信度 常规 中 高(地址栏绿色) 三、SSL证书的有什么优势? 对比传统的加密方式,SSL 证书有以下几点优势 1) 简单快捷,只需要申请一张证书,部署在服务器上,就可以在有效期内不用再做其他的操作。 2) 显示直观,部署SSL证书后,通过https访问网站,能在地址栏或地址栏右侧直接看到加密锁标志能直观的表明网站是加密的!使用 EV 证书,甚至能直接在地址栏看到公司名称。 3) 身份认证,这是别的加密方式都不具备的,能在证书信息里面看到网站所有者公司信息,进而确认网站的有效性和真实性,不会被钓鱼网站所欺骗。 四、免费SSL证书 免费SSL证书属于 Domain Validation SSL 或 DV SSL证书。是 WoSign 基础级 (Class 1) SSL证书产品,只验证域名所有权, 无需注册,快速颁发,保证了网站的机密信息从用户浏览器到服务器之间的传输是高强度加密传输的,是不会被非法窃取和非法篡改的。请参考《如何识别 DV SSL 证书》。 请注意: 免费SSL证书仅适合于个人网站或非电子商务网站,不显示单位名称,仅起到加密传输信息的作用,并不能证明网站的真实身份。由于此类只验证域名所有权的低端SSL证书已经被国外各种欺诈网站滥用,企业不推荐电子商务网站选购此类证书,推荐选购 OV SSL证书 或 EV SSL证书。
现金红包发放后会以公众号消息的形式触达用户,不同情况下触达消息的形式会有差别,规则如下: 官方地址 https://pay.weixin.qq.com/index.php/public/cms/content_detail?lang=zh&id=6000
1. 关注回复和常见问答 关注时回复图文,带用户昵称 常用问答包括 Q1、公司介绍? Q2、公司主营业务是什么? Q3、主要产品和服务是什么? Q4、公司售后服务怎么样? Q5、公司地址和联系电话? 等 3. 菜单排列 在线商城 进入购买、我的订单、我的产品、联系客服 趣味功能 在线点歌 关于我们 公司介绍 联系我们 我的产品 2. 在线客服接入 需要企业号 支持 4. 小店设计 订单查询:用户查询自己最近30天之内的订单记录。 实时通知:用户付款成功后,实时通知用户订单详情。 快递查询:已发货的订单,可以查询快递进度。 管理员提醒:管理员可以收到最新的订单通知。 5. 群发 群发素材文章:定时给所有用户群发素材文章 群发图文消息:定时给活跃用户群发图文消息 群发文本消息:定时给活跃用户群发文本消息 群发模板消息:定时给所有用户群发模板消息(需要认证服务号) 6. 门店列表 查看用户最近的门店列表并按距离排序 7. 参数二维码 每个硬件产品上有二维码,扫描后关注关注公众账号,并和产品序列号进行绑定,绑定后可查看自己所有产品的保修状态及售后时限。 对于购买产品的用户,标识专门的Tag,对该群组经常赠送优惠券,发红包,及订单抽奖活动。
一、LNMP的下载 LNMP一键安装包是一个用Linux Shell编写的可以为CentOS/RadHat/Fedora、Debian/Ubuntu/Raspbian/Deepin VPS或独立主机安装LNMP(Nginx/MySQL/PHP)、LNMPA(Nginx/MySQL/PHP/Apache)、LAMP(Apache/MySQL/PHP)生产环境的Shell程序。同时提供一些实用的辅助工具如:虚拟主机管理、FTP用户管理、Nginx、MySQL/MariaDB、PHP的升级、常用缓存组件Redis、Xcache等的安装、重置MySQL root密码、502自动重启、日志切割、SSH防护DenyHosts/Fail2Ban、备份等许多实用脚本。 官方网站为 https://www.lnmp.org/ 最新稳定版本: LNMP 1.3 完整版:http://soft.vpser.net/lnmp/lnmp1.3-full.tar.gz (478MB) 二、LNMP的安装 安装时,MySQL版本选择5.5.48(5.4以上支持utf8mb4),PHP版本选择5.4 也可以根据实际情况选择其他版本。 三、常用配置 1. 安装memcache 命令如下 [root@www.fangbei.org lnmp1.3-full]# ./addons.sh install memcached +-----------------------------------------------------------------------+ | Addons script for LNMP V1.2, Written by Licess | +-----------------------------------------------------------------------+ | A tool to Install cache,optimizer,accelerator...addons for LNMP | +-----------------------------------------------------------------------+ | For more information please visit http://www.lnmp.org | +-----------------------------------------------------------------------+ Which memcached php extension do you choose: Install php-memcache,(Discuz x) please enter: 1 Install php-memcached, please enter: 2 Enter 1 or 2 (Default 1): You choose php-memcache ====== Installing memcached ====== Press any key to install...or Press Ctrl+c to cancel 2. 启用PATH_INFO支持 该功能用于ThinkPHP开发时,URL_MODEL为2时的支持。 网站配置目录 ./usr/local/nginx/conf/vhost/www.fangbei.org.conf 打开并添加如下红包部分 server { listen 80; #listen [::]:80; server_name www.fangbei.org; index index.html index.htm index.php default.html default.htm default.php; root /home/wwwroot/www.fangbei.org; include other.conf; #error_page 404 /404.html; include enable-php.conf; location / { if (!-e $request_filename){ rewrite ^/(.*)$ /index.php?s=/$1 last; } } location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$ { expires 30d; } location ~ .*\.(js|css)?$ { expires 12h; } location ~ /\. { deny all; } access_log off; } 3. 禁用mysql日志 在MySQL数据库中,mysql-bin.000001、mysql- bin.000002等文件是数据库的操作日志,例如UPDATE一个表,或者DELETE一些数据,即使该语句没有匹配的数据,这个命令也会存储到日志文件中,还包括每个语句执行的时间,也会记录进去的。 比如如下 [root@www.fangbei.org /]# cd /usr/local/mysql/var/ [root@www.fangbei.org var]# ll total 29964 drwx------ 2 mysql mysql 4096 Feb 21 17:42 100893722 -rw-r----- 1 mysql root 8477 Feb 21 18:41 www.fangbei.org.err -rw-rw---- 1 mysql mysql 5 Feb 21 18:41 www.fangbei.org.pid -rw-rw---- 1 mysql mysql 18874368 Feb 21 18:41 ibdata1 -rw-rw---- 1 mysql mysql 5242880 Feb 21 18:41 ib_logfile0 -rw-rw---- 1 mysql mysql 5242880 Feb 21 17:08 ib_logfile1 drwx------ 2 mysql mysql 4096 Feb 21 17:08 mysql -rw-rw---- 1 mysql mysql 27735 Feb 21 17:08 mysql-bin.000001 -rw-rw---- 1 mysql mysql 1113246 Feb 21 17:08 mysql-bin.000002 -rw-rw---- 1 mysql mysql 264 Feb 21 17:08 mysql-bin.000003 -rw-rw---- 1 mysql mysql 1119 Feb 21 17:08 mysql-bin.000004 -rw-rw---- 1 mysql mysql 126 Feb 21 17:08 mysql-bin.000005 -rw-rw---- 1 mysql mysql 127076 Feb 21 18:41 mysql-bin.000006 -rw-rw---- 1 mysql mysql 107 Feb 21 18:41 mysql-bin.000007 -rw-rw---- 1 mysql mysql 133 Feb 21 18:41 mysql-bin.index drwx------ 2 mysql mysql 4096 Feb 21 17:08 performance_schema [root@www.fangbei.org var]# 以及 [root@www.fangbei.org var]# cd /root [root@www.fangbei.org ~]# ll total 491064 drwxr-xr-x 4 mysql mysql 4096 Feb 21 16:44 databases_backup_20170221164407 drwxr-xr-x 7 root root 4096 May 27 2016 lnmp1.3-full -rw-r--r-- 1 root root 500932095 Dec 4 12:32 lnmp1.3-full.tar.gz -rw-r--r-- 1 root root 1898084 Feb 21 17:18 lnmp-install.log [root@www.fangbei.org ~]# cd databases_backup_20170221164407/ [root@www.fangbei.org databases_backup_20170221164407]# ll total 21284 drwx------ 2 mysql mysql 4096 Feb 21 16:38 100893722 -rw-r----- 1 mysql root 4654 Feb 21 16:44 www.fangbei.org.err -rw-rw---- 1 mysql mysql 10485760 Feb 21 16:44 ibdata1 -rw-rw---- 1 mysql mysql 5242880 Feb 21 16:44 ib_logfile0 -rw-rw---- 1 mysql mysql 5242880 Feb 21 16:02 ib_logfile1 drwx------ 2 mysql mysql 4096 Feb 21 16:02 mysql -rw-rw---- 1 mysql mysql 19758 Feb 21 16:02 mysql-bin.000001 -rw-rw---- 1 mysql mysql 765307 Feb 21 16:02 mysql-bin.000002 -rw-rw---- 1 mysql mysql 263 Feb 21 16:02 mysql-bin.000003 -rw-rw---- 1 mysql mysql 731 Feb 21 16:02 mysql-bin.000004 -rw-rw---- 1 mysql mysql 125 Feb 21 16:02 mysql-bin.000005 -rw-rw---- 1 mysql mysql 497 Feb 21 16:44 mysql-bin.000006 -rw-rw---- 1 mysql mysql 114 Feb 21 16:11 mysql-bin.index [root@www.fangbei.org databases_backup_20170221164407]# 这些文件的生长速度是很快的,特别占用服务器资源。当服务器资源不够充足的情况下,我们可以选择定期删除这些日志文件,或者修改配置文件,不让日志生成。 编辑my.cnf 文件,命令:vi /etc/my.cnf注释掉 log-bin=mysql-bin 这个属性 #skip-networking max_connections = 500 max_connect_errors = 100 open_files_limit = 65535 # log-bin=mysql-bin binlog_format=mixed server-id = 1 expire_logs_days = 10 然后删除上述日志文件 4. phpMyAdmin超时问题 文件 home/wwwroot/default/phpmyadmin/libraries/config.default.php 设置 Cookies 有效期为12小时 $cfg['LoginCookieValidity'] = 43200; //12个小时 设定PHP session有效期的参数值 session.gc_maxlifetime 为大于12小时的秒数。下述配置多了10秒。 文件在./usr/local/php/etc/php.ini session.gc_maxlifetime = 43210 5. phpMyAdmin输入服务器地址 修改phpMyAdmin目录下的 /libraries/config.default.php中 AllowArbitraryServer 值为 true $cfg[‘AllowArbitraryServer’] = true; 9. 重启 最后重启 lnmp restart,让上述所有配置生效 10. 删除.user.ini文件 LNMP 1.2开始PHP防跨目录限制使用.user.ini,该文件在网站根目录下,可以修改open_basedir的值来设置限制目录的访问。.user.ini文件无法直接修改,而且是隐藏文件可能在winscp下可能无法看到。 当网站被删除的时候,.user.ini可以用以下方法删除 [root@www.fangbei.org]# chattr -i ".user.ini" [root@www.fangbei.org]# chmod 777 ".user.ini" [root@www.fangbei.org]# rm ".user.ini"
关键字:微信公众平台 二维码 海报作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/weixin-poster.html 本文介绍微信公众平台下二维码海报的开发过程。 一、微信二维码海报介绍 微信二维码海报是指在海报中嵌入和微信用户关联的参数二维码的海报,用户分享推广之后,新用户可以被统计为被推广人员数,从而达到增加粉丝的传播效果。其使用场景如下: 二、开发流程 在微信二维码海报生成中,需要用到以下信息 1. 自定义菜单中设置一个菜单项,点击后返回二维码海报给用户 2. 接口接收到菜单点击之后,获取用户的头像、ID(可以使用OpenID) 3. 生成和用户关联的参数二维码, 4. 将参数二维码进行缩放 5. 将头像和参数二维码合并成新的参数二维码图片 6. 将新参数二维码图片做为水印合成到背景海报中 7. 将用户昵称,以及二维码时间戳(类型为临时二维码时)等文字合成到背景海报中 8. 将海报上传成临时图片素材 9. 将图片素材使用客服接口发送给用户。 三、微信素材准备 海报底图如下 3.1 生成自定义菜单 菜单的生成方法,请参考《微信公众平台开发(58)自定义菜单》以及方倍工作室的书籍《微信公众平台开发最佳实践(第2版)》 本项目中使用的菜单JSON为 { "button": [ { "name": "我", "sub_button": [ { "type": "click", "name": "我的海报", "key": "POSTER" }, { "type": "view", "name": "推广二维码", "url": "http://nine.doucube.com/home/scene/index" }, { "type": "click", "name": "免费路由器", "key": "ROUTER" } ] }, { "name": "扫码发图", "sub_button": [ { "type": "scancode_waitmsg", "name": "扫码带提示", "key": "rselfmenu_0_0" }, { "type": "scancode_push", "name": "扫码推事件", "key": "rselfmenu_0_1" }, { "type": "pic_photo_or_album", "name": "拍照或相册发图", "key": "rselfmenu_1_1" } ] }, { "name": "发送位置", "type": "location_select", "key": "rselfmenu_2_0" } ] } 3.2 获取用户基本信息 使用方倍工作室SDK获取用户基本信息的方法如下 //获取用户信息 $userinfo = $weixin->get_user_info($openid); var_dump($userinfo); //获取用户头像 64像素 $headimgurl = substr($userinfo['headimgurl'],0,strripos($userinfo['headimgurl'], "/"))."/64"; var_dump($headimgurl); // $headimgurl = "http://wx.qlogo.cn/mmopen/R9V6295VOlibNsicszoREqUF2CiaY8hL5fFt0D8DykUCjJ8ia4rQicbYViax3A2V0am2oUEWvw5awGia0tmwQEbI0tAu4kkCL7Eiaeia7/64"; 需要注意的是,用户默认头像是640像素的大图,将其切换成64位像素大小,以便放置在二维码中间。 同样的,用户基本信息的获取方法,请参考《微信公众平台开发(76) 获取用户基本信息 》以及方倍工作室的书籍《微信公众平台开发最佳实践(第2版)》 用户头像信息如下所示 3.3 生成参数二维码 使用方倍工作室SDK获取用户基本信息的方法如下 //创建永久二维码,参数为用户openid $qrcodeinfo = $weixin->create_qrcode("QR_LIMIT_STR_SCENE", $openid); var_dump($qrcodeinfo); $qrcodeurl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=".urlencode($qrcodeinfo["ticket"]); var_dump($qrcodeurl); // $qrcodeurl = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQHf7zoAAAAAAAAAASxodHRwOi8vd2VpeGluLnFxLmNvbS9xL05rUGlyTXJsd2hxN3BCUnFNbTlNAAIEu1X8VwMEAAAAAA%3D%3D"; 参数二维码可以考虑使用永久字符串的,也可以考虑使用临时数字,临时数字优点没有上限限制,缺点是有有效期。永久的则相反。 同样的,参数二维码的获取方法,请参考《微信公众平台开发(83) 生成带参数二维码》以及方倍工作室的书籍《微信公众平台开发最佳实践(第2版)》 参数二维码如下所示 四、微信二维码海报生成 4.1 二维码缩放 微信二维码默认是430像素,将其缩放成300像素,核心代码如下 imagecopyresampled($qrcode_thumb, $qrcode_source, 0, 0, 0, 0, 300, 300, 430, 430); 4.2 头像合成到二维码图片上 核心代码如下 imagecopy($qrcode_thumb, $head_source, 118, 118, 0, 0, 64, 64); 合成后,效果如下 4.3 二维码合成到海报中 核心代码如下 //加水印 imagecopy($dst_qr, $qrcode_thumb, 212, 410, 0, 0, 300, 300); //水印位置 4.4 文字合成到海报中 核心代码如下 imagettftext($dst_qr, 30, 0, 40, 85, $textcolor, $font, $text); 合成后效果如下 五、素材上传与发送 5.1 上传临时图片素材 使用方倍工作室SDK上传图片素材的方法如下 //将图片上传临时图文素材 $material = $weixin->upload_temporary_material("image", $filename); //logo.jpg须放于类同目录,注意路径 var_dump($material); $mediaid = $material["media_id"]; // array(3) { ["type"]=> string(5) "image" ["media_id"]=> string(64) "21Lz-eMFoSsA_R5gLOUJOqxbGw6YEEPRQq-UjHVbU6q64VyUBUqt7B8252ySPKdt" ["created_at"]=> int(1487213817) } 上传后,获得图片的media_id 5.2 使用客服接口发送图片 使用方倍工作室SDK发送图片的方法如下 //客服接口发送临时图片素材 $send_result = $weixin->send_custom_message($openid, "image", array('media_id'=>$mediaid)); var_dump($send_result); 六、演示 关注方倍工作室微信公众账号,点击菜单“我的海报” 六、源码 SDK付费提供, 100元、联系QQ 1354386063 七、其他 需要完整系统,1000元/年,请看 微信场景二维码关注及统计管理系统
我有一个阿里云9折优惠码:r9lt3v,分享给你,第一次购买云服务器或云数据库可享受原价9折优惠,还可多人使用,拿走不谢。
今天,1 月 9 日,小程序正式发布,用户可以体验到各种各样的小程序,从 8 月中旬写了《别开发 app 了》后,我对小程序和微信的观察没有停止过,通过外部的观察以及和一些业内朋友交流,我逐渐清晰地推导出,微信到底想用小程序干什么,以及从小程序当中,我们能看到哪些可用创业的场景。 1 小程序的定位在变化? 1 年前的微信公开课,张小龙提出要做应用号,经过 8 个月的研发,小程序(应用号)开始内测。如果你有观察从内测至今微信小程序提供的 API、后台功能等的变化,你会发现,似乎过去 2 个月微信团队做的事比之前 8 个月还要多。 微信团队有 1000 多人,参与小程序项目的人也至少有二三十人,如果这是一个创业公司的项目,显然一年的开发周期太长了。况且,微信团队已经有数年做公众平台的经验,这样一个平台,如果纯开发,可能一两个月就能完成。 是什么原因导致 1 年后才发布当初被外界期待万分的应用号? 我的理解是,微信团队也在推演小程序的定位,在过去一年,尤其是内测前的 8 个月,他们可能推翻了多个版本。 1.1 给服务号接棒的小程序 虽然服务号上诞生了招商银行、朝夕日历、助理来也、Yoli 口语等优秀的服务号,但不可否认的是,服务号生态远远没有订阅号的繁荣。 我们能轻松查到,像一条、二更、新世相等公司,通过运营订阅号,获得了丰厚的融资,订阅号领域也出现了很多周边服务,比如 WeMedia,这家为订阅号提供服务的公司已经在新三板上市;比如新榜,这家公司汇聚了非常多的订阅号数据。 前面提到的 3 个订阅号,他们初期只做了订阅号,获得了投资,但你几乎没有听到多少公司是「只」做了服务号,然后做得不错而获得投资。 虽然我们不能只从一小部分产品获得融资的情况去判断某个平台是否足够繁华,但毋庸置疑的是,整个订阅号生态被曝光、被投资的总量相对服务号多了几个数量级。 如果订阅号是微信无心插柳缔造了一个新的创业生态,那么服务号显然是微信想仿照订阅号的路线,把内容之外的东西,也连接到微信,这些内容之外的东西,就是服务。 可惜的是,服务号发展得远远没有订阅号好,但微信从战略层面上,是希望连接一切的,如果服务号没有很好地解决「微信连接一切」的目的,是否应该有新的产品来完成这个使命? 我相信,这是小程序(应用号)诞生的背景之一,它要接棒服务号,连接更多服务和场景。 1.2 连接新场景的小程序 利用小程序提供的框架和 API,开发出来的程序体验是优于 HTML5 的,于是在 9 月底刚开始内测时,业界就出现了很多争论,包括小程序会不会替代 HTML5,会不会替代 app。这些讨论都是脱离场景的。 如果说 App 会被替代,它肯定不是被小程序替代,而是被微信替代,因为我们在微信里已经能找到 90% 以上的常用服务,完全不需要去下载一个 app。 不久前,张小龙朋友圈发了这张照片: 照片中你能看到,在安卓系统里,小程序能直接「钉在」桌面,就像一个 app 那样。仔细观察这张图,你会发现大多数都是中大型公司的产品,比如去哪儿、猫眼、携程、海航等。 如果我们认同,张小龙分享的照片,代表了当时微信对小程序的期待,那么,当时小程序的定位就是要替代原生 app,让用户在微信里就能瞬间获得服务。 然而,在微信公开课上,他却举了这样两个小程序的例子: 在公交车站,你扫一下公交站牌的二维码就可以了解下一辆公交车到站的时间 在汽车站,扫一下汽车站的二维码就可以购买车票,而不需要排长队 如果我们认同,张小龙的演讲,代表了当时微信对小程序的期待,那么,这个时候,小程序的定位其实是连接更多线下场景。 我相信,过去一年,张小龙本人也好,小程序团队也好,都在不断思考和推演,小程序到底要解决哪些需求,满足哪些场景的需要。从最新在外界看到的信息来看,似乎,小程序希望更多地连接线下。 1.3 既替代服务号又连接新场景的小程序 实际上,从功能角度,小程序替代一些低频的 app 和体验不佳的服务号是合情合理的,不管从哪个角度来看,对开发者有好处,对微信也有好处。 另一方面,线下仍有很多未被连接的场景,微信期待用小程序去连接这些场景,战略上,也是符合逻辑的。 外界对小程序的期待不断在变化,微信对小程序的定位,也一直在推演。从外部看到的信息来看,微信似乎更偏向于连接线下。 为什么? 2 小程序想要连接一切 2014 年 11 月,马化腾在「世界互联网大会」上提出腾讯要「连接一切」,要成为互联网连接器。 毫无疑问,连接一切的重任落在了微信身上。 何为连接一切? 连接人与人 连接人与服务 连接人与商业 连接人与物品 人与人之间的连接,第一个版本的微信已经实现,目前,微信已经有超过 8 亿的日活用户,几乎每个有手机的中国人,已经被微信连接。 人与服务的连接,也基本上通过服务号和微信内置的服务连接起来。这里所说的服务包括了内容。我们可以在微信里完成阅读、购物、娱乐等。 人与商业的连接,一个层面是建立在服务上,另一个层面是建立支付手段上,从这个角度,微信也已经连接了商业。 然而,物品仍然没被连接。 一张桌子、一支笔、一台空调、一辆公交车、一只狗……都没有通过微信与人产生连接。 微信以及腾讯的野心是要连接一切,但世界上仍然有很多物品没有被电子化,没有被电子化意味着无法被连接起来。 怎么办? 过去几年,我们看到很多「智能设备」出现,很多创业公司强行把芯片塞进手表、空调、自行车、水杯、台灯等现实世界的物品里,然后通过手机的 app 与这些物品产生连接。 似乎这是解决人与物品连接的好方法,然而,我们不可能在所有现实世界的物品里都塞上一块芯片,那么,这些物品该如何被连接起来? 一种很容易想到的思路是,利用图像识别和 AR 技术,通过摄像头,把现实世界的物品一一识别,就像以下这张「科幻」图片一样: 然而,如果你玩过最近支付宝推出的 AR 红包,你会发现,计算机还远远不能精准识别物理世界的物品,换个角度、变换一下光线,就会出现识别误差,我们也不可能花时间让机器 360 ° 扫描所有物品。 那么,在当前技术条件下,实现人与物品连接的「折中」解决方案有可能是什么? 二维码 设想一张桌子、一支笔、一台空调、一辆公交车、一只狗……上面都有一个二维码,通过扫码,我们能进入相应的服务,比如桌子的二维码告诉你桌子的产地,公交车的二维码告诉你下一辆车什么时候到你不用着急挤上去,狗身上的二维码记录了你与它之间的回忆…… 似乎,通过一张简单的黑白二维码,我们就能轻易把现实世界的物品「拉到」电子世界中去。二维码成为了现实世界和电子世界的超链接。 你可能会问,难道 AR 不是更好的解决方案么?二维码那么丑。可是,刚才说了,图像识别技术并不成熟;难道用 NFC 芯片不是更好的解决方案么?每个物品都贴一个 NFC 芯片不更方便么?况且 NFC 成本那么低。可是,二维码的成本更低,而且,不是每一台手机都能识别 NFC,但可能中国每台手机,都有能识别二维码的程序 — 微信也好,支付宝也好。 所以二维码成为了当前技术条件下,最有可能实现人与物品连接的「技术」手段。二维码的背后,可以是信息,也可以是服务,微信希望用小程序来承载这些信息和服务。 从某种角度上来说,小程序就是微信尝试通过二维码连接物理世界的实验田。 这就能解释,为什么张小龙举的两个例子,都是线下的场景。 其实,从小程序的功能限制上,也能看出这个偏向性。 3 人为的线上导流限制 微信小程序无法分享到朋友圈,甚至无法通过长按二维码进入,也就是说,即使你在一个网页或一篇订阅号的文章里放上小程序的二维码,用户还是无法长按打开小程序。 用户只能通过: 线下扫码 搜索 朋友分享 来打开小程序。 微信人为地限制了小程序的线上导流,通过主动搜索进入,量显然不会特别大,朋友之间的分享,扩散的速度也有限,可以说,微信在逼迫开发者尝试线下的导流渠道。 这与微信想通过二维码连接现实世界的战略是具有一致性的。 4 为什么是线下? 如果前面的论述是正确的,那么,小程序的出现,要解决的就不是 HTML5 的体验问题,没错,它是提高了网页应用的体验,但更多地,它是要解决商业问题。 过去 1 年,我不少创业圈的朋友都感叹,五六年前,做一个纯线上的产品,可能能养活一家公司甚至上市,但如今,开发一个纯在线的产品,比如社区、比如工具、比如内容,已经没有多少生存空间了。 App 的世界已经趋于饱和,我们几乎可以在 App Store 找到各种各样满足不同需求的 app,每个 app 都在互相竞争用户的时间,线上的竞争如此激烈,一个新网站或新 app,可能一年只能获得一个用户 10 秒的使用时间。 面对这样的现状,作为一个创业者,如何才能获得更多的用户时间? 设想这样一个图景,你的创业项目是一本书,你最大的期望是希望用户把书读完。然而,用户在阅读时,可能一边还在看微信,一边在看综艺节目,一边还在吃着薯片,可能一个微信通知,就让用户离开了阅读状态,「专注」地去回复微信,你的用户时间被微信「抢走」了。那么,如果你有权力,可以把用户都关在一个密闭的小房间里,并且能取走他们身边所有电子设备和零食,只给他们一本书,他们可能一两天就能把一本书看完。在这个小房间里,用户的时间都是你的。又或者,你的书有足够大的吸引力,能持续占有用户的关注度,用户也可能很快地把书读完。再或者,你能证明,读完你的书,用户能马上走上通往财务自由之路,用户也可能很快把书看完。 在这个图景里,书是你的产品,小房间是场景,吸引力就是你提供的精细服务。 在线上,我们已经很难把用户装进一个「小房间」里,让它只能看书,因为面对屏幕时,用户有太多选择。 但在线下,用户的时间是可以被某个线下场景独占的,比如等公交时,被公交站独占,吃饭时,被餐馆独占,那么,如果在这些用户时间被独占的场景,提供最适合这个场景的服务,是否更容易让用户从微信、从手游中离开,去使用这个服务? 也就是说,与线下的场景分享它所占有的用户时间是有可能的。 就像张小龙在演讲中提到的,如果你去到长途客运站,刚好你看到有个二维码可以扫码购买车票,显然在这种场景下,你扫码的可能性会比在线上时高,这样,就相当于你原本被客运站独占了时间,这个购票产品,在这个场景里,与客运站分享了你的时间。 这样一种场景化的推广方式,是否比在线上投放一个广告更容易获得用户?实际上,线上推广的成本已经奇高无比,而且往往很多推广带来的都只是一次性的用户,不少创业者已经在思考如何通过线下场景化的方式更低成本地获客。 小程序主推线下场景,除了带着腾讯「连接一切」的目的,其实也迎合了挖掘线下流量的趋势。 5 小程序想要最短服务路径 微信试图用小程序来重新定义服务路径的长度。 过去几个月,业界一直在讨论微信对小程序的定义:即用即走、触手可及。这一度让开发者疑惑,因为如果微信你期待我做的产品是即用即走的,那为什么我要开发小程序?难道产品不应该想方设法粘住用户么? 这种疑惑,是因为很多人把眼光放到了「即走」上面。事实上,好的产品用户自然会回来使用,不必花小伎俩留住用户,就像 Google,你不会因为它给你提供了精准的搜索结果「即用即走」了然后再也不用,相反,下次想搜索时,你还是会打开 Google。所以问题就变成,我们怎样才能让用户判断我们的产品是好产品? 用户的时间很宝贵,要让用户第一次使用就喜欢我们的产品,显然要让用户在最短时间里感受产品的核心,判断是不是他想要的,而不是: 打开 app,默认看几秒钟广告 第一次使用需要花时间注册 功能层层堆叠,难以查找 就像写文章一样,如果读者没有在短时间内判断文章的价值,他就可能停止阅读。 所以,如果我们做的产品确实是好产品,问题回到了「即用」上面,如何让用户马上感受产品的好? 答案是 — 建立最短路径。 如果我们认同,帮用户节省时间的产品是好产品,那么,服务号就不是一个好产品。 我明明只是想买一张汽车票,我需要扫码关注一个买票的服务号,关注后我需要花时间寻找买票的菜单,然后可能还需要注册才能完成支付。为什么不能扫码后直接购买?为什么要先关注?为什么不能在武汉扫码就默认选择武汉出发的票,在北京南站扫码就默认选择北京南站? 小程序没有关注功能,它所期待的,是用户扫码后立即获得服务,就像张小龙在演讲时举的例子,扫码后立即购票,不用关注,也不用花时间寻找购买按钮,甚至,扫码后自动用微信帐号登录,连注册的时间也节省下来。 相比之下,小程序比服务号更节省用户时间,缩短了用户获得服务的路径。用户在整个过程中是畅快且愉悦的,当他下一次需要服务时,自然会想起曾经「即用」过的产品。 从这个角度,我们可以推断,微信之所以要逐渐用小程序替代服务号,是因为服务号并没有为用户建立比 app 更快的服务路径,没有节省用户时间。 6 场景化的最短路径 脱离场景讲缩短路径是耍流氓,不妨举几个例子。 6.1 线下场景 一个小程序能生成 10000 个带参数二维码,用户通过不同的二维码可以进入同一个小程序不同的页面。 拿前面公交车的例子举例。假设某个城市,每一个公交站的每一路车的站牌上都贴了不同的二维码,在等车的乘客扫某路车的二维码,就可以知道该路车的位置以及预计到达时间。 如果拿服务号来做,也能生成带参数二维码,但用户依然需要点击关注和点对应的链接进入公交车的页面。如果拿 app 来做,除了需要下载之外,我们还需要输入想查找的公交车号码。 显然,小程序在等车这个场景中,缩短了用户获得信息的路径。用户将会更喜欢。 你可能会说,上面说的,用 HTML5 不也可以实现么?每一路车不就是一个不同的 URL 么?是的,但在这个场景里,HTML 的体验远远没有小程序优秀。 所以,小程序可以缩短线下场景的服务路径。 6.2 社群场景 在《小程序的想象力》这篇文章里,我曾经说过,微信小程序是适合做垂直社交产品的。 你会发现,不管哪个产品里,但凡我们跟其他人建立了联系,几乎都会交换微信号,然后就在微信里继续聊,而很少回到原来的产品。 因为我们的社交关系已经被微信牢牢握住。然而,每个人都有垂直社交的需求,比如,我喜欢看赛车,所以想跟其他喜欢看赛车的人交流;他喜欢旅游,想和其他驴友交流心得;A 和 B 都是冯大辉的粉丝,他们想和其他大辉粉一起交流…… 过去大半年,你会发现大辉经常在公众号推他的小道消息读者群,最初,这个读者群是基于另一个 app 的,后来,这个 app 出了微信网页版。 你可以很容易想象,从公众号导流到一个 app 是很不容易的,况且,还是导流到一个非刚需的垂直社交圈子里。 路径太长,用户很容易流失。 设想小道消息读者群,或者可能会有的「可能吧读者群」是一个微信小程序,用户在微信里就直接使用,转化率是不是会高很多? 如果结合小程序可以在对话列表置顶、可以收藏、可以深度搜索的特点,这种垂直社交的转化率和活跃度是不是会高很多? 所以,小程序可以缩短社群场景的转化路径。 6.3 协作场景 和社群场景类似,以往我们要在手机上与同事做工作上的沟通或协作要通过微信之外的工具,但与外部合作伙伴的沟通又必须回到微信,信息在两个工具之间并不能做很好互通,在这种场景里,沟通的路径被拉长了。 设想一个公司内部沟通用的是阿里的钉钉,但与外部沟通依然是微信,假设(不过不太可能)阿里做了一个微信小程序版本的钉钉,这个公司的协作和沟通就可以全部在微信里进行,不管是信息的传输路径还是员工的协作路径,都被缩短了一大截。 你可能会问,为什么做小程序就是缩短了路径?因为绝大部分中国用户的绝大部分时间,都被微信这个「场景」霸占了,通过小程序,可以与微信分享用户的时间。 所以,小程序可以缩短协作场景的沟通路径。 7 小程序生态的 3 个阶段 这篇文章其实是比较发散的,如果你已经读到这里,那么,让我们回到小程序本身吧。 因为写了不少关于小程序的文章,过去几个月很多人问我小程序适合做什么,应该怎样做,我的理解是这样的: 小程序是一个生态 这个生态希望连接更多线下场景 生态里出现的产品,会分 3 个阶段 这 3 阶段分别为: 7.1 摸索与搬迁阶段 第一个阶段,以开发者的摸索和互联网公司的搬迁为主。开发者会在这个平台做各种小玩意尝鲜,看看能玩出什么花。互联网公司会把已有的业务,复制一份到小程序平台,比如美团、携程等。 这个阶段里,会出现各种围绕小程序生态的产品,比如: 外包 快速拼装小程序的服务 培训(比如有可能学院) 数据统计(比如阿拉丁) 广告联盟 小程序商店 这个阶段,大家都在摸索。 一句题外话,我认为小程序商店对用户来说没有多大意义,因为小程序的获得应该是场景化的,而不是通过在商店探索获得,试想我们已经有多久没有在 App Store 探索新的 app 了?但对开发者来说,用来研究竞争对手,是个不错的工具,用来做数据服务帮助广告主做投放决策,也是不错的,本质是,这是个 to B 的产品。 7.2 工具阶段 因为大部分尝鲜者都是互联网公司,大部分互联网公司的线下能力是比较弱的,如果要针对微信场景做深度尝试,从成本等角度考虑,他们会优先寻找基于微信的线上场景。 互联网创业者的嗅觉很敏锐,他们会很快找到用户在微信里未被满足且能用小程序满足的需求,前面提到的社群场景、协作场景有可能会在第二阶段出现。 7.3 场景化阶段 有了开发者的尝鲜和互联网公司的产品搬迁,小程序已经逐渐为人所知,真正的场景化小程序会在这个阶段出现并被推广到普通用户身上。 这个阶段强调的是场景化和本地化,线下的流量在这个阶段可能才被真正激活,被真正地连接起来。 8 通过小程序看趋势 小程序的本质是提供一种服务触手可及的能力,并建议开发者尝试连接线下场景,一方面为开发者带来新的流量,另一方面,帮助微信构建更大的帝国。 这篇文章的目的,与其说是分析微信想要什么,不如说通过微信小程序看创业的趋势,因为小程序想要的,其实也是创业者想要的。 前面举例的场景化最短路径,如果支付宝也做一套应用号,我相信他们也会采用同样的思路。 举这些例子,包括分析微信为什么要让小程序先主攻线下,并不是想说微信有多精明,而是想通过我观察到的现象,抽离出一些趋势,比如线上已经没有太多流量空间但线下依然有可连接的机会,比如能帮自己节省时间可能是用户越来越看重的产品特性,比如场景化的精细运营获得成功的可能性更大。 即使没有小程序,这些结论在 2017 年依然成立,甚至接下来几年,也是做产品、创业时应该花时间去思考和实践的。 本文来源:http://mp.weixin.qq.com/s/6iIM1smHeTZFTPe17QvPog
================================================================ 消息分组:QQ群 518924126================================================================消息对象:微信平台开发有问必答群================================================================ 2016-11-16 18:15:33 【师兄】昵昵宝贝[付费用户]老师,公众号发红包的SDK,哪里有啊? 2016-11-16 18:18:03 方倍工作室每个人只能买一次的情况下 怎么识别用户 //openid 2016-11-16 18:18:16 昵昵宝贝[付费用户]不知道哪里有啊。 2016-11-16 18:18:26 方倍工作室https://h5.koudaitong.com/v2/goods/36cmmfpb5fv9e 2016-11-16 18:18:31 昵昵宝贝[付费用户]在哪里购买的啊? 2016-11-18 07:41:18 【路人】合作共赢[付费用户]群主,jssdk中的分享给朋友接口wx.onMenuShareAppMessage,怎么能获得分享给了谁?即如何取得分享者和被分享者的oepnid? 2016-11-18 09:37:26 【掌门】光辉岁月1979[付费用户]老师,问您个问题,我们这边的用户用我们的二维码红包贴在酒瓶上卖,发现有部分二维码在打印的时候被打印人员私自留存,目前系统后台统计了一些扫码得红包次数非常多的用户信息,如openid,微信昵称等,但无法精准定位这个微信用户,想加这些人为微信好友,请问有什么办法,谢谢件MP_verify_IbWggk5i4gWgrast.txt上传至mp.weixin.qq.com指向的web服务器(或虚拟主机)的目录 怎么处理的? 2016-11-18 11:09:49 方倍工作室群主,jssdk中的分享给朋友接口wx.onMenuShareAppMessage,怎么能获得分享给了谁?即如何取得分享者和被分享者的oepnid?//分享之前使用网页授权获得分享人的openid,分享后的跳转中将openid传入 2016-11-18 11:10:12 方倍工作室被分享的人收到的时候,再用网页授权得到他的openid 2016-11-18 11:10:34 向大狼学习[付费用户]我的这个不是分享啊 2016-11-18 11:10:54 向大狼学习[付费用户]我是在公众号里面链接别人微信公众号的文章链不过去 2016-11-18 11:11:00 方倍工作室老师,问您个问题,我们这边的用户用我们的二维码红包贴在酒瓶上卖,发现有部分二维码在打印的时候被打印人员私自留存,目前系统后台统计了一些扫码得红包次数非常多的用户信息,如openid,微信昵称等,但无法精准定位这个微信用户,想加这些人为微信好友,请问有什么办法,谢谢//企业付款接口,搞实名制, 2016-11-18 11:11:18 方倍工作室请将文件MP_verify_IbWggk5i4gWgrast.txt上传至mp.weixin.qq.com指向的web服务器(或虚拟主机)的目录 怎么处理的?//将txt文件上传到你填的域名的根目录 2016-11-18 11:15:41 合作共赢[付费用户]谢谢群主解答JSSDK分享获取OPENID,怎样能进一步知道通过网页授权获取到OPENID是分享链接中的?也就是社交关系? 2016-11-18 11:15:56 向大狼学习[付费用户]那个一直是通过的啊,要以链接这里面的文章,就是不能链接别人微信公众号的文章 2016-11-18 11:21:54 方倍工作室谢谢群主解答JSSDK分享获取OPENID,怎样能进一步知道通过网页授权获取到OPENID是分享链接中的?也就是社交关系?//A访问的时候,拿到他的openid_a,分享后,跳转新网页中index.php?openid_a=xxx,B访问的时候,拿到openid_a并通过授权拿到openid_b,这样就知道上下级关系了。 2016-11-21 10:31:54 [付费用户]如何通过openid获取用户信息?openid怎么获取? 2016-11-21 10:32:39 方倍工作室有完整的教程,地址 http://www.cnblogs.com/txw1958/p/weixin76-user-info.html 2016-11-21 13:05:52 ئىزقۇت[付费用户]图片的media id 怎么获取 2016-11-21 13:08:05 ئىزقۇت[付费用户][图片] 2016-11-21 13:08:21 ئىزقۇت[付费用户][图片] 2016-11-21 14:14:19 方倍工作室要传文件,你这个是个网址url 2016-11-21 14:14:24 方倍工作室传本地文件 2016-11-22 15:51:15 ╮(╯▽╰)╭O,Vline[付费用户]有没有微信小店的 小店概况接口 2016-11-22 15:51:53 方倍工作室开发文档上没有就没有 2016-11-22 17:24:16 在路上[付费用户]微信登录分享的功能,后台把应用签名弄错了,现在修改了微信开放平台里的应用签名,要多长时间才能生肖? 2016-11-22 17:24:47 在路上[付费用户]现在微信开放平台里改了应用签名,一直用不了微信的分享登录支付等功能了。 2016-11-22 18:59:00 方倍工作室不清楚 2016-11-22 21:58:22 `月落乌啼δ[付费用户]微信小店客户支付的钱是到那里了? 2016-11-22 21:59:21 `月落乌啼δ[付费用户]还有那几万块钱的押金是怎么说,我没交也能上传商品啊 2016-11-22 22:38:10 方倍工作室公司对公帐号 2016-11-22 22:38:25 方倍工作室现在不要押金了 2016-11-22 22:44:04 `月落乌啼δ[付费用户]要手动提现吗 还是时间到就自动转入公司帐号了 2016-11-22 22:59:23 方倍工作室自动的 2016-11-22 23:01:40 `月落乌啼δ[付费用户]一般从客户支付到实际到帐要多久 2016-11-22 23:04:33 方倍工作室商户后台有,找下 2016-11-25 19:04:07 Sunshine love[付费用户]入门教程可以发我吗 2016-11-25 19:04:20 方倍工作室http://www.cnblogs.com/txw1958/p/wechat-tutorial.html 2016-11-26 09:44:33 【大侠】You My[付费用户]微信授权方式登录 有时会获取两次code 而且code值都一样 为什么? 2016-11-26 10:34:30 方倍工作室代码有问题,跳转逻辑不正确 2016-11-26 10:35:05 You My[付费用户]代码也是按照那样来的 2016-11-26 10:36:04 方倍工作室我的这个一直是正常的 2016-11-26 10:39:30 You My[付费用户]恩恩 行 2016-11-26 10:40:53 You My[付费用户]微信网页授权方式 跳转两次 是不是也有个属性设置的? 2016-11-26 10:41:02 方倍工作室只有一次 2016-11-26 10:41:10 方倍工作室如果要跳两次,那代码肯定有问题 2016-11-26 10:52:18 Sunshine love[付费用户]群主,那种通过发送自己的位置,然后可以实现搜索附近门店的功能,怎么实现 2016-11-26 10:53:28 方倍工作室后台收到坐标后,计算所有门店用用户的距离,按远近排序,再列出来 2016-11-27 10:32:15 `月落乌啼δ[付费用户]群主的书在那卖 2016-11-27 10:32:19 `月落乌啼δ[付费用户]多少钱一本、 2016-11-27 10:37:36 方倍工作室淘宝和京东上都有 2016-11-27 10:57:27 `月落乌啼δ[付费用户]叫什么名字 2016-11-27 10:59:11 方倍工作室http://www.cnblogs.com/txw1958/p/weixin-book-dev.html 2016-11-28 17:24:57 向翠翠[付费用户]大家好,微信登录返回的openid,unionid,这两个,应该用哪个去后台注册 2016-11-28 20:27:14 方倍工作室开放平台 2016-11-28 21:26:19 `月落乌啼δ[付费用户]客户关注后取消 又再次关注 两次关注的openid一样么 2016-11-28 21:53:50 方倍工作室一样 2016-11-28 22:25:58 方倍工作室怎么知道客户的openid呢//关注时的Fromusername参数就是openid,另外通过网页授权也能取得 2016-11-30 11:57:24 `月落乌啼δ[付费用户]不交那300块钱的服务号能用么 2016-11-30 11:58:11 方倍工作室你看有客服权限没 2016-11-30 14:33:46 abc[付费用户]大家好!接受二维码推送的消息,如何实现?谢谢! 2016-11-30 14:34:03 方倍工作室就是开发者接口接收的 xml中 2016-11-30 16:32:22 前端-微信公众号开发[付费用户]请教下:要实现点击任意菜单时候,都要先判断用户是不是第一次登录,第一次登录则跳转到登录页面(登录成功则缓存数据作为判断是否第一次登录依据),否则直接打开菜单的连接,请问是要在每个菜单页面里面做判断吗? 2016-11-30 16:59:31 方倍工作室这个时候都没有数据,我问问其他人,说是服务器和微信支付通信的原因 //为什么没有数据?通信有什么原因? 2016-11-30 17:00:49 方倍工作室请教下:要实现点击任意菜单时候,都要先判断用户是不是第一次登录,第一次登录则跳转到登录页面(登录成功则缓存数据作为判断是否第一次登录依据),否则直接打开菜单的连接,请问是要在每个菜单页面里面做判断吗?//在url 里面,把用户登录记录写数据库,每次用户登的时候再从数据库查来判断 2016-11-30 17:05:41 Sunshine love[付费用户]自定义菜单的创建是不是有两种方法?一种是利用微信网页调试工具,一种是上传代码到服务器啊 2016-11-30 17:06:14 方倍工作室菜单是向微信服务器提交post,用调试工具可以,上传到服务器执行也能提交 2016-11-30 17:06:53 Sunshine love[付费用户]那上传服务器应该是上传到自己申请到的服务器里不 2016-11-30 17:07:02 方倍工作室当然 2016-11-30 17:08:55 Sunshine love[付费用户]老大,你发的配置微信公众号借口的代码内含了你的工作室信息,给我的感觉不好改啊[表情] 2016-11-30 17:10:21 Sunshine love[付费用户]我得平台可以免费给你打广告,关键在学习怎么自己做开发 2016-11-30 17:14:37 前端-微信公众号开发[付费用户]请教下:要实现点击任意菜单时候,都要先判断用户是不是第一次登录,第一次登录则跳转到登录页面(登录成功则缓存数据作为判断是否第一次登录依据),否则直接打开菜单的连接,请问是要在每个菜单页面里面做判断吗?//在url 里面,把用户登录记录写数据库,每次用户登的时候再从数据库查来判断 这样是每次都要登录再判断吗? 需求是登录过的就不需要登录了,直接可以打开菜单栏URL呢 2016-11-30 17:15:32 前端-微信公众号开发[付费用户]没登录过打开菜单栏跳转到登录页面 2016-11-30 18:23:57 方倍工作室//在url 里面,把用户登录记录写数据库,每次用户登的时候再从数据库查来判断 //登录过的就跳到你直接打开的页面,没有登录就跳转到登录页面 2016-11-30 18:24:18 方倍工作室我得平台可以免费给你打广告,关键在学习怎么自己做开发 不然以后做不大,技术受限 有没有那种通用的代码啊 //我的代码都开源的,你自己改一下就行了 2016-12-01 09:48:16 从入门到外包.avi[付费用户][图片]新手问下这里的开发者微信号是指哪个的微信号啊,公众号的吗 2016-12-01 09:50:30 方倍工作室对, 2016-12-01 09:50:38 方倍工作室一个gh_开关的字符串 2016-12-01 09:50:47 从入门到外包.avi[付费用户]可是我打印出来不一样啊 2016-12-01 09:52:16 从入门到外包.avi[付费用户]那我想通过这个xml获取用户关注的是哪个公众号怎么办 2016-12-01 09:52:35 方倍工作室用[图片] 通过这个来区分 2016-12-01 09:52:38 方倍工作室每个公众号的不一样 2016-12-01 09:52:50 从入门到外包.avi[付费用户]哦,我看看 2016-12-01 10:08:05 DreamTrue 已认证[付费用户]老师 我在微信公众平台已经配置好了 服务器也写了一个自动回复的一个功能,但是我在微信中发消息 他没有自动回复,这个要怎么调试呢 2016-12-01 10:49:52 waiting for you[付费用户]帮我一下,两个问题第一个注册一个开发者账号是不是就是公众号?什么叫以审核的网站应用呢? 2016-12-01 10:50:44 方倍工作室这个不是公众账号 2016-12-01 10:50:48 方倍工作室这个是开放平台 2016-12-01 11:11:07 waiting for you[付费用户]这句话什么意思,已审核通过的网站应用 2016-12-01 11:11:56 方倍工作室开放平台里面添加网站要审核 2016-12-01 11:12:00 DreamTrue 已认证[付费用户]就是解析了的 ,备案的 2016-12-01 11:12:18 方倍工作室审核了才能做后面的 2016-12-01 11:19:34 方倍工作室扫码是网站应用 2016-12-01 11:19:41 方倍工作室要交300元认证费用 2016-12-01 11:19:56 waiting for you[付费用户]这么贵啊 2016-12-01 11:20:09 方倍工作室全都是这个价 2016-12-01 17:44:57 方倍工作室在授权回调页面域名时,有个注意事项,里面第二条写了将文件MP_verify_xxxxxx.txt上传至域名指向的web服务器,这个步骤需要吗?好像以前设置公众号的时候没有提示要做这一步//需要 2016-12-01 17:45:13 方倍工作室群主 ,验证token的时候可以调试吗//看http://www.cnblogs.com/txw1958/p/token-verify.html 2016-12-01 17:46:05 方倍工作室京东上的最佳实践书怎么有两种啊,一个56一个40//看这http://www.cnblogs.com/txw1958/p/weixin-book-dev.html 2016-12-01 17:46:06 Sunshine love[付费用户]用微信公众平台接口调试工具时,在消息接口调试这个类型中,里面的tousername,和fromusername的数据怎么获取啊,具体点 2016-12-01 17:46:46 方倍工作室 该公众号暂时无法提供服务,请稍后再试 这是怎么回事//http://www.cnblogs.com/txw1958/p/weixin-suspend-service-solution.html 2016-12-01 17:54:44 Sunshine love[付费用户]我上传到服务器了,可是微信公众号一端没有效果啊 2016-12-01 17:54:44 方倍工作室肉眼看不出来,你直接上调试器调试就知道了 2016-12-01 17:54:54 方倍工作室没有效果就需要调试 2016-12-01 17:55:31 Sunshine love[付费用户]调试器需要tousername等,我不知道如何获取,你说的解析,我不懂 2016-12-01 17:55:48 方倍工作室看这 http://debug.fangbei.org/用这个啊 2016-12-01 17:55:53 方倍工作室我都自动配置了, 2016-12-01 17:56:07 方倍工作室都不用解析了, 2016-12-01 21:11:40 Sunshine love[付费用户]这让我有蒙了 2016-12-01 21:11:48 方倍工作室用我书上的不对,说明你没有明白书上为什么这么写 2016-12-01 21:12:06 Sunshine love[付费用户]你书上那个是个完整的代码 2016-12-01 21:12:46 方倍工作室http://debug.fangbei.org/ 用这个调试一下,看你报错在哪 2016-12-01 21:13:34 方倍工作室用书上的代码就一定对,这种就根本不成立, 2016-12-01 21:13:40 Sunshine love[付费用户]有问题,你就说调试,关键,为什么你书上的不行啊 2016-12-01 21:13:41 方倍工作室谁知道这个中间发生了什么 2016-12-01 21:13:54 方倍工作室我书上的都是行的 2016-12-01 21:14:43 Sunshine love[付费用户]那群主能看下,这个到底哪里错了 2016-12-01 21:15:00 Sunshine love[付费用户]这个就是你书上的代码 2016-12-01 21:15:18 方倍工作室你的SAE认证了吗 2016-12-01 21:16:44 方倍工作室我发现了你的一个错误了 2016-12-01 21:17:09 方倍工作室[图片] 2016-12-01 21:17:35 方倍工作室第53行,这个括号是括回来的,而你是括出去 2016-12-01 21:17:43 方倍工作室这样导致上面一个括号没有配对 2016-12-01 21:17:50 方倍工作室而我书上是括回来的,你的不是 2016-12-01 21:19:26 方倍工作室这种错误应该自己找出来,不要老觉得原因在别人身上 2016-12-01 21:21:23 方倍工作室[图片][图片] 2016-12-01 21:21:35 Sunshine love[付费用户]我再试试,多谢群主了,心里着急啊,看了一下午了,也没看出来到底哪里的问题[表情][表情] 2016-12-01 21:24:23 Sunshine love[付费用户]@The Catcher In The Night 我不是程序猿[表情] 2016-12-01 21:24:36 Sunshine love[付费用户]不过我确实太着急了,多谢群主 2016-12-01 21:25:30 Sunshine love[付费用户]群里如果有会的,多讨论啊,感觉每次只有群主回答,也很感谢中午群里一个朋友帮忙,很感谢[表情][表情] 2016-12-02 15:48:32 方倍工作室[图片]//苹果的漏洞,用软件可以改 2016-12-02 17:39:28 从入门到外包.avi[付费用户]老哥,我现在的二维码都是通过网上的api获取了二维码的图片链接地址,我有了这个地址怎么直接把图片存进我的服务器啊 2016-12-02 18:56:00 方倍工作室先生成图片,再保存到本地 2016-12-03 17:59:08 abc[付费用户]群主好!scancode_waitmsg说明:成员点击按钮后,微信客户端将调起扫一扫工具,完成扫码操作后,将扫码的结果传给开发者,同时收起扫一扫工具,然后弹出“消息接收中”提示框,随后可能会收到开发者下发的消息。 2016-12-03 17:59:50 abc[付费用户]这个意思 可以实现我的需求吧? 2016-12-03 18:38:18 方倍工作室可以 2016-12-04 10:22:27 abc[付费用户]但是agentid栏 上面写的是企业号corpid。不知是啥意思 2016-12-04 10:41:14 方倍工作室那是上面那个字段 2016-12-04 10:41:32 方倍工作室企业号的corpid,要先创建管理组 2016-12-04 10:41:38 方倍工作室管理组里面就有这个 2016-12-06 09:24:25 从入门到外包.avi[付费用户]老哥,永久的带参数二维码最多十万个,这十万个是怎么算的,每个场景id就算一个吗 2016-12-06 10:34:23 方倍工作室老哥,永久的带参数二维码最多十万个,这十万个是怎么算的,每个场景id就算一个吗//数字1到100000 2016-12-06 10:35:37 The Catcher In The Night[付费用户]方老师,用户扫了带参二维码之后关注了公众号,是不是必须接入开发者模式才能统计到用户的来源渠道 2016-12-06 10:36:14 方倍工作室方老师,用户扫了带参二维码之后关注了公众号,是不是必须接入开发者模式才能统计到用户的来源渠道//对的,需要用接口取到关注时的参数数据, 2016-12-06 10:36:35 The Catcher In The Night[付费用户]如果不接入,微信公众平台后台用户统计上,是否会显示渠道来源呢? 2016-12-06 10:37:41 方倍工作室那种有渠道来源,但不能精通到参数 2016-12-06 10:37:47 方倍工作室用户的渠道,数值代表的含义如下: 0代表其他合计 1代表公众号搜索 17代表名片分享 30代表扫描二维码 43代表图文页右上角菜单 51代表支付后关注(在支付完成页) 57代表图文页内公众号名称 75代表公众号文章广告 78代表朋友圈广告-06 12:04:07 方倍工作室post不会吗?生成菜单那样就是post 2016-12-06 12:05:44 `月落乌啼δ[付费用户]access_token 一般是保存在那 2016-12-06 12:12:14 跌跌~~撞撞[付费用户]开发者模式自定义菜单,只要发送请求就能生成吗 2016-12-06 12:20:13 方倍工作室【路人】奋斗ι ﹏,[付费用户] 12:02:04//你先在这个url做个写访问者日志的功能,看微信支付服务器是否访问过,然后再检测访问的时候有没有数据,最后检测你的程序解析数据是否成功 2016-12-06 12:20:23 方倍工作室access_token 一般是保存在那//数据库或缓存 2016-12-06 12:20:40 方倍工作室开发者模式自定义菜单,只要发送请求就能生成吗//发送后有返回,看返回状态 2016-12-06 12:38:43 跌跌~~撞撞[付费用户]本地发送也能生成吗 2016-12-06 12:38:55 跌跌~~撞撞[付费用户]发送以后就一直在了吗菜单 2016-12-06 12:41:21 跌跌~~撞撞[付费用户]菜单会不会失效 2016-12-06 15:11:42 方倍工作室【路人】跌跌~~撞撞[付费用户] 12:38:43 本地发送也能生成吗 【路人】跌跌~~撞撞[付费用户] 12:38:55 发送以后就一直在了吗菜单 【路人】跌跌~~撞撞[付费用户] 12:41:21 菜单会不会失效 2016-12-06 15:12:01 方倍工作室同步 异步是同一个 方法 行不行的?//方法是什么不用要,主要还是你怎么使用 2016-12-06 15:12:07 方倍工作室老哥,我要区分用户关注是扫描带参数的二维码还是正常的二维码能这样判断不//能 2016-12-06 15:12:17 方倍工作室不启用 能不能接收到 支付返回的xml//能,支付和这个无关 2016-12-06 15:27:17 方倍工作室你是怎么把这个地址告诉微信的呢 2016-12-06 15:27:50 奋斗ι ﹏,[付费用户]在支付的时候 2016-12-06 15:28:09 方倍工作室你确定你给的是对的吗? 2016-12-06 15:28:16 奋斗ι ﹏,[付费用户][图片] 2016-12-06 15:28:30 方倍工作室原因就在这里 2016-12-06 15:28:35 方倍工作室这个不是微信支付通知的url 2016-12-06 15:29:03 奋斗ι ﹏,[付费用户][图片] 2016-12-06 15:29:03 方倍工作室http://www.cnblogs.com/txw1958/p/wxpayv3-jsapi.html 2016-12-06 15:29:07 方倍工作室看这个教程 2016-12-06 15:29:17 方倍工作室$unifiedOrder->setParameter("notify_url",WxPayConf_pub::NOTIFY_URL);//通知地址 2016-12-06 15:53:40 从入门到外包.avi[付费用户]老哥。我这每次关注公众号都弹出来是否获取用户地理位置,这是在哪设置的,我想把它取消了 2016-12-06 16:00:18 奋斗ι ﹏,[付费用户][图片] 2016-12-06 16:00:22 奋斗ι ﹏,[付费用户]需要开启这个参数吗? 2016-12-06 16:00:41 DreamTrue 已认证[付费用户]要的 2016-12-06 20:24:54 合作共赢[付费用户]老师,[图片]微信企业支付返回报错,请问商户订单号在哪里可以看到? 2016-12-06 20:26:27 合作共赢[付费用户]付款方商户单号输入,查询,错误依旧 2016-12-06 22:34:44 `月落乌啼δ[付费用户]自动获取 access_token 的php 自我执行的思想是什么 2016-12-07 11:42:37 方倍工作室自动获取 access_token 的php 自我执行的思想是什么 //程序自动触发,或者定时触发,都可以 2016-12-07 11:43:06 方倍工作室这些http头怎么用的。我用变量接收结果全是空的 //curl里面有专门取http头的函数,找一下 2016-12-07 16:31:39 `月落乌啼δ[付费用户]我要得到所有的信息然后逐个腐殖给变量要怎么做 2016-12-07 16:32:00 做你的大白[付费用户]你是0基础吗[表情] 2016-12-07 16:32:11 `月落乌啼δ[付费用户]是的啊 2016-12-07 16:32:24 做你的大白[付费用户]多看看基础教程吧 2016-12-07 16:32:34 `月落乌啼δ[付费用户]那里人基础教程 2016-12-07 16:32:52 `月落乌啼δ[付费用户]php 么 2016-12-07 16:33:35 做你的大白[付费用户]w3school够你用的了 2016-12-07 16:35:29 做你的大白[付费用户]www.w3school.com.cn/php/index.asp 耐心看完这个 2016-12-08 15:31:02 从入门到外包.avi[付费用户][图片]老哥,这里的$newsArray是一个二维数组吗 2016-12-08 15:31:28 方倍工作室是 2016-12-08 15:56:22 家校通-学校微信公众号[付费用户]订阅号能生成带参数的二维码马 2016-12-08 16:05:12 家校通-学校微信公众号[付费用户]认证订阅号能生成带参数的二维码吗 2016-12-08 17:49:50 方倍工作室认证订阅号能生成带参数的二维码吗//不能 2016-12-08 17:50:22 方倍工作室微信图片链接怎么做,求大神//上传就有链接 2016-12-08 21:29:42 伏尔加的鱼[付费用户][图片] 2016-12-08 21:30:23 伏尔加的鱼[付费用户]这个菜单的key 怎么弄? 2016-12-08 21:30:44 方倍工作室随便填 2016-12-08 21:30:57 方倍工作室一般填成name的拼音并且大写 2016-12-08 21:31:06 伏尔加的鱼[付费用户]CLICK推送一个图文消息有什么好的写法 2016-12-08 21:31:33 方倍工作室用数组 2016-12-08 21:31:48 伏尔加的鱼[付费用户]? 2016-12-08 21:31:52 伏尔加的鱼[付费用户][表情] 2016-12-08 21:33:28 伏尔加的鱼[付费用户][图片] 2016-12-08 21:34:39 方倍工作室不要这样写,太乱了 2016-12-08 21:34:45 方倍工作室把他结构化一下 2016-12-08 21:34:47 方倍工作室http://www.cnblogs.com/txw1958/p/wechat-tutorial.html 2016-12-08 21:35:01 方倍工作室看下这里面的下载的代码,参考下 2016-12-08 21:35:05 方倍工作室或者群里面的 2016-12-08 21:38:52 方倍工作室http://www.cnblogs.com/txw1958/p/weixin-php-sdk.html 2016-12-09 10:14:33 RING GAME[付费用户]大家早上好,我想请教一个关于代公众号发起网页授权的问题,我需要用乐推微这个开发商代国镇物流公众号发起网页授权,发起网页授权的地址为:http://eh5.younle.com/CreateH5/Test/oauth 开发商与公众号的关系如下图: [图片] 现在授权页面错误提示信息如下图 [图片] 发起授权的部分代码如下: [图片] 开发商乐推微的配置是: [图片] 公众号国镇物流的配置如下: [图片] 我也查了很多关于解决scope参数错误的帖子,问题还是没解决,希望大家帮我看看,先谢啦 2016-12-09 10:21:55 方倍工作室国镇物流是订阅号还是服务号,认证了没有? 2016-12-09 10:22:11 RING GAME[付费用户]微信认证的服务号 2016-12-09 10:23:27 方倍工作室把这两个账号的账号,密码发给我 2016-12-09 10:23:31 方倍工作室另外服务器的ftp 2016-12-09 10:24:28 DreamTrue 已认证[付费用户]只要老大出手 没有解决不了的问题 2016-12-09 10:26:42 RING GAME[付费用户]公司规定不能随意外传,见谅 2016-12-09 10:26:50 方倍工作室不提供账号的话,就最终生成的请求code的url写日志记录下来,然后和开发文档对比 2016-12-09 10:27:15 方倍工作室参数、权限两个地方出问题的可能性最大 2016-12-09 11:00:17 伏尔加的鱼[付费用户]这个case 是指key 还是name? 2016-12-09 11:06:46 方倍工作室除了最终请求url还有别的地方有问题的可能么? url我和官方的文档对比过了,参数顺序都是一样的//全网发布成功过没,你的授权回调页和你填的一致吗? 2016-12-09 17:15:10 【掌门】DreamTrue 已认证[付费用户]我看了半天代码 不知道那个咋出来的 2016-12-09 17:18:08 【少侠】从入门到外包.avi[付费用户]老哥,一关注公众号就弹出来请求地理位置信息,是在哪里设置的 2016-12-09 17:46:33 【掌门】DreamTrue 已认证[付费用户][图片] 2016-12-09 17:51:08 【大侠】做你的大白[付费用户]微信连WIFI,想用Portal型路由器,需要认证公众号? 2016-12-09 18:41:32 方倍工作室老哥,一关注公众号就弹出来请求地理位置信息,是在哪里设置的//服务号接口列表中有设置 2016-12-09 18:41:50 方倍工作室还有这个东西 也是修改那几个参数得到的是不//是的,多数组 2016-12-09 18:42:07 方倍工作室微信连WIFI,想用Portal型路由器,需要认证公众号?//不需要认证,主要是有portal型的路由器 2016-12-09 18:43:20 做你的大白[付费用户]ddwrt系统用wifidog实现的Portal认证算Portal型路由器吗? 2016-12-09 18:43:39 方倍工作室实现portal认证的就是 2016-12-09 18:44:03 做你的大白[付费用户]谢谢。 2016-12-09 19:06:31 `月落乌啼δ[付费用户] 2016-12-09 19:06:51 做你的大白[付费用户]我发的图是wifidog的选项 2016-12-09 19:13:25 方倍工作室不用,这两个不相关 2016-12-09 19:13:37 方倍工作室鉴权只需要一个事实存在的页面就可以了 2016-12-10 11:15:18 从入门到外包.avi[付费用户][图片]老哥。这里的图文消息描述有长度限制吗 2016-12-10 11:18:29 方倍工作室多图文没有描述,单图文大约在几十个字左右,需要自己测试一下 2016-12-10 16:03:03 【路人】王嘉明[付费用户]老师,订阅号能不能实现网页抓取用户信息的功能,就是用户头像、昵称什么的 2016-12-10 17:49:33 方倍工作室没权限 2016-12-11 12:14:53 方倍工作室请问微信小店在哪提现?//自动提的,一周后看公司对公账户交易记录就行了,交易流水在商户平台中可以看到 2016-12-11 12:21:19 胡萝卜[付费用户]我们交易有20个交易记录,一个月了,总共有几万块钱,公户上一分钱也没有看到 2016-12-11 12:27:46 方倍工作室商户平台查 2016-12-12 09:54:16 胡萝卜[付费用户]通过电话得知,提现,要登录微信支付商户平台,在公众平台是操作不了的,这个系统做的真是麻烦,脑袋都晕,一天到晚就是不停的登录 2016-12-12 10:44:24 传导网络--小思[付费用户]请问群主,能否有个二维码,用户扫描后既可关注公众号,又可记录分享这个码的人的业绩? 2016-12-12 10:51:14 方倍工作室就是参数二维码 2016-12-12 10:56:35 传导网络--小思[付费用户]那个二维码实际是公众号的二维码,只是带有参数是吗? 2016-12-12 10:57:13 方倍工作室对 2016-12-12 11:18:04 传导网络--小思[付费用户]好的,谢谢。[表情] 2016-12-12 17:18:39 胡萝卜[付费用户]同样是这个二维码,如果通过QQ发,对方用手机自动识别后,再点就进不去,总出错。如果是用微信发的,同样是自动识别就没事,这是什么原因 2016-12-12 17:22:39 方倍工作室这个是微信二维码,只有微信能解并且响应, 其他扫了只能解码,不会有响应 2016-12-12 17:34:18 huaihaigh[付费用户]域名暂时不可用,用公网的IP可以调试吗? 2016-12-12 17:34:43 方倍工作室要备案域名 2016-12-12 17:35:51 胡萝卜[付费用户]现在各种微信二次开发营销软件,哪家好用呀,请推荐一下 2016-12-12 17:36:13 方倍工作室有赞和微盟 2016-12-13 12:33:35 与你同行[付费用户]接收通知的页面是哪个页 我抓图了 2016-12-13 12:33:41 方倍工作室notify.php 2016-12-13 12:34:01 方倍工作室默认是这个,你可以自己配置,自己改 2016-12-13 12:34:50 做你的大白[付费用户]native静态支付的过程是native.php->native_notify.php->notify.php吗? 2016-12-13 12:35:04 方倍工作室对 2016-12-13 12:37:02 与你同行[付费用户]我这个notify.php里就一个类两个函数 我不知道接收哪个字符串 表示支付成功了,然后写入我的订单逻辑 2016-12-13 12:46:53 与你同行[付费用户]我就想知道 这个文件 REQUEST 什么参数 能代表成功支付 这样我就可以写逻辑了 2016-12-13 12:47:22 方倍工作室不是request什么参数, 2016-12-13 12:47:35 方倍工作室要接收一个post过来的参数,里面有xml 2016-12-13 12:47:44 方倍工作室xml中会有支付成功的标识 2016-12-13 17:05:44 Monsieur聂[付费用户]带参数二维码扫码后如何将用户放到不同的标签分组里面 2016-12-13 19:49:23 方倍工作室接收到关注消息时,取参数,然后调用标签设置接口,给用户贴标签 2016-12-13 22:56:12 【大侠】`月落乌啼δ[付费用户]地理位置 收到的是什么东西 2016-12-14 09:25:49 方倍工作室地理位置 收到的是什么东西//经度和纬度坐标 2016-12-14 10:51:09 `月落乌啼δ[付费用户]微信可以直接回复小视频吗 2016-12-14 10:51:24 `月落乌啼δ[付费用户]不是小视频链接 2016-12-14 10:53:45 ㄒаしеら[付费用户]可以 2016-12-14 10:56:53 `月落乌啼δ[付费用户]素材上传给微信吗? 2016-12-14 10:57:08 `月落乌啼δ[付费用户]还是上传到自己的服务器也可以 2016-12-14 10:57:33 方倍工作室先上传到素材中 2016-12-14 10:57:37 方倍工作室再取得mediaid 2016-12-14 11:20:59 `月落乌啼δ[付费用户]微信默认的什么字符编码 2016-12-14 11:30:47 方倍工作室utf8 2016-12-14 11:52:57 【少侠】奋斗ι ﹏,[付费用户]我想问下 支付的时候 必须要他自己商户里面 的证书吗? 2016-12-14 11:57:22 方倍工作室收钱不要证书,发钱出去才要证书 2016-12-14 14:53:56 做你的大白[付费用户][图片]请问这个类在哪里定义的?怎么找不到 2016-12-14 15:07:45 方倍工作室prepay_id为空//前面的流程没有走到,需要调试一下代码 2016-12-14 15:08:15 方倍工作室[图片] 前面有引用文件,在引用文件里面 2016-12-14 15:10:09 做你的大白[付费用户][图片] 2016-12-14 15:10:14 做你的大白[付费用户]没有这个类[表情] 2016-12-14 15:12:37 方倍工作室不是这样用的 2016-12-14 15:12:45 say hello[付费用户]各位好 我想咨询下 我用测试号进行微信网页开发时,查看网页返回的链接是[图片],会在原来的链接后面加上nsukey 2016-12-14 15:13:35 say hello[付费用户]但是别人访问这个网页时,返回的是[图片], 2016-12-14 15:13:50 say hello[付费用户]没有 nsukey。 2016-12-14 15:14:04 方倍工作室不用管,微信浏览器改的 2016-12-14 15:17:01 say hello[付费用户]用这个动态获取url得到的链接 生成的signature 2016-12-14 15:17:34 say hello[付费用户]难道测试号开发 只能开发者正常访问? 2016-12-14 15:18:11 方倍工作室对 2016-12-14 15:18:17 方倍工作室测试号不关注是用不了的 2016-12-14 15:18:39 say hello[付费用户]好的 我再试试 谢谢啦 2016-12-14 15:25:52 say hello[付费用户]结果关注了以后 也不能正常访问 2016-12-14 15:26:04 方倍工作室那就是代码有问题了 2016-12-14 15:26:23 say hello[付费用户]但是 我作为开发者能正常访问。 2016-12-14 15:27:36 say hello[付费用户]我访问时 返回的是这样的url[图片] 别人关注后访问时 返回的是这样的url[图片] 2016-12-14 15:28:13 say hello[付费用户]不知道问题是不是这个影响的 2016-12-14 15:28:24 方倍工作室[图片] 把域名加到业务里面去 2016-12-14 15:28:57 say hello[付费用户][图片]这里加了的 2016-12-14 15:29:53 方倍工作室要他们直接访问 你能访问的那个链势头 2016-12-14 15:29:58 方倍工作室去掉后缀 2016-12-14 15:42:48 方倍工作室引号里面嵌引号容易出问题 2016-12-14 15:42:54 方倍工作室用连接符连接吧 2016-12-14 17:13:50 【大侠】做你的大白[付费用户]sublime确实不能够自动找到我要的类,现在已经可以用jsapi和扫码支付了,谢谢群主。 2016-12-14 20:25:48 `月落乌啼δ[付费用户]给用户主动发消息只能调用 客户接口么 2016-12-15 07:57:58 方倍工作室给用户主动发消息只能调用 客户接口么//客服接口,被动回复,模板消息,三种
1. 刷卡支付默认有推荐关注2. 公众号支付和扫码支付需要5元以上才有推荐关注3. APP支付默认没有,需要申请配置,需要有一定用户规模才可以申请4. 已经关注的不展示推荐栏5. 服务号未设置头像的在IOS不展示推荐关注栏6. 用户取消过关注的默认不勾选7. 服务商模式的,需要在特约商户开发配置页设置推荐关注appid8. 订阅号目前是不会有默认推荐关注的 效果图请看 微信支付开发(5) 扫码并输入金额支付
微信小应用资源汇总整理 开源项目 WeApp - 微信小程序版的微信 wechat-weapp-redux-todos - 微信小程序集成Redux实现的Todo list wechat-weapp-gank - 微信小程序版Gank客户端 wechat-dribbble - 微信小程序-Dribbble wechatApp-demo - 微信小程序 DEMO weapp-ide-crack - 微信小应用资源破解 API - API 文档 weapp-quick - 微信小应用示例代码 weapp-gold - 掘金主页 微信小应用示例 weapp-douban - 豆瓣电影 微信小程序 wechat-app-zhihudaily - 微信小程序版的知乎日报 SmallApp - 小 Demo,可参考 微信小程序开发 DEMO - 地图定位 TCP/IP 长连接服务,支持微信小程序 Websocket 微信小程序-v2ex - 微信小程序版的v2ex 微信小程序 - 公众号热门文章信息流 teamtoy-mina-demo - 一个调用 TeamToy API 的微信小程序 Demo weapp-snippet-for-sublime-text-2-3 - sublime text 2&3 微信小程序 snippet wxapp-cli - 微信小程序的脚手架 wxapp-todolist - 微信小程序之练手小玩意儿——Todo List wxapp-2048 - 微信小程序之2048小游戏 文档 官方文档 简易教程 设计指南 开发者工具文档 API 文档 视图组件文档 常见问题 微信 UI/WEB 设计规范标注 教程 微信小程序开发文档 微信公众平台 API 文档 - GitHub 微信小程序怎么开发?玩物志用一个上午上线了电商应用 | 爱范儿 首个微信小程序开发教程! 抢先看:微信官方发布的微信应用号(小程序)设计规范 开发微信小程序入门前 微信小程序开发教程! 微信小程序开发环境搭建 全球首个微信应用号开发教程!通宵吐血赶稿,每日更新! 微信小程序「官方示例代码」浅析【上】 微信小程序「官方示例代码」浅析【下】 IDE常用快捷键——微信小程序 微信小程序开发:MINA 知乎讨论 如何评价 9 月 21 日开始内测的「微信小程序」? 如何看待微信将推应用号? 微信小程序(应用号)价值是什么? 开始内测的「微信公众平台 · 小程序」可能有哪些应用场景? 微信小程序(应用号)来了,对创业者来说到底是不是好机会? 微信小程序的出现会给前端开发带来什么? 微信应用号是否真能颠覆APP? 在微信应用号(微信小程序)开发什么什么应用爆发概率大? 如何获得「微信·小程序」的内测资格? 微信“小程序”真的来了!移动端会炸吗?Native开发何去何从? 微信的小程序会导致安卓和ios开发失业吗? 微信小程序(应用号)是如何通过苹果审核的? 做微信小程序的开发者,需要掌握哪些编程技能? 媒体报道 关于微信小程序(应用号),我能透露的几个细节 微信应用号来了,程序猿要涨工资了! 微信推出小程序应用号,移动互联网第二春会来吗? 一篇文章读懂微信小程序(应用号)是什么,是否值得投入进来做? 你的产品适不适合做微信小程序?你需要这篇产品逻辑分析 微信应用号正式公开,一个开放的微信已经上路? 一文读懂微信小程序(应用号)是什么,创业者是否值得投入进来做? 一张图看懂微信“小程序” 关于微信小程序,我联想到的几点 你想做个怎样的微信小程序? 微信小程序动了谁的蛋糕,又会把蛋糕分给谁? 文章 从程序员的角度分析微信小程序 微信小程序,一个有局限的类似 React Native 轮子! 关于微信小程序(应用号)的底层逻辑分析和拥抱建议 微信小程序常见问题汇总 微信小程序有什么功能 如何申请? 关于微信小程序(应用号)的全部看法 微信应用号相关资料集合 封闭一周开发微信应用号(小程序) 微信应用号「小程序」最全的Q&A列表 为什么要发布微信应用号 微信小程序,仅仅是 Web App 么? 规范抢先看!微信小程序的官方设计指南和建议 其他 公众平台小程序文档和工具http://dwz.cn/4dH0gaWeUI 是一套同微信原生视觉体验一致的基础样式库,由微信官方设计团队为微信内网页和微信小程序量身设计,令用户的使用感知更加统一。https://weui.io/?from=singlemessage&isappinstalled=0开发微信小程序入门前http://lattecake.com/post/20098微信小程序资源汇总整理http://dwz.cn/4dH6ew全球首个微信应用号开发教程!通宵吐血赶稿。http://dwz.cn/4dH5rd简易教程做的页面,让更多人看到小程序后台。http://wx.chiki.org/?from=singlemessage&isappinstalled=0微信小程序内测版- 开发工具与文档http://yaosimin.com/477.html?from=singlemessage&isappinstalled=0知友陈宇强的回答http://dwz.cn/4dH7ze微信小程序设计规范(优化版)抢先看了!http://dwz.cn/4dH8wb微信小程序,制作工具解析http://dwz.cn/4dH9gn前端开发学习资源教程http://dwz.cn/4dH9Ry微信小程序视频教程链接:https://pan.baidu.com/s/1o8cuiG6 密码: v1vt为什么我们需要一个兼容「微信小程序」的Web框架?(内含三个超链接)http://dwz.cn/4ekUaS官方教程http://dwz.cn/4eA0X8开发资源汇总http://dwz.cn/4eNQhO微信小程序前端学习资源教程http://dwz.cn/4f0VZf微信移动UI设计规范http://gold.xitu.io/entry/57e9cbc5a0bb9f0058560585?from=timeline&isappinstalled=0集体学习第一课(1,2,3,4节内容)http://dwz.cn/4ekX7c
本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果。这个小程序的首页将会显示欢迎语以及当前用户的微信头像,点击头像,可以在新开的页面中查看当前小程序的启动日志。下载源码 1. 获取微信小程序的 AppID 如果你是收邀请的开发者,我们会提供一个帐号,利用提供的帐号,登录 https://mp.weixin.qq.com ,就可以在网站的“设置”-“开发者设置”中,查看到微信小程序的 AppID 了,注意不可直接使用服务号或订阅号的 AppID 。 如果是游客模式,可以跳过本步骤 注意:如果我们不是用注册时绑定的管理员微信号,在手机上体验该小程序。那么我们还需要操作“绑定开发者”。即在“用户身份”-“开发者”模块,绑定上需要体验该小程序的微信号。本教程默认注册帐号、体验都是使用管理员微信号。 2. 创建项目 我们需要通过开发者工具,来完成小程序创建和代码编辑。 开发者工具安装完成后,打开并使用微信扫码登录。选择创建“项目”,填入上文获取到的 AppID ,设置一个本地项目的名称(非小程序名称),比如“我的第一个项目”,并选择一个本地的文件夹作为代码存储的目录,点击“新建项目”就可以了。 为方便初学者了解微信小程序的基本代码结构,在创建过程中,如果选择的本地文件夹是个空文件夹,开发者工具会提示,是否需要创建一个 quick start 项目。选择“是”,开发者工具会帮助我们在开发目录里生成一个简单的 demo。 项目创建成功后,我们就可以点击该项目,进入并看到完整的开发者工具界面,点击左侧导航,在“编辑”里可以查看和编辑我们的代码,在“调试”里可以测试代码并模拟小程序在微信客户端效果,在“项目”里可以发送到手机里预览实际效果。 3. 编写代码 创建小程序实例 点击开发者工具左侧导航的“编辑”,我们可以看到这个项目,已经初始化并包含了一些简单的代码文件。最关键也是必不可少的,是 app.js、app.json、app.wxss 这三个。其中,.js后缀的是脚本文件,.json后缀的文件是配置文件,.wxss后缀的是样式表文件。微信小程序会读取这些文件,并生成小程序实例。 下面我们简单了解这三个文件的功能,方便修改以及从头开发自己的微信小程序。 app.js是小程序的脚本代码。我们可以在这个文件中监听并处理小程序的生命周期函数、声明全局变量。调用框架提供的丰富的 API,如本例的同步存储及同步读取本地数据。想了解更多可用 API,可参考 API 文档 //app.js App({ onLaunch: function () { //调用API从本地缓存中获取数据 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) }, getUserInfo:function(cb){ var that = this; if(this.globalData.userInfo){ typeof cb == "function" && cb(this.globalData.userInfo) }else{ //调用登录接口 wx.login({ success: function () { wx.getUserInfo({ success: function (res) { that.globalData.userInfo = res.userInfo; typeof cb == "function" && cb(that.globalData.userInfo) } }) } }); } }, globalData:{ userInfo:null } }) app.json 是对整个小程序的全局配置。我们可以在这个文件中配置小程序是由哪些页面组成,配置小程序的窗口
关键字:微信 应用号 开发教程原文: http://www.cnblogs.com/txw1958/p/weixin-yingyonghao.html 本文介绍微信应用号开发过程。 目前还处于内测阶段,微信只邀请了部分企业参与封测。想必大家都关心应用号的最终形态到底是什么样子?怎样将一个「服务号」改造成为「小程序」? 我们暂时以一款简单的第三方工具的实例,来演示一下开发过程吧—— 序言 开始开发应用号之前,先看看官方公布的「小程序」教程吧!(以下内容来自微信官方公布的「小程序」开发指南) 本文档将带你一步步创建完成一个微信小程序,并可以在手机上体验该小程序的实际效果。这个小程序的首页将会显示欢迎语以及当前用户的微信头像,点击头像,可以在新开的页面中查看当前小程序的启动日志。 1. 获取微信小程序的 AppID 首先,我们需要拥有一个帐号,如果你能看到该文档,我们应当已经邀请并为你创建好一个帐号。注意不可直接使用服务号或订阅号的 AppID。 利用提供的帐号,登录 https://mp.weixin.qq.com ,就可以在网站的「设置」-「开发者设置」中,查看到微信小程序的 AppID 了。 注意:如果我们不是用注册时绑定的管理员微信号,在手机上体验该小程序。那么我们还需要操作「绑定开发者」。即在「用户身份 - 开发者」模块,绑定上需要体验该小程序的微信号。本教程默认注册帐号、体验都是使用管理员微信号。 2. 创建项目 我们需要通过开发者工具,来完成小程序创建和代码编辑。 开发者工具安装完成后,打开并使用微信扫码登录。选择创建「项目」,填入上文获取到的 AppID,设置一个本地项目的名称(非小程序名称),比如「我的第一个项目」,并选择一个本地的文件夹作为代码存储的目录,点击「新建项目」就可以了。 为方便初学者了解微信小程序的基本代码结构,在创建过程中,如果选择的本地文件夹是个空文件夹,开发者工具会提示,是否需要创建一个 quick start 项目。选择「是」,开发者工具会帮助我们在开发目录里生成一个简单的 demo。 项目创建成功后,我们就可以点击该项目,进入并看到完整的开发者工具界面,点击左侧导航,在「编辑」里可以查看和编辑我们的代码,在「调试」里可以测试代码并模拟小程序在微信客户端效果,在「项目」里可以发送到手机里预览实际效果。 3. 编写代码 点击开发者工具左侧导航的「编辑」,我们可以看到这个项目,已经初始化并包含了一些简单的代码文件。最关键也是必不可少的,是 app.js、app.json、app.wxss 这三个。其中,.js 后缀的是脚本文件,.json 后缀的文件是配置文件,.wxss 后缀的是样式表文件。微信小程序会读取这些文件,并生成小程序实例。 下面我们简单了解这三个文件的功能,方便修改以及从头开发自己的微信小程序。 app.js 是小程序的脚本代码。我们可以在这个文件中监听并处理小程序的生命周期函数、声明全局变量。调用 MINA 提供的丰富的 API,如本例的同步存储及同步读取本地数据。 app.json 是对整个小程序的全局配置。我们可以在这个文件中配置小程序是由哪些页面组成,配置小程序的窗口 背景色,配置导航条样式,配置默认标题。注意该文件不可添加任何注释。 app.wxss 是整个小程序的公共样式表。我们可以在页面组件的 class 属性上直接使用 app.wxss 中声明的样式规则。 3. 创建页面 在这个教程里,我们有两个页面,index 页面和 logs 页面,即欢迎页和小程序启动日志的展示页,他们都在 pages 目录下。微信小程序中的每一个页面的【路径 + 页面名】都需要写在 app.json 的 pages 中,且 pages 中的第一个页面是小程序的首页。 每一个小程序页面是由同路径下同名的四个不同后缀文件的组成,如:index.js、index.wxml、index.wxss、index.json。.js 后缀的文件是脚本文件,.json 后缀的文件是配置文件,.wxss 后缀的是样式表文件,.wxml 后缀的文件是页面结构文件。 index.wxml 是页面的结构文件: 本例中使用了 <view/>、<image/>、<text/> 来搭建页面结构,绑定数据和交互处理函数。 index.js 是页面的脚本文件,在这个文件中我们可以监听并处理页面的生命周期函数、获取小程序实例,声明并处理数据,响应页面交互事件等。 index.wxss 是页面的样式表: 页面的样式表是非必要的。当有页面样式表时,页面的样式表中的样式规则会层叠覆盖 app.wxss 中的样式规则。如果不指定页面的样式表,也可以在页面的结构文件中直接使用 app.wxss 中指定的样式规则。 index.json 是页面的配置文件: 页面的配置文件是非必要的。当有页面的配置文件时,配置项在该页面会覆盖 app.json 的 window 中相同的配置项。如果没有指定的页面配置文件,则在该页面直接使用 app.json 中的默认配置。 logs 的页面结构 logs 页面使用 <block/> 控制标签来组织代码,在 <block/> 上使用 wx:for-items 绑定 logs 数据,并将 logs 数据循环展开节点 运行结果如下: 4. 手机预览 开发者工具左侧菜单栏选择「项目」,点击「预览」,扫码后即可在微信客户端中体验。 目前,预览和上传功能尚无法实现,需要等待微信官方的下一步更新。 如你所见,微信官方给出的开发指南还非常简单,很多细节、代码和功能都没有明确的展示,所以接下来就到博卡君展示实力的时候啦!开发教程正式开始! 第一章:准备工作 做好准备工作很重要。开发一个微信应用号,你需要提前到微信的官方网站(weixin.qq.com)下载开发者工具。 1. 下载最新微信开发者工具,打开后你会看到该界面: 2. 点击「新建 web+」项目,随后出现如下画面: 3. 该页面内的各项内容需要注意—— AppID:依照官方解释来填。 Appname: 项目最外层文件夹名称,如你将其命名为「ABC」,则之后的全部项目内容均将保存在「/ABC/…」目录下。 本地开发目录:项目存放在本地的目录。 注:再次强调,如果你和团队成员共同开发该项目,则建议你们使用同样的目录名称及本地目录,以确保协同开发的统一性。如果你之前已有项目,则导入过程与以上内容近似,不再赘述。 4. 准备工作全部完成后,点击「新建项目」按钮,弹出框点「确定」。 5. 如上图所示,此刻,微信开发者工具已经为你自动构建了一个初始的 demo 项目,该项目内包含了一个微信应用项目所需具备的基本内容和框架结构。点击项目名称(图中即「cards」)进入该项目,就能看到整个项目的基本架构了: 第二章:项目构架 微信目前用户群体非常庞大,微信推出公众号以后,火爆程度大家都看得到,也同样推动着 h5 的高速发展,随着公众号业务的需求越来越复杂,应用号现在的到来也是恰到好处。我们团队具体看了一两次文档后发现,它提供给开发者的方式也在发生全面的改变,从操作 DOM 转为操作数据,基于微信提供的一个过桥工具实现很多 h5 在公众号很难实现的功能,有点类似于 hybrid 开发,不同于 hybrid 开发的方式是:微信开放的接口更为严谨,结构必须采用他提供给我们的组件,外部的框架和插件都不能在这里使用上,让开发者完全脱离操作 DOM,开发思想转变很大。 工欲善其事,必先利其器。理解它的核心功能非常重要,先了解它的整个运作流程。 生命周期: 在index.js里面: 开发者工具上 Console 可以看到: 在首页 console 可以看出顺序是 App Launch-->App Show-->onload-->onShow-->onReady。 首先是整个 app 的启动与显示,app 的启动在 app.js 里面可以配置,其次再进入到各个页面的加载显示等等。 可以想象到这里可以处理很多东西了,如加载框之类的都可以实现等等。 路由: 路由在项目开发中一直是个核心点,在这里其实微信对路由的介绍很少,可见微信在路由方面经过很好的封装,也提供三个跳转方法。 wx.navigateTo(OBJECT):保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。 wx.redirectTo(OBJECT):关闭当前页面,跳转到应用内的某个页面。 wx.navigateBack():关闭当前页面,回退前一页面。 这三个基本上使用足够,在路由方面微信封装的很好,开发者根本不用去配置路由,往往很多框架在路由方面配置很繁琐。 组件: 此次微信在组件提供方面也是非常全面,基本上满足项目需求,故而开发速度非常快,开发前可以认真浏览几次,开发效率会很好。 其它: 任何外部框架以及插件基本上无法使用,就算原生的 js 插件也很难使用,因为以前我们的 js 插件也基本上全部是一操作 dom 的形式存在,而微信应用号此次的架构是不允许操作任何 dom,就连以前我们习惯使用的动态设置的rem.js也是不支持的。 此次微信还提供了 WebSocket,就可以直接利用它做聊天,可以开发的空间非常大。 跟公众号对比我们发现,开发应用号组件化,结构化,多样化。新大陆总是充满着惊喜,更多的彩蛋等着大家来发现。 接下来开始搞一些简单的代码了! 1. 找到项目文件夹,导入你的编辑器里面。在这里,我使用了 Sublime Text 编辑器。你可以根据自己的开发习惯选择自己喜欢的编辑器。 2. 接下来,你需要根据自己的项目内容调整项目结构。在范例项目中,「card_course」目录下面主要包含了「tabBar」页面以及该应用的一些配置文件。 3. 示例项目的「tabBar」是五个菜单按钮: 4. 找到「app.json」文件,用来配置这个五个菜单。在代码行中找到「”tabBar”」: 你可以根据实际项目需求更改,其中: 「Color」是底部字体颜色,「selectedColor」是切换到该页面高亮颜色,「borderStyle」是切换菜单上面的一条线的颜色,「backgroundColor」是底部菜单栏背景颜色。文字描述较为抽象,建议你一一调试并查看其效果,加深印象。 「“list”」下的代码顺序必须依次放置,不能随便更改。 「”pagePath”」之后的文件名内,「.wxml」后缀被隐藏起来了,这是微信开发代码中人性化的一点——帮你节约写代码的时间,无须频繁声明文件后缀。 「”iconPath”」为未获得显示页面的图标路径,这两个路径可以直接是网络图标。 「”selectedIconPath”」为当前显示页面高亮图标路径,可以去掉,去掉之后会默认显示为「”iconPath”」的图标。 「”Text”」为页面标题,也可以去掉,去掉之后纯显示图标,如只去掉其中一个,该位置会被占用。 注意:微信的底部菜单最多支持五栏(五个 icons),所以在你设计微信应用的 UI 和基本架构时就要预先考虑好菜单栏的排布。 5. 根据以上代码规则,我做好了示例项目的基本架构,供你参考: 6. 「Json」文件配置好后,「card_course」的基本结构入上图所示,不需要的子集都可以暂时删除,缺少的子集则需要你主动新建。删除子集时记得顺带检查一下「app.json」里的相关内容是否已经一并删除。 注意:我个人建议新建一个「wxml」文件的同时,把对应的「js」和「wxss」文件一起新建好,因为微信应用号的配置特点就是解析到一个「wxml」文件时,会同时在同级目录下找到同文件名的「js」和「wxss」文件,所以「js」文件需及时在「app.json」里预先配置好。 编写「wxml」时,根据微信应用号提供的接口编码即可,大部分就是以前的「div」,而我们现在就用「view」即可。需要用其它子集时,可以根据微信提供的接口酌情选择。 使用「class」名来设置样式,「id」名在这里基本没有什么用处。主要操作数据,不操作「dom」。 7. 以上是示例项目首页的「wxml」编码。从图中就可以看出,实现一个页面代码量非常少。 8. 「Wxss」文件是引入的样式文件,你也可以直接在里面写样式,示例中采用的是引入方式: 9. 修改代码后刷新一次,可以看到未设背景的「view」标签直接变成了粉色。 注意:修改「wxml」和「wxss」下的内容后,直接 F5 刷新就能直接看到效果,修改「js」则需点击重启按钮才能看到效果。 10. 另外,公共样式可以在「app.wxss」里直接引用。 11. 「Js」文件需要在「app.json」文件的「”page”」里预先配置好。为了项目结构清晰化,我在示例项目中的「index」首页同级目录新建其它四个页面文件,具体如下: 经过以上步骤,案例中的五个底部菜单就全部配置完毕了。
天赋秉异的人永远是少数,剩下的都是资质平庸的芸芸众生。相信即使只是普通人,也有一颗不甘于平庸的心。那么资质平庸的人该如何在职场上做出一番成就呢? 其实以大多数人的努力程度之低,根本轮不到拼天赋。你需要的是比别人更加熟悉职场的规则、遵守规则、利用规则,这个过程也是“被社会与职场的规律驯化”的过程。“被驯化”是无法避免的,只有熟悉“游戏规则”,才能更好地“玩游戏”。 一名百度员工在离职时总结出11条职场心得,希望能帮助你更好适应职场人生。 1、你有“同理心”吗? 什么叫“同理心”? 说复杂点儿,同理心就是站在当事人的角度和位置上,客观地理解当事人的内心感受,且把这种理解传达给当事人的一种沟通交流方式。 说简单点儿,同理心就是“己所不欲,勿施于人”。将心比心,也就是设身处地去感受、去体谅他人。说白了,同理心就是“情商”。 具体点说:同理心就是,领导交办一项工作,你要读懂他的目的、看清他的用意。 我经常遇到这样的情况:给团队成员安排工作时,一再询问“我说明白了吗”“有没有问题”,再三确认后,提交上来的东西仍然答非所问。所以我在接受任务时,总会向领导确认:你想要的是什么?你的目的是什么?了解这个以后,就可以站在他的角度,有效的帮他解决问题。 2、听话,出活 什么叫“听话”?有句老话叫“干活不由东,累死也无功”,谁是“东”啊?你的直属领导就是“东”,大部分时候,听他的话准没错儿。 根据我的经验,一般来说,领导都比你水平高,起码在一点上是这样:他比你信息更全面、判断的更准确。因为领导更容易接触到更高层,更了解更高层的意图,他知道的你不知道,你在自己的角度上认为“这么做对”,但领导在更高的层面,并不一定这么看。 什么叫“出活”?就是领导给你的工作,你得按时完成并且汇报总结。如果这个工作要持续较长时间,那么你需要阶段性的给领导反馈。 我们经常犯一个错误,领导安排的工作,他不问你也不说,黑不提白不提这事儿就算过去了。过去了?哪儿那么容易啊!领导都记着呢,你等他问你的时候——“诶小陈,上次安排你做的那事儿怎么样了?”——他就已经在心里给你写上了标签:“不靠谱”。一个“不靠谱”需要用十个“靠谱”来扭转,两个“不靠谱”就很难转变印象,三个“不靠谱”你就没有机会了。 3、要想人前显贵,必须背地里受罪 道理并不难懂,就是真到受苦的时候就含糊了。 有的人会说,我年纪轻轻的为什么不好好享受生活啊?这种想法很普遍,这本是一个价值观的问题,没什么可说的,一个人想怎么生活都对。但是有一些朋友是在追求理想和享受生活中纠结的,和这些朋友,是可以聊的。 马云曾经说过:我们追求的应是人生的大平衡,而不是一时一日的小平衡(大意如此)。新东方也有一句话说:怕吃苦吃苦一辈子,不怕苦吃苦半辈子。两句话大意相同,值得深思。 4、能忍多大事儿,就能成多大事儿 有一天加班,晚上2点钟到家,收到老板的一封邮件,批评我工作不到位。我收到邮件后就很崩溃,还很委屈。于是当即奋笔疾书,回邮件!解释我是如何工作的,我做的如何有道理,我做的如何有效果……写了2000多字。 写完了,我好像冷静了一些,我就琢磨一个事儿:如果我是老板,我对一个员工工作不满意,于是我给他写了封邮件批评他,我想看到的是他洋洋洒洒的解释和辩解吗?显然不是啊。然后我就突然明白了,于是我把那2000多字都删了,简单回复了一句话,大意是:我会反思工作的问题,然后尽快整改。 两个月后我晋升了。在我的晋升仪式上,我对我老板说起这件事,他对我说,我知道你很委屈,我就是想看看你在面对委屈和压力时,会有怎样的反应,这体现了一个人的成熟程度。 5、总躲着领导,你就危险了 不少人躲着领导,尽量少跟领导说话、绕着领导走。因为跟领导近了事儿就多,不跟领导多接触,事儿少,多清闲。这是“一叶障目,不见泰山”。 如果你想在工作上取得一些成绩,我建议还是应该主动的多和领导沟通。领导在平时开会时说的多是大面儿上的话,真话、有用的话、有价值的话不一定说。这并不是他不想说,而是没机会说。 有心的员工会随时抽时间和领导沟通、增加私人交流的机会:一起吃饭、一起抽烟、一起上下班、甚至一起打球K歌……通过这样的机会,你可以了解领导对于你的看法、对于工作的观点,这些都有益于你调整自己的工作的方式。 有朋友担心这样做会引起领导反感,其实完全不会,领导们多是孤独的,如果他发现有一个员工虚心向他请教、积极分享工作的思考,他是非常高兴的。 老板也是人,大家用人类的方式沟通,一切会变得简单很多。 6、帮助别人千万别吝啬 当你正在忙于某项工作时,有同事来向你“求助”,很多时候我们会很直接、甚至粗暴的拒绝,殊不知这样做正在给你今后的工作种下麻烦的种子。 风水轮流转,在一家公司里,大家的工作互相交叉的几率很大,说不定你会用上谁,这些人脉关系需要平时去维护。今天你帮助了人家,说不定明天对方就会成为你的救命稻草,这非常可能。 7、目标再目标,量化再量化 没有目标的,都不叫工作;没有量化的,都不叫目标。 在接受一项工作时,先问目标是什么;在布置一项工作时,先交代目标是什么。这个不说清楚,都是扯淡。 不想成为蒙着眼睛拉磨的驴?那么除了清楚的知道自己的目标外,还得知道你的部门、你的公司的目标,最关键的,你需要知道,你的工作在总体目标中处在什么地位、扮演什么角色。如果你发现,你工作的目标和总体目标关系很小、甚至没有关系,那么你就很容易被拿掉。 8、找到解决问题的办法是我的义务 领导安排的工作,不能说“我做不了”、“我做不到”。 公司请我们来工作,是为了解决问题的,如果不能解决问题,我们就没有价值。工作推进中遇到困难,无法继续进行,这是很正常的事儿,我们需要做的是主动寻找答案和办法,哪怕你的办法不妥,那么就去问,但无论如何不能对你的领导说,我不会。 解决问题的能力是员工最关键的能力,没有之一。在工作中遇到困难特别正常,在这时,我们有一项义务,就是找到解决问题的办法。 9、尽量不说“不是我,我没有” 尽量不说“不是我”、“没有我”这样的话,因为这些话毫无作用,领导听惯了这样的推卸之词,丝毫不会为之所动。 此时如果能够主动承担责任,反而体现了一种担当。即便真是被冤枉了,当场辩解往往也不是最明智的选择,可以先保持沉默,私下找机会和领导进行沟通。 10、“言多必失”死得惨 在公司里,少说闲话,不说是非话,不做是非人。 你就相信一点:你说的每句话,你的老板都会知道。好话可能不一定,坏话则是一定的。还是做个正直的人吧,这样最简单,也受益最大。正直人的原则是:批评当面说,赞美背后讲。 11、知道什么时候离开 好多同事和朋友和我聊过离职的话题,我对朋友们的建议是,如果你因为觉得工作不爽,那就别离职,因为甭管到哪里,都会不爽:老板不喜欢、同事不可爱、工作太劳累、关系太复杂……我以我在多家大公司工作的经历担保:几乎所有我工作过的公司,令人不爽的事儿都是一样的。 那么什么时候离开呢?有两种情况: 1、在这家公司,你已经没有上升的空间、无法学习到更多的东西了; 2、在这家公司,你已学到足够的知识,可以在新领域或新平台上一展身手了。
关键字:网站统计 设计 实现 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/website-statistic-analysis.html 本文简要介绍网站统计功能的设计与实现。 本文分为以下五个部分: 埋点设计与实现 页面引入 数据接收 数据入库 统计分析 一、埋点设计与实现 在JavaScript中,包含了很多对象,可以用于获取用户的数据。比如Document对象用于分析每个载入浏览器的 HTML 文档,可以获得当前文档的域名、URL、及当前文档的标题;Navigator对象包含有关浏览器的信息,可以得到运行浏览器的userAgent的值,当前系统的语言;而Screen对象则可以获得当前屏幕的相关信息。通过这些对象,我们可以得到一个相当完备的用户信息。另外,通过其他接口,还可以得到用户的mac地址及IP地址,继而可以分析出用户的机器及所在省市区地址等。 我们使用javascript获取访问信息,将统计代码伪装成图片通过浏览器访问触发,代码实现如下。 二、页面引入 在要做统计的web页面中引入统计脚本,并主动将其他接口获得的mac及ip地址另外传入,一个简易的页面设计如下代码所示。 三、数据接收 在后台接口中接收上报上来的数据。我们使用php程序获取get及post的数据来接收。 上述接口程序获得的文件日志中数据如下所示。 17:38:25 http://www.fangbei.org?domain=www.fangbei.org&url=http%3A%2F%2Fwww.fangbei.org%2F_test%2Fstat.html&title=%e6%96%b9%e5%80%8d%e5%b7%a5%e4%bd%9c%e5%ae%a4&referrer=&sh=1920&sw=1080&cd=24&useragent=Mozilla%2F5.0%20(Linux%3B%20U%3B%20Android%205.1.1%3B%20zh-cn%3B%20Mi-4c%20Build%2FLMY47V)%20AppleWebKit%2F533.1%20(KHTML%2C%20like%20Gecko)Version%2F4.0%20MQQBrowser%2F5.4%20TBS%2F025483%20Mobile%20Safari%2F533.1%20MicroMessenger%2F6.3.9.48_refecd3e.700%20NetType%2FWIFI%20Language%2Fzh_CN&platform=Linux%20aarch64&language=zh-CN&usermac=185E0F88F5EF&apmac=185E0F88F5F0 17:38:25 17:38:25 _GET: Key: domain; Value: www.fangbei.org 17:38:25 _GET: Key: url; Value: http://www.fangbei.org/_test/stat.html 17:38:25 _GET: Key: title; Value: 方倍工作室 17:38:25 _GET: Key: referrer; Value: 17:38:25 _GET: Key: sh; Value: 1920 17:38:25 _GET: Key: sw; Value: 1080 17:38:25 _GET: Key: cd; Value: 24 17:38:25 _GET: Key: useragent; Value: Mozilla/5.0 (Linux; U; Android 5.1.1; zh-cn; Mi-4c Build/LMY47V) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025483 Mobile Safari/533.1 MicroMessenger/6.3.9.48_refecd3e.700 NetType/WIFI Language/zh_CN 17:38:25 _GET: Key: platform; Value: Linux aarch64 17:38:25 _GET: Key: language; Value: zh-CN 17:38:25 _GET: Key: usermac; Value: 185E0F88F5EF 17:38:25 _GET: Key: apmac; Value: 185E0F88F5F0 17:38:43 http://www.fangbei.org?domain=www.fangbei.org&url=http%3A%2F%2Fwww.fangbei.org%2F_test%2Fstat.html&title=%e6%96%b9%e5%80%8d%e5%b7%a5%e4%bd%9c%e5%ae%a4&referrer=&sh=1184&sw=720&cd=24&useragent=Mozilla%2F5.0%20(Linux%3B%20U%3B%20Android%204.4.2%3B%20zh-cn%3B%20H60-L01%20Build%2FHDH60-L01)%20AppleWebKit%2F533.1%20(KHTML%2C%20like%20Gecko)Version%2F4.0%20MQQBrowser%2F5.4%20TBS%2F025489%20Mobile%20Safari%2F533.1%20MicroMessenger%2F6.3.9.48_refecd3e.700%20NetType%2FWIFI%20Language%2Fzh_CN&platform=Linux%20armv7l&language=zh-CN&usermac=185E0F88F5EF&apmac=185E0F88F5F0 17:38:43 17:38:43 _GET: Key: domain; Value: www.fangbei.org 17:38:43 _GET: Key: url; Value: http://www.fangbei.org/_test/stat.html 17:38:43 _GET: Key: title; Value: 方倍工作室 17:38:43 _GET: Key: referrer; Value: 17:38:43 _GET: Key: sh; Value: 1184 17:38:43 _GET: Key: sw; Value: 720 17:38:43 _GET: Key: cd; Value: 24 17:38:43 _GET: Key: useragent; Value: Mozilla/5.0 (Linux; U; Android 4.4.2; zh-cn; H60-L01 Build/HDH60-L01) AppleWebKit/533.1 (KHTML, like Gecko)Version/4.0 MQQBrowser/5.4 TBS/025489 Mobile Safari/533.1 MicroMessenger/6.3.9.48_refecd3e.700 NetType/WIFI Language/zh_CN 17:38:43 _GET: Key: platform; Value: Linux armv7l 17:38:43 _GET: Key: language; Value: zh-CN 17:38:43 _GET: Key: usermac; Value: 185E0F88F5EF 17:38:43 _GET: Key: apmac; Value: 185E0F88F5F0 17:38:50 http://www.fangbei.org?domain=www.fangbei.org&url=http%3A%2F%2Fwww.fangbei.org%2F_test%2Fstat.html&title=%e6%96%b9%e5%80%8d%e5%b7%a5%e4%bd%9c%e5%ae%a4&referrer=&sh=592&sw=360&cd=32&useragent=Mozilla%2F5.0%20(Linux%3B%20Android%204.4.2%3B%20H60-L01%20Build%2FHDH60-L01)%20AppleWebKit%2F537.36%20(KHTML%2C%20like%20Gecko)%20Version%2F4.0%20Chrome%2F30.0.0.0%20Mobile%20Safari%2F537.36&platform=Linux%20armv7l&language=zh-CN&usermac=185E0F88F5EF&apmac=185E0F88F5F0 17:38:50 17:38:50 _GET: Key: domain; Value: www.fangbei.org 17:38:50 _GET: Key: url; Value: http://www.fangbei.org/_test/stat.html 17:38:50 _GET: Key: title; Value: 方倍工作室 17:38:50 _GET: Key: referrer; Value: 17:38:50 _GET: Key: sh; Value: 592 17:38:50 _GET: Key: sw; Value: 360 17:38:50 _GET: Key: cd; Value: 32 17:38:50 _GET: Key: useragent; Value: Mozilla/5.0 (Linux; Android 4.4.2; H60-L01 Build/HDH60-L01) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Mobile Safari/537.36 17:38:50 _GET: Key: platform; Value: Linux armv7l 17:38:50 _GET: Key: language; Value: zh-CN 17:38:50 _GET: Key: usermac; Value: 185E0F88F5EF 17:38:50 _GET: Key: apmac; Value: 185E0F88F5F0 四、数据入库 要做统计分析,最终数据都要放放数据库, 数据库表设计如下 入库后如下所示 五、统计分析 最后,将获得的数据进行分析 比如昨天访问量的SQL查询语句如下 六、图形化输出 其他生成的统计图表如下 基于访问次数的二次分析-客户忠诚度的统计如下
关键字:支付宝 当面付 条码支付 扫码支付 二维码支付 订单查询 退款作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/alipay-f2fpay.html 本文介绍支付宝中当面付下属的条码支付、扫码支付、订单查询、退款申请的集成开发过程。 本文分为以下五个部分: 条码支付和扫码支付介绍 申请应用 密钥生成及配置 API及SDK集成 条码支付、扫码支付、订单查询、退款申请 注: 支付宝支付开发有一定的门槛,如果您愿意为知识付费来节省您宝贵的时间,请直接见底部说明。 一、条码支付及二维码支付介绍 1. 条码支付 条码支付是支付宝给到线下传统行业的一种收款方式。商家使用扫码枪等条码识别设备扫描用户支付宝钱包上的条码/二维码,完成收款。用户仅需出示付款码,所有收款操作由商家端完成。其使用场景如下: 业务流程: 使用步骤: 用户登陆支付宝钱包,点击首页“付款”,进入付款码界面; 收银员在商家收银系统操作生成订单,用户确认支付金额; 用户出示钱包的“付款码”,收银员用扫码设备来扫描用户手机上的条码/二维码后,商家收银系统提交支付; 付款成功后商家收银系统会拿到支付成功或者失败的结果。 2. 扫码支付 扫码支付,指用户打开支付宝钱包中的“扫一扫”功能,扫描商家展示在某收银场景下的二维码并进行支付的模式。该模式适用于线下实体店支付、面对面支付等场景。 其使用场景如下: 业务流程: 使用步骤: 用户登陆支付宝钱包,点击首页“付款-扫码付”,进入扫一扫界面; 收银员在商家收银系统操作生成支付宝订单,用户确认支付金额,并生成二维码; 用户使用钱包的“扫码付”,扫收银员提供的二维码,确认支付; 用户付款后商家收银系统会拿到支付成功或者失败的结果。 二、接口申请 企业在申请企业支付宝之后,进行功能申请并签约,然后在蚂蚁金服开放平台中申请应用如下(详细过程就略了) 然后在功能列表中,申请当面付这一功能,申请成功后如下。 这样,我们就有了当面付的权限了。 三、密钥生成 在支付宝当面付的接口中,使用了非对称加密算法,商户自己的公钥和私钥需要自己使用OpenSSL手动生成。对这些概念比较陌生的话,请先自行先了解一下密码学的相关知识。OpenSSL也可以从方倍工作室博客中找到。 下载支付宝官方提供的密钥生成工具OpenSSL,然后执行以下命令就可以生成公钥和私钥。 其中 genrsa -out rsa_private_key.pem 1024 是用于生成RSA私钥,执行后在程序目录中生成一个文件rsa_private_key.pem,其内容如下 -----BEGIN RSA PRIVATE KEY----- MIICXAIBAAKBgQCyffRONGd8Q/1kRh1cpsSRi360DXLHI7zxdPJGYe5HKDWF7u9b 3zZU9erZpM90XE7gZRKsxIgOurH4uqhmVRbto3e+LiYOyNpd6As3Q427KCTIT7aj hHicZ6GWhegTUiVLqiuWLsauQcbI6DO4GEZrlvAdzus0WcJiJOxW02rxSQIDAQAB AoGAXBJYyVaC4zj3Jph8YOStlR5N13bwdATdW/glWWT+0rnNEi90TQHRNvY7lNVN JgrPrTS182TVgjOPxmwSnebakhIuGIdPq99GLE4LGd5lKWTzkd84BMvhatfNsCCz cEVFqKg3tZd4t3fQ93FrILsnnZpLhiW53jIrStCkR3rx9OECQQDWMSHyc91hEVMQ qVNasbGEicKWxhoDqjdm2lHkBx4mrB9JEZFDs6MxWdajf2/Qw+tgtpN3YBcCDw/H nGHhQtStAkEA1VTyjOdAwWode8X4fu0IPq9+E19mcVOAJjLBH46mropwgOdj3raq T/ThaKeaydjabsTAiY2J18HiTiyH+1bGjQJBAKgRJXH5OFxSG7uXIbCofYJiFi34 g7EcfxxVcqxaaW4u4N2Uy0c0TXkL5T+lXzeQg8D/gfbJj0QuTVNzgdofdoECQBHY OznCFk6Xe8PguXqUhT4JG/iu4DjWjT+kuzbSjerHtcVylY4JpZFuoHRKoM4Fj6/4 UUqwRjmABFgZrX4+sfkCQCNI8RCZ6yprh5kEOePo3uazAlNENP8dKkhgqChawdK7 7NzlJ727Nt23STHFx6NkhzyruJGQ5Vx1Lkl0wKuKbXM= -----END RSA PRIVATE KEY----- 命令 rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 是用于生成RSA公钥,执行后在程序目录中生成一个文件rsa_public_key.pem,其内容如下 -----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyffRONGd8Q/1kRh1cpsSRi360 DXLHI7zxdPJGYe5HKDWF7u9b3zZU9erZpM90XE7gZRKsxIgOurH4uqhmVRbto3e+ LiYOyNpd6As3Q427KCTIT7ajhHicZ6GWhegTUiVLqiuWLsauQcbI6DO4GEZrlvAd zus0WcJiJOxW02rxSQIDAQAB -----END PUBLIC KEY----- 生成的这个RSA公钥,需要填写到应用中去,填写地址如下所示。私钥不需要填到配置中,到时候配置到代码中。 特别注意,密钥要去掉注释部分,且转换成一行字符,否则回车换行也成为密钥的一部分,将导致无法正常加解密。 同时,可以点击 “查看支付宝公钥”,将支付宝的公钥复制保存下来,后面的程序中将需要用到。 四、密钥生成API与密钥配置 公共参数 请求地址: 环境 HTTPS请求地址 正式环境 https://openapi.alipay.com/gateway.do 公共请求参数: 参数 类型 是否必填 最大长度 描述 app_id String 是 32 支付宝分配给开发者的应用ID method String 是 128 接口名称 format String 否 40 仅支持JSON charset String 是 10 请求使用的编码格式,如utf-8,gbk,gb2312等 sign_type String 是 10 商户生成签名字符串所使用的签名算法类型,目前支持RSA sign String 是 256 商户请求参数的签名串,详见签名 timestamp String 是 19 发送请求的时间,格式"yyyy-MM-dd HH:mm:ss" version String 是 3 调用的接口版本,固定为:1.0 notify_url String 否 256 支付宝服务器主动通知商户服务器里指定的页面http/https路径。 app_auth_token String 否 40 详见应用授权概述 biz_content String 是 - 请求参数的集合,最大长度不限,除公共参数外所有请求参数都必须放在这个参数中传递,具体参照各产品快速接入文档 请求参数 参数 类型 是否必填 最大长度 描述 out_trade_no String 必须 64 商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复 scene String 必须 32 支付场景 条码支付,取值:bar_code 声波支付,取值:wave_code auth_code String 必须 32 支付授权码 seller_id String 可选 28 如果该值为空,则默认为商户签约账号对应的支付宝用户ID total_amount Price 可选 11 订单总金额,单位为元, discountable_amount Price 可选 11 参与优惠计算的金额,单位为元 undiscountable_amount Price 可选 11 不参与优惠计算的金额,单位为元 subject String 必须 256 订单标题 body String 可选 128 订单描述 goods_detail GoodsDetail [] 可选 - 订单包含的商品列表信息,Json格式,其它说明详见商品明细说明 operator_id String 可选 28 商户操作员编号 store_id String 可选 32 商户门店编号 terminal_id String 可选 32 商户机具终端编号 alipay_store_id String 可选 32 支付宝的店铺编号 extend_params ExtendParams 可选 - 业务扩展参数 timeout_express String 可选 6 该笔订单允许的最晚付款时间,逾期将关闭交易。 royalty_info RoyaltyInfo 可选 - 描述分账信息,Json格式,其它说明详见分账说明 sub_merchant SubMerchant 可选 - 二级商户信息,当前只对特殊银行机构特定场景下使用此字段 公共响应参数 参数 类型 是否必填 最大长度 描述 code String 是 - 网关返回码,详见文档 msg String 是 - 网关返回码描述,详见文档 sub_code String 否 - 业务返回码,详见文档 sub_msg String 否 - 业务返回码描述,详见文档 sign String 是 - 签名,详见文档 响应参数 参数 类型 是否必填 最大长度 描述 trade_no String 必填 64 支付宝交易号 out_trade_no String 必填 64 商户订单号 buyer_logon_id String 必填 100 买家支付宝账号 total_amount Price 必填 11 交易金额 receipt_amount String 必填 11 实收金额 buyer_pay_amount Price 选填 11 买家付款的金额 point_amount Price 选填 11 使用积分宝付款的金额 invoice_amount Price 选填 11 交易中可给用户开具发票的金额 gmt_payment Date 必填 32 交易支付时间 fund_bill_list TradeFundBill [] 必填 - 交易支付使用的资金渠道 card_balance Price 选填 11 支付宝卡余额 store_name String 选填 512 发生支付交易的商户门店名称 buyer_user_id String 必填 28 买家在支付宝的用户id discount_goods_detail String 必填 - 本次交易支付所使用的单品券优惠的商品优惠信息 系统中配置如下 <?php $config = array ( //支付宝公钥 'alipay_public_key' => "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB", //商户私钥 'merchant_private_key' => "MIICXAIBAAKBgQCyffRONGd8Q/1kRh1cpsSRi360DXLHI7zxdPJGYe5HKDWF7u9b3zZU9erZpM90XE7gZRKsxIgOurH4uqhmVRbto3e+LiYOyNpd6As3Q427KCTIT7ajhHicZ6GWhegTUiVLqiuWLsauQcbI6DO4GEZrlvAdzus0WcJiJOxW02rxSQIDAQABAoGAXBJYyVaC4zj3Jph8YOStlR5N13bwdATdW/glWWT+0rnNEi90TQHRNvY7lNVNJgrPrTS182TVgjOPxmwSnebakhIuGIdPq99GLE4LGd5lKWTzkd84BMvhatfNsCCzcEVFqKg3tZd4t3fQ93FrILsnnZpLhiW53jIrStCkR3rx9OECQQDWMSHyc91hEVMQqVNasbGEicKWxhoDqjdm2lHkBx4mrB9JEZFDs6MxWdajf2/Qw+tgtpN3YBcCDw/HnGHhQtStAkEA1VTyjOdAwWode8X4fu0IPq9+E19mcVOAJjLBH46mropwgOdj3raqT/ThaKeaydjabsTAiY2J18HiTiyH+1bGjQJBAKgRJXH5OFxSG7uXIbCofYJiFi34g7EcfxxVcqxaaW4u4N2Uy0c0TXkL5T+lXzeQg8D/gfbJj0QuTVNzgdofdoECQBHYOznCFk6Xe8PguXqUhT4JG/iu4DjWjT+kuzbSjerHtcVylY4JpZFuoHRKoM4Fj6/4UUqwRjmABFgZrX4+sfkCQCNI8RCZ6yprh5kEOePo3uazAlNENP8dKkhgqChawdK77NzlJ727Nt23STHFx6NkhzyruJGQ5Vx1Lkl0wKuKbXM=", //编码格式 'charset' => "UTF-8", //支付宝网关 'gatewayUrl' => "https://openapi.alipay.com/gateway.do", //应用ID 'app_id' => "2016061501500000", //异步通知地址,只有扫码支付预下单可用 'notify_url' => "http://www.fangbei.org/alipay/notify.html", //最大查询重试次数 'MaxQueryRetry' => "10", //查询间隔 'QueryDuration' => "3" ); 其中支付宝公钥就是在前面中复制保存的,直接复制到程序中即可,而商户私钥是之前OpenSSL中生成的私钥。APPID是该服务的id号。 而这个异步通知将会接收扫码支付结果的通知。 五、条码支付、扫码支付、订单查询、退款申请 1. 条码支付 条码支付的参数配置如下 // (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线, // 需保证商户系统端不能重复,建议通过数据库sequence生成, $outTradeNo = "barpay" . date('Ymdhis') . mt_rand(100, 1000); $subject = "方倍工作室-支付宝-当面付-条码支付"; $totalAmount = 0.01; // (必填) 订单总金额,单位为元,不能超过1亿元 // (必填) 付款条码,用户支付宝钱包手机app点击“付款”产生的付款条码 $authCode = $_POST['auth_code']; //28开头18位数字 // 支付超时,线下扫码交易定义为5分钟 $timeExpress = "5m"; // 创建请求builder,设置请求参数 $barPayRequestBuilder = new AlipayTradePayContentBuilder(); $barPayRequestBuilder->setOutTradeNo($outTradeNo); $barPayRequestBuilder->setTotalAmount($totalAmount); $barPayRequestBuilder->setAuthCode($authCode); $barPayRequestBuilder->setTimeExpress($timeExpress); $barPayRequestBuilder->setSubject($subject); // 调用barPay方法获取当面付应答 $barPay = new AlipayTradeService($config); $barPayResult = $barPay->barPay($barPayRequestBuilder); switch ($barPayResult->getTradeStatus()) { case "SUCCESS": echo "支付宝支付成功:" . "<br>--------------------------<br>"; print_r($barPayResult->getResponse()); break; case "FAILED": echo "支付宝支付失败!!!" . "<br>--------------------------<br>"; if (!empty($barPayResult->getResponse())) { print_r($barPayResult->getResponse()); } break; case "UNKNOWN": echo "系统异常,订单状态未知!!!" . "<br>--------------------------<br>"; if (!empty($barPayResult->getResponse())) { print_r($barPayResult->getResponse()); } break; default: echo "不支持的交易状态,交易返回异常!!!"; break; } return; } 程序监测,最终提交的url如下 https://openapi.alipay.com/gateway.do?app_id=2016061501500000&version=1.0&format=json&sign_type=RSA&method=alipay.trade.pay&timestamp=2016-08-26+17%3A14%3A52&auth_token=&alipay_sdk=alipay-sdk-php-20160411&terminal_type=&terminal_info=&prod_code=&notify_url=&charset=UTF-8&app_auth_token=&sign=EMVoBAhPkW6B1m%2BoXytdbUpIxnIAq73jtiPhlH2VUYy4OcJQ2UiVTXWttw0y%2B7UEXHWILY8fYRDoNrJWSjBATrAqbGCLpPc4YBQSwtPCb%2F76d65dMQEyrEnk2sgcqhxCiJNKRoQjgAQmBQdHneerU7SwSNJ%2FfF%2F025yltZk5lzQ%3D 发送的json数据如下: { "scene":"bar_code", "out_trade_no":"barpay20160826051452680", "total_amount":0.01, "auth_code":"289743098358423535", "timeout_express":"5m", "subject":"方倍工作室-支付宝-当面付-条码支付" } 接收到的数据如下 { "alipay_trade_pay_response":{ "code":"10000", "msg":"Success", "buyer_logon_id":"118***@qq.com", "buyer_pay_amount":"0.01", "buyer_user_id":"2088002364008751", "fund_bill_list":[ { "amount":"0.01", "fund_channel":"ALIPAYACCOUNT" } ], "gmt_payment":"2016-08-26 17:14:59", "invoice_amount":"0.01", "open_id":"20880044751374809757987911112575", "out_trade_no":"barpay20160826051452680", "point_amount":"0.00", "receipt_amount":"0.01", "total_amount":"0.01", "trade_no":"2016082621001004750244100034" }, "sign":"pEDeMwh6x73t9LmWrZpGnVb1npnKtODw6+8MDUTurNPVWXR1JHT+x3cRt2G4SDNHzxkJTzSpUXjNylsWisRTnQJJzqRP5XMujxmaAHP/d5xXeyWasDag5Cj7yGD7t80buDAsdE4eoqQ6ox7KzJ6LwKcphOX13tI+Ukt1dGCQS5o=" } 2. 扫码支付 扫码支付的参数配置如下 // (必填) 商户网站订单系统中唯一订单号,64个字符以内,只能包含字母、数字、下划线, // 需保证商户系统端不能重复,建议通过数据库sequence生成, $outTradeNo = "qrpay".date('Ymdhis').mt_rand(100,1000); $subject = "方倍工作室-支付宝-当面付-扫码支付"; $totalAmount = "0.01"; // 支付超时,线下扫码交易定义为5分钟 $timeExpress = "5m"; // 创建请求builder,设置请求参数 $qrPayRequestBuilder = new AlipayTradePrecreateContentBuilder(); $qrPayRequestBuilder->setOutTradeNo($outTradeNo); $qrPayRequestBuilder->setTotalAmount($totalAmount); $qrPayRequestBuilder->setTimeExpress($timeExpress); $qrPayRequestBuilder->setSubject($subject); // 调用qrPay方法获取当面付应答 $qrPay = new AlipayTradeService($config); $qrPayResult = $qrPay->qrPay($qrPayRequestBuilder); // 根据状态值进行业务处理 switch ($qrPayResult->getTradeStatus()){ case "SUCCESS": echo "支付宝创建订单二维码成功:"."<br>---------------------------------------<br>"; $response = $qrPayResult->getResponse(); $qrcode = $qrPay->create_erweima($response->qr_code); echo $qrcode; print_r($response); break; case "FAILED": echo "支付宝创建订单二维码失败!!!"."<br>--------------------------<br>"; if(!empty($qrPayResult->getResponse())){ print_r($qrPayResult->getResponse()); } break; case "UNKNOWN": echo "系统异常,状态未知!!!"."<br>--------------------------<br>"; if(!empty($qrPayResult->getResponse())){ print_r($qrPayResult->getResponse()); } break; default: echo "不支持的返回状态,创建订单二维码返回异常!!!"; break; } 生成的提交请求URL如下 https://openapi.alipay.com/gateway.do?app_id=2016061501500000&version=1.0&format=json&sign_type=RSA&method=alipay.trade.precreate&timestamp=2016-08-26+17%3A38%3A13&auth_token=&alipay_sdk=alipay-sdk-php-20160411&terminal_type=&terminal_info=&prod_code=&notify_url=http%3A%2F%2F123.daoqidata.com%2Fweixin%2Frawpost.php&charset=UTF-8&app_auth_token=&sign=ayYiJRZ63RomVEt8Ayz58Uiyv3y5IrbbX8CTfX6zNHkT%2Fu11U7ISUYWCXjrwrwCo2Oq2tdo%2FjtuhrBbDp5ULnTmuBBUktQDCCF53PF5yiUDGikxUPFYugeUrTg3gw4DqxOiNKM6ZB6MI0n%2F9M78a%2FnP8GtZ4WthyHIl%2B%2FozSyT4%3D 发送的json数据如下: { "out_trade_no":"qrpay20160826053813582", "total_amount":"0.01", "timeout_express":"5m", "subject":"方倍工作室-支付宝-当面付-扫码支付" } 返回的数据如下: { "alipay_trade_precreate_response":{ "code":"10000", "msg":"Success", "out_trade_no":"qrpay20160826053813582", "qr_code":"https://qr.alipay.com/bax00885xbhszseo9l7p404d" }, "sign":"VfNTGo2WMZ+2CE1L05lNYWtFn4inHXO/tUaBZIBHN4fPlXnCvyc9IhS8S7wa3FYw23G30luEPEHkZWobnfpUjILonmExZVElHv3ylINz+Q2mQ5M8Sb/d61YPvf4Bgy1OvlrT4D3H/i3judmzEDBrOyFN9kB9vSkKaYC+b6L41Zw=" } 其中的https://qr.alipay.com/bax00885xbhszseo9l7p404d 就是二维码链接地址,使用接口将其成二维码后如下所示。 当支付宝用户扫码的时候,接口通知将收到如下数据 { "notify_id":"4c2c04c3cc50e978d44212febe7c3f0lse", "seller_email":"pay***@fangbei.org", "notify_type":"trade_status_sync", "sign":"R0iRdYmSQ0+zuSUGLzkutHcR40hoOp+CcKojVBCMa1uji3rqQFe5XeHoJB1nMBCApE3zXPKhXMdLis109ngPbGy+NUEBR7YZjYuR/hXq3WXeYfZ8aiWLvloZHrF7dQWxDho/VHYexaLeqvRi/03m0HxrwhZKUOu1eS9wMgZOlqQ=", "trade_no":"2016082621001004750241229810", "buyer_id":"2088002364008751", "app_id":"2016061501500000", "gmt_create":"2016-08-26 18:20:37", "out_trade_no":"qrpay20160826062009757", "seller_id":"2088421202724253", "notify_time":"2016-08-26 18:20:37", "subject":"方倍工作室-支付宝-当面付-扫码支付", "trade_status":"WAIT_BUYER_PAY", "open_id":"20880044751374809757987911112575", "total_amount":"0.01", "sign_type":"RSA", "buyer_logon_id":"118***@qq.com" } 当用户输入密码付款成功之后,将收到如下数据 { "fund_bill_list":"[{"amount":"0.01","fundChannel":"ALIPAYACCOUNT"}]", "subject":"方倍工作室-支付宝-当面付-扫码支付", "trade_no":"2016082621001004750241229810", "gmt_create":"2016-08-26 18:20:37", "notify_type":"trade_status_sync", "total_amount":"0.01", "out_trade_no":"qrpay20160826062009757", "invoice_amount":"0.01", "open_id":"20880044751374809757987911112575", "seller_id":"2088421202724253", "notify_time":"2016-08-26 18:20:50", "trade_status":"TRADE_SUCCESS", "gmt_payment":"2016-08-26 18:20:50", "seller_email":"pay***@fangbei.org", "receipt_amount":"0.01", "buyer_id":"2088002364008751", "app_id":"2016061501500000", "notify_id":"56f97611ee609f46384b188b409e75else", "buyer_logon_id":"118***@qq.com", "sign_type":"RSA", "buyer_pay_amount":"0.01", "sign":"nf/KJryACk0utqlNrnuYMiSnYw6HsxqpJPk2O5MhCZ+wZUVQbrD3sq5POO3GU7LSRoSiUUIO4JEYEL12Ek2+w3lTcLS9WEi60sYowPOcJEYGmVfNZbVR6+k7yO5au2WIkM3MKsxm2XxIB9xPMmRDACGhvqZ2BXUAQujkPk1FT0s=", "point_amount":"0.00" } 3. 订单查询 订单查询的参数配置如下 ////获取商户订单号 $out_trade_no = trim($_POST['out_trade_no']); //第三方应用授权令牌,商户授权系统商开发模式下使用 $appAuthToken = "";//根据真实值填写 //构造查询业务请求参数对象 $queryContentBuilder = new AlipayTradeQueryContentBuilder(); $queryContentBuilder->setOutTradeNo($out_trade_no); $queryContentBuilder->setAppAuthToken($appAuthToken); //初始化类对象,调用queryTradeResult方法获取查询应答 $queryResponse = new AlipayTradeService($config); $queryResult = $queryResponse->queryTradeResult($queryContentBuilder); //根据查询返回结果状态进行业务处理 switch ($queryResult->getTradeStatus()){ case "SUCCESS": echo "支付宝查询交易成功:"."<br>--------------------------<br>"; print_r($queryResult->getResponse()); break; case "FAILED": echo "支付宝查询交易失败或者交易已关闭!!!"."<br>--------------------------<br>"; if(!empty($queryResult->getResponse())){ print_r($queryResult->getResponse()); } break; case "UNKNOWN": echo "系统异常,订单状态未知!!!"."<br>--------------------------<br>"; if(!empty($queryResult->getResponse())){ print_r($queryResult->getResponse()); } break; default: echo "不支持的查询状态,交易返回异常!!!"; break; } 最终提交的url如下 https://openapi.alipay.com/gateway.do?app_id=2016061501500000&version=1.0&format=json&sign_type=RSA&method=alipay.trade.query&timestamp=2016-08-26+18%3A27%3A07&auth_token=&alipay_sdk=alipay-sdk-php-20160411&terminal_type=&terminal_info=&prod_code=&notify_url=&charset=UTF-8&app_auth_token=&sign=eIuYJtes95quAN3X9eXbQzBa%2FCvm5QgQ0ToUsS8MSkCjhZACYpnU7ZT5MuD31lPZPFHVEjCKsdWiq4tuNtJPFPxirg7pkTiT09C%2Bz8PsUA844Y7hjkkX%2B4CVZcGtO11m3Ap0JECrtZW8hhJTE9bPY1v43X2BSL5Cp3Ulpac1FsM%3D 发送的json数据如下: { "out_trade_no":"qrpay20160826053813582" } 接收到的数据如下 { "alipay_trade_query_response":{ "code":"10000", "msg":"Success", "buyer_logon_id":"118***@qq.com", "buyer_pay_amount":"0.01", "buyer_user_id":"2088002364008751", "fund_bill_list":[ { "amount":"0.01", "fund_channel":"ALIPAYACCOUNT" } ], "invoice_amount":"0.01", "open_id":"20880044751374809757987911112575", "out_trade_no":"qrpay20160826053813582", "point_amount":"0.00", "receipt_amount":"0.01", "send_pay_date":"2016-08-26 17:38:58", "total_amount":"0.01", "trade_no":"2016082621001004750239053830", "trade_status":"TRADE_SUCCESS" }, "sign":"E2MxjdAhW/EqRFNkZgy/Y//dA5Cmb54Hnqa0cjBz+ZcFTULi1lvFms93onP7cpVK/fI7YxbkZTKBPk29o4aeWKXlSYCrT92domAyqahzYCA7/5A3Msc/awALYrFOdWyJJdlncWdFRN9hx52iVRIjxvLJ0hIMVIQqEDavG28HPbo=" } 4. 订单退款 订单退款的参数配置如下 $out_trade_no = trim($_POST['out_trade_no']); $refund_amount = trim($_POST['refund_amount']); $out_request_no = trim($_POST['out_request_no']); //第三方应用授权令牌,商户授权系统商开发模式下使用 $appAuthToken = "";//根据真实值填写 //创建退款请求builder,设置参数 $refundRequestBuilder = new AlipayTradeRefundContentBuilder(); $refundRequestBuilder->setOutTradeNo($out_trade_no); $refundRequestBuilder->setRefundAmount($refund_amount); $refundRequestBuilder->setOutRequestNo($out_request_no); $refundRequestBuilder->setAppAuthToken($appAuthToken); //初始化类对象,调用refund获取退款应答 $refundResponse = new AlipayTradeService($config); $refundResult = $refundResponse->refund($refundRequestBuilder); //根据交易状态进行处理 switch ($refundResult->getTradeStatus()){ case "SUCCESS": echo "支付宝退款成功:"."<br>--------------------------<br>"; print_r($refundResult->getResponse()); break; case "FAILED": echo "支付宝退款失败!!!"."<br>--------------------------<br>"; if(!empty($refundResult->getResponse())){ print_r($refundResult->getResponse()); } break; case "UNKNOWN": echo "系统异常,订单状态未知!!!"."<br>--------------------------<br>"; if(!empty($refundResult->getResponse())){ print_r($refundResult->getResponse()); } break; default: echo "不支持的交易状态,交易返回异常!!!"; break; } 最终提交的url如下 https://openapi.alipay.com/gateway.do?app_id=2016061501500000&version=1.0&format=json&sign_type=RSA&method=alipay.trade.refund&timestamp=2016-08-26+18%3A47%3A35&auth_token=&alipay_sdk=alipay-sdk-php-20160411&terminal_type=&terminal_info=&prod_code=&notify_url=&charset=UTF-8&app_auth_token=&sign=Y1c5qWglAQ0t3brViEtqFnIJRQMn%2Fl9vMla1xgXKcExercJopMyS2rPOHaw%2F2PJEOKJC7r9qAfDGkNq4LHzXhBrD8sxLPqImPS6aWcW9p8s%2FzC2oQCJnLfaPx6lh8veHarj4WzDayeZLA48ttoQLjuMGPrITgOXYjHHyUKdBqSs%3D 发送的json数据如下: { "out_trade_no":"qrpay20160826053813582", "refund_amount":"0.01", "out_request_no":"1" } 接收到的数据如下 { "alipay_trade_refund_response":{ "code":"10000", "msg":"Success", "buyer_logon_id":"123***@qq.com", "buyer_user_id":"2088002364008751", "fund_change":"Y", "gmt_refund_pay":"2016-08-26 18:47:41", "open_id":"20880044751374809757987911112575", "out_trade_no":"qrpay20160826053813582", "refund_detail_item_list":[ { "amount":"0.01", "fund_channel":"ALIPAYACCOUNT" } ], "refund_fee":"0.01", "send_back_fee":"0.01", "trade_no":"2016082621001004750239053830" }, "sign":"YDNSMpX5y0rQEs0ZbfNxRFVIp8hf0W30OR74cMtwKVPO2BYee6TQC+pbnwESSZ2XSGLozTyy7o+SIa07L+FMhDv/PTt6QX1mVgQv7RhzoDkls0zDRS/5/fy9Oyj01XS1wb8Od/93iNLZDkd2yw9g0He6qGYlpcXutkmwuASd7BM=" } 我们提供支付宝接口配置SDK Demo一条龙服务,费用300元(含PHP源码提供、密钥生成、配置调试,直到demo跑通为止),需要加QQ 1354386063 有扫码支付定制开发服务,3000元起步,需要加QQ 1354386063
1. 设置Redis密码,以提供远程登陆打开redis.conf配置文件,找到requirepass,然后修改如下: requirepass yourpassword yourpassword就是redis验证密码,设置密码以后发现可以登陆,但是无法执行命令了。命令如下: redis-cli -h 127.0.0.1 -p 6379//启动redis客户端,并连接服务器 keys * //输出服务器中的所有key 报错如下 (error) ERR operation not permitted 这时候你可以用授权命令进行授权,就不报错了命令如下: auth youpassword 2. PHP访问Redis $redis = new Redis(); $conn = $redis->connect('localhost', 6379); $auth = $redis->auth('20160601'); //设置密码 var_dump($auth); $redis->set('access_token', "123213213213213213"); $redis->set('expired_time', 1464344863); var_dump($redis->get("access_token")); var_dump($redis->get("expired_time"));
本文介绍将家用普通路由器设置成微信连WiFi路由器的方法。 1. 登录路由器后台,找到无线网络的SSID名称和密码的地方。将SSID和密码分别设置为: SSID: FreeWiFi 密码: WX12345678 比如TP-LINK路由器的设置方法如下 对于双频路由器(指在2.4G和5G两个频率的),将2.4G的WiFi的SSID和密码分别设置为 FreeWiFi 和 WX12345678 设置完成之后,一定要把路由器重启,让配置生效。 2. 然后就可以使用微信扫一扫功能,扫描下面的二维码,来完成微信连WiFi的过程。 你也可以把下面的图案打印出来,张贴在醒目处。 最终的一个微信连WiFi的效果图如下
关键字:微信支付 微信支付v3 报关接口 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpay-declare.html 本文介绍微信支付下的报关接口的开发过程。微信报关是用于商户提交海关需要的订单信息。 一、报关接口API 接口地址 https://api.mch.weixin.qq.com/cgi-bin/mch/customs/customdeclareorder 是否需要证书 不需要。 请求方式:post 数据格式:xml 签名方式:MD5 注意:商户订单号金额以支付系统记录的为准,无需上传,如有子订单号则必须上传子订单应付金额、物流费、商品价格(应付金额=物流费+商品价格)。 字段名 变量名 必填 类型 示例值 说明 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法 公众账号ID appid 是 String(32) wxd678efh567hg6787 微信分配的公众账号ID 商户号 mch_id 是 String(32) 1230000109 微信支付分配的商户号 商户订单号 out_trade_no 是 String(32) 20150806125346 商户系统内部的订单号 微信支付订单号 transaction_id 是 String(28) 1000320306201511078440737890 微信支付返回的订单号 海关 customs 是 String(32) SHANGHAI NO 无需上报海关 GUANGZHOU 广州 HANGZHOU 杭州 NINGBO 宁波 ZHENGZHOU_BS 郑州(保税物流中心) CHONGQING 重庆 XIAN 西安 SHANGHAI 上海 ZHENGZHOU_ZH 郑州(综保区) SHENZHEN 深圳 商户海关备案号 mch_customs_no 否 String(32) 123456 商户在海关登记的备案号,customs非NO,此参数必填 关税 duty 否 Int 888 关税,以分为单位 以下字段在拆单或重新报关时必传 字段名 变量名 必填 类型 示例值 描述 商户子订单号 sub_order_no 否 String(32) 20150806125346 商户子订单号,如有拆单则必传 币种 fee_type 否 String(3) CNY 微信支付订单支付时使用的币种,暂只支持人民币CNY,如有拆单则必传。 应付金额 order_fee 否 Int 888 子订单金额,以分为单位,不能超过原订单金额,order_fee=transport_fee+product_fee(应付金额=物流费+商品价格),如有拆单则必传。 物流费 transport_fee 否 Int 888 物流费用,以分为单位,如有拆单则必传。 商品价格 product_fee 否 Int 888 商品费用,以分为单位,如有拆单则必传。 以下字段在微信缺少用户信息时必传,如果商户上传了用户信息,则以商户上传的信息为准。 字段名 变量名 必填 类型 示例值 描述 证件类型 cert_type 否 String(32) IDCARD 暂只支持身份证,该参数是指用户信息,商户若有用户信息,可上送,系统将以商户上传的数据为准,进行海关通关报备; 证件号码 cert_id 否 String(64) 330821198809085211 身份证号,该参数是指用户信息,商户若有用户信息,可上送,系统将以商户上传的数据为准,进行海关通关报备; 姓名 name 否 String(64) 张三 用户姓名,该参数是指用户信息,商户若有用户信息,可上送,系统将以商户上传的数据为准,进行海关通关报备; 举例如下: <xml> <appid>wx2421b1c4370ec43b</appid> <customs>ZHENGZHOU_BS</customs> <mch_customs_no>D00411</mch_customs_no> <mch_id>1262544101</mch_id> <order_fee>13110</order_fee> <out_trade_no>15112496832609</out_trade_no> <product_fee>13110</product_fee> <sign>8FF6CEF879FB9555CD580222E671E9D4</sign> <transaction_id>1006930610201511241751403478</transaction_id> <transport_fee>0</transport_fee> <fee_type>CNY</fee_type> <sub_order_no>15112496832609001</sub_order_no> </xml> 注:参数值用XML转义即可,CDATA标签用于说明数据不被XML解析器解析。 应答参数列表 字段名 变量名 必填 类型 示例值 说明 返回状态码 return_code 是 String(16) SUCCESS SUCCESS/FAIL 此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断 返回信息 return_msg 否 String(128) 签名失败 返回信息,如非空,为错误原因 签名失败 参数格式校验错误 以下字段在return_code为SUCCESS的时候有返回 字段名 变量名 必填 类型 示例值 描述 签名类型 sign_type 是 String(32) MD5 暂只支持MD5 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法 公众账号ID appid 是 String(32) wxd678efh567hg6787 微信分配的公众账号ID 商户号 mch_id 是 String(32) 1230000109 微信支付分配的商户号 业务结果 result_code 是 String(16) SUCCESS SUCCESS/FAIL 错误代码 err_code 否 String(32) SYSTEMERROR 详细参见错误列表 错误代码描述 err_code_des 否 String(128) 系统错误 错误返回的信息描述 以下字段在return_code 和result_code都为SUCCESS的时候有返回 字段名 变量名 必填 类型 示例值 描述 状态码 state 是 String(2) UNDECLARED 状态码 UNDECLARED -- 未申报 SUBMITTED -- 申报已提交(订单已经送海关,商户重新申报,并且海关还有修改接口,那么记录的状态会是这个) PROCESSING -- 申报中 SUCCESS -- 申报成功 FAIL-- 申报失败 EXCEPT --海关接口异常 微信支付订单号 transaction_id 是 String(28) 1000320306201511078440737890 微信支付返回的订单号 商户订单号 out_trade_no 是 String(32) 20150806125346 商户系统内部的订单号 商户子订单号 sub_order_no 否 String(32) 20150806125346 商户子订单号,如有拆单则必传 微信子订单号 sub_order_id 否 String(32) 20150806125346 微信子订单号 最后更新时间 modify_time 是 String(14) 20091227091010 最后更新时间,格式为yyyyMMddhhmmss,如2009年12月27日9点10分10秒表示为20091227091010。时区为GMT+8 beijing。该时间取自微信服务器 错误码 名称 描述 原因 解决方案 132011004 参数错误 报关时仅传入订单号,不传入子订单号(sub_order_no)时,不能填费用信息,须以支付系统中的值为准 请检查参数是否都正确 132021028 交易币种与商户结算币种不一致】 报关时传入子订单号(sub_order_no)时,币种参数(fee_type)必填 请检查所传币种参数(fee_type)是否为空 MCHID_NOT_SET 商户号未设置 商户号为必传参数,请求时必传 请检查商户号是否为空 MCHID_INVALID_LENGTH 无效的商户号长度 报关接口只支持12开头10位数字的商户号 请检查商户号长度是否为10位 CUSTOMSCONFIG_NOT_SET 海关配置未设置 报关接口需要商户已配置过海关信息才可以访问 请参照上文中的海关备案指引,进行海关信息报备 FEETYPE_NOT_SET 币种类型未设置 拆单情况下,币种为必填参数 请检查fee_type是否为空 OUTTRADENO_NOT_SET 商户订单号(out_trade_no)未设置 商户订单号为必传参数 请检查商户订单号(out_trade_no)是否为空 TRANSACTION_ID_NOT_SET 微信订单号(transaction_id)未设置 微信订单号(transaction_id)为必传参数 请检查微信订单号(transaction_id)是否为空 INVALID_TRANSACTION_ID 无效的微信订单号长度 微信订单号为28位数字,请确保长度一致 请检查微信订单号(transaction_id)是否正确 CUSTOMS_NOT_SET 海关信息未设置 海关信息为必传字段 请检查海关信息是否为空 CHCUSTOMSNO_NOT_SET 海关备案号未设置 海关备案号为必传字段 请检查备案号是否为空 INVALID_MCHCUSTOMSNO 无效的海关备案号长度 海关备案号一般为6位字符串 请检查海关备案号是否正确 PAYFEE_NOT_MATCH 金额不匹配 报关的订单金额必须和支付的金额一致 请检查报关订单的金额是否正确 INVALID_SUBORDER_NO 无效的子订单号长度(sub_order_no) 子订单号要求是32位以内的字符串 请检查子订单号长度是否正确 APPID_NOT_EXIST AppId未设置(sub_order_no) appid为必传字段 请检查appid是否正确 MCHID_NOT_EXIST 商户号(mch_id)未设置 MCH_ID为必传字段 请检查mch_id是否正确 AUTHORITY_NOT_FOUND 未开通自助清关功能 须先开通自助清关功能才可成功调用接口 请检查是否已开通自助清关功能,开通路径:微信支付商户平台-产品中心-自助清关中申请开通。 NO_AUTH 无权限 未获得此接口的调用权限 请检查当前商户号是否已获得此接口的调用权限 二、SDK实现 sdk定义 三、调用方式 三、返回结果 发送数据如下 array(6) { ["appid"]=> string(18) "wxa8092dd025e45123" ["mch_id"]=> string(10) "1238298123" ["out_trade_no"]=> string(22) "SH20160824095750086988" ["transaction_id"]=> string(28) "4006742001201608242098415582" ["customs"]=> string(6) "NINGBO" ["mch_customs_no"]=> string(10) "3302461123" } 接收到的数据如下 array(12) { ["return_code"]=> string(7) "SUCCESS" ["return_msg"]=> string(6) "成功" ["sign"]=> string(32) "91EFCEEAAD4322F331F3F63C4D8F1279" ["appid"]=> string(18) "wxa8092dd025e45123" ["mch_id"]=> string(10) "1238298123" ["result_code"]=> string(7) "SUCCESS" ["err_code"]=> string(1) "0" ["err_code_des"]=> string(2) "OK" ["state"]=> string(9) "SUBMITTED" ["transaction_id"]=> string(28) "4006742001201608242098415582" ["out_trade_no"]=> string(22) "SH20160824095750086988" ["modify_time"]=> string(14) "20160825111049" }
1. 发送post数据 $data = '{ "id": "17999030", "method": "sayHello", "jsonrpc": "2.0", "params": { "acmac": "00E0614CA7C6", "acconf_version": "2015-10-28-09-45" } }'; $url = "http://wifi.doucube.com/index.php/interface/device/ConfHeartbeat.html"; $res = http_request($url, $data); var_dump($res); //HTTP请求(支持HTTP/HTTPS,支持GET/POST) function http_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, TRUE); $output = curl_exec($curl); curl_close($curl); return $output; } 2. 接收post数据 <?php header('Content-type: application/json'); //方倍工作室 $postStr = isset($GLOBALS["HTTP_RAW_POST_DATA"])?$GLOBALS["HTTP_RAW_POST_DATA"]:""; logger('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].(empty($_SERVER['QUERY_STRING'])?"":("?".$_SERVER['QUERY_STRING']))); logger($postStr); foreach ($_GET as $key=>$value) { logger("_GET: Key: $key; Value: $value"); } foreach ($_POST as $key=>$value) { logger("_POST: Key: $key; Value: $value"); } //日志记录 function logger($log_content) { $max_size = 100000; $log_filename = "raw.log"; if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);} file_put_contents($log_filename, date('H:i:s')." ".$log_content."\r\n", FILE_APPEND); } $arr = array( 'code' => 0, 'errMsg' => 'OK', // 'member' =>array( // array( // 'name' => '李逍遥', // 'gender' => '男' // ), // array( // 'name' => '赵灵儿', // 'gender' => '女' // ) // ) ); echo json_encode($arr); ?>
关键字:微信支付 微信支付v3 刷卡支付 统一支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3-micropay.html 本文介绍微信支付下的刷卡支付的开发过程。刷卡支付是指用户打开微信钱包的刷卡的界面,商户扫码后提交完成支付的支付过程。 一、刷卡支付API 接口地址 https://api.mch.weixin.qq.com/pay/micropay 是否需要证书 不需要。 输入参数 名称 变量名 必填 类型 示例值 描述 公众账号ID appid 是 String(32) wx8888888888888888 微信分配的公众账号ID(企业号corpid即为此appId) 商户号 mch_id 是 String(32) 1900000109 微信支付分配的商户号 设备号 device_info 否 String(32) 013467007045764 终端设备号(商户自定义,如门店编号) 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法 商品描述 body 是 String(128) image形象店-深圳腾大- QQ公仔 商品简单描述,该字段须严格按照规范传递,具体请见参数规定 商品详情 detail 否 String(6000) {"goods_detail":[{"goods_id":"iphone6s_16G","wxpay_goods_id":"1001","goods_name":"iPhone6s 16G","goods_num":1,"price":528800,"goods_category":"123456","body":"苹果手机"},{"goods_id":"iphone6s_32G","wxpay_goods_id":"1002","goods_name":"iPhone6s 32G","quantity":1,"price":608800,"goods_category":"123789","body":"苹果手机"}]} 商品详细列表,使用Json格式,传输签名前请务必使用CDATA标签将JSON文本串保护起来。 goods_detail []:└ goods_id String 必填 32 商品的编号└ wxpay_goods_id String 可选 32 微信支付定义的统一商品编号└ goods_name String 必填 256 商品名称└ goods_num Int 必填 商品数量└ price Int 必填 商品单价,单位为分└ goods_category String 可选 32 商品类目ID└ body String 可选 1000 商品描述信息 附加数据 attach 否 String(127) 说明 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据 商户订单号 out_trade_no 是 String(32) 1217752501201407033233368018 商户系统内部的订单号,32个字符内、可包含字母,其他说明见商户订单号 商品详情 detail 否 String(8192) 与提交数据一致 实际提交的返回 订单金额 total_fee 是 Int 888 订单总金额,单位为分,只能为整数,详见支付金额 货币类型 fee_type 否 String(16) CNY 符合ISO4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 终端IP spbill_create_ip 是 String(16) 8.8.8.8 调用微信支付API的机器IP 商品标记 goods_tag 否 String(32) 商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠 指定支付方式 limit_pay 否 String(32) no_credit no_credit--指定不能使用信用卡支付 授权码 auth_code 是 String(128) 120061098828009406 扫码支付授权码,设备读取用户微信中的条码或者二维码信息 举例如下: <xml> <appid>wx2421b1c4370ec43b</appid> <attach>订单额外描述</attach> <auth_code>120269300684844649</auth_code> <body>刷卡支付测试</body> <device_info>1000</device_info> <goods_tag></goods_tag> <mch_id>10000100</mch_id> <nonce_str>8aaee146b1dee7cec9100add9b96cbe2</nonce_str> <out_trade_no>1415757673</out_trade_no> <spbill_create_ip>14.17.22.52</spbill_create_ip> <time_expire></time_expire> <total_fee>1</total_fee> <sign>C29DB7DB1FD4136B84AE35604756362C</sign> </xml> 注:参数值用XML转义即可,CDATA标签用于说明数据不被XML解析器解析。 返回结果 名称 变量名 必填 类型 示例值 描述 返回状态码 return_code 是 String(16) SUCCESS SUCCESS/FAIL 此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断 返回信息 return_msg 否 String(128) 签名失败 返回信息,如非空,为错误原因 签名失败 参数格式校验错误 当return_code为SUCCESS的时候,还会包括以下字段: 名称 变量名 必填 类型 示例值 描述 公众账号ID appid 是 String(32) wx8888888888888888 调用接口提交的公众账号ID 商户号 mch_id 是 String(32) 1900000109 调用接口提交的商户号 设备号 device_info 否 String(32) 013467007045764 调用接口提交的终端设备号, 随机字符串 nonce_str 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 微信返回的随机字符串 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 微信返回的签名,详见签名生成算法 业务结果 result_code 是 String(16) SUCCESS SUCCESS/FAIL 错误代码 err_code 否 String(32) SYSTEMERROR 详细参见错误列表 错误代码描述 err_code_des 否 String(128) 系统错误 错误返回的信息描述 当return_code 和result_code都为SUCCESS的时,还会包括以下字段: 名称 变量名 必填 类型 示例值 描述 用户标识 openid 是 String(128) Y 用户在商户appid 下的唯一标识 是否关注公众账号 is_subscribe 是 String(1) Y 用户是否关注公众账号,仅在公众账号类型支付有效,取值范围:Y或N;Y-关注;N-未关注 交易类型 trade_type 是 String(16) MICROPAY 支付类型为MICROPAY(即扫码支付) 付款银行 bank_type 是 String(16) CMC 银行类型,采用字符串类型的银行标识,值列表详见银行类型 货币类型 fee_type 否 String(16) CNY 符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 订单金额 total_fee 是 Int 888 订单总金额,单位为分,只能为整数,详见支付金额 现金支付货币类型 cash_fee_type 否 String(16) CNY 符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型 现金支付金额 cash_fee 是 Int 100 订单现金支付金额,详见支付金额 微信支付订单号 transaction_id 是 String(32) 1217752501201407033233368018 微信支付订单号 商户订单号 out_trade_no 是 String(32) 1217752501201407033233368018 商户系统的订单号,与请求一致。 商家数据包 attach 否 String(128) 123456 商家数据包,原样返回 支付完成时间 time_end 是 String(14) 20141030133525 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010。详见时间规则 举例如下: <xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> <appid><![CDATA[wx2421b1c4370ec43b]]></appid> <mch_id><![CDATA[10000100]]></mch_id> <device_info><![CDATA[1000]]></device_info> <nonce_str><![CDATA[GOp3TRyMXzbMlkun]]></nonce_str> <sign><![CDATA[D6C76CB785F07992CDE05494BB7DF7FD]]></sign> <result_code><![CDATA[SUCCESS]]></result_code> <openid><![CDATA[oUpF8uN95-Ptaags6E_roPHg7AG0]]></openid> <is_subscribe><![CDATA[Y]]></is_subscribe> <trade_type><![CDATA[MICROPAY]]></trade_type> <bank_type><![CDATA[CCB_DEBIT]]></bank_type> <total_fee>1</total_fee> <coupon_fee>0</coupon_fee> <fee_type><![CDATA[CNY]]></fee_type> <transaction_id><![CDATA[1008450740201411110005820873]]></transaction_id> <out_trade_no><![CDATA[1415757673]]></out_trade_no> <attach><![CDATA[订单额外描述]]></attach> <time_end><![CDATA[20141111170043]]></time_end> </xml> 二、刷卡支付类实现 在微信支付原来的微信支付类文件中,仿照统一支付类的方式,添加刷卡支付类如下: /** * 刷卡支付接口类 */ class MicroPay_pub extends Wxpay_client_pub { function __construct() { //设置接口链接 $this->url = "https://api.mch.weixin.qq.com/pay/micropay"; //设置curl超时时间 $this->curl_timeout = WxPayConf_pub::CURL_TIMEOUT; } /** * 生成接口参数xml */ function createXml() { try { //检测必填参数 if($this->parameters["out_trade_no"] == null){ throw new SDKRuntimeException("缺少统一支付接口必填参数out_trade_no!"."<br>"); }elseif($this->parameters["body"] == null){ throw new SDKRuntimeException("缺少统一支付接口必填参数body!"."<br>"); }elseif ($this->parameters["total_fee"] == null ) { throw new SDKRuntimeException("缺少统一支付接口必填参数total_fee!"."<br>"); }elseif ($this->parameters["auth_code"] == null) { throw new SDKRuntimeException("缺少统一支付接口必填参数auth_code!"."<br>"); } $this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID $this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号 $this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//终端ip $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//签名 // var_dump($this->parameters); return $this->arrayToXml($this->parameters); }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } } 原有的基础类和请求类也列出如下: /** * 所有接口的基类 */ class Common_util_pub { function __construct() { } function trimString($value) { $ret = null; if (null != $value) { $ret = $value; if (strlen($ret) == 0) { $ret = null; } } return $ret; } /** * 作用:产生随机字符串,不长于32位 */ public 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 formatBizQueryParaMap($paraMap, $urlencode) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if($urlencode) { $v = urlencode($v); } //$buff .= strtolower($k) . "=" . $v . "&"; $buff .= $k . "=" . $v . "&"; } $reqPar; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; } /** * 作用:生成签名 */ public function getSign($Obj) { foreach ($Obj as $k => $v) { $Parameters[$k] = $v; } //签名步骤一:按字典序排序参数 ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //echo '【string1】'.$String.'</br>'; //签名步骤二:在string后加入KEY $String = $String."&key=".WxPayConf_pub::KEY; //echo "【string2】".$String."</br>"; //签名步骤三:MD5加密 $String = md5($String); //echo "【string3】 ".$String."</br>"; //签名步骤四:所有字符转为大写 $result_ = strtoupper($String); //echo "【result】 ".$result_."</br>"; return $result_; } /** * 作用:array转xml */ function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key=>$val) { if (is_numeric($val)) { $xml.="<".$key.">".$val."</".$key.">"; } else $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } $xml.="</xml>"; return $xml; } /** * 作用:将xml转为array */ public function xmlToArray($xml) { //将XML转为array $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $array_data; } /** * 作用:以post方式提交xml到对应的接口url */ public function postXmlCurl($xml,$url,$second=30) { //初始化curl $ch = curl_init(); //设置超时 curl_setopt($ch, CURLOP_TIMEOUT, $second); //这里设置代理,如果有的话 //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8'); //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); 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); curl_close($ch); //返回结果 if($data) { curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "curl出错,错误码:$error"."<br>"; echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>"; curl_close($ch); return false; } } /** * 作用:使用证书,以post方式提交xml到对应的接口url */ function postXmlSSLCurl($xml,$url,$second=30) { $ch = curl_init(); //超时时间 curl_setopt($ch,CURLOPT_TIMEOUT,$second); //这里设置代理,如果有的话 //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8'); //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); 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); //设置证书 //使用证书:cert 与 key 分别属于两个.pem文件 //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT, dirname(__FILE__).WxPayConf_pub::SSLCERT_PATH); //默认格式为PEM,可以注释 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY, dirname(__FILE__).WxPayConf_pub::SSLKEY_PATH); //post提交方式 curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); $data = curl_exec($ch); //返回结果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "curl出错,错误码:$error"."<br>"; echo "<a href='http://curl.haxx.se/libcurl/c/libcurl-errors.html'>错误原因查询</a></br>"; curl_close($ch); return false; } } /** * 作用:打印数组 */ function printErr($wording='',$err='') { print_r('<pre>'); echo $wording."</br>"; var_dump($err); print_r('</pre>'); } } /** * 请求型接口的基类 */ class Wxpay_client_pub extends Common_util_pub { var $parameters;//请求参数,类型为关联数组 public $response;//微信返回的响应 public $result;//返回参数,类型为关联数组 var $url;//接口链接 var $curl_timeout;//curl超时时间 /** * 作用:设置请求参数 */ function setParameter($parameter, $parameterValue) { $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue); } /** * 作用:设置标配的请求参数,生成签名,生成接口参数xml */ function createXml() { $this->parameters["appid"] = WxPayConf_pub::APPID;//公众账号ID $this->parameters["mch_id"] = WxPayConf_pub::MCHID;//商户号 $this->parameters["nonce_str"] = $this->createNoncestr();//随机字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//签名 return $this->arrayToXml($this->parameters); } /** * 作用:post请求xml */ function postXml() { $xml = $this->createXml(); $this->response = $this->postXmlCurl($xml,$this->url,$this->curl_timeout); return $this->response; } /** * 作用:使用证书post请求xml */ function postXmlSSL() { $xml = $this->createXml(); $this->response = $this->postXmlSSLCurl($xml,$this->url,$this->curl_timeout); return $this->response; } /** * 作用:获取结果,默认不使用证书 */ function getResult() { $this->postXml(); $this->result = $this->xmlToArray($this->response); return $this->result; } } 三、发起支付 在程序中,获得用户的授权码,并填入到$authcode参数中。授权码就是条码上的那一串18位纯数字,以10、11、12、13、14、15开头 其他参数则自动生成或者手动输入指定。 调用函数如下所示 //全局引入微信支付类 Vendor('Wxpay.WxPayPubHelper.WxPayPubHelper'); //使用统一支付接口 $microPay = new \MicroPay_pub(); //设置统一支付接口参数 $microPay->setParameter("body","方倍商户刷卡支付");//商品描述 $microPay->setParameter("out_trade_no", "$out_trade_no");//商户订单号 $microPay->setParameter("total_fee", $total_fee);//总金额 $microPay->setParameter("auth_code", $authcode);//授权码 //获取统一支付接口结果 $microPayResult = $microPay->getResult(); //3. 异常判断 if (!isset($microPayResult["result_code"]) || ($microPayResult["result_code"] == "FAIL")) { $this->resRpcError(isset($microPayResult['result_code']) ? $microPayResult['err_code_des'] : $microPayResult['return_msg'], "21000"); }
通过openssl工具生成RSA的公钥和私钥(opnssl工具可在互联网中下载到,也可以点此下载无线接口包,里面包含此工具)打开openssl文件夹下的bin文件夹,执行openssl.exe文件: 1)生成RSA私钥 输入“生成命令.txt”文件中:“genrsa -out rsa_private_key.pem 1024”,并回车得到生成成功的结果,如下图: 此时,我们可以在bin文件夹中看到一个文件名为rsa_private_key.pem的文件,用记事本方式打开它,可以看到-----BEGIN RSA PRIVATE KEY-----开头,-----END RSA PRIVATE KEY-----结尾的没有换行的字符串,这个就是原始的私钥。 2)生成RSA公钥 输入命令:rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem,并回车,得到生成成功的结果,如下图: 此时,我们可以在bin文件夹中看到一个文件名为rsa_public_key.pem的文件,用记事本方式打开它,可以看到-----BEGIN PUBLIC KEY-----开头,-----END PUBLIC KEY-----结尾的没有换行的字符串,这个就是公钥。 3)把RSA私钥转换成PKCS8格式 输入命令:pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt,并回车当前界面中会直接显示出生成结果,这个结果就是PKCS8格式的私钥,如下图: 右键点击openssl窗口上边边缘,选择编辑→标记,选中要复制的文字(如上图), 此时继续右键点击openssl窗口上边边缘,选择编辑→复制, 把复制的内容粘土进一个新的记事本中,可随便命名,只要知道这个是PKCS8格式的私钥即可。 经过以上步骤,开发者可以在当前文件夹中(OpenSSL运行文件夹),看到dsa_private_key.pem(DSA私钥)、dsa_private_key_pkcs8.pem(pkcs8格式DSA私钥)、dsa_public_key.pem(对应DSA公钥)和dsa_param.pem(参数文件)4个文件。开发者将私钥保留,将公钥提交给支付宝网关,用于验证签名。 注意:对于使用Java的开发者,将pkcs8在console中输出的私钥去除头尾、换行和空格,作为开发者私钥,对于.NET和PHP的开发者来说,无需进行pkcs8命令行操作。
关键字:微信支付 微信支付v3 H5支付 wap支付 prepay_id 作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/wxpayv3_h5.html 本文介绍微信支付下的H5支付实现流程。 一、介绍 H5支付是基于公众号基础开发的一种非微信内浏览器支付方式(需要单独申请支付权限),可以满足在微信外的手机H5页面进行微信支付的需求。。 测试地址 http://wxpay.weixin.qq.com/pub_v2/pay/wap.v2.php http://wxpay.weixin.qq.com/mch/pay/h5.v2.php http://wxpay.wxutil.com/pub_v2/pay/wap.v2.php http://wxpay.wxutil.com/mch/pay/h5.v2.php 效果图 流程图 二、商品信息准备 主要是先定义商品的名称及价格,以及交易号。代码如下。 include_once("../WxPayPubHelper/WxPayPubHelper.php"); //使用统一支付接口 $unifiedOrder = new UnifiedOrder_pub(); //设置统一支付接口参数 //设置必填参数 //appid已填,商户无需重复填写 //mch_id已填,商户无需重复填写 //noncestr已填,商户无需重复填写 //spbill_create_ip已填,商户无需重复填写 //sign已填,商户无需重复填写 $unifiedOrder->setParameter("body","H5支付测试");//商品描述 $timeStamp = time(); $out_trade_no = WxPayConf_pub::APPID."$timeStamp"; $unifiedOrder->setParameter("out_trade_no","$out_trade_no");//商户订单号 $unifiedOrder->setParameter("total_fee","1");//总金额 //$unifiedOrder->setParameter("notify_url",WxPayConf_pub::NOTIFY_URL);//通知地址 $unifiedOrder->setParameter("trade_type","WAP");//交易类型 //非必填参数,商户可根据实际情况选填 $unifiedOrder->setParameter("device_info","100001");//设备号 上述参数最终封装成如下类似XML参数 <xml> <body><![CDATA[H5支付测试]]></body> <out_trade_no><![CDATA[100001_1433009089]]></out_trade_no> <total_fee>1</total_fee> //<notify_url><![CDATA[http://www.doucube.com/weixin/demo/notify_url.php]]></notify_url> <trade_type><![CDATA[WAP]]></trade_type> <device_info>100001</device_info> <appid><![CDATA[wx1d065b0628e21103]]></appid> <mch_id>1237905502</mch_id> <spbill_create_ip><![CDATA[61.129.47.79]]></spbill_create_ip> <nonce_str><![CDATA[gwpdlnn0zlfih21gipjj5z53i7vea8e8]]></nonce_str> <sign><![CDATA[C5A1E210F9B4402D8254F731882F41AC]]></sign> </xml> 2. 调用统一支付请求 将上述XML发送给统一支付接口 https://api.mch.weixin.qq.com/pay/unifiedorder 得到如下XML数据 <xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[OK]]></return_msg> <appid><![CDATA[wx1d065b0628e21103]]></appid> <mch_id><![CDATA[1237905502]]></mch_id> <device_info><![CDATA[100001]]></device_info> <nonce_str><![CDATA[6u8ovTtFupTagsiY]]></nonce_str> <sign><![CDATA[E84D8BC2331766DD685591F908367FF1]]></sign> <result_code><![CDATA[SUCCESS]]></result_code> <prepay_id><![CDATA[wx20150531020450bb586eb2f70717331240]]></prepay_id> <trade_type><![CDATA[WAP]]></trade_type> </xml> 这样就得到一个prepayid 二、DeepLink 商户server调用统一下单接口请求订单,api参见公共api【统一下单】(接口中trade_type需定义为WAP),微信会返回给商户prepayid,商户按固定格式生成deeplink,通过用户点击deeplink来调起微信支付。deeplink格式: weixin://wap/pay?appid%3Dwxf5b5e87a6a0fde94%26noncestr%3D123%26package%3D123%26prepayid%3Dwx20141203201153d7bac0d2e10889028866%26sign%3D6AF4B69CCC30926F85770F900D098D64%26timestamp%3D1417511263 生成deeplink 的步骤如下:步骤1:按URL 格式组装参数, $value 部分进行URL 编码,生成string1:string1 : key1=Urlencode($value1)&key2=Urlencode($value2、&...步骤2:对string1 作整体的Urlencode,生成string2:String2=Urlencode(string1);步骤3:拼接前缀,生成最终deeplink举例如下:String1: appid=wxf5b5e87a6a0fde94&noncestr=123&package=WAP&prepayid=wx201412101630480281750c890475924233&sign=53D411FB74FE0B0C79CC94F2AB0E2333&timestamp=1417511263 再对整个string1 做一次URLEncodestring2: appid%3Dwxf5b5e87a6a0fde94%26noncestr%3D123%26package%3DWAP%26prepayid%3Dwx201412101630480281750c890475924233%26sign%3D53D411FB74FE0B0C79CC94F2AB0E2333%26timestamp%3D1417511263 再加上协议头weixin://wap/pay? 得到最后的deeplink weixin://wap/pay?appid%3Dwxf5b5e87a6a0fde94%26noncestr%3D123%26package%3DWAP%26prepayid%3Dwx201412101630480281750c890475924233%26sign%3D53D411FB74FE0B0C79CC94F2AB0E2333%26timestamp%3D1417511263 字段名 变量名 必填 类型 示例值 描述 公众账号ID appid 是 String(32) wx8888888888888888 微信分配的公众账号ID 随机字符串 noncestr 是 String(32) 5K8264ILTKCH16CQ2502SI8ZNMTM67VS 随机字符串,不长于32位。推荐随机数生成算法 订单详情扩展字符串 package 是 String(32) WAP 扩展字段,固定填写WAP 预支付交易会话标识 prepayid 是 String(64) wx201410272009395522657a690389285100 微信统一下单接口返回的预支付回话标识,用于后续接口调用中使用,该值有效期为2小时 签名 sign 是 String(32) C380BEC2BFD727A4B6845133519F3AD6 签名,详见签名生成算法 时间戳 timestamp 是 String(32) 1414561699 当前的时间,其他详见时间戳规则 开发文档:https://pay.weixin.qq.com/wiki/doc/api/wap.php?chapter=15_1 三、新版流程 1、用户在商户侧完成下单,使用微信支付进行支付 2、由商户后台向微信支付发起下单请求(调用统一下单接口)注:交易类型trade_type=MWEB 3、微信支付校验商户权限 4、统一下单接口返回支付相关参数给商户后台,如支付跳转url(参数名“mweb_url”,即流程图中的微信中转页面地址) 5、商户后台收到统一下单接口返回参数,将mweb_url返回给前端 6、商户通过前端页面访问微信中转页面mweb_url(此步骤微信支付会校验refer,以判断请求来源是否合法) 7、由中转页面mweb_url主动唤起微信支付收银台 8、微信支付收银台被唤起同时关闭mweb_url中转页面 9、用户在微信支付收银台完成支付 三、如何申请微信H5支付 发邮件到weixinpay@tencent.com 申请条件:微信支付月平均支付笔数超过3W笔,日平台支付笔数超过1K笔
转换代码如下 //数组转XML function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key=>$val) { if (is_numeric($val)){ $xml.="<".$key.">".$val."</".$key.">"; }else{ $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } } $xml.="</xml>"; return $xml; } //将XML转为array function xmlToArray($xml) { //禁止引用外部xml实体 libxml_disable_entity_loader(true); $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $values; } Array转XML $money = 101; $sender = "方倍工作室"; $obj2 = array(); $obj2['wxappid'] = APPID; $obj2['mch_id'] = MCHID; $obj2['mch_billno'] = MCHID.date('YmdHis').rand(1000, 9999); $obj2['client_ip'] = $_SERVER['REMOTE_ADDR']; $obj2['re_openid'] = $openid; $obj2['total_amount'] = $money; $obj2['min_value'] = $money; $obj2['max_value'] = $money; $obj2['total_num'] = 1; $obj2['nick_name'] = $sender; $obj2['send_name'] = $sender; $obj2['wishing'] = "恭喜发财"; $obj2['act_name'] = "方倍工作室送红包"; $obj2['remark'] = "关注公众账号"; 转换后 <xml> <wxappid><![CDATA[wx1b7559b818e3c123]]></wxappid> <mch_id>1235571234</mch_id> <mch_billno>1235571234201605241726128109</mch_billno> <client_ip><![CDATA[127.0.0.1]]></client_ip> <re_openid><![CDATA[oiPuduGV7gJ_MOSfAWpVmhhgXh-U]]></re_openid> <total_amount>101</total_amount> <min_value>101</min_value> <max_value>101</max_value> <total_num>1</total_num> <nick_name><![CDATA[方倍工作室]]></nick_name> <send_name><![CDATA[方倍工作室]]></send_name> <wishing><![CDATA[恭喜发财]]></wishing> <act_name><![CDATA[方倍工作室送红包]]></act_name> <remark><![CDATA[关注公众账号]]></remark> </xml> XML转为Array <xml> <return_code><![CDATA[SUCCESS]]></return_code> <return_msg><![CDATA[发放成功]]></return_msg> <result_code><![CDATA[SUCCESS]]></result_code> <err_code><![CDATA[MONEY_LIMIT]]></err_code> <err_code_des><![CDATA[发放成功]></err_code_des> <mch_billno><![CDATA[1235571234201605241651123985]]></mch_billno> <mch_id>1235571234</mch_id> <wxappid><![CDATA[wx1b7559b818e3c123]]></wxappid> <re_openid><![CDATA[oiPuduGV7gJ_MOSfAWpVmhhgXh-U]]></re_openid> <total_amount>1</total_amount> </xml> 转换后 array(10) { ["return_code"]=> string(7) "SUCCESS" ["return_msg"]=> string(12) "发放成功" ["result_code"]=> string(7) "SUCCESS" ["err_code"]=> string(11) "MONEY_LIMIT" ["err_code_des"]=> string(12) "发放成功" ["mch_billno"]=> string(28) "1235571234201605241651123985" ["mch_id"]=> string(10) "1235571234" ["wxappid"]=> string(18) "wx1b7559b818e3c123" ["re_openid"]=> string(28) "oiPuduGV7gJ_MOSfAWpVmhhgXh-U" ["total_amount"]=> string(1) "1" }
The Python Tutorial (Python 2.7.11) 的中文翻译版本。Python Tutorial 为初学 Python 必备官方教程,本教程适用于 Python 2.7.X 系列。 在线阅读 » Fork Me » The Python Tutorial (Python 3.5.1) 的中文翻译版本。Python Tutorial 为初学 Python 必备官方教程,本教程适用于 Python 3.5.x。 在线阅读 » Fork Me » Flask 是一个轻量级的 Web 应用框架。其 WSGI 工具箱采用 Werkzeug ,模板引擎则使用 Jinja2。本教程适用于 Flask 0.10.1 以上版本。 在线阅读 » Fork Me » 探索 Flask 是一本关于使用 Flask 开发 Web 应用程序的最佳实践和模式的书籍。这本书是 Flask 官方教程的一个有力的补充材料。适合进阶使用。 在线阅读 » Fork Me » Flask Mega Tutorial 是一个非官方的很完整的 Flask 教程。 在线阅读 » Fork Me » Flask-Cache 是一个用于 Flask 作为缓存的第三方扩展。 在线阅读 » Fork Me » Flask-Exceptional 是一个为 Flask 添加 Exceptional 支持。 在线阅读 » Fork Me » Flask-PyMongo 是一个为 Flask 和 PyMongo 搭建桥梁的扩展。 在线阅读 » Fork Me » Flask-Dashed 是一个提供构建简单、可扩展的管理界面的第三方扩展。 在线阅读 » Fork Me » Flask + SQLAlchemy + Postgresql 异步方案示例,为 Flask 开发提供数据库异步参考。 在线阅读 » Fork Me » Flask-SQLAlchmey 为 Flask 提供了简单且有用的 SQLAlchmey 集成。 在线阅读 » Fork Me » Flask-Mail 是一个在 Flask 中能够发送邮件的扩展!Flask-Mail 扩展中封装了 smtplib 模块。 在线阅读 » Fork Me » Flask-Testing 为 Flask 提供了单元测试的工具。 在线阅读 » Fork Me » Miguel 编写的使用 Python 以及 Flask 编写 RESTful API。 在线阅读 » Fork Me » Flask-WTF 为 Flask 提供了简单并且实用的 WTForms 集成。 在线阅读 » Fork Me » Flask-Login 为 Flask 提供了用户会话管理。 在线阅读 » Fork Me » 在 Flask 中整合 Celery,使得 Flask 支持后台作业! 在线阅读 » Fork Me » Flask-DebugToolbar 为 Flask 添加了工具栏的支持。 在线阅读 » Fork Me » Flask-Babel 为 Flask 添加了 i18n 和 l10n 支持。 在线阅读 » Fork Me » Flask-RESTful 为 Flask 添加了快速构建 REST APIs 的支持。 在线阅读 » Fork Me » Sphinx 是一个简单和便捷的工具,它能够轻易地创建智慧和优雅的文档。Sphinx 官方文档中文翻译正在进行中,有时间和精力的使用者可以参与翻译! 在线阅读 » Fork Me » SQLAlchemy 提供了 SQL 工具包及对象关系映射(ORM)工具。SQLAlchemy 官方文档中文翻译正在进行中,有时间和精力的使用者可以参与翻译! Fork Me » 网页框架 Django Django - Django。 Channels - Channels旨在增强Django的异步能力,同时让Django不仅仅局限于Request-Response模型,能够支持WebSocket、HTTP2推送和背景任务。2015年出现的十大流行Python库 。 Django-Baker - Django Baker可以帮助开发者快速启动项目。只要提供app名称,Django Baker就可以根据models.py文件中的models,自动生成视图、表单、URL、admin页面以及模板。2015年出现的十大流行Python库 。 Django-Q - Django Q是一个原生Django分布式任务队列处理应用,通过Python的mutliprocessing模块功能实现。2015年出现的十大流行Python库 。 django-webpack-loader - Django webpack loader对webpack-bundle-tracker的输出结果进行处理,让你可以在自己的Django应用中使用生成的bundles。2015年出现的十大流行Python库 。 django-hackathon-starter - django-hackathon-starter这是一个Django Web应用模板程序,可以帮助你快速生成应用。必定能够为你节省大量的开发时间,同时这个库也能用作开发者的学习指南。2015年出现的十大流行Python库 。 django-seed - Django-seed通过faker库,为Django模型生成测试数据。该库支持Python和Django的最新版本。2015年出现的十大流行Python库 。 django-tenants - django-tenants让django驱动的网站支持多个tenants,这个功能时通过PostgreSQL schemas实现的。这是每个SASS(软件即服务)网站的核心功能。2015年出现的十大流行Python库 。 Python+Django构建的Blog - 基于Python+Django构建的Blog http://xushvai.github.io/io/ LibraryManagement - LibraryManagement图书管理系统(Django1.9.1+Bootstrap3)。 Flask flask - flask, 官方教程中文翻译1 ,官方教程中文翻译2,Flask使用小结,Flask开发团队Pocoo的内部编码风格指南| 编程派 | Coding Python.html。 Tornado tornado - tornado是非阻塞式 Web 服务器框架,而且速度相当快。官网,Introduction to Tornado 中文翻译 , 中文教程。 其他网页框架 Bottle - Bottle是一个小型的轻量网络开发框架,同时速度也很快。 Wooey - Wooey 是一个简单的Python脚本的Web UI 界面。它能够提供日常数据分析,文件处理等功能。2015年出现的十大流行Python库 。 用户图形接口相关 pyglet - Pyglet是一个纯Python语言编写的跨平台框架,用于开发多媒体和窗口特效应用。 kivy - Kivy 是一个开源工具包能够让使用相同源代码创建的程序能跨平台运行。它主要关注创新型用户界面开发,如:多点触摸应用程序。Kivy 还提供一个多点触摸鼠标模拟器。基于 Cython(C extensions for Python) 构建,当前支持的平台包括:Linux、Windows、Mac OS X和Android。 Py2exe - 把Python脚本转换为windows平台上面可以运行的可执行程序(*.exe)的工具,通过修改源码可以支持python3.0的代码。 pyinstaller - 把Python脚本转换为能直接运行的可执行文件,支持python2.7、python3.3-3.5,支持Windows (32-bit and 64-bit)、Linux (32-bit and 64-bit)、Mac OS X (32-bit and 64-bit)平台。 cx_Freeze - 把Python脚本转换为能直接运行的可执行文件,支持python3.x,特别简单。 Tkinter - Tkinter的是Tk的GUI工具包,与Python附带的Python接口。 wxPython - wxPython一个开源的Python接口的wxWindows。 PyQt - PyQt是一个创建GUI应用程序的工具包。它是Python编程语言和Qt库的成功融合。Qt库是目前最强大的库之一。 Eric - Eric一个支持python、Ruby的强大IDE,与PyQt配合功能非常强大。 网络相关 aiohttp - aiohttp是一个为 asyncio 提供了简洁易用的 HTTP 客户端和服务器的库。 Requests - Requests是python的一个HTTP客户端库,跟urllib,urllib2类似。 数据库相关 SQLAlchemy - SQLAlchemy一个知名企业级的持久化模式的,专为高效率和高性能的数据库访问设计的,改编成一个简单的Python域语言的完整套件。它采用了数据映射模式(像Java中的Hibernate)而不是Active Record模式(像Ruby on Rails的ORM)。 SQLObject - SQLObject是一个介于SQL数据库和Python之间映射对象的Python ORM, 类似于Ruby on Rails的ActiveRecord模式。 Peewee - Peewee是一个小型但是十分强大的库,支持通过ORM的方式访问数据库,原生支持SQLite、MySQL和PostgreSQL等数据库。 pony - pony官网 Pony是一个非常酷和新的 Python ORM ,它能够让你使用Python generators来查询一个数据库。这些generators然后会转成高效的SQL。 asyncmongo - AsyncMongo是基于Tornado iploop的mongo数据库的异步库。 influxdb-python - InfluxDB -python 是一个时间序列数据库,用它来储存不同时间的测量值。通过 RESTFul API,它变得极其易用而且高效,另外,由于其内建了聚类功能,因此对数据的检索和分组也变得十分轻松。 elasticsearch-dsl-py - elasticsearch-dsl-py提供基于JSON的完整的Query DSL查询表达式(DSL即领域专用语言)。 MongoHub-Mac - MongoHub-Mac:mongo 图形化管理工具。 mongotron - mongotron:mongo 图形化管理工具,基于Electron与AngularJS写成。 asyncmongo - AsyncMongo是基于Tornado iploop的mongo数据库的异步库。 游戏相关 游戏服务器端架构升级之路 - 游戏服务器端架构升级之路,参考flask设计的tcp server:haven 、 参考flask设计的tcp server:maple。 开源框架 高效的Python数据分析框架Ibis - 高效的Python数据分析框架Ibis ibis-project , 通过IPN了解Ibis. RabbitMQ - 一个工业级的消息队列服务器,RabbitMQ+Python入门经典-兔子和兔子窝 ZeroMQ - 是一个简单好用的传输层socket library,使得 Socket 编程更加简单、简洁和性能更高。 大数据相关 pandas - 为 Python 编程语言提供高性能,易用数据结构和数据分析工具。在数据改动和数据预处理方面,Python 早已名声显赫,但是在数据分析与建模方面,Python 是个短板。Pands 软件就填补了这个空白,能让你用 Python 方便地进行你所有数据的处理,而不用转而选择更主流的专业语言,例如 R 语言。12 个使效率倍增的 Pandas 技巧 上、 下 。 pulp - PuLP 是一个用 Python 编写的线性编程模型。它能产生线性文件,能调用高度优化的求解器,GLPK,COIN CLP/CBC,CPLEX,和GUROBI,来求解这些线性问题。 Matplotlib - Matplotlib是基于 Python 的 2D(数据)绘图库,它产生(输出)出版级质量的图表,用于各种打印纸质的原件格式和跨平台的交互式环境。matplotlib 既可以用在 python 脚本, python 和 ipython 的 shell 界面 (ala MATLAB® 或 Mathematica®),web 应用服务器,和6类 GUI 工具箱。matplotlib 尝试使容易事情变得更容易,使困难事情变为可能。你只需要少量几行代码,就可以生成图表,直方图,能量光谱(power spectra),柱状图,errorcharts,散点图(scatterplots)等。 Scikit-Learn - Scikit-Learn是一个简单有效地数据挖掘和数据分析工具(库)。关于最值得一提的是,它人人可用,重复用于多种语境。它基于 NumPy,SciPy 和 mathplotlib 等构建。 Spark -Spark 由一个驱动程序构成,它运行用户的 main 函数并在聚类上执行多个并行操作。Spark 最吸引人的地方在于它提供的弹性分布数据集(RDD),那是一个按照聚类的节点进行分区的元素的集合,它可以在并行计算中使用。RDDs 可以从一个 Hadoop 文件系统中的文件(或者其他的 Hadoop支持的文件系统的文件)来创建,或者是驱动程序中其他的已经存在的标量数据集合,把它进行变换。用户也许想要 Spark 在内存中永久保存 RDD,来通过并行操作有效地对 RDD 进行复用。最终,RDDs 无法从节点中自动复原。Spark 中第二个吸引人的地方在并行操作中变量的共享。 SciPy - SciPy是一个开源的Python算法库和数学工具包,SciPy包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号 处理和图像处理、常微分方程求解和其他科学与工程中常用的计算。其功能与软件MATLAB、Scilab和GNU Octave类似。Numpy和Scipy常常结合着使用,Python大多数机器学习库都依赖于这两个模块。 NumPy - NumPy几乎是一个无法回避的科学计算工具包,最常用的也许是它的N维数组对象,其他还包括一些成熟的函数库,用于整合C/C++和 Fortran代码的工具包,线性代数、傅里叶变换和随机数生成函数等。NumPy提供了两种基本的对象:ndarray(N-dimensional array object)和 ufunc(universal function object)。ndarray是存储单一数据类型的多维数组,而ufunc则是能够对数组进行处理的函数。 ipython - iPython 是一个Python 的交互式Shell,比默认的Python Shell 好用得多,功能也更强大。 她支持语法高亮、自动完成、代码调试、对象自省,支持 Bash Shell命令,内置了许多很有用的功能和函式等,非常容易使用。默认开启了matploblib的绘图交互,用起来很方便。jupyter-notebook - jupyter官网。 PyML - PyML是一个Python机器学习工具包,为各分类和回归方法提供灵活的架构。它主要提供特征选择、模型选择、组合分类器、分类评估等功能。 gensim - gensim是一种NLP(自然语言处理),它提供了一些常用算法,例如 tf-idf、word2vec、doc2vec、LSA 等的快速、可拓展(内存无关)实现,同时还提供了简单易用的接口和完善的文档。 Blaze - Blaze 是下一代的 NumPy。用于处理分布式的各种不同数据源的计算。 Dask - Dask是一款基于外存的Python 调度工具。它通过将数据集分块处理并根据所拥有的核数分配计算量,这有助于进行大数据并行计算。它主要针对单机的并行计算进程。 GWPY - GWPY一个可以分析引力波数据的Python包。 网络爬虫 scrapy - 最出名的网络爬虫,一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。官方主页,Scrapy 轻松定制网络爬虫 - 教程,Scrapy 中文指南 。 BeautifulSoup - Beautifu Soup不完全是一套爬虫工具,需要配合urllib使用,而是一套HTML/XML数据分析,清洗和获取工具。 python-goose - Python-Goose用Python重写,依赖了Beautiful Soup。给定一个文章的URL, 获取文章的标题和内容很方便。 pyspider - PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI。采用Python语言编写,分布式架构,支持多种数据库后端,强大的WebUI支持脚本编辑器,任务监视器,项目管理器以及结果查看器。demo地址,网络爬虫剖析,以Pyspider为例 , Scrapy 示例 —— Web 爬虫框架 。 测试 splinter - Python自动化测试工具Splinter,不仅可以当web自动化测试工具 同时也可以当抓取交互式网站的爬虫程序来用的,不用去分析ajax请求数据了,可以模拟登录,用Python开发自动化测试脚本-splinter。 swarm - 是一个简单的使用 gevent 开发的支持自定义协议的长连接压测框架。 PySonar2 - PySonar2王垠开发的,针对 Python 的代码静态分析工具。 Behave - BDD自动化测试框架。 Nose - Nose是最流行的针对Python的测试库之一。简单实例 破解脚本 ibrute - 一个攻击iCloud账户的Python脚本,2014年很多明星的账号就是被这个脚本攻破的,苹果已经修改这个漏洞了。 bruteforce_py - 暴力破解脚本,ssh bf, wordpress bf, cpanel bf, mysql bf, etc ... 可以说是暴力破解大全。 keychain-bruteforce - 暴力破解MAC OS X 的密码管理。 gamblerbfe - 路由器也可以暴力破解了。 AndroidPINCrack - android的pin密码破解。 rarPasswordCrackere - rar加密文件破解。 Python-ZIP-Cracker - zip加密文件破解。 图表及图像相关 vincent - Python 构建的专为运用 D3.js 进行可视化的 vega 转换工具。 Scikit-image - 一组用于图像处理的算法的集合,使图像处理任务如模糊,增强对比度,缩放只需要一些函数调用就可以完成。 PIL - PIL (Python Imaging Library)是 Python 中最常用的图像处理库。 运维相关 pywebsocketserver - 程序Log实时监控 – python + websocket。 pupy - Pupy是一个远程管理工具(Administration Tool),开源并且支持多个平台。Pupy还内置了一个Python解释器,可以从内存中加载Python包,访问远程Python对象。 Fabric - Fabric 一个通过SSH进行应用部署以及系统任务管理的命令行工具。 Invoke - Invoke让你通过一个Python库便捷地执行系统管理任务。如果你想使用稳定的工具(即使是不再积极开发),可以考虑Invoke的前身——Fabric。 DeployDjango - 不到一分钟安全部署Django应用的脚本,操作教程。 HealthChecks - HealthChecks基于 cron 的监控服务。在 cron 里配置好监控只需要几分钟时间,却能让你晚上睡得更好!2015年出现的十大流行Python库 。 dockerizing-django - 是realpython网站一篇相关教程的代码库,讲的是如何将Django应用Docker化。2015年出现的十大流行Python库 。 用Python脚本实现对Linux服务器的监控 - 用Python脚本实现对Linux服务器的监控。 plumbum控 - plumbum提供了非常易用的语法,可以轻松地以跨平台的方式执行本地或者远程命令,获取输出或者错误代码。还可以组合它们(shell 管道的方式),而且它还提供了创建命令行应用的接口。 virtualenv - virtualenv用来建立一个虚拟的python环境,一个专属于项目的python环境。用virtualenv 来保持一个干净的环境非常有用。 Gunicorn - Gunicorn 是一个Python WSGI UNIX的HTTP服务器。这是一个pre-fork worker的模型,Gunicorn服务器大致与各种Web框架兼容,只需非常简单的执行,轻量级的资源消耗,以及相当迅速,Nginx+Gunicorn+Django 部署小记。 mitmproxy - mitmproxy 是用 Python 和 C 开发的一个中间人代理软件(man-in-the-middle proxy),它可以用来拦截、修改、重放和保存 HTTP/HTTPS 请求。 Sentry - Sentry 是一个实时的事件日志和聚合平台,基于 Django 构建。Sentry 可以帮助你将 Python 程序的所有 exception 自动记录下来,然后在一个好用的 UI 上呈现和搜索。 newrelic - newrelic性能监控的好工具,国内有;云智慧、ONE APM。 ipapy - iOS项目自动打包脚本,并且上传到fir.im,然后发送邮件给测试人员。 树莓派 图片自动发邮箱 - 报警图片自动发邮箱功能。 自动更新树莓派的内网、外网IP地址到 自己的github上 - 自动更新树莓派的内网、外网IP地址到 自己的github。 rpi-start - 树莓派初始配置指南(2代B型)。 RaspberryWechatPi - 基于树莓派的智能家居控制平台 微信服务端。 dotbro-server - 瀑布IM 开源点歌系统,架设树莓派点歌系统:如何共享办公室的音箱。 第三方平台 wechat-python-sdk - wechat-python-sdk微信公众平台Python开发包 http://wechat-python-sdk.readthedocs.org/ , 非官方微信公众平台 Python 开发包,包括官方接口和非官方接口。 wechatpy - wechatpy 是一个微信 (WeChat) 公众平台的第三方 Python SDK, 实现了普通公众平台和企业号公众平台的解析消息、生成回复和主动调用等 API。阅读文档:http://wechatpy.readthedocs.org/zh_CN/latest/ wechat-deleted-friends - wechat-deleted-friends查看被删的微信好友。 wxBot - wxBot为Python包装的网页微信API。可以很容易地实现微信机器人。参考文章:《挖掘微信Web版通信的全过程》、《微信协议简单调研笔记》。 WeixinBot - WeixinBot微信web协议分析和实现微信机器人(微信网页版 wx2.qq.com)。其他版本 WeRoBot - WeRoBot是一个面向公众号的微信机器人框架,文档 。 WxRobot - WxRobot:面向个人账户的微信机器人框架,文档 。 Wechat django - Wechat django一个基于django开发的微信公众平台,整体环境搭建在新浪SAE平台上,暂时实现的功能:查询天气情况、翻译。 gxgk-wechat-server - gxgk-wechat-server莞香广科微信公众号后端,使用 Python、Flask、Redis、MySQL、Celery ,为在校学生提供一系列信息查询与便民服务。 weChat-python-sdk - weChat-python-sdk微信公共平台非官方SDK,主要实现主动的消息推送和获取,该项目已经过期! wechat-admin - 基于Flask和MySQL能够帮助快速迁移微信服务号后台到自家服务器的框架(tag: Python, wechat, weixin, admin, Flask) 。 IDE PyCharm - PyCharm是由JetBrains打造的一款Python IDE,Community社区版本是免费的,Professional版本$199.00/年。 Eric - Eric是一个集成了项目管理功能的 Python和Ruby集成开发环境。 PyDev - PyDev是Eclipse开发Python的 IDE,支持Python,Jython和IronPython的开发。 KomodoEdit - Komodo Edit 是非常干净,专业的 Python IDE。 PyScripter - PyScripter是一个开源的Python语言集成开发环境。 WingIDE - WingIDE是个相当优秀的 IDE。 IEP - IEP 是跨平台的 Python IDE,旨在提供简单高效的 Python 开发环境。包括两个重要的组件:编辑器和 Shell,并且提供插件工具集从各个方面来提高开发人员的效率。 Emacs - Linux文本编辑器Emacs是一种强大的文本编辑器,在程序员和其他以技术工作为主的计算机用户中广受欢迎。 sublimetext - sublimetext:Sublime Text 是一个轻量、简洁、高效、跨平台的编辑器。 Atom - Atom 是 Github 专门为程序员推出的一个跨平台文本编辑器。具有简洁和直观的图形用户界面,并有很多有趣的特点:支持CSS,HTML,JavaScript等网页编程语言。它支持宏,自动完成分屏功能,集成了文件管理器。官网下载,比较不错的插件:爆炸效果 activate-power-mode、程序员鼓励师 atom-miku 。 其他 IoTNotes - 开源硬件记录。 GitHub上Star最多的100个python repository - GitHub上Star最多的100个python repository。 10个Python 模块 - 你该了解的10个 Python 模块。 dask - 【(Python)集成任务调度/阻塞算法的数据并行处理库Dask】支持大数据集的分割多核并行处理,Doc。 Phonenumbers - Phonenumbers 小巧,实用简便,没有地理代编码,运营商,时区等metadata数据。它能识别多种格式,然后使用不同的格式/样式进行有效匹配。 toyplot - Python交互绘图库Toyplot,文档doc。 pythalesians - Python金融(分析工具)库PyThalesians。 20个机器学习开源项目 - 20 个顶尖的 Python 机器学习开源项目 Scikit-learn、Pylearn2、NuPIC…… Seaborn - 用 Seaborn 画出好看的分布图, 使用说明 。 Python_Coding_Rule - 【Python代码指南】,这篇文档改编自Guido最初的《Python风格指南》一文,希望对初学Python的朋友们有所借鉴。 GGTinypng - 批量压缩png和jpg图片python脚本,已经支持子文件夹里面的图片,会按原始的相对路径存放到输出文件夹内。 sinaweibopy - 新浪微博Python SDK。 keras - Keras是一个高度模块化的神经网络库,用Python语言编写,可以基于TensorFlow或Theano框架运行。 yapf - yapf是一个Python文件代码格式化工具,但与其他类似工具采取了不同的算法。它脱胎于由 Daniel Jasper 开发的 clang-format。 tqdm - tqdm可以在长循环中添加一个进度提示信息,用户只需要封装任意的迭代器 tqdm(iterator),是一个快速、扩展性强的进度条工具库。 pyvim - pyvim用Python语言实现的Vim编辑器。 snake - Snake用来取代Vim的VimScript进行Vim的插件编程,借由Python的强大,让插件编程如虎添翼。 pyxley - 使用Flask和React.js,快速开发数据面板(dashboard。在网页上显示一个数据面板是与人分享数据科学发现的最直观方法。对R语言来说有Shiny来简化数据科学家开发网页的工作,而Pyxley就相当于Python版的Shiny。使用Pyxley不光不用写HTML、CSS,你还可以加入自己的JavaScript来进行定制。 Tomorrow - Tomorrow为Python 2.7中的异步代码提供了神奇的装饰器语法实现。 ibis - Ibis是Cloudera Labs推出的一个新项目,目前还是预览版。它试图解决的就是数据集规模的问题,但对用户提供的确是单机上Python的体验,而且能够与现有的Python数据生态圈(Pandas、Scikit-learn、Numpy)进行集成。未来它还计划加入与机器学习和高级分析集成的功能。 ipython - IPython 是一个在多种编程语言之间进行交互计算的命令行 shell,最开始是用 python 开发的,提供增强的内省,富媒体,扩展的 shell 语法,tab 补全,丰富的历史等功能。 bpython - bpython是一个不错的Python解释器的界面,很像现在的IDE(集成开发环境)。 Ptpython - Ptpython是一个高级的python 交互式解释器(REPL)。python-prompt-toolkit 。 DreamPie - DreamPie 是一个Python shell,为Python开发者提供自动完成的属性;功能和文档显示;并且将session历史存储为HTML文件。 Arrow - Arrow这个库可以更好地处理Python中的日期和时间(data/time)。 retrying - Retrying库可以帮你避免重复劳动:它实现了『重试』行为。它提供了一个通用的 decorator,而且还可以设置一系列的属性,如最大重试次数、延时、退避休眠(backoff sleeping)和错误条件(error conditions)等,以此来获得你想要的重试行为。简单轻便。 python-phonenumbers - python-phonenumbers从Google 的『libphonenumbers』库移植而来,用来解析、格式化或者验证电话号码,而且需要写的代码非常少。最重要的是,『phonenumbers』可以判断一个电话号码是否是唯一的(遵照 E.164 格式)。它同时支持 Python 2 和 Python 3。 monkeylearn-python - monkeylearn-python通过简单易用的 RESTFul API 提供了云端的文本挖掘功能:比如文字中的情感、最重要的关键字,可以对文本进行话题检测,还可以使用自定义的文本分类器进行其他任何处理。 Cookiecutter - 一个命令行实用程序,从cookiecutters(项目模板)创建的项目,比如:创建从一个Python包项目模板的Python包项目。 Sunburnt - Sunburnt全文搜索服务器Solr的Python接口。 Celery - Celery是基于Python开发的分布式任务队列。它支持使用任务队列的方式在分布的机器/进程/线程上执行任务调度。 Gevent - Gevent是一个基于greenlet的Python的并发框架,以微线程greenlet为核心,使用了epoll事件监听机制以及诸多其他优化而变得高效。 Greenlet - Greenlet是一个python的并行处理的一个库。 Eventlet - Eventlet是一个用来处理和网络相关的python库函数,而且可以通过协程来实现并发。 Python Async IO Resources - asyncio python的异步iO操作资源, asyncio - asyncio3.4以后作为python标准库来使用了。 Twisted - Twisted是一个用python语言写的事件驱动的网络框架,支持很多种协议,也是一个异步机制的框架。 eviltransform.python - eviltransform.python解决国内GPS地图坐标偏移问题,它将政府加密过的GCJ-02坐标,转成世界通用的WGS-84坐标。 pagure - Pagure是一个用Python编写的新的、功能齐全的、提供 Web 服务的 Git仓库。它类似于Github 和 Gitlab ,同时允许开源贡献者分享彼此的资源,实现代码和内容上的合作。官网 博客与播客及书籍文档 值得关注的10个python语言博客 - 值得关注的10个python语言博客, Planet Python 最出名的python博客其中之一; lucumrflask的创始人; love-python 有很多有用的知识和代码; Doug Hellmann 博主是PYMOTW(Python Module Of the Week)成员之一,博客里面包含了很多library的知识; Code Who Says Py 这个博客很不错,虽然它更新的不是很及时; effbot 代码和任何你能想得到的东西都在里面; pydanny 主要关于Django的博客; inventwithpython Al Sweigat,他写了很多本关于python的书; pythonlibrary 最有用的博客,他让我的python技术迅猛提; freepythontips 打不开了。 听技术播客 - 听技术播客:一边学Python编程一边学英语。Talk Python to Me 每期都会请一些知名的Python开发者做嘉宾; Podcastinit Podcastinit也是专注于Python语言的,每期节目也会邀请不同的嘉宾,探讨与Python有关的工具和产品,另外也时常探讨技术领域多样性和包容性等更加宽泛、更具社会性的话题; Python Test Podcast 聚焦的主题是测试,大部分都是与测试有关的。 django-web-app-book - Django Web 开发实战,本书是一本在线的免费的Django Web编程书籍。 Django-Design-Patterns-and-Best-Practices - Django设计模式与最佳实践。 他人总结 awesome-python - Awesome可能是GitHub上寻找和整理开源项目最好的方式 。 interview_python - 十分全面的Python的面试题。 issue-198-top2015 - 蠎周刊2015年度最赞。
API开发文档 接口1:打印内容 参数 说明 deviceNo 打印机编号 key 密钥 printContent 打印内容 times 固定传1 调用方式:HTTP POSTURL:http://open.printcenter.cn:8080/addOrder返回结果:JSON字符串 ----------S1小票机返回的结果有如下几种:---------- {"responseCode":0,"msg":"订单添加成功,打印完成","orderindex":"xxxxxxxxxxxxxxxxxx"} {"responseCode":1,"msg":"订单添加成功,正在打印中","orderindex":"xxxxxxxxxxxxxxxxxx"} {"responseCode":2,"msg":"订单添加成功,但是打印机缺纸,无法打印","orderindex":"xxxxxxxxxxxxxxxxxx"} {"responseCode":3,"msg":"订单添加成功,但是打印机不在线","orderindex":"xxxxxxxxxxxxxxxxxx"} ----------以上情况无须再次发送订单;下面的情况需要进行错误处理---------- {"responseCode":10,"msg":"内部服务器错误;"} {"responseCode":11,"msg":"参数不正确;"} {"responseCode":12,"msg":"打印机未添加到服务器;"} {"responseCode":13,"msg":"未添加为订单服务器;"} {"responseCode":14,"msg":"订单服务器和打印机不在同一个组;"} {"responseCode":15,"msg":"订单已经存在,不能再次打印;"} ----------USB小票机返回的结果有如下几种:---------- {"responseCode":0,"msg":"已加入打印队列"} {"responseCode":2,"msg":"服务器处理订单失败"} 接口2:查询订单是否打印成功 参数 说明 deviceNo 打印机编号 key 密钥 orderindex 订单索引(orderindex,该值由接口一返回) 调用方式:HTTP POSTURL:http://open.printcenter.cn:8080/queryOrder返回结果:JSON字符串 ----------S1小票机返回的结果有如下几种:---------- {"responseCode":0,"msg":"打印成功"} {"responseCode":1,"msg":"正在打印中"} {"responseCode":2,"msg":"打印机缺纸"} {"responseCode":3,"msg":"打印机下线"} {"responseCode":16,"msg":"订单不存在"} 接口3:查询打印机的状态 参数 说明 deviceNo 打印机编号 key 打印密钥 调用方式:HTTP POSTURL:http://open.printcenter.cn:8080/queryPrinterStatus返回结果:JSON字符串 ----------S1小票机返回的结果有如下几种:---------- {"responseCode":1,"msg":"打印机正常在线"} {"responseCode":2,"msg":"打印机缺纸"} {"responseCode":3,"msg":"打印机下线"} 代码示例 <?php header("Content-Type: text/html;charset=utf-8"); $DEVICE_NO = '123458615'; $key = '72264'; $content = "^N1^F1\n"; $content .= "^B2 测试打印\n"; $content .= "名称 单价 数量 金额\n"; $content .= "--------------------------------\n"; $content .= "饭 1.0 1 1.0\n"; $content .= "炒饭 10.0 10 10.0\n"; $content .= "蛋炒饭 10.0 10 100.0\n"; $content .= "鸡蛋炒饭 100.0 1 100.0\n"; $content .= "番茄蛋炒饭 1000.0 1 100.0\n"; $content .= "西红柿蛋炒饭 1000.0 1 100.0\n"; $content .= "西红柿鸡蛋炒饭 100.0 10 100.0\n"; $content .= "备注:加辣\n"; $content .= "--------------------------------\n"; $content .= "^H2合计:xx.0元\n"; $content .= "^H2送货地点:广州市南沙区xx路xx号\n"; $content .= "^H2联系电话:13888888888888\n"; $content .= "^H2订餐时间:2014-08-08 08:08:08\n"; $qrlength=chr(strlen('http://www.dzist.com')); $content .= "^Q".$qrlength."http://www.dzist.com\n"; $result = sendSelfFormatOrderInfo($DEVICE_NO, $key, 1,$content); var_dump($result); function sendSelfFormatOrderInfo($device_no,$key,$times,$orderInfo){ // $times打印次数 $selfMessage = array( 'deviceNo'=>$device_no, 'printContent'=>$orderInfo, 'key'=>$key, 'times'=>$times ); $url = "http://open.printcenter.cn:8080/addOrder"; $options = array( 'http' => array( 'header' => "Content-type: application/x-www-form-urlencoded ", 'method' => 'POST', 'content' => http_build_query($selfMessage), ), ); $context = stream_context_create($options); $result = file_get_contents($url, false, $context); return $result; } ?> 打印机基本指令S1小票机2.0以上版本适用 一、字体放大 命令^Nn: 该命令位于所有数据前面,用于控制打印张数,可以不加,不加默认打一张。 例如: ^N5 打印机打印测试 Print order data **************** 表示打印 5 张相同订单。 命令^Hn 该命令位于每行数据首位,用于控制此行字体纵向放大 n 倍,可以不加,不加默认不放大。 例如: ^H2 放大 2 倍 此时“放大 2 倍”这几个字会纵向放大 2 倍,效果见下图。 注意:正常大小的字体,每行最多可以打 16 个汉字或 32 个英文或数字,如果每行超过最大字数限制,会出现多出的字覆盖这行最开始的字,导致看起来乱码,所以使用该命令请确保字数在每行最大字数内,如果超过,请手动回车换行。 命令^Wn 该命令位于每行数据首位,用于控制此行字体横向放大 n 倍,可以不加,不加默认不放大。 例如: ^W2 放大 2 倍 此时“放大 2 倍”这几个字会横向放大 2 倍,效果见下图。 注意:正常大小的字体,每行最多可以打 16 个汉字或 32 个英文或数字,由于^Wn 命令会横向放大 n 倍,如果每行超过(最大字数/n)限制,会出现多出的字覆盖这行最开始的字,导致看起来乱码,所以使用该命令请确保字数在每行字数在(最大字数/n)内,如果超过,请手动回车换行。如^W4 测试打印机放大,共 7 个汉字,放大后会占用 28 个汉字的位置,已经超过每行最多 16 个汉字。 命令^Bn 该命令位于每行数据首位,用于控制此行字体横向纵向同时放大 n 倍,可以不加,不加默认不放大。 例如: ^B2 放大 2 倍 此时“放大 2 倍”这几个字会横向纵向同时放大 2 倍,效果见下图。 注意:正常大小的字体,每行最多可以打 16 个汉字或 32 个英文或数字,由于^Bn 命令会横向纵向同时放大 n 倍,如果每行超过(最大字数/n)限制,会出现多出的字覆盖这行最开始的字,导致看起来乱码,所以使用该命令请确保字数在每行字数在(最大字数/n)内,如果超过,请手动回车换行。如 ^B3 测试打印机放大,共 7 个汉字,放大后会占用 21 个汉字的位置,已经超过每行最多 16 个汉字。 效果图: 命令^Qn 该命令位于需要打印的宣传关注二维码链接首位,用于将链接自动转换成二维码,达到宣传关注的目的。n 的值为二维码链接的字符长度,用 ASCII 编码表示。此命令,可以不加,不加默认不打。 例如: ^Q +http://weixin.qq.com/r/2Eg2LkzEKRFWrQhN9123 此时 http://weixin.qq.com/r/2Eg2LkzEKRFWrQhN9123 的长度为 43,对应 ASCII 值是’+’,计算机可以自动计算长度,这里为了描述清晰,查出 43 对应的 ASCII 字符。此链接经过转换后的二维码效果见下图。 注意:此二维码最多支持 49 个字符,请不要加入中文。打印机会自动更具字符多少转换成大小不一样的二维码,智能打印在打印纸中间。使用最为广泛的就是微信公众号的关注二维码。 命令^Pn 该命令位于需要打印的动态支付二维码链接首位,用于将链接自动转换成二维码,达到支付宝等支付的目的(支付成功后,此二维码失效,即:扫描第二次不起作用)。n 的值为二维码链接的长度,用 ASCII 编码表示。此命令,可以不加,不加默认不打。 例如: ^P(https://qr.alipay.com/pmr1bs2a1i1udbumf7 此时“https://qr.alipay.com/pmr1bs2a1i1udbumf7”的长度为 40,对应 ASCII 值是’(’,计算机可以自动计算长度,这里为了描述清晰,查出 40 对应的 ASCII 字符。此链接经过转换后的支付二维码效果见下图。 注意:此动态支付二维码最多支持 49 个字符,请不要加入中文。打印机会自动更具字符多少转换成大小不一样的二维码,智能打印在打印纸中间。使用最为广泛的就是外卖或用餐结束后,结账时无需再使用现金或者刷卡浪费时间,直接使用支付宝扫描,输入密码支付完成即可,效率将非常高。 命令^On 该命令位于需要打印的动态条码(一维码)链接首位,用于将链接自动转换成扫描枪扫描的一维码,达到迅速录入的目的。n 的值为一维码的长度,用 ASCII 编码表示。此命令,可以不加,不加默认不打。 例如: ^P test12345 此时“test12345”的长度为 9,对应 ASCII 值是’ ’(水平制表符),计算机可以自动计算长度,这里为了描述清晰,查出 9 对应的 ASCII 字符。此条码转换后的效果见下图。 注意:此动态条码最多支持 13 个字符,请不要加入中文。打印机会自动更具字符多少转换成大小不一样的条码,智能打印在打印纸中间。使用最为广泛的就是物流、仓库和超市等地方,达到迅速录入或查找等应用。
关键字:微信公众平台 JSSDK 发送给朋友 收货地址共享接口 openAddress 作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/p/weixin-openaddress.html 在这篇微信公众平台开发教程中,我们将介绍如何在网页中实现获取收货地址的功能。 收货地址共享接口 在2016年4月13日 进行过升级,2016年5月20日只能使用新接口,本教程为新版接口的教程! 本文分为以下二个部分: 生成JS-SDK权限验证签名 实现获取共享收货地址 一、微信JS-SDK 1. 获得Access Token access token的获得方法在前面有介绍,详情见 微信公众平台开发(26) ACCESS TOKEN 2. 获取jsapi_ticket 生成签名之前必须先了解一下jsapi_ticket,jsapi_ticket是公众号用于调用微信JS接口的临时票据。正常情况下,jsapi_ticket的有效期为7200秒,通过access_token来获取。由于获取jsapi_ticket的api调用次数非常有限,频繁刷新jsapi_ticket会导致api调用受限,影响自身业务,开发者必须在自己的服务全局缓存jsapi_ticket 。 参考以下文档获取access_token(有效期7200秒,开发者必须在自己的服务全局缓存access_token):用第一步拿到的access_token 采用http GET方式请求获得jsapi_ticket(有效期7200秒,开发者必须在自己的服务全局缓存jsapi_ticket),接口地址如下 https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi 成功返回如下JSON: { "errcode":0, "errmsg":"ok", "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", "expires_in":7200 } 获得jsapi_ticket之后,就可以生成JS-SDK权限验证的签名了。 3. 签名算法实现 签名生成规则如下:参与签名的字段包括noncestr(随机字符串), 有效的jsapi_ticket, timestamp(时间戳), url(当前网页的URL,不包含#及其后面部分) 。对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是所有参数名均为小写字符。对string1作sha1加密,字段名和字段值都采用原始值,不进行URL 转义。 即signature=sha1(string1)。 示例: noncestr=Wm3WZYTPz0wzccnW jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg timestamp=1414587457 url=http://mp.weixin.qq.com?params=value 步骤1. 对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1: jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW&timestamp=1414587457&url=http://mp.weixin.qq.com?params=value 步骤2. 对string1进行sha1签名,得到signature: 0f9de62fce790f9a083d5c99e95740ceb90c27ed 完整代码如下 <?php class JSSDK { private $appId; private $appSecret; public function __construct($appId, $appSecret) { $this->appId = $appId; $this->appSecret = $appSecret; } public function getSignPackage() { $jsapiTicket = $this->getJsApiTicket(); // 注意 URL 一定要动态获取,不能 hardcode. $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://"; $url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; $timestamp = time(); $nonceStr = $this->createNonceStr(); // 这里参数的顺序要按照 key 值 ASCII 码升序排序 $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url"; $signature = sha1($string); $signPackage = array( "appId" => $this->appId, "nonceStr" => $nonceStr, "timestamp" => $timestamp, "url" => $url, "signature" => $signature, "rawString" => $string ); return $signPackage; } private function createNonceStr($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str = ""; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } private function getJsApiTicket() { // jsapi_ticket 应该全局存储与更新,以下代码以写入到文件中做示例 $data = json_decode(file_get_contents("jsapi_ticket.json")); if ($data->expire_time < time()) { $accessToken = $this->getAccessToken(); // 如果是企业号用以下 URL 获取 ticket // $url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken"; $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken"; $res = json_decode($this->httpGet($url)); $ticket = $res->ticket; if ($ticket) { $data->expire_time = time() + 7000; $data->jsapi_ticket = $ticket; $fp = fopen("jsapi_ticket.json", "w"); fwrite($fp, json_encode($data)); fclose($fp); } } else { $ticket = $data->jsapi_ticket; } return $ticket; } private function getAccessToken() { // access_token 应该全局存储与更新,以下代码以写入到文件中做示例 $data = json_decode(file_get_contents("access_token.json")); if ($data->expire_time < time()) { // 如果是企业号用以下URL获取access_token // $url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret"; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret"; $res = json_decode($this->httpGet($url)); $access_token = $res->access_token; if ($access_token) { $data->expire_time = time() + 7000; $data->access_token = $access_token; $fp = fopen("access_token.json", "w"); fwrite($fp, json_encode($data)); fclose($fp); } } else { $access_token = $data->access_token; } return $access_token; } private function httpGet($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_TIMEOUT, 500); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_URL, $url); $res = curl_exec($curl); curl_close($curl); return $res; } } 二、收货地址共享接口 一. 简介 微信收货地址共享,是指用户在微信浏览器内打开网页,填写过地址后,后续可以免填写支持快速选择,也可增加和编辑。此地址为用户属性,可在各商户的网页中共享使用。支持原生控件填写地址,地址数据会传递到商户。 地址共享是基于微信JavaScript API 实现,只能在微信内置浏览器中使用,其他浏览器调用无效。同时,需要微信5.0 版本才能支持,建议通过user agent 来确定用户当前的版本号后再调用地址接口。以iPhone 版本为例,可以通过useragent可获取如下微信版本示例信息:"Mozilla/5.0(iphone;CPU iphone OS 5_1_1 like Mac OS X)AppleWebKit/534.46(KHTML,like Geocko) Mobile/9B206MicroMessenger/5.0"其中5.0 为用户安装的微信版本号,商户可以判定版本号是否高于或者等于5.0。 地址格式微信地址共享使用的数据字段包括: 收货人姓名 地区,省市区三级 详细地址 邮编 联系电话 其中,地区对应是国标三级地区码,如“广东省-广州市-天河区”,对应的邮编是是510630。详情参考链接:http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html 2. 绑定域名 先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。 3. 获取签名包 <?php require_once "jssdk.php"; $jssdk = new JSSDK("yourAppID", "yourAppSecret"); $signPackage = $jssdk->GetSignPackage(); ?> 4. 引入JS文件 在需要调用JS接口的页面引入如下JS文件: 特别注意:JS-SDK版本需使用http://res.wx.qq.com/open/js/jweixin-1.1.0.js <script src="http://res.wx.qq.com/open/js/jweixin-1.1.0.js"></script> 5.通过config接口注入权限验证配置 所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用。 <script> wx.config({ debug: false, appId: '<?php echo $signPackage["appId"];?>', timestamp: <?php echo $signPackage["timestamp"];?>, nonceStr: '<?php echo $signPackage["nonceStr"];?>', signature: '<?php echo $signPackage["signature"];?>', jsApiList: [ // 所有要调用的 API 都要加到这个列表中 'checkJsApi', 'openAddress', ] }); </script> 5. 通过ready接口处理成功验证 需要在页面加载时就调用,需要把相关接口放在ready函数中调用来确保正确执行 wx.ready(function () { }); 5.1 通过checkJsApi判断当前客户端版本是否支持分享参数自定义 wx.checkJsApi({ jsApiList: [ 'openAddress', ], success: function (res) { alert(JSON.stringify(res)); } }); 5.3. 实现收货地址共享 wx.openAddress({ trigger: function (res) { alert('用户开始拉出地址'); }, success: function (res) { alert('用户成功拉出地址'); alert(JSON.stringify(res)); document.form1.address1.value = res.provinceName; document.form1.address2.value = res.cityName; document.form1.address3.value = res.countryName; document.form1.detail.value = res.detailInfo; document.form1.national.value = res.nationalCode; document.form1.user.value = res.userName; document.form1.phone.value = res.telNumber; document.form1.postcode.value = res.postalCode; document.form1.errmsg.value = res.errMsg; document.form1.qq.value = 1354386063; }, cancel: function (res) { alert('用户取消拉出地址'); }, fail: function (res) { alert(JSON.stringify(res)); } }); 返回说明 返回值 说明 errMsg 获取编辑收货地址成功返回“openAddress:ok”。 userName 收货人姓名。 postalCode 邮编。 provinceName 国标收货地址第一级地址(省)。 cityName 国标收货地址第二级地址(市)。 countryName 国标收货地址第三级地址(国家)。 detailInfo 详细收货地址信息。 nationalCode 收货地址国家码。 三、实现效果
关键字:微信公众平台 微信开放平台 微信登录 移动应用微信登录 使用微信账号登录APP作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/p/weixin-applogin.html 在这篇微信公众平台开发教程中,我们将介绍如何使用微信开放平台接口实现移动应用微信登录的功能。 移动应用微信登录是基于OAuth2.0协议标准构建的微信OAuth2.0授权登录系统。 在进行微信OAuth2.0授权登录接入之前,在微信开放平台注册开发者帐号,并拥有一个已审核通过的移动应用,并获得相应的AppID和AppSecret,申请微信登录且通过审核后,可开始接入流程。 1、目前移动应用上微信登录只提供原生的登录方式,需要用户安装微信客户端才能配合使用。 2、对于Android应用,建议总是显示微信登录按钮,当用户手机没有安装微信客户端时,请引导用户下载安装微信客户端。 3、对于iOS应用,考虑到iOS应用商店审核指南中的相关规定,建议开发者接入微信登录时,先检测用户手机是否已安装微信客户端(使用sdk中isWXAppInstalled函数 ),对未安装的用户隐藏微信登录按钮,只提供其他登录方式(比如手机号注册登录、游客登录等)。 授权流程说明 微信OAuth2.0授权登录让微信用户使用微信身份安全登录第三方应用或网站,在微信用户授权登录已接入微信OAuth2.0的第三方应用后,第三方可以获取到用户的接口调用凭证(access_token),通过access_token可以进行微信开放平台授权关系接口调用,从而可实现获取微信用户基本开放信息和帮助用户实现基础开放功能等。 微信OAuth2.0授权登录目前支持authorization_code模式,适用于拥有server端的应用授权。该模式整体流程为: 1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数; 2. 通过code参数加上AppID和AppSecret等,通过API换取access_token; 3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。 获取access_token时序图: 第一步:请求CODE 移动应用微信授权登录 开发者需要配合使用微信开放平台提供的SDK进行授权登录请求接入。正确接入SDK后并拥有相关授权域(scope,什么是授权域?)权限后,开发者移动应用会在终端本地拉起微信应用进行授权登录,微信用户确认后微信将拉起开发者移动应用,并带上授权临时票据(code)。 iOS平台应用授权登录接入代码示例(请参考iOS接入指南): -(void)sendAuthRequest { //构造SendAuthReq结构体 SendAuthReq* req =[[[SendAuthReq alloc ] init ] autorelease ]; req.scope = @"snsapi_userinfo" ; req.state = @"123" ; //第三方向微信终端发送一个SendAuthReq消息结构 [WXApi sendReq:req]; } Android平台应用授权登录接入代码示例(请参考Android接入指南): { // send oauth request Final SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "wechat_sdk_demo_test"; api.sendReq(req); } 参数说明 参数 是否必须 说明 appid 是 应用唯一标识,在微信开放平台提交应用审核通过后获得 scope 是 应用授权作用域,如获取用户个人信息则填写snsapi_userinfo(什么是授权域?) state 否 用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验 返回示例: appid: wxd477edab60670232 scope: snsapi_userinfo state: wechat_sdk_demo 可拉起微信打开授权登录页: 返回说明 用户点击授权后,微信客户端会被拉起,跳转至授权界面,用户在该界面点击允许或取消,SDK通过SendAuth的Resp返回数据给调用方。 返回值 说明 ErrCode ERR_OK = 0(用户同意)ERR_AUTH_DENIED = -4(用户拒绝授权)ERR_USER_CANCEL = -2(用户取消) code 用户换取access_token的code,仅在ErrCode为0时有效 state 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K lang 微信客户端当前语言 country 微信用户当前国家信息 第二步:通过code获取access_token 获取第一步的code后,请求以下链接获取access_token: https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code 参数说明 参数 是否必须 说明 appid 是 应用唯一标识,在微信开放平台提交应用审核通过后获得 secret 是 应用密钥AppSecret,在微信开放平台提交应用审核通过后获得 code 是 填写第一步获取的code参数 grant_type 是 填authorization_code 返回如下 { "access_token": "OezXcEiiBSKSxW0eoylIeOZ0dfxvb93UyrFdwznvwUv3JkVNVV1yFvQQa3IfuyMi4iZGDsAfe81sCaUXxyKrI-5XgCvhAS02eAC4MF2fJFl80Y9s-0h1EsuBmIVKgu0GnKhxCQ0M8G-gkQAJpzLzmQ", "expires_in": 7200, "refresh_token": "OezXcEiiBSKSxW0eoylIeOZ0dfxvb93UyrFdwznvwUv3JkVNVV1yFvQQa3IfuyMiH7dCabGFyMRtZHnHPHuEK78cf1eISYJ4y453T8pDa2tFAIJu8bFeLMBpeFSv9dgnGrK-ZfRxHzhq7IW4qevEMQ", "openid": "oH9d2v7NmDhsFzICG63UPSIOgUcY", "scope": "snsapi_userinfo", "unionid": "o4wcnwx0BVC4F_hSl5qCd5rC4Jps" } 参数说明 参数 说明 access_token 接口调用凭证 expires_in access_token接口调用凭证超时时间,单位(秒) refresh_token 用户刷新access_token openid 授权用户唯一标识 scope 用户授权的作用域,使用逗号(,)分隔 unionid 当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段 获取用户个人信息(UnionID机制) 接口说明 此接口用于获取用户个人信息。开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。请注意,在用户修改微信头像后,旧的微信头像URL将会失效,因此开发者应该自己在获取用户信息后,将头像图片保存下来,避免微信头像URL失效后的异常情况。 请求说明 http请求方式: GET https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID 参数说明 参数 是否必须 说明 access_token 是 调用凭证 openid 是 普通用户的标识,对当前开发者帐号唯一 lang 否 国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语,默认为zh-CN { "openid": "oH9d2v7NmDhsFzICG63UPSIOgUcY", "nickname": "方倍", "sex": 0, "language": "zh_CN", "city": "", "province": "", "country": "CN", "headimgurl": "http://wx.qlogo.cn/mmopen/pburdzLK7PUTcFw3ozK52Gravkznno51DSjnqnzsG6WzJLUOtadGBYYSVqh5YDicdawxrD6hHoR96OcyyDWAEgA/0", "privilege": [], "unionid": "o4wcnwx0BVC4F_hSl5qCd5rC4Jps" } 参数说明 参数 说明 openid 普通用户的标识,对当前开发者帐号唯一 nickname 普通用户昵称 sex 普通用户性别,1为男性,2为女性 province 普通用户个人资料填写的省份 city 普通用户个人资料填写的城市 country 国家,如中国为CN headimgurl 用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空 privilege 用户特权信息,json数组,如微信沃卡用户为(chinaunicom) unionid 用户统一标识。针对一个微信开放平台帐号下的应用,同一用户的unionid是唯一的。 完整PHP SDK class class_app { var $appid = APPID; var $appsecret = APPSECRET; //构造函数 public function __construct($appid = NULL, $appsecret = NULL) { if($appid && $appsecret){ $this->appid = $appid; $this->appsecret = $appsecret; } } //通过code获取access_token public function oauth2_access_token($code) { $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->appsecret."&code=".$code."&grant_type=authorization_code"; $res = $this->http_request($url); return json_decode($res, true); } //获取用户个人信息(UnionID机制) public function oauth2_get_user_info($access_token, $openid) { $url = "https://api.weixin.qq.com/sns/userinfo?access_token=".$access_token."&openid=".$openid."&lang=zh_CN"; $res = $this->http_request($url); return json_decode($res, true); } //HTTP请求(支持HTTP/HTTPS,支持GET/POST) protected function http_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, TRUE); $output = curl_exec($curl); curl_close($curl); return $output; } //日志记录 private function logger($log_content) { if(isset($_SERVER['HTTP_APPNAME'])){ //SAE sae_set_display_errors(false); sae_debug($log_content); sae_set_display_errors(true); }else if($_SERVER['REMOTE_ADDR'] != "127.0.0.1"){ //LOCAL $max_size = 500000; $log_filename = "log.xml"; if(file_exists($log_filename) and (abs(filesize($log_filename)) > $max_size)){unlink($log_filename);} file_put_contents($log_filename, date('Y-m-d H:i:s').$log_content."\r\n", FILE_APPEND); } } } 调用方法 /* 方倍工作室 http://www.fangbei.org/ CopyRight 2014 All Rights Reserved 微信开放平台 移动应用 (微信登录) */ header("Content-type: text/html; charset=utf-8"); define('APPID', "wx3f05f4b79761d123"); define('APPSECRET', "9acc222b92afb29cff90b9bcfc7d6080"); $code = "041359a1b393c92a5a509ce24e2ef50f"; $weixin = new class_app(); var_dump($weixin); //传入授权临时票据(code) $oauth2_info = $weixin->oauth2_access_token($code); var_dump($oauth2_info); $result = $weixin->oauth2_get_user_info($oauth2_info['access_token'], $oauth2_info['openid']); var_dump($result);
关键字:微信支付 收货地址共享作者:方倍工作室原文: http://www.cnblogs.com/txw1958/p/weixin-editAddress.html 请看新版教程 微信支付开发(7) 收货地址共享接口V2 本文介绍微信支付下的收货地址共享接口的开发过程。 一. 简介 微信收货地址共享,是指用户在微信浏览器内打开网页,填写过地址后,后续可以免填写支持快速选择,也可增加和编辑。此地址为用户属性,可在各商户的网页中共享使用。支持原生控件填写地址,地址数据会传递到商户。 地址共享是基于微信JavaScript API 实现,只能在微信内置浏览器中使用,其他浏览器调用无效。同时,需要微信5.0 版本才能支持,建议通过user agent 来确定用户当前的版本号后再调用地址接口。以iPhone 版本为例,可以通过useragent可获取如下微信版本示例信息:"Mozilla/5.0(iphone;CPU iphone OS 5_1_1 like Mac OS X)AppleWebKit/534.46(KHTML,like Geocko) Mobile/9B206MicroMessenger/5.0"其中5.0 为用户安装的微信版本号,商户可以判定版本号是否高于或者等于5.0。 地址格式微信地址共享使用的数据字段包括: 收货人姓名 地区,省市区三级 详细地址 邮编 联系电话 其中,地区对应是国标三级地区码,如“广东省-广州市-天河区”,对应的邮编是是510630。详情参考链接:http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html 二. OAuth2.0授权 获取收货地址之前前需要调用 登录授权接口获取到一次OAuth2.0的Access Token 。所以需要做一次授权,这次授权是不弹出确认框的。其实质就是在用户访问 http://www.fangbei.org/wxpay/js_api_call.php 时跳转到 https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx8888888888888888&redirect_uri=http://www.fangbei.org/wxpay/js_api_call.php&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect 以此来获得code参数,并根据code来获得授权access_token及openid,这个access token将用于收货地址共享接口。 其实现的详细流程可参考 微信公众平台开发(71)OAuth2.0网页授权 二、获取随机字符串 生成随机字符串的方法如下 三、生成签名 参与addrSign 签名的字段包括:appId、url(调用JavaScript API的网页url)、timestamp、noncestr、accessToken对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)后,使用URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串string1。这里需要注意的是签名过程中所有参数名均为小写字符,例如appId 在排序后字符串则为appid;对string1作签名算法,字段名和字段值都采用原始值,不进行URL 转义。具体签名算法为addrSign = SHA1(string1)。这里给出生成addrSign 的具体示例如下: appId=wx17ef1eaef46752cb url=http://open.weixin.qq.com/ timeStamp=1384841012 nonceStr=123456 accessToken=OezXcEiiBSKSxW0eoylIeBFk1b8VbNtfWALJ5g6aMgZHaqZwK4euEskSn78Qd5pLsfQtuMdgmhajVM5QDm24W8X3tJ18kz5mhmkUcI3RoLm7qGgh1cEnCHejWQo8s5L3VvsFAdawhFxUuLmgh5FRA i:经过a过程键值对排序后得到string1 为: accesstoken=OezXcEiiBSKSxW0eoylIeBFk1b8VbNtfWALJ5g6aMgZHaqZwK4euEskSn78Qd5pLsfQtuMdgmhajVM5QDm24W8X3tJ18kz5mhmkUcI3RoLm7qGgh1cEnCHejWQo8s5L3VvsFAdawhFxUuLmgh5FRA&appid=wx17ef1eaef46752cb&noncestr=123456&timestamp=1384841012&url=http://open.weixin.qq.com/?code=CODE&state=STATE ii:经过b过程签名后可得到: addrSign=SHA1(accesstoken=OezXcEiiBSKSxW0eoylIeBFk1b8VbNtfWALJ5g6aMgZHaqZwK4euEskSn78Qd5pLsfQtuMdgmhajVM5QDm24W8X3tJ18kz5mhmkUcI3RoLm7qGgh1cEnCHejWQo8s5L3VvsFAdawhFxUuLmg h5FRA&appid=wx17ef1eaef46752cb&noncestr=123456&timestamp=1384841012&url=http://open.weixin.qq.com/?code=CODE&state=STATE)=ca604c740945587544a9cc25e58dd090f200e6fb 实现代码如下 四、获得收货地址 编辑并获取用户收货地址editAddress接口,在网页前端调用。参数列表: 参数 必填 说明 appId 是 公众号appID scope 是 填写“jsapi_address”,获得编辑地址权限 signType 是 签名方式,目前仅支持SHA1 addrSign 是 签名,由各参数一起参与签名生成 timeStamp 是 时间戳 nonceStr 是 随机字符串 调用方法如下 参数返回: 返回值 说明 err_msg edit_address:ok获取编辑收货地址成功 edit_address:fail获取编辑收货地址失败 username 收货人姓名 telNumber 收货人电话 addressPostalCode 邮编 proviceFirstStageName 国标收货地址第一级地址 addressCitySecondStageName 国标收货地址第二级地址 addressCountiesThirdStageName 国标收货地址第三级地址 addressDetailInfo 详细收货地址信息 nationalCode 收货地址国家码 五、示例 六、完整代码 <?php /* 方倍工作室 http://www.fangbei.org/ CopyRight 2014 All Rights Reserved */ define('APPID', "wx—b7559b828e3c13e"); define('APPSECRET', "2b21b42d0c497de9a691a6bb5048a601"); class class_weixin { var $appid = APPID; var $appsecret = APPSECRET; //构造函数,获取Access Token public function __construct($appid = NULL, $appsecret = NULL) { if($appid && $appsecret){ $this->appid = $appid; $this->appsecret = $appsecret; } } //生成OAuth2的URL public function oauth2_authorize($redirect_url, $scope, $state = NULL) { $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$this->appid."&redirect_uri=".$redirect_url."&response_type=code&scope=".$scope."&state=".$state."#wechat_redirect"; return $url; } //生成OAuth2的Access Token public function oauth2_access_token($code) { $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->appsecret."&code=".$code."&grant_type=authorization_code"; $res = $this->http_request($url); return json_decode($res, true); } //生成随机字符串 function create_noncestr($length = 16) { $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; $str = ""; for ($i = 0; $i < $length; $i++ ){ $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; } //生成签名 function get_biz_sign($bizObj) { //参数小写 foreach ($bizObj as $k => $v){ $bizParameters[strtolower($k)] = $v; } //字典序排序 ksort($bizParameters); //URL键值对拼成字符串 $buff = ""; foreach ($bizParameters as $k => $v){ $buff .= $k."=".$v."&"; } //去掉最后一个多余的& $buff2 = substr($buff, 0, strlen($buff) - 1); //sha1签名 return sha1($buff2); } //HTTP请求(支持HTTP/HTTPS,支持GET/POST) protected function http_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, TRUE); $output = curl_exec($curl); curl_close($curl); return $output; } } <?php require_once('wxaddr.class.php'); $weixin = new class_weixin(); $url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; if (!isset($_GET["code"])){ $jumpurl = $weixin->oauth2_authorize($url, "snsapi_base", "fangbei"); Header("Location: $jumpurl"); }else{ $oauth2_access_token = $weixin->oauth2_access_token($_GET["code"]); $access_token = $oauth2_access_token['access_token']; } $timestamp = strval(time()); $noncestr = $weixin->create_noncestr(); $obj['appId'] = $weixin->appid; $obj['url'] = $url; $obj['timeStamp'] = $timestamp; $obj['noncestr'] = $noncestr; $obj['accesstoken'] = $access_token; $signature = $weixin->get_biz_sign($obj); ?> <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>获取共享收货地址</title> <meta name="viewport" content="width=device-width,height=device-height,inital-scale=1.0,maximum-scale=1.0,user-scalable=no;"> <script language="javascript"> function callpay() { WeixinJSBridge.invoke('editAddress',{ "appId" : "<?php echo $obj['appId'];?>", "scope" : "jsapi_address", "signType" : "sha1", "addrSign" : "<?php echo $signature;?>", "timeStamp" : "<?php echo $timestamp;?>", "nonceStr" : "<?php echo $noncestr;?>", },function(res){ alert(JSON.stringify(res)); document.form1.address1.value = res.proviceFirstStageName; document.form1.address2.value = res.addressCitySecondStageName; document.form1.address3.value = res.addressCountiesThirdStageName; document.form1.detail.value = res.addressDetailInfo; document.form1.national.value = res.nationalCode; document.form1.user.value = res.userName; document.form1.phone.value = res.telNumber; document.form1.postcode.value = res.addressPostalCode; document.form1.errmsg.value = res.err_msg; }); } </script> </head> <body> <form name="form1" target="_blank"> <table border="1"> <colgroup><col width="20%"><col width="80%"></colgroup> <TR><th>结果</th><th><INPUT value="" name="errmsg" id="9"></th> <TR><th>国家码</th><th><INPUT value="" name="national" id="6"></th> <TR><th>国家</th><th><INPUT value="" name="address3" id="3"></th> <TR><th>省</th><th><INPUT value="" name="address1" id="1"></th> <tr><th>市</th><th><INPUT value="" name="address2" id="2"></th> <TR><th>详细</th><th><INPUT value="" name="detail" id="4"></th> <TR><th>收货人</th><th><INPUT value="" name="user" id="7"></th> <TR><th>电话</th><th><INPUT value="" name="phone" id="5"></th> <TR><th>邮编</th><th><INPUT value="" name="postcode" id="8"></th> </table> </form> <div> <button type="button" onclick="callpay()">获取收货地址</button> </div> </body> </html>
关键字:微信公众平台 微信卡券 团购券 代金券 折扣券 礼品券(兑换券) 优惠券 导入code 核查code 修改库存 群发卡券 通过卡券货架投放卡券 创建二维码投放 核销卡券 查询卡券 微信买单 删除卡券 设置卡券失效 拉取卡券概况数据 获取免费券数据 拉取会员卡数据 朋友的券(共享券) 会员卡 会议/演出门票 景区门票 电影票 飞机票作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/p/weixin-card.html 在这篇微信公众平台开发教程中,我们将介绍如何在实现微信卡券(团购券 代金券 折扣券 礼品券(兑换券) 优惠券 会员卡 特殊票类)的功能。 本文分为以下二个部分: 创建卡券 卡券投放 核销卡券 管理卡券 朋友的券(共享券) 会员卡 特殊票类 本文PHP SDK源代码下载为收费服务,感谢理解与支持! 一、创建卡券 1.1 上传卡券LOGO 开发者需调用该接口上传商户图标至微信服务器,获取相应logo_url,用于卡券创建。 接口调用请求说明 https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN 参数说明 参数 是否必须 说明 buffer 是 文件的数据流 access_token 是 调用接口凭证 请求数据 // $result = $weixin->upload_image("fangbei.jpg"); 返回数据 array(1) { ["url"]=> string(119) "http://mmbiz.qpic.cn/mmbiz/K4LBh6RUO0qAa2sbY1EyJGDZ0eCetML4quMDRsiczNX98UPE6ryGM7ynjWCX1kibM5iaOLV5ibXHRhs8kdNoAthSjw/0" } 1.2 获取卡券适用门店、 商户可以通过该接口,批量查询自己名下的门店list,并获取已审核通过的poi_id(所有状态均会返回poi_id,但该poi_id不一定为最终id)、商户自身sid 用于对应、商户名、分店名、地址字段。 接口调用请求说明 协议 https http请求方式 POST 请求Url https://api.weixin.qq.com/cgi-bin/poi/getpoilist?access_token=TOKEN POST数据格式 json 请求参数说明 参数 说明 是否必填 access_token 调用接口凭证 是 buffer json数据 是 POST数据示例 { "begin":0, "limit":10 } //1.3 选取卡券背景颜色 {"errcode":0,"errmsg":"ok","colors":[{"name":"Color010","value":"#63b359"},{"name":"Color020","value":"#2c9f67"},{"name":"Color030","value":"#509fc9"},{"name":"Color040","value":"#5885cf"},{"name":"Color050","value":"#9062c0"},{"name":"Color060","value":"#d09a45"},{"name":"Color070","value":"#e4b138"},{"name":"Color080","value":"#ee903c"},{"name":"Color081","value":"#f08500"},{"name":"Color082","value":"#a9d92d"},{"name":"Color090","value":"#dd6549"},{"name":"Color100","value":"#cc463d"},{"name":"Color101","value":"#cf3e36"},{"name":"Color102","value":"#5E6671"}]} 1.4 创建卡券 1.4.1 团购券 1.4.2 代金券 1.4.3 折扣券 1.4.4 礼品券(兑换券) 1.4.5 优惠券 2 卡券投放 2.1 导入code接口 2.2 核查code接口 2.3 修改库存接口 2.3.1 群发卡券 2.3.2 通过卡券货架投放卡券 2.3.3 创建二维码投放 3. 核销卡券 3.1 查询Code接口 3.2 核销Code接口 4. 管理卡券4.1 批量查询卡券4.2 查询卡券详情4.3 获取用户已领取卡券4.4 设置微信买单接口4.5 删除卡券4.6 设置卡券失效4.7 拉取卡券概况数据接口4.8 获取免费券数据接口4.9 拉取会员卡数据接口 5 朋友的券(共享券) 6 会员卡6.1 创建会员卡 6.2 会员卡激活6.3 设置开卡字段接口 6.4 拉取会员信息接口 7 特殊票类7.1 会议/演出门票7.1.1 创建会议/演出门票 7.1.2 更新会议门票 7.2 景区门票7.2.1 创建景区门票 7.3 电影票7.3.1 创建电影票7.3.2 更新电影票 7.4 飞机票7.4.1 创建飞机票7.4.2 更新飞机票