好久不写博客了,最近发现支付宝的对接方式改了。虽然新版不影响老版的使用,不过对于新项目来说,最好采用新版对接方式。(个人建议,不喜勿喷)
下面进入正题,我们采用的是Java对接的方式。
第一步
引入pom.xml依赖
<!-- 支付宝(新版) -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-easysdk</artifactId>
<version>2.2.0</version>
</dependency>
第二步
配置application.yml文件
server:
port: 8888
alipay:
#应用ID
app_id: **写你的应用ID**
#应用私钥
merchant_private_key: **写你的应用私钥**
#支付宝公钥
alipay_public_key: **写你的支付公钥**
#format
format: json
#异步通知回调地址,不能加?id=123这类自定义参数
notify_url: **写你的回调地址**
#即支付成功之后,需要跳转到的页面
return_url: **写你的支付成功页面**
#签名方式
sign_type: RSA2
#字符编码格式
charset: utf-8
#支付宝网关,这一项是写死的,正式环境是openapi.alipay.com
gatewayUrl: openapi.alipaydev.com
第三步
增加AlipayConfig.java配置文件
package com.alipay.explam.config;
/**
* @author :Mall
* @date :Created in 2021-02-01
* @description :支付宝配置类
*/
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
@Component
public class AlipayConfig implements ApplicationRunner {
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
@Value("${alipay.app_id}")
public String app_id;
// 商户私钥,您的PKCS8格式RSA2私钥
@Value("${alipay.merchant_private_key}")
public String merchant_private_key;
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
@Value("${alipay.alipay_public_key}")
public String alipay_public_key;
//格式
@Value("${alipay.format}")
public String format;
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
@Value("${alipay.notify_url}")
public String notify_url;
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 即支付成功之后,需要跳转到的页面,一般为网站的首页
@Value("${alipay.return_url}")
public String return_url = "http://www.baidu.com";
// 签名方式
@Value("${alipay.sign_type}")
public String sign_type;
// 字符编码格式
@Value("${alipay.charset}")
public String charset;
// 支付宝网关
@Value("${alipay.gatewayUrl}")
public String gatewayUrl;
@Override
public void run(ApplicationArguments args) throws Exception {
//这里省略了一些不必要的配置,可参考文档的说明
Config config = new Config();
config.protocol = "https";
config.gatewayHost = this.gatewayUrl;
config.signType = this.sign_type;
config.appId = this.app_id;
// 为避免私钥随源码泄露,推荐从文件中读取私钥字符串而不是写入源码中
config.merchantPrivateKey = this.merchant_private_key;
// 注:如果采用非证书模式,则无需赋值上面的三个证书路径,改为赋值如下的支付宝公钥字符串即可
config.alipayPublicKey = this.alipay_public_key;
// 可设置异步通知接收服务地址(可选)
config.notifyUrl = this.notify_url;
//初始化支付宝SDK
Factory.setOptions(config);
System.out.println("=======支付宝SDK初始化成功");
}
}
第四步
增加支付所需Service层
```java
package com.alipay.explam.service;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.alipay.explam.config.AlipayConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author :Mall
* @date :Created in 2021-02-01
* @description :
*/
@Service
public class AlipayService {
@Autowired
private AlipayConfig alipayConfig;
/**
* 电脑版支付
*
* @param subject 标题
* @param orderId 订单ID
* @param total 金额
* @return
* @throws Exception
*/
public String toPayPage(String subject, String orderId, String total) throws Exception {
AlipayTradePagePayResponse response = Factory.Payment.Page().pay(subject, orderId, total, alipayConfig.return_url);
return response.getBody();
}
}
第五步
增加Controller层
package com.alipay.explam.controller;
import com.alipay.easysdk.factory.Factory;
import com.alipay.explam.config.QRCodeUtil;
import com.alipay.explam.service.AlipayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
/**
* @author :Mall
* @date :Created in 2021-02-01
* @description :阿里支付Controller
*/
@RestController
@RequestMapping("/alipay")
public class AliPayController {
@Autowired
private AlipayService alipayService;
@RequestMapping("/hello")
public String hello() {
return "index";
}
/**
* 跳转到支付界面
*
* @return
* @throws Exception
*/
@RequestMapping("/page")
public String pay(String subject, String total) throws Exception {
return alipayService.toPayPage(subject, "10010", total);
}
/**
* @param request: 请求
* @return java.lang.String
* @description: 支付宝异步回调
* @date: 2020/11/3
*/
@RequestMapping("/notify_url")
public String notify_url(HttpServletRequest request) throws Exception {
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));
}
// 支付宝验签
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"));
}
}
return "success";
}
}
第六步
测试功能,浏览器输入【https://你的外网域名/alipay/page?subject=Test&total=100】
会直接跳转到支付宝支付页面。如果提示防钓鱼网站,可使用360浏览器访问。
打完收工~
关于支付宝沙箱的配置,我会在下一篇博客中介绍。