【SSH项目】在线支付功能解析

来源:互联网 发布:最新免费x站地域名 编辑:程序博客网 时间:2024/05/22 05:32

SSH框架

     struts+spring+hibernate,

    首先盗百科图一张,来看一下SSH框架结构:

                    

在线支付

    小编最近在做一个网上商城的项目.今天正好做到了加入购物车之后的功能实现. 爱网购的都会了解在线支付的流程. 那下面就来看看这简单操作背后的故事. 

    网购流程图:     

                      

    顾客在确认订单时,购物网站就重定向到第三方支付平台(易宝),且将付款金额,订单号,哪个银行等数据经过加密算法和密钥加密后传过去,且加密后会得到一个hmac码;然后第三方支付平台也用相同算法将网站传过来的数据进行加密,得到hmac码,与之前得到的hmac码进行比较,如果码值相同就重定向到付款银行进行下一步支付操作. 若不同,说明数据被篡改.

重定向和转发

   1.看得到的区别:

       转发:浏览器的地址栏中只显示第一次发送请求的地址;

       重定向:浏览器地址栏中显示的是每次请求的新地址.

   2.看不见的本质区别:

       转发:在整个发送请求的过程中,只创建一次request和response对象,多次请求之间是共享这两个对象的,就是说任何请求都可以访问第一次请求中的信息;

       重定向:浏览器每发送一次请求就会创建新的request和response对象,多次请求之间是不可共享对象信息的,也就是说后面的请求不能访问前面请求中的信息.

   3.相同点:不管是重定向还是转发都可以发送多次请求.


重要代码:

OrderAction.java

// 为订单付款:public String payOrder() throws IOException {// 1.修改数据:Order currOrder = orderService.findByOid(order.getOid());currOrder.setAddr(order.getAddr());currOrder.setName(order.getName());currOrder.setPhone(order.getPhone());// 修改订单orderService.update(currOrder);// 2.完成付款:// 付款需要的参数:String p0_Cmd = "Buy"; // 业务类型:String p1_MerId = "10001126856";// 商户编号:String p2_Order = order.getOid().toString();// 订单编号:String p3_Amt = "0.01"; // 付款金额:String p4_Cur = "CNY"; // 交易币种:String p5_Pid = ""; // 商品名称:String p6_Pcat = ""; // 商品种类:String p7_Pdesc = ""; // 商品描述:String p8_Url = "http://localhost/shop/order_callBack.action"; // 商户接收支付成功数据的地址:String p9_SAF = ""; // 送货地址:String pa_MP = ""; // 商户扩展信息:String pd_FrpId = this.pd_FrpId;// 支付通道编码:String pr_NeedResponse = "1"; // 应答机制:String keyValue = "69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl"; // 秘钥     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, keyValue); // hmac// 向易宝发送请求:StringBuffer sb = new StringBuffer("https://www.yeepay.com/app-merchant-proxy/node?");sb.append("p0_Cmd=").append(p0_Cmd).append("&");sb.append("p1_MerId=").append(p1_MerId).append("&");sb.append("p2_Order=").append(p2_Order).append("&");sb.append("p3_Amt=").append(p3_Amt).append("&");sb.append("p4_Cur=").append(p4_Cur).append("&");sb.append("p5_Pid=").append(p5_Pid).append("&");sb.append("p6_Pcat=").append(p6_Pcat).append("&");sb.append("p7_Pdesc=").append(p7_Pdesc).append("&");sb.append("p8_Url=").append(p8_Url).append("&");sb.append("p9_SAF=").append(p9_SAF).append("&");sb.append("pa_MP=").append(pa_MP).append("&");sb.append("pd_FrpId=").append(pd_FrpId).append("&");sb.append("pr_NeedResponse=").append(pr_NeedResponse).append("&"); sb.append("hmac=").append(hmac);// 重定向:向易宝出发:ServletActionContext.getResponse().sendRedirect(sb.toString());return NONE;}

  PaymentUtil.java:    

package cn.itcast.shop.utils;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Arrays;public class PaymentUtil {private static String encodingCharset = "UTF-8";/** * 生成hmac方法 *  * @param p0_Cmd 业务类型 * @param p1_MerId 商户编号 * @param p2_Order 商户订单号 * @param p3_Amt 支付金额 * @param p4_Cur 交易币种 * @param p5_Pid 商品名称 * @param p6_Pcat 商品种类 * @param p7_Pdesc 商品描述 * @param p8_Url 商户接收支付成功数据的地址 * @param p9_SAF 送货地址 * @param pa_MP 商户扩展信息 * @param pd_FrpId 银行编码 * @param pr_NeedResponse 应答机制 * @param keyValue 商户密钥 * @return */public static String buildHmac(String p0_Cmd,String p1_MerId,String p2_Order, String p3_Amt, String p4_Cur,String p5_Pid, String p6_Pcat,String p7_Pdesc,String p8_Url, String p9_SAF,String pa_MP,String pd_FrpId,String pr_NeedResponse,String keyValue) {StringBuilder sValue = new StringBuilder();// 业务类型sValue.append(p0_Cmd);// 商户编号sValue.append(p1_MerId);// 商户订单号sValue.append(p2_Order);// 支付金额sValue.append(p3_Amt);// 交易币种sValue.append(p4_Cur);// 商品名称sValue.append(p5_Pid);// 商品种类sValue.append(p6_Pcat);// 商品描述sValue.append(p7_Pdesc);// 商户接收支付成功数据的地址sValue.append(p8_Url);// 送货地址sValue.append(p9_SAF);// 商户扩展信息sValue.append(pa_MP);// 银行编码sValue.append(pd_FrpId);// 应答机制sValue.append(pr_NeedResponse);return PaymentUtil.hmacSign(sValue.toString(), keyValue);}/** * 返回校验hmac方法 *  * @param hmac 支付网关发来的加密验证码 * @param p1_MerId 商户编号 * @param r0_Cmd 业务类型 * @param r1_Code 支付结果 * @param r2_TrxId 易宝支付交易流水号 * @param r3_Amt 支付金额 * @param r4_Cur 交易币种 * @param r5_Pid 商品名称 * @param r6_Order 商户订单号 * @param r7_Uid 易宝支付会员ID * @param r8_MP 商户扩展信息 * @param r9_BType 交易结果返回类型 * @param keyValue 密钥 * @return */public static boolean verifyCallback(String hmac, String p1_MerId,String r0_Cmd, String r1_Code, String r2_TrxId, String r3_Amt,String r4_Cur, String r5_Pid, String r6_Order, String r7_Uid,String r8_MP, String r9_BType, String keyValue) {StringBuilder sValue = new StringBuilder();// 商户编号sValue.append(p1_MerId);// 业务类型sValue.append(r0_Cmd);// 支付结果sValue.append(r1_Code);// 易宝支付交易流水号sValue.append(r2_TrxId);// 支付金额sValue.append(r3_Amt);// 交易币种sValue.append(r4_Cur);// 商品名称sValue.append(r5_Pid);// 商户订单号sValue.append(r6_Order);// 易宝支付会员IDsValue.append(r7_Uid);// 商户扩展信息sValue.append(r8_MP);// 交易结果返回类型sValue.append(r9_BType);String sNewString = PaymentUtil.hmacSign(sValue.toString(), keyValue);return sNewString.equals(hmac);}/** * @param aValue * @param aKey * @return */public static String hmacSign(String aValue, String aKey) {byte k_ipad[] = new byte[64];byte k_opad[] = new byte[64];byte keyb[];byte value[];try {keyb = aKey.getBytes(encodingCharset);value = aValue.getBytes(encodingCharset);} catch (UnsupportedEncodingException e) {keyb = aKey.getBytes();value = aValue.getBytes();}Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);Arrays.fill(k_opad, keyb.length, 64, (byte) 92);for (int i = 0; i < keyb.length; i++) {k_ipad[i] = (byte) (keyb[i] ^ 0x36);k_opad[i] = (byte) (keyb[i] ^ 0x5c);}MessageDigest md = null;try {md = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {return null;}md.update(k_ipad);md.update(value);byte dg[] = md.digest();md.reset();md.update(k_opad);md.update(dg, 0, 16);dg = md.digest();return toHex(dg);}public static String toHex(byte input[]) {if (input == null)return null;StringBuffer output = new StringBuffer(input.length * 2);for (int i = 0; i < input.length; i++) {int current = input[i] & 0xff;if (current < 16)output.append("0");output.append(Integer.toString(current, 16));}return output.toString();}/** *  * @param args * @param key * @return */public static String getHmac(String[] args, String key) {if (args == null || args.length == 0) {return (null);}StringBuffer str = new StringBuffer();for (int i = 0; i < args.length; i++) {str.append(args[i]);}return (hmacSign(str.toString(), key));}/** * @param aValue * @return */public static String digest(String aValue) {aValue = aValue.trim();byte value[];try {value = aValue.getBytes(encodingCharset);} catch (UnsupportedEncodingException e) {value = aValue.getBytes();}MessageDigest md = null;try {md = MessageDigest.getInstance("SHA");} catch (NoSuchAlgorithmException e) {e.printStackTrace();return null;}return toHex(md.digest(value));}}

         效果图:订单页页面正在完善,重点在功能上.当用户确认订单后,就会重定向到易宝平台再到付款银行的支付界面.这样就可以洗刷刷你的银行卡了.爱剁手的菇凉还是少看到这个页面的好,看到它就说明你又剁手啦⊙﹏⊙b

                  

                  

                     


总结

    本篇博客主要讲解了在线支付功能的实现,外加重定向和转发的区别. 


0 0
原创粉丝点击