pc端支付宝支付 前后端完整实例 看不懂找个厂吧
pom.xml maven导入
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.60</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.9.28.ALL</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.javen205/IJPay -->
<dependency>
<groupId>com.github.javen205</groupId>
<artifactId>IJPay</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>4.9.28.ALL</version>
</dependency>
package com.modules.Test;
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 com.modules.Test.AjaxJson;
import com.jpay.alipay.AliPayApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Map;
import java.util.UUID;
@Slf4j
@RestController
@RequestMapping("/alipay")
public class AlipayController {
private static String SERVER_URL = "https://openapi.alipay.com/gateway.do";
private static String FORMAT = "json";
private static String CHARSET = "UTF-8";
private static String SIGN_TYPE = "RSA2";
private static String APPID = "*******************";
private static String PRIVATE_KEY = "**************";//应用私钥
private static String ALIPAY_PUBLIC_KEY = "******************************";//支付宝公钥
private static String NOTIFY_URL = "http://www.***.com/notify";//支付成功通知地址
private static String RETURN_URL = "http://www.***.com/index.html";//支付成功回调页面
/**
* pc 支付宝支付
* @param request
* @return
* @throws Exception
*/
@RequestMapping("/alipay")
public AjaxJson pay(HttpServletRequest request) throws Exception {
Double price = 0.00;//支付金额
BigDecimal b = new BigDecimal(price);
price = b.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
String payPrice = String.valueOf(price); //实际支付金额 保留两位小数
//String payPrice = "0.01"; //实际支付金额 保留两位小数
/**实例化客户端*/
AlipayClient alipayClient = new DefaultAlipayClient(SERVER_URL,
APPID, PRIVATE_KEY, FORMAT,CHARSET,ALIPAY_PUBLIC_KEY, SIGN_TYPE);
//订单号
String orderNum = UUID.randomUUID().toString().replace("-","").toUpperCase();
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();//创建API对应的request
//同步通知
alipayRequest.setReturnUrl(RETURN_URL);
//异步通知
alipayRequest.setNotifyUrl(NOTIFY_URL);
//out_trade_no 指的是商户订单号,唯一标识
//product_code 固定的
//total_amount 支付金额,单位元。
//subject 主题 可填可不填
//body 商品详情,可填可不填
//timeout_express 二维码有效期
//方式一
alipayRequest.setBizContent("{" +
" \"out_trade_no\":\""+ orderNum +"\"," +
" \"product_code\":\"FAST_INSTANT_TRADE_PAY\"," +
" \"total_amount\":"+ payPrice +"," +
" \"subject\":\""+ "alipay" +"\"," +
" \"body\":\""+ "充钱使你变得更强" +"\"" +
" }"+
" }");//填充业务参数
String form="";
try {
form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}
//方式二
/*AlipayTradeWapPayModel alipayTradeWapPayModel = new AlipayTradeWapPayModel();
alipayTradeWapPayModel.setOutTradeNo(orderNum);
alipayTradeWapPayModel.setProductCode("FAST_INSTANT_TRADE_PAY");
alipayTradeWapPayModel.setTotalAmount(payPrice);
alipayTradeWapPayModel.setSubject("alipay");
alipayTradeWapPayModel.setBody("充钱使你变得更强");
alipayRequest.setBizModel(alipayTradeWapPayModel);
String form="";
try {
form = alipayClient.pageExecute(alipayRequest).getBody();
} catch (AlipayApiException e) {
e.printStackTrace();
}*/
System.out.println(alipayRequest);
//form就是一个表单 html 直接给前端 替换 body标签里面的东西
AjaxJson json = new AjaxJson();
json.setSuccess(true);
json.setMsg("支付创建成功");
json.put("form",form);
return json;
}
@RequestMapping("/notify")
public String notify(HttpServletRequest request, HttpServletResponse response)throws Exception{
Map<String, String> params = AliPayApi.toMap(request); // 将异步通知中收到的待验证所有参数都存放到map中
String paramsJson = JSON.toJSONString(params);
log.info("支付宝回调,{}", paramsJson);
/*gmt_create = 2021-01-30 19:46:39
charset = UTF-8
gmt_payment = 2021-01-30 19:46:50
notify_time = 2021-01-30 19:46:51
subject = 支付价格
sign = aAfDqNi6U+UO32dV1g2aso
buyer_id = 2088422
body = 一笔订单
invoice_amount = 0.01
version = 1.0
notify_id = 2021013000222194650069481
fund_bill_list = [{"amount":"0.01","fundChannel":"ALIPAYACCOUNT"}]
notify_type = trade_status_sync
out_trade_no = 20210130074621-417586
total_amount = 0.01
trade_status = TRADE_SUCCESS
trade_no = 2021013022001469481423016991
auth_app_id = 20210011
receipt_amount = 0.01
point_amount = 0.00
buyer_pay_amount = 0.01
app_id = 20210011
sign_type = RSA2
seller_id = 208893165*/
try {
// 调用SDK验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY,CHARSET,SIGN_TYPE);
if (signVerified) {
log.info("支付宝回调签名认证成功=======================");
// 按照支付结果异步通知中的描述,对支付结果中的业务内容进行1\2\3\4二次校验,校验成功后在response中返回success,校验失败返回failure
//String passbackParams = params.get("passback_params");//商户传入业务信息,具体值要和支付宝约定,应用于安全,营销等参数直传场景,格式为json格式
String outTradeNo = params.get("out_trade_no");//商户订单号,64个字符以内、可包含字母、数字、下划线;需保证在商户端不重复
log.info("======支付订单号========"+outTradeNo);
String totalAmount = params.get("buyer_pay_amount");//订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]。
log.info("======订单总金额========"+totalAmount);
//TODO-------------------处理逻辑-------------------------------------------
if("TRADE_SUCCESS".equals(params.get("trade_status"))){
}
// 如果签名验证正确,立即返回success,后续业务另起线程单独处理
// 业务处理失败,可查看日志进行补偿,跟支付宝已经没多大关系。
return "success";
} else {
log.info("支付宝回调签名认证失败,signVerified=false, paramsJson:{}", paramsJson);
return "failure";
}
} catch (AlipayApiException e) {
log.error("支付宝回调签名认证失败,paramsJson:{},errorMsg:{}", paramsJson, e.getMessage());
return "failure";
}
}
}
package com.modules.Test;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.jeeplus.core.mapper.JsonMapper;
import org.springframework.http.HttpStatus;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* $.ajax后需要接受的JSON
*
* @author
*
*/
public class AjaxJson extends HashMap<String,Object> implements Serializable {
public AjaxJson(){
this.put("success", true);
this.put("code", HttpStatus.OK.value());
this.put("msg", "操作成功");
}
public String getMsg() {
return (String)this.get("msg");
}
public void setMsg(String msg) {//向json中添加属性,在js中访问,请调用data.msg
this.put("msg", msg);
}
public boolean isSuccess() {
return (boolean)this.get("success");
}
public void setSuccess(boolean success) {
this.put("success", success);
}
@JsonIgnore//返回对象时忽略此属性
public String getJsonStr() {//返回json字符串数组,将访问msg和key的方式统一化,都使用data.key的方式直接访问。
String json = JsonMapper.getInstance().toJson(this);
return json;
}
@JsonIgnore//返回对象时忽略此属性
public static AjaxJson success(String msg) {
AjaxJson j = new AjaxJson();
j.setSuccess(true);
j.setMsg(msg);
return j;
}
@JsonIgnore//返回对象时忽略此属性
public static AjaxJson error(String msg) {
AjaxJson j = new AjaxJson();
j.setSuccess(false);
j.setMsg(msg);
return j;
}
public static AjaxJson success(Map<String, Object> map) {
AjaxJson restResponse = new AjaxJson();
restResponse.putAll(map);
return restResponse;
}
public static AjaxJson success() {
return new AjaxJson();
}
@Override
public AjaxJson put(String key, Object value) {
super.put(key, value);
return this;
}
public AjaxJson putMap(Map m) {
super.putAll(m);
return this;
}
public int getCode() {
return (int)this.get("code");
}
public void setCode(int code) {
this.put("code", code);
}
}
前端
页面上加个点击事件
判断此订单是否支付过
未支付过直接跳转到支付页面
function pay(){
var orderNum = "";
$.ajax({
type: "get",
url: "/api/pay",
data: {orderNum:orderNum},
dataType: "json",
success: function(result){
if(result.success){
window.open("/pay.html?orderNum="+orderNum)
}else{
layer.msg(result.msg)
}
},
error:{}
});
}
调用后端支付接口
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
</head>
<body>
<h1>跳转中。。。</h1>
</body>
<script src="js/jquery.min.js"></script>
<script src="js/jquery.js"></script>
<script src="js/util.js"></script>
<script>
$(function() {
var orderNum = getQueryStringByName("orderNum");
console.log("=============================",orderNum)
$.ajax({
type: "post",
url: "/aliPay/aliPay",
data: {orderNum:orderNum},
dataType: "json",
success: function(result){
if(result.code == "1"){
const div=document.createElement('divform');
div.innerHTML=result.data;
document.body.appendChild(div);
document.forms[0].acceptCharset='UTF-8';//保持与支付宝默认编码格式一致,如果不一致将会出现:调试错误,请回到请求来源地,重新发起请求,错误代码 invalid-signature 错误原因: 验签出错,建议检查签名字符串或签名私钥与应用公钥是否匹配
document.forms[0].submit();
}else{
this.$alert("错误:"+result.data,"提示",{
confirmButtonText:'确定'
});
}
},
error:{}
});
});
function getQueryStringByName(name) {
var result = location.search.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i"));
if (result == null || result.length < 1) {
return "";
}
return result[1];
}
</script>
</html>