java接入支付宝支付(沙箱环境)

沙箱环境配置网络上有很多说明都是比较详细的,下面我直接记录下我实现支付的代码(也可去官方下载demo可以直接使用的,具体还要根据业务来使用)

支付前端:(本人并没有做多大改动只是把demo拿来改改,加个请求,至于请求中的参数都是写死的!这个由码友们自行去根据业务需要传参即可~)

<!doctype html>
<html lang="en">
<head>
<title>支付宝电脑网站支付</title>
<script src="js/jquery-3.4.1.js"></script>

<style>
* {
margin: 0;
padding: 0;
}

ul, ol {
list-style: none;
}

body {
font-family: "Helvetica Neue", Helvetica, Arial, "Lucida Grande",
sans-serif;
}

.tab-head {
margin-left: 120px;
margin-bottom: 10px;
}

.tab-content {
clear: left;
display: none;
}

h2 {
border-bottom: solid #02aaf1 2px;
width: 200px;
height: 25px;
margin: 0;
float: left;
text-align: center;
font-size: 16px;
}

.selected {
color: #FFFFFF;
background-color: #02aaf1;
}

.show {
clear: left;
display: block;
}

.hidden {
display: none;
}

.new-btn-login-sp {
padding: 1px;
display: inline-block;
width: 75%;
}

.new-btn-login {
background-color: #02aaf1;
color: #FFFFFF;
font-weight: bold;
border: none;
width: 100%;
height: 30px;
border-radius: 5px;
font-size: 16px;
}

#main {
width: 100%;
margin: 0 auto;
font-size: 14px;
}

.red-star {
color: #f00;
width: 10px;
display: inline-block;
}

.null-star {
color: #fff;
}

.content {
margin-top: 5px;
}

.content dt {
width: 100px;
display: inline-block;
float: left;
margin-left: 20px;
color: #666;
font-size: 13px;
margin-top: 8px;
}

.content dd {
margin-left: 120px;
margin-bottom: 5px;
}

.content dd input {
width: 85%;
height: 28px;
border: 0;
-webkit-border-radius: 0;
-webkit-appearance: none;
}

#foot {
margin-top: 10px;
position: absolute;
bottom: 15px;
width: 100%;
}

.foot-ul {
width: 100%;
}

.foot-ul li {
width: 100%;
text-align: center;
color: #666;
}

.note-help {
color: #999999;
font-size: 12px;
line-height: 130%;
margin-top: 5px;
width: 100%;
display: block;
}

#btn-dd {
margin: 20px;
text-align: center;
}

.foot-ul {
width: 100%;
}

.one_line {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #eeeeee;
width: 100%;
margin-left: 20px;
}

.am-header {
display: -webkit-box;
display: -ms-flexbox;
display: box;
width: 100%;
position: relative;
padding: 7px 0;
-webkit-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
background: #1D222D;
height: 50px;
text-align: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
box-pack: center;
-webkit-box-align: center;
-ms-flex-align: center;
box-align: center;
}

.am-header h1 {
-webkit-box-flex: 1;
-ms-flex: 1;
box-flex: 1;
line-height: 18px;
text-align: center;
font-size: 18px;
font-weight: 300;
color: #fff;
}
</style>
</head>
<body text=#000000 bgColor="#ffffff" leftMargin=0 topMargin=4>
<header class="am-header">
<h1>在线支付</h1>
</header>
<div id="main">
<div id="tabhead" class="tab-head">
<h2 id="tab1" class="selected" name="tab" hidden>付 款</h2>
<!--<h2 id="tab2" name="tab">交 易 查 询</h2>-->
<!--<h2 id="tab3" name="tab">退 款</h2>-->
<!--<h2 id="tab4" name="tab">退 款 查 询</h2>-->
<!--<h2 id="tab5" name="tab">交 易 关 闭</h2>-->
</div>

<div id="body1" class="show" name="divcontent">
<dl class="content">
<dt>商户订单号 :</dt>
<dd>
<input id="WIDout_trade_no" name="WIDout_trade_no" value="444666777555555" />
</dd>
<hr class="one_line">
<dt>订单名称 :</dt>
<dd>
<input id="WIDsubject" name="WIDsubject" value="测试订单" />
</dd>
<hr class="one_line">
<dt>付款金额 :</dt>
<dd>
<input id="WIDtotal_amount" name="WIDtotal_amount" value="666"/>
</dd>
<hr class="one_line">
<dt>商品描述:</dt>
<dd>
<input id="WIDbody" name="WIDbody" value="测试测试测试!"/>
</dd>
<hr class="one_line">
<dt></dt>
<dd id="btn-dd">
<span class="new-btn-login-sp">
<button class="new-btn-login" id="payfor"
style="text-align: center;">付 款</button>
</span> <span class="note-help">如果您点击“付款”按钮,即表示您同意该次的执行操作。</span>
</dd>
</dl>
</div>

<div id="foot">
<ul class="foot-ul">
<li>支付宝版权所有 2015-2019 ALIPAY.COM</li>
</ul>
</div>
</div>

</body>
<script language="javascript">

$(function(){
$('#payfor').click(function(){
$.ajax({
url: "/antMap/expand/pay/alipay.htm",
type: 'POST',
data: {
"WIDout_trade_no": $('#WIDout_trade_no').val(),
"WIDtotal_amount":$('#WIDtotal_amount').val(),
"WIDsubject":$('#WIDsubject').val(),
"WIDbody":$('#WIDbody').val()
},
dataType:"html"
})
.done(function(ress) {
            //成功后将后端返回的html代码直接塞到div中,细心地朋友会发现返回的代码中包含提交支付,那么这里就直接在塞进去后点击按钮跳转支付界面啦~~ 
if (ress != "" && ress != null) {

var div=document.createElement('divform');
div.innerHTML=ress;
document.body.appendChild(div);
document.forms[0].acceptCharset='UTF-8';//保持与支付宝默认编码格式一致,如果不一致将会出现:调试错误,请回到请求来源地,重新发起请求,错误代码 invalid-signature 错误原因: 验签出错,建议检查签名字符串或签名私钥与应用公钥是否匹配
document.forms[0].submit();
}
})
.fail(function(ress){
alert(ress);//这里可以填写失败后采取的措施
})
});
});

</script>
</html>


阿里存配置的页面:里面的内容大多数都是沙箱环境中填写的配置,公钥、私匙等等,可以去网上浏览沙箱环境搭建的过程~这里不再阐述~
package cn.com.antMap.expand.common;
import java.io.FileWriter;
import java.io.IOException;

public class AlipayConfig {
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "";

// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = ""
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "http://mmgy.nat300.top/.../alipayNotifyNotice.htm";//请求回调后台

// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "http://mmgy.nat300.top/.../alipayReturnNotice.htm";

// 签名方式
public static String sign_type = "RSA2";

public static String timeout_express = "3m";

// 字符编码格式
public static String charset = "utf-8";

// 支付宝网关
  //这是沙箱的网关,和正式环境不同注意哦~
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";

// 支付宝网关
public static String log_path = "C:\\";


/**
* 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
* @param sWord 要写入日志里的文本内容
*/
public static void logResult(String sWord) {
FileWriter writer = null;
try {
writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
writer.write(sWord);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

}

后端代码:
package cn.com.antMap.expand.alipay;
import cn.com.antMap.expand.common.AlipayConfig;
import com.alipay.api.*;
import com.alipay.api.domain.AlipayTradePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/*

@Controller
@RequestMapping(value = "/expand/pay/")
public class PayController {
@RequestMapping(value = "alipay.htm",method=RequestMethod.POST)
@ResponseBody
public void goAlipay(HttpServletRequest request,HttpServletResponse httpResponse) throws Exception {

//获得初始化的AlipayClient

AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

//设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
AlipayTradePayModel model = new AlipayTradePayModel();
model.setOutTradeNo(new String(request.getParameter("WIDout_trade_no")));
System.out.println(request.getParameter("WIDsubject"));
model.setProductCode("FAST_INSTANT_TRADE_PAY");
model.setTotalAmount(new String(request.getParameter("WIDtotal_amount")));
model.setSubject(request.getParameter("WIDsubject"));
model.setBody(request.getParameter("WIDbody"));
model.setTimeoutExpress("3m");

//这里设置支付后跳转的地址
alipayRequest.setReturnUrl(AlipayConfig.return_url);
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
alipayRequest.setBizModel(model);
//商户订单号,商户网站订单系统中唯一订单号,必填
//String out_trade_no = PayMessage.getLocalTrmSeqNum();
String form = "";
try {
form = alipayClient.pageExecute(alipayRequest).getBody(); // 调用SDK生成表单
} catch (AlipayApiException e) {
e.printStackTrace();
}

httpResponse.setContentType("text/html;charset=" + AlipayConfig.charset);
httpResponse.getWriter().write(form);//直接将生成的表单传到前台
httpResponse.getWriter().flush();
httpResponse.getWriter().close();
}
  



   /*这里是回调方法,
   *return和notify代码是一样的只是请求不一样,我这里用的是post也就是notify
*/
@RequestMapping(value = "alipayReturnNotice.htm", method = RequestMethod.GET)
@ResponseBody
public String alipayReturnNotice(HttpServletRequest request, HttpServletRequest response) throws Exception {

System.out.println("支付成功11111111111");

//获取支付宝get过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> 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] + ",";
}
//乱码解决,这段代码在出现乱码时使用
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}

boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

//——请在这里编写您的程序(以下代码仅作参考)——

if(signVerified) {//验证成功
//商户订单号
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

//支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

//交易状态
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

//付款金额
String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");

if(trade_status.equals("TRADE_FINISHED")){
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序

//注意: 尚自习的订单没有退款功能, 这个条件判断是进不来的, 所以此处不必写代码
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
}else if (trade_status.equals("TRADE_SUCCESS")){
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序

//注意:
//付款完成后,支付宝系统发送该交易状态通知

// 修改叮当状态,改为 支付成功,已付款; 同时新增支付流水

}
System.out.println("111支付成功");

}else {//验证失败

}

return "success";
}



@RequestMapping(value = "alipayNotifyNotice.htm", method = RequestMethod.POST)
@ResponseBody
public String alipayNotifyNotice(HttpServletRequest request, HttpServletRequest response) throws Exception {
//获取支付宝POST过来反馈信息
Map<String,String> params = new HashMap<String,String>();
Map<String,String[]> requestParams = request.getParameterMap();
for (Iterator<String> 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] + ",";
}
//乱码解决,这段代码在出现乱码时使用
// valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
params.put(name, valueStr);
}

boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

//——请在这里编写您的程序(以下代码仅作参考)——



if(signVerified) {//验证成功
//商户订单号
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

//支付宝交易号
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

//交易状态
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

//付款金额
String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8");

if(trade_status.equals("TRADE_FINISHED")){
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序

//注意: 尚自习的订单没有退款功能, 这个条件判断是进不来的, 所以此处不必写代码
//退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
}else if (trade_status.equals("TRADE_SUCCESS")){
System.out.println("业务流程");
System.out.println(out_trade_no);
//判断该笔订单是否在商户网站中已经做过处理
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
//如果有做过处理,不执行商户的业务程序

//注意:
//付款完成后,支付宝系统发送该交易状态通知

// 修改叮当状态,改为 支付成功,已付款; 同时新增支付流水

}
System.out.println("支付成功");

}else {//验证失败

}

return "success";
}
}

到这里简单的支付就完成了,还有很多其他接口,查询,退款...等等都大同小异在这里不在一一赘述啦,网络上也有很多资源可以供大家参考,这里只是本人简单的记录一下~


posted @ 2019-10-17 10:49  福尔摩洋  阅读(1702)  评论(0编辑  收藏  举报