场景需求:
通过支付宝扫描二维码进入手机H5网站,获取用户唯一标识appid来标识用户以及处理逻辑。一系列操作后,调起支付窗口完成支付宝支付
1、支付宝开放平台配置
1、登陆支付宝开放平台中心,选择“ 网页&移动应用 ”,然后创建一个应用。此时该应用的状态为开发中,需要我们添加一些功能和信息后去审核,审核通过就成了已上线。就可以开始使用了。
这里我们只需要两项功能:1、手机网站支付;2、用户信息授权
除此之外还需要配置一下开发设置,如下图:
具体配置可以参照上面官方的文档来。
我这里只配了一个接口加签方式(支付使用),加签方式有两种,一种是普通加签——需要设置支付宝公钥。另一种是证书加签方式。这个有点复杂,看个人需求,具体参照官方文档。
我这里选择普通加签方式,按照官方文档的指示,下载了一个“ 支付宝开放平台开发助手 ” 的软件用来生成相应的应用公钥和应用私钥
首先,用上面这个工具生成一对密钥,这里叫做应用私钥和应用公钥。我们要做的就是 保存 好这对密钥!!!。普通加签方式就是把这里的应用公钥上传(复制粘贴)到配置里面,然后旁边会有个生成支付宝公钥的按钮,点击生成支付宝公钥。然后把这段支付宝公钥保存下来。跟之前应用私钥和应用公钥一起。后面支付会用到。
接下来就是配置授权回调地址。:这个回调地址就是我们做用户信息授权登陆的时候用到的。这里要配置一个正规的可访问域名。支付宝会检测的。
这里简单介绍一下这个回调地址有什么用。首先我们得知道用户信息授权的流程:用户通过特定规则拼接传输数据到支付宝指定授权地址(url),支付宝校验你传输的数据,通过的话就会给你返回一个auth_code。我们再通过返回过来的auth_code去换取支付宝用户唯一标识appid。拿到这个appid。我们就完成了授权。
上面返回的auth_code就是在支付宝校验我们传输的数据后,会请求我们后台配置的授权回调地址。然后会在url后面带上auth_code
简单来说就是:我们请求支付宝,支付宝通过后会访问我们配置的授权回调地址来将auth_code返回给我们。
配置这一块就结束了。总共配置两个地方:一个加签方式(支付使用),一个授权回调地址(授权使用)。完成后我们就可以提交,等待审核了。(所有功能都必须审核通过才能使用)
用户信息授权
上面我们基本配置了授权所需要的配置,其实就只配置一个授权回调地址来获取返回的auth_code。
先上代码后讲解:
redirectForAliCode() {
goodsApi.getAliSign().then(res => {//授权需要用到开放平台里我们创建应用的appid。不是用户appid。
const rr = res.data;
const redirectUrl = window.location.href;
var result = redirectUrl.match(/=(\S*)#/)[1];
var results = result.match(/(\d*)/)[1];
let param = 'app_id=' + rr
param += '&scope=auth_base'//可参考文档,因为我们只要授权,所以,这里只写auth_base
//下面的redirect_uri值必须经过URLENCODE转义,不能明文传输
param += '&redirect_uri=' + encodeURIComponent('http://****.com')//这里写我们后台配置的授权回调地址
param += '&state='+results //一定要一模一样,否则授权会失败
console.log('url:', 'https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?'+ param);
window.location.href = 'https://openauth.alipay.com/oauth2/publicAppAuthorize.htm?' + param;//支付宝授权指定url
}).catch(err => {
})
}
通过该代码调用获取auth_code后,我们再通过这个auth_code去换取appid
public Map<String, Object> getPrivateAccessToken(String code) {//之前拿到的auth_code
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.URL,//支付宝api
alipayConfig.APPID,alipayConfig.RSA_PRIVATE_KEY,alipayConfig.FORMAT,alipayConfig.CHARSET,alipayConfig.ALIPAY_PUBLIC_KEY,alipayConfig.SIGNTYPE);
AlipaySystemOauthTokenRequest request = new AlipaySystemOauthTokenRequest();
request.setCode(code);
request.setGrantType("authorization_code");
Map map = Maps.newHashMap();
try {
AlipaySystemOauthTokenResponse oauthTokenResponse = alipayClient.execute(request);
logger.info("AccessToken:"+oauthTokenResponse.getAccessToken());
logger.info("UserId:"+oauthTokenResponse.getUserId());
map.put("AccessToken",oauthTokenResponse.getAccessToken());
map.put("UserId",oauthTokenResponse.getUserId());
} catch (AlipayApiException e) {
//处理异常
e.printStackTrace();
logger.info("获取userID异常,信息如下:"+e.getErrMsg());
}
return map;
}
通过上面这个代码,可以换取到auth_code。上面创建支付宝api实例的时候有几个参数。
URL:固定请求地址。
APPID:应用appid。
RSA_PRIVATE_KEY:还记得之前保存的应用私钥吗。这里用到了。
FORMAT:格式,只支持json。
CHARSET:编码,只支持UTF-8。
ALIPAY_PUBLIC_KEY:之前配置加签方式保存下来的支付宝公钥
SIGNTYPE:签名类型,固定:RSA2
至此,我们的appid就拿到了,用户授权信息功能也完成了。接下来就是业务逻辑的一些处理了。(上面授权的这些参数待会支付接口也会用到。)
手机网站支付
下面就到了支付环节了,首先我简单说下支付的大概流程:
我们整理一下订单数据,通过调用支付宝api,然后返回一个form表单,我们再把得到的form表单放到页面上自动提交,就会调起支付密码框,输入密码后就支付完成。
整个支付接口,我分为两个阶段
1、支付准备阶段:
这里最少需要准备两个订单数据字段,一个是我们的业务系统订单号(不可重复哟)。再一个就是支付的金额了(单位是元,最小到分)。
public String aliPay(String orderSn,Double monery){
AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig.URL,alipayConfig.APPID,alipayConfig.RSA_PRIVATE_KEY,alipayConfig.FORMAT,alipayConfig.CHARSET,alipayConfig.ALIPAY_PUBLIC_KEY,alipayConfig.SIGNTYPE);
AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
//支付成功与否回调通知地址
request.setNotifyUrl(alipayConfig.notify_url);
//支付完成后自动返回的地址(一般为作我们的业务系统自定义的查询是否支付页面)
request.setReturnUrl(alipayConfig.return_url+orderSn);
request.setBizContent("{" +
"\"subject\":\"随便写个名称,用作支付宝后台报表查询标识的\"," +
"\"out_trade_no\":\""+orderSn+"\"," +
"\"total_amount\":"+monery+"," +
"\"product_code\":\"QUICK_WAP_WAY\"" +
" }");
AlipayTradeWapPayResponse response = null;
try {
response = alipayClient.pageExecute(request);
//这里会返回一个form表单(调起支付框--这个框就是我们平时用支付宝支付,输密码的框)
String result = response.getBody();
logger.info(result);
return result;
} catch (AlipayApiException e) {
e.printStackTrace();
}
if(response.isSuccess()){
System.out.println("调用成功");
} else {
System.out.println("调用失败");
}
return null;
}
这上面构造支付宝api实例的参数跟上面获取授权一样。不同的是支付这里,必须得传一个支付是否成功的回调通知地址,以及一个支付完成后的返回地址。(支付宝这里跟微信jsapi支付不同,是要我们自己将地址传到支付宝后台,由他们来请求我们的地址。)
我们拿到form表单后,把这个表单返回给前台自动提交。
<form name="punchout_form" method="post" action="">
<input type="hidden" name="biz_content" value="{"subject":"深圳校服","out_trade_no":"20200513085536016569","total_amount":0.01,"product_code":"QUICK_WAP_WAY" }">
<input type="submit" value="立即支付" style="display:none" >
</form>
<script>document.forms[0].submit();</script>
生成的form表单大概是这个样子。
aliPrepare(){
//前台传订单号去后台,后台查出订单金额传给支付宝api,返回一个form表单
payApi.aliPrepare(this.order.orderNo).then(res => {
// 存储微信支付数据data
let data = res.data//返回的form表单
console.log("即将跳转支付宝支付,返回的数据为:"+data)
const div = document.createElement('div');
div.innerHTML = data
document.body.appendChild(div)
document.forms[0].submit();
//这些document操作应该不用过多解释了=-=
}).catch(err =>{
Toast('系统异常,青稍后再试')
Toast(err)
})
},
执行完这个js后就会自动弹出一个支付框啦。支付准备阶段就完成了。
2、支付完成阶段
在我们输入密码完成支付后,(页面):支付宝会请求我们支付的时候传的return_url地址。
(后台):支付宝会调用我们传过去的通知回调NotifyUrl地址
如何处理回调通知。官方文档里有demo。这里就不做展示了。
支付宝手机网站demo
我这里由于用的是springboot。所以直接返回即可
/**
* 支付宝支付回调
* @return
*/
@RequestMapping(value = "ali/notify",method = RequestMethod.POST)
public String aliNotify(){
logger.info("开始进入支付宝支付的回调,地址:ali/notify");
String msg = aliPayService.resultNotify();
logger.info("支付宝回调返回:"+msg);
String jsonmes = JSON.toJSONString(msg);
logger.info("支付宝回调返回(fast处理):"+jsonmes);
return msg;//直接返回success,不要带任何东西,否则会一直回调
}
问题一:
由于maven中央仓库里没有支付宝的api。所以我们需要手动下载jar。提取码为:gt05
springboot的话,只需要这一个jar包就可以。
然后自己导入进maven仓库里。具体步骤可以自行百度,将jar打进你本地的maven仓库后就可以正常导入pom文件使用。
pom文件展示:
<!-- alipay -->
<dependency>
<groupId>com.alipay</groupId>
<artifactId>sdk-java</artifactId>
<version>4.9.3</version>
</dependency>
至此,支付宝授权登陆,支付接口就完成了。
实战操作建议配合官方文档一起,便于自己深刻理解。
如对上面有疑问的可以评论留言,看到会解答。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/99024.html