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

 

我的视频课程(基础):《(NDK)FFmpeg打造Android万能音频播放器》

我的视频课程(进阶):《(NDK)FFmpeg打造Android视频播放器》

我的视频课程(编码直播推流):《Android视频编码和直播推流》

 

目录:

 

        移动大脑-SpringMVc搭建RestFul后台服务(一)-环境搭建

        移动大脑-SpringMVc搭建RestFul后台服务(二)-配置mysql数据库

        移动大脑-SpringMVc搭建RestFul后台服务(三)-RestFul接口编写(模拟用户注册登录)

        移动大脑-SpringMVc搭建RestFul后台服务(四)-添加Token拦截器

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

        移动大脑-SpringMVc搭建RestFul后台服务(六)-微信支付(Android)        

        移动大脑-SpringMVc搭建RestFul后台服务(七)-增量更新

 

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

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

 

 

支付宝支付逻辑主要是:

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

开始搬砖

一、添加订单表“t_order”

1.1订单实体类OrderBean.java

 

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中配置表结构

 

 

<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,包含四个方法,可看注解

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

 

 

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

 

<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

 

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

 

 

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

 

 

四、编写PayAction

 

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状态和过期时间等信息。

 

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

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

 

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));
            }
        });

支付结果处理:

 

 

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 下一篇文章将会添加微信支付

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ywl5320

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值