场景
最近在做支付宝的接口对接,之前做过一个版本,但是由于申请了新的账号以前旧的的接口对接就不能使用了
所以就开始对接新的版本接口对接,在这里也记录一下让那些还没有对接的兄弟少走点弯路。
准备
先申请一个企业账户
https://memberprod.alipay.com/account/reg/enterpriseIndex.htm
创建应用
去支付宝的开放平台
https://open.alipay.com/platform/home.htm
添加应用:
https://docs.open.alipay.com/200/105310
按照这个链接的文档一步一步操作;
账号准备好之后,就可以了解相关的接口了,以(即时到账)支付接口为例。
阅读接口文档
https://docs.open.alipay.com/270/alipay.trade.page.pay/
下载SDK
https://docs.open.alipay.com/54/103419
选择java版本
将sdk集成进入项目中
sdk中有一个jar包
将这个jar包上传到私服上去。
参考这个:
http://blog.csdn.net/huchunlinnk/article/details/17789175
项目引入sdk中的关键jar包
这里的gav的写法取决于你上传私服的时候的填写
com.alipay
alipay-api
1.0.0
处理AlipayConfig对象
取消AlipayConfig配置文件中的部分常量
打开下载sdk应该可以找到
将这个类中的前几个静态常量变成非静态的,以便可以支持多个配置对象。
/* *
*类名:AlipayConfig
*功能:基础配置类
*详细:设置帐户有关信息及返回路径
*修改日期:2017-04-05
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
@Data
publicclassAlipayConfig{
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
publicString app_id ="";
// 商户私钥,您的PKCS8格式RSA2私钥
publicString merchant_private_key ="";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
publicString alipay_public_key ="";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
publicString notify_url ="";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
publicString return_url ="";
// 签名方式
publicstaticString sign_type ="RSA2";
// 字符编码格式
publicstaticString charset ="utf-8";
// 支付宝网关
publicstaticString gatewayUrl ="https://openapi.alipay.com/gateway.do";
//日志路径
publicstaticString log_path ="C:\\";
}
公众号注:文中代码看不全可左右滑动
编写请求支付的接口
后端向支付宝发起支付的请求,在这个同时需要传递必要参数,下面我们就来编写如何向支付宝发起支付。
编写conroller层
/**
* 阿里支付控制器
*
*@authorWangSen(wangsenhehe@126.com)
*@Date2017年8月16日
*/
@Controller
@RequestMapping("/alipay")
publicclassAliPayController{
@Autowired
privateAlipayViewService alipayViewService;
/**
* 跳转到去支付的jsp页面
*
*@paramorderId 订单号
*
*@parampayAccountType 支付账号类型
*
*@parammodel 模型
*
*@throwsException
*/
@RequestMapping
publicvoidgotopay(longorderId, Model model)throwsException{
alipayViewService.setGoToPayInfo(orderId, model);
}
}
编写viewService层
/**
* 阿里支付页面服务类
*
*@authorWangSen(wangsenhehe@126.com)
*@Date2017年8月16日
*/
@Service
publicclassAlipayViewService{
@Autowired
privateNewAlipayBusinessService newAlipayBusinessService;
/**
* 设置去支付信息
*
*@paramorderId 订单id
*@parammodel 模型
*@parampayAccountType 支付账号类型
*
*@return构建的字符串
*/
publicvoidsetGoToPayInfo(longorderId, Model model)throwsException{
model.addAttribute("htmlStr", newAlipayBusinessService.buildPayRequest(orderId, payPrice,"报名费","略"));
}
}
编写service层
/**
* 新的阿里支付页面服务类
*
* 阿里升级接口之后使用这个服务类
*
*@authorWangSen(wangsenhehe@126.com)
*@Date2017年8月16日
*/
@Data
publicclassNewAlipayBusinessService{
/**
* 阿里的配置文件对象
*/
privateAlipayConfig alipayConfig;
/**
* 构建支付请求
*
*@paramorderId 订单号
*@parampayPrice 付款金额
*@paramorderName 订单名称
*@parambody 商品描述
*
*@returnhtml字符串
*/
publicStringbuildPayRequest(longorderId,longpayPrice, String orderName, String body)throwsException{
//获得初始化的AlipayClient
AlipayClient alipayClient = getAlipayClient();
//设置请求参数
String bizContent = getBizContent(ConvertUtil.obj2str(orderId), AmountUtils.changeF2Y(payPrice), orderName,
body);
returnalipayClient.pageExecute(setAlipayRequestParameters(bizContent)).getBody();
}
/**
* 设置阿里支付请求参数
*
*@parambizContent 包含关键参数的json字符串
*
*@returnAlipayTradePagePayRequest对象
*/
privateAlipayTradePagePayRequestsetAlipayRequestParameters(String bizContent){
AlipayTradePagePayRequest alipayRequest =newAlipayTradePagePayRequest();
alipayRequest.setReturnUrl(alipayConfig.getReturn_url());
alipayRequest.setNotifyUrl(alipayConfig.getNotify_url());
alipayRequest.setBizContent(bizContent);
returnalipayRequest;
}
privateAlipayClientgetAlipayClient(){
AlipayClient alipayClient =newDefaultAlipayClient(AlipayConfig.gatewayUrl, alipayConfig.getApp_id(),
alipayConfig.getMerchant_private_key(),"json", AlipayConfig.charset,
alipayConfig.getAlipay_public_key(), AlipayConfig.sign_type);
returnalipayClient;
}
/**
* 获取业务的关键内容
*
*@paramout_trade_no 订单号
*@paramtotal_amount 付款金额
*@paramsubject 订单名称
*@parambody 商品描述
*
*@return拼接之后的json字符串
*/
privateStringgetBizContent(String out_trade_no, String total_amount, String subject, String body){
ExceptionUtil.checkEmpty(out_trade_no,"订单号不能为空");
ExceptionUtil.checkEmpty(total_amount,"价格不能为空");
ExceptionUtil.checkEmpty(subject,"订单名称不能为空");
ExceptionUtil.checkEmpty(body,"商品描述不能为空");
StringBuffer sb =newStringBuffer();
sb.append("{");
sb.append("\"out_trade_no\":\"").append(out_trade_no).append("\",");
sb.append("\"total_amount\":\"").append(total_amount).append("\",");
sb.append("\"subject\":\"").append(subject).append("\",");
sb.append("\"body\":\"").append(body).append("\",");
sb.append("\"product_code\":\"FAST_INSTANT_TRADE_PAY\"");
sb.append("}");
returnsb.toString();
}
}
通过xml文件配置支付对象
<?xml version="1.0" encoding="UTF-8"?>
xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd"
>
<!-- 数理化支付配置对象 -->
<!-- 阿里支付业务服务类 -->
编写jsp页面
<%@pageimport="com.we.core.common.util.DateTimeUtil"%>
<%@pagelanguage="java"contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
支付宝即时到账交易接口
${htmlStr }
测试
页面访问:
localhost:8091/alipay/gotopay.json?orderId=232323
就可以看到支付页面了;
编写支付的异步通知接口
用户支付完成之后支付宝会通过你配置的的notify_url的值进行回调,
我需要编写这个逻辑,以完成整个的支付流程。
编写controller层
/**
* 阿里支付控制器
*
*@authorWangSen(wangsenhehe@126.com)
*@Date2017年8月16日
*/
@Controller
@RequestMapping("/alipay")
publicclassAliPayController{
@Autowired
privateAlipayViewService alipayViewService;
/**
* 支付完成
*/
@Void
@NotSso
@ResponseBody
@RequestMapping
publicvoidpayFinish()throwsException{
alipayViewService.payFinish();
}
}
编写viewService层
/**
* 阿里支付页面服务类
*
*@authorWangSen(wangsenhehe@126.com)
*@Date2017年8月16日
*/
@Service
publicclassAlipayViewService{
@Autowired
privateNewAlipayBusinessService newAlipayBusinessService;
/**
* 支付完成
*
*@throwsIOException io异常
*/
publicvoidpayFinish()throwsException{
newAlipayBusinessService.payFinish();
}
}
编写处理支付完成的servie
/**
* 新的阿里支付页面服务类
*
* 阿里升级接口之后使用这个服务类
*
* @author WangSen(wangsenhehe@126.com)
* @Date 2017年8月16日
*/
@Data
publicclassNewAlipayBusinessService{
/**
* 阿里的配置文件对象
*/
privateAlipayConfig alipayConfig;
/**
* 支付完成
*
* @throws Exception 异常对象
*/
publicvoidpayFinish() throws Exception{
HttpServletRequest request = MvcUtil.getRequest();
PrintWriterout= MvcUtil.getResponse().getWriter();
//获取支付宝POST过来反馈信息
Mapparams= getParames(request);
if(!isSuccess(params)) {
fail(out);
return;
}
longorderId = getOrderId(params);
longpayPrice = getTotalFee(params);
try{
//编辑你支付完成之后的逻辑
success(out);
}catch(Exception e) {
fail(out);
}
}
/**
* 获取订单id
*
* @param params 请求参数
* @return 订单id
*/
privatelonggetOrderId(Mapparams){
String order_no =params.get("out_trade_no");
returnConvertUtil.obj2long(order_no);
}
/**
* 获取总金额
*
* @param params 请求参数
* @return 总金额
*/
privatelonggetTotalFee(Mapparams){
String total_fee =params.get("total_amount");
returnConvertUtil.obj2long(AmountUtils.changeY2F(total_fee));
}
/**
* 校验支付宝支付是否成功
*
* @param params http请求
* @return 成功即为真
* @throws AlipayApiException
*/
privatebooleanisSuccess(final Mapparams) throws AlipayApiException{
boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getAlipay_public_key(),
AlipayConfig.charset, AlipayConfig.sign_type);//调用SDK验证签名
if(!signVerified) {
returnfalse;
}
//交易状态
String trade_status =params.get("trade_status");
if(!trade_status.equals("TRADE_FINISHED") && !trade_status.equals("TRADE_SUCCESS")) {
returnfalse;
}
returntrue;
}
/**
* 成功
*
* TODO 重构方法名
* @param out 输出流
*/
privatevoidsuccess(PrintWriterout){
out.println("success");
}
/**
* 失败
*
* TODO 重构方法名
* @param out 输出流
*/
privatevoidfail(PrintWriterout){
out.println("fail");
}
/**
* 获取参数
*
* @param request HttpServletRequest对象
*
* @return 返回支付宝携带的参数
*/
privateMapgetParames(HttpServletRequest request){
Mapparams=newHashMap();
@SuppressWarnings("unchecked")
Map requestParams = request.getParameterMap();
for(Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = ConvertUtil.obj2str(iter.next());
@SuppressWarnings("cast")
String[] values = (String[]) requestParams.get(name);
String valueStr ="";
for(inti =0; i < values.length; i++) {
valueStr = (i == values.length -1) ? valueStr + values[i] : valueStr + values[i] +",";
}
//乱码解决,这段代码在出现乱码时使用
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
returnparams;
}
}
做的过程可能用到的资源
支付接口以及异步通知接口的参数详解:
https://docs.open.alipay.com/270/105902/
生成公钥私钥的步骤:
https://doc.open.alipay.com/docs/doc.htm?treeId=291&articleId=105971&docType=1
服务端的sdk:
https://docs.open.alipay.com/203/105910
即时到账新老版本接口对比:
https://docs.open.alipay.com/270/106759
扩展阅读
Spring MVC+Spring+Mybatis实现支付宝支付功能(图文详解)
来源:https://www.cnblogs.com/wangsen/p/7512391.html