因项目中有用到支付宝支付,这里对java微信支付的开发流程和注意事项到做一次记录,以遍后面有需要的时候翻阅,方便回顾

接入前准备工作可自行参考支付宝官方文档配置,参考地址:https://opendocs.alipay.com/open/204/105051

支付宝支付交互流程如下图:

笔者使用的是java,应用maven依赖引入,最新版本依赖资源下载https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java,可自行查看引入

        <dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.10.192.ALL</version></dependency>

支付宝支付Java 代码

配置信息

alipay:serverUrl: https://openapi.alipay.com/gateway.doappId: ###privateKey: ######notifyUrl: ###
package com.hjy.ft.config;import com.hjy.pay.AliPayUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;import java.io.*;/*** @version 1.0* @className AliPayStartUpRunner* @description 程序启动后加载* @since 2021/5/13 16:46*/
@Component
@Order(value = 0)
public class AliPayStartUpRunner implements CommandLineRunner {/*** 服务网关*/@Value("${alipay.serverUrl}")private String serverUrl;/*** 应用id*/@Value("${alipay.appId}")private String appId;/*** 应用私钥*/@Value("${alipay.privateKey}")private String privateKey;/*** 异步通知地址*/@Value("${alipay.notifyUrl}")private String notifyUrl;@Overridepublic void run(String... args) throws Exception {AliPayUtil.appId = appId;AliPayUtil.serverUrl = serverUrl;AliPayUtil.privateKey = privateKey;AliPayUtil.notifyUrl = notifyUrl;//应用公钥证书路径AliPayUtil.certPath = aliPayPath("appCertPublicKey_2021002113644216.crt");//支付宝公钥证书路径AliPayUtil.alipayPublicCertPath = aliPayPath("alipayCertPublicKey_RSA2.crt");//支付宝根证书路径AliPayUtil.rootCertPath = aliPayPath("alipayRootCert.crt");}/*** 读取临时文件(jar)* @param fileName (文件路径)* @return 临时文件路径*/public String aliPayPath(String fileName) {String url = null;//返回读取指定资源的输入流InputStream is = this.getClass().getResourceAsStream("/alipay/"+fileName);//InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("/alipay/"+fileName);String path = System.getProperty("user.dir");//create folderString dirPath = path + File.separator + "uploadAlipayFiles";File dir = new File(dirPath);dir.mkdirs();//create fileString filePath = dirPath + File.separator + fileName;File file = new File(filePath);//判断文件是否存在if (!file.exists()) {try {file.createNewFile();//文件不存,创建流输入数据到新文件inputStreamToFile(is, file);} catch (IOException e) {e.printStackTrace();}url = filePath;}else{url = filePath;}return url;}public void inputStreamToFile(InputStream ins, File file) {OutputStream os = null;try {os = new FileOutputStream(file);int bytesRead = 0;byte[] buffer = new byte[1024];while ((bytesRead = ins.read(buffer, 0, 1024)) != -1) {os.write(buffer, 0, bytesRead);}os.close();ins.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}
}

生成支付宝订单:

/*** 生成支付宝订单信息* @return 订单信息* @throws AlipayApiException*/@Overridepublic String alipayRecharge(AliPayModel aliPayModel) throws Exception {//初始化配置信息AlipayClient alipayClient = initAlipay();//生成订单号Long orderNumber = 0L;//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.payAlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();model.setBody(aliPayModel.getBody());model.setSubject(aliPayModel.getSubject());model.setOutTradeNo(String.valueOf(orderNumber));model.setTimeoutExpress(AliPayUtil.TIMEOUTEXPRESS);model.setTotalAmount(aliPayModel.getTotalAmount());model.setProductCode(AliPayUtil.PRODUCT_CODE);request.setBizModel(model);//异步通知地址request.setNotifyUrl(AliPayUtil.notifyUrl);try  {//业务处理//dosomething//这里和普通的接口调用不同,使用的是sdkExecuteAlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);return response.getBody(); //就是orderString 可以直接给客户端请求,无需再做处理。}catch(AlipayApiException e) {logger.error("生成支付订单错误:",e);return null;}}
    //配置信息public AlipayClient initAlipay() throws AlipayApiException {//构造clientCertAlipayRequest certAlipayRequest = new CertAlipayRequest();//设置网关地址certAlipayRequest.setServerUrl(AliPayUtil.serverUrl);//设置应用IdcertAlipayRequest.setAppId(AliPayUtil.appId);//设置应用私钥certAlipayRequest.setPrivateKey(AliPayUtil.privateKey);//设置请求格式,固定值jsoncertAlipayRequest.setFormat(AliPayUtil.FORMAT);//设置字符集certAlipayRequest.setCharset(AliPayUtil.CHARSET);//设置签名类型certAlipayRequest.setSignType(AliPayUtil.SIGN_TYPE);//设置应用公钥证书路径certAlipayRequest.setCertPath(AliPayUtil.certPath);//设置支付宝公钥证书路径certAlipayRequest.setAlipayPublicCertPath(AliPayUtil.alipayPublicCertPath);//设置支付宝根证书路径certAlipayRequest.setRootCertPath(AliPayUtil.rootCertPath);//构造clientAlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);return alipayClient;}

支付宝回调

    /*** 支付宝 - 回调接口* @param request 请求* @return 验签状态*/@Overridepublic String alipayCallbackNotify(HttpServletRequest request) {// 将异步通知中收到的待验证所有参数都存放到map中Map<String, String> params = AliPayUtil.convertRequestParamsToMapWith(request);String paramsJson = JSON.toJSONString(params);logger.info("支付宝回调,{}", paramsJson);try {// 调用SDK验证签名boolean signVerified = AlipaySignature.rsaCertCheckV1(params, AliPayUtil.alipayPublicCertPath,AliPayUtil.CHARSET, AliPayUtil.SIGN_TYPE);if (signVerified) {// 按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success,校验失败返回failurethis.check(params);String tradeStatus = params.get("trade_status");String outTradeNo = params.get("out_trade_no");//通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功if(tradeStatus.equals(AliPayUtil.TRADE_SUCCESS) || tradeStatus.equals(AliPayUtil.TRADE_FINISHED)){//业务逻辑处理//do something}return "success";} else {logger.info("支付宝回调签名认证失败,signVerified=false, paramsJson:{}", paramsJson);return "failure";}} catch (AlipayApiException e) {logger.error("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}", paramsJson, e.getMessage());return "failure";}}
    /*** request 转 map* @param request* @return*/public static Map<String,String> convertRequestParamsToMapWith(HttpServletRequest request){Map<String,String> params = new HashMap <String,String >();Map requestParams = request.getParameterMap();for(Iterator 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 ]  +   "," ;}//乱码解决,这段代码在出现乱码时使用。//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");params . put ( name ,  valueStr );}return params;}
    /*** 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,* 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),* 3、校验通知中的seller_id(或者seller_email)是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email),* 4、验证app_id是否为该商户本身。上述1、2、3、4有任何一个验证不通过,则表明本次通知是异常通知,务必忽略。* 在上述验证通过后商户必须根据支付宝不同类型的业务通知,正确的进行不同的业务处理,并且过滤重复的通知结果数据。* 在支付宝的业务通知中,只有交易通知状态为TRADE_SUCCESS或TRADE_FINISHED时,支付宝才会认定为买家付款成功。** @param params 支付宝回调参数* @throws AlipayApiException*/private void check(Map<String, String> params) throws AlipayApiException {//订单号String outTradeNo = params.get("out_trade_no");//商户订单实际金额String totalAmount = params.get("total_amount");//APPIdString appId = params.get("app_id");//验证订单号UserRechargeRecord userRechargeRecord = checkOutTradeNo(outTradeNo);if(userRechargeRecord == null){throw new AlipayApiException("out_trade_no错误");}//验证订单实际金额if(userRechargeRecord != null && !totalAmount.equals(userRechargeRecord.getPayAmount().toString())){throw new AlipayApiException("支付金额不一致");}//验证app_id是否为商户本身if(!appId.equals(AliPayUtil.appId)){throw new AlipayApiException("app_id不一致");}}

同步验签

     /*** 客户端同步验签* @param request* @return true:验证成功,false:验证失败* @throws AlipayApiException*/@Overridepublic Boolean getVerifySignResult(HttpServletRequest request) throws AlipayApiException {Map<String, String> params = AliPayUtil.convertRequestParamsToMapWith(request);String paramsJson = JSON.toJSONString(params);logger.info("支付宝回调,{}", paramsJson);boolean signVerified = AlipaySignature.rsaCertCheckV1(params, AliPayUtil.alipayPublicCertPath,AliPayUtil.CHARSET,AliPayUtil.SIGN_TYPE);return signVerified;}

需要注意的是,params参数一定要严格按照支付宝提供的参数顺序,不然会一直验签错误,返回false

支付宝订单查询

    /*** 获取支付宝交易订单* @param outTradeNo 商户订单号* @param tradeNo 支付宝交易号* @return 支付结果*/@Overridepublic String getAlipayOutTradeNo(Long outTradeNo, Long tradeNo) throws AlipayApiException {//初始化支付宝配置AlipayClient alipayClient = initAlipay();AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();AlipayTradeQueryModel model = new AlipayTradeQueryModel();model.setOutTradeNo(outTradeNo.toString());if(tradeNo != null){model.setTradeNo(tradeNo.toString());}request.setBizModel(model);AlipayTradeQueryResponse response = alipayClient.certificateExecute(request);return response.getBody();}

其他接口可自行到支付宝官方Api接口查阅

java APP支付宝支付相关推荐

  1. java对接支付宝支付

    java对接支付宝支付演示 现在有不少的项目都需要对接支付,这里主要是进行讲解对接支付宝H5支付 废话不多说 上代码 引入支付宝官方的sdk <!-- https://mvnrepository ...

  2. 【超详细,全流程】java对接支付宝支付

    支付流程 一.对接前的准备 1.1创建应用,获取参数:APPID(使用沙箱环境可跳过) 1.1.1添加产品 1.1.2配置密钥,获取第二个参数:商户的私钥 1.1.3支付宝网关 1.1.4生成参数密钥 ...

  3. 【APP支付】关于APP支付宝支付那些事

    昨天整理了关于APP微信支付的东西,今天在整理代码之后,来谈谈支付宝的APP支付. 两者有很大相似之处,也有区别,只要理解了一个,另一个就很好理解了,如果是第一次做服务端的支付的话,建议先看看上面那篇 ...

  4. JAVA对接支付宝支付(超详细,一看就懂)

    Java对接支付宝支付 更多内容 冷文博客: 传送门 引入 为什么要发这篇帖子呢?原因很简单,就是因为在一个稍稍正规一点的应用上都会有支付这个环节,我们日常的在线支付如今包括支付宝,微信钱包,QQ钱包 ...

  5. Java接入支付宝支付测试买iPhone13 pro max

    Java接入支付宝支付 一.介绍 二.沙箱 三.支付流程 四.准备支付宝 五.代码 1.前端代码 2.后端代码 六.测试 一.介绍 支付宝官方网站 支付宝(中国)网络技术有限公司是国内的第三方支付平台 ...

  6. node egg APP支付宝支付

    1.首先安装 npm包 npm install alipay-sdk 2.使用 const AlipaySdk = require('alipay-sdk').default const aliUti ...

  7. Java接入支付宝支付超级详细教程——从入门到精通

    ​ Java接入支付宝支付教程 源码下载 源码获取:点击获取源码 本文介绍了"二维码付款"的代码.其他支付方式的代码都在源码中. 一.创建应用 1.登录支付宝开放平台 支付宝开放平 ...

  8. Java接入支付宝支付教程

    Java接入支付宝支付教程 一.创建应用 1.登录支付宝开放平台 支付宝开放平台网址:https://open.alipay.com/platform/developerIndex.htm 2.创建一 ...

  9. app支付宝支付java后台_支付宝app支付java后台流程demo

    支付宝app支付java后台流程demo 使用ssm框架实现支付宝支付功能. 支付宝测试环境代码测试 源代码 https://github.com/OUYANGSIHAI/sihai-maven-ss ...

  10. JAVA集成支付宝支付 周期扣费 (证书方式)

    依赖 <!-- <dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-s ...

最新文章

  1. 最新:2022校友会中国大学排名发布!
  2. Flutter开发之ListView下拉刷新上拉加载更多(35)
  3. uva 610(割边)
  4. 最详细的phpmailer的使用方法
  5. CentOS7安装Docker详细教程
  6. 【LeetCode-SQL每日一练】—— 627. 变更性别
  7. ClickHouse入门
  8. Echart 地图实例
  9. dmv io读写高的sql_使用内置的动态管理视图(DMV)发现更多SQL Server信息
  10. 浅析微信支付:1前篇大纲
  11. vue 父子之间通信及非父子之间通信
  12. 四川大学计算机学院 学术委员会,学术委员会完整列表
  13. linux搭建虚拟ftp,linux下搭建ftp服务器(虚拟用户)
  14. 添加最顶层js广告_js实现网站最上边可关闭的浮动广告条代码
  15. 多元线性回归矩阵求导
  16. 单日复利,单月复利计算java实现
  17. Rust websocket 客户端实现
  18. 又一视频下载神器,一键下载b站收藏夹视频和up主所有视频
  19. post模拟传数据的几种方法
  20. ArcGis之椭球面积计算工具

热门文章

  1. hdu6184 判断三元环
  2. Java学习-Thread
  3. SEM: 科研图片处理
  4. 抖音、西瓜视频、B站竞品分析!
  5. 后缀为axd 的文件
  6. 阿里字体图标库的使用
  7. hadoop功能测试
  8. windows_clion_Process finished with exit code -1073741515 (0xC0000135)
  9. 开发一个 app 有多难?
  10. 怎样申请.EDU邮箱