Java使用Servlet或者springMVC,使用maven进行环境搭建。
|
package com.tank.pay.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); // �ױ�֧����ԱID sValue.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));
}
// public static void main(String[] args) { // System.out.println(hmacSign("AnnulCard1000043252120080620160450.0http://localhost/SZXpro/callback.asp��?4564868265473632445648682654736324511","8UPp0KE8sq73zVP370vko7C39403rtK1YwX40Td6irH216036H27Eb12792t")); // } } |
p1_MerId=10001126856 keyValue=69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl responseURL=http://localhost:9003/payresponse.action |
易宝支付:
package com.tank.pay.web;
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import com.tank.pay.utils.PaymentUtil;
/** * 支付请求,发起支付 */ public class PayServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//发起请求,拼接参数,重定向到指定页面 //正常情况如果是支付未支付的数据,应该传递参数过来,比如订单号等信息,然后服务端查询需要多少钱,而不是以页面传递为准, //如果是正常的充值,则以传递为准,但是是否有额外条件,需要自己判断,比如页面上面的选项只有,10.50,,100.
//拼接13个请求参数 String p0_Cmd = "Buy";//业务类型 String p1_MerId = "10001126856";// 商户编号 String p2_Order = "ta12345679890";//商户订单号 String p3_Amt = "0.01";// 支付金额 String p4_Cur = "CNY";//交易币种 String p5_Pid = "Mathbook";//商品名称 String p6_Pcat = "book";// 商品种类 String p7_Pdesc = "lean more ";//商品描述 String p8_Url = "http://localhost:18080/ResponseServlet";//商户接收支付成功数据的地址 String p9_SAF = "0";//送货地址 String pa_MP = "yuanyangfanhui";//商户扩展信息 String pd_FrpId = "ICBC-NET";// 支付通道编码(指定工商银行) String pr_NeedResponse = "1";//应答机制
//拼接前面13个参数的校验值 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"); //正式请求地址 String url="https://www.yeepay.com/app-merchant-proxy/node?"+ "&p0_Cmd="+p0_Cmd+ "&p1_MerId="+p1_MerId+ "&p2_Order="+p2_Order+ "&p3_Amt="+p3_Amt+ "&p4_Cur="+p4_Cur+ "&p5_Pid="+p5_Pid+ "&p6_Pcat="+p6_Pcat+ "&p7_Pdesc="+p7_Pdesc+ "&p8_Url="+p8_Url+ "&p9_SAF="+p9_SAF+ "&pa_MP="+pa_MP+ "&pd_FrpId="+pd_FrpId+ "&pr_NeedResponse="+pr_NeedResponse+ "&hmac="+hmac; response.sendRedirect(url);
}
}
|
返回的url:
http://localhost:18080/ResponseServlet?p1_MerId=10001126856&r0_Cmd=Buy&r1_Code=1&r2_TrxId=716287214431153I&r3_Amt=0.01&r4_Cur=RMB&r5_Pid=Mathbook&r6_Order=ta12345679890&r7_Uid=&r8_MP=yuanyangfanhui&r9_BType=1&ru_Trxtime=20171125154812&ro_BankOrderId=51579430841711&rb_BankId=ICBC-NET&rp_PayDate=20171125154759&rq_CardNo=&rq_SourceFee=0.0&rq_TargetFee=0.0&hmac=6e7ace8edfab5831173ca12ce61d74e7
/** * 处理支付响应 */ public class ResponseServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); }
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Map System.out.println(parameterMap);
} }
|
控制台打印信息:
{p1_MerId=[Ljava.lang.String;@9db5a4, r0_Cmd=[Ljava.lang.String;@5a5607, r1_Code=[Ljava.lang.String;@65ded4, r2_TrxId=[Ljava.lang.String;@1675c3c, r3_Amt=[Ljava.lang.String;@54fd21, r4_Cur=[Ljava.lang.String;@c7d02, r5_Pid=[Ljava.lang.String;@d582a9, r6_Order=[Ljava.lang.String;@148a373, r7_Uid=[Ljava.lang.String;@70f38e, r8_MP=[Ljava.lang.String;@167726f, r9_BType=[Ljava.lang.String;@1d16ee0, ru_Trxtime=[Ljava.lang.String;@1061e92, ro_BankOrderId=[Ljava.lang.String;@29793f, rb_BankId=[Ljava.lang.String;@51979f, rp_PayDate=[Ljava.lang.String;@bd5e5b, rq_CardNo=[Ljava.lang.String;@13a2a50, rq_SourceFee=[Ljava.lang.String;@174d49, rq_TargetFee=[Ljava.lang.String;@7cd0bb, hmac=[Ljava.lang.String;@9916a9} |
成功后跳转到自己指定的路径,带回返回的数据。
支付成功会有两次不同地方的返回:
1. 返回到自己指定的响应页面(responseServlet),可以对返回值进行处理判断
2. 服务器会进行端到端的传输。(成功以服务器的成功为标准)
注意:这里只是一个支付的简单测试,在实际的开发中,我们支付时需要在前台页面进行银行的选择,jsp的跳转需要我们在实际情况中去考虑,返回结果,我们需要去判断各种情况的发生,对不同情况进行相应的处理,我们的支付(13个参数)或者返回数据,我们可以将他们封装层Bean对象,方便我们去调用,或者查看数据信息。