这段时间帮助一个电商平台做了手机支付宝支付的模块,过程中遇到了一些坑,也收获了一些经验,在此做一下记录,也希望能帮助到后来的人。
我们的需求比较常规,就是下单的时候选择支付宝支付,支付给卖家即可。接入支付宝支付模块后应尽量让卖家操作简单,毕竟卖家不一定有开发能力,也不一定很懂电脑。为此,我们选择服务商授权第三方应用模式,卖家只需在蚂蚁金服务开放平台注册手机网站支付应用,然后在平台一键授权即可,非常简单。
首先,我们先看支付宝官方的文档以及官方demo,可以说基本所有问题都可以从文档里找到答案,实在找不到答案可以去问蚂蚁金服的人工客服。支付宝手机支付官方文档地址:https://docs.open.alipay.com/203/105288/ ,在文档里可以找到官方demo。我们先按照支付宝手机支付的官方文档完成支付宝支付功能。
可以使用沙箱账号,也可以直接使用真实账号,我们这里就不介绍沙箱账号配置方法,使用真实账号。需要提醒的是,沙箱账号有个坑:配置沙箱卖家账号之后,支付也只能使用沙箱买家账号,对于手机端,要下载沙箱版的支付宝app,登陆沙箱账号,而沙箱账号在我们用的支付宝app上是无法登陆的!
在蚂蚁金服开放平台使用支付宝账号密码登录,第一次登陆的时候要选择身份,可以选择系统服务商(ISV),也可以选择自主开发者,在后期可以扩展身份,这里选择系统服务商好了,对于注册应用似乎没什么影响。然后就需要注册应用,可以参考文档:https://docs.open.alipay.com/203/107084/ 即可,这里有一个授权回调地址,这是后来授权给第三方应用需要配置的项,现在可以不填或者随便填一个地址,支付宝网关是图里固定的一个url(对于沙箱是另一个url),支付宝公钥和应用公钥、应用私钥都可查看文档在本地生成,这些在代码里也要用到。
应用注册好,通过审核、上线之后,需要添加手机网站支付的功能,点击应用详情,进入应用详情页,点击添加功能,输入一系列必要的资料,等审核通过即可(对于个人账号貌似需要公司营业执照,公司支付宝账号似乎不需要,当时做的太快忘记了。。)。
准备工作做好之后,就要开始写代码。首先,因为在实现过程中需要调用支付宝的很多接口,我们需要导入alipay的jar包,在pom文件里添加依赖:
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.1.0</version>
</dependency>
然后,在application.yml文件里添加相关基本配置:
pay:
alipay:
gatewayUrl: https://openapi.alipay.com/gateway.do
appid: 申请的应用id
appPrivateKey: 生成的应用私钥
alipayPublicKey: 支付宝公钥
returnUrl: https://xxxxxx/alipay/returnurl
notifyUrl: https://xxxxxx/alipay/notifyurl
charset: UTF-8
format: json
signtype: RSA2
returnUrl和notifyUrl是两个接口地址,都需要是线上可访问的,因为是支付宝来调用这两个接口。
接下来新建AlipayController.java文件,在这个controller里写有关支付宝支付的所有接口,必要的接口包括创建支付宝订单接口、异步回调接口、同步回调接口和退款接口,其他一些辅助接口(比如交易查询接口、下载对账单接口等)可根据自己项目需要再加上。
创建支付宝订单接口包括两部分,一部分是和自己业务相关的,根据自己的订单获取支付金额、支付信息等,另一部分是调用alipay-sdk中的相关接口,由支付宝来处理支付信息,跳到支付宝支付界面进行支付。代码如下:
/**
* 生成支付宝支付订单接口,传入参数为多个订单orderNo的数组,可多个订单一起支付
* @param orderNoDTO
* @return
* @throws ServletException
* @throws IOException
*/
@PostMapping(value = "/createAlipayOrder")
public Object createAlipayOrder(@RequestBody OrderNoDTO orderNoDTO) throws ServletException, IOException{
Map<String, Object> map = new HashMap<>();
if(orderNoDTO.getOrderNo().size()<=0){
return ResponseJsonUtil.returnJson(map, BusinessConstants.GET_ORDER_LIST_ERROR, PsiInfo.ERROR.code);
}//判断orderNoDTO里是否有订单,没有订单报错
String firstOrderNo=orderNoDTO.getOrderNo().get(0);
Long sellerId=orderService.selectSellerIdByOrderNo(firstOrderNo);//所有订单卖家相同,因此根据第一个订单编号即可获取卖家id
double money=0.0;//支付金额初始值
String subject="";//支付描述信息
AlipayOrder alipayOrder=new AlipayOrder();//创建支付订单
alipayOrder.setOut_trade_no(CreateOrderNo.createOrderNo("Alipay"));//创建由Alipay打头的支付订单号,多个订单号对应一个支付订单号
for(String orderNo:orderNoDTO.getOrderNo()){
try{
Order order=orderService.getSingleOrderByOrderNo(orderNo);
order.setAlipay_out_trade_no(alipayOrder.getOut_trade_no());
orderService.updateOrderByExample(order);//获取原销售订单,将支付订单号传入并更新
List<OrderEx> orderExlist=orderService.getOrderDetailByOrderNo(orderNo);//获取原支付订单包含的物品信息
for(OrderEx orderEx:orderExlist){
subject+=orderEx.getGoodsName();//支付订单描述由所有物品信息组成
logger.info("subject:{}",subject);
}
money+=order.getMoney().doubleValue();//支付订单金额等于原订单金额之和
logger.info("money:{}",money);
}catch (Exception e){
}
}
//以上是与自己业务相关的代码,可根据自己业务来,最重要的是要生成支付订单号,获取支付金额和支付描述信息
alipayOrder.setStatus((byte)0);//0代表创建订单等待付款
alipayOrder.setTotal_amount(new BigDecimal(Double.toString(money)));//支付订单金额
alipayOrder.setReceipt_amount(new BigDecimal(Double.toString(0.00)));//实收金额
alipayOrder.setInvoice_amount(new BigDecimal(Double.toString(0.00)));//开票金额
alipayOrder.setBuyerpay_amount(new BigDecimal(Double.toString(0.00)));//买家付款金额
alipayOrder.setRefund_fee(new BigDecimal(Double.toString(0.00)));//退款金额
if(orderService.createAlipayOrder(alipayOrder)<=0) {
return ResponseJsonUtil.returnJson(map, BusinessConstants.AliPay_ORDER_CREATE_FAIL, PsiInfo.ERROR.code);
}//创建支付订单,插入数据库
try{
//String alipayToken=storeService.getAlipayTokenByMemberId(sellerId);
//if(alipayToken==null){
//return ResponseJsonUtil.returnJson(map, BusinessConstants.AliPay_TOKEN_NULL, PsiInfo.ERROR.code);
// }
//以上注释是和授权有关代码,以后再提,目前对于支付并无影响
AlipayClient alipayClient=new DefaultAlipayClient(aliPayConfig.getGatewayUrl(),aliPayConfig.getAppid(),aliPayConfig.getAppPrivateKey(),"json",aliPayConfig.getCharset(),aliPayConfig.getAlipayPublicKey(),aliPayConfig.getSigntype());//初始化AlipayClient
AlipayTradeWapPayRequest alipayRequest=new AlipayTradeWapPayRequest();//初始化AlipayTradeWapPayRequest,注意是手机网站支付
AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
model.setOutTradeNo(alipayOrder.getOut_trade_no());
model.setSubject(subject);
model.setTotalAmount(alipayOrder.getTotal_amount().toString());
model.setProductCode("QUICK_WAP_WAY");
alipayRequest.setBizModel(model);
alipayRequest.setReturnUrl(aliPayConfig.getReturnUrl());
alipayRequest.setNotifyUrl(aliPayConfig.getNotifyUrl());//给alipayRequest配置必要参数
//alipayRequest.putOtherTextParam("app_auth_token", alipayToken);
//以上注释掉的是和授权有关,暂时用不到
logger.info("subject:{}",model.getSubject());
logger.info("totalamount:{}",model.getTotalAmount());
logger.info("outtradeno:{}",model.getOutTradeNo());
String form="";
try{
form=alipayClient.pageExecute(alipayRequest).getBody();//执行请求
}catch (AlipayApiException e){
e.printStackTrace();
}
map.put("form",form);//返回的form还需要前端去请求,请求之后就可以跳到支付宝支付界面了,之后的事情就是在支付宝里进行的了
return ResponseJsonUtil.returnJson(map, BusinessConstants.SERVICE_SUCCESS_MSG, PsiInfo.OK.code);
}catch (Exception e){
logger.error("异常码[{}],异常提示[{}],异常[{}]",
BusinessConstants.AliPay_ORDER_CREATE_FAIL_CODE, BusinessConstants.AliPay_ORDER_CREATE_FAIL, e);
}
return ResponseJsonUtil.returnJson(map, BusinessConstants.AliPay_ORDER_CREATE_FAIL, PsiInfo.ERROR.code);
}
支付宝支付之后,我们如何获取成功或者失败信息呢?这时候就需要支付宝回调,回调的两个接口已经在application.yml配置好了,现在需要写这两个接口。一个是异步通知接口,以它为准,在接口里修改订单状态等,另一个是同步回调地址,不以它为准,用来跳转到支付成功或失败的页面。
/**
* 支付宝支付成功后.异步请求该接口,修改订单状态,以这个接口为准
* 不直接调用,支付宝调用
* @param request
* @param response
* @return
* @throws IOException
*/
@RequestMapping(value="/notifyurl",method=RequestMethod.POST)
@ResponseBody
public String notify(HttpServletRequest request,HttpServletResponse response) throws IOException{
Map<String,String[]> aliParams=request.getParameterMap();
Map<String,String> conversionParams=new HashMap<>();
for(Iterator<String> iter=aliParams.keySet().iterator();iter.hasNext();){
String key=iter.next();
String[] values=aliParams.get(key);
String valueStr="";
for(int i=0;i<values.length;i++){
valueStr=(i==values.length-1)?valueStr+values[i]:valueStr+values[i]+",";
}
conversionParams.put(key,valueStr);//参考了一些博客和官方文档的代码
}
String status=aliPayService.notify(conversionParams);
return status;
}
重点是aliPayService.notify方法
@Override
public String notify(Map<String,String> conversionParams){
boolean signVerified=false;
try{
signVerified=AlipaySignature.rsaCheckV1(conversionParams,aliPayConfig.getAlipayPublicKey(),aliPayConfig.getCharset(),aliPayConfig.getSigntype());
}catch (AlipayApiException e){
e.printStackTrace();
}
if(signVerified){
String appId=conversionParams.get("app_id");//支付宝分配给开发者的应用Id
String notifyTime=conversionParams.get("notify_time");//通知时间:yyyy-MM-dd HH:mm:ss
String gmtCreate=conversionParams.get("gmt_create");//交易创建时间:yyyy-MM-dd HH:mm:ss
String gmtPayment=conversionParams.get("gmt_payment");//交易付款时间
String gmtRefund=conversionParams.get("gmt_refund");//交易退款时间
String gmtClose=conversionParams.get("gmt_close");//交易结束时间
String tradeNo=conversionParams.get("trade_no");//支付宝的交易号
String outTradeNo = conversionParams.get("out_trade_no");//获取商户之前传给支付宝的订单号(商户系统的唯一订单号)
String outBizNo=conversionParams.get("out_biz_no");//商户业务号(商户业务ID,主要是退款通知中返回退款申请的流水号)
String buyerLogonId=conversionParams.get("buyer_logon_id");//买家支付宝账号
String sellerId=conversionParams.get("seller_id");//卖家支付宝用户号
String sellerEmail=conversionParams.get("seller_email");//卖家支付宝账号
String totalAmount=conversionParams.get("total_amount");//订单金额:本次交易支付的订单金额,单位为人民币(元)
String receiptAmount=conversionParams.get("receipt_amount");//实收金额:商家在交易中实际收到的款项,单位为元
String invoiceAmount=conversionParams.get("invoice_amount");//开票金额:用户在交易中支付的可开发票的金额
String buyerPayAmount=conversionParams.get("buyer_pay_amount");//付款金额:用户在交易中支付的金额
String tradeStatus = conversionParams.get("trade_status");// 获取交易状态
// String outTradeNo=conversionParams.get("out_trade_no");
// String tradeNo=conversionParams.get("trade_no");
// String tradeStatus=conversionParams.get("trade_status");
// String totalAmount=conversionParams.get("total_amount");
AlipayOrder alipayOrder=orderService.selectAlipayOrderByOutTradeNo(outTradeNo);
if(alipayOrder!=null&&totalAmount.equals(alipayOrder.getTotal_amount().toString())){
if(appId!=null){
alipayOrder.setApp_id(appId);
}
if(notifyTime!=null){
alipayOrder.setNotify_time(notifyTime);
}
if(gmtClose!=null){
alipayOrder.setGmt_close_time(gmtClose);
}
if(gmtCreate!=null){
alipayOrder.setGmt_create_time(gmtCreate);
}
if(gmtPayment!=null){
alipayOrder.setGmt_payment_time(gmtPayment);
}
if(gmtRefund!=null){
alipayOrder.setGmt_refund_time(gmtRefund);
}
if(buyerLogonId!=null){
alipayOrder.setBuyer_logon_id(buyerLogonId);
}
if(outBizNo!=null){
alipayOrder.setOut_biz_no(outBizNo);
}
if(sellerId!=null){
alipayOrder.setSeller_id(sellerId);
}
if(sellerEmail!=null){
alipayOrder.setSeller_email(sellerEmail);
}
if(receiptAmount!=null){
alipayOrder.setReceipt_amount(new BigDecimal(Double.parseDouble(receiptAmount)));
}
if(invoiceAmount!=null){
alipayOrder.setInvoice_amount(new BigDecimal(Double.parseDouble(invoiceAmount)));
}
if(buyerPayAmount!=null){
alipayOrder.setBuyerpay_amount(new BigDecimal(Double.parseDouble(buyerPayAmount)));
}
if(totalAmount!=null){
alipayOrder.setTotal_amount(new BigDecimal(Double.parseDouble(totalAmount)));
}
if(tradeNo!=null){
alipayOrder.setTrade_no(tradeNo);
}
if(outTradeNo!=null){
alipayOrder.setOut_trade_no(outTradeNo);
}
switch (tradeStatus) // 判断交易结果
{
case "TRADE_FINISHED": // 交易结束并不可退款
alipayOrder.setStatus((byte) 3);
break;
case "TRADE_SUCCESS": // 交易支付成功
alipayOrder.setStatus((byte) 2);
break;
case "TRADE_CLOSED": // 未付款交易超时关闭或支付完成后全额退款
alipayOrder.setStatus((byte) 1);
break;
case "WAIT_BUYER_PAY": // 交易创建并等待买家付款
alipayOrder.setStatus((byte) 0);
break;
default:
break;
}
int returnResult=orderService.updateByExample(alipayOrder);
if(gmtRefund==null){
//这里有一个小坑,在退款成功之后也会调用这个异步通知接口。支付成功后我们会将订单状态由待付款改为待发货,而退款成功之后订单状态不会再改变,改变的是退款单的状态,因此这里由gmtRefund即退款时间是否为空来判断是退款成功还是支付成功
if(tradeStatus.equals("TRADE_SUCCESS")&&returnResult>0){
if(orderService.updateOrderByOutTradeNo(outTradeNo, OrderConstants.PAY_TYPE_ALIPAY)>0){
//修改订单状态,OrderConstants.PAY_TYPE_ALIPAY为支付方式
return "success";
}else{
return "fail";
}
}else{
return "fail";
}
}else{
if(tradeStatus.equals("TRADE_SUCCESS")&&returnResult>0){
if(orderService.updateOrderModifyTime(outTradeNo)>0) {
return "success";
}
}else{
return "fail";
}
}
}else{
return "fail";
}
}else{
return "fail";
}
return "fail";
}
/**
* 支付宝支付成功之后,同步通知接口,跳转回支付成功或者支付失败页面,但不修改订单状态,不以这个为准
* 不直接调用,支付宝调用
* @param request
* @param response
* @param outTradeNo
*/
@RequestMapping(value="/returnurl",method=RequestMethod.GET)
public void returnUrl(HttpServletRequest request, HttpServletResponse response,String outTradeNo){
Map<String,String> params = new HashMap<>();
Map requestParams=request.getParameterMap();
for (Iterator 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);
}
try{
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");
boolean verify_result = AlipaySignature.rsaCheckV1(params, aliPayConfig.getAlipayPublicKey(), aliPayConfig.getCharset(), "RSA2");
if(verify_result){
response.sendRedirect("https://xxxxxxxxxxx#/successPay");//跳到支付成功页面
}else{
response.sendRedirect("https://xxxxxxxxxxxxx/#/errorPay");//跳到支付失败页面
}
}catch (Exception e){
}
}
/**
* 支付宝退款接口
* @param id,为退款单的id
* @return
*/
@PostMapping(value = "/refund")
public String refund(@RequestParam Long id){
Map<String, Object> map = new HashMap<>();
AfterSale afterSale=afterSaleService.selectById(id);//跟自己业务有关,根据id获取退款单
if(afterSale==null){
return ResponseJsonUtil.returnJson(map, BusinessConstants.AFTER_SALE_IS_NULL, PsiInfo.ERROR.code);
}
BigDecimal totalAmount=afterSale.getTotal_amount();//退款金额
String alipayOutTradeNo=orderService.selectAlipayOutTradeNoByOrderNo(afterSale.getOrderNo());//根据原订单号获取支付订单号
String alipayTradeNo=orderService.selectAlipayTradeNoByOrderNo(afterSale.getOrderNo());//获取支付宝交易号
try{
// Long sellerId=afterSale.getSellerId();
// String alipayToken=storeService.getAlipayTokenByMemberId(sellerId);
// if(alipayToken==null){
// return ResponseJsonUtil.returnJson(map, BusinessConstants.AliPay_TOKEN_NULL, PsiInfo.ERROR.code);
// }
//与授权有关代码
AlipayClient alipayClient=new DefaultAlipayClient(aliPayConfig.getGatewayUrl(),aliPayConfig.getAppid(),aliPayConfig.getAppPrivateKey(),"json",aliPayConfig.getCharset(),aliPayConfig.getAlipayPublicKey(),aliPayConfig.getSigntype());
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
AlipayTradeRefundModel model=new AlipayTradeRefundModel();
model.setOutTradeNo(alipayOutTradeNo);
model.setTradeNo(alipayTradeNo);
model.setRefundAmount(totalAmount.toString());
model.setOutRequestNo(CreateOrderNo.createRefundNo());//随机退款流水号
request.setBizModel(model);
// request.putOtherTextParam("app_auth_token", alipayToken);授权相关代码
try{
AlipayTradeRefundResponse alipay_response =alipayClient.execute(request);
logger.info("alipay_response的内容是:{}",alipay_response.getBody());
if(alipay_response.getFundChange()==null){
map.put("result","退款失败,请重试!");
}else if(alipay_response.getFundChange().equals("Y")){
map.put("result","退款成功!");
}else{
map.put("result","退款失败,请重试!");
}//退款成功与否根据alipay_response.getFundChange()是否为Y来判断
map.put("form",alipay_response.getBody());
}catch (AlipayApiException e){
e.printStackTrace();
}
return ResponseJsonUtil.returnJson(map, BusinessConstants.SERVICE_SUCCESS_MSG, PsiInfo.OK.code);
}catch (Exception e){
logger.error("异常码[{}],异常提示[{}],异常[{}]",
BusinessConstants.AliPay_ORDER_REFUND_FAIL_CODE, BusinessConstants.AliPay_ORDER_REFUND_FAIL, e);
}
return ResponseJsonUtil.returnJson(map, BusinessConstants.AliPay_ORDER_REFUND_FAIL, PsiInfo.ERROR.code);
}
到此,支付所必需的几个接口介绍完了。接下来,我们要做和第三方授权有关的事情。
为什么要做这个第三方授权呢?根据刚才的代码,在代码里获取配置好的appid、appPrivateKey、alipayPublicKey,根据这些支付宝才能识别支付的收款方,也就是卖家。对于我们平台,需要将支付金额直接支付给卖家,那就不能直接获取配置的appid、appPrivateKey、alipayPublicKey,因为这些并不是卖家的。为了解决这个问题,开始考虑过每个卖家注册的时候填这些信息,存入数据库,在付款的时候根据sellerid获取这些,进而可以达到付款给卖家的目的,但是这个方法对于卖家操作比较复杂,并且appPrivateKey、alipayPublicKey都很长,存入数据库会让数据库十分臃肿,因而不可行。查找蚂蚁金服务开发文档,找到一种第三方授权的方式,可以让卖家支付宝授权给平台,平台即可代替第三方完成收账、退款等功能,卖家所做的只需要同意授权、生成授权码存入数据库,在支付、退款的时候提取出授权码即可识别要授权的第三方,对于卖家只需一键授权,十分方便。相关的文档如下:https://docs.open.alipay.com/20160728150111277227/intro 。
/**
* 集团、店主生成支付宝授权AppAuthCode的接口,调用之后调用生成支付宝授权码AppAuthToken的接口,一键生成授权码
* @param httpRequest
* @param httpResponse
* @return
*/
@GetMapping(value = "/createAppAuthCode")
public Object quickCreateAppAuthToken(HttpServletRequest httpRequest, HttpServletResponse httpResponse){
Map<String,Object> map = new HashMap<>();
Member member = userService.checkToken(httpRequest);
map.put("memberId",member.getId());
map.put("url","https://openauth.alipay.com/oauth2/appToAppAuth.htm?app_id=服务商appid&redirect_uri=https://xxxxxxxxxxxxx/alipay/createAppAuthToken");
return ResponseJsonUtil.returnJson(map, BusinessConstants.SERVICE_SUCCESS_MSG, PsiInfo.OK.code);
}
还记得之前注册应用的时候有一项授权回调地址吗?
授权回调地址要和redirect_uri的值,也就是https://xxxxxxxxxxxxx/alipay/createAppAuthToken保持一致,这里直接设置为我们的接口,并且需要是一个外网可以访问的接口,接下来会介绍这个接口。这里获取了memberId,是需要在生成授权码时传这个参数,根据这个参数将授权码插入到数据库对应位置。这里需要前端拼接一下,将返回的结果拼接成一个url并请求,即为请求createAppAuthToken接口。
/**
* 生成支付宝授权码AppAuthToken的接口,在生成AppAuthCode的接口/alipay/createAppAuthCode已经被调用,无需再次调用,调用之后重定向回授权界面
* @param memberId
* @param app_id
* @param source
* @param app_auth_code
* @param httprequest
* @param httpResponse
*/
@GetMapping(value = "/createAppAuthToken")
public void createAppAuthToken(@Param("memberId") Long memberId,
@Param("app_id") String app_id,
@Param("source") String source,
@Param("app_auth_code") String app_auth_code,
HttpServletRequest httprequest,
HttpServletResponse httpResponse){
Map<String, Object> map = new HashMap<>();
AlipayClient alipayClient=new DefaultAlipayClient(aliPayConfig.getGatewayUrl(),aliPayConfig.getAppid(),aliPayConfig.getAppPrivateKey(),"json",aliPayConfig.getCharset(),aliPayConfig.getAlipayPublicKey(),aliPayConfig.getSigntype());
AlipayOpenAuthTokenAppRequest request = new AlipayOpenAuthTokenAppRequest();
request.setBizContent("{" +
" \"grant_type\":\"authorization_code\"," +
" \"code\":"+"\""+app_auth_code+"\""+
" }");
try{
AlipayOpenAuthTokenAppResponse response = alipayClient.execute(request);
JSONObject jsonObject=(JSONObject)(new JSONParser().parse(response.getBody()));
Object token_app_response=jsonObject.get("alipay_open_auth_token_app_response");
JSONObject token_app_response_jsonObject=(JSONObject)(new JSONParser().parse(token_app_response.toString()));
Object final_app_auth_token=token_app_response_jsonObject.get("app_auth_token");
Member member=userService.getUserById(memberId);
Store store=storeService.getStoresById(member.getStoreId());
if(store.getAlipayToken()!=null){
throw new RuntimeException("已经授权,无需再次授权!");
}
store.setAlipayToken(final_app_auth_token.toString());
String token = member.getPhone();
Cookie cookie = new Cookie(BusinessConstants.TOKEN, token);
cookie.setPath("/");
cookie.setMaxAge(BusinessConstants.COOKIE_MAX_AGE);
httpResponse.addCookie(cookie);//将登陆cookie存入httpresponse,可以在重定向的时候回到原界面,否则要重新登陆
if(storeService.updateStoreInfo(store)>0){
httpResponse.sendRedirect("https:///xxxxxxxxxxxx//#/weixinaliPay");
}else{
httpResponse.sendRedirect("https://xxxxxxxxxxxx/#/weixinaliPay");//无论授权成功与否都跳回到原授权界面
}
}catch (Exception e){
logger.error("异常码[{}],异常提示[{}],异常[{}]",
BusinessConstants.AliPay_TOKEN_CREATE_FAIL_CODE, BusinessConstants.AliPay_TOKEN_CREATE_FAIL, e);
}
}
/**
* 判断支付宝是否已经授权的接口
* @param httprequest
* @return
*/
@GetMapping(value = "/ifAuthorized")
public Object ifAuthorized(HttpServletRequest httprequest){
Map<String, Object> map = new HashMap<>();
Member member = userService.checkToken(httprequest);
if(member==null){
return ResponseJsonUtil.returnJson(map, BusinessConstants.NON_LOGIN_STATUS_ERROR, PsiInfo.ERROR.code);
}
Long storeId=member.getStoreId();
Store store=storeService.getStoresById(storeId);
if(store.getAlipayToken()!=null){
map.put("result","Y");
}else{
map.put("result","N");
}
return ResponseJsonUtil.returnJson(map, BusinessConstants.SERVICE_SUCCESS_MSG, PsiInfo.OK.code);
}
每次到授权界面,即调用这个接口,根据这个接口判断是否授权,前端根据此显示授权健暴露与否。如果授权成功返回,即显示已授权。授权成功之后,之前的代码
request.putOtherTextParam("app_auth_token", alipayToken);
就有了意义,授权之后,将直接支付给被授权的第三方,appid、appPrivateKey、alipayPublicKey还使用原先配置的服务商的。
大功告成,写的略有点乱。。希望读者能看懂吧哈哈,有什么不懂的可以给我留言。