移动大脑-SpringMVc搭建RestFul后台服务(五)-支付宝支付

225 阅读30分钟
原文链接: blog.csdn.net

        上一篇博客《移动大脑-SpringMVc搭建RestFul后台服务(四)-添加Token过滤器》中为服务器端程序加了Token验证来确保一定的安全性,这篇和下一篇将介绍接入支付宝支付和微信支付功能。

先来看看这篇文章所达到的效果如图:



支付宝支付逻辑主要是:

        APP端发送支付请求---->服务端生成本地支付订单---->服务端调用支付宝接口在支付宝后台生成支付宝支付订单---->支付宝生成支付订单返回给服务端---->服务端把支付宝返回的支付订单信息返回给APP端---->APP获取服务端返回的支付宝支付订单信息调起本地支付宝支付(支付宝客户端/支付宝H5支付页面)---->APP端成功付款---->支付宝同步通知APP支付结果并异步调用服务器回调接口告诉服务器支付结果---->服务端验证支付宝回调结果签名以及商户信息是否合法---->服务端处理相应的结果返回给支付宝服务器。这样就完成了一次支付过程。

开始搬砖

一、添加订单表“t_order”

1.1订单实体类OrderBean.java

  1. package com.ywl5320.appservice.bean;  
  2.   
  3. /** 
  4.  * Created by ywl5320 on 2017/10/19. 
  5.  */  
  6. public class OrderBean extends BaseBean{  
  7.   
  8.     private Integer id;  
  9.     private Integer userId;  
  10.     private String phone;  
  11.     private String orderNo;//订单号  
  12.     private String payMoney; //支付金额  
  13.     private String payGoods; //支付的商品名称  
  14.     private Integer payStatus;//支付状态 0:未支付 1:支付成功  
  15.     private String payTime;//支付时间  
  16.     private Integer payWay;//支付方式 1:支付宝  2:微信  
  17.     private String subject;  
  18.   
  19.     public String getPhone() {  
  20.         return phone;  
  21.     }  
  22.   
  23.     public void setPhone(String phone) {  
  24.         this.phone = phone;  
  25.     }  
  26.   
  27.     public Integer getId() {  
  28.         return id;  
  29.     }  
  30.   
  31.     public void setId(Integer id) {  
  32.         this.id = id;  
  33.     }  
  34.   
  35.     public Integer getUserId() {  
  36.         return userId;  
  37.     }  
  38.   
  39.     public void setUserId(Integer userId) {  
  40.         this.userId = userId;  
  41.     }  
  42.   
  43.     public String getOrderNo() {  
  44.         return orderNo;  
  45.     }  
  46.   
  47.     public void setOrderNo(String orderNo) {  
  48.         this.orderNo = orderNo;  
  49.     }  
  50.   
  51.     public String getPayMoney() {  
  52.         return payMoney;  
  53.     }  
  54.   
  55.     public void setPayMoney(String payMoney) {  
  56.         this.payMoney = payMoney;  
  57.     }  
  58.   
  59.     public String getPayGoods() {  
  60.         return payGoods;  
  61.     }  
  62.   
  63.     public void setPayGoods(String payGoods) {  
  64.         this.payGoods = payGoods;  
  65.     }  
  66.   
  67.     public Integer getPayStatus() {  
  68.         return payStatus;  
  69.     }  
  70.   
  71.     public void setPayStatus(Integer payStatus) {  
  72.         this.payStatus = payStatus;  
  73.     }  
  74.   
  75.     public String getPayTime() {  
  76.         return payTime;  
  77.     }  
  78.   
  79.     public void setPayTime(String payTime) {  
  80.         this.payTime = payTime;  
  81.     }  
  82.   
  83.     public Integer getPayWay() {  
  84.         return payWay;  
  85.     }  
  86.   
  87.     public void setPayWay(Integer payWay) {  
  88.         this.payWay = payWay;  
  89.     }  
  90.   
  91.     public String getSubject() {  
  92.         return subject;  
  93.     }  
  94.   
  95.     public void setSubject(String subject) {  
  96.         this.subject = subject;  
  97.     }  
  98. }  
package com.ywl5320.appservice.bean;

/**
 * Created by ywl5320 on 2017/10/19.
 */
public class OrderBean extends BaseBean{

    private Integer id;
    private Integer userId;
    private String phone;
    private String orderNo;//订单号
    private String payMoney; //支付金额
    private String payGoods; //支付的商品名称
    private Integer payStatus;//支付状态 0:未支付 1:支付成功
    private String payTime;//支付时间
    private Integer payWay;//支付方式 1:支付宝  2:微信
    private String subject;

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public String getPayMoney() {
        return payMoney;
    }

    public void setPayMoney(String payMoney) {
        this.payMoney = payMoney;
    }

    public String getPayGoods() {
        return payGoods;
    }

    public void setPayGoods(String payGoods) {
        this.payGoods = payGoods;
    }

    public Integer getPayStatus() {
        return payStatus;
    }

    public void setPayStatus(Integer payStatus) {
        this.payStatus = payStatus;
    }

    public String getPayTime() {
        return payTime;
    }

    public void setPayTime(String payTime) {
        this.payTime = payTime;
    }

    public Integer getPayWay() {
        return payWay;
    }

    public void setPayWay(Integer payWay) {
        this.payWay = payWay;
    }

    public String getSubject() {
        return subject;
    }

    public void setSubject(String subject) {
        this.subject = subject;
    }
}
1.2在entitis.hbm.xml中配置表结构

  1. <class name="com.ywl5320.appservice.bean.OrderBean"  table="t_order">  
  2.         <id name="id"  column="id">  
  3.             <generator class= "native"/>  
  4.         </id>  
  5.         <property name="userId"  column="userId"></property>  
  6.         <property name="phone"  column="phone"></property>  
  7.         <property name="orderNo"  column="orderNo"></property>  
  8.         <property name="payMoney"  column="payMoney"></property>  
  9.         <property name="payGoods"  column="payGoods"></property>  
  10.         <property name="payStatus"  column="payStatus"></property>  
  11.         <property name="payTime"  column="payTime"></property>  
  12.         <property name="payWay"  column="payWay"></property>  
  13.     </class>  
<class name="com.ywl5320.appservice.bean.OrderBean" table="t_order">
        <id name="id" column="id">
            <generator class="native"/>
        </id>
        <property name="userId" column="userId"></property>
        <property name="phone" column="phone"></property>
        <property name="orderNo" column="orderNo"></property>
        <property name="payMoney" column="payMoney"></property>
        <property name="payGoods" column="payGoods"></property>
        <property name="payStatus" column="payStatus"></property>
        <property name="payTime" column="payTime"></property>
        <property name="payWay" column="payWay"></property>
    </class>
二、编写Dao层支付代码

2.1 OrderDao.java,包含四个方法,可看注解

  1. package com.ywl5320.appservice.dao;  
  2.   
  3. import com.ywl5320.appservice.bean.OrderBean;  
  4.   
  5. /** 
  6.  * Created by ywl5320 on 2017/10/19. 
  7.  */  
  8. public interface OrderDao {  
  9.   
  10.     /** 
  11.      * 生成订单 
  12.      * @param orderBean 
  13.      */  
  14.     void createOrder(OrderBean orderBean);  
  15.   
  16.     /** 
  17.      * 根据订单ID获取订单 
  18.      * @param orderNo 
  19.      * @return 
  20.      */  
  21.     OrderBean getOrderById(int userId, String orderNo);  
  22.   
  23.     /** 
  24.      * 更新订单 
  25.      * @param orderBean 
  26.      */  
  27.     void updateOrder(OrderBean orderBean);  
  28.   
  29.   
  30.     /** 
  31.      * 获取订单信息 
  32.      * @param orderNo 
  33.      * @return 
  34.      */  
  35.     OrderBean getOrderByOrNo(String orderNo);  
  36.   
  37. }  
package com.ywl5320.appservice.dao;

import com.ywl5320.appservice.bean.OrderBean;

/**
 * Created by ywl5320 on 2017/10/19.
 */
public interface OrderDao {

    /**
     * 生成订单
     * @param orderBean
     */
    void createOrder(OrderBean orderBean);

    /**
     * 根据订单ID获取订单
     * @param orderNo
     * @return
     */
    OrderBean getOrderById(int userId, String orderNo);

    /**
     * 更新订单
     * @param orderBean
     */
    void updateOrder(OrderBean orderBean);


    /**
     * 获取订单信息
     * @param orderNo
     * @return
     */
    OrderBean getOrderByOrNo(String orderNo);

}
2.2 OrderDaoImpl.java

  1. package com.ywl5320.appservice.dao;  
  2.   
  3. import com.ywl5320.appservice.bean.OrderBean;  
  4. import org.springframework.orm.hibernate5.support.HibernateDaoSupport;  
  5.   
  6. import java.util.List;  
  7.   
  8. /** 
  9.  * Created by ywl5320 on 2017/10/19. 
  10.  */  
  11. public class OrderDaoImpl extends HibernateDaoSupport implements OrderDao{  
  12.   
  13.     public void createOrder(OrderBean orderBean) {  
  14.         // TODO Auto-generated method stub  
  15.         this.getHibernateTemplate().save(orderBean);  
  16.     }  
  17.   
  18.     public OrderBean getOrderById(int userId, String orderNo) {  
  19.         // TODO Auto-generated method stub  
  20.         List<OrderBean> orders = (List<OrderBean>) this.getHibernateTemplate().find("from OrderBean where userId=? and orderNo=?", userId, orderNo);  
  21.         if(orders != null && orders.size() >  0)  
  22.         {  
  23.             return orders.get(0);  
  24.         }  
  25.         return null;  
  26.     }  
  27.   
  28.     public void updateOrder(OrderBean orderBean) {  
  29.         // TODO Auto-generated method stub  
  30.         this.getHibernateTemplate().update(orderBean);  
  31.   
  32.     }  
  33.   
  34.     public OrderBean getOrderByOrNo(String orderNo) {  
  35.         // TODO Auto-generated method stub  
  36.         List<OrderBean> orders = (List<OrderBean>) this.getHibernateTemplate().find("from OrderEntity where orderNo=?", orderNo);  
  37.         if(orders != null && orders.size() >  0)  
  38.         {  
  39.             return orders.get(0);  
  40.         }  
  41.         return null;  
  42.     }  
  43.   
  44. }  
package com.ywl5320.appservice.dao;

import com.ywl5320.appservice.bean.OrderBean;
import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import java.util.List;

/**
 * Created by ywl5320 on 2017/10/19.
 */
public class OrderDaoImpl extends HibernateDaoSupport implements OrderDao{

    public void createOrder(OrderBean orderBean) {
        // TODO Auto-generated method stub
        this.getHibernateTemplate().save(orderBean);
    }

    public OrderBean getOrderById(int userId, String orderNo) {
        // TODO Auto-generated method stub
        List<OrderBean> orders = (List<OrderBean>) this.getHibernateTemplate().find("from OrderBean where userId=? and orderNo=?", userId, orderNo);
        if(orders != null && orders.size() > 0)
        {
            return orders.get(0);
        }
        return null;
    }

    public void updateOrder(OrderBean orderBean) {
        // TODO Auto-generated method stub
        this.getHibernateTemplate().update(orderBean);

    }

    public OrderBean getOrderByOrNo(String orderNo) {
        // TODO Auto-generated method stub
        List<OrderBean> orders = (List<OrderBean>) this.getHibernateTemplate().find("from OrderEntity where orderNo=?", orderNo);
        if(orders != null && orders.size() > 0)
        {
            return orders.get(0);
        }
        return null;
    }

}

2.3 在beans.xml中配置OrderDaoImpl

  1. <bean id="orderDaoImpl" class= "com.ywl5320.appservice.dao.OrderDaoImpl">  
  2.         <property name="sessionFactory"  ref="sessionFactory"></property>  
  3.     </bean>  
<bean id="orderDaoImpl" class="com.ywl5320.appservice.dao.OrderDaoImpl">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

三、编写支付Service层

3.1下载新版支付宝服务端APP支付SDK(https://docs.open.alipay.com/54/106370),然后添加到web/WEB-INF/lib中并添加到项目中。


3.2创建PayService.java

  1. package com.ywl5320.appservice.service;  
  2.   
  3. import com.alipay.api.AlipayApiException;  
  4. import com.alipay.api.AlipayClient;  
  5. import com.alipay.api.DefaultAlipayClient;  
  6. import com.alipay.api.domain.AlipayTradeAppPayModel;  
  7. import com.alipay.api.request.AlipayTradeAppPayRequest;  
  8. import com.alipay.api.response.AlipayTradeAppPayResponse;  
  9. import com.ywl5320.appservice.bean.*;  
  10. import com.ywl5320.appservice.dao.OrderDao;  
  11. import com.ywl5320.appservice.dao.UserDao;  
  12. import com.ywl5320.appservice.util.CommonUtils;  
  13. import com.ywl5320.appservice.util.MD5;  
  14. import com.ywl5320.appservice.util.RestFulUtil;  
  15. import org.springframework.beans.factory.annotation.Autowired;  
  16. import org.springframework.transaction.annotation.Transactional;  
  17.   
  18. import java.util.*;  
  19.   
  20. /** 
  21.  * Created by ywl5320 on 2017/10/19. 
  22.  */  
  23. @Transactional  
  24. public class PayService {  
  25.   
  26.     public static final String ALI_APPID =  "";  
  27.   
  28.     public static final String ALI_RSA2_PRIVATE_KEY =  "";  
  29.   
  30.     public static final String ALI_PUBLIC_KEY =  "";  
  31.   
  32.     String lockSuo = "createOrder";  
  33.       
  34.     @Autowired  
  35.     private OrderDao orderDao;  
  36.   
  37.     public RestFulBean<BaseBean> createOrder(int userId, String payGoods, String payMoney,  int payWay, String subject)  
  38.     {  
  39.   
  40.         String payTime = String.valueOf(System.currentTimeMillis());  
  41.         String orderNo = "";  
  42.         OrderBean order = null;  
  43.         AliPayBean aliPayBean = null;  
  44.         WxPayBean wxPayBean = null;  
  45.         synchronized (lockSuo) {  
  46.             try {  
  47.   
  48.                 orderNo = MD5.encryptMD5(userId + payTime + payMoney + subject + "md5_create_order"); //生成订单ID  
  49.                 OrderBean orderBean = new OrderBean();  
  50.                 orderBean.setSubject(subject);  
  51.                 orderBean.setOrderNo(orderNo);  
  52.                 orderBean.setUserId(userId);  
  53.                 orderBean.setPayGoods(payGoods);  
  54.                 orderBean.setPayMoney(payMoney);  
  55.                 orderBean.setPayStatus(0);//0:未支付 1:已支付  
  56.                 orderBean.setPayTime(CommonUtils.getNowTime());  
  57.                 orderBean.setPayWay(payWay);//1:支付宝支付 2:微信支付  
  58.   
  59.                 orderDao.createOrder(orderBean);  
  60.   
  61.                 order = orderDao.getOrderById(userId, orderNo);  
  62.   
  63.                 if(order != null)  
  64.                 {  
  65.                     if(payWay == 1) //支付宝  
  66.                     {  
  67.                         //实例化客户端  
  68.                         AlipayClient alipayClient = new DefaultAlipayClient( "https://openapi.alipay.com/gateway.do", ALI_APPID, ALI_RSA2_PRIVATE_KEY, "json""utf-8", ALI_PUBLIC_KEY,  "RSA2");  
  69.                         //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay  
  70.                         AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();  
  71.                         //SDK已经封装掉了公共参数,这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。  
  72.                         AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();  
  73.                         model.setBody("我是测试数据");  
  74.                         model.setSubject(orderBean.getSubject());  
  75.                         model.setOutTradeNo(orderBean.getOrderNo());  
  76.                         model.setTimeoutExpress("30m");  
  77.                         model.setTotalAmount(orderBean.getPayMoney());  
  78.                         model.setProductCode("QUICK_MSECURITY_PAY");  
  79.                         request.setBizModel(model);  
  80.                         request.setNotifyUrl("http://10.50.50.205:8080/pay/verifyalipayresult.do");//注意:实际情况填写自己的服务器接口地址,外网才能访问。  
  81.                         try {  
  82.                             //这里和普通的接口调用不同,使用的是sdkExecute  
  83.                             AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);  
  84.                             aliPayBean = new AliPayBean();  
  85.                             aliPayBean.setOrderId(response.getOutTradeNo());  
  86.                             aliPayBean.setOrderInfo(response.getBody());  
  87. //                            System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。  
  88.                         } catch (AlipayApiException e) {  
  89.                             e.printStackTrace();  
  90.                         }  
  91.   
  92.                     }  
  93.                     else if(payWay ==  2)//微信支付  
  94.                     {  
  95.                     }  
  96.                 }  
  97.   
  98.             } catch (Exception e) {  
  99.                 // TODO Auto-generated catch block  
  100.                 e.printStackTrace();  
  101.             }  
  102.         }  
  103.   
  104.         if(payWay == 1)  
  105.         {  
  106.             if(aliPayBean != null)  
  107.             {  
  108.                 return RestFulUtil.getInstance().getResuFulBean(aliPayBean,  0"支付宝订单生成成功");  
  109.             }  
  110.             else  
  111.             {  
  112.                 return RestFulUtil.getInstance().getResuFulBean( null1"支付宝订单生成失败");  
  113.             }  
  114.         }  
  115.         else if(payWay == 2)  
  116.         {  
  117.             return RestFulUtil.getInstance().getResuFulBean(null 1"微信支付研发中");  
  118.         }  
  119.         else  
  120.         {  
  121.             return RestFulUtil.getInstance().getResuFulBean(null 1"支付方式不对");  
  122.         }  
  123.     }  
  124.   
  125.     /** 
  126.      * 支付宝验证,更新订单信息 
  127.      * @param params 
  128.      * @return 
  129.      */  
  130.     public String verifyAliPay(Map<String, String> params)  
  131.     {  
  132.         OrderBean orderBean = orderDao.getOrderByOrNo(params.get("out_trade_no"));  
  133.         if(orderBean != null)  
  134.         {  
  135.             orderBean.setPayStatus(1);//已经支付  
  136.             orderDao.updateOrder(orderBean);  
  137.             return "success";  
  138.         }  
  139.         return "fail";  
  140.     }  
  141.   
  142. }  
package com.ywl5320.appservice.service;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.ywl5320.appservice.bean.*;
import com.ywl5320.appservice.dao.OrderDao;
import com.ywl5320.appservice.dao.UserDao;
import com.ywl5320.appservice.util.CommonUtils;
import com.ywl5320.appservice.util.MD5;
import com.ywl5320.appservice.util.RestFulUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * Created by ywl5320 on 2017/10/19.
 */
@Transactional
public class PayService {

    public static final String ALI_APPID = "";

    public static final String ALI_RSA2_PRIVATE_KEY = "";

    public static final String ALI_PUBLIC_KEY = "";

    String lockSuo = "createOrder";
    
    @Autowired
    private OrderDao orderDao;

    public RestFulBean<BaseBean> createOrder(int userId, String payGoods, String payMoney, int payWay, String subject)
    {

        String payTime = String.valueOf(System.currentTimeMillis());
        String orderNo = "";
        OrderBean order = null;
        AliPayBean aliPayBean = null;
        WxPayBean wxPayBean = null;
        synchronized (lockSuo) {
            try {

                orderNo = MD5.encryptMD5(userId + payTime + payMoney + subject + "md5_create_order");//生成订单ID
                OrderBean orderBean = new OrderBean();
                orderBean.setSubject(subject);
                orderBean.setOrderNo(orderNo);
                orderBean.setUserId(userId);
                orderBean.setPayGoods(payGoods);
                orderBean.setPayMoney(payMoney);
                orderBean.setPayStatus(0);//0:未支付 1:已支付
                orderBean.setPayTime(CommonUtils.getNowTime());
                orderBean.setPayWay(payWay);//1:支付宝支付 2:微信支付

                orderDao.createOrder(orderBean);

                order = orderDao.getOrderById(userId, orderNo);

                if(order != null)
                {
                    if(payWay == 1)//支付宝
                    {
                        //实例化客户端
                        AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do", ALI_APPID, ALI_RSA2_PRIVATE_KEY, "json", "utf-8", ALI_PUBLIC_KEY, "RSA2");
                        //实例化具体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(orderBean.getSubject());
                        model.setOutTradeNo(orderBean.getOrderNo());
                        model.setTimeoutExpress("30m");
                        model.setTotalAmount(orderBean.getPayMoney());
                        model.setProductCode("QUICK_MSECURITY_PAY");
                        request.setBizModel(model);
                        request.setNotifyUrl("http://10.50.50.205:8080/pay/verifyalipayresult.do");//注意:实际情况填写自己的服务器接口地址,外网才能访问。
                        try {
                            //这里和普通的接口调用不同,使用的是sdkExecute
                            AlipayTradeAppPayResponse response = alipayClient.sdkExecute(request);
                            aliPayBean = new AliPayBean();
                            aliPayBean.setOrderId(response.getOutTradeNo());
                            aliPayBean.setOrderInfo(response.getBody());
//                            System.out.println(response.getBody());//就是orderString 可以直接给客户端请求,无需再做处理。
                        } catch (AlipayApiException e) {
                            e.printStackTrace();
                        }

                    }
                    else if(payWay == 2)//微信支付
                    {
                    }
                }

            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        if(payWay == 1)
        {
            if(aliPayBean != null)
            {
                return RestFulUtil.getInstance().getResuFulBean(aliPayBean, 0, "支付宝订单生成成功");
            }
            else
            {
                return RestFulUtil.getInstance().getResuFulBean(null, 1, "支付宝订单生成失败");
            }
        }
        else if(payWay == 2)
        {
            return RestFulUtil.getInstance().getResuFulBean(null, 1, "微信支付研发中");
        }
        else
        {
            return RestFulUtil.getInstance().getResuFulBean(null, 1, "支付方式不对");
        }
    }

    /**
     * 支付宝验证,更新订单信息
     * @param params
     * @return
     */
    public String verifyAliPay(Map<String, String> params)
    {
        OrderBean orderBean = orderDao.getOrderByOrNo(params.get("out_trade_no"));
        if(orderBean != null)
        {
            orderBean.setPayStatus(1);//已经支付
            orderDao.updateOrder(orderBean);
            return "success";
        }
        return "fail";
    }

}
这里需要填写自己申请的支付宝相关的APPID和key信息。生成支付订单参照支付宝文档:https://docs.open.alipay.com/54/106370
3.3在beans.xml中配置payService

  1. <bean id="payService" class= "com.ywl5320.appservice.service.PayService"/>  
<bean id="payService" class="com.ywl5320.appservice.service.PayService"/>


四、编写PayAction

  1. package com.ywl5320.appservice.action;  
  2.   
  3. import com.alipay.api.AlipayApiException;  
  4. import com.alipay.api.internal.util.AlipaySignature;  
  5. import com.ywl5320.appservice.bean.BaseBean;  
  6. import com.ywl5320.appservice.bean.OrderBean;  
  7. import com.ywl5320.appservice.bean.RestFulBean;  
  8. import com.ywl5320.appservice.bean.UserBean;  
  9. import com.ywl5320.appservice.service.PayService;  
  10. import org.springframework.beans.factory.annotation.Autowired;  
  11. import org.springframework.stereotype.Controller;  
  12. import org.springframework.web.bind.annotation.RequestBody;  
  13. import org.springframework.web.bind.annotation.RequestMapping;  
  14. import org.springframework.web.bind.annotation.RequestMethod;  
  15. import org.springframework.web.bind.annotation.ResponseBody;  
  16.   
  17. import javax.servlet.http.HttpServletRequest;  
  18. import javax.servlet.http.HttpServletResponse;  
  19. import java.util.HashMap;  
  20. import java.util.Iterator;  
  21. import java.util.Map;  
  22.   
  23. /** 
  24.  * Created by ywl5320 on 2017/10/19. 
  25.  */  
  26. @Controller  
  27. @RequestMapping("/pay")  
  28. public class PayAction {  
  29.   
  30.     @Autowired  
  31.     private PayService payService;  
  32.   
  33.     String alilock = "alilock";  
  34.   
  35.     /** 
  36.      * 生成订单 
  37.      * @param userId 
  38.      * @param payGoods 
  39.      * @param payMoney 
  40.      * @param payWay 
  41.      * @param subject 
  42.      * @return 
  43.      */  
  44.     @ResponseBody  
  45.     @RequestMapping(value="/createOrder.do", method= RequestMethod.PUT)  
  46.     public RestFulBean<BaseBean> register(int userId, String payGoods, String payMoney,  int payWay, String subject)  
  47.     {  
  48.         return payService.createOrder(userId, payGoods, payMoney, payWay, subject);  
  49.     }  
  50.   
  51.     /** 
  52.      * 支付宝回调接口 
  53.      * @param request 
  54.      * @param resp 
  55.      * @return 
  56.      */  
  57.     @ResponseBody  
  58.     @RequestMapping(value="/verifyalipayresult.do", method=RequestMethod.POST)  
  59.     public String verifyAliPayRight(HttpServletRequest request, HttpServletResponse resp)  
  60.     {  
  61.         synchronized (alilock) {  
  62.             Map<String,String> params = new HashMap<String,String>();  
  63.             Map requestParams = request.getParameterMap();  
  64.             for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {  
  65.                 String name = (String) iter.next();  
  66.                 String[] values = (String[]) requestParams.get(name);  
  67.                 String valueStr = "";  
  68.                 for (int i =  0; i < values.length; i++) {  
  69.                     valueStr = (i == values.length - 1) ? valueStr + values[i]  
  70.                             : valueStr + values[i] + ",";  
  71.                 }  
  72.                 params.put(name, valueStr);  
  73.             }  
  74.             try {  
  75.                 boolean flag = AlipaySignature.rsaCheckV1(params, PayService.ALI_PUBLIC_KEY,  "utf-8""RSA2");  
  76.                 if(flag)  
  77.                 {  
  78.                     if(params.get("trade_status").equals( "TRADE_SUCCESS") && params.get("app_id").equals(PayService.ALI_APPID) && params.get("seller_id").equals( "*****************"))  
  79.                     {  
  80.                         return payService.verifyAliPay(params);  
  81.                     }  
  82.                 }  
  83.             } catch (AlipayApiException e) {  
  84.                 // TODO Auto-generated catch block  
  85.                 e.printStackTrace();  
  86.                 return "fail";  
  87.             }  
  88.         }  
  89.         return "fail";  
  90.     }  
  91.   
  92. }  
package com.ywl5320.appservice.action;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.ywl5320.appservice.bean.BaseBean;
import com.ywl5320.appservice.bean.OrderBean;
import com.ywl5320.appservice.bean.RestFulBean;
import com.ywl5320.appservice.bean.UserBean;
import com.ywl5320.appservice.service.PayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * Created by ywl5320 on 2017/10/19.
 */
@Controller
@RequestMapping("/pay")
public class PayAction {

    @Autowired
    private PayService payService;

    String alilock = "alilock";

    /**
     * 生成订单
     * @param userId
     * @param payGoods
     * @param payMoney
     * @param payWay
     * @param subject
     * @return
     */
    @ResponseBody
    @RequestMapping(value="/createOrder.do", method= RequestMethod.PUT)
    public RestFulBean<BaseBean> register(int userId, String payGoods, String payMoney, int payWay, String subject)
    {
        return payService.createOrder(userId, payGoods, payMoney, payWay, subject);
    }

    /**
     * 支付宝回调接口
     * @param request
     * @param resp
     * @return
     */
    @ResponseBody
    @RequestMapping(value="/verifyalipayresult.do", method=RequestMethod.POST)
    public String verifyAliPayRight(HttpServletRequest request, HttpServletResponse resp)
    {
        synchronized (alilock) {
            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] + ",";
                }
                params.put(name, valueStr);
            }
            try {
                boolean flag = AlipaySignature.rsaCheckV1(params, PayService.ALI_PUBLIC_KEY, "utf-8", "RSA2");
                if(flag)
                {
                    if(params.get("trade_status").equals("TRADE_SUCCESS") && params.get("app_id").equals(PayService.ALI_APPID) && params.get("seller_id").equals("*****************"))
                    {
                        return payService.verifyAliPay(params);
                    }
                }
            } catch (AlipayApiException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                return "fail";
            }
        }
        return "fail";
    }

}
这里创建订单采用PUT方式,支付宝服务端异步回调参照支付宝文档:https://docs.open.alipay.com/54/106370

        以上就完成了支付宝服务端的全部操作,注意:这里支付验证里面仅仅做了支付订单状态的更改,实际情况根据自身需求来处理,比如购买VIP服务,就需要给用户一个VIP状态和过期时间等信息。


最后给出一段客户端调用支付宝的代码,具体可见文末尾源码。

获取支付订单并调用支付宝支付:

  1. btnAliPay.setOnClickListener(new View.OnClickListener() {  
  2.             @Override  
  3.             public void onClick(View v) {  
  4.                 if(MyApplication.getInstance().getUserBean() == null)  
  5.                 {  
  6.                     Toast.makeText(MainActivity.this"请先登录", Toast.LENGTH_LONG).show();  
  7.                     return;  
  8.                 }  
  9.                 showLoadDialog("创建订单");  
  10.                 PayApi.getInstance().createOrder(MyApplication.getInstance().getUserBean().getId(), "支付宝支付测试" "0.01"1"新本版支付宝SDK支付"new HttpSubscriber<AliPayBean>( new SubscriberOnListener<AliPayBean>() {  
  11.                     @Override  
  12.                     public void onSucceed( final AliPayBean data) {  
  13.                         hideLoadDialog();  
  14.                         System.out.println("支付宝支付信息:" + data.getOrderInfo());  
  15.                         Runnable payRunnable = new Runnable() {  
  16.   
  17.                             @Override  
  18.                             public  void run() {  
  19.                                 PayTask alipay = new PayTask(MainActivity. this);  
  20.                                 Map<String, String> result = alipay.payV2(data.getOrderInfo(),true);  
  21.   
  22.                                 Message msg = new Message();  
  23.                                 msg.obj = result;  
  24.                                 mHandler.sendMessage(msg);  
  25.                             }  
  26.                         };  
  27.                         // 必须异步调用  
  28.                         Thread payThread = new Thread(payRunnable);  
  29.                         payThread.start();  
  30.                     }  
  31.   
  32.                     @Override  
  33.                     public void onError( int code, String msg) {  
  34.                         hideLoadDialog();  
  35.                         Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();  
  36.                     }  
  37.                 }, MainActivity.this));  
  38.             }  
  39.         });  
btnAliPay.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(MyApplication.getInstance().getUserBean() == null)
                {
                    Toast.makeText(MainActivity.this, "请先登录", Toast.LENGTH_LONG).show();
                    return;
                }
                showLoadDialog("创建订单");
                PayApi.getInstance().createOrder(MyApplication.getInstance().getUserBean().getId(), "支付宝支付测试", "0.01", 1, "新本版支付宝SDK支付", new HttpSubscriber<AliPayBean>(new SubscriberOnListener<AliPayBean>() {
                    @Override
                    public void onSucceed(final AliPayBean data) {
                        hideLoadDialog();
                        System.out.println("支付宝支付信息:" + data.getOrderInfo());
                        Runnable payRunnable = new Runnable() {

                            @Override
                            public void run() {
                                PayTask alipay = new PayTask(MainActivity.this);
                                Map<String, String> result = alipay.payV2(data.getOrderInfo(),true);

                                Message msg = new Message();
                                msg.obj = result;
                                mHandler.sendMessage(msg);
                            }
                        };
                        // 必须异步调用
                        Thread payThread = new Thread(payRunnable);
                        payThread.start();
                    }

                    @Override
                    public void onError(int code, String msg) {
                        hideLoadDialog();
                        Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
                    }
                }, MainActivity.this));
            }
        });
支付结果处理:
  1. private Handler mHandler = new Handler(){  
  2.   
  3.         @Override  
  4.         public void handleMessage(Message msg) {  
  5.             super.handleMessage(msg);  
  6.             PayResult payResult = new PayResult((Map<String, String>) msg.obj);  
  7.             String resultStatus = payResult.getResultStatus();  
  8.             // 判断resultStatus 为9000则代表支付成功  
  9.             if (TextUtils.equals(resultStatus, "9000")) {  
  10.                 // 该笔订单是否真实支付成功,需要依赖服务端的异步通知。  
  11.                 Toast.makeText(MainActivity.this"支付成功", Toast.LENGTH_SHORT).show();  
  12.             } else {  
  13.                 // 该笔订单真实的支付结果,需要依赖服务端的异步通知。  
  14.                 Toast.makeText(MainActivity.this"支付失败", Toast.LENGTH_SHORT).show();  
  15.             }  
  16.         }  
  17.     };  
private Handler mHandler = new Handler(){

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            PayResult payResult = new PayResult((Map<String, String>) msg.obj);
            String resultStatus = payResult.getResultStatus();
            // 判断resultStatus 为9000则代表支付成功
            if (TextUtils.equals(resultStatus, "9000")) {
                // 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
                Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
            } else {
                // 该笔订单真实的支付结果,需要依赖服务端的异步通知。
                Toast.makeText(MainActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
            }
        }
    };

到这里,就完成了支付宝的支付了。附:支付宝的支付还可以全程在客户端下单支付,但是为了安全,不暴露支付宝信息,还是在服务端下单最为保险。

源码下载:GitHub AppServiceRestFul 下一篇文章将会添加微信支付