支付宝支付-手机浏览器H5支付

前言

支付宝支付—沙箱环境使用
支付宝支付-支付宝PC端扫码支付
支付宝支付-手机浏览器H5支付「本文

手机浏览器支付,用户在安装支付宝APP的情况下,调用手机网站支付接口默认会唤起支付宝钱包支付,接下来通过运行官方Demo进行测试。

本文开发环境:IDEA + Tomcat8.5 + 支付宝沙箱环境*

补充:调用沙箱环境接口,需要安装沙箱环境下的支付宝APP,不了解的小伙伴可以参考上方 支付宝支付—沙箱环境使用。

下载运行测试Demo

官方Demo下载链接:手机网站支付

下载后导入 IDEA 中后需要调整的参数如下:

AlipayConfig.java

public class AlipayConfig {// 商户appidpublic static String APPID = "2016101700705301";// 私钥 pkcs8格式的public static String RSA_PRIVATE_KEY = "";// 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问public static String notify_url = "http://ngrok.sscai.club/alipay_trade_wap_pay_java_utf_8_war_exploded/notify_url.jsp";// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址public static String return_url = "http://ngrok.sscai.club/alipay_trade_wap_pay_java_utf_8_war_exploded/return_url.jsp";// 请求网关地址public static String URL = "https://openapi.alipaydev.com/gateway.do";// 编码public static String CHARSET = "UTF-8";// 返回格式public static String FORMAT = "json";// 支付宝公钥public static String ALIPAY_PUBLIC_KEY = "";// 日志记录目录public static String log_path = "/log";// RSA2public static String SIGNTYPE = "RSA2";
}

几个主要的参数:

  1. APPID :商户appid
  2. RSA_PRIVATE_KEY:应用私钥
  3. ALIPAY_PUBLIC_KEY:支付宝公钥「注意不是应用公钥」

这几个参数不清楚的,可以看一下 沙箱环境使用,或者看一下官方文档参数说明。

项目启动后如下图所示:

Maven项目中的使用

Maven中的使用其实跟上篇 支付宝支付-支付宝PC端扫码支付 代码非常的像,换汤不换药,改几个参数,具体如下:

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 {//获得初始化的AlipayClientAlipayClient 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();// wapAlipayTradeWapPayRequest alipayWapRequest = new AlipayTradeWapPayRequest();alipayWapRequest.setReturnUrl(AlipayConfig.return_url);alipayWapRequest.setNotifyUrl(AlipayConfig.notify_url);//商户订单号,商户网站订单系统中唯一订单号,必填String out_trade_no = alipayOrderRequest.getWidOutTradeNo();//付款金额,必填String total_amount = alipayOrderRequest.getWidTotalFee();//订单名称,必填String subject = alipayOrderRequest.getWidSubject();//商品描述,可空String body = alipayOrderRequest.getWIDbody();//拼接参数alipayWapRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","+ "\"total_amount\":\""+ total_amount +"\","+ "\"subject\":\""+ subject +"\","+ "\"body\":\""+ body +"\","+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");// 发起请求return alipayClient.pageExecute( alipayWapRequest).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="{&quot;body&quot;:&quot;购买测试商品0.01元&quot;,&quot;out_trade_no&quot;:&quot;20201814955421&quot;,&quot;product_code&quot;:&quot;QUICK_WAP_WAY&quot;,&quot;subject&quot;:&quot;手机网站支付测试商品&quot;,&quot;timeout_express&quot;:&quot;2m&quot;,&quot;total_amount&quot;:&quot;0.01&quot;}" /> <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) {// TODO Auto-generated catch blocklog.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;
}

该方法返回给支付宝的 resultsuccessfail 两个结果。
从以上看来,其实不难发现支付宝支付是非常简单的,尽管我上边贴了大量的代码,其实采用开源SDK的话可以更加缩减、美化一些,如下是支付成功的截图。

ok,这篇文章就到这结束了,上边并没有详细介绍接口调用、参数说明等,详细介绍请移步官方文档:https://docs.open.alipay.com/60/104790/

本文源码下载

可运行的官方手机网站支付Demo:https://www.lanzous.com/i8oe2sb

求关注,求推荐

博客地址:https://www.cnblogs.com/niceyoo

求关注❤️,求推荐👍,如果觉得这篇文章有点东西,不妨左上角关注一下我。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/414066.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[js] 获取浏览器当前页面的滚动条高度的兼容写法

[js] 获取浏览器当前页面的滚动条高度的兼容写法 document.documentElement.scrollTop || document.body.scrollTop;个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。 主目录 与歌谣一起通关前端面试题

HTML5 input 类型

HTML5 Input 类型 HTML 4.01 与 HTML 5 之间的差异 以下类型是 HTML5 中的新类型&#xff1a;color, date, datetime, datetime-local, month, week, time, email, number, range, search, tel 以及 url。 浏览器支持 Input typeIEFirefoxOperaChromeSafariemailNo4.09.010.0No…

[js] 一道变态题 Number.call.call(Number, undefined, 0) 等于什么?

[js] 一道变态题 Number.call.call(Number, undefined, 0) 等于什么&#xff1f; call 的第一个参数用于改变上下文&#xff0c;由于没有用到 this&#xff0c;第一个参数 Number 实际上没有用。Number.call(Number, undefined, 0) 等价于 Number(undefined, 0)&#xff0c;由…

uniapp添加网站favicon文件

前言 uniapp 默认创建的项目并没有给我们提供加上网站 favicon 的 ”机会”&#xff0c;但其实官方已经给出解决方法了&#xff0c;使用的是 自定义模板 自定义模板的场景&#xff0c;通常有以下几种情况&#xff1a; 调整界面 head 中的 meta 配置补充 SEO 相关的一些配置「仅…

sed: -e expression #1, char 23: unknown option to `s'

语言&#xff1a;bash why? / 作为sed的分隔符&#xff0c;和需要操作的内容有冲突 way? 替换 / 分隔符为 # 或者其他分隔符 转载于:https://www.cnblogs.com/2bjiujiu/p/9029598.html

[js] ReferenceError和TypeError有什么区别?

[js] ReferenceError和TypeError有什么区别&#xff1f; ReferenceError 指的是引用出错&#xff0c;比如尝试访问未定义的变量&#xff0c;或者提前访问无提升的变量&#xff0c;都会引发这个错误&#xff1a; console.log(foo); // ReferenceError: foo is not defined l…

WebStorm使用教程

WebStorm 是 JetBrains 推出的一款商业的 JavaScript 开发工具任何一个编辑器都需要保存(ctrl s)&#xff0c;这是所有win平台上编辑类软件的特点&#xff0c;但是webstorm编辑文件右上角是没有那个熟悉的 * 的。好处&#xff1a;省去了ctrl s之后&#xff0c;在结合Firefox的…

微信支付—微信H5支付「非微信内部浏览器-QQ/UC浏览器等」

前言 微信支付-微信H5外部浏览器支付「本文」微信H5内部浏览器支付「待写」PC端扫码支付「待写」 一直计划着写一写微信支付相关的文章&#xff0c;希望能加深一下自己的印象&#xff0c;拖了一天又一天… 最近终于空出时间来填坑了&#xff0c;我将文章分为微信H5外部浏览器支…

[js] 如何避免JS浮点运算的精度问题(例:0.1+0.7=0.7999999999999999)

[js] 如何避免JS浮点运算的精度问题&#xff08;例&#xff1a;0.10.70.7999999999999999&#xff09; function precision(num1,num2){num1Length num1.toString().length;num2Length num2.toString().length;let len num1Length > num2Length ? num1Length : num2Len…

多线程小结(1)

原文出处 定义就不多说了&#xff0c;直接上代码 1 /// <summary> 2 /// 单线程应用 3 /// </summary> 4 class Program 5 { 6 static void Main(string[] args) 7 { 8 Console.WriteLine("进入主线程"); 9 …

uniapp中使用微信jssdk

在做自定义分享时&#xff0c;用到了微信jssdk&#xff0c;记录一下。 声明&#xff1a;本文演示uniapp中使用jssdk&#xff0c;示例为网页自定义分享 npm方式使用下方指令进行安装&#xff0c;正文部分为非npm方式。 npm install jweixin-module --save 1、下载导入jssdk文件…

[js] 举例说明js立即执行函数的写法有哪些?

[js] 举例说明js立即执行函数的写法有哪些&#xff1f; 1、(function(){ //code }())2、!function(){ //code }()3、!(function(){ //code })()4、!(()>{ //code })()个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。…

微信支付—微信H5支付「微信内部浏览器」

前言 微信支付-微信H5外部浏览器支付微信支付-微信H5内部浏览器支付「本文」微信支付-PC端扫码支付「待写」 本篇是微信支付系列的第二篇、微信H5内部浏览器支付&#xff0c;关于微信H5外部浏览器唤起微信APP支付&#xff0c;请参考上一篇文章。 开发环境&#xff1a;Java Spr…

[js] for in 和 for of 的区别?

[js] for in 和 for of 的区别&#xff1f; for of 用于遍历于数组和可迭代对象得到的是entity({key: value})&#xff0c; for in 用于遍历对象的得到的是对象的属性名 for in 不可用来遍历一个数组, for in 将会把数组中的 length 等不需要的属性给一并遍历出来 for of 不可…

微信支付—微信H5支付「PC端扫码支付」

前言 微信支付-微信H5外部浏览器支付微信支付-微信H5内部浏览器支付微信支付-PC端扫码支付「本文」 本篇是微信支付系列的第三篇&#xff0c;PC端扫码支付。 开发环境&#xff1a;Java SpringBoot Vue WxJava(开源SDK) 流程补充&#xff1a;关于微信PC端扫码支付&#xff0c;…

[js] 写一个方法判断数组内元素是否全部相同

[js] 写一个方法判断数组内元素是否全部相同 const isSameArray function (array) {if (Array.isArray(array)) {return new Set(array).size 1;}return false; };个人简介 我是歌谣&#xff0c;欢迎和大家一起交流前后端知识。放弃很容易&#xff0c; 但坚持一定很酷。欢迎…

SQL Server中使用自定义指定顺序排序

SQL Server中使用自定义指定顺序排序 原文:SQL Server中使用自定义指定顺序排序比如需要对SQL表中的字段NAME进行如下的排序&#xff1a;张三&#xff08;Z&#xff09;李四&#xff08;L)王五&#xff08;W&#xff09;赵六&#xff08;Z&#xff09; 如果想按 “ 张三、李四、…

前后端分离项目,后端是如何处理前端传递的token?

前后端分离项目中&#xff0c;在不使用 SpringSecurity、Shiro 安全框架的情况下&#xff0c;后端是如何处理前段传递的 token 的呢&#xff1f; 简单说一个场景&#xff0c;在一个非常小的项目中&#xff0c;由于业务逻辑比较简单&#xff0c;也没有啥安全要求&#xff0c;所以…

[js] 说说防止重复发送ajax请求的方法有哪些?各自有什么优缺点?

[js] 说说防止重复发送ajax请求的方法有哪些&#xff1f;各自有什么优缺点&#xff1f; // 方法一 防抖function debounce(f, ms) { let time; return function(){ let arg Array.prototype.slice.call(arguments, 1); if(time) { clearTimeout(time); } time setTimeout(fu…

linux shell的here document用法(cat EOF)

什么是Here Document?Here Document 是在Linux Shell 中的一种特殊的重定向方式&#xff0c;它的基本的形式如下cmd << delimiter Here Document Contentdelimiter其作用是将两个 delimiter 之间的内容(Here Document Content 部分) 传递给cmd 作为输入参数;比如在终端…