支付宝支付-支付宝PC端扫码支付
前言
支付宝支付—沙箱环境使用
支付宝支付-支付宝PC端扫码支付「本文」
支付宝支付-手机浏览器H5支付
支付宝支付-当面付之扫码支付
PC端扫码支付,其实就是就是 电脑网站支付,本文基于支付宝沙箱环境,不了解的可以看一下上边的链接。
废话不多说,直接进入主题。
Java支付项目实战教程,包括支付宝,微信等支付方式,不看亏!下载运行测试Demo
官方Demo下载链接:电脑网站支付(Java)
下载后导入 IDEA 中运行如下图所示:
如果在导入运行过程遇到错误,请参考这篇文章:IDEA中导入支付宝电脑网站支付测试Demo遇到的错误
进行支付测试,注意付款要用沙箱环境提供的支付宝APK。
Maven项目中使用
pom.xml中引入支付宝sdk依赖
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.1.0</version>
</dependency>
配置可以单独创建一个类,静态初始化参数:
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://ngrok.sscai.club/alipay/aliPayNotify_url";
/** [沙箱环境]页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 **/
public static String return_url = "http://ngrok.sscai.club/index.html#/alipay/success";
/** [沙箱环境] **/
public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";
}
至于接口啥的基本就是可以参考上方运行的Demo了。
简单看看生成支付宝订单「没有使用开源SDK」。
@Transactional
public String alipayOrder(AlipayOrderRequest alipayOrderRequest) throws AlipayApiException {
/** 获得初始化的AlipayClient **/
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl,
AlipayConfig.app_id,
AlipayConfig.merchant_private_key,
"json",
AlipayConfig.charset,
AlipayConfig.alipay_public_key,
AlipayConfig.sign_type);
/** 设置请求参数 **/
String payType = alipayOrderRequest.getPayType();
/** page **/
AlipayTradePagePayRequest alipayPageRequest = new AlipayTradePagePayRequest();
alipayPageRequest.setReturnUrl(AlipayConfig.return_url);
alipayPageRequest.setNotifyUrl(AlipayConfig.notify_url);
/** 商户订单号,商户网站订单系统中唯一订单号,必填 **/
String out_trade_no = alipayOrderRequest.getWidOutTradeNo();
/** 付款金额,必填 **/
String total_amount = alipayOrderRequest.getWidTotalFee();
/** 订单名称,必填 **/
String subject = alipayOrderRequest.getWidSubject();
/** 商品描述,可空 **/
String body = alipayOrderRequest.getWIDbody();
/** 拼接参数 **/
alipayPageRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
/** 发起请求 **/
return alipayClient.pageExecute(alipayPageRequest).getBody();
}
网站支付接口调用后返回的是一个 Form 表单,也就是 result 实际是一段 Html 代码,然后把 result 传给前段调用即可,下面是返回的 Form 的一个示例:
<form name="punchout_form" method="post" action="https://openapi.alipaydev.com/gateway.do?charset=UTF-8&method=alipay.trade.wap.pay&sign=xx&return_url=http%3A%2F%2Fngrok.sscai.club%2Falipay_trade_wap_pay_java_utf_8_war_exploded%2Freturn_url.jsp&notify_url=http%3A%2F%2Fngrok.sscai.club%2Falipay_trade_wap_pay_java_utf_8_war_exploded%2Fnotify_url.jsp&version=1.0&app_id=2016101700705301&sign_type=RSA2&timestamp=2020-01-08+14%3A09%3A58&alipay_sdk=alipay-sdk-java-3.3.0&format=json">
<input type="hidden" name="biz_content" value="{"body":"购买测试商品0.01元","out_trade_no":"20201814955421","product_code":"QUICK_WAP_WAY","subject":"电脑网站支付测试商品","timeout_express":"2m","total_amount":"0.01"}" />
<input type="submit" value="立即支付" style="display:none" />
</form>
怎么调用呢?下面是一段我在vue中的测试代码片段,前段接收到后端返回的 Form 表单进行提交:
const div = document.createElement('div');
console.log("我是后端返回的数据:"+res.result)
div.innerHTML = res.result;
document.body.appendChild(div);
console.log("punchout_form:"+document.forms.punchout_form)
document.forms.punchout_form.submit();
支付成功后会自动重定向到配置的跳转界面,由后端的的 return_url 参数控制。
再看看支付成功后的回调接口「没有使用开源的SDK演示」:
public String alipaynotify(Model model, HttpServletRequest request) {
log.info("支付宝异步回调 ------------beg-----------");
String result = "fail";
/**获取支付宝POST过来反馈信息**/
/* *
* 功能:支付宝服务器异步通知页面
* 说明:
* 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
* 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
*/
Map<String, String> params=this.getAlipayRequest(request);
if(params == null || params.size()==0){
BufferedReader bufferReader = null;
StringBuilder sb = new StringBuilder();
try {
bufferReader = new BufferedReader(request.getReader());
String line = null;
while ((line = bufferReader.readLine()) != null) {
sb.append(new String(line.getBytes("ISO-8859-1"), "utf-8"));
}
} catch (IOException e) {
e.printStackTrace();
}
String body= null;
try {
body = URLDecoder.decode(sb.toString(),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
params=UriComponentsBuilder.newInstance().query(body).build().getQueryParams().toSingleValueMap();
}
boolean signVerified =false;
try {
signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type);
} catch (AlipayApiException e1) {
log.error("由于"+e1.getErrMsg()+"返回给支付宝系统的结果result:fail");
model.addAttribute("result", "fail");
return result;
} /**调用SDK验证签名 **/
/**——请在这里编写您的程序(以下代码仅作参考)——**/
/* 实际验证过程建议商户务必添加以下校验:
1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
4、验证app_id是否为该商户本身。
*/
log.error("支付宝验证签名:---------------------------------"+signVerified);
if(signVerified) {/**验证成功**/
/**商户订单号**/
/**交易状态**/
log.info("支付宝异步回调验签成功!");
String trade_status = params.get("trade_status");
if("TRADE_FINISHED".equals(trade_status)){
/**判断该笔订单是否在商户网站中已经做过处理**/
/**如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序**/
/**如果有做过处理,不执行商户的业务程序**/
/**注意:**/
/**退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知**/
try {
/** 在这里处理支付成功后的操作,比如修改订单状态等等**/
coding...
result = "success";
} catch (Exception e) {
log.error(e.getMessage());
result = "fail";
}
}else if ("TRADE_SUCCESS".equals(trade_status)){
/**判断该笔订单是否在商户网站中已经做过处理**/
/**如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序**/
/**如果有做过处理,不执行商户的业务程序**/
/**注意:**/
/**付款完成后,支付宝系统发送该交易状态通知**/
try {
/** 在这里处理支付成功后的操作,比如修改订单状态等等 **/
coding...
result = "success";
} catch (Exception e) {
log.error(e.getMessage());
result = "fail";
}
}else{
result = "fail";
}
}else {/**验证失败**/
result = "fail";
/**调试用,写文本函数记录程序运行情况是否正常**/
/**String sWord = AlipaySignature.getSignCheckContentV1(params);**/
/**AlipayConfig.logResult(sWord);**/
log.debug("支付宝异步回调验签失败");
}
log.debug("异步回调返回给支付宝系统的结果result:"+result);
model.addAttribute("result", result);
log.info("支付宝异步回调 -------------end ------------");
return result;
}
该方法返回给支付宝的 result 就 success、fail 两个结果。
从以上看来,其实不难发现支付宝支付是非常简单的,尽管我上边贴了大量的代码,其实采用开源SDK的话可以更加缩减、美化一些。
ok,这篇文章就到这结束了,上边并没有详细介绍接口调用、参数说明等,详细介绍请查看官方文档:https://docs.open.alipay.com/270/105902/
官方测试Demo下载
上方可运行的官方支付Demo:https://www.lanzoux.com/i8qjxij
求关注,求推荐
博客地址:https://www.cnblogs.com/niceyoo
求关注❤️,求推荐👍,如果觉得这篇文章有点东西,不妨左上角关注一下我。