首先要2个jar包
一个是alipay-sdk--java-4.9.79.ALL.jar
一个是aliyun-java-sdk-dysmsapi-1.0.0
基本配置信息:
公共配置区:
package com.zhetian.www.alibaba; import java.io.FileWriter; import java.io.IOException; /** * @Copyright (C)遮天网络有限公司 * @Author: YUAN HUAI XING * @Date 2020/3/31 17:34 * @Descripthion: **/ public class AlipayConfig{ //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 public static String app_id = ""; // 商户私钥,您的PKCS8格式RSA2私钥 public static String merchant_private_key =""; // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 public static String alipay_public_key = ""; // 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String notify_url = ""; // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 public static String return_url = ""; // 签名方式 public static String sign_type = "RSA2"; // 字符编码格式 public static String charset = "utf-8"; // 支付宝网关 public static String gatewayUrl ="http://openapi.alipaydev.com/gateway.do"; // 支付宝网关 public static String log_path = "C:\\"; //↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑ /** * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库) * @param sWord 要写入日志里的文本内容 */ public static void logResult(String sWord) { FileWriter writer = null; try { writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt"); writer.write(sWord); } catch (Exception e) { e.printStackTrace(); } finally { if (writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
package com.zhetian.www.alibaba; import com.alipay.api.AlipayClient; import com.alipay.api.DefaultAlipayClient; /** * @Copyright (C)遮天网络有限公司 * @Author: YUAN HUAI XING * @qq联系方式: 11234013 * @Date 2020/4/10 21:28 * @Descripthion: **/ public class AlipayInstance { /** * @return * @throws Exception */ public static AlipayClient createAlipayClient(){ AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type); return alipayClient; } }
调用PC端支付宝支付类:
package com.zhetian.www.alibaba; 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.alipay.api.response.AlipayTradePagePayResponse; import java.util.HashMap; /** * @Copyright (C)遮天网络有限公司 * @Author: YUAN HUAI XING * @Date 2020/3/31 18:34 * @Descripthion: **/ public class AliPayServer { public String pay(String orderOn, Integer productPrice, String productName) 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); //设置请求参数 AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest(); alipayRequest.setReturnUrl(AlipayConfig.return_url); //设置同步回调通知 alipayRequest.setNotifyUrl(AlipayConfig.notify_url); //设置异步回调通知 //设置支付参数 HashMap
支付接口业务层:新增一个订单(订单状态为等待支付)
/** * 新增一个订单 * @param order */ @Override public Result saveOrder(Integer userId, Integer productId, Order order, HttpServletRequest request) throws Exception { Result result = new Result<>(); //1.接收产品id Product product = productDao.ProductById(productId); //2.根据产品id,获取产品价格,产品名称 String productName = product.getProductName(); Integer productPrice = product.getProductPrice(); // 1-等待支付,2-支付成功,3-支付失败 String state ="1"; //创建订单 //3.创建订单 支付状态 等待支付 String orderNo = getorderNo(); HttpSession session = request.getSession(); session.setAttribute("orderNo",orderNo); //用户id order.setUserId(userId); //产品id order.setProductId(productId); //产品订单号 order.setOrderOn(orderNo); //产品名称 order.setProductName(productName); //产品价格 order.setProductPrice(productPrice); //购买数量 Integer buyNum = order.getBuyNum(); //实际价格=产品价格*购买数量 Integer paymentPrice=productPrice*buyNum; order.setPaymentPrice(paymentPrice); //产品状态 order.setState(state); DateTime dateTime = new DateTime(); String date = String.valueOf(dateTime); //修改时间 order.setCreateTime(date); Integer productNum = product.getProductNum(); if (buyNum>productNum){ result.setCode("0001"); result.setMsg("购买量超出库存量!购买失败!"); result.setSuccess(false); return result; }else { orderDao.saveOrder(order); //4.向支付宝获取支付信息 AliPayServer aliPayServer = new AliPayServer(); String pay = aliPayServer.pay(orderNo, paymentPrice, productName); JSONObject jsonObject = JSON.parseObject(pay); String body = jsonObject.getString("body"); result.setData(body); } return result; }
同步回调异步回调接口:
package com.zhetian.www.controller; import cn.hutool.core.date.DateTime; import com.alipay.api.internal.util.AlipaySignature; import com.zhetian.www.alibaba.AliTradequery; import com.zhetian.www.alibaba.AlipayConfig; import com.zhetian.www.common.Result; import com.zhetian.www.model.Order; import com.zhetian.www.service.IOrderService; import com.zhetian.www.service.IProductService; import com.zhetian.www.service.impl.OrderService; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import java.util.*; import static com.zhetian.www.alibaba.AlipayConfig.alipay_public_key; import static java.lang.Thread.sleep; @Controller @RequestMapping("/callback") public class PayCallBackController { @Autowired private IOrderService orderService; @Autowired private IProductService productService; /** * 同步回调 * * @param request * @throws Exception */ @ResponseBody @RequestMapping("/returnUrl") public ModelAndView returnUrl(HttpServletRequest request) throws Exception { ModelAndView mav = new ModelAndView(); System.out.println("前往支付成功页面"); mav.setViewName("/tick/list"); return mav; } /** * 支付宝服务器异步通知 * * @param request * @throws Exception */ @RequestMapping("/notifyUrl") @ResponseBody public String notifyUrl(HttpServletRequest request) throws Exception { // 获取支付宝GET过来反馈信息 Mapparams = new HashMap (); Map requestParams = request.getParameterMap(); for (Iterator 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, alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); // 调用SDK验证签名 if (signVerified) { // 验证成功 更新订单信息 System.out.println("异步通知成功"); // 1.商户订单号 String orderOn = request.getParameter("out_trade_no"); // // 2.交易状态 String trade_status = request.getParameter("trade_status"); if (trade_status.equals("TRADE_SUCCESS")) { //3.订单号和支付状态修改订单 // 根据订单号修改订单状态为2,并添加一个修改日期 Order order = new Order(); order.setState("2"); DateTime dateTime = new DateTime(); String datetime = String.valueOf(dateTime); order.setUpdateTime(datetime); order.setOrderOn(orderOn); orderService.updaetOrder(order); //根据订单号查询该订单的产品id Order order1 = orderService.orderByOrderOn(orderOn); //产品id Integer productId = order1.getProductId(); //购买数量 Integer buyNum = order1.getBuyNum(); //调用修改产品方法 productService.updateProduct(productId, buyNum); return "success"; }else { Order order = new Order(); order.setState("3"); DateTime dateTime = new DateTime(); String datetime = String.valueOf(dateTime); order.setUpdateTime(datetime); order.setOrderOn(orderOn); orderService.updaetOrder(order); return "fail"; } } else { System.out.println("异步通知失败"); return "fail"; } } }
定时任务要在ssm里面配置:
xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd
线下查询接口(定时任务 写在另外一个项目 ):
@Component public class PayCallBackController { @Autowired private IOrderService orderService; /** * 查询接口 * * @param * @throws Exception */ @Scheduled(cron="* */9 * * * ?")//每隔3秒隔行一次 public void tradequery() { System.out.println("查询开始"); orderService.handleOrderPay(); System.out.println("查询结束"); } }
定时查询接口业务层:
@Override public void handleOrderPay() { // 1.定时(每10分钟)查询订单超过10分钟没支付成功 (条件:1.超过10分钟 2.状态为:2)==》订单号 String state = "1"; Listorders = orderDao.orderstateDate(state); // 2. 循环调用--》调支付宝接口查询订单实际支付状态 for (int i=0;i ) { Order order = orders.get(i); String orderOn = order.getOrderOn(); AliTradequery aliTradequery = new AliTradequery(); System.out.println("查询订单号:" + orderOn); Boolean statusAli = aliTradequery.traderefundData(orderOn); // 3. 根据是否成功更新订单 // 修改数据库 Order orderUpdate = new Order(); // 1.正在支付,2成功,3失败 String statusNew = "2"; if (!statusAli){ statusNew="3"; } orderUpdate.setState(statusNew); DateTime dateTime = new DateTime(); String datetime = String.valueOf(dateTime); orderUpdate.setUpdateTime(datetime); orderUpdate.setOrderOn(orderOn); orderDao.updaetOrder(orderUpdate); } }
根据state(状态)并且订单创建时间十分钟内的订单进行查询sql语句:
FROM `order` WHERE state=1 AND createtime>=CURRENT_TIMESTAMP - INTERVAL 10 MINUTE
@注:本博客仅为个人学习笔记。 所属人:Yuan