支付宝申请创建应用,获取APPID、应用公钥、应用私钥、支付宝公钥、商户ID等。
具体可以参考官方文档资料:https://opendocs.alipay.com/open
支付参数配置
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
@Configuration
public class AlipayConfiguration {
@Value("${alipay.gateway_url}")
private String gatewayUrl = null;
@Value("${alipay.app_id}")
private String appId = null;
@Value("${alipay.app_private_key}")
private String appPrivateKey = null;
@Value("${alipay.alipay_public_key}")
private String alipayPublicKey = null;
@Value("${alipay.method}")
private String method = null;
@Value("${alipay.version}")
private String version = null;
@Value("${alipay.format}")
private String format = null;
@Value("${alipay.charset}")
private String charset = null;
@Value("${alipay.sign_type}")
private String signType = null;
@Value("${alipay.timeout}")
private String timeout = null;
@Value("${alipay.product_code}")
private String productCode = null;
@Value("${alipay.seller_id}")
private String sellerId = null;
@Value("${alipay.seller_email}")
private String sellerEmail = null;
@Value("${alipay.return_url}")
private String returnUrl = null;
@Value("${alipay.notify_url}")
private String notifyUrl = null;
@Bean
public AlipayClient alipayClient() {
return new DefaultAlipayClient(gatewayUrl, appId, appPrivateKey, format, charset, alipayPublicKey, signType);
}
public String getGatewayUrl() {
return gatewayUrl;
}
public String getAppId() {
return appId;
}
public String getAppPrivateKey() {
return appPrivateKey;
}
public String getAlipayPublicKey() {
return alipayPublicKey;
}
public String getMethod() {
return method;
}
public String getVersion() {
return version;
}
public String getFormat() {
return format;
}
public String getCharset() {
return charset;
}
public String getSignType() {
return signType;
}
public String getTimeout() {
return timeout;
}
public String getProductCode() {
return productCode;
}
public String getSellerId() {
return sellerId;
}
public String getSellerEmail() {
return sellerEmail;
}
public void setSellerEmail(String sellerEmail) {
this.sellerEmail = sellerEmail;
}
public String getReturnUrl() {
return returnUrl;
}
public String getNotifyUrl() {
return notifyUrl;
}
}
移动应用支付
接入流程可以参考官方文档:https://opendocs.alipay.com/open/204/105297
@ApiV1RestController
public class AlipayController {
private Logger LOG = LoggerFactory.getLogger(AlipayController.class);
@Resource(name = "alipayTerminalService")
private IAlipayService alipayTerminalService = null;
@RequestMapping(value = "/recharge/alipay/terminal", method = RequestMethod.POST)
public WebResult rechargeAlipayTerminal(Long rechargeItemId) {
WebResult webResult = new WebResult();
try {
webResult.setCode(ResultCode.SUCCESS.getCode());
webResult.setData(alipayTerminalService.mreadPaymentRequest(rechargeItemId));
} catch (BusinessException be) {
webResult.setCode(ResultCode.FAILURE.getCode());
webResult.setFailure(be.getDefaultMessage());
} catch (Exception e) {
webResult.setCode(ResultCode.SYSTEM_IS_BUSY.getCode());
webResult.setFailure(ResultCode.SYSTEM_IS_BUSY.getDesc());
}
return webResult;
}
@RequestMapping(value = "/recharge/alipay/terminal/notify", method = RequestMethod.POST)
public void verifyAlipayTerminalNotify(HttpServletRequest request, HttpServletResponse response) {
try {
response.getWriter().write(alipayTerminalService.verifyPaymentNotifyCallback(request.getParameterMap()));
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
}
@Service("alipayTerminalService")
public class AlipayTerminalServiceImpl implements IAlipayService {
private Logger LOG = LoggerFactory.getLogger(AlipayTerminalServiceImpl.class);
@Autowired
private AlipayConfiguration alipayConfiguration = null;
@Resource(name = "rechargeItemService")
private IRechargeItemService rechargeItemService = null;
@Resource(name = "rechargeRecordService")
private IRechargeRecordService rechargeRecordService = null;
@Override
public String mreadPaymentRequest(Long rechargeItemId) throws BusinessException {
if (null == rechargeItemId) throw new BusinessException(ResultCode.PARAM_NULL);
RechargeItem rechargeItem = rechargeItemService.readRechargeItemById(rechargeItemId);
Map params = new HashMap();
params.put("app_id", alipayConfiguration.getAppId());
String outTradeNo = AlipayUtils.genOutTradeNo();
params.put("biz_content", genBizContent(rechargeItem.getPresentPrice(),
rechargeItem.getName(), rechargeItem.getDesc(), outTradeNo));
params.put("method", alipayConfiguration.getMethod());
params.put("charset", alipayConfiguration.getCharset());
params.put("version", alipayConfiguration.getVersion());
params.put("sign_type", alipayConfiguration.getSignType());
params.put("notify_url", alipayConfiguration.getNotifyUrl());
params.put("timestamp", DateFormatter.TIME.get().format(new Date()));
try {
String sign = AlipaySignature.rsa256Sign(AlipaySignature.getSignContent(params),
alipayConfiguration.getAppPrivateKey(), alipayConfiguration.getCharset());
params.put("sign", sign);
} catch (AlipayApiException e) {
throw new BusinessException(ResultCode.ALIPAY_SIGN_EXCEPTION);
}
insertRechargeRecord(rechargeItem, outTradeNo, params);
List> rparams = new ArrayList>(params.entrySet());
Collections.sort(rparams, new Comparator>() {
@Override
public int compare(Entry o1, Entry o2) {
return o1.getKey().compareTo(o2.getKey());
}
});
StringBuilder sb = new StringBuilder();
try {
for (Map.Entry entry : rparams) {
sb.append(entry.getKey() + "=" + URLEncoder.encode(entry.getValue(), alipayConfiguration.getCharset()) + "&");
}
} catch (UnsupportedEncodingException e) {
LOG.error(e.getMessage(), e);
}
String result = sb.length() > 0 ? sb.deleteCharAt(sb.length() - 1).toString() : "";
LOG.info("ali payment request params: {}", result);
return result;
}
@Override
public String verifyPaymentReturnCallback(Object callbackParams) throws BusinessException {
return null;
}
@SuppressWarnings("unchecked")
@Override
public String verifyPaymentNotifyCallback(Object callbackParams) throws BusinessException {
Map requestParams = (Map) callbackParams;
Map notifyParams = new HashMap();
try {
for (Map.Entry entry : requestParams.entrySet()) {
String paramKey = entry.getKey();
notifyParams.put(paramKey, "sign".equals(paramKey) ? entry.getValue()[0] :
URLDecoder.decode(entry.getValue()[0], alipayConfiguration.getCharset()));
}
} catch (UnsupportedEncodingException e) {
LOG.error(e.getMessage(), e);
}
try {
if (!AlipaySignature.rsaCheckV1(notifyParams, alipayConfiguration.getAlipayPublicKey(),
alipayConfiguration.getCharset(), notifyParams.get("sign_type"))) {
LOG.error("Alipay Signature Failure!");
return "FALSE";
}
} catch (AlipayApiException e) {
LOG.error(e.getMessage(), e);
return "FALSE";
}
if (!judgeParam(notifyParams, "seller_id", alipayConfiguration.getSellerId()) ||
!judgeParam(notifyParams, "seller_email", alipayConfiguration.getSellerEmail()) ||
!judgeParam(notifyParams, "app_id", alipayConfiguration.getAppId())) {
LOG.error("notify verify seller_id {} or seller_email {} or app_id {} error",
notifyParams.get("seller_id"), notifyParams.get("seller_email"), notifyParams.get("app_id"));
return "FALSE";
}
String totalAmountTxt = notifyParams.get("total_amount");
if (null == totalAmountTxt || "".equals(totalAmountTxt)) return "FALSE";
String outTradeNo = notifyParams.get("out_trade_no");
RechargeRecord rechargeRecord = rechargeRecordService.readRechargeRecordByOutTradeNo(outTradeNo);
if (null == rechargeRecord || !rechargeRecord.getTotalMoney().equals(
Double.parseDouble(totalAmountTxt))) {
LOG.error("charging record: {}", rechargeRecord);
LOG.error("{} , {}", rechargeRecord.getTotalMoney(), totalAmountTxt);
return "FALSE";
}
updateRechargeRecord(rechargeRecord, notifyParams);
return "SUCCESS";
}
/** 阿里APP支付字符串组合 */
private String genBizContent(Double totalMoney, String subject, String body,
String outTradeNo) throws BusinessException {
String bizContent = "" + "{\"timeout_express\":\"" + alipayConfiguration.getTimeout() + "\","
+ "\"seller_id\":\"\"," + "\"product_code\":\"" + alipayConfiguration.getProductCode() + "\","
+ "\"total_amount\":\"" + totalMoney + "\"," + "\"subject\":\"" + subject + "\"," + "\"body\":\""
+ body + "\"," + "\"out_trade_no\":\"" + outTradeNo + "\"}";
return bizContent;
}
/** 新增充值记录 */
private void insertRechargeRecord(RechargeItem rechargeItem, String outTradeNo, Map params) {
RechargeRecord rechargeRecord = new RechargeRecord();
rechargeRecord.setUserId(WebUtils.getCurrentUserId());
rechargeRecord.setTotalMoney(rechargeItem.getPresentPrice());
rechargeRecord.setRechargeItem(GsonUtils.builder().toJson(rechargeItem));
rechargeRecord.setChannel("alipay");
rechargeRecord.setOutTradeNo(outTradeNo);
rechargeRecord.setSign(params.get("sign"));
rechargeRecord.setRechargeNote(GsonUtils.fromMapExtToJson(params));
rechargeRecord.setTradeStatus(TradeStatus.INITIAL.value());
rechargeRecord.setInsertTime(new Date());
rechargeRecordService.insert(rechargeRecord);
}
private boolean judgeParam(Map params, String paramKey, String targetValue) {
String paramValue = params.get(paramKey);
return (null != paramValue && !"".equals(paramValue) && paramValue.equals(targetValue)) ? true : false;
}
/** 更新充值记录 */
private void updateRechargeRecord(RechargeRecord rechargeRecord, Map notifyParams) {
String dbTradeStatus = rechargeRecord.getTradeStatus();
if (TradeStatus.judgeIn(dbTradeStatus, TradeStatus.SUCCESS, TradeStatus.FINISHED)) return;
RechargeRecord updateRechargeRecord = new RechargeRecord();
updateRechargeRecord.setUserId(rechargeRecord.getUserId());
updateRechargeRecord.setOutTradeNo(rechargeRecord.getOutTradeNo());
updateRechargeRecord.setTradeNo(notifyParams.get("trade_no"));
updateRechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(notifyParams));
updateRechargeRecord.setTradeStatus(TradeStatus.convert(notifyParams.get("trade_status")));
rechargeRecordService.update(updateRechargeRecord);
}
}
网页支付
接入流程可以参考官方文档:https://opendocs.alipay.com/open/270/105899
@ApiV1RestController
public class AlipayController {
private Logger LOG = LoggerFactory.getLogger(AlipayController.class);
@Resource(name = "alipayWebPageService")
private IAlipayService alipayWebPageService = null;
@RequestMapping(value = "/recharge/alipay/webpage", method = RequestMethod.POST)
public void rechargeAlipayWebPage(Long rechargeItemId, HttpServletResponse response) {
try {
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(alipayWebPageService.mreadPaymentRequest(rechargeItemId));
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
@RequestMapping(value = "/recharge/alipay/webpage/return", method = RequestMethod.POST)
public void verifyAlipayWebPageReturn(HttpServletRequest request, HttpServletResponse response) {
try {
LOG.info("payment return invoked!");
alipayWebPageService.verifyPaymentNotifyCallback(request.getParameterMap());
response.getWriter().write("SUCCESS");
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
@RequestMapping(value = "/recharge/alipay/webpage/notify", method = RequestMethod.POST)
public void verifyAlipayWebPageNotify(HttpServletRequest request, HttpServletResponse response) {
try {
LOG.info("payment notify invoked!");
alipayWebPageService.verifyPaymentNotifyCallback(request.getParameterMap());
response.getWriter().write("SUCCESS");
} catch (Exception e) {
LOG.error(e.getMessage(), e);
}
}
}
@Service("alipayWebPageService")
public class AlipayWebPageServiceImpl implements IAlipayService {
private Logger LOG = LoggerFactory.getLogger(AlipayWebPageServiceImpl.class);
@Autowired
private AlipayClient alipayClient = null;
@Autowired
private AlipayConfiguration alipayConfiguration = null;
@Resource(name = "rechargeItemService")
private IRechargeItemService rechargeItemService = null;
@Resource(name = "rechargeRecordService")
private IRechargeRecordService rechargeRecordService = null;
@Override
public String mreadPaymentRequest(Long rechargeItemId) throws BusinessException {
if (null == rechargeItemId) throw new BusinessException(ResultCode.PARAM_NULL);
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setApiVersion(alipayConfiguration.getVersion());
// 同步通知路径
alipayRequest.setReturnUrl(alipayConfiguration.getReturnUrl());
// 异步通知路径
alipayRequest.setNotifyUrl(alipayConfiguration.getNotifyUrl());
RechargeItem rechargeItem = rechargeItemService.readRechargeItemById(rechargeItemId);
String outTradeNo = AlipayUtils.genOutTradeNo();
// 业务参数
Map params = new HashMap(16);
params.put("out_trade_no", outTradeNo);
params.put("total_amount", String.format("%.2f", rechargeItem.getPresentPrice()));
params.put("subject", rechargeItem.getName());
params.put("body", rechargeItem.getDesc());
params.put("product_code", "FAST_INSTANT_TRADE_PAY");
params.put("passback_params", "");
alipayRequest.setBizContent(GsonUtils.fromMapExtToJson(params));
String result = "";
try{
AlipayTradePagePayResponse alipayResponse = alipayClient.pageExecute(alipayRequest);
if(alipayResponse.isSuccess()) {
result = alipayResponse.getBody();
insertRechargeRecord(rechargeItem, outTradeNo, params);
} else {
LOG.error("payment form error : {}", alipayResponse.getSubMsg());
result = "ERROR";
}
} catch (Exception e) {
LOG.error(" payment error : {}", e.getMessage());
e.printStackTrace();
}
return result;
}
@SuppressWarnings("unchecked")
@Override
public String verifyPaymentReturnCallback(Object callbackParams) throws BusinessException {
Map requestParams = (Map) callbackParams;
Map notifyParams = new HashMap();
try {
for (Map.Entry entry : requestParams.entrySet()) {
String paramKey = entry.getKey();
notifyParams.put(paramKey, "sign".equals(paramKey) ? entry.getValue()[0] :
URLDecoder.decode(entry.getValue()[0], "UTF-8"));
}
} catch (UnsupportedEncodingException e) {
LOG.error(e.getMessage(), e);
}
LOG.info("notifyParams {}", GsonUtils.builder().toJson(notifyParams));
return "SUCCESS";
}
@SuppressWarnings("unchecked")
@Override
public String verifyPaymentNotifyCallback(Object callbackParams) throws BusinessException {
Map requestParams = (Map) callbackParams;
Map notifyParams = new HashMap();
try {
for (Map.Entry entry : requestParams.entrySet()) {
String paramKey = entry.getKey();
String[] values = entry.getValue();
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
}
notifyParams.put(paramKey, "sign".equals(paramKey) ? valueStr : URLDecoder.decode(valueStr, "UTF-8"));
}
} catch (UnsupportedEncodingException e) {
LOG.error(e.getMessage(), e);
}
LOG.info("notifyParams {}", GsonUtils.builder().toJson(notifyParams));
try {
if (!AlipaySignature.rsaCheckV1(notifyParams, alipayConfiguration.getAlipayPublicKey(),
alipayConfiguration.getCharset(), notifyParams.get("sign_type"))) {
LOG.error("Alipay Signature Failure!");
return "FALSE";
}
} catch (AlipayApiException e) {
LOG.error(e.getMessage(), e);
return "FALSE";
}
if (!judgeParam(notifyParams, "seller_id", alipayConfiguration.getSellerId()) ||
!judgeParam(notifyParams, "app_id", alipayConfiguration.getAppId())) {
LOG.error("notify verify seller_id {} or auth_app_id {} error",
notifyParams.get("seller_id"), notifyParams.get("auth_app_id"));
return "FALSE";
}
String buyerPayAmountTxt = notifyParams.get("buyer_pay_amount");
if (null == buyerPayAmountTxt || "".equals(buyerPayAmountTxt)) return "FALSE";
String outTradeNo = notifyParams.get("out_trade_no");
RechargeRecord rechargeRecord = rechargeRecordService.readRechargeRecordByOutTradeNo(outTradeNo);
if (null == rechargeRecord || !rechargeRecord.getTotalMoney().equals(
Double.parseDouble(buyerPayAmountTxt))) {
LOG.error("charging record: {}", rechargeRecord);
LOG.error("{} , {}", rechargeRecord.getTotalMoney(), buyerPayAmountTxt);
return "FALSE";
}
updateRechargeRecord(rechargeRecord, notifyParams);
return "SUCCESS";
}
/** 新增充值记录 */
private void insertRechargeRecord(RechargeItem rechargeItem, String outTradeNo, Map params) {
RechargeRecord rechargeRecord = new RechargeRecord();
rechargeRecord.setUserId(WebUtils.getCurrentUserId());
rechargeRecord.setTotalMoney(rechargeItem.getPresentPrice());
rechargeRecord.setRechargeItem(GsonUtils.builder().toJson(rechargeItem));
rechargeRecord.setChannel("alipay");
rechargeRecord.setOutTradeNo(outTradeNo);
rechargeRecord.setSign(params.get("sign"));
rechargeRecord.setRechargeNote(GsonUtils.fromMapExtToJson(params));
rechargeRecord.setTradeStatus(TradeStatus.INITIAL.value());
rechargeRecord.setInsertTime(new Date());
rechargeRecordService.insert(rechargeRecord);
}
private boolean judgeParam(Map params, String paramKey, String targetValue) {
String paramValue = params.get(paramKey);
return (null != paramValue && !"".equals(paramValue) && paramValue.equals(targetValue)) ? true : false;
}
/** 更新充值记录 */
private void updateRechargeRecord(RechargeRecord rechargeRecord, Map notifyParams) {
String dbTradeStatus = rechargeRecord.getTradeStatus();
if (TradeStatus.judgeIn(dbTradeStatus, TradeStatus.SUCCESS, TradeStatus.FINISHED)) return;
RechargeRecord updateRechargeRecord = new RechargeRecord();
updateRechargeRecord.setUserId(rechargeRecord.getUserId());
updateRechargeRecord.setOutTradeNo(rechargeRecord.getOutTradeNo());
updateRechargeRecord.setTradeNo(notifyParams.get("trade_no"));
updateRechargeRecord.setResultNote(GsonUtils.fromMapExtToJson(notifyParams));
updateRechargeRecord.setTradeStatus(TradeStatus.convert(notifyParams.get("trade_status")));
rechargeRecordService.update(updateRechargeRecord);
}
}