策略模式实现支付宝支付
- 前言
- 一、准备
- 二、主要代码
-
- 1、项目结构
- 2、支付宝支付方式枚举类
- 3、支付常量类
- 4、支付宝支付相关常量
- 5、支付宝配置类
- 6、用到的两个实体类
- 7、调用支付宝支付的工具类
- 8、controller
- 三、测试结果
本文主要以 支付宝手机网站支付为例,利用策略模式开发支付宝支付,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考和学习价值,有需要的小伙伴们就来一起学习学习吧-_-
前言
策略模式
主要解决: 在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护
何时使用: 一个系统有许多许多类,而区分它们的只是他们直接的行为
如何解决: 将这些算法封装成一个一个的类,任意地替换
关键代码: 实现同一个接口
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露
一、准备
1、到支付宝商户平台申请,获取到APPID、支付宝公钥、商户私钥
2、开发过程中所用到的依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.22.32.ALL</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.12.0</version>
</dependency>
二、主要代码
1、项目结构
2、支付宝支付方式枚举类
package com.wr.common.enums;
/**
* @Author: RainCity
* @Date: 2022-02-18 17:34:44
* @Desc: 支付宝支付方式枚举类
*/
public enum AliEnum {
/** app支付 */
APP("APP"),
/** 手机网站支付 */
WAP("WAP"),
/** 电脑网站支付 */
PAGE("PAGE"),
/** 手机扫码支付 */
QR_CODE("QR_CODE"),
/** 付款码支付 */
AUTH_CODE("AUTH_CODE");
private final String value;
AliEnum(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
3、支付常量类
这里放一些支付会用到的常量
package com.wr.common.constant;
/**
* @Author: RainCity
* @Date: 2022-02-26 14:43:22
* @Desc: 支付常量类
*/
public class PayConstants {
/**页面服务地址*/
public static final String SERVER_URL = "";
/**UTF_8编码*/
public static final String UTF_8 = "UTF-8";
/**json格式*/
public static final String FORMAT_JSON = "json";
/**RSA2*/
public static final String SIGN_RSA2 = "RSA2";
public static String YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
public static String YYYY_MM_DD_T_HH_mm_ss_TIMEZONE = "yyyy-MM-dd'T'HH:mm:ss'+08:00'";
}
4、支付宝支付相关常量
这里放的是仅支付宝中的相关常量,以后会写微信支付,所以和上面那个 PayConstants 分开,这样便于维护
package com.wr.common.constant;
/**
* @Author: RainCity
* @Date: 2022-02-28 15:16:47
* @Desc: 支付宝支付相关常量
*/
public class AliConstants {
/**支付宝回调地址*/
public static final String NOTIFY_URL = "http://xxxx/api/ali/notify";
/**网页重定向通知地址 HTTP/HTTPS开头字符串*/
public static final String RETURN_URL = "http://xxxx/api/ali/ali_return";
/**用户付款中途退出返回商户网站的地址*/
public static final String QUIT_URL = "http://xxxx/api/ali/ali_quit";
/**支付宝支付回调成功返回*/
public static final String ALI_SUCCESS_RETURN = "success";
/**支付宝支支付回调失败返回*/
public static final String ALI_FAILED_RETURN = "failure";
/**
* 交易支付成功
*/
public static final String TRADE_SUCCESS = "TRADE_SUCCESS";
/**
* 交易创建,等待买家付款
*/
public static final String WAIT_BUYER_PAY = "WAIT_BUYER_PAY";
/**
* 未付款交易超时关闭,或支付完成后全额退款
*/
public static final String TRADE_CLOSED = "TRADE_CLOSED";
/**
* 交易结束,不可退款
*/
public static final String TRADE_FINISHED = "TRADE_FINISHED";
}
5、支付宝配置类
这里的配置也可以放到项目中的配置文件里面,这里只是写了一个demo,并没有用到配置类,懒得去搞了0.0,就写到一个类中了,根据大家需求,自行选择。。。
package com.wr.common.config;
/**
* @Author: RainCity
* @Date: 2022-02-26 14:46:01
* @Desc: 支付宝配置类
*/
public class AliConfig {
/**
* 支付宝网关
* https://openapi.alipaydev.com/gateway.do
* https://openapi.alipay.com/gateway.do
*/
public static final String GATEWAY_URL = "https://openapi.alipay.com/gateway.do";
/**支付宝分配给开发者的应用ID*/
public static final String APP_ID = "your appid";
/**支付宝公钥*/
public static final String PUBLIC_KEY = "your ali public key";
/**支付宝商户私钥*/
public static final String PRIVATE_KEY = "your private key";
}
6、用到的两个实体类
package com.wr.project.entity;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @Author: RainCity
* @Date: 2022-02-26 13:50:00
* @Desc: 支付基类
*/
public class AliPay implements Serializable {
private static final long serialVersionUID = 2991507710246393025L;
/** 支付方式 */
private String payType;
/** 支付回调地址 */
private String notifyUrl;
/**网页重定向通知 HTTP/HTTPS开头字符串*/
private String returnUrl;
/** 订单编号 */
private String outTradeNo;
/** 金额 */
private BigDecimal totalAmount;
/** 订单标题 */
private String subject;
/** 公共回传参数 */
private String backParams;
/**
* 交易绝对时间
* 支付宝格式:yyyy-MM-dd HH:mm:ss
* 微信格式:YYYY-MM-DDTHH:mm:ss+TIMEZONE
*/
private String timeExpire;
/** 用户付款中途退出返回商户网站的地址 */
private String quitUrl;
/**
* 支付授权码
* 当面付场景传买家的付款码(25~30开头的长度为16~24位的数字,实际字符串长度以开发者获取的付款码长度为准)
* 或者刷脸标识串(fp开头的35位字符串)
*/
private String authCode;
/** 此处省略setter、getter、toString方法,切勿忘记,不建议使用Lombok*/
/** 此处省略setter、getter、toString方法,切勿忘记,不建议使用Lombok*/
/** 此处省略setter、getter、toString方法,切勿忘记,不建议使用Lombok*/
}
package com.wr.project.entity.dto;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* @Author: RainCity
* @Date: 2022-02-26 17:20:34
* @Desc: 接收前端传过来的参数
*/
public class PayDTO implements Serializable {
private static final long serialVersionUID = -7610591285294877627L;
/** 支付方式 */
private String payType;
/** 金额 */
private BigDecimal totalAmount;
/** 此处省略setter、getter、toString方法,切勿忘记,不建议使用Lombok*/
/** 此处省略setter、getter、toString方法,切勿忘记,不建议使用Lombok*/
/** 此处省略setter、getter、toString方法,切勿忘记,不建议使用Lombok*/
}
7、调用支付宝支付的工具类
package com.wr.common.util;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.*;
import com.alipay.api.response.*;
import com.wr.common.config.AliConfig;
import com.wr.common.constant.PayConstants;
import com.wr.project.entity.AliPay;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
/**
* @Author: RainCity
* @Date: 2022-02-26 13:42:18
* @Desc: 支付宝支付工具类
*/
public class AliPayUtils {
private static final Logger log = LoggerFactory.getLogger(AliPayUtils.class);
/**销售产品码,商家和支付宝签约的产品码(APP)*/
private static final String PRODUCT_CODE_APP = "QUICK_MSECURITY_PAY";
/**销售产品码,商家和支付宝签约的产品码(WAP)*/
private static final String PRODUCT_CODE_WAP = "QUICK_WAP_WAY";
/**销售产品码,商家和支付宝签约的产品码(PAGE)*/
private static final String PRODUCT_CODE_PAGE = "FAST_INSTANT_TRADE_PAY";
/**销售产品码,商家和支付宝签约的产品码(当面付快捷版)*/
private static final String PRODUCT_CODE_OFFLINE = "OFFLINE_PAYMENT";
/**销售产品码,商家和支付宝签约的产品码(默认当面付)*/
private static final String PRODUCT_CODE_FACE_TO_FACE = "FACE_TO_FACE_PAYMENT";
/**
* 请求参数封装
* @param aliPay
* outTradeNo 订单号
* totalAmount 总金额(单位分)
* payTitle 订单标题
* timeExpire 过期时间
* backParams 公共回传参数
* @param productCode 销售产品码
* @return bizContent
*/
private static JSONObject packageBizContent(AliPay aliPay, String productCode){
JSONObject bizContent = new JSONObject();
//商户网站唯一订单号
bizContent.put("out_trade_no", aliPay.getOutTradeNo());
//订单总金额,单位为元,精确到小数点后两位
BigDecimal amount = aliPay.getTotalAmount().setScale(2, RoundingMode.HALF_UP);
bizContent.put("total_amount", amount.toString());
//订单标题
bizContent.put("subject", aliPay.getSubject());
//销售产品码,商家和支付宝签约的产品码
bizContent.put("product_code", productCode);
//绝对超时时间,格式为yyyy-MM-dd HH:mm:ss
if(StringUtils.isNotEmpty(aliPay.getTimeExpire())){
bizContent.put("time_expire", aliPay.getTimeExpire());
}
// 公用回传参数,按需传入
if(StringUtils.isNotEmpty(aliPay.getBackParams())){
bizContent.put("passback_params", aliPay.getBackParams());
}
return bizContent;
}
/**
* 支付宝APP支付
* @param aliPay 支付参数
* @return 支付结果 https://opendocs.alipay.com/apis/028xq9
* @throws AlipayApiException
*/
public static AlipayTradeAppPayResponse tradeAppPay(AliPay aliPay) throws AlipayApiException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
AliConfig.GATEWAY_URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY, PayConstants.FORMAT_JSON,
PayConstants.UTF_8, AliConfig.PUBLIC_KEY, PayConstants.SIGN_RSA2);
//创建API对应的request类
AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
//设置回调地址
request.setNotifyUrl(aliPay.getNotifyUrl());
JSONObject bizContent = packageBizContent(aliPay, PRODUCT_CODE_APP);
request.setBizContent(bizContent.toString());
AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
log.info("TradeAppPayResponse:{}",response);
return response;
}
/**
* 支付宝手机网站支付
* @param aliPay 支付参数
* @return 支付结果 https://opendocs.alipay.com/apis/api_1/alipay.trade.wap.pay
* @throws AlipayApiException
*/
public static AlipayTradeWapPayResponse tradeWapPay(AliPay aliPay) throws AlipayApiException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
AliConfig.GATEWAY_URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY, PayConstants.FORMAT_JSON,
PayConstants.UTF_8, AliConfig.PUBLIC_KEY, PayConstants.SIGN_RSA2);
//创建API对应的request类
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
//设置回调地址
request.setNotifyUrl(aliPay.getNotifyUrl());
//网页重定向通知 HTTP/HTTPS开头字符串
request.setReturnUrl(aliPay.getReturnUrl());
JSONObject bizContent = packageBizContent(aliPay, PRODUCT_CODE_WAP);
//用户付款中途退出返回商户网站的地址
bizContent.put("quit_url", aliPay.getQuitUrl());
request.setBizContent(bizContent.toString());
AlipayTradeWapPayResponse response = alipayClient.pageExecute(request);
log.info("TradeWapPayResponse:{}",response);
return response;
}
/**
* 支付宝电脑网站支付
* @param aliPay 支付参数
* @return 支付结果 https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay?scene=22
* @throws AlipayApiException
*/
public static AlipayTradePagePayResponse tradePagePay(AliPay aliPay) throws AlipayApiException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
AliConfig.GATEWAY_URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY, PayConstants.FORMAT_JSON,
PayConstants.UTF_8, AliConfig.PUBLIC_KEY, PayConstants.SIGN_RSA2);
//创建API对应的request类
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
//设置回调地址
request.setNotifyUrl(aliPay.getNotifyUrl());
//网页重定向通知 HTTP/HTTPS开头字符串
request.setReturnUrl(aliPay.getReturnUrl());
JSONObject bizContent = packageBizContent(aliPay, PRODUCT_CODE_PAGE);
//PC扫码支付的方式
//前置模式 0:订单码-简约前置模式,对应 iframe 宽度不能小于600px,高度不能小于300px;
// 1:订单码-前置模式,对应iframe 宽度不能小于 300px,高度不能小于600px;
// 3:订单码-迷你前置模式,对应 iframe 宽度不能小于 75px,高度不能小于75px;
// 4:订单码-可定义宽度的嵌入式二维码,商户可根据需要设定二维码的大小
//跳转模式 2:订单码-跳转模式
bizContent.put("qr_pay_mode", "2");
//商户自定义二维码宽度。qr_pay_mode=4时该参数有效
//bizContent.put("qrcode_width", 100);
request.setBizContent(bizContent.toString());
AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
log.info("TradePagePayResponse:{}",response);
return response;
}
/**
* 支付宝手机扫码支付
* @param aliPay 支付参数
* @return 支付结果 https://opendocs.alipay.com/apis/api_1/alipay.trade.precreate?scene=19
* @throws AlipayApiException
*/
public static AlipayTradePrecreateResponse tradeQrCodePay(AliPay aliPay) throws AlipayApiException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
AliConfig.GATEWAY_URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY, PayConstants.FORMAT_JSON,
PayConstants.UTF_8, AliConfig.PUBLIC_KEY, PayConstants.SIGN_RSA2);
//创建API对应的request类
AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
//设置回调地址
request.setNotifyUrl(aliPay.getNotifyUrl());
JSONObject bizContent = packageBizContent(aliPay, PRODUCT_CODE_FACE_TO_FACE);
request.setBizContent(bizContent.toString());
AlipayTradePrecreateResponse response = alipayClient.execute(request);
log.info("TradePreCreateResponse:{}",response);
return response;
}
/**
* 支付宝付款码支付
* @param aliPay 支付参数
* @return 支付结果 https://opendocs.alipay.com/apis/api_1/alipay.trade.pay?scene=32
* @throws AlipayApiException
*/
public static AlipayTradePayResponse tradeAuthCodePay(AliPay aliPay) throws AlipayApiException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
AliConfig.GATEWAY_URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY, PayConstants.FORMAT_JSON,
PayConstants.UTF_8, AliConfig.PUBLIC_KEY, PayConstants.SIGN_RSA2);
//创建API对应的request类
AlipayTradePayRequest request = new AlipayTradePayRequest();
//设置回调地址
request.setNotifyUrl(aliPay.getNotifyUrl());
JSONObject bizContent = packageBizContent(aliPay, PRODUCT_CODE_FACE_TO_FACE);
//支付场景 bar_code:当面付条码支付场景;
// security_code:当面付刷脸支付场景,对应的auth_code为fp开头的刷脸标识串;
bizContent.put("scene", "bar_code");
//支付授权码 当面付场景传买家的付款码
bizContent.put("auth_code", aliPay.getAuthCode());
request.setBizContent(bizContent.toString());
AlipayTradePayResponse response = alipayClient.execute(request);
log.info("TradePayResponse:{}",response);
return response;
}
/**
* 交易查询
* @param outTradeNo 商户网站唯一订单号
* @return 查询结果
* @throws AlipayApiException
*/
public static AlipayTradeQueryResponse tradeQuery(String outTradeNo) throws AlipayApiException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
AliConfig.GATEWAY_URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY, PayConstants.FORMAT_JSON,
PayConstants.UTF_8, AliConfig.PUBLIC_KEY, PayConstants.SIGN_RSA2);
//创建API对应的request类
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
JSONObject bizContent = new JSONObject();
//商户网站唯一订单号
bizContent.put("out_trade_no", outTradeNo);
request.setBizContent(bizContent.toString());
AlipayTradeQueryResponse response = alipayClient.execute(request);
log.info("TradeQueryResponse:{}",response);
return response;
}
/**
* 交易撤销
* @param outTradeNo 户网站唯一订单号
* @return retryFlag=是否需要重试(Y/N)
* action=本次撤销触发的交易动作,接口调用成功且交易存在时返回
* 可能的返回值:
* close:交易未支付,触发关闭交易动作,无退款;
* refund:交易已支付,触发交易退款动作;
* 未返回:未查询到交易,或接口调用失败;
* @throws AlipayApiException
*/
public static AlipayTradeCancelResponse tradeCancel(String outTradeNo) throws AlipayApiException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
AliConfig.GATEWAY_URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY, PayConstants.FORMAT_JSON,
PayConstants.UTF_8, AliConfig.PUBLIC_KEY, PayConstants.SIGN_RSA2);
//创建API对应的request类
AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
JSONObject bizContent = new JSONObject();
//商户网站唯一订单号
bizContent.put("out_trade_no", outTradeNo);
request.setBizContent(bizContent.toString());
AlipayTradeCancelResponse response = alipayClient.execute(request);
log.info("TradeCancelResponse:{}",response);
return response;
}
/**
* 用于交易创建后,用户在一定时间内未进行支付,可调用该接口直接将未付款的交易进行关闭
* @param outTradeNo 商户网站唯一订单号
* @return 状态码
* @throws AlipayApiException
*/
public static AlipayTradeCloseResponse tradeClose(String outTradeNo) throws AlipayApiException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(
AliConfig.GATEWAY_URL, AliConfig.APP_ID, AliConfig.PRIVATE_KEY, PayConstants.FORMAT_JSON,
PayConstants.UTF_8, AliConfig.PUBLIC_KEY, PayConstants.SIGN_RSA2);
//创建API对应的request类
AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
JSONObject bizContent = new JSONObject();
//商户网站唯一订单号
bizContent.put("out_trade_no", outTradeNo);
request.setBizContent(bizContent.toString());
AlipayTradeCloseResponse response = alipayClient.execute(request);
log.info("TradeCloseResponse:{}",response);
return response;
}
/**
* 设置过期时间
* @param minute
* @return
*/
public static String aliTimeExpire(int minute){
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MINUTE,minute);
SimpleDateFormat sdf = new SimpleDateFormat(PayConstants.YYYY_MM_DD_HH_MM_SS);
return sdf.format(cal.getTime());
}
/**
* 获取支付宝POST过来的反馈信息
* @param request
* @return
*/
public static Map<String,String> getPostParams(HttpServletRequest request){
Map<String,String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
String[] values = requestParams.get(name);
String valueStr = "";
for (int i = 0; i < values.length; i++) {
valueStr = (i == values.length - 1) ? valueStr + values[i]
: valueStr + values[i] + ",";
}
//乱码解决,这段代码在出现乱码时使用。
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}
return params;
}
}
8、controller
package com.wr.project.web;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.wr.common.AjaxResult;
import com.wr.common.config.AliConfig;
import com.wr.common.constant.AliConstants;
import com.wr.common.constant.PayConstants;
import com.wr.common.util.AliPayUtils;
import com.wr.project.entity.dto.PayDTO;
import com.wr.project.service.AliPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* @Author: RainCity
* @Date: 2022-02-18 13:04:52
* @Desc:
*/
@RestController
@RequestMapping("/api/ali")
public class AliController {
private static final Logger log = LoggerFactory.getLogger(AliController.class);
@Autowired
private List<AliPayService> aliPayServices;
@PostMapping("/pay")
public AjaxResult pay(PayDTO payDTO) {
log.info("********** 支付宝支付==> *************");
AliPayService aliPayService = aliPayServices.stream()
.filter(service -> service.support(payDTO.getPayType()))
.findAny()
.orElseThrow(() -> new RuntimeException("支付模式:"+payDTO.getPayType()+"不支持"));
return aliPayService.execute(payDTO);
}
@PostMapping("/notify")
public String notify(HttpServletRequest request) {
log.info("********** 支付宝支付回调执行 *************");
//获取支付宝POST过来反馈信息
Map<String,String> params = AliPayUtils.getPostParams(request);
log.info("params:{}",params);
String backParams = params.get("passback_params");
log.info("backParams:{}",backParams);
try {
//切记alipaypublickey是支付宝的公钥,请去open.alipay.com对应应用下查看。
boolean flag = AlipaySignature.rsaCheckV1(params, AliConfig.PUBLIC_KEY,PayConstants.UTF_8, PayConstants.SIGN_RSA2);
if(!flag){
log.error("支付宝回调签名认证失败");
return AliConstants.ALI_FAILED_RETURN;
}
String tradeStatus= params.get("trade_status");
log.info("支付宝回调签名认证成功,tradeStatus={}",tradeStatus);
if(!AliConstants.TRADE_SUCCESS.equals(tradeStatus)){
return AliConstants.ALI_FAILED_RETURN;
}
//自己的业务逻辑......
return AliConstants.ALI_SUCCESS_RETURN;
} catch (AlipayApiException e) {
e.printStackTrace();
log.error("支付宝回调失败,code:{},msg:{}",e.getErrCode(),e.getErrMsg());
return AliConstants.ALI_FAILED_RETURN;
}
}
@GetMapping("/ali_return")
public void aliSuccess(HttpServletResponse response) throws IOException {
log.info("********** 支付宝进入成功页面 *************");
//进入页面的地址
response.sendRedirect(PayConstants.SERVER_URL + "/ali_success");
}
@GetMapping("/ali_quit")
public void aliCancel(HttpServletResponse response) throws IOException {
log.info("********** 支付宝进入取消页面 *************");
response.sendRedirect(PayConstants.SERVER_URL + "/ali_cancel");
}
}
9、业务处理service
一个service多个Impl,impl包中对应枚举类 AliEnum
package com.wr.project.service;
import com.wr.common.AjaxResult;
import com.wr.project.entity.dto.PayDTO;
/**
* @Author: RainCity
* @Date: 2022-02-26 16:36:20
* @Desc: 支付宝支付业务层
*/
public interface AliPayService {
/**
* 判断是否支持此支付方式
* @param payType
* @return
*/
boolean support(String payType);
/**
* 要执行的动作
* @param payDTO
* @return
*/
AjaxResult execute(PayDTO payDTO);
}
以手机网站(WAP)为例
package com.wr.project.service.impl;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.wr.common.AjaxResult;
import com.wr.common.constant.AliConstants;
import com.wr.common.enums.AliEnum;
import com.wr.common.util.AliPayUtils;
import com.wr.project.entity.AliPay;
import com.wr.project.entity.dto.PayDTO;
import com.wr.project.service.AliPayService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
* @Author: RainCity
* @Date: 2022-02-26 16:52:59
* @Desc: 支付宝WAP支付业务逻辑处理层
*/
@Service
public class AliWapPayServiceImpl implements AliPayService {
private static final Logger log = LoggerFactory.getLogger(AliWapPayServiceImpl.class);
@Override
public boolean support(String payType) {
return AliEnum.WAP.getValue().equals(payType);
}
@Override
public AjaxResult execute(PayDTO payDTO) {
AliPay aliPay = new AliPay();
aliPay.setPayType(payDTO.getPayType());
aliPay.setNotifyUrl(AliConstants.NOTIFY_URL);
aliPay.setReturnUrl(AliConstants.RETURN_URL);
aliPay.setQuitUrl(AliConstants.QUIT_URL);
aliPay.setOutTradeNo(String.valueOf(System.currentTimeMillis()));
aliPay.setTotalAmount(payDTO.getTotalAmount());
aliPay.setSubject("支付测试");
//过期时间,设置为5分钟后
aliPay.setTimeExpire(AliPayUtils.aliTimeExpire(5));
//回传参数
// 注:长度为512,超过了就换其他的方式吧,如redis
//language=JSON
String testStr = "{\"payType\": \""+payDTO.getPayType()+"\",\"userName\": \"测试一下\",\"userPhone\": \"15266668888\"}";
aliPay.setBackParams(testStr);
try {
AlipayTradeWapPayResponse response = AliPayUtils.tradeWapPay(aliPay);
if(response.isSuccess()){
log.info("支付调用成功");
//支付调用成功,将支付宝返回的form表单返给前端
JSONObject data = new JSONObject();
data.put("outTradeNo",response.getOutTradeNo());
data.put("formResult",response.getBody());
return AjaxResult.success(data);
}
log.error("支付调用失败,{},{}",response.getMsg(),response.getSubMsg());
return AjaxResult.error("支付调用失败!");
} catch (AlipayApiException e) {
log.error("支付调用失败,{},{}",e.getErrCode(),e.getErrMsg());
return AjaxResult.error("支付调用失败!");
}
}
}
注:代码中AjaxResult类只是一个用于数据返回的类,这里就不贴出来了 ):
三、测试结果
没有写前端页面,所以就用Api工具测了一下,可以看到已经可以调起支付了,后续放到服务器上测一下回调就结束了,嘻嘻~~~
- -THE END- -
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持!!!