在线支付功能实现代码

我们都知道,在现在的网站中,基本上都会有支付功能,在线支付作为一个潮流已是现代化网站的必备功能模块,那么几天我就分享一下如果来做这个在线支付功能。

在线支付一般来说有两种实现方式,一种是调用各个银行提供的接口,另一种是使用第三方集成好的支付功能。两种方式各有优劣,这个相信行内人士都是非常了解的了。对于第三方支付来说会需要提交企业5证来验证,还会有部分手续费,但是实现起来就非常方便了。对于直接使用银联接口的话就是使用起来必来麻烦,要为各个银行写接口实现,但是相比起来就更加安全了。


本文主要讲的是使用第三方支付平台来整合到我们的项目中,实现实际的支付功能。本文使用的例程是一个真实的支付过程,请注意,不要再测试中支付过多金额,否则后果自负。以前文说到的一个网上书店系统来说明,这里接入的是易宝支付的测试指纹和接口。如实际企业开发者可以使用企业牌照申请接口,如是普通开发者用来测试在线支付功能的可以直接使用。


我们先来说应该如何生成订单。

一、数据库设计

我们需要来一个订单表,订单详情表,以及订单的自动化序列表

[sql]  view plain  copy
  1. --订单表  
  2. create table orders(  
  3.     ordernum varchar(100) primary key,  
  4.     price float(8,2),  
  5.     number int,  
  6.     status int,   --支付成功状态位会改变  
  7.     customerId VARCHAR(100),  
  8.     CONSTRAINT customerId_fk FOREIGN KEY (customerId) REFERENCES customers(id)    
  9. )  
  10. )  
  11.   
  12. --订单详情表  
  13. create table orderitems(  
  14.     id varchar(100) primary key,  
  15.     number int,  
  16.     price float(8,2),  
  17.     ordernum varchar(100),  
  18.     bookid varchar(100),  
  19.     CONSTRAINT ordernum_fk FOREIGN KEY (ordernum) REFERENCES orders(ordernum),  
  20.     CONSTRAINT bookid_fk FOREIGN KEY (bookid) REFERENCES books(id)      
  21. )  
  22.   
  23. --订单编号表  
  24. create table ordernum(  
  25.     prefix date,  
  26.     num int   
  27. )  

二、bean设计

生成其get,set方法,并且记得要序列化Serializable

[java]  view plain  copy
  1. private String ordernum;  
  2.     private float price;  
  3.     private int number;  
  4.     private int status;  


三、接口设计

设计订单的实体类

[java]  view plain  copy
  1. public interface OrderDao {  
  2.   
  3.     void save(Order order);  
  4.   
  5.     Order findByNum(String ordernum);  
  6.   
  7.     void update(Order order);  
  8.   
  9.     //订单号降序排序  
  10.     List<Order> findByCustomerId(String customerId);  
  11.   
  12.       
  13.     List<OrderItem> findOrderItem(String ordernum);  
  14.   
  15. }  

接口的实现

[java]  view plain  copy
  1. public class OrderDaoImpl implements OrderDao {  
  2.   
  3.     private QueryRunner qr=new QueryRunner(C3P0Util.getDataSource());  
  4.       
  5.     //保存订单  
  6.     @Override  
  7.     public void save(Order order) {  
  8.           
  9.         try {  
  10.             qr.update("insert into orders (ordernum,price,number,status,customerId) values (?,?,?,?,?)",   
  11.                     order.getOrdernum(),order.getPrice(),order.getNumber(),order.getStatus(),  
  12.                     order.getCustomer()==null?null:order.getCustomer().getId());  
  13.             List<OrderItem> items = order.getItems();  
  14.             for(OrderItem item:items){  
  15.                 qr.update("insert into orderitems (id,number,price,ordernum,bookid) values (?,?,?,?,?)",   
  16.                         item.getId(),item.getNumber(),item.getPrice(),order.getOrdernum(),item.getBook()==null?null:item.getBook().getId());  
  17.             }  
  18.         } catch (SQLException e) {  
  19.             throw new RuntimeException(e);  
  20.         }  
  21.     }  
  22.   
  23.   
  24.     public Order findByNum(String ordernum) {  
  25.         try {  
  26.             Order order = qr.query("select * from orders where ordernum=?"new BeanHandler<Order>(Order.class), ordernum);  
  27.             if(order!=null){  
  28.                 Customer customer = qr.query("select * from customers where id=(select customerId from orders where ordernum=?)"new BeanHandler<Customer>(Customer.class), ordernum);  
  29.                 order.setCustomer(customer);  
  30.             }  
  31.             return order;  
  32.         } catch (SQLException e) {  
  33.             throw new RuntimeException(e);  
  34.         }  
  35.     }  
  36.     public void update(Order order) {  
  37.         try {  
  38.             qr.update("update orders set price=?,number=?,status=? where ordernum=?", order.getPrice(),order.getNumber(),order.getStatus(),order.getOrdernum());  
  39.         } catch (SQLException e) {  
  40.             throw new RuntimeException(e);  
  41.         }  
  42.     }  
  43.   
  44.   
  45.     @Override  
  46.     public List<Order> findByCustomerId(String customerId) {  
  47.         try {  
  48.             List<Order> orders=qr.query("select * from orders where customerId=?  order by ordernum desc "new BeanListHandler<Order>(Order.class),customerId);  
  49.             if(orders!=null){  
  50.                 Customer customer=qr.query("select * from customers where id=? ",new BeanHandler<Customer>(Customer.class),customerId);  
  51.                 for (Order order : orders) {  
  52.                     order.setCustomer(customer);  
  53.                 }  
  54.             }  
  55.             return orders;  
  56.         } catch (SQLException e) {  
  57.             throw new RuntimeException(e);  
  58.         }  
  59.     }  
  60.   
  61.   
  62.     @Override  
  63.     public List<OrderItem> findOrderItem(String ordernum) {  
  64.           
  65.         try {  
  66.             List<OrderItem> items = qr.query("select * from orderitems where ordernum=?"new BeanListHandler<OrderItem>(OrderItem.class), ordernum);  
  67.             if(items!=null){  
  68.                 for(OrderItem o:items){  
  69.                     Book book = qr.query("select * from books where id=(select bookId from orderitems where id=?)"new BeanHandler<Book>(Book.class), o.getId());  
  70.                     o.setBook(book);  
  71.                 }  
  72.             }  
  73.             return items;  
  74.         } catch (SQLException e) {  
  75.             throw new RuntimeException(e);  
  76.         }  
  77.     }  
  78. }  

四、Service的设计


[java]  view plain  copy
  1. //生成订单  
  2.     void genOrder(Order order);  
  3.   
  4.     //根据订单号查找订单  
  5.     Order findOrderByNum(String ordernum);  
  6.   
  7.     //更新订单信息  
  8.     void updateOrder(Order order);  
  9.       
  10.     //更新订单状态  
  11.     void changeOrderStatus(int status,String ordernum);  
  12.   
  13.     //  
  14.     List<Order> findOrdersByCustomerId(String customerId);  
  15.       
  16.     List<OrderItem> findOrderItemByCustomerId(String ordernum);  


实现其接口

[java]  view plain  copy
  1. //生成订单  
  2.     @Override  
  3.     public void genOrder(Order order) {  
  4.         if(order==null)  
  5.                 throw new RuntimeException("订单不能为空");  
  6.         if(order.getCustomer()==null)  
  7.             throw new RuntimeException("订单的客户不能为空");  
  8.         orderDao.save(order);  
  9.           
  10.     }  
  11.   
  12.     @Override  
  13.     public Order findOrderByNum(String ordernum) {  
  14.           
  15.         return orderDao.findByNum(ordernum);  
  16.     }  
  17.   
  18.     @Override  
  19.     public void updateOrder(Order order) {  
  20.         orderDao.update(order);  
  21.           
  22.     }  
  23.   
  24.     @Override  
  25.     public void changeOrderStatus(int status, String ordernum) {  
  26.         Order order=findOrderByNum(ordernum);  
  27.         order.setStatus(status);  
  28.         updateOrder(order);  
  29.     }  
  30.   
  31.     @Override  
  32.     public List<Order> findOrdersByCustomerId(String customerId) {  
  33.           
  34.         return orderDao.findByCustomerId(customerId);  
  35.     }  
  36.   
  37.     @Override  
  38.     public List<OrderItem> findOrderItemByCustomerId(String ordernum) {  
  39.       
  40.         return orderDao.findOrderItem(ordernum);  
  41.     }  



生成订单


[java]  view plain  copy
  1. //订单详情  
  2.     private void showOrders(HttpServletRequest request,  
  3.             HttpServletResponse response) throws IOException, ServletException {  
  4.         //检测是否登录;   
  5.                 HttpSession session=request.getSession();  
  6.                 Customer customer=(Customer) session.getAttribute("customer");  
  7.                 if(customer==null){  
  8.                     response.getWriter().write("请先登录");  
  9.                     response.setHeader("Refresh""2;URL="+request.getContextPath());  
  10.                     return ;  
  11.                 }  
  12.             List<Order>  orders=s.findOrdersByCustomerId(customer.getId());  
  13.             request.setAttribute("orders", orders);  
  14.               
  15.             request.getRequestDispatcher("/listOrders.jsp").forward(request, response);  
  16.                   
  17.                   
  18.           
  19.     }  
  20.   
  21.   
  22.     //生成订单  
  23.     private void genOrder(HttpServletRequest request,  
  24.             HttpServletResponse response) throws IOException, ServletException  {  
  25.         //检测是否登录;   
  26.         HttpSession session=request.getSession();  
  27.         Customer customer=(Customer) session.getAttribute("customer");  
  28.         if(customer==null){  
  29.             response.getWriter().write("请先登录");  
  30.             response.setHeader("Refresh""2;URL="+request.getContextPath());  
  31.             return ;  
  32.         }  
  33.           
  34.         Cart cart=(Cart) request.getSession().getAttribute("cart");  
  35.           
  36.         Order order=new Order();  
  37.         order.setOrdernum(OrderNumUtil.genOrderNum());  
  38.         order.setPrice(cart.getPrice());  
  39.         order.setNumber(cart.getNumber());  
  40.         order.setCustomer(customer);  
  41.           
  42.           
  43.         List<OrderItem>  oItems=new ArrayList<OrderItem>();  
  44.         //设置订单项  
  45.         for(Map.Entry<String, CartItem>  me:cart.getItems().entrySet()){  
  46.             OrderItem item=new OrderItem();  
  47.             item.setId(UUID.randomUUID().toString());  
  48.             item.setNumber(me.getValue().getNumber());  
  49.             item.setPrice(me.getValue().getPrice());  
  50.             item.setBook(me.getValue().getBook());  
  51.             oItems.add(item);  
  52.         }  
  53.         //建立和订单的关系  
  54.         order.setItems(oItems);  
  55.         s.genOrder(order);  
  56.         request.setAttribute("order", order);  
  57.         request.getRequestDispatcher("/pay.jsp").forward(request, response);  
  58.           
  59.           
  60.     }  




接下来就是支付功能的实现了。我们要为上面生成的订单来支付

五、界面设计。

订单生成后腰跳转过去支付,这个支付界面我们可以使用一个表单。pay.jsp。并且将内容提交到PayServlet中。



[java]  view plain  copy
  1. <form action="${pageContext.request.contextPath}/servlet/PayServlet" method="post">  
  2.         <table width="60%">  
  3.             <tr>  
  4.                 <td bgcolor="#F7FEFF" colspan="4">  
  5.                 订单号:<INPUT TYPE="text" NAME="ordernum" value="${order.ordernum}${param.ordernum}"  readonly="readonly">   
  6.                 支付金额:<INPUT TYPE="text" NAME="money" size="6" value="${order.price }"  readonly="readonly">元</td>  
  7.             </tr>  
  8.             <tr>  
  9.                 <td><br />  
  10.                 </td>  
  11.             </tr>  
  12.             <tr>  
  13.                 <td>请您选择在线支付银行</td>  
  14.             </tr>  
  15.             <tr>  
  16.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBCHINA-NET">招商银行  
  17.                 </td>  
  18.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="ICBC-NET">工商银行</td>  
  19.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="ABC-NET">农业银行</td>  
  20.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CCB-NET">建设银行  
  21.                 </td>  
  22.             </tr>  
  23.             <tr>  
  24.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBC-NET">中国民生银行总行</td>  
  25.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CEB-NET">光大银行  
  26.                 </td>  
  27.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="BOCO-NET">交通银行</td>  
  28.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="SDB-NET">深圳发展银行</td>  
  29.             </tr>  
  30.             <tr>  
  31.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="BCCB-NET">北京银行</td>  
  32.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CIB-NET">兴业银行  
  33.                 </td>  
  34.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="SPDB-NET">上海浦东发展银行  
  35.                 </td>  
  36.                 <td><INPUT TYPE="radio" NAME="pd_FrpId" value="ECITIC-NET">中信银行</td>  
  37.             </tr>  
  38.             <tr>  
  39.                 <td><br />  
  40.                 </td>  
  41.             </tr>  
  42.             <tr>  
  43.                 <td><INPUT TYPE="submit" value="确定支付">  
  44.                 </td>  
  45.             </tr>  
  46.         </table>  
  47.     </form>  


六、servletc逻辑处理

对于使用易宝支付我们无需导入jar包,我们直接使用其接口即可。下面这张图片是易宝支付的接口说明。




PayServlet的内容。

这里值得说一下的就是  p8_Url ,也就是支付成功后悔返回的商家界面地址。我这里写的是自己工程的地址。

[java]  view plain  copy
  1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
  2.             throws ServletException, IOException {  
  3.   
  4.         request.setCharacterEncoding("UTF-8");  
  5.         String ordernum=request.getParameter("ordernum");  
  6.         String money=request.getParameter("money");  
  7.         String pd_FrpId=request.getParameter("pd_FrpId");  
  8.           
  9.           
  10.           
  11.         String p0_Cmd = "Buy";  
  12.         String p1_MerId = "10001126856";  
  13.         String p2_Order = ordernum;  
  14.         String p3_Amt = money;  
  15.         String p4_Cur = "CNY";  
  16.         String p5_Pid = "books";  //商品名称  
  17.         String p6_Pcat = "unknown";  
  18.         String p7_Pdesc = "descrition";  
  19.         String p8_Url = "http://localhost:8080"+request.getContextPath()+"/servlet/ResponsePayServlet";  
  20.         String p9_SAF = "1";  
  21.         String pa_MP = "unknown";  
  22.         String pr_NeedResponse="1";   
  23.         String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt, p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP, pd_FrpId, pr_NeedResponse, "69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl");  
  24.           
  25.         request.setAttribute("p0_Cmd",p0_Cmd );  
  26.         request.setAttribute("p1_MerId",p1_MerId );  
  27.         request.setAttribute("p2_Order", p2_Order);  
  28.         request.setAttribute("p3_Amt", p3_Amt);  
  29.         request.setAttribute("p4_Cur",p4_Cur );  
  30.         request.setAttribute("p5_Pid",p5_Pid );  
  31.         request.setAttribute("p6_Pcat",p6_Pcat );  
  32.         request.setAttribute("p7_Pdesc",p7_Pdesc );  
  33.         request.setAttribute("p8_Url",p8_Url );  
  34.         request.setAttribute("pa_MP",pa_MP );  
  35.         request.setAttribute("pr_NeedResponse",pr_NeedResponse );  
  36.         request.setAttribute("hmac",hmac );  
  37.         request.setAttribute("p9_SAF",p9_SAF );  
  38.         request.setAttribute("pd_FrpId", pd_FrpId);  
  39.           
  40.         request.getRequestDispatcher("/sure.jsp").forward(request, response);  
  41.       
  42.     }  

PayUtil.java是一个工具类,这里我们直接使用官方的即可。

[java]  view plain  copy
  1. public class PaymentUtil {  
  2.   
  3. private static String encodingCharset = "UTF-8";  
  4.       
  5.     /** 
  6.      * 生成hmac方法 
  7.      *  
  8.      * @param p0_Cmd 业务类型 
  9.      * @param p1_MerId 商户编号 
  10.      * @param p2_Order 商户订单号 
  11.      * @param p3_Amt 支付金额 
  12.      * @param p4_Cur 交易币种 
  13.      * @param p5_Pid 商品名称 
  14.      * @param p6_Pcat 商品种类 
  15.      * @param p7_Pdesc 商品描述 
  16.      * @param p8_Url 商户接收支付成功数据的地址 
  17.      * @param p9_SAF 送货地址 
  18.      * @param pa_MP 商户扩展信息 
  19.      * @param pd_FrpId 银行编码 
  20.      * @param pr_NeedResponse 应答机制 
  21.      * @param keyValue 商户密钥 
  22.      * @return 
  23.      */  
  24.     public static String buildHmac(String p0_Cmd,String p1_MerId,  
  25.             String p2_Order, String p3_Amt, String p4_Cur,String p5_Pid, String p6_Pcat,  
  26.             String p7_Pdesc,String p8_Url, String p9_SAF,String pa_MP,String pd_FrpId,  
  27.             String pr_NeedResponse,String keyValue) {  
  28.         StringBuilder sValue = new StringBuilder();  
  29.         // 业务类型  
  30.         sValue.append(p0_Cmd);  
  31.         // 商户编号  
  32.         sValue.append(p1_MerId);  
  33.         // 商户订单号  
  34.         sValue.append(p2_Order);  
  35.         // 支付金额  
  36.         sValue.append(p3_Amt);  
  37.         // 交易币种  
  38.         sValue.append(p4_Cur);  
  39.         // 商品名称  
  40.         sValue.append(p5_Pid);  
  41.         // 商品种类  
  42.         sValue.append(p6_Pcat);  
  43.         // 商品描述  
  44.         sValue.append(p7_Pdesc);  
  45.         // 商户接收支付成功数据的地址  
  46.         sValue.append(p8_Url);  
  47.         // 送货地址  
  48.         sValue.append(p9_SAF);  
  49.         // 商户扩展信息  
  50.         sValue.append(pa_MP);  
  51.         // 银行编码  
  52.         sValue.append(pd_FrpId);  
  53.         // 应答机制  
  54.         sValue.append(pr_NeedResponse);  
  55.           
  56.         return PaymentUtil.hmacSign(sValue.toString(), keyValue);  
  57.     }  
  58.       
  59.     /** 
  60.      * 返回校验hmac方法 
  61.      *  
  62.      * @param hmac 支付网关发来的加密验证码 
  63.      * @param p1_MerId 商户编号 
  64.      * @param r0_Cmd 业务类型 
  65.      * @param r1_Code 支付结果 
  66.      * @param r2_TrxId 易宝支付交易流水号 
  67.      * @param r3_Amt 支付金额 
  68.      * @param r4_Cur 交易币种 
  69.      * @param r5_Pid 商品名称 
  70.      * @param r6_Order 商户订单号 
  71.      * @param r7_Uid 易宝支付会员ID 
  72.      * @param r8_MP 商户扩展信息 
  73.      * @param r9_BType 交易结果返回类型 
  74.      * @param keyValue 密钥 
  75.      * @return 
  76.      */  
  77.     public static boolean verifyCallback(String hmac, String p1_MerId,  
  78.             String r0_Cmd, String r1_Code, String r2_TrxId, String r3_Amt,  
  79.             String r4_Cur, String r5_Pid, String r6_Order, String r7_Uid,  
  80.             String r8_MP, String r9_BType, String keyValue) {  
  81.         StringBuilder sValue = new StringBuilder();  
  82.         // 商户编号  
  83.         sValue.append(p1_MerId);  
  84.         // 业务类型  
  85.         sValue.append(r0_Cmd);  
  86.         // 支付结果  
  87.         sValue.append(r1_Code);  
  88.         // 易宝支付交易流水号  
  89.         sValue.append(r2_TrxId);  
  90.         // 支付金额  
  91.         sValue.append(r3_Amt);  
  92.         // 交易币种  
  93.         sValue.append(r4_Cur);  
  94.         // 商品名称  
  95.         sValue.append(r5_Pid);  
  96.         // 商户订单号  
  97.         sValue.append(r6_Order);  
  98.         // 易宝支付会员ID  
  99.         sValue.append(r7_Uid);  
  100.         // 商户扩展信息  
  101.         sValue.append(r8_MP);  
  102.         // 交易结果返回类型  
  103.         sValue.append(r9_BType);  
  104.         String sNewString = PaymentUtil.hmacSign(sValue.toString(), keyValue);  
  105.         return sNewString.equals(hmac);  
  106.     }  
  107.       
  108.     /** 
  109.      * @param aValue 
  110.      * @param aKey 
  111.      * @return 
  112.      */  
  113.     public static String hmacSign(String aValue, String aKey) {  
  114.         byte k_ipad[] = new byte[64];  
  115.         byte k_opad[] = new byte[64];  
  116.         byte keyb[];  
  117.         byte value[];  
  118.         try {  
  119.             keyb = aKey.getBytes(encodingCharset);  
  120.             value = aValue.getBytes(encodingCharset);  
  121.         } catch (UnsupportedEncodingException e) {  
  122.             keyb = aKey.getBytes();  
  123.             value = aValue.getBytes();  
  124.         }  
  125.   
  126.         Arrays.fill(k_ipad, keyb.length, 64, (byte54);  
  127.         Arrays.fill(k_opad, keyb.length, 64, (byte92);  
  128.         for (int i = 0; i < keyb.length; i++) {  
  129.             k_ipad[i] = (byte) (keyb[i] ^ 0x36);  
  130.             k_opad[i] = (byte) (keyb[i] ^ 0x5c);  
  131.         }  
  132.   
  133.         MessageDigest md = null;  
  134.         try {  
  135.             md = MessageDigest.getInstance("MD5");  
  136.         } catch (NoSuchAlgorithmException e) {  
  137.   
  138.             return null;  
  139.         }  
  140.         md.update(k_ipad);  
  141.         md.update(value);  
  142.         byte dg[] = md.digest();  
  143.         md.reset();  
  144.         md.update(k_opad);  
  145.         md.update(dg, 016);  
  146.         dg = md.digest();  
  147.         return toHex(dg);  
  148.     }  
  149.   
  150.     public static String toHex(byte input[]) {  
  151.         if (input == null)  
  152.             return null;  
  153.         StringBuffer output = new StringBuffer(input.length * 2);  
  154.         for (int i = 0; i < input.length; i++) {  
  155.             int current = input[i] & 0xff;  
  156.             if (current < 16)  
  157.                 output.append("0");  
  158.             output.append(Integer.toString(current, 16));  
  159.         }  
  160.   
  161.         return output.toString();  
  162.     }  
  163.   
  164.     /** 
  165.      *  
  166.      * @param args 
  167.      * @param key 
  168.      * @return 
  169.      */  
  170.     public static String getHmac(String[] args, String key) {  
  171.         if (args == null || args.length == 0) {  
  172.             return (null);  
  173.         }  
  174.         StringBuffer str = new StringBuffer();  
  175.         for (int i = 0; i < args.length; i++) {  
  176.             str.append(args[i]);  
  177.         }  
  178.         return (hmacSign(str.toString(), key));  
  179.     }  
  180.   
  181.     /** 
  182.      * @param aValue 
  183.      * @return 
  184.      */  
  185.     public static String digest(String aValue) {  
  186.         aValue = aValue.trim();  
  187.         byte value[];  
  188.         try {  
  189.             value = aValue.getBytes(encodingCharset);  
  190.         } catch (UnsupportedEncodingException e) {  
  191.             value = aValue.getBytes();  
  192.         }  
  193.         MessageDigest md = null;  
  194.         try {  
  195.             md = MessageDigest.getInstance("SHA");  
  196.         } catch (NoSuchAlgorithmException e) {  
  197.             e.printStackTrace();  
  198.             return null;  
  199.         }  
  200.         return toHex(md.digest(value));  
  201.   
  202.     }  
  203.   
  204.       
  205. }  


对于支付成功之后,我们需要修改我们的订单状态,改为已付款,所以我们需要一个响应的servlet

[java]  view plain  copy
  1. public class ResponsePayServlet extends HttpServlet {  
  2.   
  3.   
  4.     private BusinessService s=new BusinessServiceImpl();  
  5.       
  6.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
  7.             throws ServletException, IOException {  
  8.         response.setContentType("text/html;charset=UTF-8");  
  9.         PrintWriter out = response.getWriter();  
  10.         String p1_MerId = request.getParameter("p1_MerId");  
  11.         String r0_Cmd = request.getParameter("r0_Cmd");  
  12.         String r1_Code = request.getParameter("r1_Code");//支付结果。1代表成功  
  13.         String r2_TrxId = request.getParameter("r2_TrxId");  
  14.         String r3_Amt = request.getParameter("r3_Amt");  
  15.         String r4_Cur= request.getParameter("r4_Cur");  
  16.         String r5_Pid= request.getParameter("r5_Pid");  
  17.         String r6_Order = request.getParameter("r6_Order");//订单编号  
  18.         String r7_Uid = request.getParameter("r7_Uid");  
  19.         String r8_MP = request.getParameter("r8_MP");  
  20.         String r9_BType = request.getParameter("r9_BType");//1浏览器访问的。2点对点  
  21.         String hmac = request.getParameter("hmac");  
  22.           
  23.         //数据校验  
  24.         boolean ok = PaymentUtil.verifyCallback(hmac, p1_MerId, r0_Cmd, r1_Code, r2_TrxId, r3_Amt, r4_Cur, r5_Pid, r6_Order, r7_Uid, r8_MP, r9_BType, "69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl");  
  25.         if(!ok){  
  26.             out.write("数据有可能被篡改,请联系网站");  
  27.         }else{  
  28.             if("1".equals(r1_Code)){  
  29.                 //支付成功:根据订单号更改订单状态。  点卡或充值时注意表单的重复提交问题。  
  30.                 if("2".equals(r9_BType)){  
  31.                     out.write("success");  
  32.                 }  
  33.                   
  34.                 //更改订单的状态  
  35.                 /*Order order=s.findOrderByNum(r6_Order); 
  36.                 order.setStatus(1);  //1表示已付款,0表示未付款 
  37.                 s.updateOrder(order);*/  
  38.                 s.changeOrderStatus(1, r6_Order);  
  39.                 request.getSession().removeAttribute("cart");  
  40.                 response.setHeader("Refresh""2;URL="+request.getContextPath());  
  41.             }  
  42.         }  
  43.     }  
  44.   
  45.   
  46.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
  47.             throws ServletException, IOException {  
  48.           
  49.         doGet(request,response);  
  50.           
  51.       
  52.     }  
  53.   
  54. }  


在这个网上书店的支付中,我们可以看到这样的效果:这里以支付1分钱为例,来演示在线支付功能。

用户在浏览商品后加入购物车并生成订单了。



先是跳转我们自己写的这个选择银行的表单中。


支付的过程我们会先跳转到易宝支付的页面。



我这里选择建设银行来支付。所以点击确定后就会跳转到建设银行的界面。





支付成功之后就返回。




然后就会跳转回我们自己的项目中,这个时候来查看一个订单的状态,会发现已经支付成功了。



总结:在线支付功能是个非常实用的功能,我们都应该需要掌握其基本的开发流程,并亲自动手进行测试才会更加清楚了了解。这里的话呢,额界面比较丑,唉,将就着看吧!


源码下载地址:http://download.csdn.net/download/qq_38869854/10231438


猜你喜欢

转载自blog.csdn.net/qq_38869854/article/details/79204792