java 对接支付宝支付
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
對(duì)接支付寶支付的前提:
1,商戶開(kāi)通支付能力
登錄螞蟻金服 開(kāi)放平臺(tái):https://open.alipay.com/platform/home.htm
需要開(kāi)通 的功能選項(xiàng)有:
創(chuàng)建應(yīng)用,類型是:網(wǎng)頁(yè)&移動(dòng)應(yīng)用
設(shè)置應(yīng)用的RSA 等各項(xiàng)參數(shù),界面如下:
支付寶推薦使用RSA2 加密方式,老版的加密方式只有RSA 和md5,沒(méi)有RSA2.
本項(xiàng)目使用RSA2 加密方式
2,對(duì)接支付寶依賴的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>?
我寫了一個(gè)專門封裝對(duì)接支付寶的Service 層
見(jiàn)代碼:https://gitee.com/kunlunsoft/pay_service.git
項(xiàng)目結(jié)構(gòu):
發(fā)起支付 控制器(需根據(jù)實(shí)際情況修改):
下面的"/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;@Resourceprivate AlipayNotifySuccessDao alipayNotifySuccessDao;@Resourceprivate AlipayNotifySuccessService alipayNotifySuccessService;@Resourceprivate BusinessOrderDao businessOrderDao;/**** 抹掉小數(shù)點(diǎn)后面的零頭** @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) {//支付完成,調(diào)到支付成功頁(yè) // LogicBusinessException.throwException("alreadyPaid");} else if (orderStatus == Constant2.ORDERSTATUS_CANCELLED) {//已經(jīng)取消了訂單 // LogicBusinessException.throwException("alreadyCancel");}}/**** 通過(guò)redis 獲取訂單的支付結(jié)果:是否支付成功* @param request* @param response* @param httpSession* @param model* @param orderNo* @return*/@RequestMapping("/order/payOrderResult")@ResponseBodypublic 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();}/**** 下單頁(yè)* @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,獲取當(dāng)前用戶信息* 2,根據(jù)訂單號(hào)查詢訂單詳情* 3,校驗(yàn)訂單狀態(tài)和支付方式* 4,跳轉(zhuǎn)到第三方支付* @param request* @param response* @param httpSession* @param model* @param orderNo* @param callback* @return* @throws Exception*/@RequestMapping("/order/startPay")@NoLoginpublic 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判斷該訂單號(hào)是否已經(jīng)存在AlipayNotifySuccess alipayNotifySuccess = this.alipayNotifySuccessService.getAlipayNotifySuccess(orderNo);if (null != alipayNotifySuccess) {model.addAttribute("errorMessage", "該訂單號(hào)已經(jīng)存在,orderNo:" + orderNo);return "pay/alipay";}// 判斷訂單號(hào)是否存在BusinessOrder businessOrder = this.businessOrderDao.get("orderNo", orderNo);if (null == businessOrder) {model.addAttribute("errorMessage", "該訂單號(hào)不存在,orderNo:" + orderNo);return "pay/alipay";} /*//保存訂單businessOrder = new BusinessOrder();businessOrder.setOrderNo(orderNo);businessOrder.setTotalPrice(shouldPay);CreateTimeUtil.fillTime(businessOrder);this.businessOrderDao.add(businessOrder);*///獲取當(dāng)前用戶信息//7.應(yīng)付金額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,價(jià)格;* 3,Identify;* 4,第三方支付相關(guān)接口service;* 5,callback* 6,coupon* 7,應(yīng)付金額* 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.價(jià)格BigDecimal price = null;//orderBusiness.getOrderMoney(orderInfo);if (price == null) { // LogicBusinessException.throwException("cannotPay");}//3.IdentifyString 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.callbackif (ValueWidget.isNullOrEmpty(callback)) {callback = "https:/order/view?orderNo=" + orderNo /*+ "&orgId=" + orgId*/;//千萬(wàn)不要URL轉(zhuǎn)碼}//6.couponBigDecimal coupon = null;/*if (Constant.useDebugCouponValue) {coupon = new BigDecimal(Constant.couponValue);} else {*/coupon = new BigDecimal(0); // }//7.應(yīng)付金額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服務(wù)";//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;}}支付回調(diào)控制器(需根據(jù)實(shí)際情況修改):
下面的"/notify"接口
package com.girltest.web.controller.pay;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})@ResponseBodypublic String callback(@RequestParam(required = false) String method,@RequestParam(required = false) String out_trade_no/*訂單號(hào)*/,@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/*只有支付寶手機(jī)網(wǎng)站支付才有*/,HttpServletResponse response,HttpServletRequest request) {//userIdAndLoginnameAndOrgId 在請(qǐng)求參數(shù)中// 1.獲取訂單號(hào)if (ValueWidget.isNullOrEmpty(out_trade_no)) {out_trade_no = request.getParameter("outer_trade_no");}// 2.暢捷支付沒(méi)有extra_common_param,兼容暢捷支付if (ValueWidget.isNullOrEmpty(extra_common_param) && !ValueWidget.isNullOrEmpty(notifyUrl)) {//added by huangweiiMap 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為空,說(shuō)明是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過(guò)來(lái)反饋信息Map requestParams = request.getParameterMap();Map<String, String> params = WebServletUtil.getParamMap(requestParams); // params.put("userIdAndLoginnameAndOrgId", userIdAndLoginnameAndOrgId);// 5.獲取servicePayOperation 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.驗(yàn)簽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.回調(diào),調(diào)用確認(rèn)訂單接口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; // 請(qǐng)不要修改或刪除}} 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過(guò)來(lái)反饋信息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");}//暢捷支付點(diǎn)擊[返回商家] TODOif (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;}}?
實(shí)際支付demo:
http://i.yhskyc.com/product/1
各文檔:
電腦網(wǎng)站支付快速接入
https://docs.open.alipay.com/270/105899/
API 詳細(xì)說(shuō)明:
https://docs.open.alipay.com/270/alipay.trade.page.pay/
服務(wù)端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 對(duì)應(yīng)RSA2
相關(guān)項(xiàng)目:
https://github.com/liuyu520/io0007
https://gitee.com/kunlunsoft/oa_framework
注意:
1,本項(xiàng)目使用新版支付寶支付
即時(shí)到賬新老版本接口對(duì)比
https://docs.open.alipay.com/270/106759
2,新版支付寶支付,就算僅使用PC端網(wǎng)頁(yè)支付,也需要?jiǎng)?chuàng)建一個(gè)應(yīng)用,老版不需要.
3,電腦端網(wǎng)頁(yè)支付應(yīng)該使用:
AlipayTradePagePayRequest,而不是AlipayTradePayRequest;
4,對(duì)業(yè)務(wù)參數(shù)(非公共參數(shù)),進(jìn)行 json 序列化時(shí),
一定使用阿里自己的類:
JSONWriter?writer = new JSONWriter();
String body=writer.write(model, true);
轉(zhuǎn)載于:https://my.oschina.net/huangweiindex/blog/1637847
總結(jié)
以上是生活随笔為你收集整理的java 对接支付宝支付的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2018最新大神教你用Python玩转数
- 下一篇: Python适合大数据处理吗?