沙箱支付支付宝
文章目录
- 沙箱支付支付宝
- 一、进入沙箱应用-支付宝
- 二、基本配置
- 2.1 查看自己的基本信息
- 2.2 生成自定义密钥,进行配置
- 三、springboot整合沙箱支付
- 3.1 需要导入的两个相关依赖(pom.xml)
- 3.2 需要加入的配置文件信息(application.yml)
- 3.3 controller层
- 3.4 config
- 3.5 entity
- 3.6 启动
- 四、 NATAPP
- 4.1 获取免费渠道
- 4.2 配置authtoken,并运行
- 4.2.1选择【我的渠道】---【配置】
- 4.2.2 打开下载的NATAPP文件包
- 4.2.3 外网访问
一、进入沙箱应用-支付宝
沙箱应用-开发平台(支付宝):https://open.alipay.com/develop/sandbox/app
密钥下载: 密钥工具下载 - 支付宝文档中心 (alipay.com)
二、基本配置
2.1 查看自己的基本信息
这里查看自己的APPID、支付宝网关地址、选择自定义密钥,
用来交易的账号密码
2.2 生成自定义密钥,进行配置
将下载好的密钥工具打开,选择生成密钥
保存好公钥和私钥
· 公钥:是密钥对中公开的部分,用于加密会话密钥、验证数字签名,或加密可以用相应的私钥解密的数据
· 私钥:是非公开的部分,用于解密和签名
回到沙箱应用,选择设置并查看,将生成的密钥复制进去,
三、springboot整合沙箱支付
3.1 需要导入的两个相关依赖(pom.xml)
<!-- 支付宝依赖沙箱支付 -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.2.0</version>
</dependency>
<!-- 支付宝相关-->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.34.0.ALL</version>
</dependency>
3.2 需要加入的配置文件信息(application.yml)
alipay:
appId: (APPID)
appPrivateKey: (私钥)
alipayPublicKey: (公钥)
notifyUrl: http://见4.2.3/alipay/notify
3.3 controller层
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.easysdk.factory.Factory;
import com.cqie.config.AliPayConfig;
import com.cqie.entity.AliPay;
import com.cqie.entity.Orders;
import com.cqie.mapper.OrderMapper;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.transaction.annotation.Transactional;
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 java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("alipay")
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class AliPayController {
@Resource
AliPayConfig aliPayConfig;
// @Resource
private OrderMapper shopOrderMapper;
private static final String GATEWAY_URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
private static final String FORMAT = "JSON";
private static final String CHARSET = "utf-8";
private static final String SIGN_TYPE = "RSA2";
@GetMapping("/pay") // &subject=xxx&traceNo=xxx&totalAmount=xxx
public void pay(AliPay aliPay, HttpServletResponse httpResponse) throws Exception {
AlipayClient alipayClient = new DefaultAlipayClient(GATEWAY_URL, aliPayConfig.getAppId(),
aliPayConfig.getAppPrivateKey(), FORMAT, CHARSET, aliPayConfig.getAlipayPublicKey(), SIGN_TYPE);
AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
request.setNotifyUrl(aliPayConfig.getNotifyUrl());
request.setBizContent("{\"out_trade_no\":\"" + aliPay.getTraceNo() + "\","
+ "\"total_amount\":\"" + aliPay.getTotalAmount() + "\","
+ "\"subject\":\"" + aliPay.getSubject() + "\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
String form = "";
try {
// 调用SDK生成表单
form = alipayClient.pageExecute(request).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}
httpResponse.setContentType("text/html;charset=" + CHARSET);
// 直接将完整的表单html输出到页面
httpResponse.getWriter().write(form);
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
@PostMapping("/notify") // 注意这里必须是POST接口
public String payNotify(HttpServletRequest request) throws Exception {
log.info("回调执行操作");
if (request.getParameter("trade_status").equals("TRADE_SUCCESS")) {
System.out.println("=========支付宝异步回调========");
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
params.put(name, request.getParameter(name));
// System.out.println(name + " = " + request.getParameter(name));
}
String tradeNo = params.get("out_trade_no");
String gmtPayment = params.get("gmt_payment");
String alipayTradeNo = params.get("trade_no");
// 支付宝验签
if (Factory.Payment.Common().verifyNotify(params)) {
// 验签通过
System.out.println("交易名称: " + params.get("subject"));
System.out.println("交易状态: " + params.get("trade_status"));
System.out.println("支付宝交易凭证号: " + params.get("trade_no"));
System.out.println("商户订单号: " + params.get("out_trade_no"));
System.out.println("交易金额: " + params.get("total_amount"));
System.out.println("买家在支付宝唯一id: " + params.get("buyer_id"));
System.out.println("买家付款时间: " + params.get("gmt_payment"));
System.out.println("买家付款金额: " + params.get("buyer_pay_amount"));
// 更新订单未已支付
Orders order = new Orders();
order.setId(Long.valueOf(tradeNo));
order.setStatus(2);
// order.setCheckoutTime(params.get("gmt_payment"));
// shopOrderMapper.updateById(order);
}
}
return "success";
}
}
3.4 config
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import jakarta.annotation.PostConstruct;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Data
@Component
//读取yml文件中alipay 开头的配置
@ConfigurationProperties(prefix = "alipay")
public class AliPayConfig {
private String appId;
private String appPrivateKey;
private String alipayPublicKey;
private String notifyUrl;
@PostConstruct
public void init() {
// 设置参数(全局只需设置一次)
Config config = new Config();
config.protocol = "https";
config.gatewayHost = "openapi.alipaydev.com";
config.signType = "RSA2";
config.appId = this.appId;
config.merchantPrivateKey = this.appPrivateKey;
config.alipayPublicKey = this.alipayPublicKey;
config.notifyUrl = this.notifyUrl;
Factory.setOptions(config);
System.out.println("=======支付宝SDK初始化成功=======");
}
}
3.5 entity
import lombok.Data;
@Data
public class AliPay {
private String traceNo;
private double totalAmount;
private String subject;
private String alipayTraceNo;
}
3.6 启动
在浏览器url地址栏输入(subject-收款方 ,traceNo-支付方 , totalAmount-交易金额 )
http://localhost:8080/alipay/pay?subject=xxx&traceNo=xxx&totalAmount=1000
按照2.1的买方信息填入即可
四、 NATAPP
NATAPP是一款内网穿透工具,它可以把用户将本地服务器映射到公网上,使得在任何地点都能够访问到用户本地的应用或服务
4.1 获取免费渠道
首先进入 NATAPP-内网穿透 基于ngrok的国内高速内网映射工具 ,去注册一个新账号
然后购买一个免费渠道
这里的端口根据项目来就行(后面也可以改)
4.2 配置authtoken,并运行
下载地址: NATAPP-内网穿透 基于ngrok的国内高速内网映射工具
若下载无ini文件: 使用本地配置文件config.ini - NATAPP-内网穿透 基于ngrok的国内高速内网映射工具
4.2.1选择【我的渠道】—【配置】
复制authtoken
4.2.2 打开下载的NATAPP文件包
双击natapp.exe文件,出现下面样式就完成了
4.2.3 外网访问
只能被本地访问的: http://localhost:8080/alipay/pay?subject=xxx&traceNo=xxx&totalAmount=1000
可以被外网访问的: http://上图的地址.cc/alipay/pay?subject=xxx&traceNo=xxx&totalAmount=1000
手机端浏览器打开:
电脑浏览器打开: