Appearance
相关地址(服务器端回调地址、客户端支付成功/失败回调都在)的参数我们都使用枚举类进行管理,请求参数单独封装成一个对象进行参数传递,最后对支付功能再进行进一步的封装。
创建服务器回调地址枚举类
回调地址我们使用枚举类进行统一管理
java
/**
* @author cv大魔王
* @description 支付宝支付回调地址枚举类
* @date 2022/8/13
*/
public enum AlipayNotifyUrlEnum {
TEST_URL("/api/v1/ali/callback"),
COURSE_URL("/api/v1/ali/course/callback");
private String url;
AlipayNotifyUrlEnum(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
}
创建客户端支付成功回调地址枚举类
如果是网页支付,那么支付成功时,客户端会返回我们回调的地址页面,我们对这个地址也创建枚举类
java
/**
* @author cv大魔王
* @description 支付宝支付回调地址枚举类
* @date 2022/8/13
*/
public enum AlipayReturnUrlEnum {
COURSE_URL("/course/pay/success?orderId=");
private String url;
AlipayReturnUrlEnum(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
}
创建客户端支付失败回调地址枚举类
用户付款中途退出返回商户网站的地址,也就是用户没有真的付款所跳转的地址。
java
/**
* @author cv大魔王
* @description 支付宝支付回调地址枚举类
* @date 2022/8/13
*/
public enum AlipayReturnFailUrlEnum {
COURSE_URL("/course/pay/order?orderId=")
;
private String url;
AlipayReturnFailUrlEnum(String url) {
this.url = url;
}
public String getUrl() {
return url;
}
}
支付宝请求参数传递类
java
@Data
public class AlipayParam {
/**
* 服务器端回调地址,支付成功后支付宝将支付结果按这个地址进行通知
*/
private AlipayNotifyUrlEnum callbackEnum;
/**
* 客户端支付成功回调地址,用户支付成功后跳转回网页或APP
*/
private String returnUrl;
/**
* 订单id
*/
private String orderId;
/**
* 支付金额
*/
private BigDecimal price;
/**
* 商品标题或其他标注售卖物品的信息
*/
private String title;
/**
* 客户端用户支付中途取消支付后跳转回网页或APP
*/
private String returnFailUrl;
}
发送H5支付请求工具类
H5支付请求返回的是HTML页面,我们把页面直接返回出去即可
java
@Slf4j
@Component
public class AliPayUtils {
@Autowired
private AliPayConfig aliPayConfig;
@Autowired
private AlipayClient alipayClient;
public void aliPayH5(AlipayParam alipayParam, HttpServletResponse httpResponse) {
// 1.创建阿里云支付请求对象
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
request.setNotifyUrl(aliPayConfig.getNotifyDomain() + alipayParam.getCallbackEnum().getUrl());
request.setReturnUrl(aliPayConfig.getReturnDomain() + alipayParam.getReturnUrl());
// 2.获取支付统一JSON格式请求参数
JSONObject bizContent = getBizContent(alipayParam, aliPayConfig);
// 3.JSON中设置支付方式是H5支付
bizContent.put("product_code", "QUICK_WAP_WAY");
// 4.将json数据插入到请求体中
request.setBizContent(bizContent.toString());
AlipayTradeWapPayResponse response = null;
try {
// 5.注意请求方式
response = alipayClient.pageExecute(request);
if (response.isSuccess()) {
//直接将完整的表单html输出到页面
httpResponse.setContentType("text/html;charset=UTF-8");
httpResponse.getWriter().write(response.getBody());
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
} else {
throw new DefaultException(ResultEnum.ERROR);
}
} catch (AlipayApiException | IOException e) {
e.printStackTrace();
throw new DefaultException(ResultEnum.ERROR);
}
}
/**
* 封装支付统一请求参数,订单号、支付金额、商品标题等数据都是各个都需要的
*
* @return 请求信息JSON对象
*/
private JSONObject getBizContent(AlipayParam alipayParam, AliPayConfig aliPayConfig) {
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", alipayParam.getOrderId());
bizContent.put("total_amount", alipayParam.getPrice());
// 商品标题如果长度超过100则进行截取
bizContent.put("subject", alipayParam.getTitle().length() > 100 ? alipayParam.getTitle().substring(0, 100) : alipayParam.getTitle());
bizContent.put("quit_url", aliPayConfig.getReturnDomain() + alipayParam.getReturnFailUrl());
return bizContent;
}
}
H5支付接口开发
直接在浏览器输入请求地址即可,如果有内网穿透更好,直接手机浏览器访问接口地址,即可自动跳转到支付宝。
java
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.xk857.alipay.domain.AlipayParam;
import com.xk857.alipay.enums.AlipayNotifyUrlEnum;
import com.xk857.alipay.enums.AlipayReturnFailUrlEnum;
import com.xk857.alipay.enums.AlipayReturnUrlEnum;
import com.xk857.alipay.util.AliPayUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
@RestController
@RequestMapping("/api/v1/ali")
public class AlipayController {
@Autowired
private AliPayUtils aliPayUtils;
/**
* H5测试
*/
@GetMapping("/h5")
public void submitOrderAliPay(HttpServletRequest request, HttpServletResponse response) {
AlipayParam alipayParam = new AlipayParam();
alipayParam.setCallbackEnum(AlipayNotifyUrlEnum.TEST_URL);
String orderId = IdWorker.getIdStr();
log.info("H5生成的订单id是:{}",orderId);
alipayParam.setReturnUrl(AlipayReturnUrlEnum.COURSE_URL.getUrl()+orderId);
alipayParam.setOrderId(orderId);
alipayParam.setPrice(new BigDecimal("0.05"));
alipayParam.setTitle("5分钱测试订单");
alipayParam.setReturnFailUrl(AlipayReturnFailUrlEnum.COURSE_URL.getUrl()+orderId);
aliPayUtils.aliPayH5(alipayParam,response);
}
}
说明:其他的支付方法都大体相似,官网的例子也非常清晰明了,我这里主要是撰写在项目中应该如何对接支付宝支付,对其进行了一定的封装和优化,如果你有更好的封装方法欢迎评论区留言指出,网页/移动应用文档指引 - 支付宝文档中心