1. 程式人生 > >Java SpringMVC 支付寶-即時支付介面-ping++支付

Java SpringMVC 支付寶-即時支付介面-ping++支付

一. 前言介紹:

    前幾天突然要做支付寶的支付功能,​因為以前一直沒有做過支付功能,所以比較茫然,但是後來經過不斷摸索和前輩指導,終於做了出來;後來發現,其實做支付寶的支付功能也並不難。

二.正文:

  首先你要搞到商家的支付寶賬號,合作者ID

  (1).第一步要先能夠跳轉到支付寶的支付介面(可以本地測試)。

  (2).​第二部完成支付跳轉回商家介面(必須線上測試,因為返回回來,支付寶找不到你的localhost:8080;所以必須要有域名(地址))。

首先在支付寶官網下載java的即時支付包,然後根據自己所需要,拷貝進它的原始碼,也可以全部拷入,但是不一定全部能用。

對於:資料互動方式可以用jsp,也可以用控制器​。支付寶給的demo是用的jsp實現。

而我們用的是控制器實現;線面就用控制器介紹:

程式碼:

 package com...web.alipay;

@Controller

@RequestMapping(value = "/alipay")

public class alipayController {

@Autowired

private AlipayService alipayService;

@Autowired

private ProjectService projectService;

@Autowired

private ProjectAcceleratorService projectAcceleratorService;

  //跳轉支付寶網站的方法

 @RequestMapping(value = "/deposit", method = RequestMethod.GET)

 @ResponseBody  

 public ResponseEntity deposit(HttpServletRequest request,HttpServletResponse response,Model model){

 

       //防釣魚時間戳    

    防釣魚時間戳這裡沒寫,貌似要先去支付寶申請,要稽核一個星期左右,通過了才能用

      Date date = new Date();  

       // 支付型別  

       // 必填,不能修改  

       String payment_type = "1";  

       // 伺服器非同步通知頁面路徑  

       // 需http://格式的完整路徑,不能加?id=123這類自定義引數

       String notify_url = "http://“自己網站的域名”/alipay/async";

       // 頁面跳轉同步通知頁面路徑  

       // 需http://格式的完整路徑,不能加?id=123這類自定義引數,不能寫成http://localhost/  

       String return_url = "http://“自己網站的域名”/alipay/return_url";

       // 商戶訂單號.  

       // 商戶網站訂單系統中唯一訂單號,必填  

       //String out_trade_no = date.getTime() + "";  

       // 訂單名稱  

       // 必填

       String projectId = request.getParameter("projectId");

      

       

       if(projectId != null){

       ProjectEntity project = projectService.getProject(projectId);

       if(project != null){

        //從支付頁面獲取值

           //商品名稱

           String subject = project.getName(); 

           

           //String WIDout_trade_no = request.getParameter("WIDout_trade_no");      

           // 防釣魚時間戳  

           // 若要使用請呼叫類檔案submit中的query_timestamp函式  

           //String anti_phishing_key = "";  

           // 客戶端的IP地址  

           // 非區域網的外網IP地址,如:  

           String exter_invoke_ip = "";  可不填

             

          

           String total_fee = project.getReward();

           

           String body = project.getSummary();

   //商品展示地址

   String show_url = "";可不填

   //需以http://開頭的完整路徑,例如:http://www.xxx.com/myorder.html

   

   

   

   Map sParaTemp = new HashMap();

   sParaTemp.put("service", "create_direct_pay_by_user");//介面服務----即時到賬

   sParaTemp.put("partner", AlipayConfig.partner);//支付寶PID

   sParaTemp.put("_input_charset", AlipayConfig.input_charset);//統一編碼

   sParaTemp.put("payment_type", payment_type);//支付型別

   sParaTemp.put("notify_url", notify_url);//非同步通知頁面

   sParaTemp.put("return_url", return_url);//頁面跳轉同步通知頁面

   sParaTemp.put("seller_email", "");//賣家支付寶賬號

   sParaTemp.put("out_trade_no", date.getTime()+payment_type);//商品訂單編號

   sParaTemp.put("subject", subject);//商品名稱

   sParaTemp.put("total_fee", total_fee);//價格

   sParaTemp.put("body", body);

   sParaTemp.put("extra_common_param", extra_common_param);

   sParaTemp.put("show_url", show_url);

   //sParaTemp.put("anti_phishing_key", anti_phishing_key);

   sParaTemp.put("exter_invoke_ip", exter_invoke_ip);

            

   

   String sHtmlText = AlipaySubmit.buildRequest(sParaTemp,"get","確認");

   

   try {

   response.setHeader("Pragma", "No-cache");

   response.setHeader("Cache-Control", "no-cache");

   response.setContentType("text/html; charset=utf-8");

   response.getWriter().write(sHtmlText);

   response.getWriter().close();

   } catch (IOException e) {

   // TODO Auto-generated catch block

   e.printStackTrace();

   }

   

       }

       }

return null;

 }

 

   @SuppressWarnings("rawtypes")

@RequestMapping(value="/async",method = RequestMethod.POST)

public String async(HttpServletRequest request,HttpServletResponse response){

Map params = new HashMap();  

       Map requestParams = request.getParameterMap();  

       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);  

       }  

       //獲取返回資料

       String orderTitle = request.getParameter("subject");//訂單名稱

       String payType = request.getParameter("payment_type");//支付型別

       String outTradeNo = request.getParameter("out_trade_no");//訂單號

       String tradeNo = request.getParameter("trade_no");//支付寶交易號

       String notifyId = request.getParameter("notify_id");//支付校驗id

       String amount = request.getParameter("total_fee");//交易金額

       String notifyTime = request.getParameter("notify_time");//通知時間       

       String tradeStatus = request.getParameter("trade_status");//交易狀態

       String returnId = request.getParameter("extra_common_param");//專案id

       String payer = request.getParameter("buyer_email");//支付者賬號              

                //

       if(AlipayNotify.verify(params)){//驗證成功  

           if(tradeStatus.equals("TRADE_FINISHED") || tradeStatus.equals("TRADE_SUCCESS")) {  

           //要寫的邏輯。自己按自己的要求寫

           

           //封裝交易資訊實體,存入資料庫之類的                                               

                System.out.println(">>>>>非同步返回:" + tradeNo);  

           }  

           return "success/alipay-success";  

       }else{//驗證失敗  

           return "success/alipay-fail";  

       }  

}

 

   @RequestMapping(value="/return_url",method = RequestMethod.GET)

   public String Return_url(HttpServletRequest request,HttpServletResponse response){

Map params = new HashMap();  

       Map requestParams = request.getParameterMap();  

       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);  

       }  

       String tradeNo = request.getParameter("trade_no");//支付寶交易號

      

       String tradeStatus = request.getParameter("trade_status");//交易狀態

                      

       if(AlipayNotify.verify(params)){//驗證成功  

           if(tradeStatus.equals("TRADE_FINISHED") || tradeStatus.equals("TRADE_SUCCESS")) {  

           //要寫的邏輯。自己按自己的要求寫               

               System.out.println(">>>>>充值成功" + tradeNo);  

           }  

           return "...";  

       }else{//驗證失敗  

           return "success/fail";  

       }  

     }    

}

支付流程:

先訪問​ /deposit 對映下面的方法 ---> 跳轉到支付寶的支付介面 ---> 核對支付資訊進行支付 (測試一般用1分錢)--->支付成功 --->支付寶同時呼叫同步和非同步方法;

      但是非同步方法一般要快於同步方法,因為中間還有一個跳轉流程。所以這裡特別注意的是:如果你要講支付寶返回來的資訊存入資料庫,邏輯一般是寫在非同步方法裡面,同步方法作為頁面跳轉(跳你自己的網站頁面)。如果把邏輯寫在同步方法裡面,客戶在支付成功直接關閉視窗,沒返回你的網站的話,它是訪問不到你的控制器的。

       而且對於非同步方法訪問的方法是要在瀏覽器上直接訪問到的!但是一般我們網站都做了許可權過濾的,直接方法方法,要先去判斷是否登入,沒登入一般跳轉登入介面。但是不論你是用的過濾器還是 shiro,還是其它的,總之你要暴露出這個方法要讓支付寶能訪問(不能夠跳登入介面)!

        並且這個非同步方法返回的jsp不能有其它程式碼:

        我就只寫了:​ <%=%>