网上支付心案例payment

    1.  案例的作用及用法参考该类的说明注释  
    2. 工具类分别有:  
    3. package cn.itcast.utils;  
    4.   
    5. import java.util.Properties;  
    6. /** 
    7.  * 读取配置文件 
    8.  * 
    9.  */  
    10. public class ConfigInfo {  
    11.     private static Properties cache = new Properties();  
    12.     static{  
    13.         try {  
    14.             cache.load(ConfigInfo.class.getClassLoader().getResourceAsStream("merchantInfo.properties"));  
    15.         } catch (Exception e) {  
    16.             e.printStackTrace();  
    17.         }  
    18.     }  
    19.     /** 
    20.      * 获取指定key的值 
    21.      * @param key 
    22.      * @return 
    23.      */  
    24.     public static String getValue(String key){  
    25.         return cache.getProperty(key);  
    26.     }  
    27. }  
    28.   
    29. package cn.itcast.utils;  
    30.   
    31. import java.io.UnsupportedEncodingException;  
    32. import java.security.MessageDigest;  
    33. import java.security.NoSuchAlgorithmException;  
    34. import java.util.Arrays;  
    35.   
    36.   
    37. /** 
    38.  * md5-hmac算法加密类 
    39.  */  
    40. public class DigestUtil {  
    41.   
    42.     private static String encodingCharset = "UTF-8";  
    43.   
    44.     public static String hmacSign(String aValue, String aKey) {  
    45.         byte k_ipad[] = new byte[64];  
    46.         byte k_opad[] = new byte[64];  
    47.         byte keyb[];  
    48.         byte value[];  
    49.         try {  
    50.             keyb = aKey.getBytes(encodingCharset);  
    51.             value = aValue.getBytes(encodingCharset);  
    52.         } catch (UnsupportedEncodingException e) {  
    53.             keyb = aKey.getBytes();  
    54.             value = aValue.getBytes();  
    55.         }  
    56.   
    57.         Arrays.fill(k_ipad, keyb.length, 64, (byte54);  
    58.         Arrays.fill(k_opad, keyb.length, 64, (byte92);  
    59.         for (int i = 0; i < keyb.length; i++) {  
    60.             k_ipad[i] = (byte) (keyb[i] ^ 0x36);  
    61.             k_opad[i] = (byte) (keyb[i] ^ 0x5c);  
    62.         }  
    63.   
    64.         MessageDigest md = null;  
    65.         try {  
    66.             md = MessageDigest.getInstance("MD5");  
    67.         } catch (NoSuchAlgorithmException e) {  
    68.   
    69.             return null;  
    70.         }  
    71.         md.update(k_ipad);  
    72.         md.update(value);  
    73.         byte dg[] = md.digest();  
    74.         md.reset();  
    75.         md.update(k_opad);  
    76.         md.update(dg, 016);  
    77.         dg = md.digest();  
    78.         return toHex(dg);  
    79.     }  
    80.   
    81.     public static String toHex(byte input[]) {  
    82.         if (input == null)  
    83.             return null;  
    84.         StringBuffer output = new StringBuffer(input.length * 2);  
    85.         for (int i = 0; i < input.length; i++) {  
    86.             int current = input[i] & 0xff;  
    87.             if (current < 16)  
    88.                 output.append("0");  
    89.             output.append(Integer.toString(current, 16));  
    90.         }  
    91.   
    92.         return output.toString();  
    93.     }  
    94.   
    95.     /** 
    96.      *  
    97.      * @param args 
    98.      * @param key 
    99.      * @return 
    100.      */  
    101.     public static String getHmac(String[] args, String key) {  
    102.         if (args == null || args.length == 0) {  
    103.             return (null);  
    104.         }  
    105.         StringBuffer str = new StringBuffer();  
    106.         for (int i = 0; i < args.length; i++) {  
    107.             str.append(args[i]);  
    108.         }  
    109.         return (hmacSign(str.toString(), key));  
    110.     }  
    111.   
    112.     /** 
    113.      * @param aValue 
    114.      * @return 
    115.      */  
    116.     public static String digest(String aValue) {  
    117.         aValue = aValue.trim();  
    118.         byte value[];  
    119.         try {  
    120.             value = aValue.getBytes(encodingCharset);  
    121.         } catch (UnsupportedEncodingException e) {  
    122.             value = aValue.getBytes();  
    123.         }  
    124.         MessageDigest md = null;  
    125.         try {  
    126.             md = MessageDigest.getInstance("SHA");  
    127.         } catch (NoSuchAlgorithmException e) {  
    128.             e.printStackTrace();  
    129.             return null;  
    130.         }  
    131.         return toHex(md.digest(value));  
    132.   
    133.     }  
    134.       
    135. }  
    136.   
    137.   
    138. package cn.itcast.utils;  
    139.   
    140. public class PanymentUtil {  
    141.     /** 
    142.      * 生成hmac方法 
    143.      *  
    144.      * @param p0_Cmd 业务类型 
    145.      * @param p1_MerId 商户编号 
    146.      * @param p2_Order 商户订单号 
    147.      * @param p3_Amt 支付金额 
    148.      * @param p4_Cur 交易币种 
    149.      * @param p5_Pid 商品名称 
    150.      * @param p6_Pcat 商品种类 
    151.      * @param p7_Pdesc 商品描述 
    152.      * @param p8_Url 商户接收支付成功数据的地址 
    153.      * @param p9_SAF 送货地址 
    154.      * @param pa_MP 商户扩展信息 
    155.      * @param pd_FrpId 银行编码 
    156.      * @param pr_NeedResponse 应答机制 
    157.      * @param keyValue 商户密钥 
    158.      * @return 
    159.      */  
    160.     public static String buildHmac(String p0_Cmd,String p1_MerId,  
    161.             String p2_Order, String p3_Amt, String p4_Cur,String p5_Pid, String p6_Pcat,  
    162.             String p7_Pdesc,String p8_Url, String p9_SAF,String pa_MP,String pd_FrpId,  
    163.             String pr_NeedResponse,String keyValue) {  
    164.         StringBuffer sValue = new StringBuffer();  
    165.         // 业务类型  
    166.         sValue.append(p0_Cmd);  
    167.         // 商户编号  
    168.         sValue.append(p1_MerId);  
    169.         // 商户订单号  
    170.         sValue.append(p2_Order);  
    171.         // 支付金额  
    172.         sValue.append(p3_Amt);  
    173.         // 交易币种  
    174.         sValue.append(p4_Cur);  
    175.         // 商品名称  
    176.         sValue.append(p5_Pid);  
    177.         // 商品种类  
    178.         sValue.append(p6_Pcat);  
    179.         // 商品描述  
    180.         sValue.append(p7_Pdesc);  
    181.         // 商户接收支付成功数据的地址  
    182.         sValue.append(p8_Url);  
    183.         // 送货地址  
    184.         sValue.append(p9_SAF);  
    185.         // 商户扩展信息  
    186.         sValue.append(pa_MP);  
    187.         // 银行编码  
    188.         sValue.append(pd_FrpId);  
    189.         // 应答机制  
    190.         sValue.append(pr_NeedResponse);  
    191.           
    192.         String sNewString = DigestUtil.hmacSign(sValue.toString(), keyValue);  
    193.         return sNewString;  
    194.     }  
    195.       
    196.     /** 
    197.      * 返回校验hmac方法 
    198.      *  
    199.      * @param hmac 支付网关发来的加密验证码 
    200.      * @param p1_MerId 商户编号 
    201.      * @param r0_Cmd 业务类型 
    202.      * @param r1_Code 支付结果 
    203.      * @param r2_TrxId 易宝支付交易流水号 
    204.      * @param r3_Amt 支付金额 
    205.      * @param r4_Cur 交易币种 
    206.      * @param r5_Pid 商品名称 
    207.      * @param r6_Order 商户订单号 
    208.      * @param r7_Uid 易宝支付会员ID 
    209.      * @param r8_MP 商户扩展信息 
    210.      * @param r9_BType 交易结果返回类型 
    211.      * @param keyValue 密钥 
    212.      * @return 
    213.      */  
    214.     public static boolean verifyCallback(String hmac, String p1_MerId,  
    215.             String r0_Cmd, String r1_Code, String r2_TrxId, String r3_Amt,  
    216.             String r4_Cur, String r5_Pid, String r6_Order, String r7_Uid,  
    217.             String r8_MP, String r9_BType, String keyValue) {  
    218.         StringBuffer sValue = new StringBuffer();  
    219.         // 商户编号  
    220.         sValue.append(p1_MerId);  
    221.         // 业务类型  
    222.         sValue.append(r0_Cmd);  
    223.         // 支付结果  
    224.         sValue.append(r1_Code);  
    225.         // 易宝支付交易流水号  
    226.         sValue.append(r2_TrxId);  
    227.         // 支付金额  
    228.         sValue.append(r3_Amt);  
    229.         // 交易币种  
    230.         sValue.append(r4_Cur);  
    231.         // 商品名称  
    232.         sValue.append(r5_Pid);  
    233.         // 商户订单号  
    234.         sValue.append(r6_Order);  
    235.         // 易宝支付会员ID  
    236.         sValue.append(r7_Uid);  
    237.         // 商户扩展信息  
    238.         sValue.append(r8_MP);  
    239.         // 交易结果返回类型  
    240.         sValue.append(r9_BType);  
    241.         String sNewString = DigestUtil.hmacSign(sValue.toString(), keyValue);  
    242.   
    243.         if (hmac.equals(sNewString)) {  
    244.             return true;  
    245.         }  
    246.         return false;  
    247.     }  
    248. }  
    249.   
    250.   
    251. Servlet相关的类  
    252. package cn.itcast.servlet;  
    253.   
    254. import java.io.IOException;  
    255. import javax.servlet.ServletException;  
    256. import javax.servlet.http.HttpServlet;  
    257. import javax.servlet.http.HttpServletRequest;  
    258. import javax.servlet.http.HttpServletResponse;  
    259.   
    260. import cn.itcast.utils.ConfigInfo;  
    261. import cn.itcast.utils.PanymentUtil;  
    262. /** 
    263.  * 发起支付请求 
    264.  * @author 传智播客 
    265.  * 
    266.  */  
    267. public class PaymentRequest extends HttpServlet {  
    268.   
    269.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
    270.             throws ServletException, IOException {  
    271.         this.doPost(request, response);  
    272.     }  
    273.   
    274.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
    275.             throws ServletException, IOException {  
    276.         request.setCharacterEncoding("GBK");  
    277.         String orderid = request.getParameter("orderid");//订单号  
    278.         String amount = request.getParameter("amount");//支付金额  
    279.         String pd_FrpId = request.getParameter("pd_FrpId");//选择的支付银行  
    280.         String p1_MerId = ConfigInfo.getValue("p1_MerId");  
    281.         String keyValue = ConfigInfo.getValue("keyValue");  
    282.         String merchantCallbackURL = ConfigInfo.getValue("merchantCallbackURL");          
    283.         String messageType = "Buy"// 请求命令,在线支付固定为Buy  
    284.         String currency = "CNY"// 货币单位  
    285.         String productDesc = ""// 商品描述  
    286.         String productCat = ""// 商品种类  
    287.         String productId = ""// 商品ID  
    288.         String addressFlag = "0"// 需要填写送货信息 0:不需要 1:需要          
    289.         String sMctProperties = ""// 商家扩展信息  
    290.         String pr_NeedResponse = "0"// 应答机制  
    291.         String md5hmac = PanymentUtil.buildHmac(messageType, p1_MerId, orderid, amount, currency,  
    292.                 productId, productCat, productDesc, merchantCallbackURL, addressFlag, sMctProperties,   
    293.                 pd_FrpId, pr_NeedResponse, keyValue);  
    294.           
    295.         request.setAttribute("messageType", messageType);  
    296.         request.setAttribute("merchantID", p1_MerId);  
    297.         request.setAttribute("orderId", orderid);  
    298.         request.setAttribute("amount", amount);  
    299.         request.setAttribute("currency", currency);  
    300.         request.setAttribute("productId", productId);  
    301.         request.setAttribute("productCat", productCat);  
    302.         request.setAttribute("productDesc", productDesc);  
    303.         request.setAttribute("merchantCallbackURL", merchantCallbackURL);  
    304.         request.setAttribute("addressFlag", addressFlag);  
    305.         request.setAttribute("sMctProperties", sMctProperties);  
    306.         request.setAttribute("frpId", pd_FrpId);  
    307.         request.setAttribute("pr_NeedResponse", pr_NeedResponse);  
    308.         request.setAttribute("hmac", md5hmac);  
    309.           
    310.         request.getRequestDispatcher("/WEB-INF/page/connection.jsp").forward(request, response);  
    311.     }  
    312.   
    313. }  
    314.   
    315.   
    316. package cn.itcast.servlet;  
    317.   
    318. import java.io.IOException;  
    319.   
    320. import javax.servlet.ServletException;  
    321. import javax.servlet.http.HttpServlet;  
    322. import javax.servlet.http.HttpServletRequest;  
    323. import javax.servlet.http.HttpServletResponse;  
    324.   
    325. import cn.itcast.utils.ConfigInfo;  
    326. import cn.itcast.utils.PanymentUtil;  
    327. /** 
    328.  * 响应银行支付结果请求 
    329.  * @author 传智播客 
    330.  * 
    331.  */  
    332. public class PaymentResutlResponse extends HttpServlet {  
    333.   
    334.     public void doGet(HttpServletRequest request, HttpServletResponse response)  
    335.             throws ServletException, IOException {  
    336.         this.doPost(request, response);  
    337.     }  
    338.   
    339.     public void doPost(HttpServletRequest request, HttpServletResponse response)  
    340.             throws ServletException, IOException {  
    341.         request.setCharacterEncoding("GBK");  
    342.         String merchantID = ConfigInfo.getValue("p1_MerId"); // 商家ID  
    343.         String keyValue = ConfigInfo.getValue("keyValue"); // 商家密钥  
    344.           
    345.         String sCmd = request.getParameter("r0_Cmd"); //业务类型  
    346.         String sResultCode = request.getParameter("r1_Code"); //扣款结果,该字段值为1时表示扣款成功.  
    347.         String sTrxId = request.getParameter("r2_TrxId"); //YeePay易宝交易订单号  
    348.         String amount = request.getParameter("r3_Amt");//扣款金额,交易结束后,YeePay易宝交易系统将实际扣款金额返回给商户  
    349.         String currency = request.getParameter("r4_Cur");//交易币种,人民币为CNY  
    350.         String productId = request.getParameter("r5_Pid");//商品ID  
    351.         String orderId = request.getParameter("r6_Order");//商户订单号  
    352.         String userId = request.getParameter("r7_Uid");//YeePay易宝会员ID  
    353.         String mp  = request.getParameter("r8_MP");//商户扩展信息,可以任意填写1K 的字符串,交易返回时将原样返回  
    354.         String bType = request.getParameter("r9_BType");//交易结果通知类型,1: 交易成功回调(浏览器重定向)2: 交易成功主动通知(服务器点对点通讯)  
    355.         String rb_BankId  = request.getParameter("rb_BankId");//支付银行  
    356.         String rp_PayDate = request.getParameter("rp_PayDate");//在银行支付时的时间  
    357.         String hmac = request.getParameter("hmac");//MD5交易签名  
    358.           
    359.         boolean result = PanymentUtil.verifyCallback(hmac, merchantID, sCmd, sResultCode, sTrxId, amount,  
    360.                 currency, productId, orderId, userId, mp, bType, keyValue);  
    361.         if(result){  
    362.             if("1".equals(sResultCode)){  
    363.                 //你们这个地方应该把数据库中订单的支付状态设置成已经支付.  
    364.                 String message = "订单号为:"+ orderId+ "的订单支付成功了";  
    365.                 message += ",用户支付了"+ amount +"元";  
    366.                 message +=",交易结果通知类型:";  
    367.                 if("1".equals(bType)){  
    368.                      message += "浏览器重定向";  
    369.                 }else if("2".equals(bType)){  
    370.                      message += "易宝支付网关后台程序通知";  
    371.                 }  
    372.                 message += ",易宝订单系统中的订单号为:"+ sTrxId;  
    373.                 request.setAttribute("message", message);  
    374.             }else{  
    375.                 request.setAttribute("message""用户支付失败");  
    376.             }  
    377.         }else{  
    378.             request.setAttribute("message""数据来源不合法");  
    379.         }  
    380.         request.getRequestDispatcher("/WEB-INF/page/paymentResult.jsp").forward(request, response);  
    381.     }  
    382.   
    383. }  
    384.   
    385. 显示界面jsp  
    386. <%@ page language="java" import="java.util.*" pageEncoding="GBK"%>  
    387. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
    388. <html>  
    389.   <head>  
    390.     
    391.     <title>巴巴运动网_支付第一步,选择支付银行</title>  
    392.     <meta http-equiv="pragma" content="no-cache">  
    393.     <meta http-equiv="cache-control" content="no-cache">  
    394.     <meta http-equiv="expires" content="0">      
    395.   
    396.   </head>  
    397.     
    398.   <body>  
    399. <table width="960" border="0" align="center">  
    400.   <tr>  
    401.     <td width="536" valign="top">  
    402.     <form action="${pageContext.request.contextPath}/servlet/yeepay/paymentRequest" method="post" name="paymentform">  
    403.       
    404.     <table width="100%" border="0">  
    405.       <tr>  
    406.         <td height="30" colspan="4"><table width="100%" height="50" border="0" cellpadding="0" cellspacing="1" bgcolor="#A2E0FF">  
    407.           <tr>  
    408.             <td align="center" bgcolor="#F7FEFF"><h3>订单号:<INPUT TYPE="text" NAME="orderid"> 应付金额:¥<INPUT TYPE="text" NAME="amount" size="6">元</h3></td>  
    409.           </tr>  
    410.         </table></td>  
    411.         </tr>  
    412.       <tr>  
    413.         <td colspan="4"> </td>  
    414.         </tr>  
    415.       <tr>  
    416.         <td height="30" colspan="4" bgcolor="#F4F8FF"><span class="STYLE3">请您选择在线支付银行</span> </td>  
    417.         </tr>  
    418.       <tr>  
    419.         <td width="26%" height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBCHINA-NET">招商银行 </td>  
    420.         <td width="25%" height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="ICBC-NET">工商银行</td>  
    421.         <td width="25%" height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="ABC-NET">农业银行</td>  
    422.         <td width="24%" height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CCB-NET">建设银行 </td>  
    423.       </tr>  
    424.       <tr>  
    425.         <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBC-NET">中国民生银行总行</td>  
    426.         <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CEB-NET" >光大银行 </td>  
    427.         <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="BOCO-NET">交通银行</td>  
    428.         <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="SDB-NET">深圳发展银行</td>  
    429.       </tr>  
    430.       <tr>  
    431.         <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="BCCB-NET">北京银行</td>  
    432.         <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="CIB-NET">兴业银行 </td>  
    433.         <td height="25"><INPUT TYPE="radio" NAME="pd_FrpId" value="SPDB-NET">上海浦东发展银行 </td>  
    434.         <td ><INPUT TYPE="radio" NAME="pd_FrpId" value="ECITIC-NET">中信银行</td>  
    435.       </tr>  
    436.       <tr>  
    437.         <td colspan="4"> </td>  
    438.         </tr>  
    439.       <tr>  
    440.         <td colspan="4" align="center"><input type="submit" value=" 确认支付 " /></td>  
    441.         </tr>  
    442.     </table>  
    443.     </form>   </td>  
    444.     <td colspan="2" valign="top"><div class="divts"><table width="400" border="0" align="center" cellpadding="5" cellspacing="0">  
    445.       <tr>  
    446.         <td bgcolor="#F4F8FF"><span class="STYLE5"> 温馨提示</span></td>  
    447.       </tr>  
    448.       <tr>  
    449.         <td><ul><li> 建行客户需到柜面签约网上银行才能支付</li>  
    450.         <li>请关闭弹出窗口拦截功能</li>  
    451.         <li>务必使用IE5.0以上浏览器</li>  
    452.         <li>支付出错时勿按IE“后退”键</li>  
    453.         </ul></td>  
    454.       </tr>  
    455.     </table>  
    456.     </div>  
    457.       
    458.     <div id="blankmessage"></div>   </td>  
    459.   </tr>  
    460.   <tr>  
    461.     <td> </td>  
    462.     <td width="290"> </td>  
    463.     <td width="120"> </td>  
    464.   </tr>  
    465. </table>  
    466.   </body>  
    467. </html>  
    468.   
    469. 发起支付请求  
    470. <%@ page language="java" pageEncoding="GBK"%>  
    471. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
    472. <html>  
    473.   <head>  
    474.     <title>发起支付请求</title>  
    475.       
    476.     <meta http-equiv="pragma" content="no-cache">  
    477.     <meta http-equiv="cache-control" content="no-cache">  
    478.     <meta http-equiv="expires" content="0">      
    479.   </head>  
    480.     
    481.   <body onload="javascript:document.forms[0].submit()">  
    482.     <!-- http://tech.yeepay.com:8080/robot/debug.action -->  
    483.     <form name="yeepay" action="https://www.yeepay.com/app-merchant-proxy/node" method='post'>      
    484.         <input type='hidden' name='p0_Cmd'   value="${messageType}"> <!-- 请求命令,在线支付固定为Buy -->  
    485.         <input type='hidden' name='p1_MerId' value="${merchantID}"> <!-- 商家ID -->  
    486.         <input type="hidden" name="p2_Order" value="${orderId}"> <!-- 商家的交易定单号 -->  
    487.         <input type='hidden' name='p3_Amt'   value="${amount}"> <!-- 订单金额 -->  
    488.         <input type='hidden' name='p4_Cur'   value="${currency}"> <!-- 货币单位 -->  
    489.         <input type='hidden' name='p5_Pid'   value="${productId}"> <!-- 商品ID -->  
    490.         <input type='hidden' name='p6_Pcat'  value="${productCat}"> <!-- 商品种类 -->  
    491.         <input type='hidden' name='p7_Pdesc' value="${productDesc}"> <!-- 商品描述 -->  
    492.         <input type='hidden' name='p8_Url'   value="${merchantCallbackURL}"> <!-- 交易结果通知地址 -->  
    493.         <input type='hidden' name='p9_SAF'   value="${addressFlag}"> <!-- 需要填写送货信息 0:不需要 1:需要 -->  
    494.         <input type='hidden' name='pa_MP'    value="${sMctProperties}"> <!-- 商家扩展信息 -->  
    495.         <input type='hidden' name='pd_FrpId' value="${frpId}"> <!-- 银行ID -->  
    496.         <!-- 应答机制 为“1”: 需要应答机制;为“0”: 不需要应答机制 -->  
    497.         <input type="hidden" name="pr_NeedResponse"  value="0">  
    498.         <input type='hidden' name='hmac' value="${hmac}"><!-- MD5-hmac验证码 -->  
    499.     </form>  
    500.   </body>  
    501. </html>  
    502.   
    503. 支付结果  
    504. <%@ page language="java" pageEncoding="GBK"%>  
    505. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  
    506. <html>  
    507.   <head>  
    508.     <title>支付结果</title>  
    509.       
    510.     <meta http-equiv="pragma" content="no-cache">  
    511.     <meta http-equiv="cache-control" content="no-cache">  
    512.     <meta http-equiv="expires" content="0">      
    513.   </head>  
    514.     
    515.   <body >  
    516.     <center><h3><font color="red">  
    517.     ${message }  
    518.     </font></h3></center>  
    519.   </body>  
    520. </html> 
posted @ 2014-02-07 16:33  chenchangyan  阅读(476)  评论(0编辑  收藏  举报