支付宝接口文档
一、下载资源
网盘链接:
链接:https://pan.baidu.com/s/14EYx6oHAiydzxX58AmlfvQ
提取码:cy06
–来自百度网盘超级会员V4的分享
其实官网也可以下载
目录结构核心内容如下:
二、java里初步配置
1、打开“RSA”签名验签工具.bat,选择2048(对应RSA2),点击生成密钥
2、导入依赖,将工具类中的两个java文件复制进项目里
(1) 导入依赖,pom.xml:
<!-- 支付宝支付依赖 -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.13.50.ALL</version>
</dependency>
(2)进入支付宝开放平台
-
进入支付宝官网:https://open.alipay.com/dev/workspace,扫码登录
-
进入沙箱,由于不是正式的支付项目,所以暂时使用沙箱模式模拟支付流程。
(3)com/xxx/util/AlipayTemplate.java
package com.qhx.util;
import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
@Component
public class AlipayTemplate {
//在支付宝创建的应用的id
private String app_id = "2021000120618155";
// 商户私钥,您的PKCS8格式RSA2私钥
private String merchant_private_key ="验签工具里生成的私钥";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
private String alipay_public_key ="支付宝开放平台里的支付宝公钥";
// 服务器[异步通知]页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
// 支付宝会悄悄的给我们发送一个请求,告诉我们支付成功的信息
// 一个接收支付成功信息的东西,可以返回支付的订单号 要看返回的路径
public static String notify_url = "http://localhost:8080/Dangdang/...";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
//同步通知,支付成功,一般跳转到成功页(如我的订单页面),也可以跳到一个controller。这里返回到改变订单状态的controller,方法里改变订单状态由未支付到支付,并重定向至支付成功页面
public static String return_url = "http://localhost:8080/Dangdang/order/changeOrderState.do";
// 签名方式
private String sign_type = "RSA2";
// 字符编码格式
private String charset = "utf-8";
// 支付宝网关; https://openapi.alipaydev.com/gateway.do
private String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
public String pay(PayVo vo) throws AlipayApiException {
//AlipayClient alipayClient = new DefaultAlipayClient(AlipayTemplate.gatewayUrl, AlipayTemplate.app_id, AlipayTemplate.merchant_private_key, "json", AlipayTemplate.charset, AlipayTemplate.alipay_public_key, AlipayTemplate.sign_type);
//1、根据支付宝的配置生成一个支付客户端
AlipayClient alipayClient = new DefaultAlipayClient(gatewayUrl,
app_id, merchant_private_key, "json",
charset, alipay_public_key, sign_type);
//2、创建一个支付请求 //设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(return_url);
alipayRequest.setNotifyUrl(notify_url);
//商户订单号,商户网站订单系统中唯一订单号,必填
String out_trade_no = vo.getOut_trade_no();
//付款金额,必填
String total_amount = vo.getTotal_amount();
//订单名称,必填
String subject = vo.getSubject();
//商品描述,可空
String body = vo.getBody();
alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
String result = alipayClient.pageExecute(alipayRequest).getBody();
return result;
}
public boolean rsaCheckV1(HttpServletRequest request){
Map<String, String> params = convertRequestParamsToMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
String paramsJson = JSON.toJSONString(params);
boolean signVerified = false;
try {
signVerified = AlipaySignature.rsaCheckV1(params, alipay_public_key,
charset, sign_type);
} catch (AlipayApiException e) {
e.printStackTrace();
}
return signVerified;
}
// 将request中的参数转换成Map
private static Map<String, String> convertRequestParamsToMap(HttpServletRequest request) {
Map<String, String> retMap = new HashMap<String, String>();
Set<Map.Entry<String, String[]>> entrySet = request.getParameterMap().entrySet();
for (Map.Entry<String, String[]> entry : entrySet) {
String name = entry.getKey();
String[] values = entry.getValue();
int valLen = values.length;
if (valLen == 1) {
retMap.put(name, values[0]);
} else if (valLen > 1) {
StringBuilder sb = new StringBuilder();
for (String val : values) {
sb.append(",").append(val);
}
retMap.put(name, sb.toString().substring(1));
} else {
retMap.put(name, "");
}
}
return retMap;
}
public String getApp_id() {
return app_id;
}
public void setApp_id(String app_id) {
this.app_id = app_id;
}
public String getMerchant_private_key() {
return merchant_private_key;
}
public void setMerchant_private_key(String merchant_private_key) {
this.merchant_private_key = merchant_private_key;
}
public String getAlipay_public_key() {
return alipay_public_key;
}
public void setAlipay_public_key(String alipay_public_key) {
this.alipay_public_key = alipay_public_key;
}
public String getNotify_url() {
return notify_url;
}
public void setNotify_url(String notify_url) {
this.notify_url = notify_url;
}
public String getReturn_url() {
return return_url;
}
public void setReturn_url(String return_url) {
this.return_url = return_url;
}
public String getSign_type() {
return sign_type;
}
public void setSign_type(String sign_type) {
this.sign_type = sign_type;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public String getGatewayUrl() {
return gatewayUrl;
}
public void setGatewayUrl(String gatewayUrl) {
this.gatewayUrl = gatewayUrl;
}
}
(4)将验签工具里生成的私钥粘贴到merchant_private_key里
(5)应用自定义密钥,将生成的应用公钥粘贴到网页的“应用公钥”里,点下一步,生成支付宝公钥。将支付宝公钥粘贴到alipay_public_key。
(6)配置APPID,支付宝网关地址
至此,AlipayTemplate.java配置完成。还会有一个payVo类,封装的是支付订单对象,调用AlipayTemplate.java的pay()方法,返回一个js脚本(如下图的String pay),自动跳转到支付页面。
调用方式:响应
(7)com/xxx/entity/Vo/payVo.java,封装的订单信息
package com.qhx.util;
import org.springframework.stereotype.Component;
@Component
public class PayVo {
private String out_trade_no; // 商户订单号 必填
private String subject; // 订单名称 必填
private String total_amount; // 付款金额 必填
private String body; // 商品描述 可空
public PayVo() {
}
public PayVo(String out_trade_no, String subject, String total_amount, String body) {
this.out_trade_no = out_trade_no;
this.subject = subject;
this.total_amount = total_amount;
this.body = body;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getTotal_amount() {
return total_amount;
}
public void setTotal_amount(String total_amount) {
this.total_amount = total_amount;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
至此,配置完成,该控制器层的调用。
三、控制器层
调用的时候,记得设置响应格式
// 支付
@Autowired
private AlipayTemplate alipayTemplate;
@RequestMapping("/pay.do")
public void pay(HttpSession session,HttpServletResponse resp) throws Exception{
// 获取要支付的订单状态
PayVo payVo = (PayVo) session.getAttribute("payVo");
String pay = alipayTemplate.pay(payVo);
// 响应返回的支付页面
resp.setContentType("text/html;charset=utf-8");
PrintWriter pw = resp.getWriter();
pw.print(pay);
}
如果不设置响应格式(text/html;utf-8),会出现“验签错误,…不匹配”的报错,其实是无法解析响应到页面的pay字符串。
支付成功后,会自动跳到工具类的return_url,可以是一个静态页面,也可以是一个controller方法。这里返回的是controller,会自动更改订单的支付状态(由未支付到支付)。其实notify_url可以返回订单号,可以通过返回的订单号改变支付状态,这个就具体和业务层逻辑代码有关系了。
到此,支付完成。
调试了很多遍,总是说验签不正确,最后才发现是没有设置charset=utf-8。还是要仔细查看报错信息,及时寻求老师、网络的帮助啊。
相关文章
暂无评论...