线上充值 每一个支付平台都有一个支付平台需要传递的参数,请参考支付宝文档
1. 首先我定义了一个类,来确定该平台是和哪个支付平台做合作,可以通过传递参数的不同,很容易解决
2.定义几个实体类:
Pyment类
RechargeDetail 类
3. 通过传递的参数不同,来获取不同的支付平台,在这里我定义了一个抽象类Factory
4. 实现上面接口
4. 功能:基础配置类
5、提现操作类
1. 首先我定义了一个类,来确定该平台是和哪个支付平台做合作,可以通过传递参数的不同,很容易解决
public interface Constant {
//与数据库配置保持一致
public static final int GOPAY = 1;
public static final int ALIPAY = 2;
public static final int TENPAY = 3;
}
2.定义几个实体类:
Parameter类,作用:把提充值涉及到的参数都封装到该类中
public class Parameter {
private String name;
private String value;
public Parameter()
{
}
public Parameter(String name, String value)
{
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
Pyment类
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Payment {
//发送过去的链接
private String gatewayUrl;
//方法传送(有get和post)
private String method;
//传递的参数信息
private Map<String,String> paramMap;
//把需要传递的参数封装到List<Parameter>下
private List<Parameter> parameters = new ArrayList<Parameter>();
public String getGatewayUrl() {
return gatewayUrl;
}
public void setGatewayUrl(String gatewayUrl) {
this.gatewayUrl = gatewayUrl;
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public Map<String, String> getParamMap() {
return paramMap;
}
public void setParamMap(Map<String, String> paramMap) {
this.paramMap = paramMap;
parameters.clear();
for (String key: paramMap.keySet())
{
parameters.add(new Parameter(key,paramMap.get(key)));
System.out.println(key +":" + paramMap.get(key));
}
}
public List<Parameter> getParameters() {
return parameters;
}
}
RechargeDetail 类
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 充值明细记录
*
* @author hzh
*
*/
public class RechargeDetail {
//充值ID
private long id ;
// 用户ID
private long userId;
// 用户名
private String userName;
// 充值金额
private BigDecimal rechargeValue = BigDecimal.valueOf(0);
// 充值费用
private BigDecimal rechargeFee = BigDecimal.valueOf(0);
// 流水号
private String rechargeSequence;
// 状态
private int recharged;
// 实际划款日期时间
private Date acctualRechargedDate;
// 实际划款金额
private BigDecimal acctualRechargedValue;
// 更新时间
private Timestamp updateTime;
// 第三方支付/银行操作流水号
private String responseSequence;
// 预留
private String reserved;
private BigDecimal sumAcctualRechargedValue;
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
//重写安卓手机端实际充值时间
public String getMobileRechargeDate(){
if(null != acctualRechargedDate){
return sdf.format(acctualRechargedDate);
}
return "";
}
public BigDecimal getSumAcctualRechargedValue() {
return sumAcctualRechargedValue;
}
public void setSumAcctualRechargedValue(BigDecimal sumAcctualRechargedValue) {
this.sumAcctualRechargedValue = sumAcctualRechargedValue;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public long getUserId() {
return userId;
}
public void setUserId(long userId) {
this.userId = userId;
}
public BigDecimal getRechargeValue() {
return rechargeValue;
}
public void setRechargeValue(BigDecimal rechargeValue) {
this.rechargeValue = rechargeValue;
}
public BigDecimal getRechargeFee() {
return rechargeFee;
}
public void setRechargeFee(BigDecimal rechargeFee) {
this.rechargeFee = rechargeFee;
}
public BigDecimal getRechargValue() {
return rechargeValue;
}
public void setRechargValue(BigDecimal rechargValue) {
this.rechargeValue = rechargValue;
}
public String getRechargeSequence() {
return rechargeSequence;
}
public void setRechargeSequence(String rechargeSequence) {
this.rechargeSequence = rechargeSequence;
}
public int getRecharged() {
return recharged;
}
public void setRecharged(int recharged) {
this.recharged = recharged;
}
public BigDecimal getAcctualRechargedValue() {
return acctualRechargedValue;
}
public void setAcctualRechargedValue(BigDecimal acctualRechargedValue) {
this.acctualRechargedValue = acctualRechargedValue;
}
public Date getAcctualRechargedDate() {
return acctualRechargedDate;
}
public void setAcctualRechargedDate(Date acctualRechargedDate) {
this.acctualRechargedDate = acctualRechargedDate;
}
public Timestamp getUpdateTime() {
return updateTime;
}
public void setAcctualRechargedDate(Timestamp acctualRechargedDate) {
this.acctualRechargedDate = acctualRechargedDate;
}
public void setUpdateTime(Timestamp updateTime) {
this.updateTime = updateTime;
}
public String getResponseSequence() {
return responseSequence;
}
public void setResponseSequence(String responseSequence) {
this.responseSequence = responseSequence;
}
public String getReserved() {
return reserved;
}
public void setReserved(String reserved) {
this.reserved = reserved;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getRechargeName(){
return ""+recharged;//1是充值失败;2是充值成功
}
// public String toString()
// {
// return // 用户ID
// userId;
// // 用户真实姓名
// userRealName;
// // 充值金额
// rechargeValue;
// // 充值费用
// rechargeFee;
// // 流水号
// private String rechargeSequence;
//
// // 是否已经到账
// private boolean recharged;
// // 实际划款日期时间
// private Date acctualRechargedDate;
// // 实际划款金额
// private BigDecimal acctualRechargedValue;
// // 更新时间
// private Date updateTime;
// // 第三方支付/银行操作流水号
// private String responseSequence;
// // 预留
// private String reserved;
//
// private BigDecimal sumAcctualRechargedValue;
//
// "rechargeValue:" + rechargeValue + "," +
// "rechargeFee" + rechargeFee + "," +
//
// }
}
3. 通过传递的参数不同,来获取不同的支付平台,在这里我定义了一个抽象类Factory
import cn.company.common.model.Payment;
import cn.company.common.model.BasicUser;
import cn.company.common.model.RechargeDetail;
import cn.company.common.util.AirScapeApplicationContext;
public abstract class PaymentFactory {
public static PaymentFactory getPaymentFactory(int payIndex)
{
//至于AirScapeApplicationContext在上一篇有提到过,这个类的作用就是从spring容器通过beanId提取指定的类
Factory f = null;
switch(payIndex){
case PayConstant.GOPAY:
f = AirScapeApplicationContext.getBean("GuoFuBaoPaymentFactory", PaymentFactory.class);
break;
case PayConstant.ALIPAY:
f = AirScapeApplicationContext.getBean("OtherPaymentFactory", PaymentFactory.class);
break;
case PayConstant.TENPAY:
f = AirScapeApplicationContext.getBean("AnotherPaymentFactory", PaymentFactory.class);
break;
default:
break;
}
return f;
}
public abstract Payment createPayment(int payIndex, BasicUser user, String bankCode,
String clientIP, RechargeDetail rechargeOrder);
//方法参数:payIndex:区分支付平台参数
user:自己平台充值提现的用户信息
bankCode:银行代码(如工商银行代码为:ICBC,在这里有一套统一机制)
rechargeOrder:提现的基本信息(如充值金额、充值利息、充值时间等都封装到该类下)。
}
4. 实现上面接口
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import cn.company.bbd.cooperate.PaymentFactory;
import cn.company.bbd.cooperate.model.Payment;
import cn.company.common.model.BasicUser;
import cn.company.common.model.RechargeDetail;
import cn.company.common.util.CryptoKit;
@Component("GuoFuBaoPaymentFactory")
public class GuoFuBaoPaymentFactory extends PaymentFactory {
@Autowired(required = true)
@Qualifier("GuoFuBaoConfiguration")
private GuoFuBaoConfiguration config;
//public static final String prefix = "gopay.";
//private static final String serverTimeUrl = "https://www.gopay.com.cn/PGServer/time";
//这个本平台发送给国付宝定死的数据(死数据)
public static final String staticParams[] = { "version", "charset", "language",
"signType", "tranCode", "merchantID", "currencyType","isRepeatSubmit",
"frontMerUrl", "backgroundMerUrl", "virCardNoIn", "userType","charsetName",
"VerficationCode","goodsName", "goodsDetail"};
//这个是本平台用户操作产生的充值信息,然后传送给国付宝支付平台的数据(活数据)
public static final String orderParams[] = { "merOrderNum", "tranAmt", "feeAmt",
"tranDateTime", "tranIP", "buyerName","buyerContact", "merRemark1", "merRemark2", "bankCode",
"customerEMail",
"gopayServerTime","signValue" };
private SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
private DecimalFormat df = new DecimalFormat("0.00");
@Override
public Payment createPayment(int payIndex, BasicUser user, String bankCode, String clientIP, RechargeDetail rechargeOrder) {
Payment p = new Payment();
p.setGatewayUrl(config.getGateWay());
p.setMethod("POST");
Map<String, String> map = new HashMap<String, String>();
int idx = 0;
map.put(staticParams[idx++], config.getVersion());
map.put(staticParams[idx++], config.getCharset());
map.put(staticParams[idx++], config.getLanguage());
map.put(staticParams[idx++], config.getSignType());
map.put(staticParams[idx++], config.getTranCode());
map.put(staticParams[idx++], config.getMerchantID());
map.put(staticParams[idx++], config.getCurrencyType());
map.put(staticParams[idx++], config.getIsRepeatSubmit());
map.put(staticParams[idx++], "");
map.put(staticParams[idx++], config.getBackgroundMerUrl()); //force to empty for Browser redirect
map.put(staticParams[idx++], config.getVirCardNoIn());
map.put(staticParams[idx++], config.getUserType());
map.put(staticParams[idx++], config.getCharsetName());
map.put(staticParams[idx++], config.getVerficationCode());
map.put(staticParams[idx++], config.getGoodsName());
map.put(staticParams[idx++], config.getGoodsDetail());
idx = 0;
map.put(orderParams[idx++], rechargeOrder.getRechargeSequence());
map.put(orderParams[idx++], df.format(rechargeOrder.getRechargeValue()));
map.put(orderParams[idx++], df.format(rechargeOrder.getRechargeFee()));
map.put(orderParams[idx++], sdf.format(new Date()));
map.put(orderParams[idx++], clientIP);
map.put(orderParams[idx++], user.getUsername());
map.put(orderParams[idx++], user.getMobile());
map.put(orderParams[idx++], "");
map.put(orderParams[idx++], "");
map.put(orderParams[idx++], bankCode);
map.put(orderParams[idx++], "");
map.put(orderParams[idx++], config.getGopayServerTime());
map.put(orderParams[idx++], caculateSignValue(map));
p.setParamMap(map);
return p;
}
private String caculateSignValue(Map<String, String> params) {
String plain = "version=[" + params.get("version") + "]tranCode=["
+ params.get("tranCode") + "]merchantID=[" + params.get("merchantID")
+ "]merOrderNum=[" + params.get("merOrderNum") + "]tranAmt=["
+ params.get("tranAmt") + "]feeAmt=[" + params.get("feeAmt") + "]tranDateTime=["
+ params.get("tranDateTime") + "]frontMerUrl=[" + params.get("frontMerUrl")
+ "]backgroundMerUrl=[" + params.get("backgroundMerUrl")
+ "]orderId=[]gopayOutOrderId=[]tranIP=[" + params.get("tranIP")
+ "]respCode=[]gopayServerTime=[" + params.get("gopayServerTime")
+ "]VerficationCode=[" + params.get("VerficationCode") + "]";
System.out.println(plain);
String sign = CryptoKit.md5Digest(plain);
System.out.println(sign);
return sign;
}
}
4. 功能:基础配置类
/* *
*类名:GuoFuBaoConfiguration
*功能:基础配置类
*详细:设置帐户有关信息及前后台通知地址
*版本:2.1
*日期:2014-05-27
*说明:
*以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
*该代码仅供学习和研究国付宝接口使用,只是提供一个参考。
*/
public class GuoFuBaoConfiguration {
// version=[2.1]tranCode=[]merchantID=[0000075851]merOrderNum=[18]tranAmt=[1600.00]feeAmt=[5.60]tranDateTime=[20131121105823]frontMerUrl=[http://www.richbridge.cn/bbdai/callback/RechargeCallback.jsf]backgroundMerUrl=[http://www.richbridge.cn/bbdai/callback/RechargeCallback.jsf]orderId=[]gopayOutOrderId=[]tranIP=[0:0:0:0:0:0:0:1]respCode=[]gopayServerTime=[https://www.gopay.com.cn/PGServer/time]VerficationCode=[57275929]
// 国付宝提供给商户调试的网关地址
private String gateWay = "https://www.gopay.com.cn/PGServer/Trans/WebClientAction.do";
//网关版本号
private String version = "";
//字符集
private String charset = "";
//网关语言版本
private String language = "";
//报文加密方式
private String signType = "";
// 交易代码
private String tranCode = "";
// 商户ID
private String merchantID = "";
// 订单号
private String merOrderNum = "";
// 交易金额
private String tranAmt = "";
// 手续费
private String feeAmt = "";
//货币种类
private String currencyType = "";
// 商户返回页面地址
private String frontMerUrl = "";
// 商户后台通知地址
private String backgroundMerUrl ="";
private String callbackUrl="";
// 交易时间
private String tranDateTime = "";
// 国付宝转入账户
private String virCardNoIn = "";
// 用户浏览器IP
private String tranIP = "";
// 订单是否允许重复提交
private String isRepeatSubmit = "0";
//商品名字
private String goodsName = "";
//商品详情
private String goodsDetail = "";
// 买方姓名
private String buyerName = "";
// 买方联系方式
private String buyerContact = "";
// 商户备用信息字段1
private String merRemark1 = "";
// 商户备用信息字段2
private String merRemark2 = "";
// 银行代码
private String bankCode = "";
// 用户类型
private String userType = "1";
//商户验证
private String VerficationCode = "" ;
// MD5加密报文
private String signValue = "";
// 国付宝服务器时间
private String gopayServerTime = "";
// 商户QQ
private String customerEMail = "zehui.huang@richbridge.cn";
// 商户账户号
private String virCardNo = "0000000001000000584";
// 字符编码格式,目前支持 GBK 或 UTF-8
private String charsetName = "UTF-8";
// 国付宝服务器时间,反钓鱼时使用
private String serverTime = "https://www.gopay.com.cn/PGServer/time";
public String getMerchantID() {
return merchantID;
}
public void setMerchantID(String merchantID) {
this.merchantID = merchantID;
}
public String getCustomerEMail() {
return customerEMail;
}
public void setCustomerEMail(String customerEMail) {
this.customerEMail = customerEMail;
}
public String getVirCardNo() {
return virCardNo;
}
public void setVirCardNo(String virCardNo) {
this.virCardNo = virCardNo;
}
public String getVirCardNoIn() {
return virCardNoIn;
}
public void setVirCardNoIn(String virCardNoIn) {
this.virCardNoIn = virCardNoIn;
}
public String getGateWay() {
return gateWay;
}
public void setGateWay(String gateWay) {
this.gateWay = gateWay;
}
public String getServerTime() {
return serverTime;
}
public void setServerTime(String serverTime) {
this.serverTime = serverTime;
}
public String getCharset() {
return charset;
}
public void setCharset(String charset) {
this.charset = charset;
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getSignType() {
return signType;
}
public void setSignType(String signType) {
this.signType = signType;
}
public String getCurrencyType() {
return currencyType;
}
public void setCurrencyType(String currencyType) {
this.currencyType = currencyType;
}
public String getGoodsName() {
return goodsName;
}
public void setGoodsName(String goodsName) {
this.goodsName = goodsName;
}
public String getGoodsDetail() {
return goodsDetail;
}
public void setGoodsDetail(String goodsDetail) {
this.goodsDetail = goodsDetail;
}
public String getCharsetName() {
return charsetName;
}
public void setCharsetName(String charsetName) {
this.charsetName = charsetName;
}
public String getTranCode() {
return tranCode;
}
public void setTranCode(String tranCode) {
this.tranCode = tranCode;
}
public String getMerOrderNum() {
return merOrderNum;
}
public void setMerOrderNum(String merOrderNum) {
this.merOrderNum = merOrderNum;
}
public String getTranAmt() {
return tranAmt;
}
public void setTranAmt(String tranAmt) {
this.tranAmt = tranAmt;
}
public String getFeeAmt() {
return feeAmt;
}
public void setFeeAmt(String feeAmt) {
this.feeAmt = feeAmt;
}
public String getFrontMerUrl() {
return frontMerUrl;
}
public void setFrontMerUrl(String frontMerUrl) {
this.frontMerUrl = frontMerUrl;
}
public String getBackgroundMerUrl() {
return backgroundMerUrl;
}
public void setBackgroundMerUrl(String backgroundMerUrl) {
this.backgroundMerUrl = backgroundMerUrl;
}
public String getTranDateTime() {
return tranDateTime;
}
public void setTranDateTime(String tranDateTime) {
this.tranDateTime = tranDateTime;
}
public String getTranIP() {
return tranIP;
}
public void setTranIP(String tranIP) {
this.tranIP = tranIP;
}
public String getIsRepeatSubmit() {
return isRepeatSubmit;
}
public void setIsRepeatSubmit(String isRepeatSubmit) {
this.isRepeatSubmit = isRepeatSubmit;
}
public String getBuyerName() {
return buyerName;
}
public void setBuyerName(String buyerName) {
this.buyerName = buyerName;
}
public String getBuyerContact() {
return buyerContact;
}
public void setBuyerContact(String buyerContact) {
this.buyerContact = buyerContact;
}
public String getMerRemark1() {
return merRemark1;
}
public void setMerRemark1(String merRemark1) {
this.merRemark1 = merRemark1;
}
public String getMerRemark2() {
return merRemark2;
}
public void setMerRemark2(String merRemark2) {
this.merRemark2 = merRemark2;
}
public String getBankCode() {
return bankCode;
}
public void setBankCode(String bankCode) {
this.bankCode = bankCode;
}
public String getUserType() {
return userType;
}
public void setUserType(String userType) {
this.userType = userType;
}
public String getVerficationCode() {
return VerficationCode;
}
public void setVerficationCode(String verficationCode) {
VerficationCode = verficationCode;
}
public String getSignValue() {
return signValue;
}
public void setSignValue(String signValue) {
this.signValue = signValue;
}
public String getGopayServerTime() {
return gopayServerTime;
}
public void setGopayServerTime(String gopayServerTime) {
this.gopayServerTime = gopayServerTime;
}
public String getCallbackUrl() {
return callbackUrl;
}
public void setCallbackUrl(String callbackUrl) {
this.callbackUrl = callbackUrl;
}
}
5、提现操作类
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import cn.company.bbd.cooperate.PaymentFactory;
import cn.company.bbd.cooperate.model.Parameter;
import cn.company.bbd.cooperate.model.Payment;
import cn.company.common.model.BasicUser;
import cn.company.common.model.RechargeDetail;
import cn.company.common.util.RequestUtil;
@Controller("RechargeBean")
@Scope("session")
public class RechargeController implements Serializable {
public static final String pageParams[] = { "version", "charset", "language",
"signType", "tranCode", "merchantID","merOrderNum","tranAmt", "feeAmt",
"currencyType", "frontMerUrl", "backgroundMerUrl","tranDateTime","virCardNoIn",
"tranIP","isRepeatSubmit","goodsName", "goodsDetail", "buyerName","buyerContact",
"merRemark1", "merRemark2",
"bankCode","userType","signValue","gopayServerTime"};
private static final Logger log = Logger
.getLogger(RechargeController.class);
private String bankCode = "ICBC";
private RechargeDetail recharge;
private Payment payment = null;
private List<Parameter> parameters;
public RechargeController()
{
recharge = new RechargeDetail();
recharge.setRechargeValue(BigDecimal.valueOf(1000));
}
//提交充值方法
public String submit() {
//实际应该是从数据库中调用,在这里就简单的new出来一个
BasicUser bu= new BasicUser();
//确定第三方支付 先固定为国付宝,后续灵活调整
int payIndex = 1;
//生成并记录充值订单
String merOrderNum = "111111111111111111111";
recharge = createRechargeOrder(merOrderNum, payIndex);
//生成第三方支付数据
PaymentFactory pf = PaymentFactory.getPaymentFactory(payIndex);
payment = pf.createPayment(payIndex, bu, bankCode, RequestUtil.getClientIP(), recharge);
parameters = new ArrayList<Parameter>();
Map<String, String> map = payment.getParamMap();
for (String param : pageParams)
{
String val = map.get(param);
if (param.equals("gopayServerTime"))
val = "https://www.gopay.com.cn/PGServer/time";
Parameter pm = new Parameter(param, val);
parameters.add(pm);
}
return "";//可以根据不同的字符串返回不用的界面
}
private RechargeDetail createRechargeOrder(String merOrderNum, int payIndex) {
//这里应该是从数据库中查询出来的,在这里就实例化然后赋值。。。
BasicUser user = new BasicUser();
//给user赋值........
recharge.setId(10000);
recharge.setUserId(user.getUserId());
recharge.setUserName(user.getUsername());
// recharge.setRechargeValue(rechargeValue);
recharge.setRecharged(1);
BigDecimal fee = null;//这里要加入自己平台收取费用的计算,后面跟方法,在这里没做处理
recharge.setRechargeFee(fee);
recharge.setRechargeSequence(merOrderNum);
return recharge;
}
public RechargeDetail getRecharge() {
return recharge;
}
public void setRecharge(RechargeDetail recharge) {
this.recharge = recharge;
}
public Payment getPayment() {
return payment;
}
public List< Parameter> getParameters()
{
return this.parameters;
}
public String getBankCode() {
return bankCode;
}
public void setBankCode(String bankCode) {
this.bankCode = bankCode;
}
}
6、页面
待完成.....................