ssh实现支付功能

其实支付功能主要就是为每个注册用户提供一个账号,提供一套加密算法和一个秘钥,调用了一个第三方的接口,输入一些信息而已,只要调用了第三方接口就重定向到第三方支付平台(易宝),重定向就不会显示传过去的数据,且将付款金额,订单号,哪个银行,发货地址,钱的类型,业务类型等数据经过加密算法和密钥加密后传过去,且加密后会得到一个hmac码;然后第三方支付平台也用相同算法将网站传过来的数据进行加密,得到hmac码,与之前得到的hmac码进行比较,如果码值相同就重定向到付款银行进行下一步支付操作. 若不同,自己调用别的操作


上面是一些参数的意思,代码实现如下:
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   这里是支付跳第三方界面转易宝

重定向支付界面和支付成功或失败回调的方法

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




猜你喜欢

转载自blog.csdn.net/qq_27026603/article/details/64026270