All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
net.mingsoft.pay.action.web.AlipayAction Maven / Gradle / Ivy
/**
* Copyright (c) 2012-present 铭软科技(mingsoft.net)
* 本软件及相关文档文件(以下简称“软件”)的版权归 铭软科技 所有
* 遵循 铭软科技《服务协议》中的《保密条款》
*/
package net.mingsoft.pay.action.web;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alipay.api.*;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import net.mingsoft.base.entity.ResultData;
import net.mingsoft.basic.util.BasicUtil;
import net.mingsoft.basic.util.StringUtil;
import net.mingsoft.mdiy.util.ConfigUtil;
import net.mingsoft.pay.action.BaseAction;
import net.mingsoft.pay.bean.PayBean;
import net.mingsoft.pay.biz.IPayLogBiz;
import net.mingsoft.pay.constant.Const;
import net.mingsoft.pay.entity.PayLogEntity;
import net.mingsoft.pay.entity.PayLogEntity.LogStatusEnum;
import net.mingsoft.pay.entity.PayLogEntity.LogTypeEnum;
import net.mingsoft.pay.util.PayUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
/**
* 支付宝支付接口
*/
@Api(tags = {"前端-支付模块接口"})
@Controller
@RequestMapping("/mpay/alipay")
public class AlipayAction extends BaseAction {
/**
* 交易记录
*/
@Autowired
private IPayLogBiz payLogBiz;
@ApiOperation(value = "支付宝回调接口")
@SuppressWarnings("rawtypes")
@PostMapping("/notify")
@ResponseBody
public ResultData notify(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException {
// 获取支付宝POST过来反馈信息
Map params = new HashMap();
Map requestParams = request.getParameterMap();
LOG.info("requestParams {}",JSONUtil.toJsonStr(requestParams));
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
String name = (String) iter.next();
LOG.info("name {}",JSONUtil.toJsonStr(requestParams.get(name)));
String valueStr = "";
if (requestParams.get(name) instanceof String[]) {
String[] values = (String[]) requestParams.get(name);
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
}else {
valueStr = (String) requestParams.get(name);
}
// 乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
params.put(name, valueStr);
}
// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
// 商户订单号
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
String price = request.getParameter("total_amount");
String logTitle = request.getParameter("subject");
//公用回传参数
String passextraCommonParamback = request.getParameter("passback_params");
// 支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
// 交易状态
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"), "UTF-8");
// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
LOG.debug("支付回调");
Map alipayConfig = ConfigUtil.getMap(Const.ALIPAY_PAY_CONFIG_NAME);
//app支付验证标记
//网站支付验证标记
boolean flag = false;
//验证一次就会消耗sign
flag = AlipaySignature.rsaCheckV1(params, alipayConfig.get("payAlipayPublicKey"), "utf-8", "RSA2");
if (flag) {
// 验证成功
// ////////////////////////////////////////////////////////////////////////////////////////
// 请在这里加上商户的业务逻辑程序代码
// ——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
LOG.debug("支付回调成功");
PayLogEntity payLog = new PayLogEntity();
payLog.setOrderNo(out_trade_no);
PayLogEntity newPayLog = (PayLogEntity) payLogBiz.getEntity(payLog);
//TRADE_SUCCESS :交易支付成功、TRADE_FINISHED :交易结束,不可退款
if ("TRADE_FINISHED".equals(trade_status) || "TRADE_SUCCESS".equals(trade_status)) {
// 判断该笔订单是否在商户网站中已经做过处理
// 如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
// 如果有做过处理,不执行商户的业务程序
LOG.debug("支付回调订单:" + out_trade_no);
//回写日志,修改支付状态
if (newPayLog != null) {
if (StringUtils.equals(newPayLog.getLogStatus(), LogStatusEnum.UN_PAY.toString())) {
HashMap map = JSON.parseObject(URLDecoder.decode(passextraCommonParamback), HashMap.class);
newPayLog.setLogStatus(LogStatusEnum.PAY.toString());
newPayLog.setLogPayType(PayBean.Type.ALIPAY);
newPayLog.setLogDate(new Date());
newPayLog.setUpdateDate(new Date());
newPayLog.setLogTransactionId(trade_no);
newPayLog.setLogType(LogTypeEnum.OUTCOME.toString());
newPayLog.setPeopleId(map.get(Const.Attach.USER_ID).toString());
payLogBiz.updateEntity(newPayLog);
LOG.info("附加参数attach:{}会员编号{}", passextraCommonParamback, newPayLog.getPeopleId());
//根据扩展字段回调执行方法
if (StringUtils.isNotBlank(passextraCommonParamback)) {
PayUtil.callPayNotfiy(newPayLog, URLDecoder.decode(passextraCommonParamback));
}
}
}
return ResultData.build().success(newPayLog);
// 注意:
// 该种交易状态只在两种情况下出现
// 1、开通了普通即时到账,买家付款成功后。
// 2、开通了高级即时到账,从该笔交易成功时间算起,过了签约时的可退款时限(如:三个月以内可退款、一年以内可退款等)后。
}
LOG.debug("支付回调成功,支付状态trade_status:{}验证失败", trade_status);
return ResultData.build().error(this.getResString("pay.notify.fail"));
} else {// 验证失败
LOG.debug("支付回调订单失败:");
return ResultData.build().error(this.getResString("pay.notify.verification.fail"));
}
}
@ApiOperation(value = "支付宝支付接口,只提供网关调用/mpay/pay/gateway")
@RequestMapping(value = "/pay", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public ResultData pay(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
//https://docs.open.alipay.com/62/104744/ 即时到账文档
PayBean pay = (PayBean) request.getAttribute("pay");
String notifyUrl = pay.getNotifyUrl();
// 把请求参数打包成数组
Map sParaTemp = new HashMap();
if (StringUtils.isBlank(notifyUrl)) {
notifyUrl = BasicUtil.getApp().getAppHostUrl() + net.mingsoft.pay.constant.Const.ALIPAY_NOTIFY_URL;
}
AlipayRequest pagePayRequest;
AlipayTradePagePayModel model = new AlipayTradePagePayModel();
if (this.isMobileDevice(request)) {// 判断是否是手机端
pagePayRequest = new AlipayTradeWapPayRequest();
model.setProductCode("QUICK_WAP_PAY");
} else {
pagePayRequest = new AlipayTradePagePayRequest();
model.setProductCode("FAST_INSTANT_TRADE_PAY");
}
pagePayRequest.setNotifyUrl(notifyUrl);
pagePayRequest.setReturnUrl(pay.getReturnUrl());
model.setOutTradeNo(pay.getOrderNo());
LOG.info("pay支付订单:{}", pay.getOrderNo());
model.setBody(pay.getOrderDesc());
model.setSubject(pay.getOrderName());
model.setTotalAmount(pay.getOrderPrice());
//该笔订单允许的最晚付款时间
model.setTimeoutExpress("100m");
if (ObjectUtil.isNotNull(pay.getAttach())) {
//公用回传参数
model.setPassbackParams(URLEncoder.encode(pay.getAttach(), "UTF-8"));
}
pagePayRequest.setBizModel(model);
LOG.debug("model参数:{}", JSONUtil.toJsonStr(model));
Map alipayConfig = ConfigUtil.getMap(Const.ALIPAY_PAY_CONFIG_NAME);
if (CollUtil.isEmpty(alipayConfig)) {
return ResultData.build().error(this.getResString("err.not.exist", this.getResString("bank.pay")));
}
//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(net.mingsoft.pay.constant.Const.ALIPAY_GATEWAY_URL,
alipayConfig.get("payAppId"),
alipayConfig.get("payAppPrivateKey"),
AlipayConstants.FORMAT_JSON, AlipayConstants.CHARSET_UTF8,
alipayConfig.get("payAlipayPublicKey"), AlipayConstants.SIGN_TYPE_RSA2);
try {
String body = alipayClient.pageExecute(pagePayRequest).getBody();
return ResultData.build().success(body);
} catch (AlipayApiException e) {
e.printStackTrace();
return ResultData.build().error(this.getResString("pay.notify.verification.fail"));
}
}
/**
* 支付宝app支付,只提供网关调用/mpay/pay/gateway
*
* @param request
* @param response
*/
@ApiOperation(value = "支付宝APP支付接口,只提供网关调用/mpay/pay/gateway")
@RequestMapping(value = "/appPay", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public ResultData appPay(HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
// 支付所有参数通过网关传递过来
PayBean pay = (PayBean) request.getAttribute("pay");
Map alipayConfig = ConfigUtil.getMap(Const.ALIPAY_PAY_CONFIG_NAME);
if (CollUtil.isEmpty(alipayConfig)) {
return ResultData.build().error(getResString("err.empty", this.getResString("pay.config")));
}
//实例化客户端
AlipayClient alipayClient = new DefaultAlipayClient(net.mingsoft.pay.constant.Const.ALIPAY_APP_PAY_URL,
alipayConfig.get("payAppId"),
alipayConfig.get("payAppPrivateKey"),
"json", "UTF-8",
alipayConfig.get("payAlipayPublicKey"), "RSA2");
//实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
AlipayTradeAppPayRequest payRequest = new AlipayTradeAppPayRequest();
//SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
//需要配合前端传递参数
model.setBody(pay.getOrderDesc());
//订单标题
model.setSubject(pay.getOrderName());
//订单号
model.setOutTradeNo(pay.getOrderNo());
//该笔订单允许的最晚付款时间
model.setTimeoutExpress("100m");
//支付金额
model.setTotalAmount(pay.getOrderPrice());
//销售产品码,商家和支付宝签约的产品码,为固定值
model.setProductCode("QUICK_MSECURITY_PAY");
//判断是否有其他信息参数
if (ObjectUtil.isNotNull(pay.getAttach())) {
//公用回传参数
model.setPassbackParams(URLDecoder.decode(pay.getAttach(), "UTF-8"));
}
payRequest.setBizModel(model);
if (StringUtils.isEmpty(pay.getNotifyUrl())) {
pay.setNotifyUrl(BasicUtil.getApp().getAppHostUrl() + net.mingsoft.pay.constant.Const.ALIPAY_NOTIFY_URL);
}
//支付回调
payRequest.setNotifyUrl(BasicUtil.getUrl() + pay.getNotifyUrl());
try {
//这里和普通的接口调用不同,使用的是sdkExecute
AlipayTradeAppPayResponse alipayTradeAppPayResponse = alipayClient.sdkExecute(payRequest);
return ResultData.build().success(alipayTradeAppPayResponse.getBody());
} catch (AlipayApiException e) {
e.printStackTrace();
return ResultData.build().error(this.getResString("pay.notify.verification.fail"));
}
}
}