支付宝电脑网站支付及回调
官方文档:https://docs.open.alipay.com/270
支付
电脑网站支付的支付接口 alipay.trade.page.pay 调用时序图如下:
调用顺序如下:
- 商户系统请求支付宝接口 alipay.trade.page.pay,支付宝对商户请求参数进行校验,而后重新定向至用户登录页面。
- 用户确认支付后,支付宝通过 get 请求 returnUrl(商户入参传入),返回同步返回参数。
- 交易成功后,支付宝通过 post 请求 notifyUrl(商户入参传入),返回异步通知参数。
- 若由于网络等问题异步通知没有到达,商户可自行调用交易查询接口 alipay.trade.query 进行查询,根据查询接口获取交易以及支付信息(商户也可以直接调用查询接口,不需要依赖异步通知)。
注意:
- 由于同步返回的不可靠性,支付结果必须以异步通知或查询接口返回为准,不能依赖同步跳转。
- 商户系统接收到异步通知以后,必须通过验签(验证通知中的 sign 参数)来确保支付通知是由支付宝发送的。详细验签规则参考异步通知验签。
- 接收到异步通知并验签通过后,一定要检查通知内容,包括通知中的 app_id、out_trade_no、total_amount 是否与请求中的一致,并根据 trade_status 进行后续业务处理。
- 在支付宝端,partnerId 与 out_trade_no 唯一对应一笔单据,商户端保证不同次支付 out_trade_no 不可重复;若重复,支付宝会关联到原单据,基本信息一致的情况下会以原单据为准进行支付。
开放平台提供了支持主流开发语言的 SDK 接入的方式。对于页面跳转类 API,SDK 不会也无法像系统调用类 API 一样自动请求支付宝并获得结果,而是在接受 request 请求对象后,为开发者生成前台页面请求需要的完整 form 表单的 html(包含自动提交脚本),商户直接将这个表单的 String 输出到 http response 中即可。
以 JAVA 语言为例,调用统一收单下单并支付页面接口 alipay.trade.page.pay 的代码示例如下:
public void doPost(HttpServletRequest httpRequest,HttpServletResponse httpResponse) throws ServletException, IOException {AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE); //获得初始化的AlipayClientAlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的requestalipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp");alipayRequest.setNotifyUrl("http://domain.com/CallBack/notify_url.jsp");//在公共参数中设置回跳和通知地址alipayRequest.setBizContent("{" +" \"out_trade_no\":\"20150320010101001\"," +" \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +" \"total_amount\":88.88," +" \"subject\":\"Iphone6 16G\"," +" \"body\":\"Iphone6 16G\"," +" \"passback_params\":\"merchantBizType%3d3C%26merchantBizNo%3d2016010101111\"," +" \"extend_params\":{" +" \"sys_service_provider_id\":\"2088511833207846\"" +" }"+" }");//填充业务参数String form="";try {form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单} catch (AlipayApiException e) {e.printStackTrace();}httpResponse.setContentType("text/html;charset=" + CHARSET);httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面httpResponse.getWriter().flush();httpResponse.getWriter().close();
}
对异步返回结果进行验签的 JAVA 示例代码如下:
Map<String, String> paramsMap = ... //将异步通知中收到的所有参数都存放到 map 中
boolean signVerified = AlipaySignature.rsaCheckV1(paramsMap, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE) //调用SDK验证签名
if(signVerfied){// TODO 验签成功后,按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验,校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failure
}else{// TODO 验签失败则记录异常日志,并在response中返回failure.
}
以 JAVA 语言为例,调用统一收单线下交易查询接口 alipay.trade.query 的示例代码如下:
AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do","app_id","your private_key","json","GBK","alipay_public_key","RSA2");
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
request.setBizContent("{" +
" \"out_trade_no\":\"20150320010101001\"," +
" \"trade_no\":\"2014112611001004680 073956707\"" +
" }");
AlipayTradeQueryResponse response = alipayClient.execute(request);
if(response.isSuccess()){
System.out.println("调用成功");
} else {
System.out.println("调用失败");
}
(以上来自支付宝官方文档)
看完官方文档,是不是觉得特简单。其实真的特简单,所以千万放轻松!而且官方也提供了demo。
jar包只需要这一个,maven导入就可以。
<!-- 支付宝 --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>3.7.110.ALL</version></dependency>
//调用支付接口public ServerResponse pay(Integer userId,String orderNo){if(StringUtils.isBlank(orderNo)){return ServerResponse.createByError(ResponseCode.ILLEGAL_ARGUMENT.getCode(),ResponseCode.ILLEGAL_ARGUMENT.getDesc());}Order order = orderMapper.selectByOrderNoAndUserId(userId,orderNo);if(order == null){return ServerResponse.createByErrorMessage("该订单不存在");}//获得初始化的AlipayClientAlipayClient alipayClient = AlipayConfig.getAlipayClient(); //注意:仔细查看文档,这里用的是,支付宝公钥、商户私钥//设置请求参数AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request//官方文档说的是,callback是根据notifyUrl作为回调地址,但我测试的时候明明是根据returnUrl地址来的alipayRequest.setReturnUrl(AlipayConfig.NOTIFY_URL); //支付完成后返回的页面地址alipayRequest.setNotifyUrl(AlipayConfig.NOTIFY_URL); //在公共参数中设置回跳和通知地址//商户订单号,商户网站订单系统中唯一订单号,必填String out_trade_no = orderNo;//付款金额,必填 商品金额+运费+(优惠活动(可选))String total_amount = BigDecimalUtil.add(order.getPayment().doubleValue(),order.getPostage().doubleValue()).toString();//订单名称,必填String subject = "优阅网--用户的专属书房";//商品描述,可空String body = "优阅网订单";alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","+ "\"total_amount\":\""+ total_amount +"\","+ "\"subject\":\""+ subject +"\","+ "\"body\":\""+ body +"\","+ "\"timeout_express\":\"180m\"," //超时时间,3分钟+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");String form="";try {form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单} catch (AlipayApiException e) {e.printStackTrace();}return ServerResponse.createBySucess(form);}public ServerResponse callBack(HttpServletRequest request){//获取支付宝POST过来反馈信息Map<String,String> params = new HashMap<String,String>();Map<String,String[]> requestParams = request.getParameterMap();for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {String name = (String) iter.next();String[] values = (String[]) requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i]: valueStr + values[i] + ",";}params.put(name, valueStr);}logger.info("支付宝回调,sign:{},trade_status:{},参数:{}",params.get("sign"),params.get("trade_status"),params.toString());//验签//验证回调的正确性,是不是支付宝发的.并且要避免重复通知.params.remove("sign_type"); //remove这里看源码会发现,移不移除都没什么差,验签时会自动移除try{boolean signVerified = AlipaySignature.rsaCheckV2(params, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, AlipayConfig.SIGN_TYPE); //调用SDK验证签名if(signVerified) {//验证成功//商户订单号String out_trade_no = params.get("out_trade_no");//支付宝交易号String trade_no = params.get("trade_no");//新版支付接口回调不返回trade_status,调用交易查询接口return this.selectTradeStatus(out_trade_no,trade_no);}else {//验证失败return ServerResponse.createByErrorMessage("非法请求,验证不通过!");}}catch (AlipayApiException e){logger.error("支付宝回调异常",e);}return ServerResponse.createByError();}/*** 交易状态,新版支付接口回调不返回trade_status* @param out_trade_no* @param trade_no* @return*/public ServerResponse selectTradeStatus(String out_trade_no,String trade_no){try {AlipayClient alipayClient = AlipayConfig.getAlipayClient();AlipayTradeQueryRequest tradeQueryRequest = new AlipayTradeQueryRequest();tradeQueryRequest.setBizContent("{" +" \"out_trade_no\":\""+out_trade_no+"\"," +" \"trade_no\":\""+trade_no+"\"" +" }");AlipayTradeQueryResponse response = alipayClient.execute(tradeQueryRequest);if(response.isSuccess()){//交易状态String trade_status = response.getTradeStatus();/*** 只有交易通知状态为 TRADE_SUCCESS 或 TRADE_FINISHED 时,支付宝才会认定为买家付款成功。* 注意:* 状态 TRADE_SUCCESS 的通知触发条件是商户签约的产品支持退款功能的前提下,买家付款成功;* 交易状态 TRADE_FINISHED 的通知触发条件是商户签约的产品不支持退款功能的前提下,买家付款成功;或者,商户签约的产品支持退款功能的前提下,交易已经成功并且已经超过可退款期限。*/if(trade_status.equals(Config.TradeStatus.TRADE_SUCCESS.getDesc())){//do something}else if(trade_status.equals(Config.TradeStatus.TRADE_CLOSED.getDesc())){ //交易关闭,未付款交易超时关闭,或支付完成后全额退款//do something}PayInfo payInfo = new PayInfo();payInfo.setUserId(order.getUserId());payInfo.setOrderNo(out_trade_no);payInfo.setPayPlatfrom(Config.PaymentType.ALIPAY.getCode());payInfo.setPlatfromNumber(trade_no);payInfo.setPlatfromStatus(trade_status);payInfoMapper.insert(payInfo);return ServerResponse.createBySuccess();} else {logger.error("支付宝支付错误,商户订单号:{},支付宝交易号:{}",out_trade_no,trade_no);return ServerResponse.createByErrorMessage("支付宝支付回调错误!");}}catch (AlipayApiException e){logger.error("支付宝查询订单状态异常",e);}return ServerResponse.createByError();}
注意:
1、新版支付接口不返回trade_status,想要查询交易状态,需要调用支付查询接口。
2、回调成功后需要返回“success”字符串,并且只返回“success”字符串。
public interface AliCallBack{String RESPONSE_SUCCESS = "success";String RESPONSE_FAILED = "failed";}@RequestMapping(value = "callback")public Object AliCallBack(HttpServletRequest request){ServerResponse response = iOrderService.callBack(request);if(response.isSuccess()){return Config.AliCallBack.RESPONSE_SUCCESS;}else {return Config.AliCallBack.RESPONSE_FAILED;}}
3、
支付宝电脑网站支付及回调相关推荐
- Spring Boot集成支付宝电脑网站支付功能
Spring Boot集成支付宝电脑网站支付功能 接入准备 登录 创建应用 添加能力 生成私钥与公钥 开发设置 沙箱环境 示例Demo的使用与学习 下载Demo 启动项目 参数配置 执行测试 Spri ...
- Laravel 集成支付宝电脑网站支付
前期准备: 1.下载SDK,里面还有Demo,可以参照Demo里面的内容快速接入 支付宝电脑网站支付SDK&Demo 2.把下载的zip文件解压,放到项目目录里,这里作者放在app文件夹里,方 ...
- 支付宝开放平台开发助手_支付宝:如何创建和接入支付宝电脑网站支付-新手必备...
1.登录支付宝 1.打开支付宝官网,以"我是支付宝商家"用户登录 https://www.alipay.com/ 2.进入"产品中心",选择并申请支付类型 2. ...
- 支付宝电脑网站支付 demo 启动过程
接支付的这个需求,想了很久,看了官网总是没有头绪,依旧不知道怎么做,于是把demo下载下来跑一下,由于太菜,弄了一天. 准备工作: 支付宝开发平台登录后注册获取APPID,支付宝公钥,私钥 (http ...
- SpringBoot(二)集成支付宝 - 电脑网站支付和查询账单案例
一.简介 电脑支付常用于电商和后台管理系统的账户充值等场景. 电脑网站支付 文档 电脑网站支付流程图 项目源代码(含数据库):码云Gitee 二.集成步骤 0.创建应用.配置密钥 集成前需要先创建应用 ...
- 接入支付宝电脑网站支付实现JAVA版
简介 首先要说明的是个人感觉接入支付宝比微信简单多了,很轻松的,所以同学们不要紧张~ 当然还是老规矩啦,上来肯定的贴上官网地址,因为我这些服务天天在更新,而我的文章是教大家方法,而让你不是照葫芦画瓢 ...
- 支付宝-电脑网站支付初长成
前言 企业制定金额生成微信二维码集成完后,客户需要再集成支付宝,经过差文档及看博客终于实现出来(支付宝生成指定金额二维码,需要在"蚂蚁金服开放平台"注册账号,并且开通"电 ...
- 支付宝电脑网站支付(新版)
前言 继前面几篇文章以后,查看了常用的支付方式,发现还有电脑网站的支付方式,因此,这里稍微整理了一下,其实原理和手机网站支付差不多,只是使用沙箱测试的时候可能会遇到一点小坑. 沙箱采坑 因为在本地测试 ...
- 支付宝电脑网站支付 alipay.trade.page.pay
只涉及支付接口 其他接口没有使用 支付宝官方文档:https://docs.open.alipay.com/270/105899/ 支付接口文档 https://docs.open.alipay.co ...
最新文章
- android hal 驱动,AndroidHAL-Teseo
- python timer使用-关于定时器的两种使用方法
- mysql主从复制、基于GTID的主从、半同步
- 第14件事 分析竞争对手的方法
- Visual C++——黄维通《 Visual C++面向对象与可视化程序设计》——例题9-5
- 递归与分治——全排列问题
- 关于压缩工具 7z(7-zip) 的选项 -x(排除文件)的解读
- ArrayList去除集合中字符串的重复值
- 【前端自动化构建】之 自动化部署
- python从入门到精通-Python从入门到精通,跟着《这本书》学就够了?
- bzoj 3123 [Sdoi2013]森林
- CS224N刷题——Assignment1.3_word2vec
- oracle18c创建数据库,Oracle 18C 手工创建CDB
- unity学习之路——什么是unity(附学习路线)
- 电脑关闭所有应用的快捷键
- c语言 结构体 ppt,第8章C语言的结构体和共同体.ppt
- 吕文翰 php,自己动手打造基于 WKWebView 的混合开发框架(二)——js 向 Native 一句话传值并反射出 Swift 对象执行指定函数...
- 计算机科班出身和培训出身有什么区别?
- 【常见的编解码场景】
- ArcGIS矢量图层投影与地理坐标系转为投影坐标系——ArcMap
热门文章
- Encode Decode
- 【Flink】基于 Flink 的电商用户行为分析(二)
- 编程语言的发展历史剧。(参考https://baijiahao.baidu.com/s?id=1588675986991787716wfr=spiderfor=pc)
- 大数据与数据分析的关联,主要应用在哪些领域?
- 360工业互联网安全研究院入选2021年度AloT“独角兽”创新企业奖
- 【精彩推荐】RT-Thread操作系统μC/OS-III兼容层
- Linux/Ubuntu 下使用USBasp下载程序(Atmel AVR or AT89S52 etc)
- 测试点云反射强度的辅助脚本
- 微软输入法打带声调的拼音
- 智能仓库数字孪生好不好?工业系统厂家强荐广州华锐互动