对接支付宝支付的前提:
1,商户开通支付能力
登录蚂蚁金服 开放平台:https://open.alipay.com/platform/home.htm
需要开通 的功能选项有:
创建应用,类型是:网页&移动应用
设置应用的RSA 等各项参数,界面如下:
支付宝推荐使用RSA2 加密方式,老版的加密方式只有RSA 和md5,没有RSA2.
本项目使用RSA2 加密方式
2,对接支付宝依赖的jar包
<!-- https://mvnrepository.com/artifact/net.guerlab/sdk-alipay-core -->
<dependency>
<groupId>net.guerlab</groupId>
<artifactId>sdk-alipay-core</artifactId>
<version>1.0.3</version>
</dependency>
我写了一个专门封装对接支付宝的Service 层
见代码:https://gitee.com/kunlunsoft/pay_service.git
项目结构:
发起支付 控制器(需根据实际情况修改):
下面的"/order/startPay"接口
package com.girltest.web.controller.pay; import com.common.annotation.NoLogin; import com.common.bean.BaseResponseDto; import com.common.dict.Constant2; import com.common.util.RedisHelper; import com.common.util.SystemHWUtil; import com.girltest.dao.AlipayNotifySuccessDao; import com.girltest.dao.BusinessOrderDao; import com.girltest.entity.BusinessOrder; import com.house.ujiayigou.thirdpart.alipay.config.AlipayConfig; import com.house.ujiayigou.thirdpart.alipay.info.PayFormInfo; import com.string.widget.util.RandomUtils; import com.string.widget.util.ValueWidget; import com.time.util.TimeHWUtil; import com.yunmasoft.service.pay.AlipayNotifySuccessService; import com.yunmasoft.service.pay.alipay.AliPayService; import com.yunmasoft.service.pay.alipay.PayOperation; import com.yunmasoft.service.pay.alipay.PayService; import oa.entity.AlipayNotifySuccess; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.math.BigDecimal; import java.util.Date; /** * Created by tonyjiang on 15/8/28. */ @Controller public class PayOrderController { @Resource(name = "alipay") private AliPayService aliPayService; public static org.slf4j.Logger HttpClientRestLogger = LoggerFactory.getLogger("pay_log"); // @Resource // private OrderDetailViewModel orderDetailViewModel; @Resource private AlipayNotifySuccessDao alipayNotifySuccessDao; @Resource private AlipayNotifySuccessService alipayNotifySuccessService; @Resource private BusinessOrderDao businessOrderDao; /*** * 抹掉小数点后面的零头 * * @param orderPrice * @return */ private static String removeDecimalPoint(BigDecimal orderPrice) { String formatPrice = ValueWidget.formatBigDecimal(orderPrice); return formatPrice; } private static void checkOrderStatus(int orderStatus) { if (orderStatus == Constant2.ORDERSTATUS_PAID_ALREADY) { //支付完成,调到支付成功页 // LogicBusinessException.throwException("alreadyPaid"); } else if (orderStatus == Constant2.ORDERSTATUS_CANCELLED) { //已经取消了订单 // LogicBusinessException.throwException("alreadyCancel"); } } /*** * 通过redis 获取订单的支付结果:是否支付成功 * @param request * @param response * @param httpSession * @param model * @param orderNo * @return */ @RequestMapping("/order/payOrderResult") @ResponseBody public String getOrderPayResult(HttpServletRequest request, HttpServletResponse response, HttpSession httpSession, Model model, @RequestParam(value = "orderNo", required = true) String orderNo) { BaseResponseDto baseResponseDto = new BaseResponseDto(PayService.isPaySuccess(orderNo)); return baseResponseDto.toJson(); } /*** * 下单页 * @param model * @param request * @param response * @param release * @return */ @RequestMapping(value = "/order/place", produces = SystemHWUtil.RESPONSE_CONTENTTYPE_JSON_UTF) public String json2(Model model, HttpServletRequest request, HttpServletResponse response , @RequestParam(required = false, defaultValue = "true") Boolean release) { String orderNo = "Xr20001" + RandomUtils.getNextInt(); model.addAttribute("orderNo", orderNo); return "pay/wap/placeorder"; } /*** * 步骤: * 1,获取当前用户信息 * 2,根据订单号查询订单详情 * 3,校验订单状态和支付方式 * 4,跳转到第三方支付 * @param request * @param response * @param httpSession * @param model * @param orderNo * @param callback * @return * @throws Exception */ @RequestMapping("/order/startPay") @NoLogin public String startPay(HttpServletRequest request, HttpServletResponse response, HttpSession httpSession, Model model, @RequestParam(value = "orderNo", required = true) String orderNo, @RequestParam(value = "callback", required = false) String callback , BigDecimal shouldPay) throws Exception { //p判断该订单号是否已经存在 AlipayNotifySuccess alipayNotifySuccess = this.alipayNotifySuccessService.getAlipayNotifySuccess(orderNo); if (null != alipayNotifySuccess) { model.addAttribute("errorMessage", "该订单号已经存在,orderNo:" + orderNo); return "pay/alipay"; } // 判断订单号是否存在 BusinessOrder businessOrder = this.businessOrderDao.get("orderNo", orderNo); if (null == businessOrder) { model.addAttribute("errorMessage", "该订单号不存在,orderNo:" + orderNo); return "pay/alipay"; } /* //保存订单 businessOrder = new BusinessOrder(); businessOrder.setOrderNo(orderNo); businessOrder.setTotalPrice(shouldPay); CreateTimeUtil.fillTime(businessOrder); this.businessOrderDao.add(businessOrder);*/ //获取当前用户信息 //7.应付金额 String strShouldPay = null; if (ValueWidget.isNullOrEmpty(shouldPay)) { shouldPay=businessOrder.getPrice(); } strShouldPay = ValueWidget.formatBigDecimal(shouldPay); //8. 账户 String sellerAccount = AlipayConfig.seller_email; //9.其它 // RedisHelper.getInstance().saveKeyCache(PayService.REDIS_KEY_STORE_ORDER_PAY_TIME, orderNo, TimeHWUtil.formatDate(new Date(), TimeHWUtil.YYYYMMDD_NO_LINE)); String orderName = businessOrder.getProductBaseInfo().getDisplayName(); //10. com.house.ujiayigou.thirdpart.alipay.info.PayFormInfo payFormInfo = new PayFormInfo(); payFormInfo.setOut_trade_no(orderNo); payFormInfo.setSubject(orderName); payFormInfo.setBody(orderName); payFormInfo.setTotal_amount(strShouldPay); payFormInfo.setSeller_id(sellerAccount); String form = aliPayService.preparePostRequest(payFormInfo); HttpClientRestLogger.error("form:" + form); model.addAttribute("form", form); return "pay/alipay"; } /** * 1,获取订单; * 2,价格; * 3,Identify; * 4,第三方支付相关接口service; * 5,callback * 6,coupon * 7,应付金额 * 8,账户 * 9,其它 * 10, * * @param access_token * @param orderNo * @param payType * @param callback * @return */ public String postThirdPayAction(String access_token, String orderNo, String payType, String callback) { //订单 /* OrderInfoBean orderInfo = orderBusiness.getOrderInfoByOrderNo(access_token, orderNo); if (orderInfo == null || orderInfo.getItems().size()==0) { LogicBusinessException.throwException("cannotMatchOrder"); } checkOrderStatus(orderInfo.orderStatus); if (orderInfo.orderStatus != Constant.ORDERSTATUS_ORDERS_SUBMITTED) { LogicBusinessException.throwException("20506"); }*/ //2.价格 BigDecimal price = null;//orderBusiness.getOrderMoney(orderInfo); if (price == null) { // LogicBusinessException.throwException("cannotPay"); } //3.Identify String identifier = null;//orderBusiness.getPayIdentify(orderNo, access_token, userInfo, price); PayOperation service = null;//(PayOperation) SpringMVCUtil.getBean( payType); if (service == null) { // LogicBusinessException.throwException("service is null"); } //5.callback if (ValueWidget.isNullOrEmpty(callback)) { callback = "https:/order/view?orderNo=" + orderNo /*+ "&orgId=" + orgId*/;//千万不要URL转码 } //6.coupon BigDecimal coupon = null; /*if (Constant.useDebugCouponValue) { coupon = new BigDecimal(Constant.couponValue); } else {*/ coupon = new BigDecimal(0); // } //7.应付金额 BigDecimal shouldPay = price.subtract(coupon.compareTo(price) < 0 ? coupon : new BigDecimal(0));// String strShouldPay = ValueWidget.formatBigDecimal(shouldPay); //8. 账户 String sellerAccount = AlipayConfig.seller_email; //9.其它 RedisHelper.getInstance().saveKeyCache(PayService.REDIS_KEY_STORE_ORDER_PAY_TIME, orderNo, TimeHWUtil.formatDate(new Date(), TimeHWUtil.YYYYMMDD_NO_LINE)); String orderName = "xxx服务"; //10. com.house.ujiayigou.thirdpart.alipay.info.PayFormInfo payFormInfo = new PayFormInfo(); payFormInfo.setOut_trade_no(orderNo); payFormInfo.setSubject(orderName); payFormInfo.setBody(orderName); payFormInfo.setTotal_amount(strShouldPay); payFormInfo.setSeller_id(sellerAccount); String form = service.preparePostRequest(payFormInfo); return form; } }
支付回调控制器(需根据实际情况修改):
下面的"/notify"接口
import com.common.dict.Constant2; import com.common.util.*; import com.yunmasoft.service.pay.alipay.PayOperation; import com.io.hw.json.HWJacksonUtils; import com.string.widget.util.ValueWidget; import oa.util.SpringMVCUtil; import org.apache.log4j.Logger; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Map; @Controller @RequestMapping("/pay") public class PayController { public static Logger logger = Logger.getRootLogger(); @RequestMapping(value = "notify", produces = {SystemHWUtil.RESPONSE_CONTENTTYPE_JSON_UTF}) @ResponseBody public String callback( @RequestParam(required = false) String method, @RequestParam(required = false) String out_trade_no/*订单号*/, @RequestParam(required = false) String trade_no, @RequestParam(required = false) String trade_status, @RequestParam(required = false) String extra_common_param, @RequestParam(required = false) String notifyUrl, @RequestParam(required = false) String body/*只有支付宝手机网站支付才有*/, HttpServletResponse response, HttpServletRequest request) { //userIdAndLoginnameAndOrgId 在请求参数中 // 1.获取订单号 if (ValueWidget.isNullOrEmpty(out_trade_no)) { out_trade_no = request.getParameter("outer_trade_no"); } // 2.畅捷支付没有extra_common_param,兼容畅捷支付 if (ValueWidget.isNullOrEmpty(extra_common_param) && !ValueWidget.isNullOrEmpty(notifyUrl)) {//added by huangweii Map argMap = RequestUtil.parseQueryString(notifyUrl); extra_common_param = (String) argMap.get("chanpay"); } logger.info(HWJacksonUtils.getJsonP(request.getParameterMap())); // 3.兼容extra_common_param为空的情况 boolean isAlipayMobile = false; if (ValueWidget.isNullOrEmpty(extra_common_param)) {//added by huangweii,extra_common_param为空,说明是xx支付 String extra_common_paramSuffix = RedisHelper.getInstance().getCache("store_" + out_trade_no + "_Identifier") + "::" + RedisHelper.getInstance().getCache("store_" + out_trade_no + "_userinfo"); if (ValueWidget.isNullOrEmpty(request.getParameter("out_trade_no"))) { extra_common_param = "chanpay::" + extra_common_paramSuffix; } else { isAlipayMobile = true; extra_common_param = "alipay::" + extra_common_paramSuffix; } } // 4. 缓存日志 // String currentCache = RedisHelper.getInstance().getKeyCache(Constant.REDIS_ID_STORE, out_trade_no) + "<br>"; // RedisHelper.getInstance().saveKeyCacheAndExpire(Constant.REDIS_ID_STORE, out_trade_no, currentCache +request.getRequestURI()+ extra_common_param + ",notifyUrl:" + notifyUrl); logger.info("extra_common_param:" + extra_common_param); // 获取支付宝POST过来反馈信息 Map requestParams = request.getParameterMap(); Map<String, String> params = WebServletUtil.getParamMap(requestParams); // params.put("userIdAndLoginnameAndOrgId", userIdAndLoginnameAndOrgId); // 5.获取service PayOperation service = null; if (extra_common_param != null && extra_common_param.contains("::")) { String[] info = extra_common_param.split("::"); service = (PayOperation) SpringMVCUtil.getBean(request, info[0]); } if (service == null) { return "fail"; } // 6.验签 String verity_ok = service.verify(WebServletUtil.getParamMap(requestParams)); if (!verity_ok.equals("success")) { logger.error(params.toString()); logger.error("verify fail"); return verity_ok; } // 7. 缓存日志 // currentCache = RedisHelper.getInstance().getKeyCache(Constant.REDIS_ID_STORE, out_trade_no) + "<br>"; // RedisHelper.getInstance().saveKeyCacheAndExpire(Constant.REDIS_ID_STORE, out_trade_no, currentCache + "verity->" + verity_ok); // 8.回调,调用确认订单接口 try { String pay_ok = service.payNotify(out_trade_no, trade_no, trade_status, params); if (pay_ok != null) { logger.debug(pay_ok + ""); return pay_ok; // 请不要修改或删除 } } catch (Exception ex) { logger.error("payNOtify error:", ex); return "fail"; } return "fail"; } @RequestMapping(value = "payResult") public String getPaymentResult(@RequestParam(required = false) String orderid, @RequestParam(required = false) String userid, HttpServletRequest request, HttpServletResponse response, Model model) throws IOException { logger.info("payResult orderid:" + orderid); // 获取支付宝POST过来反馈信息 Map requestParams = request.getParameterMap(); Map<String, String> params = WebServletUtil.getParamMap(requestParams); String orderId = orderid; if (ValueWidget.isNullOrEmpty(orderId)) { orderId = params.get("orderid"); } if (orderId == null) { orderId = params.get("out_trade_no"); } //畅捷支付点击[返回商家] TODO if (orderId == null) { orderId = params.get("orderId"); } logger.info("payResult params:" + params); String payResult = params.get("payResult"); String extra_common_param = params.get("extra_common_param"); logger.info("payResult extra_common_param:" + extra_common_param); if (!Constant2.CHANPAY_ORDER_RESULT_SUCCESS.equals(payResult)) { response.sendRedirect("/order/payOrder?orderId=" + orderId /*+ "&orgId=" + service.getOrgId(orderId)*/); return null; } response.sendRedirect("/order/payComplete?orderId=" + orderId /*+ "&orgId=" + service.getOrgId(orderId)*/); return null; } }
实际支付demo:
各文档:
电脑网站支付快速接入
https://docs.open.alipay.com/270/105899/
API 详细说明:
https://docs.open.alipay.com/270/alipay.trade.page.pay/
服务端SDK
https://docs.open.alipay.com/54/103419
RSA私钥及公钥生成
https://docs.open.alipay.com/58/103242/
RSA私钥及公钥生成 工具:
https://gitee.com/kunlunsoft/http_request_tool
上图中2048 对应RSA2
相关项目:
https://github.com/liuyu520/io0007
https://gitee.com/kunlunsoft/oa_framework
注意:
1,本项目使用新版支付宝支付
即时到账新老版本接口对比
https://docs.open.alipay.com/270/106759
2,新版支付宝支付,就算仅使用PC端网页支付,也需要创建一个应用,老版不需要.
3,电脑端网页支付应该使用:
AlipayTradePagePayRequest,而不是AlipayTradePayRequest;
4,对业务参数(非公共参数),进行 json 序列化时,
一定使用阿里自己的类:
JSONWriter writer = new JSONWriter();
String body=writer.write(model, true);
相关推荐
java对接支付宝
Java对接支付宝支付Demo是一个典型的在线支付集成案例,主要用于帮助开发者快速理解并实现Java应用程序与支付宝接口的对接。在这个Demo中,我们通常会涉及到以下几个关键知识点: 1. **支付宝开放平台API**:支付宝...
在Java开发中,对接支付宝支付是一项常见的任务,尤其对于电商或者服务类网站来说更是必不可少的功能。这个项目提供了直接运行的代码示例,帮助开发者快速理解和实现支付宝的沙箱环境支付功能,无需进行复杂的配置和...
java对接微信/支付宝支付,全套代码包括退款,统一app支付,统一网站支付,统一公众号支付,依赖,实体类,工具类,复制粘贴即可用
Alipay SDK:支付宝提供了Java版的SDK,可以帮助我们快速集成支付宝支付功能。通过Alipay SDK,我们可以实现支付宝的即时到账、手机网站支付、扫码支付等功能。2. Wechat Pay SDK:微信支付也提供了Java版的SDK,...
本文将详细解析“商户对接支付宝支付”的相关知识点,帮助开发者更好地理解和实施这一过程。 一、支付宝支付概述 支付宝是由阿里巴巴集团旗下的蚂蚁金服提供的一种第三方在线支付服务。它为商家和消费者提供了一个...
Java微信支付宝支付DEMO是一个用于演示如何在Java环境中集成微信和支付宝支付功能的项目。这个DEMO可以帮助开发者快速理解和实现在线支付的流程,为电子商务、移动应用或其他需要处理在线交易的平台提供技术支持。 ...
- **SDK使用**:支付宝提供`alipay.trade.app.pay`接口,用于生成支付宝支付二维码或者唤起支付宝客户端进行支付。需要传递的商品信息、金额、回调地址等参数通过签名机制打包成JSON格式的请求字符串。 - **签名...
java对接支付宝需要的包_alipay java支付宝很简单,也可以从官网下载。
已对接`支付宝`服务商和普通商户接口,支持RSA和RSA2签名 已对接`云闪付`服务商接口,可选择多家支付机构 提供http形式接口,提供各语言的`sdk`实现,方便对接 接口请求和响应数据采用签名机制,保证交易安全可靠 ...
Java支付宝扫码支付是一种常见的在线支付方式,主要用于移动设备上的交易。在Java开发环境中,我们可以利用支付宝提供的SDK(Software Development Kit)来实现扫码支付的功能。这个SDK包含了一系列的接口和类库,...
1. 引入支付宝SDK:首先,你需要下载或通过Maven/Gradle引入支付宝的JAVA SDK,这个包包含了调用接口所需的所有类和方法。 2. 初始化配置:创建一个AlipayClient对象,设置AppID、商户私钥、支付宝公钥、签名类型等...
支付宝APP支付Java版是支付宝为开发者提供的一种便捷的在线支付接口,主要应用于移动应用中的商品购买、服务费用收取等场景。在Java环境下实现支付宝APP支付,开发者需要掌握以下几个关键知识点: 1. **集成SDK**: ...
二、对接多种通道:支付宝,微信,拉卡拉,盛付通,瑞银信等第三方支付公司 三、可开通小微商户,当面付,银联快捷等功能,刷脸支付,聚合支付,支持硬件:扫码枪、云喇叭、扫印机、刷脸设备(小蜻蜓、小青蛙) 四...
Java实现支付宝、微信、银联支付项目实例源码
这就对开发者增加了一定的难度,因为产品没有上线,然后需要对接支付宝接口就是很大的问题,所以出现了沙箱环境,具有虚拟的用户和管理员账户,进行实验测试是否对接成功。接下来就根据我的经验,简单的介绍一下我的...
支付宝提供了一套名为Alipay SDK的API接口,用于在Java应用中集成支付宝支付。SDK包含了处理订单创建、支付请求、支付结果查询等功能的类和方法。开发者需要获取到支付宝的商户ID、应用ID、私钥等安全信息,并在代码...
《支付宝对接文档(for Java)详解》 在现代电子商务领域,支付宝作为国内领先的第三方支付平台,其接口对接工作对于开发者来说至关重要。本篇文章将详细解析基于Java的支付宝对接过程,包括核心概念、步骤以及如何...
这些接口允许开发者在自己的应用或网站上集成支付宝支付功能,为用户提供安全、便捷的支付体验。 首先,我们来了解一下"标准双接口"。标准双接口是支付宝提供的一种常见的支付方式,它包含了“即时到账”和“担保...