支付宝支付功能(沙箱)+springboot+jsp

                从零搭建支付宝支付案例

1.注册开发者账号,获取【公钥】和【私钥】,对支付宝提供给开发者的账号进行充值,请参考“ 会吐泡的鱼”的博客一到六步:https://blog.csdn.net/suprezheng/article/details/84931225

(注:该文档复制粘贴就能跑,如对里面参数不懂地方,欢迎留言,博主一一回应)

2.SpringBoot pom文件配置

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
	<groupId>com.edu</groupId>
	<artifactId>edu</artifactId>
	<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>edu-pay</artifactId>
<dependencies>

	<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->

	<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>
</dependencies>
<build>
	<plugins>
		<!--跳过测试类打包 -->
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-surefire-plugin</artifactId>
			<configuration>
				<skip>true</skip>
			</configuration>
		</plugin>
		<!-- maven打包插件 -->
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>
</project>

application.yml配置

server:
port: 8888
servlet:
context-path: /
spring:
  mvc:
   view:
     prefix: /WEB-INF/views/
     suffix: .jsp 

3.前端jsp页面

前端jsp页面是我从蚂蚁金服开发者中心下载的,

<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>支付宝电脑网站支付</title>
<style>
*{
margin: 0;
padding: 0;
}

ul, ol {
list-style: none;
}

body {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande",
	sans-serif;
}

.tab-head {
margin-left: 120px;
margin-bottom: 10px;
}

.tab-content {
clear: left;
display: none;
}

h2 {
border-bottom: solid #02aaf1 2px;
width: 200px;
height: 25px;
margin: 0;
float: left;
text-align: center;
font-size: 16px;
}

.selected {
color: #FFFFFF;
background-color: #02aaf1;
}

.show {
clear: left;
display: block;
}

.hidden {
display: none;
}

.new-btn-login-sp {
padding: 1px;
display: inline-block;
width: 75%;
}

.new-btn-login {
background-color: #02aaf1;
color: #FFFFFF;
font-weight: bold;
border: none;
width: 100%;
height: 30px;
border-radius: 5px;
font-size: 16px;
}

#main {
width: 100%;
margin: 0 auto;
font-size: 14px;
}

.red-star {
color: #f00;
width: 10px;
display: inline-block;
}

.null-star {
color: #fff;
}

.content {
margin-top: 5px;
}

.content dt {
width: 100px;
display: inline-block;
float: left;
margin-left: 20px;
color: #666;
font-size: 13px;
margin-top: 8px;
}

.content dd {
margin-left: 120px;
margin-bottom: 5px;
}

.content dd input {
width: 85%;
height: 28px;
border: 0;
-webkit-border-radius: 0;
-webkit-appearance: none;
}

#foot {
margin-top: 10px;
position: absolute;
bottom: 15px;
width: 100%;
}

.foot-ul {
width: 100%;
}

.foot-ul li {
width: 100%;
text-align: center;
color: #666;
}

.note-help {
color: #999999;
font-size: 12px;
line-height: 130%;
margin-top: 5px;
width: 100%;
display: block;
}

#btn-dd {
margin: 20px;
text-align: center;
}

.foot-ul {
width: 100%;
}

.one_line {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #eeeeee;
width: 100%;
margin-left: 20px;
}

.am-header {
display: -webkit-box;
display: -ms-flexbox;
display: box;
width: 100%;
position: relative;
padding: 7px 0;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
background: #1D222D;
height: 50px;
text-align: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
box-pack: center;
-webkit-box-align: center;
-ms-flex-align: center;
box-align: center;
}

.am-header h1 {
-webkit-box-flex: 1;
-ms-flex: 1;
box-flex: 1;
line-height: 18px;
text-align: center;
font-size: 18px;
font-weight: 300;
color: #fff;
}
</style>
</head>
<body text=#000000 bgColor="#ffffff" leftMargin=0 topMargin=4>
<header class="am-header">
<h1>支付宝电脑网站支付体验入口页</h1>
</header>
<div id="main">
	<div id="tabhead" class="tab-head">
		<h2 id="tab1" class="selected" name="tab">付 款</h2>
		<h2 id="tab2" name="tab">交 易 查 询</h2>
		<h2 id="tab3" name="tab">退 款</h2>
		<h2 id="tab4" name="tab">退 款 查 询</h2>
		<h2 id="tab5" name="tab">交 易 关 闭</h2>
	</div>
	<form name=alipayment action=/order/alipay method=post
	>
		<div id="body1" class="show" name="divcontent">
			<dl class="content">
				<dt>商户订单号 :</dt>
				<dd>
					<input id="out_trade_no" name="out_trade_no" />
				</dd>
				<hr class="one_line">
				<dt>订单名称 :</dt>
				<dd>
					<input id="subject" name="subject" />
				</dd>
				<hr class="one_line">
				<dt>付款金额 :</dt>
				<dd>
					<input id="total_amount" name="total_amount" />
				</dd>
				<hr class="one_line">
				<dt>商品描述:</dt>
				<dd>
					<input id="body" name="body" />
				</dd>
				<hr class="one_line">
				<dt></dt>
				<dd id="btn-dd">
					<span class="new-btn-login-sp">
						<button class="new-btn-login" type="submit"
							style="text-align: center;">付 款</button>
					</span> <span class="note-help">如果您点击“付款”按钮,即表示您同意该次的执行操作。</span>
				</dd>
			</dl>
		</div>
	</form>
	<form name=tradequery action=alipay.trade.query.jsp method=post
		target="_blank">
		<div id="body2" class="tab-content" name="divcontent">
			<dl class="content">
				<dt>商户订单号 :</dt>
				<dd>
					<input id="WIDTQout_trade_no" name="WIDTQout_trade_no" />
				</dd>
				<hr class="one_line">
				<dt>支付宝交易号 :</dt>
				<dd>
					<input id="WIDTQtrade_no" name="WIDTQtrade_no" />
				</dd>
				<hr class="one_line">
				<dt></dt>
				<dd id="btn-dd">
					<span class="new-btn-login-sp">
						<button class="new-btn-login" type="submit"
							style="text-align: center;">交 易 查 询</button>
					</span> <span class="note-help">商户订单号与支付宝交易号二选一,如果您点击“交易查询”按钮,即表示您同意该次的执行操作。</span>
				</dd>
			</dl>
		</div>
	</form>
	<form name=traderefund action=alipay.trade.refund.jsp method=post
		target="_blank">
		<div id="body3" class="tab-content" name="divcontent">
			<dl class="content">
				<dt>商户订单号 :</dt>
				<dd>
					<input id="WIDTRout_trade_no" name="WIDTRout_trade_no" />
				</dd>
				<hr class="one_line">
				<dt>支付宝交易号 :</dt>
				<dd>
					<input id="WIDTRtrade_no" name="WIDTRtrade_no" />
				</dd>
				<hr class="one_line">
				<dt>退款金额 :</dt>
				<dd>
					<input id="WIDTRrefund_amount" name="WIDTRrefund_amount" />
				</dd>
				<hr class="one_line">
				<dt>退款原因 :</dt>
				<dd>
					<input id="WIDTRrefund_reason" name="WIDTRrefund_reason" />
				</dd>
				<hr class="one_line">
				<dt>退款请求号 :</dt>
				<dd>
					<input id="WIDTRout_request_no" name="WIDTRout_request_no" />
				</dd>
				<hr class="one_line">
				<dt></dt>
				<dd id="btn-dd">
					<span class="new-btn-login-sp">
						<button class="new-btn-login" type="submit"
							style="text-align: center;">退 款</button>
					</span> <span class="note-help">商户订单号与支付宝交易号二选一,如果您点击“退款”按钮,即表示您同意该次的执行操作。</span>
				</dd>
			</dl>
		</div>
	</form>
	<form name=traderefundquery
		action=alipay.trade.fastpay.refund.query.jsp method=post
		target="_blank">
		<div id="body4" class="tab-content" name="divcontent">
			<dl class="content">
				<dt>商户订单号 :</dt>
				<dd>
					<input id="WIDRQout_trade_no" name="WIDRQout_trade_no" />
				</dd>
				<hr class="one_line">
				<dt>支付宝交易号 :</dt>
				<dd>
					<input id="WIDRQtrade_no" name="WIDRQtrade_no" />
				</dd>
				<hr class="one_line">
				<dt>退款请求号 :</dt>
				<dd>
					<input id="WIDRQout_request_no" name="WIDRQout_request_no" />
				</dd>
				<hr class="one_line">
				<dt></dt>
				<dd id="btn-dd">
					<span class="new-btn-login-sp">
						<button class="new-btn-login" type="submit"
							style="text-align: center;">退 款 查 询</button>
					</span> <span class="note-help">商户订单号与支付宝交易号二选一,如果您点击“退款查询”按钮,即表示您同意该次的执行操作。</span>
				</dd>
			</dl>
		</div>
	</form>
	<form name=tradeclose action=alipay.trade.close.jsp method=post
		target="_blank">
		<div id="body5" class="tab-content" name="divcontent">
			<dl class="content">
				<dt>商户订单号 :</dt>
				<dd>
					<input id="WIDTCout_trade_no" name="WIDTCout_trade_no" />
				</dd>
				<hr class="one_line">
				<dt>支付宝交易号 :</dt>
				<dd>
					<input id="WIDTCtrade_no" name="WIDTCtrade_no" />
				</dd>
				<hr class="one_line">
				<dt></dt>
				<dd id="btn-dd">
					<span class="new-btn-login-sp">
						<button class="new-btn-login" type="submit"
							style="text-align: center;">交 易 关 闭</button>
					</span> <span class="note-help">商户订单号与支付宝交易号二选一,如果您点击“交易关闭”按钮,即表示您同意该次的执行操作。</span>
				</dd>
			</dl>
		</div>
	</form>
	<div id="foot">
		<ul class="foot-ul">
			<li>支付宝版权所有 2015-2018 ALIPAY.COM</li>
		</ul>
	</div>
</div>
</body>
<script language="javascript">
var tabs = document.getElementsByName('tab');
var contents = document.getElementsByName('divcontent');

(function changeTab(tab) {
    for(var i = 0, len = tabs.length; i < len; i++) {
        tabs[i].onmouseover = showTab;
    }
})();

function showTab() {
    for(var i = 0, len = tabs.length; i < len; i++) {
        if(tabs[i] === this) {
            tabs[i].className = 'selected';
            contents[i].className = 'show';
        } else {
            tabs[i].className = '';
            contents[i].className = 'tab-content';
        }
    }
}

function GetDateNow() {
	var vNow = new Date();
	var sNow = "";
	sNow += String(vNow.getFullYear());
	sNow += String(vNow.getMonth() + 1);
	sNow += String(vNow.getDate());
	sNow += String(vNow.getHours());
	sNow += String(vNow.getMinutes());
	sNow += String(vNow.getSeconds());
	sNow += String(vNow.getMilliseconds());
	document.getElementById("out_trade_no").value =  sNow;
	document.getElementById("subject").value = "测试";
	document.getElementById("total_amount").value = "0.01";
}
GetDateNow();
</script>
</html>

4.后台包结构

在这里插入图片描述
alipay.properties,用注册开发者账号时,得到的相应的参数替代该文档****

# 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
app_id =****
# 商户私钥,您的PKCS8格式RSA2私钥
 merchant_private_key=****
# 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
alipay_public_key=****
# 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数 
notify_url=http://本机IP4地址:8888/notify_url.jsp
#notify_url =http://www.baidu.com
#页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数 
return_url=http://本机IP4地址:8888/return
#return_url =http://www.baidu.com
# 签名方式
sign_type=RSA2
# 字符编码格式
charset=UTF-8
#数据格式
format=json
# 支付宝网关
gatewayUrl=https://openapi.alipaydev.com/gateway.do
# 
log_path ="C:\\"
method=alipay.trade.page.pay
version=1.0

5.pojo包代码

AlipayBean

package com.edu.pojo;

import lombok.Data;
import lombok.experimental.Accessors;

@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="30s";	//超时参数
private String product_code="FAST_INSTANT_TRADE_PAY";
private String scene="bar_code";
private String qr_code_timeout_express="2m"; 
//具体商品需要哪些参数,请结合实际开发需求,参考开发文档写pojo对象
}

ResponseBean

package com.edu.pojo;

import java.io.Serializable;
import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
public class ResponseBean implements Serializable {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private String code;		//网关返回码,
private String msg;			//网关返回码描述
private String sign;
private String trade_no;		//支付宝交易号
private String out_trade_no;	//seller_id
private String seller_id;
private String total_amount;
private String merchant_order_no;
}

6.config包代码

PropertiesConfig

package com.edu.config;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Component;

@Component//读取支付配置文件
public class PropertiesConfig implements ApplicationListener{

//保存加载参数
private static Map<String, String> aliPropertiesMap = new HashMap<>();

//获取配置参数值
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文件
		Resource resouces = resolver.getResource("classpath:/alipay.properties");
		PropertiesFactoryBean config = new PropertiesFactoryBean();
		config.setLocation(resouces);
		config.afterPropertiesSet();
		Properties prop = config.getObject();
		//遍历配置文件,将配置信息存入集合
		for (String key : prop.stringPropertyNames()) {
			map.put(key, (String)prop.get(key));
		}
	} catch (Exception e) {
		new Exception("配置文件加载失败");
	}
 }	
}

AlipayUtil

package com.edu.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.edu.pojo.AlipayBean;

public class AlipayUtil {


//建立与支付宝连接
public static String connect(AlipayBean bean) 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.设置请求参数.
	//2、设置请求参数
	AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
	//页面跳转同步通知页面路径
	alipayRequest.setReturnUrl(PropertiesConfig.getKey("return_url"));
	// 服务器异步通知页面路径
	alipayRequest.setNotifyUrl(PropertiesConfig.getKey("notify_url"));

	//封装参数
	String jsonString = JSON.toJSONString(bean, SerializerFeature.UseSingleQuotes);
	System.out.println(jsonString);
	alipayRequest.setBizContent(jsonString);
	//3、请求支付宝进行付款,并获取支付结果
	String result = alipayClient.pageExecute(alipayRequest).getBody();
	//4.返回付款信息
	return result;
}
}

7.controller

OrderController

package com.edu.controller;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.alipay.api.AlipayApiException;
import com.edu.pojo.AlipayBean;
import com.edu.service.PayService;

@Controller
public class OrderController {

@Resource
private PayService payService;

/*阿里支付*/
@RequestMapping(value = "/order/alipay")
@ResponseBody
public String alipay (AlipayBean alipayBean) throws AlipayApiException{
	return payService.alipay(alipayBean);

}

/*异步通知*/
@RequestMapping("return")
public String notify(HttpServletRequest request,Model model) {
	//获取支付宝POST过来反馈信息
	Map<String, String> params = new HashMap<String, String>();
	Map<String, String[]> requestParams = request.getParameterMap();
	// 签名验证
	 for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {
		   System.out.println("key= " + entry.getKey() + " and value= " + Arrays.toString(entry.getValue()));
		  }
		  //这里我只打印了支付宝返回的信息,你们可以根据自己业务作相因的改变,注意这个success是jsp页面,具体根据yml配置
	return "success";
	

}
}

8.serviceI

package com.edu.service;

import com.alipay.api.AlipayApiException;
import com.edu.pojo.AlipayBean;

public interface PayService {

    String alipay(AlipayBean alipayBean) throws AlipayApiException;

}

8.serviceImpl

package com.edu.service.impl;

import org.springframework.stereotype.Service;

import com.alipay.api.AlipayApiException;
import com.edu.config.AlipayUtil;
import com.edu.pojo.AlipayBean;
import com.edu.service.PayService;
@Service
public class PayServiceImpl implements PayService{

@Override
public String alipay(AlipayBean alipayBean) throws AlipayApiException {
	return AlipayUtil.connect(alipayBean);
}

}

9.代码已经写完了,接下来进行测试,访问http://localhost:8888/index.jsp 注意,该jsp在wabapp文件夹下

在这里插入图片描述

在这里插入图片描述

至此,支付宝支付模块就已完成

发布了6 篇原创文章 · 获赞 14 · 访问量 1260

猜你喜欢

转载自blog.csdn.net/weixin_44802598/article/details/97973290