在pc电脑端调起支付宝支付,最终会返回支付宝的网页构造表单。
支付宝电脑网站支付文档:https://docs.open.alipay.com/270/105899/
前期工作准备如下:
- 支付宝AppId
- 支付宝公钥、应用公钥、私钥
这些信息可以在蚂蚁金服平台获取到,具体怎么获取可以查看搜索教程,这里不具体展开说明。
拿到这些信息之后就快要编写代码调起支付宝支付了
1. POM文件加入
<!-- 支付宝支付组件 -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.7.110.ALL</version>
</dependency>
2. 调起支付宝支付
支付参数的参考文档:https://docs.open.alipay.com/api_1/alipay.trade.page.pay/
private String aLiAppID; //支付宝AppId
private String aLiPrivateKey; //私钥
private String aLiPublicKey; //支付宝公钥
private String gatewayUrL; //请求地址:https://openapi.alipay.com/gateway.do
/**
* 支付宝支付
* @param tradeNumber //商户订单号
* @param price //支付金额
* @return
*/
@Transactional(rollbackFor = Exception.class)
public synchronized String Alipay(String tradeNumber,BigDecimal price) {
try {
Long startTime = System.currentTimeMillis();//获得系统当前时间的毫秒数
Long expireTime = startTime+=30*1000*60; //在当前系统时间的基础上往后加30分钟
//设置过期时间为30分钟
String timeExpire = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(expireTime);
//订单总金额,单位为元,精确到小数点后两位额,这里我使用了BigDecimal,用到了一个CommonUtil工具类,文章后面会提供这个工具类
String prices = CommonUtil.setScare(price,2);
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrL, aLiAppID, aLiPrivateKey, "json","utf-8",aLiPublicKey,"RSA2");
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
//支付宝服务器主动通知商户服务器里指定的页面http/https路径。简称回调地址
alipayRequest.setNotifyUrl("http://127.0.0.1/aLiOrderNotifyResult");
//支付后返回的页面,非必填
alipayRequest.setReturnUrl("http://sxlb.shunxinlb.com/#/");
alipayRequest.setBizContent("{" +
"\"out_trade_no\":\""+tradeNumber+ "\"," +
"\"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
"\"timeout_express\":\"30m\"," +
"\"total_amount\":\""+prices+ "\"," +
"\"subject\":\"xxx订单\"," +
"\"time_expire\":\""+timeExpire+"\"}");
AlipayTradePagePayResponse response = alipayClient.pageExecute(alipayRequest);
if(response.isSuccess()) {
String result = alipayClient.pageExecute(alipayRequest).getBody();
System.out.println("---------------支付宝支付网页表单:");
System.out.println(result);
return result;
} else {
System.out.println("支付宝构造支付网页表单失败");
System.out.println(response);
return null;
}
}catch (Exception e) {
e.printStackTrace();
}
}
3. 支付宝回调方法
private String publicKey; //应用公钥
/*
* 支付宝支付回调
*/
@PostMapping("/aLiOrderNotifyResult")
@ResponseBody
@Transactional(rollbackFor = Exception.class)
public synchronized String aLiOrderNotifyResult(HttpServletRequest request, String out_trade_no,String trade_no,String trade_status)throws AlipayApiException {
Map<String, String> map = new HashMap<String, String>();
Map<String, String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = iter.next();
String[] values = requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
System.out.println(valueStr);
}
map.put(name, valueStr);
}
boolean signVerified = false;
try {
signVerified = AlipaySignature.rsaCheckV1(map,publicKey,"utf-8","RSA2");
} catch (AlipayApiException e) {
e.printStackTrace();
return ("fail");// 验签发生异常,则直接返回失败
}
try {
if (signVerified) {
System.out.println("支付宝支付回调验签成功");
return ("success");
}else {
log.info("支付宝支付回调验证失败");
return ("fail");
}
}catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
4. CommonUtil工具类,用于BigDecimal金额换算
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
public class CommonUtil {
/**
* 除法
*/
public static BigDecimal divide(String arg1, String arg2) {
if (StringUtils.isEmpty(arg1)) {
arg1 = "0.0";
}
if (StringUtils.isEmpty(arg2)) {
arg2 = "0.0";
}
BigDecimal big3 = new BigDecimal("0.00");
if (Double.parseDouble(arg2) != 0) {
BigDecimal big1 = new BigDecimal(arg1);
BigDecimal big2 = new BigDecimal(arg2);
big3 = big1.divide(big2, 2, BigDecimal.ROUND_HALF_EVEN);
}
return big3;
}
/**
* 乘法
*/
public static BigDecimal mul(String arg1, String arg2) {
if (StringUtils.isEmpty(arg1)) {
arg1 = "0.0";
}
if (StringUtils.isEmpty(arg2)) {
arg2 = "0.0";
}
BigDecimal big1 = new BigDecimal(arg1);
BigDecimal big2 = new BigDecimal(arg2);
BigDecimal big3 = big1.multiply(big2);
return big3;
}
/**
* 减法
*/
public static BigDecimal sub(String arg1, String arg2) {
if (StringUtils.isEmpty(arg1)) {
arg1 = "0.0";
}
if (StringUtils.isEmpty(arg2)) {
arg2 = "0.0";
}
BigDecimal big1 = new BigDecimal(arg1);
BigDecimal big2 = new BigDecimal(arg2);
BigDecimal big3 = big1.subtract(big2);
return big3;
}
/**
* 加法
*/
public static BigDecimal add(String arg1, String arg2) {
if (StringUtils.isEmpty(arg1)) {
arg1 = "0.0";
}
if (StringUtils.isEmpty(arg2)) {
arg2 = "0.0";
}
BigDecimal big1 = new BigDecimal(arg1);
BigDecimal big2 = new BigDecimal(arg2);
BigDecimal big3 = big1.add(big2);
return big3;
}
/**
* 加法
*/
public static String add2(String arg1, String arg2) {
if (StringUtils.isEmpty(arg1)) {
arg1 = "0.0";
}
if (StringUtils.isEmpty(arg2)) {
arg2 = "0.0";
}
BigDecimal big1 = new BigDecimal(arg1);
BigDecimal big2 = new BigDecimal(arg2);
BigDecimal big3 = big1.add(big2);
return big3.toString();
}
/**
* 四舍五入保留N位小数 先四舍五入在使用double值自动去零
*
* @param arg
* @param scare
* 保留位数
* @return
*/
public static String setScare(BigDecimal arg, int scare) {
BigDecimal bl = arg.setScale(scare, BigDecimal.ROUND_HALF_UP);
return String.valueOf(bl.doubleValue());
}
public static double setDifScare(double arg) {
BigDecimal bd = new BigDecimal(arg);
BigDecimal bl = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
return Double.parseDouble(bl.toString());
}
/**
* 四舍五入保留两位小数 先四舍五入在使用double值自动去零
*
* @param arg
* @return
*/
public static String setDifScare(String arg) {
BigDecimal bd = new BigDecimal(arg);
BigDecimal bl = bd.setScale(2, BigDecimal.ROUND_HALF_UP);
return bl.toString();
}
/**
* 四舍五入保留N位小数 先四舍五入在使用double值自动去零(传参String类型)
*
* @param arg
* @return
*/
public static String setDifScare(String arg, int i) {
BigDecimal bd = new BigDecimal(arg);
BigDecimal bl = bd.setScale(i, BigDecimal.ROUND_HALF_UP);
return bl.toString();
}
/**
* 转化成百分数 先四舍五入在使用double值自动去零
*
* @param arg
* @return
*/
public static String setFenScare(BigDecimal arg) {
BigDecimal bl = arg.setScale(3, BigDecimal.ROUND_HALF_UP);
String scare = String.valueOf(mul(bl.toString(), "100").doubleValue());
String fenScare = scare + "%";
return fenScare;
}
/**
* 使用java正则表达式去掉多余的.与0
*
* @param s
* @return
*/
public static String subZeroAndDot(String s) {
if (s.indexOf(".") > 0) {
s = s.replaceAll("0+?$", "");// 去掉多余的0
s = s.replaceAll("[.]$", "");// 如最后一位是.则去掉
}
return s;
}
}