随着移动互联网的飞速发展,线上支付成为越来越多人的支付方式之一,而微信支付由于其便捷、安全、快速等特性,逐渐成为众多用户的首选支付方式。而微信支付的开发,也成为了商家不可或缺的一项技能之一。本文将基于微信支付SDK(Software Development Kit),详细解析如何开发微信支付接口,以及注意事项和常见问题。
一、准备工作
1、注册微信支付商户号和开通微信支付功能
在开发微信支付接口之前,我们需要先注册一个微信支付商户号,并且开通微信支付功能。注册商户号,需要提供真实的企业信息和相关证件资料,审核通过后即可开通微信支付功能。
2、下载使用微信支付SDK
微信官方提供了微信支付SDK,不同语言的SDK都可以在微信开放平台上下载,我们可以选择适合自己的SDK进行下载。本文以Java语言为例,我们从官网下载微信支付Java SDK,将对其进行介绍和使用。
二、微信支付流程介绍
在开发微信支付接口之前,我们需要了解微信支付的整个流程以及各个环节的作用。
1、用户下单
用户在商户APP或网站上选择商品、填写订单信息并选择微信支付通道进行支付。
2、商户系统生成订单
商户系统根据用户选择的商品和订单信息生成一个订单号,并将其保存到数据库中。
3、调用统一下单API接口
商户系统调用微信支付的统一下单API接口,向微信支付平台发起支付申请,传入必要的参数(商品描述、商品价格、商户订单号、回调地址等),并由微信支付平台生成预支付交易单号。
4、调用获取二维码链接API接口
商户系统根据预支付交易单号调用微信支付平台的获取二维码链接API接口,获取支付二维码内容,将其转化为二维码图片展示给用户。
5、用户扫码支付
用户在微信中扫描二维码,进入微信支付界面,确认支付金额和商品信息后,输入支付密码完成支付。
6、微信支付回调
微信支付平台完成支付后,会将回调数据发送给商户系统的回调URL,商户系统根据回调数据处理订单状态,并向微信支付平台发送回调信息。
7、商户系统处理订单状态
商户系统接收到微信支付平台的回调信息后,处理订单状态,标记订单为已支付,并发送邮件或短信等通知用户支付成功。
三、微信支付接口开发
1、添加微信支付SDK到项目中
将下载好的微信支付SDK解压后,将其中的wxpay_java_sdk.jar文件放置到项目的lib目录下,并将其添加到项目的classpath中。
2、定义配置文件
微信支付SDK提供了对应的配置文件,以方便开发者配置各项参数。在项目中新建一个pay.properties文件,在其中定义以下属性:
```java
# 基本配置
appId=yourAppId
mchId=yourMchId
apiKey=yourApiKey
signType=MD5
# 统一下单接口url
unifiedOrderUrl=https://api.mch.weixin.qq.com/pay/unifiedorder
```
其中appId、mchId和apiKey分别为微信支付商户的应用ID、商户号和API密钥,signType定义签名类型,默认为MD5,unifiedOrderUrl为统一下单API接口的URL。
3、定义支付请求对象
微信支付SDK提供了对应的请求对象,用于存放支付请求的参数。在项目中新建一个PayReqVo类,定义以下属性:
```java
private String body; // 商品描述
private String outTradeNo; // 商户订单号
private int totalFee; // 总金额,单位为分
private String spbillCreateIp; // 用户IP地址
private String notifyUrl; // 异步通知url
private String tradeType; // 交易类型
private String productId; // 商品ID
private String openid; // 用户标识
```
其中,最主要的参数有body、outTradeNo、totalFee、spbillCreateIp、notifyUrl和tradeType,分别是商品描述、商户订单号、总金额、用户IP地址、异步回调URL和交易类型,其他参数根据具体业务需要进行定义。
4、定义支付返回对象
微信支付SDK提供了对应的请求对象,用于存放支付请求的参数。在项目中新建一个PayResVo类,定义以下属性:
```java
private String returnCode; // 返回状态码
private String returnMsg; // 返回信息
private String appid; // 应用ID
private String mchId; // 商户号
private String nonceStr; // 随机字符串
private String sign; // 签名
private String resultCode; // 业务结果
private String prepayId; // 预支付交易会话标识
private String tradeType; // 交易类型
private String codeUrl; // 二维码链接
```
其中,最主要的返回参数有returnCode、returnMsg、resultCode、prepayId、tradeType和codeUrl,分别是返回状态码、返回信息、业务结果、预支付交易会话标识、交易类型和二维码链接。其他参数根据具体业务需要进行定义。
5、定义微信支付客户端
在项目中新建一个WxPayClient类,定义以下方法:
```java
public static String generateNonceStr(int length) // 生成随机字符串
public static String generateTimeStamp() // 生成时间戳
public static String generateTradeNo() // 生成商户订单号
public static String createSign(SortedMap
public static String request(String requestData, String requestUrl) // 发送请求
```
以上方法分别用于生成随机字符串、生成时间戳、生成商户订单号、生成签名和发送请求。其中,生成随机字符串和生成时间戳是微信支付接口所必需的,而生成签名和生成商户订单号则根据业务需求而定。
6、定义微信支付工具类
微信支付SDK提供了对应的工具类,用于组装请求参数,进行签名验证等。在项目中新建一个WxPayUtil类,定义下列方法:
```java
public static String buildXml(Map
public static String getRequestData(SortedMap
public static String generateSign(Map
public static boolean isSignatureValid(Map
```
其中,buildXml用于将Map数据转为xml格式,getRequestData用于将SortedMap数据转为xml格式,generateSign用于生成签名,isSignatureValid用于验证签名。
7、调用微信支付统一下单接口
在项目中,我们需要调用微信支付统一下单API接口,完成支付请求的发起。为了实现这一功能,我们需要实现以下步骤:
a、生成随机字符串和商户订单号,组装请求参数。
b、生成签名,组装请求参数。
c、将请求参数转为xml格式,发送请求并获取响应结果。
d、解析响应结果,获取预支付交易会话标识,生成二维码链接,返回支付结果。
具体代码实现,可以参考以下示例:
```java
public static PayResVo unifiedOrder(PayReqVo payReqVo) throws Exception {
// 生成随机字符串和商户订单号
String nonceStr = WxPayClient.generateNonceStr(32);
String outTradeNo = WxPayClient.generateTradeNo();
// 组装请求参数
SortedMap
params.put("appid", WxPayUtil.APP_ID);
params.put("mch_id", WxPayUtil.MCH_ID);
params.put("nonce_str", nonceStr);
params.put("body", payReqVo.getBody());
params.put("out_trade_no", outTradeNo);
params.put("total_fee", payReqVo.getTotalFee());
params.put("spbill_create_ip", payReqVo.getSpbillCreateIp());
params.put("notify_url", payReqVo.getNotifyUrl());
params.put("trade_type", WxPayUtil.TRADE_TYPE_NATIVE);
params.put("product_id", payReqVo.getProductId());
String sign = WxPayClient.createSign(params, WxPayUtil.API_KEY);
// 组装请求参数
Map
paramMap.put("appid", WxPayUtil.APP_ID);
paramMap.put("mch_id", WxPayUtil.MCH_ID);
paramMap.put("nonce_str", nonceStr);
paramMap.put("body", payReqVo.getBody());
paramMap.put("out_trade_no", outTradeNo);
paramMap.put("total_fee", String.valueOf(payReqVo.getTotalFee()));
paramMap.put("spbill_create_ip", payReqVo.getSpbillCreateIp());
paramMap.put("notify_url", payReqVo.getNotifyUrl());
paramMap.put("trade_type", WxPayUtil.TRADE_TYPE_NATIVE);
paramMap.put("product_id", payReqVo.getProductId());
paramMap.put("sign", sign);
String requestData = WxPayUtil.buildXml(paramMap);
// 发送请求并获取响应结果
String responseData = WxPayClient.request(requestData, WxPayUtil.UNIFIED_ORDER_URL);
// 解析响应结果,获取预支付交易会话标识,生成二维码链接,返回支付结果
PayResVo payResVo = new PayResVo();
Map
if ("SUCCESS".equals(responseMap.get("return_code"))) {
payResVo.setReturnCode(responseMap.get("return_code"));
payResVo.setReturnMsg(responseMap.get("return_msg"));
if ("SUCCESS".equals(responseMap.get("result_code"))) {
payResVo.setAppid(responseMap.get("appid"));
payResVo.setMchId(responseMap.get("mch_id"));
payResVo.setNonceStr(responseMap.get("nonce_str"));
payResVo.setSign(responseMap.get("sign"));
payResVo.setResultCode(responseMap.get("result_code"));
payResVo.setPrepayId(responseMap.get("prepay_id"));
payResVo.setTradeType(responseMap.get("trade_type"));
payResVo.setCodeUrl(responseMap.get("code_url"));
}
}
return payResVo;
}
```
8、生成支付二维码
在调用微信支付统一下单API接口后,我们需要生成对应的支付二维码,供用户扫描完成支付。为了实现这一功能,我们可以采用ZXing库来生成二维码。具体实现步骤如下:
a、导入zxing-core-2.2.jar文件,将其添加到项目的lib目录下,并将其添加到项目的classpath中。
b、定义生成二维码方法。
具体代码实现,可以参考以下示例:
```java
public static void generateQrCode(String codeUrl, String filePath) throws Exception {
int width = 300; // 二维码图片宽度
int height = 300; // 二维码图片高度
String format = "png"; // 二维码格式
Hashtable
hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 指定字符编码
BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE, width, height, hints);
Path path = FileSystems.getDefault().getPath(filePath);
MatrixToImageWriter.writeToPath(bitMatrix, format, path);
}
```
9、处理微信支付回调
在完成支付后,微信支付平台会将回调数据发送给商户系统的回调URL,商户系统需要及时响应请求并进行支付状态更新,以保证订单状态的正确性。
为了实现这一功能,我们需要实现以下步骤:
a、验证签名,解析并处理回调参数。
b、将处理结果封装为XML格式,发送响应请求。
c、更新订单状态,发送通知邮件或短信等。
具体代码实现,可以参考以下示例:
```java
public static String processPayNotify(HttpServletRequest request) throws Exception {
String requestData = WxPayUtil.getRequestBody(request);
// 验证签名,解析并处理回调参数
Map
if (WxPayUtil.isSignatureValid(responseMap, WxPayUtil.API_KEY)) {
// 处理支付回调,更新订单状态
// TODO 更新订单状态、发送通知邮件或短信等
// 封装回调结果并发送响应请求
Map
resultMap.put("return_code", "SUCCESS");
resultMap.put("return_msg", "OK");
return WxPayUtil.buildXml(resultMap);
} else {
Map
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", "SIGN ERROR");
return WxPayUtil.buildXml(resultMap);
}
}
```
四、注意事项和常见问题
1、支付二维码有效期
在用户扫描支付二维码后,微信支付平台会在一定时间内保留该二维码的支付有效性,具体有效期根据实际业务情况进行设置,不能过短,避免影响用户支付体验。
2、二维码自定义样式
为了提升品牌形象,商户可以根据自己的业务需求来设置支付二维码的样式和风格。
3、微信支付API调试工具
为了便于API的集成和调试,微信官方提供了微信支付API调试工具,可以方便地进行API参数填写和返回结果查看等操作。
4、微信支付接入指南
在进行微信支付接口开发之前,建议参考微信支付接入指南,了解各类API接口的使用要求和开发流程。
5、常见问题解析
在微信支付接口开发过程中,有可能会出现各种问题和异常,建议参考微信支付开发文档中的常见问题解析,以便于快速解决开发中的问题。
五、总结
本文主要介绍了如何开发微信支付接口,包括微信支付流程介绍、微信支付接口开发、注意事项和常见问题等内容。随着微信支付的不断完善和更新,我们需要不断学习和掌握其最新的技术和规范,以提高自己微信支付接口开发的能力和竞争力。