前期准备工作

微信商户账户/密码(获取appid等信息)
微信公众号账户/密码(获取cert证书等信息,不做线上退款不需要证书)

下载php支付demo

从商户平台进入的话是以下界面或者直接搜索公众号支付文档

支付类型

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1

 
payType.png
php-demo下载

https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1

 
php-demo.png
修改部分文件并预览index.php

解压文件,打开index.php修改
可以改成绝对路径,即你放的位置(某个域名或者某个域名下某个文件夹下)或者相对路径

http://'.$_SERVER['HTTP_HOST'].'/WxpayAPI/example/jsapi.php
 
path.png
更改配置(整个demo最重要的修改的地方)
 
config.png

说明
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,它是微信支付用户的凭证

 
auth.png
配置支付目录
 
mchId.png
上传整个文件夹到你写的支付目录下的域名下

比如你的是www.xxx.com/WxpayAPI/example/
那么你就把你整个WxpayAPI文件夹传到你的www.xxx.com域名目录下
预览index.php

 
index.png
确认你的商户信息
 
pay.png
重点(坑点)

支付成功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)的更多相关文章

  1. 微信支付和微信支付通知基于sdk的说明

    前提是,有微信服务号(必须开通了支付功能,也就是说有了商户后台) (注意商户后台 安全目录 的设置,不然即使你写的没错误,也调用不成功) 公众号h5页面写法:  (购物车提交--我们上一步已经生成了订 ...

  2. react-native 的微信SDK辅助包,支持微信登录、微信分享、微信支付

    微信SDK集成示例,现已完成微信授权登录,之后将陆续包装分享等其他功能. ReactNative高级交流群 127482131 或访问  http://blog.1ygowu.com ReactNat ...

  3. 微信、企业微信和支付窗 SDK 三合一,JeeWx-api 1.2.0 版本发布

    摘要: JEEWX-API 是第一款JAVA版微信极速SDK,同时集成企业微信SDK,支付窗SDK,可以快速的基于她进行微信公众号.企业微信.支付窗应用开发.基于 jeewx-api 开发可以立即拥有 ...

  4. 微信,支付宝,支付异步通知验签,notify_url

    在支付接口开发中 ,当用户支付完成之后,阿里或者微信会向我们服务器发送一个支付结果的通知,里边带有一系列参数:其中特殊的是签名类型,和签名(他们根据这些参数做出来的签名). 我们的得到这些参数之后要去 ...

  5. Win10环境前后端分离项目基于Vue.js+Django+Python3实现微信(wechat)扫码支付流程(2021年最新攻略)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_182 之前的一篇文章:mpvue1.0+python3.7+Django2.0.4实现微信小程序的支付功能,主要介绍了微信小程序内 ...

  6. 怎样调通微信支付及微信发货通知接口(Js API)

    怎样调通微信支付及微信发货通知接口(Js API) 微信支付提供了一个支付測试页面,微信支付正式使用须要測通支付.发货通知接口 .告警接口.维权接口.告警接口.维权接口非常easy.支付界面调通也相对 ...

  7. 转《基于Ionic3实现微信支付和支付宝支付》

    在Ionic应用里实现支付并不难,但是有的坑真是不爬不知道. 一:支付宝支付 网上关于支付宝支付cordova插件真是非常多,但是大多会报一些让你很无语的错误.比如sdk早已过时不是最新的,或者没有出 ...

  8. 微信支付v3接口的 官方 Java SDK

    啰嗦几句:微信支付v3版接口麻烦吗?在对接微信支付v3接口时,本来是一件很简单的事情,其实微信支付v3接口并不是很复杂,但是微信团队的管理很混乱,给我们开发者带来了巨大的麻烦. 微信支付v3版接口对接 ...

  9. 微信小程序支付以及微信退款开发

    最近公司项目急着测试,需要开发微信小程序+微信支付+微信退款,本着这几天的一些研究,决定记录一下开发的过程. 本着知识分享的原则,希望对大家有所帮助. 本篇针对的是微信小程序的支付开发,如果有对微信公 ...

随机推荐

  1. 最短路径之Dijsktra算法(python)

    定义: 起始位置:A 终止位置:F 持久集合:permanent = set() 暂时集合:temporary = set() 首先将起始位置A加入永久集合,并将A的距离设为0, 此时遍历A的邻接节点 ...

  2. webpack 使用style-loader,css-loader添加css样式

    // 注意:webpack 默认只能打包处理js类型的文件// 如果要处理非js类型文件,需要手动安装第三方加载器// 1安装npm install style-loader css-loader - ...

  3. JQuery之Ajax基础

    众所周知JQuery中的Ajax主要用于数据传输,其数据传输格式为JSON格式数据,比XML格式数据传输更快. ajax 是 Asynchronous JavaScript and XML的简写,aj ...

  4. bbbbbb

    Blazor 机制初探以及什么是前后端分离,还不赶紧上车? 标签: Blazor .Net 上一篇文章我发了一个 BlazAdmin 的尝鲜版,这一次主要聊聊 Blazor 是如何做到用 C# 来写前 ...

  5. MySql报错(持续更新)

    目录 MySql报错 1. 重复键报错1062- duplicate entry '0' for key 'xxx' 1.1 报错场景 1.2 报错原因 1.3 解决方法 1.4 具体举例 2. VS ...

  6. java基础学习笔记 第二周(面向对象)

    Day01 什么是抽象数据类型:将不同数据类型的集合组成的一个整体,我们称为抽象数据类型 类就是一个抽象数据类型 成员变量:类中的数据类型就是成员变量(属性) 方法:类中的一些行为就是方法 面向过程( ...

  7. right join 和left join 的区别

    SQL 数据库 right join 和left join 的区别   left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中 ...

  8. PHP 生成 UUID 函数

    Generate name based md5 UUID (version 3) /** * Generate name based md5 UUID (version 3). * @example ...

  9. JavaScript-----7.循环

    1.循环 在JS中主要有以下三种类型的循环 for循环 while循环 do...while循环 2. for循环 2.1 语法结构如下: for (初始化变量: 条件表达式: 操作表达式) { // ...

  10. 【使用篇二】配置文件application.properties参数详解(21)

    springboot提供了许多启动器starter,大部分的启动器都有配置属性,这些配置属性一般可以在这里找到: xxxxxxxx-autoconfigure-xxxxx.jar/META-INF/s ...