1. 备注

Alipay Easy SDK 简化了服务端调用方式,减少支付的开发流程,对于不以交易为重点的项目是非常合适的。
以下只是简单的调用示例,说明多在代码注释中,更多方法如验签、AES加密、退款、对账等可以查看官方文档了解。
GitHub地址 :https://github.com/alipay/alipay-easysdk/tree/master/java
接口文档:https://www.aliyundrive.com/s/dawCJYNec33

2. 添加maven依赖

<!-- 支付宝支付(必须)-->
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-easysdk</artifactId><version>2.2.3</version>
</dependency><!-- JSON解析器(非必须)-->
<dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId>
</dependency><!-- ZXing二维码(非必须)-->
<dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.4.1</version>
</dependency>
<dependency><groupId>com.google.zxing</groupId><artifactId>javase</artifactId><version>3.4.1</version>
</dependency>

3. 调用支付方法获得付款二维码

/*** 支付宝付款*/
@PostMapping("/alipay")
public R alipay(@RequestBody HashMap<String, Object> map) {//设置参数Factory.setOptions(getOptions());try {//商家订单号String outTradeNo = IdUtils.fastSimpleUUID();//支付金额double totalMoney = 99.99;//商品名称String subject = "千里香混沌";//发起API调用(以创建当面付收款二维码为例)AlipayTradePrecreateResponse response = Factory.Payment.FaceToFace()//.asyncNotify("https://www.test.com/callback")//如在此处设置异步通知地址,其优先级高于全局Config中配置的地址.preCreate(subject, outTradeNo, String.valueOf(totalMoney));/*//当SDK的API声明中的参数不满足个性化需求时,可按如下方式追加可选业务参数://第一种List<Object> goodsDetailList = new ArrayList<>();Map<String, Object> goodsDetail = new HashMap<>();goodsDetail.put("goods_id", "apple-01");goodsDetail.put("goods_name", "Apple iPhone11 128G");goodsDetail.put("quantity", 1);goodsDetail.put("price", "5799.00");goodsDetailList.add(goodsDetail);AlipayTradePrecreateResponse response = Factory.Payment.FaceToFace()// 调用optional扩展方法,完成可选业务参数(biz_content下的可选字段)的设置.optional("seller_id", "2088******225135").optional("discountable_amount", "8.88").optional("goods_detail", goodsDetailList).preCreate("Apple iPhone11 128G", "2234567890", "5799.00");//第二种Map<String, Object> optionalArgs = new HashMap<>();optionalArgs.put("seller_id", "2088******225135");optionalArgs.put("discountable_amount", "8.88");optionalArgs.put("goods_detail", goodsDetailList);AlipayTradePrecreateResponse response = Factory.Payment.FaceToFace()// 也可以调用batchOptional扩展方法,批量设置可选业务参数(biz_content下的可选字段).batchOptional(optionalArgs).preCreate("Apple iPhone11 128G", "2234567890", "5799.00");*///处理响应或异常if (ResponseChecker.success(response)) {log.info("支付宝付款调用成功");//支付二维码链接String qrCode = response.getQrCode();//二维码链接转图片base64String qrBase64 = QRCodeGenerator.qrToBase64(qrCode);//一些自定义的订单保存操作//map.put("outTradeNo", outTradeNo);//map.put("totalMoney", totalMoney);//map.put("subject", subject);//service.insertPayRecord(map);//返回数据return R.ok(qrBase64);} else {log.info("支付宝付款调用失败,原因:" + response.msg + "," + response.subMsg);throw new ServiceException("网络异常!");}} catch (Exception e) {log.info("支付宝付款调用失败,原因:" + e.getMessage());throw new ServiceException("网络异常!");}
}//这些参数可配置在yaml中,这里以公钥模式为例,也可改为证书模式
private Config getOptions() {Config config = new Config();config.protocol = "https";//协议config.gatewayHost = gatewayHost;//支付宝网关,沙箱环境为:openapi-sandbox.dl.alipaydev.comconfig.signType = "RSA2";//签名方式config.appId = appId;//应用idconfig.merchantPrivateKey = merchantPrivateKey;//应用私钥config.alipayPublicKey = alipayPublicKey;//支付宝公钥(公钥模式必填)//config.merchantCertPath = "/foo/appCertPublicKey_2019051064521003.crt";//应用公钥证书文件路径(证书模式必填)//config.alipayCertPath = "/foo/alipayCertPublicKey_RSA2.crt";//支付宝公钥证书文件路径(证书模式必填)//config.alipayRootCertPath = "/foo/alipayRootCert.crt";//支付宝根证书文件路径(证书模式必填)config.notifyUrl = notifyUrl;//回调地址//config.encryptKey = "aa4BtZ4tspm2wnXLb1ThQA==";//AES密钥,调用AES加解密相关接口时需要(可选)return config;
}

4. 接收支付结果异步回调

/*** 支付结果异步回调*/
@CrossOrigin
@RequestMapping("/callback")
public void callback(HttpServletRequest request) throws Exception {try {Map<String, String> params = getRequestParam(request);if (!Factory.Payment.Common().verifyNotify(params)) {log.info("支付结果校验失败");}String outTradeNo = params.get("out_trade_no");String tradeStatus = params.get("trade_status");if (tradeStatus .equals("TRADE_SUCCESS")) {log.info("支付成功,订单号:" + outTradeNo );//更新保存的订单信息//updatePayRecord1(params, outTradeNo );} else {log.info("支付失败,订单号:" + outTradeNo );//更新保存的订单信息//updatePayRecord2(params, outTradeNo );}} catch (Exception e) {e.printStackTrace();}
}//处理得到的参数
private Map<String, String> getRequestParam(final HttpServletRequest request) {Map<String, String> res = new HashMap<>();Enumeration<?> temp = request.getParameterNames();while (temp.hasMoreElements()) {String en = (String) temp.nextElement();String value = request.getParameter(en);res.put(en, value);}return res;
}

5. 查询支付状态

/*** 付款状态同步查询* 当需要即时了解支付状态时可调用此接口,如扫码未付款、支付成功、支付失败* 可使用定时器轮询或改造为webscoket*/
@GetMapping("/payStatus/{outTradeNo}")
public R payStatus(@PathVariable String outTradeNo ) {AlipayTradeQueryResponse query = null;try {Factory.setOptions(getOptions());query = Factory.Payment.Common().query(outTradeNo );} catch (Exception e) {e.printStackTrace();}String httpBody = query.getHttpBody();JSONObject jsonObject = JSONObject.parseObject(httpBody);JSONObject query_response = jsonObject.getJSONObject("alipay_trade_query_response");String trade_status = query_response.getString("trade_status");if (StringUtils.isBlank(trade_status)) {trade_status = "NO_SCAN_CODE";}return R.ok(trade_status);
}

6. 二维码工具类

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;public class QRCodeGenerator {//二维码链接转图片base64public static String qrToBase64(String qrStr) {int width = 300; // 二维码图像宽度int height = 300; // 二维码图像高度String format = "png"; // 二维码图像格式// 设置二维码参数Map<EncodeHintType, Object> hints = new HashMap<>();hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");BitMatrix bitMatrix;try {bitMatrix = new MultiFormatWriter().encode(qrStr, BarcodeFormat.QR_CODE, width, height, hints);} catch (WriterException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}// 将BitMatrix转换为BufferedImageBufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);// 将BufferedImage转换为Base64编码的字符串ByteArrayOutputStream baos = new ByteArrayOutputStream();try {ImageIO.write(image, format, baos);} catch (IOException e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}byte[] imageBytes = baos.toByteArray();return Base64.getEncoder().encodeToString(imageBytes);}
}

7. 获得应用id和密钥

支付宝开放平台:https://open.alipay.com/develop/sandbox/app

支付宝沙箱支付AlipayEasy相关推荐

  1. 基于SpringBoot vue的电脑商城平台源码和论文含支付宝沙箱支付

    演示视频: 基于SpringBoot vue的电脑商城平台源码和论文含支付宝沙箱支付演示视频 支付宝沙箱: package com.java.controller;import java.util.* ...

  2. 【支付宝沙箱支付】麻瓜教程——申请----代码----修改测试----问题解决

    文章目录 支付宝沙箱环境 沙箱概述: 支付宝沙箱支付操作 `1.搜索进入支付宝开放平台` `2.登录,进入控制台` `3.进入沙箱` `4.进入支付宝开发助手下载所需的工具(度娘搜索就有)` `5.然 ...

  3. 一文叫你学会用JavaWeb开发共享图书馆系统(附加支付宝沙箱支付接入)

    前提: 学习书籍: 黑马程序员的<Java Web程序设计任务教程>: 如果没有本文的资源均可以评论留言,我可以免费发给你们学习. 下载安装Eclipse 2021.MySQL 5.5.T ...

  4. SpringBoot+Vue整合支付宝沙箱支付

    SpringBoot+Vue2整合实现支付宝沙箱支付 原创不易,转载请注明!!原创不易,转载请注明!!原创不易,转载请注明!!原创不易,转载请注明!!原创不易,转载请注明!! 在进行电脑网站开发时我们 ...

  5. 支付宝沙箱支付可能遇见的问题

    问题1:付款时显示订单已付款 原因: 向支付宝提交的订单号重复,且之前的订单号已支付过 解决办法: 换个订单号就行 问题2: 触发点击事件时界面显示404NotFound 原因1:支付宝网关填写有错误 ...

  6. Asp.Net支付宝沙箱支付(也可用手机扫描支付)详细教程

    要想完成支付宝沙箱支付就必须先完成这些设置后才能往后走 一.首先先注册 1.点击下面的网址,点击右上角的立即入驻,然后用支付宝账号扫码登陆.然后填写信息,登陆. 支付宝开放平台 然后进入平台找到沙箱后 ...

  7. 基于SpringBoot vue的茶叶商城平台源码和论文含支付宝沙箱支付

    此项目是前后端分离的 后台项目:shop 前端项目:Vue-shop 后端项目启动步骤: 1.先把sql导入数据库 2.把后台项目导入编辑器 3.修改数据库配置 4.启动项目   前端项目启动步骤: ...

  8. springboot整合支付宝沙箱支付

    springboot整合支付宝沙箱支付 1.简介 支付宝开发平台地址:https://open.alipay.com/develop/sandbox/app 对于学生来说,目前网上确实没有比较统一而且 ...

  9. 阿里云支付宝沙箱支付

    阿里云支付宝沙箱支付 项目文件是maven项目 第一步pom.xml引入jar包 <!-- 沙箱支付依赖--><dependency><groupId>com.al ...

最新文章

  1. AMD猛攻数据中心市场,拿下15年来最高份额,英特尔DCG收入下滑20%
  2. 编译linux3内核,与busybox,用qemu模拟运行
  3. 基于PYQT编写一个人脸识别软件(2)
  4. jmap 文件解析_[Java基础] 使用JMAP dump及分析dump文件
  5. 链表反转2(Reverse Linked List II)
  6. lamp php5.5,CentOS 5.5快速搭建Apache+PHP5+MySQL完美Web服务器(LAMP)
  7. java字符流和字节流的区别_java字符流与字节流的区别是什么
  8. 大橙子_【大橙子活动】工程学院新媒体中心第二届总结大会圆满结束!
  9. 一个基于 SpringBoot 开源的小说和漫画在线阅读网站,简洁大方、强烈推荐
  10. 论计算机专业毕业生的人文素养
  11. Go语言学习笔记——Go语言数据类型
  12. R语言入门1:安装R和RStudio
  13. StringTokenizer字符串分解器
  14. LabVIEW编程LabVIEW开发以编程方式将前面板移动到所需位置
  15. 教师计算机课教学反思范文,信息技术课优秀教学反思
  16. 【渝粤教育】 国家开放大学2020年春季 1308外国文学专题 参考试题
  17. python实操实例100例_趣学Python算法100例
  18. 利用 @media screen 实现网页布局的自适应,@media screen and
  19. 数据结构笔记:选择排序
  20. 【软件测试】—— 基础知识总结

热门文章

  1. java.lang.ClassNotFoundException: com.jdbc.driver.Driver
  2. arcGis 加载地图
  3. 小说里的编程 【连载之十四】元宇宙里月亮弯弯
  4. MyBatis 中的trim标签介绍
  5. MipMap贴图原理
  6. 年终固定资产大盘点的解决方案
  7. SpringCloud 2020版本教程0:springcloud 2020版本概述
  8. Mac OS X 映射网络驱动器
  9. springboot 之 自动生成接口文档工具JApiDocs
  10. QTest 单元测试框架及单元测试思考