微信支付
1.微信支付流程概述
2.工程搭建
3.微信支付的相关配置
4.生成支付二维码
5.查询支付订单
6.关闭订单
7.项目案例
模式一
1.商户后台根据微信的规定生成二维码,展示给用户
2.用户打开微信扫二维码,微信客户端将信息发送到微信支付系统。
3.微信支付系统收到客户端请求,发起对商户后台系统支付回调URL的调用。调用请求将带productid和用户的openid等参数,并要求商户系统返回交数据包。
4.后台收到微信支付的回调请求,根据productid生成商户系统的订单。
5.商户系统调用微信支付【统一下单api】请求下单,返回交易会话标识prepay_id
6.微信支付系统根据商户系统的请求生成预支付交易,并返回交易会话标识(prepay_id)。
7.商户后台系统得到交易会话标识prepay_id(2小时内有效)
8.商户后台系统将prepay_id返回给微信支付系统。
9.微信支付系统根据交易会话标识,发起用户端授权支付流程。
10.用户在客户端输入密码,支付授权。
11.微信支付系统验证后,扣款完成交易。
12.微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。
13.)微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。
14.未收到支付通知的情况,商户后台系统调用【查询订单API】。
15.商户确认后发货。
生成二维码规则
二维码中的内容为链接,形式为:
weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXXX&time_stamp=XXXXXX&nonce_str=XXXXX
其中XXXXX为商户需要填写的内容,商户将该链接生成二维码,如需要打印发布二维码,需要采用此格式。商户可调用第三方库生成二维码图片。参数说明如下:
表6.1 生成二维码所需参数列表
名称 | 变量名 | 类型 | 必填 | 示例值 | 描述 |
---|---|---|---|---|---|
公众账号ID | appid | String(32) | 是 | wx8888888888888888 | 微信分配的公众账号ID |
商户号 | mch_id | String(32) | 是 | 1900000109 | 微信支付分配的商户号 |
时间戳 | time_stamp | String(10) | 是 | 1414488825 | 系统当前时间,定义规则详见时间戳 |
随机字符串 | nonce_str | String(32) | 是 | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 随机字符串,不长于32位。推荐随机数生成算法 |
商品ID | product_id | String(32) | 是 | 88888 | 商户定义的商品id 或者订单号 |
签名 | sign | String(32) | 是 | C380BEC2BFD727A4B6845133519F3AD6 | 签名,详见签名生成算法 |
举例:
weixin://wxpay/bizpayurl?appid=wx2421b1c4370ec43b&mch_id=10000100&nonce_str=f6808210402125e30663234f94c87a8c&product_id=1&time_stamp=1415949957&sign=512F68131DD251DA4A45DA79CC7EFE9D
回调商户支付URL
商户提供的支付回调URL(回调地址设置)需要实现以下功能:接收用户扫码后微信支付系统发送的数据,根据接收的数据生成支付订单,调用【统一下单API】提交支付交易。
3.1 输入参数
表6.2 输入参数说明
名称 | 变量名 | 类型 | 必填 | 示例值 | 描述 |
---|---|---|---|---|---|
公众账号ID | appid | String(32) | 是 | wx8888888888888888 | 微信分配的公众账号ID |
用户标识 | openid | String(128) | 是 | o8GeHuLAsgefS_80exEr1cTqekUs | 用户在商户appid下的唯一标识 |
商户号 | mch_id | String(32) | 是 | 1900000109 | 微信支付分配的商户号 |
是否关注公众账号 | is_subscribe | String(1) | 是 | Y | 用户是否关注公众账号,仅在公众账号类型支付有效,取值范围:Y或N;Y-关注;N-未关注 |
随机字符串 | nonce_str | String(32) | 是 | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 随机字符串,不长于32位。推荐随机数生成算法 |
商品ID | product_id | String(32) | 是 | 88888 | 商户定义的商品id 或者订单号 |
签名 | sign | String(32) | 是 | C380BEC2BFD727A4B6845133519F3AD6 | 返回数据签名,签名生成算法 |
3.2 输出参数
表6.3 输出参数说明
名称 | 变量名 | 类型 | 必填 | 示例值 | 描述 |
---|---|---|---|---|---|
返回状态码 | return_code | String(16) | 是 | SUCCESS | SUCCESS/FAIL,此字段是通信标识,非交易标识,交易是否成功需要查看result_code来判断 |
返回信息 | return_msg | String(128) | 否 | 签名失败 | 返回信息,如非空,为错误原因;签名失败;具体某个参数格式校验错误. |
公众账号ID | appid | String(32) | 是 | wx8888888888888888 | 微信分配的公众账号ID |
商户号 | mch_id | String(32) | 是 | 1900000109 | 微信支付分配的商户号 |
随机字符串 | nonce_str | String(32) | 是 | 5K8264ILTKCH16CQ2502SI8ZNMTM67VS | 微信返回的随机字符串 |
预支付ID | prepay_id | String(64) | 是 | wx201410272009395522657a690389285100 | 调用统一下单接口生成的预支付ID |
业务结果 | result_code | String(16) | 是 | SUCCESS | SUCCESS/FAIL |
错误描述 | err_code_des | String(128) | 否 | 当result_code为FAIL时,商户展示给用户的错误提示 | |
签名 | sign | String(32) | 是 | C380BEC2BFD727A4B6845133519F3AD6 | 返回数据签名,签名生成算法 |
生成二维码规则
模式二
1.商户后台根据选购的商品生成订单。
2.用户确认支付后调用微信支付【统一下单api】生成预支付交易,生成二维码连接code_url
3.微信支付系统根据返回的code_url,后台将二维码展示给用户。
4.用户扫二维码,提交扫描连接,微信支付系统验证用户的有效性。返回用户需要授权
5.用户输入密码,授权,微信支付系统验证,完成支付交易。
6.返回给客户端支付结果,返回给后端商户的支付信息。
7.后台告知支付通知接收的情况。
8.后台可以查询支付情况,微信支付系统返回支付结果。
9.发货。
1.流程概述
1.1简述
- 注册公众号
- 认证公众号,300
- 提交资料申请微信支付
- 开户成功
- 在线签署协议
1.2开发文档
https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=2_1
1.appid:微信公众号或者开放平台的唯一标识
2.mch_id:商户号(配置文件 中的partner)
3.partnerkey:商户密钥
4.sign:数字签名,根据微信官方提供的密钥和一套算法加密信息。保证安全性。
1.3微信支付SDK
2.web工程
<!--微信支付-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.3</version>
</dependency>
<dependency>
<groupId>com.github.wxpay</groupId>
<artifactId>wxpay-sdk</artifactId>
<version>0.0.3</version>
</dependency>
导入代码
WXPayConstants.java
WXPayUtil.java
WXPayXmlUtil.java
编写工具类
package com.utils;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class UrlPreUtils {
private static final String ENCODING = "UTF-8";
private final static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class);
/**
* post json
* @param url
* @param json
*
* @return
*/
public static String post(String url,String json){
StringBuffer requestText = new StringBuffer();
CloseableHttpResponse response = null;
CloseableHttpClient client = null;
HttpPost httpPost = new HttpPost(url);
StringEntity entityParams = null;
try{
entityParams = new StringEntity(json,"utf-8");
httpPost.setEntity(entityParams);
httpPost.setHeader("Content-Type","type/json;charset=ISO-8859-1");
client = HttpClients.createDefault();
response = client.execute(httpPost);
byte[] x = EntityUtils.toByteArray(response.getEntity());
requestText.append(new String(x,"utf-8"));
}catch (Exception e){
logger.info("Request="+requestText.toString());
}finally{
logger.info("Request="+requestText.toString());
}
return requestText.toString();
}
/**
* 通用get方法
* @param url
* @return
*/
public static String get(String url) throws RuntimeException{
CloseableHttpClient client = HttpClients.createDefault();
String responseText = "";
CloseableHttpResponse response = null;
try{
HttpGet get = new HttpGet(url);
response = client.execute(get);
HttpEntity entity = response.getEntity();
if (entity!=null){
responseText = EntityUtils.toString(entity,ENCODING);
}
}catch (Exception e){
throw new RuntimeException(e);
}finally {
try {
if (response!=null)
response.close();
}catch (Exception e){
e.printStackTrace();
}
}
return responseText;
}
}
编写微信支付核心配置类
package com.utils;
public class ConfigConstant {
//appid
public static final String appId ="";
//商户id
public static final String mchId = "";
//密钥
public static final String key = "";
}
生成支付二维码
3.核心配置
配置文件
jdbc.url=jdbc:mysql://47.98.99.250:3306/platform_shop?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456789
jdbc.initialSize=5
jdbc.maxActive=30
jdbc.minPoolSize=2
jdbc.maxIdleTime=30000
jdbc.idleConnectionTestPeriod=100
AppSecret=c49e2c8883261ee38405a75f14f21239
AppID=wxf3e49fd014c2194c
#小程序ID
wx.appId=wxf3e49fd014c2194c
#小程序密钥
wx.secret=c49e2c8883261ee38405a75f14f21239
#商户号
wx.mchId=
#支付签名
wx.paySignKey=
#交易类型
wx.tradeType=JSAPI
#证书名称,对应不同的商户号
wx.certName=/cert/apiclient_cert.p12
#支付回调地址
wx.notifyUrl=https://www.yourdomain.com/platform-framework/api/notify
#获取code的请求地址
wx.getCode=https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=%s&state=STAT#wechat_redirect
#获取Web_access_tokenhttps的请求地址
wx.webAccessTokenhttps = https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code
#拉取用户信息的请求地址
wx.userMessage=https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN
#微信统一下单接口路径
wx.uniformorder=https://api.mch.weixin.qq.com/pay/unifiedorder
#退款地址
wx.refundUrl=https://api.mch.weixin.qq.com/secapi/pay/refund
#退款查询地址
wx.refundqueryUrl=https://api.mch.weixin.qq.com/pay/refundquery
#微信查询订单状态
wx.orderquery=https://api.mch.weixin.qq.com/pay/orderquery
4.生成二维码
google生成二维码的依赖
s&lang=zh_CN
#微信统一下单接口路径
wx.uniformorder=https://api.mch.weixin.qq.com/pay/unifiedorder
#退款地址
wx.refundUrl=https://api.mch.weixin.qq.com/secapi/pay/refund
#退款查询地址
wx.refundqueryUrl=https://api.mch.weixin.qq.com/pay/refundquery
#微信查询订单状态
wx.orderquery=https://api.mch.weixin.qq.com/pay/orderquery
``
参考视频
参考狂神的教学视屏