java实现支付宝接口-支付流程_菜鸟编程98K的博客-程序员宅基地_支付宝支付java

技术标签: Java  Alipay  支付宝接口  支付流程  ——【支付宝】  • 扩展知识  SpringBoot  

支付宝支付流程及注意事项(沙箱测试版) ---demo已做升级

​ 项目demo下载-CSDN(新-推荐)https://download.csdn.net/download/qq_39938758/11751843

 项目demo下载-CSDN(旧):https://download.csdn.net/download/qq_39938758/10581629

一、准备工作

1、springbootdemo

2、idea开发工具(有的跳过)

3、获得沙箱帐号

  • 注册蚂蚁金服开发者账号(免费,不像苹果会收取费用)

    注册地址:https://open.alipay.com,用你的支付宝账号扫码登录,完善个人信息,选择服务类型(我选的是自研)。

  • 进入沙箱,第一次需要填写信息!(我已经有了所以就不需要了)

  • 记得把下面生成的商户公钥保存到沙箱上

4、生成2048位商户公私钥(私钥保存与支付宝)

  • 进入官方地址:https://docs.open.alipay.com/291/105971

  • 下载生成工具

    支付宝-支付流程

     

  • 生成公私钥,并且保存

     

    标题

     

  • 保存公私钥

  • 把支付宝公钥 保存到沙箱环境。

     

5、pom.xml文件依赖alipay得jar包

<dependency>    
    <groupId>com.alipay.sdk</groupId>
    <artifactId>alipay-sdk-java</artifactId>
    <version>3.0.0</version>
</dependency>
​
<!-- 因为sdk有用这个包,所以需要有这个的哦。不过一般springboot项目已经自己引入了,就不用引入哈 -->
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.1.1</version>
</dependency>
​
<!-- 这个包是用户参数转成JSON用的 -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.33</version>
</dependency>
<!-- 简化代码插件的包,记得要在idea安装 lombok的插件哦 -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

二、支付宝支付代码流程

Demo项目结构: 请下载lombok插件

标题

第一步: 配置alipay.properties

# 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
app_id = 2016091600527203
# 商户私钥,您的PKCS8格式RSA2私钥
merchant_private_key = MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCAWY4SMml0Y9cWjf/19/zTFu9YFsmsV/QiD/9yk37MNrYxElo6hcdWbxBMX984kZVMs9WR0y3LcoENo43dOch+5UWsmHdMdX/DLJ4p4qx7JuYKUIcYT89dzAJe6e0LN/b7Sng7MoN9QD/iuzGTfHehZ2nU9VqBE7OW05m74MfT9rEYjLuJQc7IGezFV3uBbAUjtHUhIzq4iQ5shMf8JewbWXAh45FhHadD6yVFxPDmkyQJSRlfE39jXN+I4RILegMeJJNu5Mzd5GmTGukksLOoCBVoWpa5CgoPymBHosQpWgpjw5ItCJ4o0ttxnKW10kWQxcE+5E7nwTMpXdy3/veRAgMBAAECggEAdgtnmh7ZVF2a7biOCDgbRD2cxcS3mRWPiGB0TXmQLdvH9xvs9lQhwMIHGGc4kvt6eAAR1buHK81VGikpiaTiXKsbSKE1X5HVfrkjglxizCU7f5MOnPKSQq8mIws8o4vGUNnt+Gv9+Q1FdI88Cmx4Tm8hK+a4ZWysSHS2uNAEmVG5EB5zZmAG/N+oXGRQ+Kisf5pO27AQpc7bC1w6FZ1Te1wZKEX+5GPZc7dRLINvbzX7eEXiAE9Rv3RzRU+98HGXgA3kMTmQXqN24y2NIKOB5TZz8zsuUmW+haoxvRoL4fxnIhuaH39lwvsJyQa/T8kLWw9+2CmVDvEfWk/y2sDkAQKBgQDuWkOdlwJIySzXwTNlPQ7q0X3GJ3rjkgG0xysIHP69GCk5WwxlKx8WOORfnoPpYT0V8G1IYfy7RpVzqRkx3mYOEEk1OQGVhGRPuDnjhdyc39NVcrPU2P09aVnOp074Fwr7ei7tUAhSNJE0YNgyteq4pDRCl3cggeqQB/KWrgFj0QKBgQCJ2kxHaH8zPVGot3NdGhnuw9KibdPL3kx2n6ZSBL5IGQZk0sMCsnfb2dHCTZJhZs9MCG7okpBD9m0JsmY9b3FEupbA4YbF+4PKId+ShlUJNY2RDPNzb3kyYbEFzHcUJo7qFkeASTWIxKeZYXhtWT0Ue0Zf+lnsalKcm/dq8bgHwQKBgA0yyF24l/LJ2QbVdvAbMnFESm+njgF9+0Q0Zyia2mxEIzw+02/itGT5n4O/9lP9A3Hsj1CbxG/mV65A5dlCFGqg8jzVPEY4P4m+jM4RgobZSg2IPXcC0PsOk1+DGjdYp04HlQOlE+DhckzxM+eS9T1mMlKhqoINT5zMI92+IuuRAoGAcTPc0/8SBcfjGQOdLuVSSmpwvIYoGRByBi/QayYOBDLYt08EaWCZYOccg80j2eyNasi6Gy7QXZ8tp3rizqyHfYMkbTxGaqrCbOkoKbE6f5eEq4rRGQh/pEnpDvP7DYckcULecJCt76ReZWxPcqyHphwdjI+P7L7bHFRP93iMQYECgYAk/zyG+5qjEcAnyIptvrgxSklBz/2P1AEex4ZcJpkc3EgYB5sSqiSt4tpAb3s+XfQkP/+5djgGdFSIn4QmczSSf/35cck8G+bISOPoZ08wGRv8LzhXXRVpIooAtEYnJk+Xp3E1RcFmuq2IZCRX7IU3AMFRg941vW+4EAdKmk6oPQ==
# 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
alipay_public_key = MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAgFmOEjJpdGPXFo3/9ff80xbvWBbJrFf0Ig//cpN+zDa2MRJaOoXHVm8QTF/fOJGVTLPVkdMty3KBDaON3TnIfuVFrJh3THV/wyyeKeKseybmClCHGE/PXcwCXuntCzf2+0p4OzKDfUA/4rsxk3x3oWdp1PVagROzltOZu+DH0/axGIy7iUHOyBnsxVd7gWwFI7R1ISM6uIkObITH/CXsG1lwIeORYR2nQ+slRcTw5pMkCUkZXxN/Y1zfiOESC3oDHiSTbuTM3eRpkxrpJLCzqAgVaFqWuQoKD8pgR6LEKVoKY8OSLQieKNLbcZyltdJFkMXBPuRO58EzKV3ct/73kQIDAQAB
# 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数 
notify_url = http://外网ip:端口/error.html
# 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数 
return_url = http://外网ip:端口/sccess.html
# 签名方式
sign_type = RSA2
# 字符编码格式
charset = utf-8
# 支付宝网关
gatewayUrl = https://openapi.alipaydev.com/gateway.do
# 支付宝网关
log_path = "C:\\"

第二步: 编写测试页面 index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<H1>支付宝demo测试</H1>
<hr>
<form action="order/alipay" method="post">
    *商户订单 :<br>
    <input type="text" name="out_trade_no"><br>
    *订单名称 :<br>
    <input type="text" name="subject"><br>
    *付款金额 :<br>
    <input type="text" name="total_amount"><br>
     商品描述 :<br>
    <input type="text" name="body"><br>
    <input type="submit" value="支付宝支付">
</form>
</body>
</html>

第三步: 编写参数bean

/*支付实体对象*/
@Data
@Accessors(chain = true)
public class AlipayBean {
    /*商户订单号,必填*/
    private String out_trade_no;
    /*订单名称,必填*/
    private String subject;
    /*付款金额,必填*/
    private StringBuffer total_amount;
    /*商品描述,可空*/
    private String body;
    /*超时时间参数*/
    private String timeout_express="10m";
    private String product_code="FAST_INSTANT_TRADE_PAY";
}

第四步: 编写应用加载完成加载相关配置参数

/* 应用启动加载文件*/
@Component
public class PropertiesConfig implements ApplicationListener {
    //保存加载配置参数
    private static Map<String, String> aliPropertiesMap = new HashMap<String, String>();
    
    /*获取配置参数值*/
    public static String getKey(String key) {
        return aliPropertiesMap.get(key);
    }
    
    /*监听启动完成,执行配置加载到aliPropertiesMap*/
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ApplicationReadyEvent) {
            this.init(aliPropertiesMap);//应用启动加载
        }
    }
​
    /*初始化加载aliPropertiesMap*/
    public void init(Map<String, String> map) {
        // 获得PathMatchingResourcePatternResolver对象
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        try {
            //加载resource文件(也可以加载resources)
            Resource resources = resolver.getResource("classpath:config/alipay.properties");
            PropertiesFactoryBean config = new PropertiesFactoryBean();
            config.setLocation(resources);
            config.afterPropertiesSet();
            Properties prop = config.getObject();
            //循环遍历所有得键值对并且存入集合
            for (String key : prop.stringPropertyNames()) {
                map.put(key, (String) prop.get(key));
            }
        } catch (Exception e) {
            new Exception("配置文件加载失败");
        }
    }
}

第五步: 编写支付宝util

/* 支付宝 */
public class AlipayUtil {
    public static String connect(AlipayBean alipayBean) throws AlipayApiException {
         //1、获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(
                PropertiesConfig.getKey("gatewayUrl"),//支付宝网关
                PropertiesConfig.getKey("app_id"),//appid
                PropertiesConfig.getKey("merchant_private_key"),//商户私钥
                "json",
                PropertiesConfig.getKey("charset"),//字符编码格式
                PropertiesConfig.getKey("alipay_public_key"),//支付宝公钥
                PropertiesConfig.getKey("sign_type")//签名方式
        );
        //2、设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        //页面跳转同步通知页面路径
        alipayRequest.setReturnUrl(PropertiesConfig.getKey("return_url"));
        // 服务器异步通知页面路径
        alipayRequest.setNotifyUrl(PropertiesConfig.getKey("notify_url"));
        //封装参数
        alipayRequest.setBizContent(JSON.toJSONString(alipayBean));
​
        //3、请求支付宝进行付款,并获取支付结果
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        //返回付款信息
        return  result;
    }
}

第六步: 编写业务层

/*支付服务*/
public interface PayService {
    /*支付宝*/
    String aliPay(AlipayBean alipayBean) throws AlipayApiException;
}
 
/* 支付服务 */
@Service(value = "alipayOrderService")
public class PayServiceImpl implements PayService {
    @Override
    public String aliPay(AlipayBean alipayBean) throws AlipayApiException {
        return AlipayUtil.connect(alipayBean);
    }
}

第七步:编写web接口测试

/* 订单接口 */
@RestController()
@RequestMapping("order")
public class OrderController {
    @Resource
    private PayService payService;//调用支付服务
​
    /*阿里支付*/
    @PostMapping(value = "alipay")
    public String alipay(String out_trade_no,String subject,String total_amount,String body) throws AlipayApiException {
​
        return  payService.aliPay(new AlipayBean()
                 .setBody(body)
                 .setOut_trade_no(out_trade_no)
                 .setTotal_amount(new StringBuffer().append(total_amount))
                 .setSubject(subject));
    }
}

 

三、测试验证

 

 

备注1:相关注意事项

1、注意下载lombok插件和依赖lombokjar

2、其中service可以不要的,直接接口调用util文件也可以,当然你也可以直接在接口写连接加载都可以

备注2:支付宝相关资料链接

1、实现支付宝支付功能

2、叫你如何用支付宝测试扫一扫付钱功能

备注3:个人说明

  • * 沙箱版和正式流程无误,只是参数变化  和需要把应用增加到支付宝里面
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39938758/article/details/81387522

智能推荐

百度UEditor开发案例(JSP)_weixin_33897722的博客-程序员宅基地

本案例的开发环境:MyEclipse+tomcat+jdk    本案例的开发内容:用百度编辑器发布新闻(UEditor的初始化开发部署)编辑已发过的新闻(UEditor的应用——编辑旧文章)上传附件、图片等     由于百度编辑器强大的功能,web开发爱好者无不喜爱。但网上关于其开发的具体细节或整个项目的开发案例并不是很多,因此写下这篇简单开发百度编辑器UEditor的案...

视频测试地址_knowledgebao的博客-程序员宅基地_视频测试地址

视频测试地址​mp4文件http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4http://vjs.zencdn.net/v/oceans.mp4https://media.w3.org/2010/05/sintel/trailer.mp4http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4m3u8直播http://devimages.apple.com/

通过bt下载旧版debian镜像_αc的博客-程序员宅基地

我在上一篇文章中叙述了使用jigdo-lite下载debian镜像,我试验后,发现速度还是很慢,于是就有了这篇文章。debian镜像站提供了bt下载方式,以debian9.11为例,在它的amd64目录下有bt-cd目录,这意味着你可以使用任何bt工具快速下载,就是可以用迅雷下载了。...

USB WIFI驱动分析_一叶知秋dong的博客-程序员宅基地_usb wifi驱动

1. USB设备枚举过程     设备在插入USB 接口到设备成功找到它自己的驱动这一过程为:当把USB 设备插到USB 接口上后,USB 中央控制器会检测到有设备插入USB 接口了,Linux 内核会给设备分配一个数据结构来代表这个设备,Linux 会分配一个struct usb_device 数据结构来代表该设备,该数据结构记录设备的一些属性及数据。并把该数据结构挂载到一个全局的USB 设备链...

element-ui 表格列动态展示,排序错乱问题_一望损莓苔的博客-程序员宅基地

&amp;lt;el-table :data=&quot;tableData&quot; border stripe style=&quot;width: 100%;background:white;&quot; &amp;gt; &amp;lt;el-table-column key=&quot;1&quot; type=&quot;index&quot; label=&quot;序号&quot; align=&quot;center&quot; width

rtmp H264多Slice封装学习笔记_vonchenchen1的博客-程序员宅基地

1.背景在使用src_librtmp转推H264数据时,拉流端观看出现了花屏问题。经过排查发现客户端X264编码时如果设置了分片,转推为rtmp就会导致花屏,关闭分片相关设置视频正常。在转推H264前将数据写入本地,播放正常,播放转推后的rtmp花屏,ffplay会报错。这里推断是rtmp封装问题导致了花屏,下面首先需要对于这种一帧H264视频中包含多个Slice的情况,应当如何封装。2.与ffmpeg推流进行对比这里们尝试使用ffmpeg来推一段多slice的H264码流,ffplay拉流播放

随便推点

HTML空格占位符[转]_jianchangxiang的博客-程序员宅基地

&#32; == 普通的英文半角空格&#160; == &nbsp; == &#xA0; == no-break space (普通的英文半角空格但不换行)&#12288; == 中文全角空格 (一个中文宽度)&#8194; == &ensp; == en空格 (半个中文宽度)&#8195; == &emsp; == em空格 (一个中文宽度)&#8197;

STM32学习心得二十三:ADC转换原理及模数转换实验_天亮继续睡的博客-程序员宅基地

记录一下,方便以后翻阅~主要内容:1) STM32 ADC相关知识;2) 相关寄存器和库函数配置;3) 相关实验代码解读。实验功能:针对GPIOA, 引脚1,实时采集开发版上3.3v的电压信号(用杜邦线连接),在串口调试助手上实时观察该电压值。官方资料:《STM32中文参考手册V10》第11章——模拟/数字转换(ADC)1. ADC (Analog-to-Digital Converter)模/数转换器ADC是指将连续变量的模拟信号转换为离散的数字信号的器件。典型的模拟/数字转换

if语句和switch语句_用户5673143920_新浪博客_一颗程序媛0915的博客-程序员宅基地

选择结构if语句的几种形式(1)不带else的if语句 若条件为真,执行语句,否则,不执行if(表达式1) //表达式可以是逻辑表达式 关系表达式 也可以是一个变量{ 语句块1;}(2)if-else语句:若条件为真,执行语句1,否则,执行语句2if(表达式1){ 语句块1;}else //若此句不写则语句块二与表达式无关{ 语句块...

使用递归方法建树_yololee_的博客-程序员宅基地

使用递归方法建树[email protected](value = "/tree/menu") public HttpResponseTemp&lt;?&gt; getTreeMenu() { return pueService.getTreeMenu(); }service.Implpublic HttpResponseTemp&lt;?&gt; getTreeMenu() { List&lt;Pue&gt; pueList = pueBi

HIT-2019ICS大作业 程序人生-Hello’s P2P_matrix72的博客-程序员宅基地

HIT-2019ICS大作业 程序人生-Hello’s P2P计算机系统大作业Word文件(可查看图片)题 目 程序人生-Hello’s P2P 专 业 计算机科学与技术学   号 1180400420班   级 1803003学 生 刘文洋   指 导 教 师 史...

SpringMVC - 基础笔记_斑目晴信的博客-程序员宅基地

HelloWorld步骤:加入 jar – 包在 web.xml 中配置 DispatcherServlet加入 Spring MVC 的配置文件编写处理请求的处理器,并标识为处理器编写视图jar 包:commons-logging-1.1.3.jar spring-aop-4.0.0.RELEASE.jar spring-beans-4.0.0.RELEASE.jar spri