谁做过微信微信网页支付接口开发发的

27028人阅读
项目中可圈可点的技术
ASP.NET(28)
  前2天,做一个手机网页的微信支付的项目,费了好些周折,记录一下。接下来,按照开发步骤,细数一下,我遇到的那些坑。
【坑1】官方邮件中下载的demo只有PHP版本,其他版本没有给链接。可能让人误以为只有PHP版本,事实上,各种版本都有。
拿到了腾讯发给客户的,微信支付商户资料,邮件中提示:证书的详细使用方案,请查看。根据邮件的链接,定向到一个新的邮件附件,里面的内容:
  3. 使用公众号发起支付请求
  使用JS API在微信的网页中发起支付请求,详细方法见文档中有关JS API的章节。
  微信支付接口文档及demo(公众账号).zip
微信支付接口文档及demo(公众账号).zip,下载以后包含
  【微信支付】微信公众号支付接口文档V3.3.7
  公众账号支付DEMO,只有PHP版。
之前看到别人说,为什么现在很多微信公众平台项目都用PHP开发,因为腾讯官方的Demo很多只给了PHP版本,心里暗骂,怎么微信支付这么重要的东西也只给PHP版,哎,先把PHP版本跑通吧。于是在本地配置PHP环境,修改给的demo的配置参数。运行demo,看到请在微信客户端中打开链接的提示,于是把它部署到朋友服务器,在微信中去测试,结果,报一个json扩展方法不支持,于是去搜索,怎么配置这个扩展方法。到晚上12点了,睡觉了,没搞好。临睡前想的是,PHP版本就算支付走通了,更新订单状态的代码也不好搞呀,逻辑比较复杂,用PHP再写一遍很烦人,我PHP基本不会。
这里走弯路了,其实是有.net版本的demo的,无意间在公众平台的后台点击链接看到了,大喜过望,SDK下载-&,JAVA,.NET
C#,PHP,IOS,Android都有。幸福的下载.NET版。
.NET版本Demo第一处修改:default.aspx页面里面的链接路径,居然都指向到paysdk.,改成自己的路径后,还是运行报错,因为下面的坑:
【坑2】代理服务器设置,注释就可以了,lib\HttpService.cs中get和post方法里。
         //下面设置HttpWebRequest的相关属性
request = (HttpWebRequest)WebRequest.Create(url);
request.Method = &POST&;
request.Timeout = timeout * 00;//默认传过来是6秒,手动加了一分钟
//设置代理服务器
//WebProxy proxy = new WebProxy();
//定义一个网关对象
//proxy.Address = new Uri(WxPayConfig.PROXY_URL);
//网关服务器端口:端口
//request.Proxy =
【坑3】redirect_url参数错误,网页授权-&网页账号,填写域名。
因为我选择的的“JS API”支付,这种支付需要网页授权,先获取code,再拿code去获取openid和prepay_id。这个网页授权需要登录微信公众平台。点击左侧菜单“开发者中心”,在右侧“权限列表”中找到“网页账号”,点击最右侧的修改,把测试的域名写进去,注意不要加http。经过测试发现,域名必须完全匹配,设置顶级域名,程序是的二级域名都不行。
微信公众平台登陆还要微信管理员在个人微信号上授权,要等客户公司员工上班了,才授权,增加了解决问题等待的时间。
【坑4】&数据类型要和接口文档要求的完全一致。报错:ERROR&下单失败,WxPayData字段数据类型错误
项目中的订单编号是long类型,微信接口规范是string类型,报了上面的错误,改为string类型就好了。这个属于需要注意的,严格来说,不能算坑
趟过上面的几个坑,终于支付成功了。接下来,要去完成更新订单的逻辑。
ResultNotify页面更新订单的逻辑并没有按照预料的走,查看IIS的日志,微信有发请求到ResultNotify页面,状态是500内部服务器错误。网站程序的Log中并没有记录到,一步一步用Log.Debug,记录程序走的情况,发现微信订单号应该成功获取到了,并且验证签名成功,返回的XML也正常。
INFO WxPayAPI.ResultNotify: Check sign success
DEBUG WxPayApi: OrderQuery response : &xml&&return_code&&![CDATA[SUCCESS]]&&/return_code&
&return_msg&&![CDATA[OK]]&&/return_msg&
&total_fee&10&/total_fee&
于是,在关键代码处,添加了try catch,这一步早就应该做,就不用一步一步的试错了,走弯路了,异步通知页面的找出错误很麻烦,要支付一次,看响应的结果。接下来,有依次经历了以下几个异常。
&【坑5】ERROR WxPayAPI.ResultNotify: 更新订单的时候发生异常:该字符串未被识别为有效的 DateTime
&time_end&&![CDATA[17]]&&/time_end&
这一步,我直接写DateTime.Parse转换的,抛异常,后来改写为DateTime.ParseExact方法,解决问题,注意format是yyyyMMddHHmmss,不明白为什么HH也要大写,不然也报错。
DateTime payDate = notifyData.IsSet(&time_end&) ? DateTime.ParseExact(notifyData.GetValue(&time_end&).ToString(), &yyyyMMddHHmmss&, System.Globalization.CultureInfo.CurrentCulture) : DateTime.MinV
改了以后,抛出的异常是&更新订单的时候发生异常:正在中止线程在 System.Threading.Thread.AbortInternal(),这个百思不得琪姐。百度搜索一般是Response.Redirect和Server.Transfer导致线程终止,也没找到类似的问题。一行一行过代码发现以下Bug.
【坑6】微信支付的单位是分,一般网站单位是元。而且微信的total_fee不能接收小数点,不能是0.1分钱。
我的更新订单程序有一行if (orderAmount == payAmount){}一个是微信获取到的单位是分,一个是网站的,单位是元,这个坑也浪费了好久时间,一行一行过代码才发现,因为是逻辑错误。幸好有这个判断,否则钱相差100倍,天大的BUG。
这个BUG改好以后,订单状态被成功的更新了。&
微信做的比较人性化的是,设置测试目录以及微信号白名单,测试期间,只有白名单中的微信号才能支付。部署到给客户测试,测试没有问题后,部署到的时候,居然又报redirect_url参数错误,看到微信提示说,测试目录不能和正式目录一样,否则会支付失败,我测试目录是/wxpay/,正式目录是/wxpay/,难道wxpay的文件夹名称也不能一样?没道理呀,把测试目录改成其他的,还是不对。搜索了一下,恍然大悟,是【坑3】导致的。之前把网页账号的域名改为了,改为,成功支付。注意:域名要完全匹配,程序在,网页账号设置一样报redirect_url参数错误。
至此,微信支付JS API调用整个流程完成,相对于支付宝Wap支付来说,花的时间更多。
1.对于第一个坑,是否有.net版,一般各种版本都会有,如果没有及时的发现.net版,用PHP去开发,那对于我来说,工作量就更大了。应该仔细的看官方各种帮助文档,也许它藏的比较深。
其实支付接口的主要逻辑,官方都做好了,重点是配置。
这里不得不说,腾讯随邮件发送的Demo下载包含各种版本网页路径,不是更好吗?
2.仔细看接口文档,先过一遍程序,自己去找潜在的问题,有利于提升分析问题的能力,如果时间紧急,请看3。
3.如果自己确定应该没有什么问题了,而没有预期工作,那么要去找出问题。
3.1 判断是不是微信端的error,在关键位置加日志,微信的demo中,可以设置输入Log的级别,测试的时候输出debug,Info,error,正式环境可以设置只输出error,这一点很赞。
3.2 自己代码的BUG: 整段代码加try...catch,把异常信息保存到日志中去,这样能快速的找出问题。try catch不用多说了,标配。
3.3 异常容易捕获,如果是逻辑错误,需要细心的过代码。
官方demo,先跳转到example/ProductPage.aspx,这个页面主要是调用【网页授权获取用户信息】接口获取用户的openid,点击按钮的时候,跳转到JsApiPayPage.aspx页面,传递openid和total_fee支付金额过去,其中用ViewState保存openid是个槽点,web app尽量不要用ViewState和服务器控件,它们会生成臃肿的HTML,增加网络流量,影响加载速度,你要知道,手机如果是在GSM网络下访问站点,多一些文本都是压力,尽可能精简。
直接把获取openid的逻辑写到JsApiPayPage页面就好了,省的多跳转一个页面,后台代码是要验证授权,然后获取到前台JS API调用需要的参数wxJsApiParam。
public partial class JsApiPayPage : BaseOnlineSend
public static string wxJsApiParam {} //H5调起JS API参数
protected void Page_Load(object sender, EventArgs e)
(this.GetType().ToString(), &page load&);
if (!IsPostBack)
JsApiPay jsApiPay = new JsApiPay(this);
jsApiPay.GetOpenidAndAccessToken();
string openid = jsApiPay. ;
OrderDetail = this.D
//付款金额
decimal total_fee = OrderDetail.TotalOrderAmount + OrderDetail.TotalLogisticsFee + OrderDetail.OrderAmountRevise + OrderDetail.LogisticsFeeR
//检测是否给当前页面传递了相关参数
if (string.IsNullOrEmpty(openid) || total_fee &= 0)
Log.Error(this.GetType().ToString(), &This page have not get params, cannot be inited, exit...&);
//若传递了相关参数,则调统一下单接口,获得后续相关接口的入口参数
jsApiPay.total_fee = (int)(total_fee * 100);//单位是分,不能有小数
jsApiPay.orderId = this.OrderID.ToString();
jsApiPay.siteName = this.GetConfig(&SiteName&);
//JSAPI支付预处理
WxPayData unifiedOrderResult = jsApiPay.GetUnifiedOrderResult();
wxJsApiParam = jsApiPay.GetJsApiParameters();//获取H5调起JS API参数
Log.Debug(this.GetType().ToString(), &wxJsApiParam : & + wxJsApiParam);
catch(Exception ex)
Response.Write(&&span style='color:#FF0000;font-size:20px'&& + &下单失败,请返回重试& + &&/span&&);
Log.Error(this.GetType().ToString(), &下单失败,& + ex.Message +&;& +ex.StackTrace);
其中,主要需要注意的是jsApiPay.total_fee,单位是分,要和自己项目的单位进行换算一些,否则会出错。
前台,页面加载之后,直接调用微信JS api 支付,支付完成后,直接在本页面显示支付结果。如果支付失败,让人家可以点击按钮尝试重新支付。
&script type=&text/javascript&&
//调用微信JS api 支付
function jsApiCall()
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
&%=wxJsApiParam%&,//josn串
function (res)
WeixinJSBridge.log(res.err_msg);
if(res.err_msg == &get_brand_wcpay_request:ok& ) {
document.getElementById(&payFail&).style.display=&none&;
document.getElementById(&paySuccess&).style.display=&block&;
document.getElementById(&payFail&).style.display=&block&;
function callpay()
//官方代码,不贴了
callpay();
&dl class=&item_desc& id=&dlPayInfo&&
&dt class=&item_title&&&span class=&txt&&支付信息&/span&&/dt&
&dd class=&item_panel pl1&&
&span class=&title&&&%=this.OrderDetail.ProductNames %&&/span&
&dd class=&item_panel pl1&&
&span class=&title&&订单号:&/span&&span class=&selected com_c4&&&%=this.OrderID %&&/span&
&dd class=&item_select item_last&&
&div class=&title&&
&strong&应付金额: &/strong&&span class=&com_c4&&&%=OrderDetail.TotalOrderAmount + OrderDetail.TotalLogisticsFee + OrderDetail.OrderAmountRevise + OrderDetail.LogisticsFeeRevise %& 元&/span&
&dd class=&item_select& id=&paySuccess& style=&display:none&&
&div class=&title& style=&padding-left:3rem&&
&img src=&/images/onSuccess.gif& title=&支付成功& /&
&span class=&selected&&&b class=&big&&支付成功!&/b&&br /&
系统正在处理收款,订单状态可能会有1-5分钟的滞后,感谢您的耐心等待。&br /&
&a href=&/member/order/info1/&&查看订单&/a&&br /&&br /&
您还可以:&a href=&/&&继续购物&/a&&br /&&br /&
&br /&&br /&
&dd class=&item_select&id=&payFail& style=&display:none&&
&div class=&title item& style=&padding-left:2.0rem&&
&span class=&selected&&&b class=&big&&支付失败!&/b&&/span&
&div class=&btns& style=&margin-top:10px&&&a class=&com_btn_7& style=&padding:1cursor:& onclick=&callpay()&&重新支付&/a&&/div&
&div class=&title item& style=&padding-left:2.0rem&&
&span class=&selected&&
您可以查看微信交易记录。如果没有扣费,可以稍后尝试重新支付。如果已经扣费,请拨打客服电话联系我们
&br /&&br /&
如果多次重新支付还是遇到了问题,稍后您可以在登陆状态下,访问个人中心-&&a href=&/member/order/&&我的订单&/a&,为编号为&%=this.OrderID %&的订单付款,有多种支付方式供您选择
&&相关文章推荐
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:397429次
积分:4047
积分:4047
排名:第7005名
原创:102篇
评论:63条
(1)(1)(1)(2)(2)(3)(1)(5)(1)(2)(2)(1)(3)(2)(4)(2)(1)(1)(1)(1)(1)(2)(2)(2)(5)(3)(3)(4)(5)(2)(2)(6)(5)(6)(3)(7)(4)(2)(2)(3)(3)(1)(1)&>&&>&&>&&>&微信支付接口demo
微信支付接口demo
上传大小:3.07MB
最近在最微信支付对接微商城,顺便把文档发出来,供给大家分享学习,包含微信支付详细文档,java、.net、php三种语言的demo
综合评分:4.2(668位用户评分)
收藏((43))
所需积分:1
下载次数:4842
审核通过送C币
创建者:leavingchen
创建者:nliuwenpeng
课程推荐相关知识库
上传者其他资源上传者专辑
移动开发热门标签
VIP会员动态
android服务器底层网络模块的设计方法
所需积分:0
剩余积分:720
您当前C币:0
可兑换下载积分:0
兑换下载分:
兑换失败,您当前C币不够,请先充值C币
消耗C币:0
你当前的下载分为234。
微信支付接口demo
会员到期时间:
剩余下载次数:
你还不是VIP会员
开通VIP会员权限,免积分下载
你下载资源过于频繁,请输入验证码
你下载资源过于频繁,请输入验证码
您因违反CSDN下载频道规则而被锁定帐户,如有疑问,请联络:!
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:01:05 提问
请问微信支付支付成功后如何获取所谓notify的返回值
情况其实不复杂,就是有一个地方一直没搞明白。我已经按照demo构成好了xml包,顺利的换取到了prepal_id,也通过js的那个接口,顺利的能弹出输入密码的对话框,也能输入密码并且钱也到了我的账户上来,都OK。
但一直困扰我的是这个:$input-&SetNotify_url("
其他教程基本都教到掉用JS接口弹出输入框就结束了,后面附加一句,当交易成功中,通知接口会收到一份XML文档(含有transaction_id等参数),可以用GET方法获取。所谓通知接口应该就是我们事先设置好的notify_url没跑了。但这个notify_url在文档的解释是异步处理,那理论上不需要我们另外调用,我试过另行跳转,但无法GET到相关信息。
那么不主动跳转的话,这个异步动作是在什么时候执行的呢?我要如何GET到transaction_id等参数,在收到钱的同时做些别的事情呢(给买家派发短信等)?
按赞数排序
问题就在你的notify_url上
微信的异步通知地址不能携带参数 也解析不了index.php/xxxx/这种地址
比如按你设定的url它会发送到
微信就是这么逗比,这个问题也纠结了我几天orz tmd腾讯就没考虑过我们用tp之类框架的码奴么?
反正微信支付就是个神坑 表示支付宝接口好用多了= =
prepal_id几天都没有获取到,我心烦
有个连续方式吗 我也遇到这个问题了 请教下!
$xml = $GLOBALS['HTTP_RAW_POST_DATA'];把$xml写入文件,一看便知
烦。。支付没问题,但是回调怎么搞。
其他相似问题微信支付——开发体系
时间: 16:59:59
&&&& 阅读:14696
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&&&&&&&&&&有了微信支付方面的一些前期准备以及理论知识后,我们可以开始打造我们的微信支付平台了。
商户向微信公众号提供企业以及银行账户资料,商户功能审核通过后,可以获得以下账户包括财付通的商户账户,用于公众号支付
公众号身份的唯一标识。
paySignKey
公众号支付请求中用于加密的密钥Key,可验证商户唯一身份,PaySignKey对应于支付场景中的appKey值。
除了支付请求需要用到paySignKey,公众平台接口API 的权限获取所需密钥Key,在使用所有公众平台API 时,都需要先用它去换取access_token,然后再进行调用(详情参考文档API 接口部分)。
财付通商户身份的标识。
partnerKey
财付通商户权限密钥Key。
其中:appSecret、paySignKey、partnerKey是验证商户唯一性的安全标识,对于appSecret和paySignKey的区别,可以这样认为:appSecret是API使用时的登录密码,会在网络中传播的,而paySignKey是在所有支付相关数据传输时用于加密并进行身份校验的密钥,仅保留在第三方后台和微信后台,不会在网络中传播,而且paySignKey仅用于支付请求。
JS API(网页内)支付接口
根据支付场景的交互细节,来设计商户页面的逻辑
(1)用户打开商户网页选购商品,发起支付,在网页通过javascript调用getBrandWCPayRequest接口,发起微信支付请求,用户进入支付流程。
(2)用户成功支付点击完成按钮后,商户的前端会收到javascript的返回值。商户直接跳转支付成功的静态页面进行展示。
(3)商户后台收到来自微信开放平台的支付成功回调通知,标志该笔订单支付成功。
微信JS API只能在微信内置浏览器中使用,其他浏览器调用无效。js的判断方法为:
&span style=&white-space:pre&& &/span&if(typeof WeixinJSBridge === 'undefined') {
alert('微信支付必须在微信内置浏览器中使用.');
微信提供getBrandWCPayRequest接口供商户前端网页调用,调用之前微信会鉴定商户支付权限,若商户具有调起支付的权限,则将开始支付流程。接口注意:所以传入参数都是字符串类型! &&
getBrandWCPayRequest参数以及返回值定义
格式
字符串类型
商户注册具有支付权限的公众号成功后即可获得;
字符串类型,32个字节以下
商户生成,从日00:00:00至今的秒数,即当前的时间,且最终需要转换为字符串形式;
随机字符串
字符串类型,32个字节以下
商户生成的随机字符串;
订单详情扩展字符串
字符串类型,4096个字节以下
商户将订单信息组成该字符串,具体组成方案参见接口使用说明中package组包帮劣;由商户按照规范拼接后传入;
字符串类型,参数取值&SHA1&
按照文档中所示填入,目前仅支持SHA1;
字符串类型
商户将接口列表中的参数按照指定方式迚行签名,签名方式使用signType中标示的签名方式,具体签名方案参见接口使用说明中签名帮劣;由商户按照规范签名后传入;
返回值是:
get_brand_wcpay_request:ok
get_brand_wcpay_request:cancel
支付过程用户取消
get_brand_wcpay_request:fail
根据官方文档,将相关的函数和方法做了封装,代码如下:
* Description of weixinPayHelper
* @author kewin
class weixinPayHelper {
public $appId = &&;
public $appSecret = &&;
public $partnerId = &&;
public $paySignKey = &&;
public $partnerKey = &&;
public $token = &&;
public function __construct($appId, $appSecret, $partnerId, $paySignKey, $partnerKey, $token) {
$this-&appId = $appId;
$this-&appSecret = $appS
$this-&partnerId = $partnerId;
$this-&paySignKey = $paySignK
$this-&partnerKey = $partnerK
$this-&token = $
* @param type $api_url
* @return boolean
public function open_request($api_url, $data) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
$ret = curl_exec($ch);
$error = curl_errno($ch);
curl_close($ch);
if ($error) {
* 对数组排序
* @param type $para 排序前的数组
* @return type 排序后的数组
public function argsort($para) {
ksort($para);
reset($para);
* 把数组所有元素按照&参数=参数值&的模式用&字符拼接成字符串
* @param type $para
* @return type
public function createlinkstring($para) {
$args = &&;
foreach ($para as $key =& $val) {
$args .= strtolower($key) . &=& . $val . &&&;
//去掉最后一个&字符
if (strlen($args) & 0) {
$args = substr($args, 0, count($args) - 2);
//如果存在转义字符,那么去掉转义
if (get_magic_quotes_gpc()) {
$args = stripcslashes($args);
* 除去数组中的空值和签名参数
* @param type $para
* @return type
public function parafilter($para) {
$para_filter = array();
foreach ($para as $key =& $val) {
if ($key == &sign_method& || $key == &sign& || $val == &&) {
$para_filter[$key] = $para[$key];
return $para_
* 创建sign
* @param type $arr
* @return type
public function create_sign($arr) {
$para = $this-&parafilter($arr);
$_signValue = $this-&argsort($para);
$signValue_ = $_signValue . &&key=& . $this-&partnerK
$signValue = strtoupper(md5($signValue_));
return $signV
* 创建app_signature
* @param type $arr
* @return type
public function create_app_signature($arr) {
$_para = $this-&parafilter($arr);
$para = $this-&argsort($_para);
$signValue = sha1($this-&createlinkstring($para));
return $signV
* 生成jsapi支付请求json
public function create_biz_json($package){
if($this-&check_cft_parameters($package) == false) {
message(&生成package参数缺失!& . &&br&&);
$nativeObj[&appId&] = $this-&appId;
$nativeObj[&package&] = $
$nativeObj[&timeStamp&] = &&.time().&&;
$nativeObj[&nonceStr&] = $this-&create_noncestr();
$nativeObj[&paySign&] = $this-&getSign($nativeObj);
$nativeObj[&signType&] = 'SHA1';
json_encode($nativeObj);
* 获取paySign
* @param type $package
public function getSign($bizObj){
foreach ($bizObj as $k =& $v){
$bizParameters[strtolower($k)] = $v;
$bizParameters[&appkey&] = $this -& paySignK
ksort($bizParameters);
$bizString = $this-&formatBizQueryParaMap($bizParameters, false);
return sha1($bizString);
function check_cft_parameters($package){
if($package[&bank_type&] == null || $package[&body&] == null || $package[&partner&] == null ||
$package[&out_trade_no&] == null || $package[&total_fee&] == null || $package[&fee_type&] == null ||
$package[&notify_url&] == null || $package[&spbill_create_ip&] == null || $package[&input_charset&] == null
function getToken($weid) {
$url = &https://api./cgi-bin/token?grant_type=client_credential&appid=$this-&appId&secret=$this-&appSecret&;
$content = ihttp_get($url);
if (empty($content) || !is_array($content)) {
message('获取微信公众号授权失败, 请稍后重试!');
$token = @json_decode($content['content'], true);
if (empty($token) || !is_array($token)) {
message('获取微信公众号授权失败, 请稍后重试! 公众平台返回原始数据为: &br /&' . $content['meta']);
if (empty($token['access_token']) || empty($token['expires_in'])) {
message('解析微信公众号授权失败, 请稍后重试!');
$record = array();
$record['token'] = $token['access_token'];
$record['expire'] = TIMESTAMP + $token['expires_in'];
$row = array();
$row['access_token'] = iserializer($record);
pdo_update('wechats', $row, array('weid' =& $weid));
return $record['token'];
* 发货通知
* @param type $openid
* @param type $transid 交易单号
* @param type $out_trade_no 商户订单号
* @param type $deliver_status
* @param type $deliver_msg
* @return type
public function delivernotify($weid,$openid, $transid, $out_trade_no, $deliver_status = '1', $deliver_msg = 'ok') {
$post = array();
$post['appid'] = $this-&appId;
$post['appkey'] = $this-&paySignK
$post['openid'] = $
$post['transid'] = $
$post['out_trade_no'] = $out_trade_
$post['deliver_timestamp'] = time();
$post['deliver_status'] = $deliver_
$post['deliver_msg'] = $deliver_
ksort($post);
$bizString = $this -& formatBizQueryParaMap($post, false);
$post['app_signature']
= sha1($bizString);
$post['sign_method'] = &SHA1&;
$jsonmenu =
&appid& : &'.$post['appid'].'&,
&openid& : &'.$post['openid'].'&,
&transid& : &'. $post['transid'].'&,
&out_trade_no& : &'.$post['out_trade_no'].'&,
&deliver_timestamp& : &'.$post['deliver_timestamp'].'&,
&deliver_status& : $deliver_status,
&deliver_msg& : $deliver_msg,
&app_signature& : &'.$post['app_signature'].'&,
&sign_method& : &sha1&
$url = &https://api./pay/delivernotify?access_token=&.$this-&
$ret = $this-&open_request($url, $jsonmenu);
if ( in_array($ret['errcode'],array(,42001))){
$this-&token = $this-&getToken($weid);
return $this-&delivernotify($weid,$openid,$transid,$out_trade_no,$deliver_status,$deliver_msg);
* 订单查询
* @param type $out_trade_no
* @return type
public function order_query($out_trade_no) {
$post = array();
$post['appid'] = $this-&appId;
$sign = $this-&create_sign(array('out_trade_no' =& $out_trade_no, 'partner' =& $this-&partnerId));
$post['package'] = &out_trade_no=$out_trade_no&partner=& . $this-&partnerId . &&sign=$sign&;
$post['timestamp'] = time();
$post['app_signature'] = $this-&create_app_signature(array('appid' =& $this-&appId, 'appkey' =& $this-&paySignKey, 'package' =& $post['package'], 'timestamp' =& $post['timestamp']));
$post['sign_method'] = &SHA1&;
$data = json_encode($post);
$url = 'https://api./pay/orderquery?access_token=' . $this-&
$ret = $this-&open_request($url, $data);
* 构建支付请求数组
* @param type $parameter
* @return type
public function buildForm($parameter) {
$parameter['package'] = $this-&buildPackage($parameter); //生成订单package
$paySignArray = array('appid' =& $this-&appId, 'appkey' =& $this-&paySignKey, 'noncestr' =& $parameter['noncestr'], 'package' =& $parameter['package'], 'timestamp' =& $parameter['timestamp']);
$parameter['paysign'] = $this-&create_app_signature($paySignArray);
function formatBizQueryParaMap($paraMap, $urlencode){
$buff = &&;
ksort($paraMap);
foreach ($paraMap as $k =& $v){
if($urlencode){
$v = urlencode($v);
$buff .= strtolower($k) . &=& . $v . &&&;
if (strlen($buff) & 0) {
$reqPar = substr($buff, 0, strlen($buff)-1);
return $reqP
function formatQueryParaMap($paraMap, $urlencode){
$buff = &&;
ksort($paraMap);
foreach ($paraMap as $k =& $v) {
if (null != $v && &null& != $v && &sign& != $k) {
if ($urlencode) {
$v = urlencode($v);
$buff .= $k . &=& . $v . &&&;
if (strlen($buff) & 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
return $reqP
* 构建支付请求包
* @param type $parameter
* @return type
public function buildPackage($parameter) {
$filter = array('bank_type', 'body', 'attach', 'partner', 'out_trade_no', 'total_fee', 'fee_type', 'notify_url', 'spbill_create_ip', 'time_start', 'time_expire', 'transport_fee', 'product_fee', 'goods_tag', 'input_charset');
$base = array(
'bank_type' =& 'WX',
'fee_type' =& '1',
'input_charset' =& 'UTF-8',
'partner' =& $this-&partnerId,
'noncestr' =& md5(uniqid(time(), true))
$parameter = array_merge($parameter, $base);
$unSignParaString = $this-&formatQueryParaMap($parameter, false);
$paraString = $this-&formatQueryParaMap($parameter, true);
$string = $unSignParaString.&&key=& . $this-&partnerK
$sign = strtoupper(md5($string));
return $paraString . &&sign=& . $
* 从xml中获取数组 post过来的数据
* @return boolean
public function getXmlArray() {
$postStr = file_get_contents('php://input');
if ($postStr) {
$postStr = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
if (!is_object($postStr)) {
$array = json_decode(json_encode($postStr), true); //xml对象转数组
return array_change_key_case($array, CASE_LOWER); //所有键小写
* 创建随机串
* @param type $length
* @return type
public function create_noncestr($length = 16) {
$chars = &abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&;
$str = &&;
for ($i = 0; $i & $ $i++) {
$str.= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
public function trimString($value) {
if (null != $value) {
if (strlen($ret) == 0) {
有了工具类后,就可以开始我们的支付流程过程需要的函数调用了, 附上一个微信支付的demo——pay.php
* [WeEngine System] Copyright (c) 2013 WE7.CC
require '/www/web//source/bootstrap.inc.php';
include '../../source/class/weixinPayHelper.class.php';
取得公众号的一下数据$appid $secret $partnerId $paySignKey $partnerKey $token
$weixin = new weixinPayHelper($appid, $secret, $partnerId, $paySignKey, $partnerKey, $token);
$body = $_GET['title'];
$fee = $_GET['fee']*100;
$create_ip = $_W['clientip'];
$data = array(
'body' =& $body,
'spbill_create_ip' =& $create_ip,
'total_fee' =& &$fee&,
'attach' =& '120',
'notify_url' =& $_W['siteroot'] . 'notify2.php',
'out_trade_no' =& $weixin-&create_noncestr(),
$package = $weixin-&buildPackage($data);
&!DOCTYPE html&
&meta http-equiv=&Content-Type& content=&text/ charset=utf-8& /&
&meta name=&viewport& content=&width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no&&
&title&微信支付&/title&
&script type='text/javascript' src='../../resource/script/jquery-1.7.2.min.js'&&/script&
.pay_table{
border:1px solid #cad9
border-collapse:
width:100%;
font-size:15
.pay_table th{
background:#003399;
font-size:16
.pay_table td{
border:1px solid #
&script language=&javascript&&
function callpay()
if(typeof WeixinJSBridge === 'undefined') {
alert('微信支付必须在微信内置浏览器中使用.');
WeixinJSBridge.invoke('getBrandWCPayRequest',&?php echo $weixin-&create_biz_json($package);?&,function(res){
WeixinJSBridge.log(res.err_msg);
if(res.err_msg == &get_brand_wcpay_request:ok&){
//支付成功后的跳转&span style=&white-space:pre&&
&/span&window.location.href=&&;
//返回跳转到订单详情页面
window.location.href=&&;
&div style=&&&
&table class=&pay_table&&
&th&订单支付&/th&
&td&订单名称:&?php echo $_GET['title']?&&/td&
&td&支付金额:&?php echo sprintf('%.2f', $_GET['fee']);?&&span class=&muted&& 元&/span&&/td&
&button type=&button& style=&width:100%;height:40px& onclick=&callpay()&&微信支付&/button&
但此时要注意一个问题,微信的授权目录和请求路径已经固定,所以pay.php需要是请求调用的而不能是直接包含进某个功能块的,在这里我们可以跳转到支付页面,连接后面跟上需要的参数
至此,可以实现付款了。
标签:&&&&&&&&&&&&&&&
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!}

我要回帖

更多关于 微信网页支付接口开发 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信