您现在的位置是:主页 > news > 广州网站设计价格/黑马培训价目表

广州网站设计价格/黑马培训价目表

admin2025/6/2 3:20:33news

简介广州网站设计价格,黑马培训价目表,网站 cms,网页美工设计实训中职期末试卷SpringBoot 集成支付宝(支付宝支付、支付宝转账[提现功能])支付宝支付(APP支付【普通模式】)1.登录支付宝开放平台1.在控制台查看自己的移动应用,没有的需要创建2.查看自己应用的APPID,并且有APP支付的能力…

广州网站设计价格,黑马培训价目表,网站 cms,网页美工设计实训中职期末试卷SpringBoot 集成支付宝(支付宝支付、支付宝转账[提现功能])支付宝支付(APP支付【普通模式】)1.登录支付宝开放平台1.在控制台查看自己的移动应用,没有的需要创建2.查看自己应用的APPID,并且有APP支付的能力…

SpringBoot 集成支付宝(支付宝支付、支付宝转账[提现功能])

  • 支付宝支付(APP支付【普通模式】)
    • 1.登录支付宝开放平台
      • 1.在控制台查看自己的移动应用,没有的需要创建
      • 2.查看自己应用的APPID,并且有APP支付的能力
      • 3.设置接口加签方式
        • 1.进来就是下面这个页面,我们选择的是公钥模式。
        • 2.支付宝密钥需要使用支付宝的生产工具生成
        • 3.使用工具生成应用私钥、公钥
        • 4.将应用公钥复制到刚刚的页面,并点击保存设置
        • 5.得到了我们需要的支付宝公钥
    • 2. 导入依赖
    • 3.创建支付宝配置类
    • 4.这下可以开始自己的业务模块了
      • 1.创建服务接口
      • 2.创建接口实现类
      • 3. 创建自己的控制类
  • 支付宝支付(APP支付证书模式)
    • 1.登录支付宝开发平台
      • 1.获取自己的APPID,并获取到支付功能
      • 2.设置接口加签方式
        • 1. 打开我们的支付宝密钥生成工具,获取CSR文件。
        • 2. 设置接口加密方式,这里我们要选择公钥证书
    • 2.导入依赖
    • 3.创建支付宝配置类
    • 4. 业务模块
      • 1. 业务接口
      • 2. 接口实现类
  • 支付宝支付(网页扫码支付【证书模式】)
    • 1.登录支付宝开放平台
      • 1.获取自己的APPID,开通支付功能
      • 2.设置接口加签方式
        • 1. 打开我们的支付宝密钥生成工具,获取CSR文件。
        • 2.设置接口加密方式,这里我们要选择公钥证书
    • 2.导入依赖
    • 3.创建支付宝配置类
    • 4.开始自己的业务模块
      • 1.创建服务接口
      • 2.创建接口实现类
      • 3.创建控制类

支付宝支付(APP支付【普通模式】)

1.登录支付宝开放平台

支付宝开放平台

1.在控制台查看自己的移动应用,没有的需要创建

在这里插入图片描述

2.查看自己应用的APPID,并且有APP支付的能力

在这里插入图片描述

3.设置接口加签方式

在这里插入图片描述

1.进来就是下面这个页面,我们选择的是公钥模式。

在这里插入图片描述

2.支付宝密钥需要使用支付宝的生产工具生成

下载地址:支付宝密钥生产器
选择自己的版本下载安装、再打开。
在这里插入图片描述

3.使用工具生成应用私钥、公钥

这里的应用私钥在接口需要使用,需要保存下来
在这里插入图片描述

4.将应用公钥复制到刚刚的页面,并点击保存设置

在这里插入图片描述

5.得到了我们需要的支付宝公钥

在这里插入图片描述
到这里我们的准备工作都做完了,所需要的也都拿到了。

2. 导入依赖

<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
<dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.15.12.ALL</version>
</dependency>

3.创建支付宝配置类


/*** 支付宝支付* @author Lenovo*/
public class AlipayConfig {/*** 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号*/public static String APP_ID = "APPID";/*** 商户私钥,您的PKCS8格式RSA2私钥,这些就是我们刚才设置的*/public static String MERCHANT_PRIVATE_KEY = "应用私钥";/*** 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。,这些就是我们刚才设置的*/public static String ALIPAY_PUBLIC_KEY = "支付宝公钥";/*** 异步通知,再这里我们设计自己的后台代码*/public static String notify_url = "异步回调url/alipay/notify";/*** 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问*/public static String return_url = "同步回调url/alipay/return";/*** 签名方式  固定*/public static String SIGN_TYPE = "RSA2";/*** 字符编码格式  固定*/public static String CHARSET = "utf-8";/*** 支付宝网关  正式环境*/public static String GATEWAYURL = "https://openapi.alipay.com/gateway.do";}

4.这下可以开始自己的业务模块了

1.创建服务接口


import com.alipay.api.AlipayApiException;/*** 支付接口** @author Lenovo*/
public interface AlipayService {/*** app端订单支付** @param outTradeNo  订单编号* @param totalAmount 订单价格* @param subject     商品名称*/String appPagePay(String outTradeNo, Double totalAmount, String subject, String passbackParams) throws Exception;/*** 退款** @param outTradeNo   订单编号* @param refundReason 退款原因* @param refundAmount 退款金额* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传*/String refund(String outTradeNo, String refundReason, Integer refundAmount, String outRequestNo) throws AlipayApiException;/*** 交易查询** @param outTradeNo 订单编号(唯一)*/String query(String outTradeNo) throws AlipayApiException;/*** 交易关闭** @param outTradeNo 订单编号(唯一)*/String close(String outTradeNo) throws AlipayApiException;/*** 退款查询** @param outTradeNo   订单编号(唯一)* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传*/String refundQuery(String outTradeNo, String outRequestNo) throws AlipayApiException;
}

2.创建接口实现类


import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.*;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.daosheng.project.common.config.AlipayConfig;
import com.daosheng.project.service.AlipayService;
import org.springframework.stereotype.Service;/*** 支付实现类** @author Lenovo*/
@Service("alipayService")
public class AlipayServiceImpl implements AlipayService {/*** 调取支付宝接口app端支付*/AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.GATEWAYURL, AlipayConfig.APP_ID, AlipayConfig.MERCHANT_PRIVATE_KEY, "json", AlipayConfig.CHARSET, AlipayConfig.ALIPAY_PUBLIC_KEY, AlipayConfig.SIGN_TYPE);/*** app端订单支付** @param outTradeNo  订单编号* @param totalAmount 订单价格(元)* @param subject     商品名称*/@Overridepublic String appPagePay(String outTradeNo, Double totalAmount, String subject, String passbackParams) throws Exception {AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();/** 同步通知,支付完成后,支付成功页面*/alipayRequest.setReturnUrl(AlipayConfig.return_url);/** 异步通知,支付完成后,需要进行的异步处理*/alipayRequest.setNotifyUrl(AlipayConfig.notify_url);/**销售产品码(固定)*/String productCode = "QUICK_WAP_WAY";/** 进行赋值 */AlipayTradeWapPayModel wapPayModel = new AlipayTradeWapPayModel();wapPayModel.setOutTradeNo(outTradeNo);wapPayModel.setSubject(subject);wapPayModel.setTotalAmount(totalAmount.toString());wapPayModel.setBody("商品名称");//超时时间wapPayModel.setTimeoutExpress("2m");wapPayModel.setProductCode(productCode);wapPayModel.setPassbackParams(passbackParams);alipayRequest.setBizModel(wapPayModel);/** 格式转换*/AlipayTradeAppPayResponse payResponse = alipayClient.sdkExecute(alipayRequest);String result = payResponse.getBody().replace('\"', '\'').replace('\n', ' ');return result;}/*** 退款** @param outTradeNo   订单编号* @param refundReason 退款原因* @param refundAmount 退款金额* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传*/@Overridepublic String refund(String outTradeNo, String refundReason, Integer refundAmount, String outRequestNo) throws AlipayApiException {AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();/** 调取接口*/alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\","+ "\"refund_amount\":\"" + refundAmount + "\","+ "\"refund_reason\":\"" + refundReason + "\","+ "\"out_request_no\":\"" + outRequestNo + "\"}");String result = alipayClient.execute(alipayRequest).getBody();return result;}/*** 交易查询** @param outTradeNo 订单编号(唯一)*/@Overridepublic String query(String outTradeNo) throws AlipayApiException {AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();/**请求接口*/alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"," + "\"trade_no\":\"" + "" + "\"}");/**转换格式*/String result = alipayClient.execute(alipayRequest).getBody();return result;}/*** 交易关闭** @param outTradeNo 订单编号(唯一)*/@Overridepublic String close(String outTradeNo) throws AlipayApiException {AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"," + "\"trade_no\":\"" + "" + "\"}");String result = alipayClient.execute(alipayRequest).getBody();return result;}/*** 退款查询** @param outTradeNo   订单编号(唯一)* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传*/@Overridepublic String refundQuery(String outTradeNo, String outRequestNo) throws AlipayApiException {AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();/** 请求接口*/alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\","+ "\"out_request_no\":\"" + outRequestNo + "\"}");/** 格式转换*/String result = alipayClient.execute(alipayRequest).getBody();return result;}}

3. 创建自己的控制类


import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.daosheng.project.common.aop.annotation.NoRepeatSubmit;
import com.daosheng.project.common.config.AlipayConfig;
import com.daosheng.project.common.utils.DataResult;
import com.daosheng.project.common.utils.RandomNickNameUtils;
import com.daosheng.project.common.utils.SnowflakeUtils;
import com.daosheng.project.pojo.vo.req.PayReq;
import com.daosheng.project.service.AlipayService;
import com.daosheng.project.service.UserinfoService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.Instant;
import java.util.HashMap;
import java.util.Map;/*** 支付宝** @author Lenovo*/
@RestController
@RequestMapping("/alipay")
@Api(tags = "支付宝支付")
public class AlipayController {@Autowired@Qualifier("alipayService")private AlipayService alipayService;@Resourceprivate UserinfoService userinfoService;/*** app 订单支付*/@PostMapping("getAppPagePay")@ApiOperation(value = "app支付")@NoRepeatSubmitpublic DataResult getAppPagePay(@RequestBody @Validated PayReq payReq) throws Exception {/** 模仿数据库,从后台调数据*///订单号String outTradeNo = SnowflakeUtils.nextIdStr();Double totalAmount = 0.01;String subject = RandomNickNameUtils.getRandomJianHan(5);String s = JSONObject.toJSONString(payReq);String pay = alipayService.appPagePay(outTradeNo, totalAmount, subject, s);return DataResult.success(pay);}/*** 异步通知** @param request* @throws Exception*/@RequestMapping("/notify")@ApiOperation(value = "支付宝异步通知", hidden = true)public String notify(HttpServletRequest request) throws Exception {if (check(request.getParameterMap())) {System.out.println(request.getParameter("trade_status"));System.out.println("异步通知 " + Instant.now());Map<String, String[]> params = request.getParameterMap();Map<String, String> paramters = new HashMap<>();for (Map.Entry<String, String[]> entry : params.entrySet()) {paramters.put(entry.getKey(), entry.getValue()[0]);}String trade_no = paramters.get("trade_no");String out_trade_no = paramters.get("out_trade_no");String total_amount = paramters.get("total_amount");// 订单金额/** 支付状态*/String trade_status = paramters.get("trade_status");if ("TRADE_SUCCESS".equals(trade_status)) {String passbackParams = paramters.get("passback_params");PayReq aliPayReq = JSONObject.parseObject(passbackParams, PayReq.class);userinfoService.payment("2", aliPayReq.getType(), out_trade_no, trade_no,aliPayReq.getUserId(), aliPayReq.getLevel(), aliPayReq.getLevelName(), aliPayReq.getAmount());/** 支付成功*/return "success";}return "failure";} else {System.out.println("验签失败");return "failure";}}/*** SDK验证签名** @param requestParams* @return* @throws Exception*/private boolean check(Map<String, String[]> requestParams) throws Exception {// 获取支付宝响应参数Map<String, String> paramters = new HashMap<>();for (Map.Entry<String, String[]> entry : requestParams.entrySet()) {paramters.put(entry.getKey(), entry.getValue()[0]);}return AlipaySignature.rsaCheckV1(paramters, AlipayConfig.ALIPAY_PUBLIC_KEY,AlipayConfig.CHARSET, AlipayConfig.SIGN_TYPE); //调用SDK验证签名}/*** 交易查询** @param outTradeNo 订单号*/@PostMapping("aipayQuery")public DataResult alipayQuery(String outTradeNo) throws Exception {/**调取支付订单号*/outTradeNo = "13123";String query = alipayService.query(outTradeNo);Object json = JSONObject.toJSON(query);/*JSONObject jObject = new JSONObject();jObject.get(query);*/return DataResult.success(json);}/*** 退款** @throws AlipayApiException*/@PostMapping("alipayRefund")public DataResult alipayRefund(@RequestParam("outTradeNo") String outTradeNo,@RequestParam(value = "outRequestNo", required = false) String outRequestNo,@RequestParam(value = "refundAmount", required = false) Integer refundAmount) throws AlipayApiException {/** 调取数据*///String outTradeNo = "15382028806591197";String refundReason = "用户不想购买";//refundAmount = 1;//outRequestNo = "22";String refund = alipayService.refund(outTradeNo, refundReason, refundAmount, outRequestNo);System.out.println(refund);return DataResult.success(refund);}/*** 退款查询** @throws AlipayApiException*/@PostMapping("refundQuery")public DataResult refundQuery() throws AlipayApiException {/** 调取数据*/String outTradeNo = "13123";String outRequestNo = "2";String refund = alipayService.refundQuery(outTradeNo, outRequestNo);return DataResult.success(refund);}/*** 交易关闭** @throws AlipayApiException*/@PostMapping("alipayclose")public DataResult alipaycolse() throws AlipayApiException {/** 调取数据*/String outTradeNo = "13123";String close = alipayService.close(outTradeNo);return DataResult.success(close);}}

支付宝支付(APP支付证书模式)

1.登录支付宝开发平台

支付宝开发平台

1.获取自己的APPID,并获取到支付功能

这个在上述APP支付有详细描述

2.设置接口加签方式

1. 打开我们的支付宝密钥生成工具,获取CSR文件。

点击获取CSR文件,完善一下信息。
在这里插入图片描述
填写完信息后,点击生成CSR文件。下面的私钥和公钥都保存好,在本地也有文件保存的。
在这里插入图片描述

2. 设置接口加密方式,这里我们要选择公钥证书

在这里插入图片描述
这里上传我们工具生成的CSR文件。
在这里插入图片描述
上传完成之后再次打开接口加签设置就可以下载证书了。
在这里插入图片描述

把三个证书下载下来并保存到项目resources目录下面,我这里放在/static/cert/alipay下。

2.导入依赖

这里的依赖用的4.13.50.ALL版本

        <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.13.50.ALL</version></dependency>

3.创建支付宝配置类


/*** @author Lenovo*/
public class AlipayConfig {/*** 应用公钥证书路径*/public static final String APP_CERT_PATH = "static/cert/alipay/appCertPublicKey_2021001145671220.crt";/*** 支付宝公钥证书路径*/public static final String ALIPAY_CERT_PATH = "static/cert/alipay/alipayCertPublicKey_RSA2.crt";/*** 支付宝根证书路径*/public static final String ALIPAY_ROOT_CERT_PATH = "static/cert/alipay/alipayRootCert.crt";/*** 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号,开发时使用沙箱提供的APPID,生产环境改成自己的APPID*/public static String app_id = "APPID";/*** 私钥,您的PKCS8格式RSA2私钥(应用私钥)*/public static String merchant_private_key = "应用私钥";/*** 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(可以使用natapp内容穿透完成外网设置)*/public static String notify_url = "异步通知url/web/aliPay/aliPayCallBack";/*** 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问*/public static String return_url = "同步通知url";/*** 签名方式  固定*/public static String sign_type = "RSA2";/*** 字符编码格式  固定*/public static String charset = "utf-8";/*** 支付宝网关   开发环境*/public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";}

4. 业务模块

1. 业务接口

import com.alipay.api.AlipayApiException;import java.io.FileNotFoundException;
import java.rmi.ServerException;/*** 支付接口** @author Lenovo*/
public interface AlipayService {/*** app端订单支付** @param outTradeNo  订单编号* @param totalAmount 订单价格* @param subject     商品名称*/String appPagePay(String outTradeNo, Double totalAmount, String subject, String passbackParams) throws Exception;/*** 退款** @param outTradeNo   订单编号* @param refundReason 退款原因* @param refundAmount 退款金额* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传*/String refund(String outTradeNo, String refundReason, Integer refundAmount, String outRequestNo) throws AlipayApiException, ServerException, FileNotFoundException;/*** 交易查询** @param outTradeNo 订单编号(唯一)*/String query(String outTradeNo) throws AlipayApiException, ServerException, FileNotFoundException;/*** 交易关闭** @param outTradeNo 订单编号(唯一)*/String close(String outTradeNo) throws AlipayApiException, ServerException, FileNotFoundException;/*** 退款查询** @param outTradeNo   订单编号(唯一)* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传*/String refundQuery(String outTradeNo, String outRequestNo) throws AlipayApiException, ServerException, FileNotFoundException;
}

2. 接口实现类

package com.daosheng.project.service.impl;import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.request.*;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.daosheng.project.common.config.AlipayConfig;
import com.daosheng.project.service.AlipayService;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;import java.io.*;
import java.rmi.ServerException;/*** 支付实现类** @author Lenovo*/
@Service("alipayService")
public class AlipayServiceImpl implements AlipayService {private static AlipayClient alipayClient;/*** 单例模式* 初始化 支付宝 客户端*/private static AlipayClient initAlipayClient() throws ServerException, FileNotFoundException, AlipayApiException {if (alipayClient == null) {synchronized (AlipayServiceImpl.class) {if (alipayClient == null) {String basePath = queryPath();// 构造clientCertAlipayRequest certAlipayRequest = new CertAlipayRequest();// 设置网关地址certAlipayRequest.setServerUrl(AlipayConfig.GATEWAYURL);// 设置应用IdcertAlipayRequest.setAppId(AlipayConfig.APP_ID);// 设置应用私钥certAlipayRequest.setPrivateKey(AlipayConfig.MERCHANT_PRIVATE_KEY);// 设置请求格式,固定值jsoncertAlipayRequest.setFormat("json");// 设置字符集certAlipayRequest.setCharset(AlipayConfig.CHARSET);// 设置签名类型certAlipayRequest.setSignType(AlipayConfig.SIGN_TYPE);// 设置应用公钥证书路径certAlipayRequest.setCertPath(basePath + AlipayConfig.APP_CERT_PATH);// 设置支付宝公钥证书路径certAlipayRequest.setAlipayPublicCertPath(basePath + AlipayConfig.ALIPAY_CERT_PATH);// 设置支付宝根证书路径certAlipayRequest.setRootCertPath(basePath + AlipayConfig.ALIPAY_ROOT_CERT_PATH);// 构造clientalipayClient = new DefaultAlipayClient(certAlipayRequest);}}}return alipayClient;}/*** 证书模式   获取文件路径* 不这样把证书复制出来服务器上会获取不到证书路径** @return* @throws FileNotFoundException* @throws ServerException*/public static String queryPath() throws FileNotFoundException, ServerException {String basePath = ResourceUtils.getURL("classpath:").getPath();basePath = initCart(basePath);return basePath;}/*** 证书模式 初始化证书文件** @param basePath* @return* @throws ServerException*/private static String initCart(String basePath) throws ServerException {if (basePath.contains("jar!")) {if (basePath.startsWith("file:")) {basePath = basePath.replace("file:", "");}String appCertPath = AlipayConfig.APP_CERT_PATH;checkAndcopyCart(basePath, appCertPath);String alipayCertPath = AlipayConfig.ALIPAY_CERT_PATH;checkAndcopyCart(basePath, alipayCertPath);String alipayRootCertPath = AlipayConfig.ALIPAY_ROOT_CERT_PATH;checkAndcopyCart(basePath, alipayRootCertPath);}return basePath;}/*** 证书模式下需要** @param basePath* @param path* @throws ServerException* @description 查找在该文件路径下是否已经存在这个文件,如果不存在,则拷贝文件*/private static void checkAndcopyCart(String basePath, String path) throws ServerException {InputStream cartInputStream = null;OutputStream cartOutputStream = null;String cartPath = basePath + path;File cartFile = new File(cartPath);File parentFile = cartFile.getParentFile();parentFile.mkdirs();try {if (!cartFile.exists()) {cartInputStream = ClassUtils.getDefaultClassLoader().getResourceAsStream(path);cartOutputStream = new FileOutputStream(cartFile);byte[] buf = new byte[1024];int bytesRead;while ((bytesRead = cartInputStream.read(buf)) != -1) {cartOutputStream.write(buf, 0, bytesRead);}cartInputStream.close();cartOutputStream.close();}} catch (IOException e) {throw new ServerException(e.getMessage());}}/*** app端订单支付** @param outTradeNo  订单编号* @param totalAmount 订单价格(元)* @param subject     商品名称*/@Overridepublic String appPagePay(String outTradeNo, Double totalAmount, String subject, String passbackParams) throws Exception {AlipayTradeAppPayRequest alipayRequest = new AlipayTradeAppPayRequest();/** 同步通知,支付完成后,支付成功页面*/alipayRequest.setReturnUrl(AlipayConfig.return_url);/** 异步通知,支付完成后,需要进行的异步处理*/alipayRequest.setNotifyUrl(AlipayConfig.notify_url);/**销售产品码(固定)*/String productCode = "QUICK_WAP_WAY";/** 进行赋值 */AlipayTradeWapPayModel wapPayModel = new AlipayTradeWapPayModel();wapPayModel.setOutTradeNo(outTradeNo);wapPayModel.setSubject(subject);
//        wapPayModel.setTotalAmount(totalAmount.toString());wapPayModel.setTotalAmount("0.01");wapPayModel.setBody("商品名称");//超时时间wapPayModel.setTimeoutExpress("2m");wapPayModel.setProductCode(productCode);wapPayModel.setPassbackParams(passbackParams);alipayRequest.setBizModel(wapPayModel);/** 请求接口*/alipayClient = initAlipayClient();AlipayTradeAppPayResponse payResponse = alipayClient.sdkExecute(alipayRequest);String result = payResponse.getBody().replace('\"', '\'').replace('\n', ' ');return result;}/*** 退款** @param outTradeNo   订单编号* @param refundReason 退款原因* @param refundAmount 退款金额* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传*/@Overridepublic String refund(String outTradeNo, String refundReason, Integer refundAmount, String outRequestNo) throws AlipayApiException, ServerException, FileNotFoundException {AlipayTradeRefundRequest alipayRequest = new AlipayTradeRefundRequest();/** 调取接口*/alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\","+ "\"refund_amount\":\"" + refundAmount + "\","+ "\"refund_reason\":\"" + refundReason + "\","+ "\"out_request_no\":\"" + outRequestNo + "\"}");alipayClient = initAlipayClient();String result = alipayClient.execute(alipayRequest).getBody();return result;}/*** 交易查询** @param outTradeNo 订单编号(唯一)*/@Overridepublic String query(String outTradeNo) throws AlipayApiException, ServerException, FileNotFoundException {AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();/**请求接口*/alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"," + "\"trade_no\":\"" + "" + "\"}");alipayClient = initAlipayClient();String result = alipayClient.execute(alipayRequest).getBody();return result;}/*** 交易关闭** @param outTradeNo 订单编号(唯一)*/@Overridepublic String close(String outTradeNo) throws AlipayApiException, ServerException, FileNotFoundException {AlipayTradeCloseRequest alipayRequest = new AlipayTradeCloseRequest();alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\"," + "\"trade_no\":\"" + "" + "\"}");alipayClient = initAlipayClient();String result = alipayClient.execute(alipayRequest).getBody();return result;}/*** 退款查询** @param outTradeNo   订单编号(唯一)* @param outRequestNo 标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传*/@Overridepublic String refundQuery(String outTradeNo, String outRequestNo) throws AlipayApiException, ServerException, FileNotFoundException {AlipayTradeFastpayRefundQueryRequest alipayRequest = new AlipayTradeFastpayRefundQueryRequest();/** 请求接口*/alipayRequest.setBizContent("{\"out_trade_no\":\"" + outTradeNo + "\","+ "\"out_request_no\":\"" + outRequestNo + "\"}");alipayClient = initAlipayClient();String result = alipayClient.execute(alipayRequest).getBody();return result;}
}

支付宝支付(网页扫码支付【证书模式】)

1.登录支付宝开放平台

1.获取自己的APPID,开通支付功能

这个在上述APP支付有详细描述

2.设置接口加签方式

1. 打开我们的支付宝密钥生成工具,获取CSR文件。

点击获取CSR文件,完善一下信息。
在这里插入图片描述
填写完信息后,点击生成CSR文件。下面的私钥和公钥都保存好,在本地也有文件保存的。
在这里插入图片描述

2.设置接口加密方式,这里我们要选择公钥证书

在这里插入图片描述
这里上传我们工具生成的CSR文件。
在这里插入图片描述
上传完成之后再次打开接口加签设置就可以下载证书了。
在这里插入图片描述

把三个证书下载下来并保存到项目resources目录下面。

2.导入依赖

这里的依赖用的4.13.50.ALL版本

        <!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java --><dependency><groupId>com.alipay.sdk</groupId><artifactId>alipay-sdk-java</artifactId><version>4.13.50.ALL</version></dependency>

3.创建支付宝配置类


/*** @author Lenovo*/
public class AlipayConfig {/*** 应用公钥证书路径*/public static final String APP_CERT_PATH = "static/cert/alipay/appCertPublicKey_2021001145671220.crt";/*** 支付宝公钥证书路径*/public static final String ALIPAY_CERT_PATH = "static/cert/alipay/alipayCertPublicKey_RSA2.crt";/*** 支付宝根证书路径*/public static final String ALIPAY_ROOT_CERT_PATH = "static/cert/alipay/alipayRootCert.crt";/*** 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号,开发时使用沙箱提供的APPID,生产环境改成自己的APPID*/public static String app_id = "APPID";/*** 私钥,您的PKCS8格式RSA2私钥(应用私钥)*/public static String merchant_private_key = "应用私钥";/*** 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问(可以使用natapp内容穿透完成外网设置)*/public static String notify_url = "异步通知url/web/aliPay/aliPayCallBack";/*** 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问*/public static String return_url = "同步通知url";/*** 签名方式  固定*/public static String sign_type = "RSA2";/*** 字符编码格式  固定*/public static String charset = "utf-8";/*** 支付宝网关   开发环境*/public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";}

4.开始自己的业务模块

代码里面有我的一些业务处理类,可随意删除!!!

1.创建服务接口


import com.alipay.api.AlipayApiException;
import com.ddz.project.pojo.vo.req.AliPayReq;import javax.servlet.http.HttpServletRequest;
import java.io.FileNotFoundException;
import java.rmi.ServerException;
import java.util.Map;/*** @program: translation-api* @description 支付宝支付* @author: ddz* @create: 2021-05-12 23:07**/
public interface AliPayService {/*** 获得支付页面** @param aliPayReq @return* @param request* @return*/String aliPayLine(AliPayReq aliPayReq, HttpServletRequest request) throws AlipayApiException, ServerException, FileNotFoundException;/*** 获取异步返回的参数** @param requestParams* @return*/Map<String, String> getAliParams(Map requestParams);//    /**
//     * 异步通知
//     * @param request
//     * @param response
//     * @return
//     */
//    Object notify(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException;/*** 查看订单** @return*/String query(String orderNo) throws AlipayApiException;
}

2.创建接口实现类


import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.CertAlipayRequest;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
import com.ddz.project.common.config.AlipayConfig;
import com.ddz.project.common.utils.RedisUtil;
import com.ddz.project.entity.PayOrder;
import com.ddz.project.entity.SetMealVersion;
import com.ddz.project.mapper.PayOrderMapper;
import com.ddz.project.mapper.SetMealVersionMapper;
import com.ddz.project.pojo.vo.req.AliPayReq;
import com.ddz.project.service.AliPayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.rmi.ServerException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;/*** @program: translation-api* @description 网页支付宝支付* @author: ddz* @create: 2021-05-12 23:07**/
@Slf4j
@Service
public class AliPayServiceImpl implements AliPayService {@Resourceprivate PayOrderMapper payOrderMapper;@Resourceprivate SetMealVersionMapper setMealVersionMapper;@Resourceprivate RedisUtil redisUtil;/*** 证书模式   获取文件路径** @return* @throws FileNotFoundException* @throws ServerException*/public String queryPath() throws FileNotFoundException, ServerException {String basePath = ResourceUtils.getURL("classpath:").getPath();basePath = this.initCart(basePath);return basePath;}/*** 证书模式 初始化证书文件** @param basePath* @return* @throws ServerException*/private String initCart(String basePath) throws ServerException {if (basePath.contains("jar!")) {if (basePath.startsWith("file:")) {basePath = basePath.replace("file:", "");}String appCertPath = AlipayConfig.APP_CERT_PATH;this.checkAndcopyCart(basePath, appCertPath);String alipayCertPath = AlipayConfig.ALIPAY_CERT_PATH;this.checkAndcopyCart(basePath, alipayCertPath);String alipayRootCertPath = AlipayConfig.ALIPAY_ROOT_CERT_PATH;this.checkAndcopyCart(basePath, alipayRootCertPath);}return basePath;}/*** 证书模式下需要** @param basePath* @param path* @throws ServerException* @description 查找在该文件路径下是否已经存在这个文件,如果不存在,则拷贝文件*/private void checkAndcopyCart(String basePath, String path) throws ServerException {InputStream cartInputStream = null;OutputStream cartOutputStream = null;String cartPath = basePath + path;File cartFile = new File(cartPath);File parentFile = cartFile.getParentFile();parentFile.mkdirs();try {if (!cartFile.exists()) {cartInputStream = ClassUtils.getDefaultClassLoader().getResourceAsStream(path);cartOutputStream = new FileOutputStream(cartFile);byte[] buf = new byte[1024];int bytesRead;while ((bytesRead = cartInputStream.read(buf)) != -1) {cartOutputStream.write(buf, 0, bytesRead);}cartInputStream.close();cartOutputStream.close();}} catch (IOException e) {throw new ServerException(e.getMessage());}}/*** 构建client** @return* @throws AlipayApiException* @throws ServerException* @throws FileNotFoundException*/public AlipayClient initAlipayClient() throws AlipayApiException, ServerException, FileNotFoundException {String basePath = this.queryPath();// 构造clientCertAlipayRequest certAlipayRequest = new CertAlipayRequest();// 设置网关地址certAlipayRequest.setServerUrl(AlipayConfig.gatewayUrl);// 设置应用IdcertAlipayRequest.setAppId(String.valueOf(redisUtil.getHash(AlipayConfig.ZFB_CACHE, AlipayConfig.ZFB_APP_ID)));// 设置应用私钥certAlipayRequest.setPrivateKey(String.valueOf(redisUtil.getHash(AlipayConfig.ZFB_CACHE, AlipayConfig.ZFB_PRIVATE_KEY)));// 设置请求格式,固定值jsoncertAlipayRequest.setFormat("json");// 设置字符集certAlipayRequest.setCharset(AlipayConfig.charset);// 设置签名类型certAlipayRequest.setSignType(AlipayConfig.sign_type);// 设置应用公钥证书路径certAlipayRequest.setCertPath(basePath + AlipayConfig.APP_CERT_PATH);// 设置支付宝公钥证书路径certAlipayRequest.setAlipayPublicCertPath(basePath + AlipayConfig.ALIPAY_CERT_PATH);// 设置支付宝根证书路径certAlipayRequest.setRootCertPath(basePath + AlipayConfig.ALIPAY_ROOT_CERT_PATH);// 构造clientAlipayClient alipayClient = new DefaultAlipayClient(certAlipayRequest);return alipayClient;}/*** 获得支付页面** @param aliPayReq @return* @param request* @return*/@Overridepublic String aliPayLine(AliPayReq aliPayReq, HttpServletRequest request) throws AlipayApiException, ServerException, FileNotFoundException {AlipayClient alipayClient = this.initAlipayClient();String out_trade_no = "ZFB" + DateUtil.current(true);/** 生成预支付订单 存入数据库*/PayOrder payOrder = new PayOrder();payOrder.setUserId(aliPayReq.getUserId());payOrder.setOrderNo(out_trade_no);payOrder.setOriginalAmount(aliPayReq.getAmount());payOrder.setDiscountAmount(0);SetMealVersion setMealVersion = setMealVersionMapper.selectById(aliPayReq.getSetMealId());payOrder.setOrderType(setMealVersion.getVersionName());payOrder.setActualAmount(aliPayReq.getAmount());// 支付状态 1:支付中 2:支付成功 3:支付失败(未付款交易超时关闭,或支付完成后全额退款)4:交易结束,不可退款payOrder.setStatus("1");// 1:微信 2:支付宝payOrder.setPayType("2");payOrderMapper.insert(payOrder);String total_amount = String.valueOf(aliPayReq.getAmount());String subject = "用户" + aliPayReq.getUserId() + "支付订单";String body = subject;// 设置请求参数AlipayTradePagePayRequest aliRequest = new AlipayTradePagePayRequest();// 设置回调地址aliRequest.setReturnUrl(AlipayConfig.return_url);aliRequest.setNotifyUrl(AlipayConfig.notify_url);// 封装参数,以及自己需要的参数 如果请求时传递了该参数,则返回给商户时会回传该参数。支付宝会在异步通知时将该参数原样返回AlipayTradePagePayModel model = new AlipayTradePagePayModel();model.setOutTradeNo(out_trade_no);// TODO: 2021/5/24 测试金额model.setTotalAmount("0.01");model.setSubject(subject);model.setBody(body);model.setTimeoutExpress("30m");model.setProductCode("FAST_INSTANT_TRADE_PAY");String json = JSONObject.toJSONString(aliPayReq);// 附加参数model.setPassbackParams(json);aliRequest.setBizModel(model);//请求,返回的数据由前端进行解析String result = alipayClient.pageExecute(aliRequest).getBody();return result;}/*** 获取阿里支付回调的数据拼装 验签,该方法在同步回调,异步回调时,必须要用到的*/@Overridepublic Map<String, String> getAliParams(Map requestParams) {Map<String, String> params = new HashMap<String, String>();for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {String name = (String) iter.next();String[] values = (String[]) requestParams.get(name);String valueStr = "";for (int i = 0; i < values.length; i++) {valueStr = (i == values.length - 1) ? valueStr + values[i]: valueStr + values[i] + ",";}params.put(name, valueStr);}return params;}//    /**
//     * 异步通知
//     *
//     * @param request
//     * @param response
//     * @return
//     */
//    @Override
//    @Transactional
//    public Object notify(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException {
//        // 获得返回的参数
//        Map<String, String> params = this.getAliParams(request.getParameterMap());
//        //验证签名
//        boolean flag = AlipaySignature.rsaCheckV1(params, String.valueOf(redisUtil.getHash(AlipayConfig.ZFB_CACHE, AlipayConfig.ZFB_PUBLIC_KEY))
//                , "UTF-8", "RSA2");
//
//        // 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表
//        // 交易状态
//        String trade_status = request.getParameter("trade_status");
//
//        // 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表
//        // 验证成功
//        if (flag) {
//            if ("TRADE_SUCCESS".equals(trade_status)) {
//                log.info("支付宝订单支付成功!");
//                String out_trade_no = params.get("out_trade_no");
//                String passback_params = params.get("passback_params");
//                AliPayReq req = JSONObject.parseObject(passback_params, AliPayReq.class);
//                // 交易流水号
//                String trade_no = params.get("trade_no");
//            }
//            return "success";
//        } else {
//            System.out.println("签名验证不通过");
//            return "failure";
//        }
//    }/*** 查看订单** @param orderNo* @return*/@Overridepublic String query(String orderNo) throws AlipayApiException {//获得初始化的AlipayClientAlipayClient alipayClient = this.initAlipayClient();AlipayTradeQueryRequest alipayRequest = new AlipayTradeQueryRequest();/**请求接口*/AlipayTradePagePayModel model = new AlipayTradePagePayModel();model.setOutTradeNo(orderNo);alipayRequest.setBizModel(model);/**转换格式*/String result = alipayClient.certificateExecute(alipayRequest).getBody().replace('\"', '\'').replace('\n', ' ');log.info(result);JSONObject jsonObject = JSONObject.parseObject(result, JSONObject.class);JSONObject resp = (JSONObject) jsonObject.get("alipay_trade_query_response");String code = (String) resp.get("code");String status = "1";if ("40004".equals(code)) {status = "3";}String trade_status = (String) resp.get("trade_status");//支付成功||交易结束,不可退款if ("TRADE_SUCCESS".equals(trade_status) || "TRADE_FINISHED".equals(trade_status)) {status = "2";//交易创建,等待买家付款} else if ("WAIT_BUYER_PAY".equals(trade_status)) {status = "1";//未付款交易超时关闭,或支付完成后全额退款} else if ("TRADE_CLOSED".equals(trade_status)) {status = "3";}return status;}}

3.创建控制类


import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.ddz.project.common.config.AlipayConfig;
import com.ddz.project.common.utils.RedisUtil;
import com.ddz.project.pojo.vo.req.AliPayReq;
import com.ddz.project.service.AliPayService;
import com.ddz.project.service.PayOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
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.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;/*** @author Lenovo*/
@Slf4j
@RestController
@RequestMapping("web/aliPay")
@Api(tags = "支付宝支付")
public class AliPayController {@Resourceprivate AliPayService aliPayService;@Resourceprivate PayOrderService payOrderService;@Resourceprivate RedisUtil redisUtil;/*** 支付宝支付*/@GetMapping("alipayLine")@ApiOperation(value = "获取付款码")public void alipayLine(AliPayReq req, HttpServletRequest request, HttpServletResponse httpResponse) throws AlipayApiException, IOException {String form = aliPayService.aliPayLine(req, request);httpResponse.setContentType("text/html;charset=" + AlipayConfig.charset);httpResponse.getWriter().write(form);httpResponse.getWriter().flush();httpResponse.getWriter().close();}/*** 异步回调*/@PostMapping("/aliPayCallBack")@ApiOperation(value = "异步回调", hidden = true)public Object notify_url(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException {// 获得返回的参数Map<String, String> params = aliPayService.getAliParams(request.getParameterMap());//验证签名boolean flag = AlipaySignature.rsaCheckV1(params, String.valueOf(redisUtil.getHash(AlipayConfig.ZFB_CACHE, AlipayConfig.ZFB_PUBLIC_KEY)), "UTF-8", "RSA2");// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表String trade_status = request.getParameter("trade_status");// 获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表if (flag) {if (trade_status.equals("TRADE_SUCCESS")) {log.info("支付宝订单支付成功!");String out_trade_no = params.get("out_trade_no");String passback_params = params.get("passback_params");AliPayReq req = JSONObject.parseObject(passback_params, AliPayReq.class);// 交易流水号String trade_no = params.get("trade_no");/** 支付处理*/Integer amount = req.getAmount();payOrderService.payment("2", out_trade_no, trade_no, req.getUserId(), amount * 1.0, req.getSetMealId(), req.getCount());}//这里通知支付宝回调成功,不然一直回调log.info("\n=========\n支付回调成功");return "success";} else {return "failure";}}/*** 同步回调, 注意get请求*/@RequestMapping("/returnUrl")@ApiOperation(value = "同步回调", hidden = true)public void return_url(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException {// 调用方法进行验签Map<String, String> paramsMap = aliPayService.getAliParams(request.getParameterMap());boolean flag = AlipaySignature.rsaCheckV1(paramsMap, String.valueOf(redisUtil.getHash(AlipayConfig.ZFB_CACHE, AlipayConfig.ZFB_PUBLIC_KEY)), "UTF-8", "RSA2");if (flag) {//跳转支付成功界面try {response.sendRedirect("https://www.baidu.com");} catch (IOException e) {e.printStackTrace();}} else {System.out.println("flag=====验签失败");//跳转支付失败界面}}@PostMapping("/query")@ApiOperation(value = "查询订单")public Object query(String orderNo) throws Exception {return aliPayService.query(orderNo);}
}