在线支付听起来是比较唬人,会吓到一片初学者,本人也曾是其中之一~~不过,只要认真研究平台提供的API和实例,就会发现在线支付不难~~
一般在线支付平台都已经封装的很好了!我们程序员所要做的只是实现接口对接而已!!
一般的在线支付都主要是2部分!!
1、请求(即把支付金额,支付帐户等相关信息给支付平台)
2、回调处理(在用户支付以后,支付平台会把相关信息又返回给本地系统,我们程序员要做的就是处理好这个步骤!)
下面我拿财付通做实例!实现下struts2+财付通 实现在线支付,strut2的相关配置就不做说明了!有兴趣的朋友可以去买本《struts2权威指南》看看,挺适合初学者的~
由于我要为后期实现各类支付方式打下基础。所以这里我会先写一个父类~封装一些商品通用属性。
import java.util.Map; import com.ecfront.util.Constants; import com.ecfront.util.DateFormat; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.Preparable; /** * 支付请求action * @author ZhuFeng */ public class PayAction extends ActionSupport implements Preparable { protected Object uId;// 用户ID protected Integer userId;// 用户ID protected long payId;// 订单ID /* 初始化用户ID */ public void prepare() throws Exception { Map sessions = ActionContext.getContext().getSession(); uId = sessions.get(Constants.USER_ID); if (uId != null) { userId = Integer.valueOf(uId.toString()); } } //省略set、get }
这里是简单的把支付的订单ID、系统内部用户的ID、做了封装~
下面是财付通的请求action
import javax.servlet.http.HttpServletRequest; import org.apache.struts2.interceptor.ServletRequestAware; import com.ecfront.pojo.Pay; import com.ecfront.service.PayService; import com.ecfront.util.Constants; import com.ecfront.util.PriceFormat; import com.opensymphony.xwork2.ActionSupport; import com.tenpay.bean.PayRequest; import com.tenpay.bean.PayResponse; import com.tenpay.helper.PayRequestHelper; import com.tenpay.helper.PayResponseHelper; import com.tenpay.util.TenpayUtil; /** * 财付通接口连接action * @author ZhuFeng */ public class TenPayAction extends PayAction implements ServletRequestAware { private HttpServletRequest request;// 请求环境变量 private PayService payService;//注入订单服务层 private String bargainor_id; // 商户号 private String key; // 密钥 private String return_url; // 回调地址 private String sendUrl;//请求网关转发地址,因为struts2基于请求转发模式,此处利用jsp界面进行财付通网关的转发 /*支付请求,封装了订单的相关信息*/ public String request() { Pay pay = payService.getUserPay(userId, payId); String currTime = TenpayUtil.getCurrTime(); String strRandom = TenpayUtil.buildRandom(4) + ""; PayRequest payRequest = new PayRequest(); payRequest.setAttach(String.valueOf(pay.getId()));// 自定义串,原样返回 存放订单ID payRequest.setBank_type("0"); // 银行类型 0:财付通 payRequest.setBargainor_id(bargainor_id); // 商户号 payRequest.setCmdno("1");// 任务代码 支付为1 payRequest.setDate(currTime.substring(0, 8));// 商户日期 yyyyMMdd payRequest.setDesc("动脉商城(" + pay.getId() + ")");// 商品名称,以“动脉商城(订单编号)”为值 payRequest.setFee_type("1");// 现金支付币种 1:人民币 其它币种暂不支持 payRequest.setPurchaser_id("");// 买家财付通帐号,可以留空 payRequest.setReturn_url(return_url);// 回调URL payRequest.setSp_billno(currTime + strRandom);// 商户订单号 payRequest.setTotal_fee(pay.getPrice());// 订单总价,以分为单位 payRequest.setTransaction_id(bargainor_id + currTime + strRandom);// 财付通交易单号 String ip = TenpayUtil.toString(request.getRemoteAddr());// ip设置 payRequest.setSpbill_create_ip(ip); PayRequestHelper helper = new PayRequestHelper(key, payRequest); sendUrl = helper.getSendUrl(); return SUCCESS; } /*支付回调处理,对于正确支付则调用相应的业务逻辑,否则返回失败界面*/ public String handler() { PayResponseHelper helper = new PayResponseHelper(); helper.setKey(key); helper.setPayResponse(request); PayResponse payResponse = helper.getPayResponse(); if ("0".equals(payResponse.getPay_result())) { // 支付成功,注意判断交易单重复性 payService.modifPayOnline( Long.valueOf(payResponse.getAttach()), Constants.PAY_CAIFU, "", payResponse.getTotal_fee()); // 注意金额问题,财付通以分为单位 return SUCCESS; } return INPUT; }
注意下面几个属性~除了sendUrl以为,我都采用了IOC的方式,通过配置文件注入~(采用了spring做粘合)
bargainor_id; // 商户号 财付通申请的时候给你的
key; // 密钥
return_url; // 回调地址 这里相当重要,必须是一个http的绝对路径,最好是IP路径
sendUrl;//此处是一点小技巧,也是struts2实现的关键所在,用于把最后提交的地址保存到这个变量里面去!
下面是配置的相关信息!
<action name="tenpay_request" class="tenPayAction" method="request"> <result>../Pages/Buy/request.jsp</result> </action> <action name="tenpay_handler" class="tenPayAction" method="handler"> <result type="redirect-action">../UserManager/mypay.action</result> </action>
tenpay_request.action是用于请求的路径~调用商品的request方法,把sendUrl提交给../pages/Buy/request.jsp页面~~这个页面里面就二句代码~~
<%
String obj = pageContext.getAttribute("sendUrl").toString();
response.sendRedirect(obj);
%>
就是把前面拼凑的sendUrl转向而已!
下面是请求处理,即交付款项以后,本地系统要做的事情~
本人的一点粗浅建议~可以分为2部~
1、对返回的数据包的数据提取重要信息,比如前面,我提交的时候,把订单的ID放到了自定义属性里面去。这时候我们要做的就是把这个订单ID拿回来
2、比对订单信息~上面拿回订单ID以后~在自己系统里面查找该ID符合的订单,并且比对该订单应付款和转向回来已付款~~如果都是正确的,则可以把该订单给完结~~否则,哪怕差1分钱,都放弃完成订单~~
有点乱~~~~算是给自己做个笔记,有兴趣的朋友在我博客首页加我QQ或发邮件 ,一起讨论讨论在线支付!!说实在,我上面的方法实在不咋地!!
评论关闭。