第三方支付方式:易宝支付。

支付过程图解:

在线支付(易宝支付)

相关资料:

易宝支付产品通用接口帮助文档点击打开链接

使用步骤:

    ①src下面放入支付测试用的merchantInfo.properties(包含商家id【p1_MerId=10001126856】+加密解密用的keyValue【keyValue=69cl522AV6q613Ii4W6u8K6XuW8vM1N6bFgyv769220IuYe9u37N4y7rI4Pl】+支付成功后的重定向路径)
注意:下面的p8_Url是支付成功后供用户重定向返回网站或者服务器之间点对点通知支付成功用的。所以其ip是内网localhost时,只能通过用户重定向返回网站通知支付成功,易宝支付是无法通知网站支付成功的(除了用公网)。
    ②servlet准备 付款的金额totalMoney+订单id 数据转发给通用支付页面pay.jsp (注意:页面中的单选框的值来自于易宝支付提供的“支付通道编码”,固定
1
<%@page language="java" import="java.util.*" contentType="text/html;charset=utf-8"%>
2
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
3
<html>
4
<head>
5
<title>在线支付</title>
6
</head>
7
8
<body>
9
    <form action="${pageContext.request.contextPath }/servlet/PayServlet" method="post">
10
        <table width="60%">
11
            <tr>
12
                <td bgcolor="#F7FEFF" colspan="4">
13
                <!-- 实际开发中:这里的订单号和支付金额来自servlet传递过来 -->
14
                订单号:<INPUT TYPE="text" NAME="orderId" value="20170815110723"> 
15
                支付金额:<INPUT TYPE="text" NAME="money" size="6" value="0.01"></td>
16
            </tr>
17
            <tr>
18
                <td>
19
                    <br/>
20
                </td>
21
            </tr>
22
            <tr>
23
                <td>请您选择在线支付银行</td>
24
            </tr>
25
            <tr>
26
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="ICBC-NET">工商银行</td>
27
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="ABC-NET">农业银行</td>
28
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CCB-NET">建设银行</td>
29
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBCHINA-NET">招商银行</td>
30
            </tr>
31
            <tr>
32
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CMBC-NET">中国民生银行总行</td>
33
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CEB-NET">光大银行</td>
34
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="BOCO-NET">交通银行</td>
35
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="SDB-NET">深圳发展银行</td>
36
            </tr>
37
            <tr>
38
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="BCCB-NET">北京银行</td>
39
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="CIB-NET">兴业银行</td>
40
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="SPDB-NET">上海浦东发展银行</td>
41
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="ECITIC-NET">中信银行</td>
42
            </tr>
43
            <tr>
44
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="POST-NET-B2C">中国邮政</td>
45
                <td><INPUT TYPE="radio" NAME="pd_FrpId" value="BOC-NET-B2C">中国银行</td>
46
            </tr>
47
            <tr>
48
                <td>
49
                    <br/>
50
                </td>
51
            </tr>
52
            <tr>
53
                <td><input type="submit" value="进入银行支付" /></td>
54
            </tr>
55
        </table>
56
    </form>
57
</body>
58
</html>
    ③pay.jsp页面选择支付银行后,进入servlet,组织第三方易宝支付需要的数据,最后重定向到第三方提供的支付链接https://www.yeepay.com/app-merchant-proxy/node 上。 
    读取properties文件时用到的自定义工具PropertiesUtils.java
1
package com.cn.pay.utils;
2
3
import java.util.ResourceBundle;
4
5
public class PropertiesUtils {
6
7
    private static ResourceBundle bundle;
8
    
9
    //加载一次配置文件
10
    static{
11
        bundle = ResourceBundle.getBundle("merchantInfo");
12
    }
13
    
14
    public static String getPropertiesByKey(String key){
15
        
16
        return bundle.getString(key);
17
    }
18
}
19
    ③只有当用户付款成功后,第三方易宝支付会通知用户(浏览器重定向)和商户(服务器点对点通讯)。这时,系统再进行付款成功后的业务逻辑处理(重定向的url在merchantInfo.properties配置中)。
    
    第三方易宝支付自己的支付工具(加密+验证)PaymentUtil.java
1
package com.cn.utils;
2
3
4
import java.io.UnsupportedEncodingException;
5
import java.security.MessageDigest;
6
import java.security.NoSuchAlgorithmException;
7
import java.util.Arrays;
8
9
public class PaymentUtil {
10
11
    private static String encodingCharset = "UTF-8";
12
    
13
    /**
14
     * 生成hmac方法
15
     * 
16
     * @param p0_Cmd 业务类型
17
     * @param p1_MerId 商户编号
18
     * @param p2_Order 商户订单号
19
     * @param p3_Amt 支付金额
20
     * @param p4_Cur 交易币种
21
     * @param p5_Pid 商品名称
22
     * @param p6_Pcat 商品种类
23
     * @param p7_Pdesc 商品描述
24
     * @param p8_Url 商户接收支付成功数据的地址
25
     * @param p9_SAF 送货地址
26
     * @param pa_MP 商户扩展信息
27
     * @param pd_FrpId 银行编码
28
     * @param pr_NeedResponse 应答机制
29
     * @param keyValue 商户**
30
     * @return
31
     */
32
    public static String buildHmac(String p0_Cmd,String p1_MerId,
33
            String p2_Order, String p3_Amt, String p4_Cur,String p5_Pid, String p6_Pcat,
34
            String p7_Pdesc,String p8_Url, String p9_SAF,String pa_MP,String pd_FrpId,
35
            String pr_NeedResponse,String keyValue) {
36
        StringBuilder sValue = new StringBuilder();
37
        // 业务类型
38
        sValue.append(p0_Cmd);
39
        // 商户编号
40
        sValue.append(p1_MerId);
41
        // 商户订单号
42
        sValue.append(p2_Order);
43
        // 支付金额
44
        sValue.append(p3_Amt);
45
        // 交易币种
46
        sValue.append(p4_Cur);
47
        // 商品名称
48
        sValue.append(p5_Pid);
49
        // 商品种类
50
        sValue.append(p6_Pcat);
51
        // 商品描述
52
        sValue.append(p7_Pdesc);
53
        // 商户接收支付成功数据的地址
54
        sValue.append(p8_Url);
55
        // 送货地址
56
        sValue.append(p9_SAF);
57
        // 商户扩展信息
58
        sValue.append(pa_MP);
59
        // 银行编码
60
        sValue.append(pd_FrpId);
61
        // 应答机制
62
        sValue.append(pr_NeedResponse);
63
        
64
        return PaymentUtil.hmacSign(sValue.toString(), keyValue);
65
    }
66
    
67
    /**
68
     * 返回校验hmac方法
69
     * 
70
     * @param hmac 支付网关发来的加密验证码
71
     * @param p1_MerId 商户编号
72
     * @param r0_Cmd 业务类型
73
     * @param r1_Code 支付结果
74
     * @param r2_TrxId 易宝支付交易流水号
75
     * @param r3_Amt 支付金额
76
     * @param r4_Cur 交易币种
77
     * @param r5_Pid 商品名称
78
     * @param r6_Order 商户订单号
79
     * @param r7_Uid 易宝支付会员ID
80
     * @param r8_MP 商户扩展信息
81
     * @param r9_BType 交易结果返回类型
82
     * @param keyValue **
83
     * @return
84
     */
85
    public static boolean verifyCallback(String hmac, String p1_MerId,
86
            String r0_Cmd, String r1_Code, String r2_TrxId, String r3_Amt,
87
            String r4_Cur, String r5_Pid, String r6_Order, String r7_Uid,
88
            String r8_MP, String r9_BType, String keyValue) {
89
        StringBuilder sValue = new StringBuilder();
90
        // 商户编号
91
        sValue.append(p1_MerId);
92
        // 业务类型
93
        sValue.append(r0_Cmd);
94
        // 支付结果
95
        sValue.append(r1_Code);
96
        // 易宝支付交易流水号
97
        sValue.append(r2_TrxId);
98
        // 支付金额
99
        sValue.append(r3_Amt);
100
        // 交易币种
101
        sValue.append(r4_Cur);
102
        // 商品名称
103
        sValue.append(r5_Pid);
104
        // 商户订单号
105
        sValue.append(r6_Order);
106
        // 易宝支付会员ID
107
        sValue.append(r7_Uid);
108
        // 商户扩展信息
109
        sValue.append(r8_MP);
110
        // 交易结果返回类型
111
        sValue.append(r9_BType);
112
        String sNewString = PaymentUtil.hmacSign(sValue.toString(), keyValue);
113
        return sNewString.equals(hmac);
114
    }
115
    
116
    /**
117
     * @param aValue
118
     * @param aKey
119
     * @return
120
     */
121
    public static String hmacSign(String aValue, String aKey) {
122
        byte k_ipad[] = new byte[64];
123
        byte k_opad[] = new byte[64];
124
        byte keyb[];
125
        byte value[];
126
        try {
127
            keyb = aKey.getBytes(encodingCharset);
128
            value = aValue.getBytes(encodingCharset);
129
        } catch (UnsupportedEncodingException e) {
130
            keyb = aKey.getBytes();
131
            value = aValue.getBytes();
132
        }
133
134
        Arrays.fill(k_ipad, keyb.length, 64, (byte) 54);
135
        Arrays.fill(k_opad, keyb.length, 64, (byte) 92);
136
        for (int i = 0; i < keyb.length; i++) {
137
            k_ipad[i] = (byte) (keyb[i] ^ 0x36);
138
            k_opad[i] = (byte) (keyb[i] ^ 0x5c);
139
        }
140
141
        MessageDigest md = null;
142
        try {
143
            md = MessageDigest.getInstance("MD5");
144
        } catch (NoSuchAlgorithmException e) {
145
146
            return null;
147
        }
148
        md.update(k_ipad);
149
        md.update(value);
150
        byte dg[] = md.digest();
151
        md.reset();
152
        md.update(k_opad);
153
        md.update(dg, 0, 16);
154
        dg = md.digest();
155
        return toHex(dg);
156
    }
157
158
    public static String toHex(byte input[]) {
159
        if (input == null)
160
            return null;
161
        StringBuffer output = new StringBuffer(input.length * 2);
162
        for (int i = 0; i < input.length; i++) {
163
            int current = input[i] & 0xff;
164
            if (current < 16)
165
                output.append("0");
166
            output.append(Integer.toString(current, 16));
167
        }
168
169
        return output.toString();
170
    }
171
172
    /**
173
     * 
174
     * @param args
175
     * @param key
176
     * @return
177
     */
178
    public static String getHmac(String[] args, String key) {
179
        if (args == null || args.length == 0) {
180
            return (null);
181
        }
182
        StringBuffer str = new StringBuffer();
183
        for (int i = 0; i < args.length; i++) {
184
            str.append(args[i]);
185
        }
186
        return (hmacSign(str.toString(), key));
187
    }
188
189
    /**
190
     * @param aValue
191
     * @return
192
     */
193
    public static String digest(String aValue) {
194
        aValue = aValue.trim();
195
        byte value[];
196
        try {
197
            value = aValue.getBytes(encodingCharset);
198
        } catch (UnsupportedEncodingException e) {
199
            value = aValue.getBytes();
200
        }
201
        MessageDigest md = null;
202
        try {
203
            md = MessageDigest.getInstance("SHA");
204
        } catch (NoSuchAlgorithmException e) {
205
            e.printStackTrace();
206
            return null;
207
        }
208
        return toHex(md.digest(value));
209
210
    }
211
}   

支付演示

pay.jsp支付页面,选择支付银行
在线支付(易宝支付)
进入相应银行网站
  在线支付(易宝支付)
输入相应短信验证(不同银行过程不同)
在线支付(易宝支付)
银行引导用户访问第三方易宝支付,携带相应支付完成信息,跳转到电商网站,提示信息(完成支付成功后的逻辑业务)
在线支付(易宝支付)
 

相关文章: