1、支付宝沙箱1.1 jar包 alipay-sdk<!-- alipay-sdk --><dependency> <groupId>com.alipay.sdk</groupId> <artifactId>alipay-sdk-java</artifactId> <version>4.10.90.ALL</version></dependency>1.2 信息配置类1.2.1 配置信息public class AlipayConfig { // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 public static String app_id = ""; // 商户应用私钥,您的PKCS8格式RSA2私钥 public static String merchant_private_key = ""; // 对应APPID下的支付宝公钥 。public static String alipay_public_key = ""; // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String notify_url = "http://localhost:8080(/项目名,没有的不需要)/Alipay/notify_url.do"; // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String return_url = "http://localhost:8080(/项目名,没有的不需要)/Alipay/alipay_return.do"; // 签名方式 public static String sign_type = "RSA2"; // 字符编码格式 public static String charset = "UTF-8"; // 支付宝网关 public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";}1.2.2配置信息来源登录自己已经入驻的支付宝账号:https://open.alipay.com/develop/sandbox/app
1.2.2.1 APPID
文章插图
1.2.2.2 公钥,私钥
文章插图
1.3 支付控制层/** * 支付宝支付 */@Controller@RequestMapping("/Alipay")public class AlipayController { /** * 生成订单直接跳转支付宝付款 */ @RequestMapping("/to_alipay.do") public void toAlipay(HttpServletResponse response, HttpServletRequest request) throws Exception{ AlipayClient alipayClient = new DefaultAlipayClient( AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); // 取购买人名称 String in_name = request.getParameter("in_name"); // 取手机号 String in_phone = request.getParameter("in_phone"); // 创建唯一订单号 int random = (int) (Math.random() * 10000); String dateStr = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()); // 订单号拼接规则:手机号后四位+当前时间后四位+随机数四位数 String out_trade_no = in_phone.substring(7) + dateStr.substring(10) + random; // 拼接订单名称 String subject = in_name + "的订单"; // 取付款金额 String total_amount = request.getParameter("in_money"); // 设置请求参数 AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); alipayRequest.setReturnUrl(AlipayConfig.return_url);//支付成功响应后跳转地址 alipayRequest.setNotifyUrl(AlipayConfig.notify_url);//异步请求地址 /*FAST_INSTANT_TRADE_PAY 二维码瞬时支付 * out_trade_no 订单号 total_amount 订单金额 subject 订单名称 */ alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," + "\"total_amount\":\"" + total_amount + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\"" + ""+ "\"," + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}"); String result = "请求无响应"; // 请求 try { //通过阿里客户端,发送支付页面请求 result = alipayClient.pageExecute(alipayRequest).getBody(); response.setContentType("text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); response.getWriter().println(result); response.getWriter().flush(); } catch (AlipayApiException e) { e.printStackTrace(); } finally { response.getWriter().close(); } } /** * 支付成功后处理业务 */ @RequestMapping("/alipay_return.do") public String alipayReturn(HttpServletRequest request, Map<String, Object> map) throws Exception{ // 响应信息 String msg = ""; // 请在这里编写您的程序(以下代码仅作参考) if (verifyAlipayReturn(request)) {//验签成功后执行的自定义业务代码 // 商户订单号 String out_trade_no = new String(request.getParameter( "out_trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); // 支付宝交易号 String trade_no = new String(request.getParameter("trade_no") .getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); // 付款金额 String total_amount = new String(request.getParameter( "total_amount").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); msg = "支付宝交易号:" + trade_no + "<br/>商户订单号" + out_trade_no + "<br/>付款金额:" + total_amount; } else { msg = "验签/支付失败"; } map.put("msg", msg); return "forward:/success.jsp"; //支付完成后,跳转的页面 } /** * 支付宝异步通知 * @param request * @param response * @throws Exception */ @RequestMapping("/notify_url.do") public void alipayNotify(HttpServletRequest request,HttpServletResponse response) throws Exception { // ——请在这里编写您的程序(以下代码仅作参考)—— /* * 实际验证过程建议商户务必添加以下校验: 1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号, * 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), * 3、校验通知中的seller_id(或者seller_email) * 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email) * 4、验证app_id是否为该商户本身 。 */ if (verifyAlipayReturn(request)) {// 验证成功 // 商户订单号 String out_trade_no = new String(request.getParameter( "out_trade_no").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); System.out.println(out_trade_no); // 支付宝交易号 String trade_no = new String(request.getParameter("trade_no") .getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); System.out.println(trade_no); // 交易状态 String trade_status = new String(request.getParameter( "trade_status").getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); if (trade_status.equals("TRADE_FINISHED")) { // 判断该笔订单是否在商户网站中已经做过处理 // 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 // 如果有做过处理,不执行商户的业务程序 // 注意: // 退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 } else if (trade_status.equals("TRADE_SUCCESS")) { // 判断该笔订单是否在商户网站中已经做过处理 // 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 // 如果有做过处理,不执行商户的业务程序 // 注意: // 付款完成后,支付宝系统发送该交易状态通知 } } else {// 验证失败 response.setContentType("text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); response.getWriter().println("验签/支付失败!"); response.getWriter().flush(); response.getWriter().close(); // 调试用,写文本函数记录程序运行情况是否正常 // String sWord = AlipaySignature.getSignCheckContentV1(params); // AlipayConfig.logResult(sWord); } } /** * @author zhukang * @date 2021-04-23 * @return * @description 验证支付宝的反馈信息 */ private boolean verifyAlipayReturn(HttpServletRequest request) throws UnsupportedEncodingException { // 获取支付宝回调反馈的信息 Map<String, String> params = new HashMap<>(); 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] + ","; } // 乱码解决,这段代码在出现乱码时使用 valueStr = new String(valueStr.getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8); params.put(name, valueStr); } boolean signVerified = false; try {// 调用SDK验证签名 signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); } catch (AlipayApiException e) { e.printStackTrace(); } return signVerified; }}
经验总结扩展阅读
- 世界上的五大人种
- 佐助五影会谈第几集
- 动森五一活动迷宫攻略
- 支付宝蚂蚁庄园10月28日答提分享
- 主力建仓时的五大特征是什么
- 四大名山和五岳在哪
- 支付宝蚂蚁庄园10月28日答案是什么
- 如何删除支付宝的帐户明细
- 王者荣耀五杀限制时间是多久
- 如何制作梅干菜扣肉烧饼