Struts2实现财付通、支付宝、网银……

在线支付听起来是比较唬人,会吓到一片初学者,本人也曾是其中之一~~不过,只要认真研究平台提供的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或发邮件 ,一起讨论讨论在线支付!!说实在,我上面的方法实在不咋地!!

2 条评论。

  1. grandpashabet - trackback on 2024 年 3 月 10 日 在 上午 8:36
  2. grandpashabet - trackback on 2024 年 3 月 19 日 在 上午 4:55

Trackbacks and Pingbacks: