其实支付功能主要就是为每个注册用户提供一个账号,提供一套加密算法和一个秘钥,调用了一个第三方的接口,输入一些信息而已,只要调用了第三方接口就重定向到第三方支付平台(易宝),重定向就不会显示传过去的数据,且将付款金额,订单号,哪个银行,发货地址,钱的类型,业务类型等数据经过加密算法和密钥加密后传过去,且加密后会得到一个hmac码;然后第三方支付平台也用相同算法将网站传过来的数据进行加密,得到hmac码,与之前得到的hmac码进行比较,如果码值相同就重定向到付款银行进行下一步支付操作. 若不同,自己调用别的操作
对于这里数据库的增删改最好都写在业务层,便于支付成功后调用对应的业务操作。
另外易宝支付产品通用接口帮助文档下载:http://download.csdn.net/detail/qq_27026603/9786738 有支付通道编码列表,以及接入易宝的出现的问题和步骤,支付通道编码列表就是jsp界面的value值,第三方接口接入各银行的银行编码值。只能接入第三方支付合作的网银,否则也没用,api文档里面有,想要加那个就改变下银行编码就行。
还有一些银行的logo图标:http://download.csdn.net/detail/qq_27026603/9787135
上面是一些参数的意思,代码实现如下:
JSP界面
订单支付信息类
JSP界面
选择银行:
招商银行 中国民生银行 工商银行 中国银行
农业银行 建设银行
交通银行
package org.company.group.finance.model;
import java.io.Serializable;
/**
* @ClassName: PayInfo
* @Description:TODO(订单支付和银行信息类)
* @author: java_liuchaojun
* @date: 2017-3-19 下午11:48:20
*
*/
public class PayInfo implements Serializable {
private static final long serialVersionUID = 1L;
/*
* 获得商品订单和选择的银行信息
*/
private String serviceType; // 业务类型
// private String shangHuId; // 取得商户编号
private String orderId; // 订单编号
private String payMoney; // 设置支付金额
private String jiaoYiMoneyType; // 交易币种
private String commodityName; // 商品名称
private String commodityType; // 商品种类
private String commodityDetail; // 商品描述
// private String paySuccessUrl; // 商户接收支付成功数据的地址
private String address; // 送货地址
private String commodityExtendInfo; // 商户扩展信息
private String bankCode;// 银行编码
private String responseJiZhi; // 应答机制
// private String shangHuKeyValue;// 商户密钥
public String getServiceType() {
return serviceType;
}
public void setServiceType(String serviceType) {
this.serviceType = serviceType;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getPayMoney() {
return payMoney;
}
public void setPayMoney(String payMoney) {
this.payMoney = payMoney;
}
public String getJiaoYiMoneyType() {
return jiaoYiMoneyType;
}
public void setJiaoYiMoneyType(String jiaoYiMoneyType) {
this.jiaoYiMoneyType = jiaoYiMoneyType;
}
public String getCommodityName() {
return commodityName;
}
public void setCommodityName(String commodityName) {
this.commodityName = commodityName;
}
public String getCommodityType() {
return commodityType;
}
public void setCommodityType(String commodityType) {
this.commodityType = commodityType;
}
public String getCommodityDetail() {
return commodityDetail;
}
public void setCommodityDetail(String commodityDetail) {
this.commodityDetail = commodityDetail;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCommodityExtendInfo() {
return commodityExtendInfo;
}
public void setCommodityExtendInfo(String commodityExtendInfo) {
this.commodityExtendInfo = commodityExtendInfo;
}
public String getBankCode() {
return bankCode;
}
public void setBankCode(String bankCode) {
this.bankCode = bankCode;
}
public String getResponseJiZhi() {
return responseJiZhi;
}
public void setResponseJiZhi(String responseJiZhi) {
this.responseJiZhi = responseJiZhi;
}
}
密文生成工具类
package org.company.group.finance.util;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import org.company.group.finance.model.PayInfo;
public class PaymentUtil {
private static String encodingCharset = "UTF-8";
/**
* 生成hmac方法 用户那边发送根据信息创建属性方法
*
*/
// 把传来的信息全部加入的缓冲区里面
public static String buildHmac(PayInfo payInfo, String shanghuId,
String paySuccessUrl, String shanghuKeyValue) {
// 把传来的信息全部加入的缓冲区里面
StringBuilder sValue = new StringBuilder();
// 业务类型
sValue.append(payInfo.getServiceType());
// 商户编号
sValue.append(shanghuId);
// 商户订单号
sValue.append(payInfo.getOrderId());
// 支付金额
sValue.append(payInfo.getPayMoney());
// 交易币种
sValue.append(payInfo.getJiaoYiMoneyType());
// 商品名称
sValue.append(payInfo.getCommodityName());
// 商品种类
sValue.append(payInfo.getCommodityType());
// 商品描述
sValue.append(payInfo.getCommodityDetail());
// 商户接收支付成功数据的地址
sValue.append(paySuccessUrl);
// 送货地址
sValue.append(payInfo.getAddress());
// 商户扩展信息
sValue.append(payInfo.getCommodityExtendInfo());
// 银行编码
sValue.append(payInfo.getBankCode());
// 应答机制
sValue.append(payInfo.getResponseJiZhi());
return PaymentUtil.hmacSign(sValue.toString(), shanghuKeyValue);
}
/**
* @param aValue
* 缓存区的内容
* @param aKey
* 密钥
* @return 下面两个方法都是把缓存区的内容和商户密钥进行MD5加密
*/
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();
// 加密完成
String zaiciJiaMi = toHex(dg);
return zaiciJiaMi;
}
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();
}
public static boolean verifyCallback(String zhifuCode, String shanghuId,
PayInfo payInfo, String shanghuKeyValue, String payResult,
String liuShuiHao, String yiBaoUserId, String payResultType) {
StringBuilder sValue = new StringBuilder();
// 业务类型
sValue.append(payInfo.getServiceType());
// 商户编号
sValue.append(shanghuId);
// 支付金额
sValue.append(payInfo.getPayMoney());
// 交易币种
sValue.append(payInfo.getJiaoYiMoneyType());
// 商户订单号
sValue.append(payInfo.getOrderId());
// 商品名称
sValue.append(payInfo.getCommodityName());
// 支付金额
sValue.append(payInfo.getPayMoney());
// 交易币种
sValue.append(payInfo.getJiaoYiMoneyType());
// 商户扩展信息
sValue.append(payInfo.getCommodityExtendInfo());
// 支付结果
sValue.append(payResult);
// 易宝支付交易流水号
sValue.append(liuShuiHao);
// 易宝支付会员ID
sValue.append(yiBaoUserId);
// 交易结果返回类型
sValue.append(payResultType);
// 把缓存区的内容和密钥传过去
String sNewString = PaymentUtil.hmacSign(sValue.toString(),
shanghuKeyValue);
// 得到加密的商户网关发来的内容进行加密
// 加密的值sNewString
// zhifuCode 支付网关发来的加密验证码
return sNewString.equals(zhifuCode);
}
}
链接信息配置文件
merchantInfo.properties
shangHuId=xxxxxxxxxxxxxxx 这里是商户的编号
shangHuKeyValue=xxxxxxxxxxxxxxxxxxxxxxx 这里是商户的密钥
paySuccessUrl=xxxxxxxxxxxxxxxxxxxxxx 这里是支付成功回滚的地址
fangwenUrl=https://www.yeepay.com/app-merchant-proxy/node 这里是支付跳第三方界面转易宝
shangHuId=xxxxxxxxxxxxxxx 这里是商户的编号
shangHuKeyValue=xxxxxxxxxxxxxxxxxxxxxxx 这里是商户的密钥
paySuccessUrl=xxxxxxxxxxxxxxxxxxxxxx 这里是支付成功回滚的地址
fangwenUrl=https://www.yeepay.com/app-merchant-proxy/node 这里是支付跳第三方界面转易宝
重定向支付界面和支付成功或失败回调的方法
private String config = "merchantInfo.properties";
public String zhffu() throws Exception {
payInfo.setServiceType("Buy");// 业务类型
payInfo.setOrderId(baseModel.getParamInt() + ""); // 订单编号=====
payInfo.setPayMoney(touziMoney);
payInfo.setJiaoYiMoneyType("CNY");
payInfo.setCommodityName("");// 商品名称
payInfo.setCommodityType("");// 商品类型
payInfo.setCommodityDetail("");// 商品描述
payInfo.setAddress("");// 商品地址
payInfo.setCommodityExtendInfo("");// 商品扩展信息
payInfo.setBankCode(pd_FrpId);// 银行编码
payInfo.setResponseJiZhi("1");// 应答机制==========
payMoney(payInfo, config);
}
public String paySuccessBack() {
String payResult = servletRequest.getParameter("r1_Code");
String liuShuiHao = servletRequest.getParameter("r2_TrxId");
String yiBaoUserId = servletRequest.getParameter("r7_Uid");
String payResultType = servletRequest.getParameter("r9_BType");
String zhifuCode = servletRequest.getParameter("hmac");
Properties props = new Properties();
InputStream input = this.getClass().getClassLoader()
.getResourceAsStream(config);
try {
props.load(input);
} catch (IOException e1) {
e1.printStackTrace();
}
String shanghuId = props.getProperty("shangHuId");// 商户编号
String paySuccessUrl = props.getProperty("paySuccessUrl");// 商户接收支付成功数据的地址
String shanghuKeyValue = props.getProperty("shangHuKeyValue");// 商户密钥
String fangWenHeadURL = props.getProperty("fangwenUrl");
boolean flag = PaymentUtil.verifyCallback(zhifuCode, shanghuId,
payInfo, shanghuKeyValue, payResult, liuShuiHao, yiBaoUserId,
payResultType);
if (!flag) {
baseModel.setMessage("不要乱填信息好不好!");
request.put("baseModel", baseModel);
return "error";
} else {
//跳转到支付成功的界面
return "payMoneySuccess";
}
}
对于这里数据库的增删改最好都写在业务层,便于支付成功后调用对应的业务操作。
另外易宝支付产品通用接口帮助文档下载:http://download.csdn.net/detail/qq_27026603/9786738 有支付通道编码列表,以及接入易宝的出现的问题和步骤,支付通道编码列表就是jsp界面的value值,第三方接口接入各银行的银行编码值。只能接入第三方支付合作的网银,否则也没用,api文档里面有,想要加那个就改变下银行编码就行。
还有一些银行的logo图标:http://download.csdn.net/detail/qq_27026603/9787135