微信支付和微信支付通知基于sdk的说明(2)
前期准备工作
微信商户账户/密码(获取appid等信息)
微信公众号账户/密码(获取cert证书等信息,不做线上退款不需要证书)
下载php支付demo
从商户平台进入的话是以下界面或者直接搜索公众号支付文档
支付类型
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1
php-demo下载
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
修改部分文件并预览index.php
解压文件,打开index.php修改
可以改成绝对路径,即你放的位置(某个域名或者某个域名下某个文件夹下)或者相对路径
http://'.$_SERVER['HTTP_HOST'].'/WxpayAPI/example/jsapi.php
更改配置(整个demo最重要的修改的地方)
说明
appId:是你的微信公众平台的appId
appsecret:是你商户平台的appsecret这两个参数可登录你的微信公众平台查看
mchId:是你的商户Id,这个是你的微信公众号开通微信支付,微信分配给你的一个商户支付ID,可登陆商户平台查看,即是你登录商户平台的账号
key:是你商户平台的支付秘钥,这个参数很关键,它是一个32位的字符串
一定要保证你以上四个参数的正确,不然出现的各种错误皆可能是这四个参数不正确造成的,当然前提是你开通微信支付并且配置正确的授权域名和支付目录
修改异步通知地址
打开example文件夹下的jsapi.php
$input->SetNotify_url("http://www.xxx.com/WxpayAPI/example/notify.php"); //设置接收微信支付异步通知回调地址
改为你自己的地址,可以写死或者相对路径获取该地址
添加异步通知地址配置
Wxpay.api.php中的unifiedOrder下单方法中需要
//异步通知url未设置,则使用配置文件中的url
if(!$inputObj->IsNotify_urlSet()){
$inputObj->SetNotify_url(WxPayConfig::NOTIFY_URL);//异步通知url
}
所以如果你没设置,则需要去WXPay.Config.php中添加一条:
const NOTIFY_URL='https://www.xxx.com/WxpayAPI/example/notify.php';
配置授权域名
因为微信支付要获取openId,它是微信支付用户的凭证
配置支付目录
上传整个文件夹到你写的支付目录下的域名下
比如你的是www.xxx.com/WxpayAPI/example/
那么你就把你整个WxpayAPI文件夹传到你的www.xxx.com域名目录下
预览index.php
确认你的商户信息
重点(坑点)
支付成功jsapi中的js就可以根据返回的信息跳转到支付成功的页面,这是接收微信同步返回的处理
function jsApiCall()
{
WeixinJSBridge.invoke(
'getBrandWCPayRequest',
<?php echo $jsApiParameters; ?>, //订单参数
function (res) {
alert(res.err_msg);
WeixinJSBridge.log(res.err_msg);
if (res.err_msg == 'get_brand_wcpay_request:ok') {
window.location.href = 'http://h.yiwang.com/index.php?r=cart/finishedorder&paymentId='+<?php echo $paymentId;?>+'&orderId='+<?php echo $orderId;?>;
}else if (res.err_msg == 'get_brand_wcpay_request:cancel') {
alert('cancel');
} else {
alert('fail');
alert(res.err_msg);
}
}
);
}
但是最终是否支付成功不能以这个为准,而是notify.php接收到的异步通知为准,这是微信异步返回的结果处理
public function NotifyProcess($data, &$msg)
{
Log::DEBUG("call back:" . json_encode($data));
$notfiyOutput = array();
if(!array_key_exists("transaction_id", $data)){
$msg = "输入参数不正确";
return false;
}
//查询订单,判断订单真实性
if(!$this->Queryorder($data["transaction_id"])){
$msg = "订单查询失败";
return false;
}
$this->UpdateOrderStatus();//自定义更改数据库支付成功状态
return true;
}
具体的更改数据库订单状态需要接收到微信异步通知的xml,然后判断是否支付成功,再进行更改
function UpdateOrderStatus() {
$string = file_get_contents("php://input");//微信返回的xml支付结果
$arr = (array) simplexml_load_string($string, 'SimpleXMLElement', LIBXML_NOCDATA);
if ($arr['result_code'] == 'SUCCESS' && $arr['return_code'] == 'SUCCESS') {
//操作数据库处理订单状态等
}
}
以上是分析的demo大致流程,接下来我说一下我遇到的坑,望各位注意:
坑一:签名错误
这是我最开始调试SDK的demo时候第一个坑
我们公司把已经使用是APP的商户Id和key给我,让我用这个,这个后台可以登录,我看到了商户id没问题,但key看不到,只有重置才可以,因为线上用着,我也没法重置,还以为代码有问题,各种输出查看。
百度好多人都让重置key,说同一个key重新提交一次也行,有人提交两三次同一个key,说就不报签名无效了。但我们没有开发环境,我不能任性重置。只能找代码的问题
最终发现还是第一步的四个配置参数有问题,appId没问题是公众号的id,我没用他们给我的appId,他们的appId应该是App开放平台的appId
商户id和秘钥,给我的是app的商户id和key,其实不是。应该是我们微信公众号申请微信支付分配的商户id和秘钥。而不是说用APP申请的商户id和秘钥。
虽然文档说的很清楚,我也知道,但领导就说和app共用一个,我也很无奈。因为开始我也不是很清楚,就觉得那就是吧,或许是demo有问题(哈哈哈)
坑二:out_trade_no的最少位数问题
微信说是32位以内,但是,如果你传1位,肯定会报错,它的提示还很弱,不是说位数不足,具体什么提示我忘了。反正位数太少会出错,我在这里也是摔了个跟头
坑三:不知道notify.php这个文件怎么接收微信支付返回结果
搜了好多资料,大部分人都只讲解了demo,说支付成功以异步通知为准,微信是通知给你设置的地址了,但问题是我怎么获取他的通知呢?
总是觉得没有返回变量,就不知道怎么输出变量,怎么处理。
$string = file_get_contents("php://input");
这就是接收到微信的通知,一个xml,详细代码上边有
坑四:jsapi.php接收不到上一个页面post或get传过来的参数
原因:在创建商户订单时,需要获取到用户的openid
//①、获取用户openid
$tools = new JsApiPay();
$openId = $tools->GetOpenid();
Wxpay.JsApiPay.php
但是在获取用户openid的过程中需要请求CODE,CODE请求函数如下:
public function GetOpenid()
{
//通过code获得openid
if (!isset($_GET['code'])){
//触发微信返回code码
$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING']);
$url = $this->__CreateOauthUrlForCode($baseUrl);
Header("Location: $url");
exit();
} else {
//获取code码,以获取openid
$code = $_GET['code'];
$openid = $this->getOpenidFromMp($code);
return $openid;
}
}
因此,在获取openid商户后台与微信系统进行多次交互,当再次回到生成商户订单页的时候,我们之前从h5页面通过$_GET或者$_POST方式获取的参数已经被清空,所以无法生成商户订单。
解决办法:
1.先将用户h5页面提交过来的参数保存到session中,然后再重定向到要生成商户订单的页面,
在生成商户订单的页面中先获取openid,再获取session
中的值(这是我百度到别人采用的方法)
2.我的办法:
在获取openid之前把post或者get的参数取到,然后传给微信(采用和他获取code的机制一样)
//①、获取用户openid
$tools = new JsApiPay();
$arr = $tools->GetOpenid($Out_trade_no,$paymentId,$Total_fee);
重写GetOpenid方法,如下:
public function GetOpenid($orderId,$paymentId,$totalFee)
{
//通过code获得openid
if (!isset($_GET['code'])){
//触发微信返回code码
$baseUrl = urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'].$_SERVER['QUERY_STRING'].'?orderId='.$orderId.'&paymentId='.$paymentId.'&totalFee='.$totalFee);
$url = $this->__CreateOauthUrlForCode($baseUrl);
Header("Location: $url");
exit();
} else {
//获取code码,以获取openid
$code = $_GET['code'];
$orderId = $_GET['orderId'];
$paymentId= $_GET['paymentId'];
$totalFee = $_GET['totalFee'];
$openid = $this->getOpenidFromMp($code);
return $arr;
}
}
金额的问题
传递的金额,微信是以分为单位,而一般是以元为单位,所以记得金额转换一下,不要传给微信小数点
还有这个金额最好在jsapi这个页面,查询一下数据库该笔订单应支付多少,而不是从提交订单页面传输过来,这样不安全,也别以为请求接口会安全,都不安全,只要存在网络传输就会出现篡改,最好是自己在本页面查询出来,然后传给微信
out_trade_no的问题
(说明这是针对我们的流程设计出次下策)
我们的提交订单会生成一个orderId和paymentId存在我们的两个表中(这两个表),然后因为要给微信传我们自己的订单id,一般来说只需要传orderId就行,但是接收到微信异步通知的支付成功以后, 我们需要根据paymenId去改我们的支付状态。
问题是从微信返回时我们没有paymentId。
用orderId去查可能会不唯一(我们数据库设计如此,会有多订单支付),另一方面是多次请求会慢,所以我采取了把订单id和paymentId拼接在一起作为传给微信,然后支付成功以后微信返回out_trade_no就是我们的orderId和paymentId
转载:https://www.jianshu.com/p/e2f756146a0e
微信支付和微信支付通知基于sdk的说明(2)的更多相关文章
- 微信支付和微信支付通知基于sdk的说明
前提是,有微信服务号(必须开通了支付功能,也就是说有了商户后台) (注意商户后台 安全目录 的设置,不然即使你写的没错误,也调用不成功) 公众号h5页面写法: (购物车提交--我们上一步已经生成了订 ...
- react-native 的微信SDK辅助包,支持微信登录、微信分享、微信支付
微信SDK集成示例,现已完成微信授权登录,之后将陆续包装分享等其他功能. ReactNative高级交流群 127482131 或访问 http://blog.1ygowu.com ReactNat ...
- 微信、企业微信和支付窗 SDK 三合一,JeeWx-api 1.2.0 版本发布
摘要: JEEWX-API 是第一款JAVA版微信极速SDK,同时集成企业微信SDK,支付窗SDK,可以快速的基于她进行微信公众号.企业微信.支付窗应用开发.基于 jeewx-api 开发可以立即拥有 ...
- 微信,支付宝,支付异步通知验签,notify_url
在支付接口开发中 ,当用户支付完成之后,阿里或者微信会向我们服务器发送一个支付结果的通知,里边带有一系列参数:其中特殊的是签名类型,和签名(他们根据这些参数做出来的签名). 我们的得到这些参数之后要去 ...
- Win10环境前后端分离项目基于Vue.js+Django+Python3实现微信(wechat)扫码支付流程(2021年最新攻略)
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_182 之前的一篇文章:mpvue1.0+python3.7+Django2.0.4实现微信小程序的支付功能,主要介绍了微信小程序内 ...
- 怎样调通微信支付及微信发货通知接口(Js API)
怎样调通微信支付及微信发货通知接口(Js API) 微信支付提供了一个支付測试页面,微信支付正式使用须要測通支付.发货通知接口 .告警接口.维权接口.告警接口.维权接口非常easy.支付界面调通也相对 ...
- 转《基于Ionic3实现微信支付和支付宝支付》
在Ionic应用里实现支付并不难,但是有的坑真是不爬不知道. 一:支付宝支付 网上关于支付宝支付cordova插件真是非常多,但是大多会报一些让你很无语的错误.比如sdk早已过时不是最新的,或者没有出 ...
- 微信支付v3接口的 官方 Java SDK
啰嗦几句:微信支付v3版接口麻烦吗?在对接微信支付v3接口时,本来是一件很简单的事情,其实微信支付v3接口并不是很复杂,但是微信团队的管理很混乱,给我们开发者带来了巨大的麻烦. 微信支付v3版接口对接 ...
- 微信小程序支付以及微信退款开发
最近公司项目急着测试,需要开发微信小程序+微信支付+微信退款,本着这几天的一些研究,决定记录一下开发的过程. 本着知识分享的原则,希望对大家有所帮助. 本篇针对的是微信小程序的支付开发,如果有对微信公 ...
随机推荐
- Aiseesoft 4K Converter for Mac如何转换视频格式?Aiseesoft 4K使用方法
Aiseesoft 4K如何转换视频格式?由于这款4K UHD转换器支持最新的4K编码/解码技术,因此您可以将4K视频转换为4K电视或其他设备支持的任何其他视频格式.Aiseesoft 4K使用方法分 ...
- 自学Java编程,如何混到一个7k薪资实习生的岗位
现在Java软件开发的专业一直都是热门,有很多专业的学生,比如电子.机械.会计.土木等等专业由于专业本身没有更高的提升空间,所以现在的年轻人更加喜欢做一些科技前沿的工作,毕竟现在接触的都是电子产品.而 ...
- 带你揭秘Shiro(二)
授权流程 1.对subject进行授权,调用方法isPermitted("permission串") 2.SecurityManager执行授权,通过ModularRealmAut ...
- Java继承之方法重写
目录 Java继承之方法重写 代码体现 概念 注意事项 "两同两小一大" 其他注意点 重写与重载 @Override注解 Java继承之方法重写 在Java继承中,子类可以获得父类 ...
- C#使用Linq to csv读取.csv文件数据2_处理含有非列名数据的方法(说明信息等)
第一篇博客为:https://www.cnblogs.com/lxhbky/p/11884474.html 本文主要是为了解决上面博客遗留的一个含有不规范数据的一种方法,目前暂时没有从包里发现可以从第 ...
- Docker Compose部署Nexus3时的docker-compose,yml代码
场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...
- Spring Bean Expression Language(EL)
1, Add dependency. <dependency> <groupId>org.springframework</groupId> <artifac ...
- iOS多线程知识梳理
iOS多线程知识梳理 线程进程基础概念 进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 线程 1个进程要想执行任务,必须得有线程(每1个 ...
- Python语法速查:目录
1. 数据类型与内置函数 2. 列表.元组.字典.集合操作 3. 字符串格式化 4. 字符串常用操作 5. 运算符.math模块.表达式 6. 循环与迭代 7. 函数基础 8. 类与对象 9. 函数进 ...
- s3c2440裸机-代码重定位、清bss的改进和位置无关码
1.代码重定位的改进 用ldr.str代替ldrb, strb加快代码重定位的速度. 前面重定位时,我们使用的是ldrb命令从的Nor Flash读取1字节数据,再用strb命令将1字节数据写到SDR ...