java web实现第三方在线支付

java web在线支付

下面我们先来了解一下在线支付的方式及其各自的优缺点

在线支付:

和银行对接

和第三方支付对接

银行对接
优点:免费,无需支付任何费用

缺点:接口参数较多,开发成本及维护成本高

第三方支付
优点:第三方提供接口,开发成本及维护成本低

缺点:需要支付一定的费用

此处使用第三方支付,使用第三方支付平台“易宝支付”。
可访问官网http://www.yeepay.com/详细了解

一、易宝支付java在线支付流程如下:

java web实现第三方在线支付_第1张图片

使用易宝支付:

接入免费,只需从交易金额中扣取1%的手续费
- ①申请账号
- ②获取秘钥及加密算法
- ③发送请求
- ④接受回调
- ⑤处理相应的逻辑

二、代码编写如下:

准备工作:

(1)商户账号:p1_MerId=10001126856
(2)商户的keyValue:keyValue=69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl
(3)PaymentUtil类。

将(1)(2)中账户账号、商户keyvalue以及回调地址放入配置文件”merchantInfo.properties“中代码如下

        p1_MerId=10001126856
        keyValue=69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl
        responseURL=http://localhost:8888/store/order?method=callback

注:此处的responseURL采用的是本地的地址,如果有相应的域名则采用点对点的方式,填写相应的域名


PaymentUtil类代码如下:

package com.itheima.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));

}
}

java发送支付请求代码如下:

public String pay(HttpServletRequest request,HttpServletResponse respone) throws Exception{
    //接受参数
    String address=request.getParameter("address");
    String name=request.getParameter("name");
    String telephone=request.getParameter("telephone");
    String oid=request.getParameter("oid");


    //通过id获取order
    OrderService s=(OrderService) BeanFactory.getBean("OrderService");
    Order order = s.getById(oid);

    order.setAddress(address);
    order.setName(name);
    order.setTelephone(telephone);

    //更新order
    s.updateOrder(order);


    // 组织发送支付公司需要哪些数据
    String pd_FrpId = request.getParameter("pd_FrpId");
    String p0_Cmd = "Buy";
    String p1_MerId = ResourceBundle.getBundle("merchantInfo").getString("p1_MerId");
    String p2_Order = oid;
    String p3_Amt = "0.01";
    String p4_Cur = "CNY";
    String p5_Pid = "";
    String p6_Pcat = "";
    String p7_Pdesc = "";
    // 支付成功回调地址 ---- 第三方支付公司会访问、用户访问
    // 第三方支付可以访问网址
    String p8_Url = ResourceBundle.getBundle("merchantInfo").getString("responseURL");
    String p9_SAF = "";
    String pa_MP = "";
    String pr_NeedResponse = "1";
    // 加密hmac 需要密钥
    String keyValue = ResourceBundle.getBundle("merchantInfo").getString("keyValue");
    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);


    //发送给第三方
    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);

    respone.sendRedirect(sb.toString());

    return null;
}

回调函数代码如下:

public String callback(HttpServletRequest request,HttpServletResponse response) throws Exception{
    String p1_MerId = request.getParameter("p1_MerId");
    String r0_Cmd = request.getParameter("r0_Cmd");
    String r1_Code = request.getParameter("r1_Code");
    String r2_TrxId = request.getParameter("r2_TrxId");
    String r3_Amt = request.getParameter("r3_Amt");
    String r4_Cur = request.getParameter("r4_Cur");
    String r5_Pid = request.getParameter("r5_Pid");
    String r6_Order = request.getParameter("r6_Order");
    String r7_Uid = request.getParameter("r7_Uid");
    String r8_MP = request.getParameter("r8_MP");
    String r9_BType = request.getParameter("r9_BType");
    String rb_BankId = request.getParameter("rb_BankId");
    String ro_BankOrderId = request.getParameter("ro_BankOrderId");
    String rp_PayDate = request.getParameter("rp_PayDate");
    String rq_CardNo = request.getParameter("rq_CardNo");
    String ru_Trxtime = request.getParameter("ru_Trxtime");
    // 身份校验 --- 判断是不是支付公司通知
    String hmac = request.getParameter("hmac");
    String keyValue = ResourceBundle.getBundle("merchantInfo").getString(
            "keyValue");

    // 自己对上面数据进行加密 --- 比较支付公司发过来hamc
    boolean isValid = 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, keyValue);
    if (isValid) {
        // 响应数据有效
        if (r9_BType.equals("1")) {
            // 浏览器重定向
            System.out.println("111");
            request.setAttribute("msg", "您的订单号为:"+r6_Order+",金额为:"+r3_Amt+"已经支付成功,等待发货~~");

        } else if (r9_BType.equals("2")) {
            // 服务器点对点 --- 支付公司通知你
            System.out.println("付款成功!222");
            // 修改订单状态 为已付款
            // 回复支付公司
            response.getWriter().print("success");
        }

        //修改订单状态
        OrderService s=(OrderService) BeanFactory.getBean("OrderService");
        Order order = s.getById(r6_Order);
        order.setState(1);

        s.updateOrder(order);


    } else {
        // 数据无效
        System.out.println("数据被篡改!");
    }


    return "/jsp/msg.jsp";

}

相应的界面操作流程

java web实现第三方在线支付_第2张图片

java web实现第三方在线支付_第3张图片

java web实现第三方在线支付_第4张图片

java web实现第三方在线支付_第5张图片

java web实现第三方在线支付_第6张图片

如上界面中,点击“通知商户支付成功“后调用回调函数

三、总结

(1)实现接口对接时,注意参数名称的正确性
(2)下载接口说明文档,理解请求参数相关说明

你可能感兴趣的:(-----在线支付,java,java,web,在线支付,第三方支付)