微信支付notify遗漏 怎么查看notify

最近微信APP支付遇到的一些坑 - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
最近微信支付莫名其妙的进行了升级,在提交的移动应用开发中微信支付,如果收到的是这样的则无法使用在开放平台的移动应用开发的。因为邮件中少了2个关键的KEY:paySignKey, partnerKey。
一直询问支持,给的都是,研究了下,都是公众号的开发。
后面找到了这份,研究了一番,依旧觉得是公众号的,里面的需要个openid,这分明是微信公众号的开发。后面看到openid只是在公众号开发的时候才传递,所以决定按照这份文档一试。
按照文档中的,当进行到第三步的时候,文档这样说:
步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为prepay_id=wx
但是我我找遍了所有地方,都没有说明这个package具体的事例,以及参加签名的字段partnerId是老文档中的描述,而且这里的字符串怎么突然有大小写了?后面参考了老文档,成功了。
3.5 添加 prepayid 再次签名
获取到 prepayid 后,将参数 appid、appkey、noncestr、package(注意:此处应置为 Sign=WXPay)、partnerid、prepayid、timestamp 签名后返回给 APP,签名方法跟 3.4 节
app_signature 说明一致。得到参数列表如下,通过这些参数即可在客户端调起支付。
“appid”:“wxd930ea5d5a258f4f”, “noncestr”:“7a773f894d”, “package”:“Sign=WXpay”;
“partnerid”:“” “prepayid”:“f”, “sign”:“7ffecb600d810d2d8f28bc2811827b”, “timestamp”:“”
总结下开发:
先按照去获取prepay_id
得到prepay_id, 参考上面的 3.5 添加 prepayid 再次签名
然后再吐槽下微信支付:新接口获取prepay_id确实方便了很多,不需要去获取token、packge,请求与接收都有JSON换成了XML。但接口更新也不正式的声明下,文档也乱写,也没用完全开放出来,坑啊!
#!/usr/bin/env python
# coding=utf-8
xml2json:https:/&#/hay/xml2json
log_debug, log_info 相当于print
from flask import current_app
from aladin.helpers import log_debug, log_info
from hashlib import md5
import requests, time, json
from xml.etree import ElementTree
from xml2json import xml2json
import optparse
class WeiXinPay():
&&&微信支付,返回回客户端需要参数
def __init__(self, order_id, body, total_fee, nonce_str, spbill_create_ip='8.8.8.8'):
:param order_id: 订单ID
:param body: 订单信息
:param total_fee: 订单金额
:param nonce_str: 32位内随机字符串
:param spbill_create_ip: 客户端请求IP地址
self.params = {
'appid': current_app.config['APPID'],
'mch_id': current_app.config['MCHID'],
'nonce_str': nonce_str,
'body': body,
'out_trade_no': str(order_id),
'total_fee': str(int(total_fee)),
'spbill_create_ip': spbill_create_ip,
'trade_type': 'APP',
'notify_url': current_app.config['WEIXIN_NOTIFY_URL']
self.url = 'https://api.mch./pay/unifiedorder' # 微信请求url
self.error = None
def key_value_url(self, value):
&&&将将键值对转为 key1=value1&key2=value2
key_az = sorted(value.keys())
pair_array = []
for k in key_az:
v = value.get(k, '').strip()
v = v.encode('utf8')
k = k.encode('utf8')
log_info('%s =& %s' % (k,v))
pair_array.append('%s=%s' % (k, v))
tmp = '&'.join(pair_array)
log_info(&key_value_url ==& %s & %tmp)
return tmp
def get_sign(self, params):
&&&生成sign
stringA = self.key_value_url(params)
stringSignTemp = stringA + '&key=' + current_app.config['APIKEY'] # APIKEY, API密钥,需要在商户后台设置
log_info(&stringSignTemp ==& %s& % stringSignTemp)
sign = (md5(stringSignTemp).hexdigest()).upper()
params['sign'] = sign
log_info(&sign ==& %s& % sign)
def get_req_xml(self):
&&&拼接XML
self.get_sign(self.params)
xml = &&xml&&
for k, v in self.params.items():
v = v.encode('utf8')
k = k.encode('utf8')
xml += '&' + k + '&' + v + '&/' + k + '&'
xml += &&/xml&&
log_info(xml)
return xml
def get_prepay_id(self):
请求获取prepay_id
xml = self.get_req_xml()
headers = {'Content-Type': 'application/xml'}
r = requests.post(self.url, data=xml, headers=headers)
log_info(r.text)
log_info(&++++++++++++++++++++++++++&)
re_xml = ElementTree.fromstring(r.text.encode('utf8'))
xml_status = re_xml.getiterator('result_code')[0].text
log_info(&result_code ==& %s& % xml_status)
if xml_status != 'SUCCESS':
self.error = u&连接微信出错啦!&
prepay_id = re_xml.getiterator('prepay_id')[0].text
self.params['prepay_id'] = prepay_id
self.params['package'] = 'Sign=WXPay'
self.params['timestamp'] = str(int(time.time()))
def re_finall(self):
&&&得到prepay_id后再次签名,返回给终端参数
self.get_prepay_id()
if self.error:
sign_again_params = {
'appid': self.params['appid'],
'noncestr': self.params['nonce_str'],
'package': self.params['package'],
'partnerid': self.params['mch_id'],
'timestamp': self.params['timestamp'],
'prepayid': self.params['prepay_id']
self.get_sign(sign_again_params)
self.params['sign'] = sign_again_params['sign']
# 移除其他不需要返回参数
for i in self.params.keys():
if i not in [
'appid', 'mch_id', 'nonce_str',
'timestamp', 'sign', 'package', 'prepay_id']:
self.params.pop(i)
return self.params
class WeiXinResponse(WeiXinPay):
微信签名验证
def __init__(self, xml):
:param xml: 支付成功回调的XML
self.xml = xml
options = optparse.Values({&pretty&: False})
self.xml_json = json.loads(xml2json(self.xml, options))['xml']
self.sign = self.xml_json.get('sign', '')
def verify(self):
&&&验证签名&&&
self.xml_json.pop('sign')
self.get_sign(self.xml_json)
if self.sign != self.xml_json['sign']:
log_info(&signValue:%s !=
sing:%s& % (self.xml_json['sign'], self.sign))
return False
return True
不过,建议用nodejs写一个版本玩玩
恩,后面打算写个coffee的。
coffee真的很好用,哇哈哈
帅哥, 里的&下载&链接好像都不能点的,你是怎么下载SDK的呢?
打电话问过腾讯了,DEMO还在写中,只有被扫支付。所以只能看文档摸着过河,和参考原来的微信开放平台的移动应用开发https://open./cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&lang=zh_CN
非常感谢,没想到你还真回了,你的信息对我挺有用。
请问nonce_str
这个随机码是不是,获取prepay_id 与 第二次签名时 。都是用同一个。
nonce_str: 32位内随机字符串, 是同一个。
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。微信支付PHP SDK
—— 公众号支付代码详解
时间: 09:48:00
&&&& 阅读:75615
&&&& 评论:
&&&& 收藏:0
标签:&&&&&&在微信支付 开发者文档页面 下载最新的 php SDK
http://mch./wiki/doc/api/jsapi.php?chapter=11_1
这里假设你已经申请完微信支付
1. 微信后台配置& 如图
我们先进行测试,所以先把测试授权目录和 测试白名单添加上。测试授权目录是你要发起微信请求的哪个文件所在的目录。
例如jsapi 发起请求一般是jsapi.php所在目录 为测试目录,测试白名单即开发人员的微信号。
正式的支付授权目录不能和测试的一样否则会报错。不填写或者填错授权目录以及测试白名单都会报错。
报错样例:
NaNsystem:access_denied
不在测试白名单
2. 配置 lib/WxPay.Config.php文件
最主要配置一下四项:
const APPID = '';
const MCHID = '';
const KEY = '';
const APPSECRET = '';
APPID 和 APPSECRET都可以在微信后台中找到。
MCHID 在申请微信支付后发来的邮件中可以找到,KEY 则根据邮件提示
去商户平台配置即可。
3. 访问起始 index.php&
首先访问 index.php 你可以看到界面
我们首先需要的是 JSAPI支付。但是看代码 index.php 最下面的链接。他默认是个demo的链接,改为我们自定义的即可
    &li style=&background-color:#FF7F24&&&a href=&&?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/jsapi.php';?&&&JSAPI支付&/a&&/li&
    &li style=&background-color:#698B22&&&a href=&&?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/micropay.php';?&&&刷卡支付&/a&&/li&
    &li style=&background-color:#8B6914&&&a href=&&?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/native.php';?&&&扫码支付&/a&&/li&
    &li style=&background-color:#CDCD00&&&a href=&&?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/orderquery.php';?&&&订单查询&/a&&/li&
    &li style=&background-color:#CD3278&&&a href=&&?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/refund.php';?&&&订单退款&/a&&/li&
    &li style=&background-color:#848484&&&a href=&&?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/refundquery.php';?&&&退款查询&/a&&/li&
    &li style=&background-color:#8EE5EE&&&a href=&&?php echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].'example/download.php';?&&&下载订单&/a&&/li&
当然你也可以直接写死为自己的访问链接。
4. JSAPI 支付
必要代码解析:
$logHandler= new CLogFileHandler(&../logs/&.date('Y-m-d').'.log');
$log = Log::Init($logHandler, 15);
调用日志类 可以通过 $log-&DEBUG(‘test‘); 打印调试信息。其实也可以直接使用 $Log::DEBUG(‘test‘); 来调试
$tools = new JsApiPay();
$openId = $tools-&GetOpenid();
主要是为了获取 openid 其中GetOpenid() 函数定义在 文件 WxPay.JsApiPay.php 文件中
public function GetOpenid()
//通过code获得openid
if (!isset($_GET['code'])){
//触发微信返回code码
$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].$_SERVER['QUERY_STRING']);
$url = $this-&__CreateOauthUrlForCode($baseUrl);
Header(&Location: $url&);
//获取code码,以获取openid
$code = $_GET['code'];
$openid = $this-&getOpenidFromMp($code);
$baseUrl 其实就是为了在跳转回来这个页面。& 可以继续跟踪函数__CreateOauthUrlForCode()& 其实就是通过微信的Auth2.0 来获取Openid
参考链接:http://mp./wiki/17/c0f37d13d5d2c37b468d75.html
这就需要你把微信的 网页授权接口也设置好。
获取到 Openid 就可以调用微信支付的统一下单接口了。回到 文件 jsapi.php 如下代码
$input = new WxPayUnifiedOrder();
$input-&SetBody(&test&);
$input-&SetAttach(&test&);
$input-&SetOut_trade_no(WxPayConfig::MCHID.date(&YmdHis&));
$input-&SetTotal_fee(&1&);
$input-&SetTime_start(date(&YmdHis&));
$input-&SetTime_expire(date(&YmdHis&, time() + 600));
$input-&SetGoods_tag(&test&);
$input-&SetNotify_url(&http://paysdk./example/notify.php&);
$input-&SetTrade_type(&JSAPI&);
$input-&SetOpenid($openId);
$order = WxPayApi::unifiedOrder($input);
echo '&font color=&#f00&&&b&统一下单支付单信息&/b&&/font&&br/&';
printf_info($order);
$jsApiParameters = $tools-&GetJsApiParameters($order);这里面的代码:
$input-&SetAttach(&test&);如果 把值改为 $input-&SetAttach(&test this is attach&);就会存在bug 后面再说,其实这个参数不是必须的干脆可以去掉。
$input-&SetNotify_url(&http://paysdk./example/notify.php&);是设置接收支付结果通知的Url 这里是默认的demo 链接我们可以设置成我们的:
$input-&SetNotify_url(dirname('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']).'/notify.php');
当然你也可以选择直接写死。
其中的函数 unifiedOrder($input) 可以到WxPay.Api.php 中文件跟踪,其实就是调用统一下单接口。
在 WxPay.Api.php 中需要更改的一处代码是:
//异步通知url未设置,则使用配置文件中的url
if(!$inputObj-&IsNotify_urlSet()){
$inputObj-&SetNotify_url(WxPayConfig::NOTIFY_URL);//异步通知url
就是当没设置 notifyUrl 的时候回去配置文件中找,但是配置文件中根本没有设置。
所以你可以选择在 配置文件WxPay.Config.php 中加上这个配置,也可以直接写一个默认的notify链接。
函数 GetJsApiParameters() 是获取jsApi支付的参数给变量 $jsApiParameters 方便在下面的Js中调用
jsapi.php 中js的代码:
function jsApiCall()
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
&?php echo $jsApiP ?&,
function(res){
WeixinJSBridge.log(res.err_msg);
alert(res.err_code+res.err_desc+res.err_msg);
function callpay()
if (typeof WeixinJSBridge == &undefined&){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
jsApiCall();
其中点击立即支付按钮调用的就是 callpay() 函数,他有会调用jsApiCall() 函数打开支付程序。
此后输入密码完成支付。
在完成支付页面点击完成会回到这个支付页面,并弹出 支付成功的提示框
这个其实就是 js函数 jsApiCall 里面的alter 弹出的对话框
其中 res.err_msg 为get_brand_wcpay_request:ok 表明前端判断的支付成功,我们可以根据这个将支付跳转到成功页面。
但是这个并不可信。确认是否支付成功还是应当 通过notify.php 处理业务逻辑。
5. 支付结果通知 notify.php
其实这个页面最主要的代码就两行
$notify = new PayNotifyCallBack();
$notify-&Handle(false);其中大部分逻辑在 Handle 函数中处理 文件 WxPay.Notify.php
final public function Handle($needSign = true)
$msg = &OK&;
//当返回false的时候,表示notify中调用NotifyCallBack回调失败获取签名校验失败,此时直接回复失败
$result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg);
if($result == false){
$this-&SetReturn_code(&FAIL&);
$this-&SetReturn_msg($msg);
$this-&ReplyNotify(false);
//该分支在成功回调到NotifyCallBack方法,处理完成之后流程
$this-&SetReturn_code(&SUCCESS&);
$this-&SetReturn_msg(&OK&);
$this-&ReplyNotify($needSign);
}主要代码:
$result = WxpayApi::notify(array($this, 'NotifyCallBack'), $msg);跟踪函数 notify 文件WxPay.Api.php
public static function notify($callback, &$msg)
//获取通知的数据
$xml = $GLOBALS['HTTP_RAW_POST_DATA'];
//如果返回成功则验证签名
$result = WxPayResults::Init($xml);
} catch (WxPayException $e){
$msg = $e-&errorMessage();
return call_user_func($callback, $result);
}通过 $GLOBALS[‘HTTP_RAW_POST_DATA‘]; 获取同志数据 然后 Init 函数验证签名等。验签成功运行代码return call_user_func($callback, $result);
即调用了一个回调函数,NotifyCallBack() 函数并传递参数 $result 在NotifyCallBack函数中会调用我们重写的NotifyProcess()函数(此函数在notify.php 中被重写)
NotifyProcess() 判断也没有问题就会 设置返回 success的xml信息
$this-&SetReturn_code(&SUCCESS&);
$this-&SetReturn_msg(&OK&);并最终调用函数 $this-&ReplyNotify($needSign);& echo success的结果
函数ReplyNotify 需要修改一处代码:
final private function ReplyNotify($needSign = true)
//如果需要签名
if($needSign == true &&
$this-&GetReturn_code($return_code) == &SUCCESS&)
$this-&SetSign();
WxpayApi::replyNotify($this-&ToXml());
$this-&GetReturn_code($return_code) == &SUCCESS&)改为
$this-&GetReturn_code() == &SUCCESS&)即可。
这样整个流程就结束了。上面提到了 传递订单参数
$input-&SetAttach(&test&);如果我设置 值为 test this is attach (其实只要有空格就会存在bug)
如图 传递的订单信息
可以看到 attach 信息正常,当然支付也是正常的没有任何问题。
但是发现总是会收到notify 通知,即意味着没有返回给微信服务器正确的结果通知。
打印服务器发来的通知数据
可以看到 attach 是 test+this+is+attach 即空格被转化为加号
打印接收到的签名和程序算出来的签名发现 签名不同,即认为接收结果异常。
所以我们要是想使用attach 这个值就不能有空格,要么干脆不使用这个参数
(等待微信修复这个bug, 也可能是我这边有哪个地方不会? - -#)
这样 微信支付的 JsApi支付就大致分析完成了。
标签:&&&&&&
我也是做PHP的,若是JSAPI&Ajax请求怎么办?/php/1200.html,里面的jsapi支付跟你讲的类似。
&&国之画&&&& &&&&chrome插件
版权所有 京ICP备号-2
迷上了代码!练习(44)
在支付接口开发中
,当用户支付完成之后,阿里或者微信会向我们服务器发送一个支付结果的通知,里边带有一系列参数;其中特殊的是签名类型,和签名(他们根据这些参数做出来的签名)。
我们的得到这些参数之后要去除签名类型和签名(他们根据这些参数做出来的签名);之后我们再用这些参数做好排序生成一个签名,与他们返回来的这个签名做比较。
支付宝SDK里边有一套验签工具,微信方面可以自行做一个验签。
1、支付宝验签文档:/lab/help_detail.htm?help_id=243094
支付宝的验签:AlipaySignature.rsaCheckV1();这个方法是支付宝sdk里自带的。alipay-sdk-java50版本的
https://docs./54/103419这个地址可以下载支付宝给出的SDK。
2、下单之后支付宝和微信都会在下单返回的数据中放置一个支付二维码内容的链接,我们可以用这个链接自行生成一个二维码供用户支付。
3、接收微信服务器发送过来的通知数据:
// 读取参数
Map&String, Object& items = HttpUtil.convertModel(request);
InputStream inputS
StringBuffer sb = new StringBuffer();
inputStream = request.getInputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(
inputStream, &UTF-8&));
while ((s = in.readLine()) != null) {
sb.append(s);
in.close();
inputStream.close();
其中的sb即是接收过来的xml数据;后续我们可以通过自己工程里的xml解析工具即可解析得到map格式的数据或者json格式的数据,以供之后的验签,存储等业务操作。
4、接收阿里返回通知的数据
Map&String, String& params = new HashMap&String, String&();
Map requestParams = request.getParameterMap();
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = &&;
for (int i = 0; i & values. i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + &,&;
// 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
// valueStr = new String(valueStr.getBytes(&ISO-8859-1&), &gbk&);
params.put(name, valueStr);
// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
// 商户订单号
String out_trade_no = new String(request.getParameter(&out_trade_no&).getBytes(&ISO-8859-1&), &UTF-8&);
可以通过这块代码得到通知的数据,转换之后的map数据在params 里边,也可以直接从request里读取数据如上的订单号。
之后我们就可以根据这些参数做验签,存储,更新等的操作了。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:27892次
排名:千里之外
原创:57篇
转载:14篇
(4)(1)(2)(2)(1)(2)(1)(6)(1)(10)(5)(13)(4)(4)(7)(7)如何调通微信支付及微信发货通知接口
如何调通微信支付及微信发货通知接口(JsAPI)微信支付提供了一个支付测试页面,微信支付正式使用需要测通支付、发货通知接口、告警接口、维权接口。告警接口、维权接口非常简单。支付界面调通也相对简单,主要是发货通知接口稍微复杂一点。调通发货通知接口需要注意以下几点:(1)微信支付文档中提到发货通知接口的PostData,这个其实不是一个fom里的一项,其实PostData的提法有点误导,理解为json串就可以了。(2)以下的写法是错误的:fomname="fom2"taget="_lank"method="post"inputtype="hidden"name="appId"value=""inputtype="hidden"name="openId"value=""inputtype="hidden"name="tansid"value=""inputtype="hidden"name="out_tade_no"value=""inputtype="hidden"name="delive_timestamp"value=""inputtype="hidden"name="delive_status"value=""inputtype="hidden"name="delive_msg"value=""inputtype="hidden"name="sign_method"value=""inputtype="hidden"name="app_signatue"value=""fom也不要写成:inputtype="hidden"name="PostData"value=""其实在支付成功的回调方法中,只需要写一行代码:jQuey.post(ul,tmpData);其中ul:"https:api.paydelivenotify?access_token=生成的token",tmpData是一个json串。tmpData的构成:
& 果果文库所有资源均来源于互联网,仅供网友学习交流,若侵犯了您的权益,请联系我们予以删除。
5129&&人浏览
18414&&人浏览
16967&&人浏览
12172&&人浏览
2111&&人浏览
10833&&人浏览
15769&&人浏览
2372&&人浏览
5273&&人浏览
7466&&人浏览
13550&&人浏览
11991&&人浏览
8767&&人浏览
3277&&人浏览
5321&&人浏览
本文标题:如何调通微信支付及微信发货通知接口 链接地址:
2013- Inc. All Rights Reserved 果果文库 版权所有 联系站长: ; 经营许可证编号:浙ICP备号}

我要回帖

更多关于 微信支付 notify 处理 的文章

更多推荐

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

点击添加站长微信