java服务器端移动银联支付的流程

一,银联支付的整体流程

客户端提供服务器给服务器订单信息----服务器端拿到数据推送给银联指定的地址----银联给服务器端返回一个流水账号----服务器将流水账号返给客户端
----客户端由于集成了银联控件,根据流水账号调用银联支付界面进行支付----支付完成之后银联会回调服务器端提供的回调地址----服务器端根据回调参数处理业务逻辑

二,服务器端主要代码解析.

upmp.properties

security.key=******//银联技术给我们提供的商户密钥
mer.id=88000000000***** //商户的银联账号

mer.back.end.url=/servlet/unionpaycallback//支付成功后银联的回调地址
mer.front.end.url=http://www.yourdomain.com/your_path/yourFrontEndUrl//支付成功后银联回调的前段地址,可不填

# message info
version=1.0.0//版本号
charset=UTF-8//编码
sign.method=MD5//加密方法

# server url
upmp.trade.url=http://222.66.233.198:8080/gateway/merchant/trade//处理交易请求的银联地址
upmp.query.url=http://222.66.233.198:8080/gateway/merchant/query//查询交易的银联地址

card=6226440123456785//银联提供的测试账户
password=111101//银联提供的测试密码

 下面是给银联推送订单的代码.
/**
  * 银联支付推送给银联
  */
 public String executeUnionPayMoney(String auth, String info, String basePath) {
  //returnMap--返回的Map
  //returnParams--定义的参数返回类型
  Map<String,Object> returnMap = new HashMap<String,Object>();
  String result ="";
  try{
   //把info中的信息解析成map
   @SuppressWarnings("unchecked")
   Map<String,Object> map = JSON.parseObject(info, Map.class);
   OrderDao orderDao = (OrderDao) ac.getBean("orderDao");
   if(map.get("order_id")!=null&&!map.get("order_id").equals("")&&
     map.get("user_id")!=null&&!map.get("user_id").equals("")&&
     map.get("payMoney")!=null&&!map.get("payMoney").equals("")){
    //把订单数据推给银联(订单推送接口),根据返回结果是否为true
    Order order = orderDao.getById(Long.valueOf(map.get("order_id").toString()));
    Map<String, String> req = new HashMap<String, String>();
    Map<String, String> reqReservedMap = new HashMap<String, String>();
       reqReservedMap.put("user_id", map.get("user_id").toString());
       reqReservedMap.put("order_id", map.get("order_id").toString());
       reqReservedMap.put("opt", "0");//自己自定义的参数,把Map转换成json字符串,通过请求方保留域reqReserved传递给银联,方便银联回调服务器时,服务器处理业务逻辑使用
    req.put("version", UpmpConfig.VERSION);// 版本号
    req.put("charset", UpmpConfig.CHARSET);// 字符编码
    req.put("transType", "01");// 交易类型
    req.put("merId", UpmpConfig.MER_ID);// 商户代码
    //req.put("backEndUrl",basePath.substring(0, basePath.length()-1) + UpmpConfig.MER_BACK_END_URL);// 通知URL
    req.put("backEndUrl",basePath.substring(0, basePath.length()-1) + UpmpConfig.MER_BACK_END_URL);// 通知URL  我自己提供给银联支付成功后的回调地址
    req.put("frontEndUrl", UpmpConfig.MER_FRONT_END_URL);// 前台通知URL(可选)
    req.put("orderDescription", "航空机票付款");// 订单描述(可选)
    req.put("orderTime", new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()));// 交易开始日期时间yyyyMMddHHmmss
    req.put("orderTimeout", "");// 订单超时时间yyyyMMddHHmmss(可选);默认的是一小时
    req.put("orderNumber", orderDao.getById(Long.valueOf(map.get("order_id").toString())).getOrderNum());//订单号(商户根据自己需要生成订单号)
    req.put("orderAmount", Integer.valueOf(map.get("payMoney").toString())*100+"");// 订单金额;因为这里默认的单位是分,而通常客户端传过来的单位是元,所以需要再此
//处进行*100的操作,防止因为单位换算导致支付出现问题,需要注意的是:银联回调时你如果从回调的参数中拿settleAmount,记得进行除100的操作
          req.put("orderCurrency", "156");// 交易币种(可选) 156代表人民币
          req.put("reqReserved", new Gson().toJson(reqReservedMap));// 请求方保留域(可选,用于透传商户信息)//此处用于传递咱们自己的参数,可以再银联回调时使用,
//此处我是以json字符串的方式传递参数的,之后解析json字符串即可获取相关参数.

    Map<String, String> resp = new HashMap<String, String>();
    boolean validResp = UpmpService.trade(req, resp);
   if(order.getPayState()==0){
    returnMap.put("errcode",-98);
    returnMap.put("msg","该订单已支付");
   }else{
          // 商户的业务逻辑
          if (validResp){
              // 服务器应答签名验证成功
           returnMap.put("tn", resp.get("tn"));//交易流水号,默认的参数就是tn
           returnMap.put("errcode",0);
     returnMap.put("msg","成功返回流水号");
          }else {
              // 服务器应答签名验证失败
           returnMap.put("errcode",-100);
     returnMap.put("msg","系统出错");
          }
   }
   }else {
    returnMap.put("errcode",-9);
    returnMap.put("msg","传值错误");
   }
   
  }catch (Exception e) {
   e.printStackTrace();
   returnMap.put("errcode",-99);
   returnMap.put("msg","服务器出现异常");
  }
  result=JSON.toJSONString(returnMap);
  return result;
 }

CallBackUnionPay.java
这个是我自己写的一个银联回调的servlet,opt为自定义参数,opt=0代表支付订单,opt=1代表充值操作

/**
 * Alipay.com Inc.
 * Copyright (c) 2005-2008 All Rights Reserved.
 */
package com.unionpay.upmp.sdk.callback;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.airplane.base.AbstractExecution;
import com.airplane.dao.AccountDao;
import com.airplane.dao.IntegralDao;
import com.airplane.dao.OrderDao;
import com.airplane.dao.UserDao;
import com.airplane.domain.Account;
import com.airplane.domain.Integral;
import com.airplane.domain.Order;
import com.airplane.domain.User;
import com.google.gson.Gson;
import com.unionpay.upmp.sdk.service.UpmpService;

/**
 * 接收通知并处理
 * 
 * @author gxw
 */
public class CallBackUnionPay extends HttpServlet {


    private static final long                          serialVersionUID = 7216412938937049671L;
    private static Log logger = LogFactory.getLog(CallBackUnionPay.class);

    @SuppressWarnings("unchecked")
 public void doPost(HttpServletRequest request, HttpServletResponse response){
     logger.info("==============================here===========================");
     System.out.println("接收到通知!");
     PrintWriter out;
  try {
   out = response.getWriter();
     Map<String,String> params = new HashMap<String,String>();
     Map requestParams = request.getParameterMap();
     logger.info("request的参数:"+requestParams);
     for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
      String name = (String) iter.next();
      String[] values = (String[]) requestParams.get(name);
      String valueStr = "";
      for (int i = 0; i < values.length; i++) {
       valueStr = (i == values.length - 1) ? valueStr + values[i]
         : valueStr + values[i] + ",";
      }
      params.put(name, valueStr);
     }
     logger.info("request处理后的参数:"+params);
     Map<String,String> personParams = new Gson().fromJson(params.get("reqReserved"), Map.class);//解析在上一步自定义的json参数,方便处理业务逻辑.
     if(UpmpService.verifySignature(params)){// 服务器签名验证成功
      //请在这里加上商户的业务逻辑程序代码
        if("0".equals(personParams.get("opt"))){
   String user_id = personParams.get("user_id");
   String order_id = personParams.get("order_id");
   logger.info("user_id"+user_id+"&order_id="+order_id);
      //获取通知返回参数,可参考接口文档中通知参数列表(以下仅供参考)
      String transStatus = request.getParameter("transStatus");// 交易状态
      if (null != transStatus && transStatus.equals("00")) {
          // 交易处理成功
     }
      out.println("success");
     }
     if("1".equals(personParams.get("opt"))){
   String payMoney2 = params.get("settleAmount");
   String user_id2 = personParams.get("user_id");
      //获取通知返回参数,可参考接口文档中通知参数列表(以下仅供参考)
      String transStatus2 = request.getParameter("transStatus");// 交易状态
      if (null != transStatus2 && transStatus2.equals("00")) {
          // 交易处理成功
      }
      out.println("success");
     }
     else{// 服务器签名验证失败
      out.println("fail");
     }
     }
     
  }catch (IOException e) {
   e.printStackTrace();
   logger.error(e);
  }
    }
    /*public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
     doPost(request, response);
 }*/

}



转载地址:

http://www.blogjava.net/g710246442/articles/404373.html

发布了99 篇原创文章 · 获赞 22 · 访问量 58万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览