通过支付宝提供的API实现移动支付功能

一:下载相关的依赖和工具

蚂蚁金服 https://open.alipay.com/platform/home.htm

移动支付开发文档 https://docs.open.alipay.com/203/105285/

sdk-jar文件下载 https://docs.open.alipay.com/54/103419/

支付宝接口参数说明 https://docs.open.alipay.com/api_1/alipay.trade.wap.pay

   在线支付实例下载 https://docs.open.alipay.com/54/106682/

  生成支付宝公钥和私钥  https://gw.alipayobjects.com/os/rmsportal/PpisHyUkzJnZltrPyfuD.zip

二:搭建开发环境

   (1):直接下载好sdk依赖包导入lib目录alipay-sdk-java-3.4.49.ALL.jar

   (2):通过Maven依赖下载jar

 <dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.4.49.ALL</version>
</dependency>

三:移动支付-全局配置类

package com.svse.util;
/**
* 移动支付-全局配置类
* @author lenovo
*
*/
public class AlipayConfig {
  // 商户appid
  public static final String APPID="";
  // 请求网关地址
  public static final String URL="https://openapi.alipay.com/gateway.do";
  // 返回格式
  public static final String FORMAT="json";
  // 编码
  public static final String CHARSET="UTF-8";
  // RSA2
  public static final String SIGNTYPE="RSA2";
  // 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
  public static final String notify_url="http://商户网关地址/alipay.trade.wap.pay-JAVA-UTF-8/notify_url.jsp";
  // 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址
  public static final String return_url="http://商户网关地址/alipay.trade.wap.pay-JAVA-UTF-8/return_url.jsp";
  // 过RSA签名验签工具生成支付宝公钥
  public static final String ALIPAY_PUBLIC_KEY="";
  // 通过RSA签名验签工具生成,PKCS8格式私钥
  public static final String RSA_PRIVATE_KEY=""; }

四:编写相关业务接口代码

1:支付宝在线支付接口

@RequestMapping("payment")
public void payment(HttpServletRequest request,HttpServletResponse response) throws IOException{   if(request.getParameter("WIDout_trade_no")!=null||request.getParameter("WIDtrade_no")!=null){
    //商户订单号
    String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
    // 订单名称,必填
    String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"),"UTF-8");
    System.out.println(subject);
    // 付款金额,必填
    String total_amount=new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"),"UTF-8");
    // 商品描述,可空
    String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"),"UTF-8");
    // 超时时间 可空
    String timeout_express="2m";
    // 销售产品码 必填
    String product_code="QUICK_WAP_WAY";
    /**********************/
    // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
    //调用RSA签名方式
    AlipayClient client =this.getAlipayClient();     AlipayTradeWapPayRequest alipay_request=new AlipayTradeWapPayRequest();
    // 封装请求支付信息
    AlipayTradeWapPayModel model=new AlipayTradeWapPayModel();
    model.setOutTradeNo(out_trade_no);
    model.setSubject(subject);
    model.setTotalAmount(total_amount);
    model.setBody(body);
    model.setTimeoutExpress(timeout_express);
    model.setProductCode(product_code);
    alipay_request.setBizModel(model);
    // 设置异步通知地址
    alipay_request.setNotifyUrl(AlipayConfig.notify_url);
    // 设置同步地址
    alipay_request.setReturnUrl(AlipayConfig.return_url);     // form表单生产
    String form = "";
    try {
      // 调用SDK生成表单
      form = client.pageExecute(alipay_request).getBody();
      response.setContentType("text/html;charset=" + AlipayConfig.CHARSET);
      response.getWriter().write(form);//直接将完整的表单html输出到页面
      response.getWriter().flush();
      response.getWriter().close();
    } catch (AlipayApiException e) {
      e.printStackTrace();
    }
    }else{
      System.out.println("订单出现问题,支付失败");
   }
}

2:支付宝在线生成订单接口

@RequestMapping("generateOrder")
public void generateOrder(HttpServletRequest request11,HttpServletResponse response11) throws UnsupportedEncodingException{
  if(request11.getParameter("WIDout_trade_no")!=null||request11.getParameter("WIDtrade_no")!=null){
  //商户订单号
  String out_trade_no = new String(request11.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
  //实例化客户端
  AlipayClient client =this.getAlipayClient();
  //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
  AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
  //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
  AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
  model.setBody("我是测试数据");
  model.setSubject("App支付测试Java");
  model.setOutTradeNo(out_trade_no);
  model.setTimeoutExpress("30m");
  model.setTotalAmount("0.01");
  model.setProductCode("QUICK_MSECURITY_PAY");
  request.setBizModel(model);
  request.setNotifyUrl("商户外网可以访问的异步地址");
  try {
    //这里和普通的接口调用不同,使用的是sdkExecute
    AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
    System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
  } catch (AlipayApiException e) {
    e.printStackTrace();
  }
 }
}

3:支付宝在线订单查询接口

@RequestMapping("searchOrder")
public void searchOrder(HttpServletRequest request,HttpServletResponse response){
  if(request.getParameter("WIDout_trade_no")!=null||request.getParameter("WIDtrade_no")!=null){
  try {
    //商户订单号,商户网站订单系统中唯一订单号,必填
    String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
    //支付宝交易号
    String trade_no = new String(request.getParameter("WIDtrade_no").getBytes("ISO-8859-1"),"UTF-8");
    /**********************/
    // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
    AlipayClient client =this.getAlipayClient();
    AlipayTradeQueryRequest alipay_request = new AlipayTradeQueryRequest();     AlipayTradeQueryModel model=new AlipayTradeQueryModel();
    model.setOutTradeNo(out_trade_no);
    model.setTradeNo(trade_no);
    alipay_request.setBizModel(model);     AlipayTradeQueryResponse alipay_response;
      try {
        alipay_response = client.execute(alipay_request);
        System.out.println(alipay_response.getBody());
      } catch (AlipayApiException e) {
        e.printStackTrace();
      }    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
   }
  }
}

4:支付宝在线订单退款接口

@RequestMapping("orderRefund")
public void orderRefund(HttpServletRequest request,HttpServletResponse response){
  if(request.getParameter("WIDout_trade_no")!=null||request.getParameter("WIDtrade_no")!=null){
    //商户订单号和支付宝交易号不能同时为空。 trade_no、 out_trade_no如果同时存在优先取trade_no
    //商户订单号,和支付宝交易号二选一
    String out_trade_no;
    try {
       out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
       //支付宝交易号,和商户订单号二选一
      String trade_no = new String(request.getParameter("WIDtrade_no").getBytes("ISO-8859-1"),"UTF-8");
      //退款金额,不能大于订单总金额
      String refund_amount=new String(request.getParameter("WIDrefund_amount").getBytes("ISO-8859-1"),"UTF-8");
      //退款的原因说明
      String refund_reason=new String(request.getParameter("WIDrefund_reason").getBytes("ISO-8859-1"),"UTF-8");
      //标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传。
      String out_request_no=new String(request.getParameter("WIDout_request_no").getBytes("ISO-8859-1"),"UTF-8");
      /**********************/
      // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
       AlipayClient client =this.getAlipayClient();
      AlipayTradeRefundRequest alipay_request = new AlipayTradeRefundRequest();
      AlipayTradeRefundModel model=new AlipayTradeRefundModel();
      model.setOutTradeNo(out_trade_no);
      model.setTradeNo(trade_no);
      model.setRefundAmount(refund_amount);
      model.setRefundReason(refund_reason);
      model.setOutRequestNo(out_request_no);
      alipay_request.setBizModel(model);       AlipayTradeRefundResponse alipay_response;
        try {
           alipay_response = client.execute(alipay_request);
          System.out.println(alipay_response.getBody());
        } catch (AlipayApiException e) {
          e.printStackTrace();
        }      } catch (UnsupportedEncodingException e1) {
          e1.printStackTrace();
     }
   }
}

5:订单退款查询接口

 @RequestMapping("searchOrderRefund")
public void searchOrderRefund(HttpServletRequest request,HttpServletResponse response){
  if(request.getParameter("WIDout_trade_no")!=null||request.getParameter("WIDtrade_no")!=null && request.getParameter("WIDout_request_no")!=null){
      try {
          //商户订单号和支付宝交易号不能同时为空。 trade_no、 out_trade_no如果同时存在优先取trade_no
         //商户订单号,和支付宝交易号二选一
         String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
         //支付宝交易号,和商户订单号二选一
       String trade_no = new String(request.getParameter("WIDtrade_no").getBytes("ISO-8859-1"),"UTF-8");
       //请求退款接口时,传入的退款请求号,如果在退款请求时未传入,则该值为创建交易时的外部交易号
       String out_request_no = new String(request.getParameter("WIDout_request_no").getBytes("ISO-8859-1"),"UTF-8");
       /**********************/
       // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
       AlipayClient client =this.getAlipayClient();
       AlipayTradeFastpayRefundQueryRequest alipay_request = new AlipayTradeFastpayRefundQueryRequest();        AlipayTradeFastpayRefundQueryModel model=new AlipayTradeFastpayRefundQueryModel();
       model.setOutTradeNo(out_trade_no);
       model.setTradeNo(trade_no);
       model.setOutRequestNo(out_request_no);
       alipay_request.setBizModel(model);        AlipayTradeFastpayRefundQueryResponse alipay_response=client.execute(alipay_request);
       System.out.println(alipay_response.getBody());
    } catch (Exception e) {
       e.printStackTrace();
   }
  }
}

6:账单下载接口

@RequestMapping("downloadBill")
public void downloadBill(HttpServletRequest request,HttpServletResponse response){
   if(request.getParameter("WIDbill_type")!=null&&request.getParameter("WIDbill_date")!=null){
   try {
    // 账单类型,商户通过接口或商户经开放平台授权后其所属服务商通过接口可以获取以下账单类型:trade、signcustomer;
    // trade指商户基于支付宝交易收单的业务账单;signcustomer是指基于商户支付宝余额收入及支出等资金变动的帐务账单;
    String bill_type = new String(request.getParameter("WIDbill_type").getBytes("ISO-8859-1"),"UTF-8");
    // 账单时间:日账单格式为yyyy-MM-dd,月账单格式为yyyy-MM。
    String bill_date = new String(request.getParameter("WIDbill_date").getBytes("ISO-8859-1"),"UTF-8");
    /**********************/
    // SDK 公共请求类,包含公共请求参数,以及封装了签名与验签,开发者无需关注签名与验签
     AlipayClient client =this.getAlipayClient();
    AlipayDataDataserviceBillDownloadurlQueryRequest alipay_request = new AlipayDataDataserviceBillDownloadurlQueryRequest();     AlipayDataDataserviceBillDownloadurlQueryModel model =new AlipayDataDataserviceBillDownloadurlQueryModel();
    model.setBillType(bill_type);
    model.setBillDate(bill_date);
    alipay_request.setBizModel(model);     AlipayDataDataserviceBillDownloadurlQueryResponse alipay_response = client.execute(alipay_request);
    System.out.println(alipay_response.getBillDownloadUrl());
   } catch (Exception e) {
    e.printStackTrace();    }
  }
}

7:异步通知消息接口

@RequestMapping("notifyUrl")
@ResponseBody
public String notify(HttpServletRequest request){
  int im=0;
  im++;
  //测试请求次数
  System.out.println("次数:"+im);
  //获取支付宝POST过来反馈信息
  Map<String,String> params = new HashMap<String,String>();
  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);
  }
  //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
  //商户订单号
  String out_trade_no = request.getParameter("out_trade_no");
  //支付宝交易号
  String trade_no = request.getParameter("trade_no");   //交易状态
  String trade_status = request.getParameter("trade_status");
  System.out.println(trade_status);
  try {
    boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, "utf-8", "RSA2");
    if(verify_result){
      //验证成功
      //请在这里加上商户的业务逻辑程序代码
      System.out.println("returnUrl_params:验证成功");
      //——请根据您的业务逻辑来编写程序(以下代码仅作参考)——
      boolean flag = false;
      if(trade_status.equals("TRADE_FINISHED")){
        System.out.println("returnUrl_params:交易结束");
        //交易结束,不可退款         //注意:
        //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
      }else if (trade_status.equals("TRADE_SUCCESS")){
        //交易支付成功         //注意:
        //付款完成后,支付宝系统发送该交易状态通知         //根据订单号将订单状态和支付宝记录表中状态都改为已支付
        System.out.println("returnUrl_params:交易支付成功");
        flag = true;
        //——请根据您的业务逻辑来编写程序(以上代码仅作参考)——         if(flag){
          return "success";
        }else{
          return "fail";
        }
      }
    }else{
      //验证失败
      System.out.println("交易失败");
      return "fail";
    }
  } catch (Exception e) {
    e.printStackTrace();
    return "500";
  }
  return null;
}

8:同步通知消息接口

@RequestMapping("/returnUrl")
public ModelAndView result(HttpServletRequest request) {
   System.out.println("进来");
  //用ModelAndView 进行数据渲染
  ModelAndView mv = new ModelAndView("alipay/return_url");
  //获取支付宝GET过来反馈信息
  Map<String,String> params = new HashMap<String,String>();
  Map<String, String[]> requestParams = request.getParameterMap();
  for(String str:requestParams.keySet()){
    String[] values=requestParams.get(str);
    String valueStr="";
    for (int i = 0; i < values.length; i++) {
      valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
    }
    //乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
    //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
    params.put(str, valueStr);
   }
  //交易订单编号
  String out_trade_no = request.getParameter("out_trade_no");
  //交易金额
  String total_amount = request.getParameter("total_amount");
  //支付宝交易账号
  //String trade_no = request.getParameter("trade_no");
  //订单创建时间
  String timestamp = request.getParameter("timestamp");
  mv.addObject("out_trade_no", out_trade_no);
  mv.addObject("total_amount", total_amount);
  mv.addObject("timestamp", timestamp);
  //打印所有响应数据
  System.out.println("returnUrl_params:"+params);
  try {
    //切记AlipayConfig.ALIPAY_PUBLIC_KEY是支付宝的公钥,请去open.alipay.com对应应用下查看。
    boolean verify_result = AlipaySignature.rsaCheckV1(params, AlipayConfig.ALIPAY_PUBLIC_KEY, "utf-8", "RSA2");
    if(verify_result){
      //验证成功 这里写的是假代码
      //系统处理根据支付宝回调更改订单状态或者其他关联表的数据 (走业务流程, 根据订单编号获取订单数据
      //Order order =orderService.queryOrderByNumber(out_trade_no);       /* if(order !=null){
        //order不为null
      mv.addObject("verify_result", verify_result);
      mv.addObject("msg", "商户订单号不存在");
      } */
      return mv;
    }else{
      //验证失败 跳失败页面
      System.out.println("验证失败");
      return null;
    }   } catch (Exception e) {
    e.printStackTrace();
    //出现异常 跳失败页面
    return null;
  }
}

支付宝alipay移动支付的更多相关文章

  1. laravel5集成支付宝alipay扫码支付流程(Laravel 支付解决方案)

    首先我们来探讨如何在Laravel应用中使用支付宝进行支付,对此,GitHub上有很多相关的包,其中最流行的两个包:Omnipay For Laravel 5 & Lumen 和 Larave ...

  2. 自己动手搞定支付宝手机网站支付接口 FOR ECShop

    支付宝WAP网站版本的支付接口网上整合的比较少,看到很多网站在卖,顿觉无语. 主要是得自己查看支付宝官方提供的SDK中的开发文档. 支付宝sdk下载地址:https://doc.open.alipay ...

  3. 支付宝手机网站支付流程(Node实现)

    前言 公司M站要接入支付宝,借机研究了一下支付宝的支付流程.毕竟,只有公司才能拿到支付接口权限. 主要参考文档: https://doc.open.alipay.com/doc2/detail?tre ...

  4. 简聊iOS支付集成(支付宝和微信支付)

    一.支付集成是什么 1.现在大部分app都有快捷支付功能,支付集成将第三方支付平台集成到自己的项目中,能够完成自己项目中的支付功能, 二.支付集成的使用 <1>.支付宝: 下载SDK和De ...

  5. 支付sdk —— 该组件为封装了 微信,支付宝,银联支付

    [精品]  支付组件 简要说明该组件为封装了 微信,支付宝,银联支付, 一键快速集成,几行代码即可集成 微信,支付宝,银联支付. ## 示例: # 测试账号:1.银联支付:提供测试使用卡号.手机号信息 ...

  6. ASP.NET Core Web 支付功能接入 支付宝-电脑网页支付篇

    这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入支付宝-电脑网页支付接口及同步跳转及异步通知功能. 开发环境:Win 10 x64.VS2017 15.6.4..NET ...

  7. ***CodeIgniter框架集成支付宝即时到账支付SDK

    本文为CI集成支付宝即时到账支付接口 1.下载支付宝官方demo ;即时到账交易接口(create_direct_pay_by_user)(DEMO下载) 原文地址:https://doc.open. ...

  8. 【转载】ASP.NET Core Web 支付功能接入 支付宝-电脑网页支付篇

    转自:http://www.cnblogs.com/essenroc/p/8627775.html 这篇文章将介绍ASP.NET Core中使用 开源项目 Payment,实现接入支付宝-电脑网页支付 ...

  9. php支付宝手机网页支付类实例

    <?php $alipayConfig = array( 'key' => 'xxxxx', //买卖安全校验码,用于签名的32位密钥 'transport' => 'https', ...

随机推荐

  1. web框架的前生今世--从servlet到spring mvc到spring boot

    背景 上世纪90年代,随着Internet和浏览器的飞速发展,基于浏览器的B/S模式随之火爆发展起来.最初,用户使用浏览器向WEB服务器发送的请求都是请求静态的资源,比如html.css等.  但是可 ...

  2. PHP打印指定日期

    打印某一日期的前一天 echo date("Y-m-d",(strtotime("2009-01-01") - 3600*24)); (1)打印明天此时的时间戳 ...

  3. mybatis教程6(逆向工程)

    什么是逆向工程 简单点说,就是通过数据库中的单表,自动生成java代码. Mybatis官方提供了逆向工程,可以针对单表自动生成mybatis代码(mapper.java\mapper.xml\po类 ...

  4. python——文件读写

    open()函数用法: file-object = open(file_name, access_mode = ' ', buffering = -1) filename可以是相对路径或绝对路径,ac ...

  5. 记录解决phpStudy报出403Forbidden问题的方法

    本人输入ip地址+目录去访问PHPTutorial/WWW目录下的某个文件,发生了没有权限访问的问题,导了一个下午,终于解决……不忘在此做个记录 1. 打开phpStudy,点击按键“其他选项菜单”= ...

  6. 【学习笔记】JS设计模式总结

    前言:这段时间都在学习Vue的知识,虽然手边放着一本js高程,但确实好久没有好好复习了.温故而知新,因此特意把JS常见的设计模式总结,希望对大家有所帮助... 1. 工厂模式 释义:像工厂一样流水线般 ...

  7. 初始mvc4(一) 新建项目

    mvc4和mvc4.5基本大同小异,vs2012中已经集成了mvc,不需要手动安装了,现在就来看看如何新建mvc项目 一.首先打开vs2012,新建项目,选中web中mvc4 二.选择项目模板 这里面 ...

  8. SQL Server中锁与事务隔离级别

    SQL Server中的锁分为两类: 共享锁 排它锁 锁的兼容性:事务间锁的相互影响称为锁的兼容性. 锁模式 是否可以持有排它锁 是否可以持有共享锁 已持有排它锁 否 否 已持有共享锁 否 是 SQL ...

  9. [PHP] 算法-两个n位的二进制整数相加问题PHP实现

    两个n位二进制数分别存储在两个n元数组A和B中,这两个整数的和存在一个n+1元的数组C中答:此问题主要是考察相加进位的问题,元素1+1 =0 并且往前进一位ADD-BINARY(A,B) C=new ...

  10. 【Tomcat】详解tomcat的连接数与线程池

    前言 在使用tomcat时,经常会遇到连接数.线程数之类的配置问题,要真正理解这些概念,必须先了解Tomcat的连接器(Connector). Connector的主要功能,是接收连接请求,创建Req ...