近期公司須要提供支付寶支付,對於一個沒有聯調過支付接口的我來講可謂是頭痛的死.還有找到支付寶境外接口的技術人員, 無論咋地,多謝支付寶技術人員的解答.api
首先要知道公司的pid和key.經過登陸境外支付寶帳號查詢,key是須要支付寶的支付密碼不要弄錯哦.網址:https://globalprod.alipay.com/transaction/fpTransInfo.htm異步
你能夠到網上找客戶叫他們給你旺旺號碼發demo給你:jsp
請求參數能夠去查看pdf文檔,記住不要把簽名和簽名類型這兩個參數,添加到生成要簽名的集合裏面去--->生成求情url:請求參數是什麼意思,請查看相關pdf,改文檔裏面描述了請求參數和請求URL的格式以及返回的code含義.請求接口/支付寶網關能夠去詢問支付寶相關技術支持,我這裏就不貼出來了測試
1 /** 2 * 建立請求支付寶的URL 3 * @param paygateway 支付寶鏈接 4 * @param service 支付寶服務接口 5 * @param sign_type 簽名方式(加密類型) 6 * @param out_trade_no 境外商戶交易號 7 * @param input_charset 編碼 8 * @param partner 境外商戶支付寶ID 9 * @param key 10 * @param body 描述 11 * @param total_fee 交易金額 12 * @param currency 幣種 13 * @param subject 商品名稱 14 * @param notify_url支付成功的回調路徑 我的以爲notify_url與return_url都相差無幾 15 * @param return_url支付成功的回調路徑 16 * @return 17 */ 18 public static String createUrl(String paygateway, String service, String sign_type, 19 String out_trade_no,String input_charset, 20 String partner,String key, 21 String body, String total_fee, String currency, 22 String subject ,String notify_url, 23 String return_url) { 24 25 Map<String,Object> params = new HashMap<String,Object>(); 26 params.put("service", service); 27 params.put("partner", partner); 28 params.put("subject", subject); 29 params.put("body", body); 30 params.put("out_trade_no", out_trade_no); 31 params.put("rmb_fee", total_fee);//表示商品的標價是人民幣,具體參考pdf 32 // params.put("total_fee", total_fee); 33 params.put("currency",currency); 34 params.put("return_url", return_url);//這兩個url是須要外網可以訪問的 35 params.put("notify_url", notify_url);//須要外網可以訪問的 36 params.put("_input_charset", input_charset); 37 38 String prestr = ""; 39 40 prestr = prestr + key; 41 //System.out.println("prestr=" + prestr); 42 43 String sign = DigestUtils.md5Hex(getContent(params, key));//生成簽名 44 String parameter = ""; 45 parameter = parameter + paygateway; 46 47 List<Object> keys = new ArrayList<Object>(params.keySet()); 48 for (int i = 0; i < keys.size(); i++) { 49 try { 50 parameter = parameter + keys.get(i) + "=" 51 + URLEncoder.encode((String) params.get(keys.get(i)), input_charset) + "&"; 52 } catch (UnsupportedEncodingException e) { 53 54 e.printStackTrace(); 55 } 56 } 57 58 parameter = parameter + "sign=" + sign + "&sign_type=" + sign_type; 59 60 return parameter; 61 62 }
1 /** 2 * 把集合拼接成請求參數 3 * @param params 請求參數集合 4 * @param privateKey 公司key 5 * @return 6 */ 7 private static String getContent(Map params, String privateKey) { 8 List keys = new ArrayList(params.keySet()); 9 Collections.sort(keys); 10 11 String prestr = ""; 12 13 for (int i = 0; i < keys.size(); i++) { 14 String key = (String) keys.get(i); 15 String value = (String) params.get(key); 16 17 if (i == keys.size() - 1) { 18 prestr = prestr + key + "=" + value; 19 } else { 20 prestr = prestr + key + "=" + value + "&"; 21 } 22 } 23 // String p = prestr + privateKe+"&forex_biz=\"FP\""; 24 String p = prestr+privateKey; 25 System.out.println(p); 26 return p; 27 }
拿到這個請求url你能夠用A標籤或者用httpclient訪問httpclient能夠查看境外支付寶報關接口對接博客.(有些狀況是不能使用httpclient,好比使用國內的支付寶即時到帳功能不能使用httpclient)網站
支付寶支付成功後回調的URL,支付成功的消息都在請求裏面:trade_status狀態等於TRADE_FINISHED的時候纔算支付成功(這裏是return_url,適用於提供給用戶顯示,notify_url適用於作本身的業務邏輯,記住,若是成功了要先支付寶發送成的消息,看下面的return_url)this
public ModelAndView payResult(HttpServletRequest request){ ModelAndView model = new ModelAndView(); Map<String,String> params = new HashMap<String,String>(); @SuppressWarnings("rawtypes") Map requestParams = request.getParameterMap(); for (@SuppressWarnings("rawtypes") 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] + ","; try { valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8"); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } } params.put(name, valueStr); } //亂碼解決,這段代碼在出現亂碼時使用。若是mysign和sign不相等也可使用這段代碼轉化 try { //獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(如下僅供參考)// //訂單外幣金額 String total_fee = new String(request.getParameter("total_fee").getBytes("ISO-8859-1"),"UTF-8"); //清算幣種 String currency = new String(request.getParameter("currency").getBytes("ISO-8859-1"),"UTF-8"); //商戶訂單號 String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); //支付寶交易號 String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); System.out.println("支付寶交易號:___"+trade_no); //交易狀態 String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); System.out.println("交易狀態:___"+trade_status); if(StringUtils.isNotBlank(trade_status) && "TRADE_FINISHED".equals(trade_status)){ model.setViewName("pay/pay_success"); model.addObject("message", "支付成功!"); AlipayNotify.verify(params);//這個是demo裏面的方法, 下載上面的demo就有該類,就不貼出來了 String responseTxt = "true"; if(params.get("notify_id") != null) { String notify_id = params.get("notify_id"); responseTxt = AlipayNotify.verifyResponse(notify_id); } String sign = ""; if(params.get("sign") != null) { sign = params.get("sign"); } boolean isSign = AlipayNotify.getSignVeryfy(params, sign); //寫日誌記錄(若要調試,請取消下面兩行註釋) String sWord = "responseTxt=" + responseTxt + "\n isSign=" + isSign + "\n 返回回來的參數:" + AlipayCore.createLinkString(params); Logger.getLogger(this.getClass().getName()).info(sWord); Map<String,String> paramMap = new HashMap<String,String>(); paramMap.put("orderNu", out_trade_no); paramMap.put("payNu", trade_no); orderService.updateAliOrderStatus(paramMap);
// PrintWriter out = response.getWriter();
// out.print("success");//這段代碼是在notify_url的地址中,我這裏是沒有貼notify_url了 } else { model.setViewName("pay/pay_fail"); model.addObject("message", "支付失敗!");
// PrintWriter out = response.getWriter();//這段代碼是在notify_url的地址中,我這裏是沒有貼notify_url了
//out.print("fail");
} } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return model; }
調用:編碼
1 // String paygateway = "https://openapi.alipaydev.com/gateway.do?"; //支付寶測試環境 2 String paygateway = "https://mapi.alipay.com/gateway.do?"; // 支付寶正式環境 3 String service = "create_forex_trade";//接口名稱 4 String sign_type = "MD5";//簽名方式 5 String out_trade_no = orderDTO.getOrderCode(); //本地系統訂單號() 6 String input_charset = "utf-8"; 7 // String partner = "2088101122136241"; //測試環境pid 8 String partner = ""; //pid 9 // String key = "760bdzec6y9goq7ctyx96ezkz78287de"; //測試環境的key 10 String key = ""; //商戶key 11 String body = "";//商品描述 12 if(orderDetails != null && orderDetails.size() > 1){ 13 body = orderDetails.get(0).getProductName()+"等多件"; //trade description 14 } else { 15 body = orderDetails.get(0).getProductName(); //trade description 16 } 17 // String total_fee = "1"; //range is 0.01~1000000.00 18 String total_fee = (String)request.getSession().getAttribute("sumPriceForAli");//支付金額 19 String currency = "USD";//幣種 20 String subject = "";//商品名稱 21 if(orderDetails != null && orderDetails.size() > 1){ 22 subject= orderDetails.get(0).getProductName()+"等多件"; // 23 } else { 24 subject= orderDetails.get(0).getProductName(); // 25 } 26 String notify_url = ""; //異步通知,能夠理解爲後臺處理邏輯程序 27 String return_url = "http://m.uecun.com/uec/pay/payResult"; // 同步通知,能夠理解爲前臺頁面顯示給用戶看的 28 String ItemUrl=Payment.createUrl(paygateway,service,sign_type,out_trade_no,input_charset,partner,key,body,total_fee,currency,subject,notify_url,return_url);
這段代碼,我是寫在jsp裏面的, 固然能夠改寫,Payment類的createUrl方法就是第一段代碼,其餘驗證簽名的方法和類能夠下載上面連接。
加密