亚洲国产一区二区视频,依依综合在线,这里只有精品在线http://www.aygfsteel.com/g710246442/category/54441.html向javaEE前進zh-cnWed, 23 Jul 2014 14:44:22 GMTWed, 23 Jul 2014 14:44:22 GMT60java服務器端移動銀聯支付的流程http://www.aygfsteel.com/g710246442/articles/404373.html龔小偉龔小偉Tue, 24 Sep 2013 06:47:00 GMThttp://www.aygfsteel.com/g710246442/articles/404373.htmlhttp://www.aygfsteel.com/g710246442/comments/404373.htmlhttp://www.aygfsteel.com/g710246442/articles/404373.html#Feedback3http://www.aygfsteel.com/g710246442/comments/commentRss/404373.htmlhttp://www.aygfsteel.com/g710246442/services/trackbacks/404373.html一,銀聯支付的整體流程

客戶端提供服務器給服務器訂單信息----服務器端拿到數據推送給銀聯指定的地址----銀聯給服務器端返回一個流水賬號----服務器將流水賬號返給客戶端
----客戶端由于集成了銀聯控件,根據流水賬號調用銀聯支付界面進行支付----支付完成之后銀聯會回調服務器端提供的回調地址----服務器端根據回調參數處理業務邏輯

二,服務器端主要代碼解析.

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);
 }*/
}

 



龔小偉 2013-09-24 14:47 發表評論
]]>
支付寶快捷支付(安卓版)的服務器開發流程http://www.aygfsteel.com/g710246442/articles/402797.html龔小偉龔小偉Wed, 14 Aug 2013 06:12:00 GMThttp://www.aygfsteel.com/g710246442/articles/402797.htmlhttp://www.aygfsteel.com/g710246442/comments/402797.htmlhttp://www.aygfsteel.com/g710246442/articles/402797.html#Feedback2http://www.aygfsteel.com/g710246442/comments/commentRss/402797.htmlhttp://www.aygfsteel.com/g710246442/services/trackbacks/402797.html 1 package com.alipay.client.base;
 2 
 3 public class PartnerConfig {
 4     
 5     //合作商戶ID。用簽約支付寶賬號登錄ms.alipay.com后,在賬戶信息頁面獲取。
 6     public static final String PARTNER = "2088011096718773";
 7     // 賬戶ID。用簽約支付寶賬號登錄ms.alipay.com后,在賬戶信息頁面獲取。
 8     public static final String SELLER = "2088011096718773";
 9     // 商戶(RSA)私鑰
10     public static final String RSA_PRIVATE = "";
11                                                     
12     // 支付寶(RSA)公鑰 用簽約支付寶賬號登錄ms.alipay.com后,在密鑰管理頁面獲取。
13     public static final String RSA_ALIPAY_PUBLIC = "";
14     
15 }PartnerConfig.java為封裝商家提供的屬性類,參數全部由商戶提供或者技術生成
PARTNER 與
SELLER 為商戶提供的pid,可以再支付寶ms.alipay.com查看.
RSA_PRIVATE為支付寶提供的openssl-0.9.8k_WIN32(RSA密鑰生成工具)生成商戶私鑰.根據商戶私鑰生成商戶公鑰(RSA密鑰生成工具),把商戶公鑰在支付寶的私鑰管理頁面進行提交,支付寶會為商戶提供一個支付寶公鑰既RSA_ALIPAY_PUBLIC字段的值

package com.alipay.client.callback;

import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;

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

import com.alipay.client.base.PartnerConfig;
import com.alipay.client.security.RSASignature;

/**
 * 安全支付支付完成商戶同步處理程序
 * 對支付寶返回訂單信息驗簽名
 
*/
public class RSACallBack extends HttpServlet {


    private static final long serialVersionUID = -2234271646410251381L;
    
    //簽名成功
    public static final String RESULT_CHECK_SIGN_SUCCEED  = "T";
    //簽名失敗
    public static final String RESULT_CHECK_SIGN_FAILED = "F";
    
    @SuppressWarnings("unchecked")
    public void doPost(HttpServletRequest request, HttpServletResponse response)throws UnsupportedEncodingException {
        //獲得待簽名數據和簽名值
        String sign = URLDecoder.decode(request.getParameter("sign"),"utf-8");
        String content = URLDecoder.decode(request.getParameter("content"),"utf-8");
        
        String retVal = RESULT_CHECK_SIGN_FAILED;
        //使用支付寶公鑰驗簽名
        try {
            PrintWriter out = response.getWriter();
            if(RSASignature.doCheck(content, sign, PartnerConfig.RSA_ALIPAY_PUBLIC)){
                retVal=RESULT_CHECK_SIGN_SUCCEED;
            }
            
            response.setContentType("text/html");   
            System.out.println("retVal : " + retVal);
            out.print(retVal);
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("驗簽名失敗");
        }

    }
}
這個類基本不需要做修改,主要是RESULT_CHECK_SIGN_SUCCEED和RESULT_CHECK_SIGN_FAILED的值必須要與客戶端相應代碼的相應字段保持一致.這個類主要是支付完成之后客戶端與服務器進行的一次驗簽名,可以用來更新數據給客戶端.
/**
 * Alipay.com Inc.
 * Copyright (c) 2005-2008 All Rights Reserved.
 
*/
package com.alipay.client.notify;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
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.IntegralDao;
import com.airplane.dao.OrderDao;
import com.airplane.dao.UserDao;
import com.airplane.domain.Integral;
import com.airplane.domain.Order;
import com.airplane.domain.User;
import com.alipay.client.base.PartnerConfig;
import com.alipay.client.security.RSASignature;

/**
 * 接收通知并處理
 * 
 * 
@author 3y
 * 
@version $Id: NotifyReceiver.java, v 0.1 2011-8-15 下午03:11:58 3y Exp $
 
*/
public class RSANotifyReceiver extends HttpServlet {


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

    @SuppressWarnings("unchecked")
    public void doPost(HttpServletRequest request, HttpServletResponse response){
        System.out.println("接收到通知!");
        //獲得通知參數
        try{
        Map map = request.getParameterMap();
        //獲得通知簽名
        String sign = (String) ((Object[]) map.get("sign"))[0];
        logger.info("sign="+sign);
        //獲得待驗簽名的數據
        String verifyData = getVerifyData(map);
        logger.info("verifyData="+verifyData);
        boolean verified = false;
        //使用支付寶公鑰驗簽名
        try {
            verified = RSASignature.doCheck(verifyData, sign, PartnerConfig.RSA_ALIPAY_PUBLIC);
            logger.info("verified="+verified);
        } catch (Exception e) {
            e.printStackTrace();
        }
        PrintWriter out = response.getWriter();
        //驗證簽名通過
        if (verified) {
            //根據交易狀態處理業務邏輯
            
//當交易狀態成功,處理業務邏輯成功。回寫success
                    logger.info("支付寶支付:保存數據庫信息success");
                    out.print("success");
                }else{
                    out.print("fail");
                }
            }
                
            }else{
                out.print("fail");
            }
        } else {
            System.out.println("接收支付寶系統通知驗證簽名失敗,請檢查!");
            out.print("fail");
        }
        }catch (Exception e) {
            e.printStackTrace();
            logger.info(e);
        }
    }

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
        doPost(request, response);
    }

    /**
     * 獲得驗簽名的數據
     * 
@param map
     * 
@return
     * 
@throws Exception 
     
*/
    @SuppressWarnings("unchecked")
    private String getVerifyData(Map map) {
        String notify_data = (String) ((Object[]) map.get("notify_data"))[0];
        logger.info(notify_data);
        return "notify_data="+notify_data;
    }
}
RSANotifyReceiver.java是支付寶回調服務器的servlet,需要安卓客戶端傳遞該servlet地址及相關參數給支付寶,支付寶會在支付完成之后進行回調.回調之后會返回消息給支付寶.
/**
 * Alipay.com Inc.
 * Copyright (c) 2005-2008 All Rights Reserved.
 
*/
package com.alipay.client.trade;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.Security;

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 org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.airplane.action.BackStageAction;
import com.alipay.client.base.PartnerConfig;
import com.alipay.client.security.RSASignature;
import com.alipay.client.util.StringUtil;

/**
 * 
 * 安全支付服務器端處理程序
 * 
 * 1.將業務參數:合作商戶ID、 外部交易號、商品名稱、商品的具體描述、商品總價、賣家帳戶、notify_url這些參數按照固定順序簽名
 * 2.將簽名結果返回客戶端
 * 
@author 3Y
 
*/
public class RSATrade extends HttpServlet {

    private static final long serialVersionUID = -3035307235076650766L;
    private static Log logger = LogFactory.getLog(RSATrade.class);
    static {
          Security.addProvider(new BouncyCastleProvider());
       }
    String basePath="";
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        System.out.println("request in");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        logger.info("here");
        //得到應用服務器地址
        String path = request.getContextPath();
        basePath = request.getScheme() + "://" + request.getLocalAddr() + ":"
                                   + request.getServerPort() + path + "/";
        logger.info("here1");
        String strReString="";
        //檢查商戶PartnerConfig.java文件的配置參數
        logger.info(checkInfo());
        if(!checkInfo()){
            strReString="<result><is_success>F</is_success><error>缺少partner或者seller," +
                    "請在com/alipay/client/base/PartnerConfig.java中增加</error></result>";
            out.print(strReString);
            return;
        }
        
        String signData=getSignDate(request);
        String sign = sign(signData,PartnerConfig.RSA_PRIVATE);
        signData = URLEncoder.encode(signData,"utf-8");
         sign = URLEncoder.encode(sign,"utf-8");
        logger.info(signData);
        logger.info(sign);
        //返回待簽名數據和簽名數據
        strReString="<result><is_success>T</is_success><content>"+signData+"</content><sign>"+sign+"</sign></result>";
        logger.info(strReString);
        //對返回客戶端的數據encode
        out.print(strReString); 
        return;
    }
    
    

    //檢查商戶PartnerConfig.java文件的配置參數
    private boolean checkInfo() {
        String partner = PartnerConfig.PARTNER;
        String seller = PartnerConfig.SELLER;
        //如果合作商戶ID為空或者賬號ID為空返回false
        if (StringUtil.isBlank(partner) || StringUtil.isBlank(seller))
            return false;
        
        return true;
    }
    
    
    /**
     * 準備待簽名的數據
     * 
     * 
@param request
     * 
@return
     * 
@throws UnsupportedEncodingException
     
*/
    private String getSignDate(
            HttpServletRequest request) throws UnsupportedEncodingException {
        request.setCharacterEncoding("utf-8");
        
        //合作商戶ID
        String partner = PartnerConfig.PARTNER;
        //賣家帳號
        String seller = PartnerConfig.SELLER;
     // 外部交易號 這里取當前時間,商戶可根據自己的情況修改此參數,但保證唯一性
        String outTradeNo = System.currentTimeMillis() + "";
        String opt = request.getParameter("opt").trim();
        String user_id = request.getParameter("user_id").trim();
        //opt:0為支付,1為充值
        if("0".equals(opt)){
            outTradeNo = request.getParameter("order_id").trim();
        }else if("1".equals(opt)){
            outTradeNo = System.currentTimeMillis() + "";
        }
        
        // 商品名稱
        String subject = request.getParameter("subject").trim();
        // 商品具體描述
        String body = request.getParameter("body").trim();
        // 商品總價
        String totalFee = request.getParameter("total_fee").trim();
        // 接收支付寶發送的通知的url 商戶可根據自己的情況修改此參數
        String notify_url = basePath+"servlet/RSANotifyReceiver?opt=" + opt +"&order_id="+outTradeNo+"&user_id="+user_id+"&payMoney="+totalFee;
        
        //組裝待簽名數據
        String signData = "partner=" + "\"" + partner + "\"";
        signData += "&";
        signData += "seller=" + "\"" + seller + "\"";
        signData += "&";
        signData += "out_trade_no=" + "\"" + outTradeNo + "\"";
        signData += "&";
        signData += "subject=" + "\"" + subject+ "\"";
        signData += "&";
        signData += "body=" + "\"" + body + "\"";
        signData += "&";
        signData += "total_fee=" + "\""+ totalFee + "\"";
        signData += "&";
        signData += "notify_url=" + "\""+notify_url+ "\"";
        return signData;
    }

    
    
    /**
     * 對參數進行簽名
     * 
     * 
@param signData 待簽名數據,key rsa商戶私鑰
     * 
@return
     
*/
    private String sign(String signData,String key) {
        System.out.println("signData:"+signData);
        String sign = "";
        try {
            sign = RSASignature.sign(signData, key);
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        return sign;
    }

    
}
RSATrade.java為客戶端與服務器端為商品信息進行的簽名操作,簽名完成之后服務器會將簽名信息以及回調地址返給客戶端.客戶端拿到回調地址交給支付寶進行回調.
支付寶流程為:客戶端在支付寶支付之前請求RSATrade.java,此時服務器為商品信息注冊簽名,簽名完成之后服務器把簽名過的商品信息和支付寶的回調地址(RSANotifyReceiver
)和參數傳給客戶端,客戶端會把回調地址和簽過名的商品信息交給支付寶,支付寶在完成支付之后請求回調地址,進行簽名和公鑰驗證,驗證成功即可執行持久化操作.若操作成功,客戶端會請求RSACallBack.java類,進行客戶端與服務器端的同步操作.


龔小偉 2013-08-14 14:12 發表評論
]]>
主站蜘蛛池模板: 赣州市| 东丰县| 唐河县| 蚌埠市| 五大连池市| 丰台区| 雅安市| 巴青县| 盘山县| 凤城市| 宁城县| 汾西县| 侯马市| 九江市| 绩溪县| 方山县| 承德县| 中西区| 洪泽县| 德惠市| 秦皇岛市| 栾城县| 五家渠市| 华坪县| 许昌市| 霸州市| 册亨县| 安远县| 商南县| 兴安盟| 德庆县| 四子王旗| 肇庆市| 秦皇岛市| 武陟县| 靖远县| 长治市| 庐江县| 兴国县| 宜春市| 抚州市|