前言
之前的众酬网项目,涉及到资金流动
,近来 ITAEM 团队一个省立大创项目,电子病历,挂号等功能,也涉及到资金流动。
下面笔者分享一下项目中使用涉及这方面的核心代码。抽取核心代码,写成一个 demo。
由于使用 支付宝支付
,可以使用沙箱,而使用 微信支付
,得先交 300 块,这对学生不是很友好。
于是打算先使用 支付宝支付,后面再加上微信支付,毕竟现在网站基本都支持支付宝支付、微信支付。
简单演示
简单说明:
①在输入框中输入金额 15(随便,沙箱可以任性充值~)
②点击按钮,进入支付页面
③根据①中的金额,使用手机的支付宝沙箱APP,扫码支付对应的金额 15 块
④提示支付成功页面
⑤跳转到自定义的页面(没写)
代码结构
核心代码内容
支付宝配置 Config
package com.cun.config;
/**
* 支付宝配置信息
* @author linhongcun
*
*/
public class AlipayConfig {
//开发者中心 / 研发服务 / 沙箱环境 / 沙箱应用/ 信息配置/ 必看部分/ APPID(填自己的,下面都是改过的~)
public static String app_id = "0123456789";
//开发者中心 / 研发服务 / 沙箱环境 / 沙箱应用/ 信息配置/ 必看部分/ 生成公钥时对应的私钥(填自己的,下面都是改过的~)
public static String private_key = "abcdefghijklmnopqrstuvwxyz0123456789";
//Controller Mapping:得放到服务器上,且使用域名解析 IP
public static String notify_url = "http://www.linhongcun.com/SpringBootPay-0.0.1-SNAPSHOT/pay/notifyUrl";
//Controller Mapping:得放到服务器上,且使用域名解析 IP
public static String return_url = "http://www.linhongcun.com/SpringBootPay-0.0.1-SNAPSHOT/pay/returnUrl";
//开发者中心 / 研发服务 / 沙箱环境 / 沙箱应用/ 信息配置/ 必看部分/ 支付宝网关(注意沙箱alipaydev,正式则为 alipay)
public static String url = "https://openapi.alipaydev.com/gateway.do";
public static String charset = "UTF-8";
public static String format = "json";
//开发者中心 / 研发服务 / 沙箱环境 / 沙箱应用/ 信息配置/ 必看部分/ 公钥(填自己的,下面都是改过的~)
public static String public_key = "abcdefghijklmnopqrstuvwxyz0123456789";
public static String signtype = "RSA2";
}
支付宝接口 Controller
package com.cun.controller;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.cun.config.AlipayConfig;
import com.cun.util.DateUtil;
/**
* 支付宝支付Controller
* @author linhongcun
*
*/
@Controller
@RequestMapping("/alipay")
public class AlipayController {
// 获取配置文件的信息
String app_id = AlipayConfig.app_id;
String private_key = AlipayConfig.private_key;
String notify_url = AlipayConfig.notify_url;
String return_url = AlipayConfig.return_url;
String url = AlipayConfig.url;
String charset = AlipayConfig.charset;
String format = AlipayConfig.format;
String public_key = AlipayConfig.public_key;
String signtype = AlipayConfig.signtype;
/**
* 支付请求
*
* @param order
* @param request
* @param response
* @throws Exception
*/
@RequestMapping("/pay")
public void pay(HttpServletRequest request, HttpServletResponse response,String money) throws Exception {
// 模拟从前台传来的数据
String orderNo = DateUtil.getCurrentDateStr(); // 生成订单号
String totalAmount = money; // 支付总金额
String subject = "ITAEMBook"; // 订单名称
String body = "reading"; // 商品描述
// 封装请求客户端
AlipayClient client = new DefaultAlipayClient(url, app_id, private_key, format, charset, public_key, signtype);
// 支付请求
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(return_url);
alipayRequest.setNotifyUrl(notify_url);
AlipayTradePayModel model = new AlipayTradePayModel();
model.setProductCode("FAST_INSTANT_TRADE_PAY"); // 设置销售产品码
model.setOutTradeNo(orderNo); // 设置订单号
model.setSubject(subject); // 订单名称
model.setTotalAmount(totalAmount); // 支付总金额
model.setBody(body); // 设置商品描述
alipayRequest.setBizModel(model);
String form = client.pageExecute(alipayRequest).getBody(); // 生成表单
response.setContentType("text/html;charset=" + charset);
response.getWriter().write(form); // 直接将完整的表单html输出到页面
response.getWriter().flush();
response.getWriter().close();
}
/**
* 同步跳转
*
* @param request
* @throws Exception
*/
@RequestMapping("/returnUrl")
public ModelAndView returnUrl(HttpServletRequest request) throws Exception {
ModelAndView mav = new ModelAndView();
// 获取支付宝GET过来反馈信息(官方固定代码)
Map<String, String> params = new HashMap<String, String>();
Map<String, String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
params.put(name, valueStr);
}
boolean signVerified = AlipaySignature.rsaCheckV1(params, public_key, charset, signtype); // 调用SDK验证签名
// 返回界面
if (signVerified) {
System.out.println("前往支付成功页面");
mav.setViewName("successReturn");
} else {
System.out.println("前往支付失败页面");
mav.setViewName("failReturn");
}
return mav;
}
/**
* 支付宝服务器异步通知
*
* @param request
* @throws Exception
*/
@RequestMapping("/notifyUrl")
public void notifyUrl(HttpServletRequest request) throws Exception {
// 获取支付宝GET过来反馈信息
Map<String, String> params = new HashMap<String, String>();
Map<String, String[]> requestParams = request.getParameterMap();
for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
String name = (String) iter.next();
String[] values = (String[]) requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
params.put(name, valueStr);
}
boolean signVerified = AlipaySignature.rsaCheckV1(params, public_key, charset, signtype); // 调用SDK验证签名
if (signVerified) { // 验证成功 更新订单信息
System.out.println("异步通知成功");
// 商户订单号
String out_trade_no = request.getParameter("out_trade_no");
// 交易状态
String trade_status = request.getParameter("trade_status");
// 修改数据库
} else {
System.out.println("异步通知失败");
}
}
}
Maven 依赖
但是发布到 Linux 服务器,打成 war 包是不会加进去的,要额外设置一下
<!-- 支付宝支付 -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.0.52.ALL</version>
</dependency>