一:注册沙箱账号
1.注册
url:https://open.alipay.com/platform/home.htm
2.填写信息

3.操作步骤
先选择开发者中心

然后,选择研发服务

出现:

生成秘钥:

使用工具:

生成秘钥:

然后添加到
应用公钥与支付宝公钥都要保存起来,支付宝公钥在程序中使用。

4.可以参考记录文档链接
https://docs.open.alipay.com/291/105971#LDsXr
二:开发
0.程序结构

1.添加依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
2.在resource下新建一个配置alipay.properties
其实可以用在默认的文件下,这里根据网上的来,也学习一下
# 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 appId:2016092900622443 # 商户私钥,您的PKCS8格式RSA2私钥 privateKey:M.......秘钥不便显示.......9vdkUTw= # 支付宝公钥,查看地址:https://openhome.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 publicKey:MI.......秘钥不便显示.......AB # 服务器异步通知页面路径需http://格式的完整路径,不能加?id=123这类自定义参数 notifyUrl: http://localhost/error.html # 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数 returnUrl: http://127.0.0.1:8080/success.html # 签名方式 signType: RSA2 # 字符编码格式 charset: utf-8 # 支付宝网关 gatewayUrl: https://openapi.alipaydev.com/gateway.do # 支付宝网关 logPath: "D://"
3.增加一个 PropertiesListener 监听器用于在应用启动时加载配置文件属性。
PropertiesListener.java
package com.jun.epaypro.config;
import com.jun.epaypro.entity.AlipayProperties;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
/**
* @description 配置文件监听器,用来加载自定义配置文件
* @author caojun
* @date 2020/2/19
*/
@Component
public class PropertiesListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
AlipayProperties.loadProperties();
}
}
4.上面的监听器加载属性,是通过具体的属性加载器加载的,比如支付宝支付属性加载类如下。
AlipayProperties.java
package com.jun.epaypro.entity;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
/**
* 应用启动加载文件
* @author caojun
* @date 2020/2/19
*/
@Component
@Getter
@Slf4j
public class AlipayProperties {
private static final String APP_ID = "appId";
private static final String PRIVARY_KEY = "privateKey";
private static final String PUBLIC_KEY = "publicKey";
private static final String NOTIFY_URL = "notifyUrl";
private static final String RETURN_URL = "returnUrl";
private static final String SIGN_TYPE = "signType";
private static final String CHARSET = "charset";
private static final String GATEWAY_URL = "gatewayUrl";
private static final String LOG_PATH = "logPath";
/**
* 保存加载配置参数
*/
private static Map<String, String> propertiesMap = new HashMap<>();
/**
* 加载属性
*/
public static void loadProperties() {
// 获得PathMatchingResourcePatternResolver对象
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
try {
Resource resources = resolver.getResource("classpath:alipay.properties");
PropertiesFactoryBean config = new PropertiesFactoryBean();
config.setLocation(resources);
config.afterPropertiesSet();
Properties prop = config.getObject();
// 循环遍历所有得键值对并且存入集合
assert prop != null;
for (String key : prop.stringPropertyNames()) {
propertiesMap.put(key, (String) prop.get(key));
}
} catch (Exception e) {
log.info("配置加载失败");
}
}
/**
* 获取配置参数值
*/
public static String getKey(String key) {
return propertiesMap.get(key);
}
public static String getAppId() {
return propertiesMap.get(APP_ID);
}
public static String getPrivateKey() {
return propertiesMap.get(PRIVARY_KEY);
}
public static String getPublicKey() {
return propertiesMap.get(PUBLIC_KEY);
}
public static String getNotifyUrl() {
return propertiesMap.get(NOTIFY_URL);
}
public static String getReturnUrl() {
return propertiesMap.get(RETURN_URL);
}
public static String getSignType() {
return propertiesMap.get(SIGN_TYPE);
}
public static String getCharset() {
return propertiesMap.get(CHARSET);
}
public static String getGatewayUrl() {
return propertiesMap.get(GATEWAY_URL);
}
public static String getLogPath() {
return propertiesMap.get(LOG_PATH);
}
}
5.支付宝支付接口封装
package com.jun.epaypro.controller;
import com.alipay.api.AlipayApiException;
import com.jun.epaypro.entity.AlipayBean;
import com.jun.epaypro.service.PayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @description 订单接口
* @author caojun
* @date 2020/2/19
*/
@RestController
@RequestMapping("order")
public class OrderRestController {
@Resource
private PayService payService;
/**
* 支付接口
* @param outTradeNo 商户订单
* @param subject 订单名称
* @param totalAmount 付款金额
* @param body 商品描述
*/
@PostMapping(value = "alipay")
public String alipay(String outTradeNo, String subject, String totalAmount, String body) throws AlipayApiException {
AlipayBean alipayBean = new AlipayBean();
alipayBean.setOut_trade_no(outTradeNo);
alipayBean.setSubject(subject);
alipayBean.setTotal_amount(totalAmount);
alipayBean.setBody(body);
return payService.aliPay(alipayBean);
}
}
6.订单业务封装
package com.jun.epaypro.service;
import com.alipay.api.AlipayApiException;
import com.jun.epaypro.entity.AlipayBean;
/**
* @description PayService
* @author caojun
* @date 2020/2/19
*/
public interface PayService {
/**
* 支付宝支付接口
* @param alipayBean 支付参数
*/
String aliPay(AlipayBean alipayBean) throws AlipayApiException;
}
package com.jun.epaypro.service.impl;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.jun.epaypro.service.PayService;
import com.jun.epaypro.entity.AlipayProperties;
import com.jun.epaypro.entity.AlipayBean;
import org.springframework.stereotype.Service;
/**
* @description pay的service具体实现
* @author caojun
* @date 2020/2/19
*/
@Service
public class PayServiceImpl implements PayService {
@Override
public String aliPay(AlipayBean alipayBean) throws AlipayApiException {
return pay(alipayBean);
}
/**
* 支付接口
* @param alipayBean 支付参数
*/
private static String pay(AlipayBean alipayBean) throws AlipayApiException {
// 1、获得初始化的AlipayClient
String serverUrl = AlipayProperties.getGatewayUrl();
String appId = AlipayProperties.getAppId();
String privateKey = AlipayProperties.getPrivateKey();
String format = "json";
String charset = AlipayProperties.getCharset();
String alipayPublicKey = AlipayProperties.getPublicKey();
String signType = AlipayProperties.getSignType();
String returnUrl = AlipayProperties.getReturnUrl();
String notifyUrl = AlipayProperties.getNotifyUrl();
AlipayClient alipayClient = new DefaultAlipayClient(serverUrl, appId, privateKey, format, charset, alipayPublicKey, signType);
// 2、设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
// 页面跳转同步通知页面路径
alipayRequest.setReturnUrl(returnUrl);
// 服务器异步通知页面路径
alipayRequest.setNotifyUrl(notifyUrl);
// 封装参数
alipayRequest.setBizContent(JSON.toJSONString(alipayBean));
// 3、请求支付宝进行付款,并获取支付结果
// 返回付款信息
return alipayClient.pageExecute(alipayRequest).getBody();
}
}
package com.jun.epaypro.entity;
import org.springframework.stereotype.Component;
/**
* 支付实体对象
* 根据支付宝接口协议,其中的属性名,必须使用下划线,不能修改
* @author caojun
* @date 2020/2/19
*/
@Component
public class AlipayBean {
/**
* 商户订单号,必填
*
*/
private String out_trade_no;
/**
* 订单名称,必填
*/
private String subject;
/**
* 付款金额,必填
* 根据支付宝接口协议,必须使用下划线
*/
private String total_amount;
/**
* 商品描述,可空
*/
private String body;
/**
* 超时时间参数
*/
private String timeout_express= "10m";
/**
* 产品编号
*/
private String product_code= "FAST_INSTANT_TRADE_PAY";
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getTotal_amount() {
return total_amount;
}
public void setTotal_amount(String total_amount) {
this.total_amount = total_amount;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getTimeout_express() {
return timeout_express;
}
public void setTimeout_express(String timeout_express) {
this.timeout_express = timeout_express;
}
public String getProduct_code() {
return product_code;
}
public void setProduct_code(String product_code) {
this.product_code = product_code;
}
}
7.前台页面
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>支付测试</title>
<style>
.form-container {
padding-top:10px;
}
input {
margin:10px;
}
</style>
</head>
<body>
<H1>支付测试</H1>
<hr>
<div class="form-container">
<form id="form" action="order/alipay" method="post">
*商户订单 :
<input type="text" name="outTradeNo" value="dzcp10001"><br>
*订单名称 :
<input type="text" name="subject" value="红魔手机"><br>
*付款金额 :
<input type="text" name="totalAmount" value="0.1" ><br>
*商品描述 :
<input type="text" name="body" value="红魔戏手机"><br>
<input type="button" value="支付宝支付" onclick="submitForm('order/alipay')">
<input type="button" value=" 微信支付 " onclick="submitForm('order/wexpay')">
</form>
</div>
</body>
<script language="javascript">
function submitForm(action) {
document.getElementById("form").action = action
document.getElementById("form").submit()
}
</script>
</html>
success.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h2>SUCCESS</h2>
</body>
</html>
三:测试
1.这里需要使用沙箱账号才可以进行测试
链接:https://openhome.alipay.com/platform/appDaily.htm?tab=account
2.支付

登录沙箱买家账号:

进行支付:

3.结果
根据沙箱工具,下载沙箱支付宝
在付款之后,在余额中将会发现,余额增加了。