4.alipay 頁面跳轉同步通知處理數據庫
4.1 頁面跳轉同步通知安全
當買家完成了支付流程後,會出現成功支付的頁面,該頁面作短暫停留後,會跳轉到咱們AlipayConfig.xml中的 return_url 屬性所指定的頁面,這稱爲頁面跳轉同步通知。服務器
咱們須要在該頁面請求中,作相應的商業邏輯處理,如判斷並更改訂單狀態,增長數據庫中表示money的字段,注意:判斷狀態是十分必要的,避免重複進行操做。異步
4.2 returnURLjsp
1 /** 2 * 功能:付完款後跳轉的頁面(頁面跳轉同步通知頁面) 3 * WAIT_SELLER_SEND_GOODS(表示買家已在支付寶交易管理中產生了交易記錄且付款成功,但賣家沒有發貨); 4 * TRADE_FINISHED(表示買家已經確認收貨,這筆交易完成); 5 * 6 * @return 7 */ 8 public String returnURL() { 9 String key = AlipayConfig.key; 10 // 獲取支付寶GET過來反饋信息 11 Map params = new HashMap(); 12 13 // MyServletContext 爲自定義的類,可無視,換成以下寫法: 14 // HttpServletRequet request = ServletActionContext.getRequest(); 15 HttpServletRequest request = MyServletContext.getRequest(); 16 17 Map requestParams = request.getParameterMap(); 18 for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { 19 String name = (String) iter.next(); 20 String[] values = (String[]) requestParams.get(name); 21 String valueStr = ""; 22 for (int i = 0; i < values.length; i++) { 23 valueStr = (i == values.length - 1) ? valueStr + values[i] 24 : valueStr + values[i] + ","; 25 } 26 // 亂碼解決,這段代碼在出現亂碼時使用。若是mysign和sign不相等也能夠使用這段代碼轉化 27 try { 28 valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8"); 29 } catch (UnsupportedEncodingException e) { 30 e.printStackTrace(); 31 } 32 params.put(name, valueStr); 33 } 34 35 // 判斷responsetTxt是否爲ture,生成的簽名結果mysign與得到的簽名結果sign是否一致 36 // responsetTxt的結果不是true,與服務器設置問題、合做身份者ID、notify_id一分鐘失效有關 37 // mysign與sign不等,與安全校驗碼、請求時的參數格式(如:帶自定義參數等)、編碼格式有關 38 String mysign = AlipayNotify.GetMysign(params, key); 39 String responseTxt = AlipayNotify.Verify(request 40 .getParameter("notify_id")); 41 String sign = request.getParameter("sign"); 42 43 // 寫日誌記錄(若要調試,請取消下面兩行註釋) 44 // String sWord = "responseTxt=" + responseTxt + 45 // "\n return_url_log:sign=" + sign + "&mysign=" + mysign + 46 // "\n return回來的參數:" + AlipayFunction.CreateLinkString(params); 47 // AlipayFunction.LogResult(sWord); 48 49 // 獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(如下僅供參考)// 50 String trade_no = request.getParameter("trade_no"); // 支付寶交易號 51 String order_no = request.getParameter("out_trade_no"); // 獲取訂單號 52 String total_fee = request.getParameter("price"); // 獲取總金額 53 String subject = ""; 54 try { 55 subject = new String(request.getParameter("subject").getBytes( 56 "ISO-8859-1"), "UTF-8"); 57 } catch (UnsupportedEncodingException e1) { 58 // TODO Auto-generated catch block 59 e1.printStackTrace(); 60 }// 商品名稱、訂單名稱 61 62 String body = ""; 63 if (request.getParameter("body") != null) { 64 try { 65 body = new String(request.getParameter("body").getBytes( 66 "ISO-8859-1"), "UTF-8"); 67 } catch (UnsupportedEncodingException e) { 68 e.printStackTrace(); 69 }// 商品描述、訂單備註、描述 70 } 71 String buyer_email = request.getParameter("buyer_email"); // 買家支付寶帳號 72 String receive_name = "";// 收貨人姓名 73 if (request.getParameter("receive_name") != null) { 74 try { 75 receive_name = new String(request.getParameter("receive_name") 76 .getBytes("ISO-8859-1"), "UTF-8"); 77 } catch (UnsupportedEncodingException e) { 78 e.printStackTrace(); 79 } 80 } 81 String receive_address = "";// 收貨人地址 82 if (request.getParameter("receive_address") != null) { 83 try { 84 receive_address = new String(request.getParameter( 85 "receive_address").getBytes("ISO-8859-1"), "UTF-8"); 86 } catch (UnsupportedEncodingException e) { 87 e.printStackTrace(); 88 } 89 } 90 String receive_zip = "";// 收貨人郵編 91 if (request.getParameter("receive_zip") != null) { 92 try { 93 receive_zip = new String(request.getParameter("receive_zip") 94 .getBytes("ISO-8859-1"), "UTF-8"); 95 } catch (UnsupportedEncodingException e) { 96 e.printStackTrace(); 97 } 98 } 99 String receive_phone = "";// 收貨人電話 100 if (request.getParameter("receive_phone") != null) { 101 try { 102 receive_phone = new String(request 103 .getParameter("receive_phone").getBytes("ISO-8859-1"), 104 "UTF-8"); 105 } catch (UnsupportedEncodingException e) { 106 // TODO Auto-generated catch block 107 e.printStackTrace(); 108 } 109 } 110 String receive_mobile = "";// 收貨人手機 111 if (request.getParameter("receive_mobile") != null) { 112 try { 113 receive_mobile = new String(request.getParameter( 114 "receive_mobile").getBytes("ISO-8859-1"), "UTF-8"); 115 } catch (UnsupportedEncodingException e) { 116 e.printStackTrace(); 117 } 118 } 119 String trade_status = request.getParameter("trade_status"); // 交易狀態 120 // 獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以上僅供參考)// 121 122 String verifyStatus = ""; 123 if (mysign.equals(sign) && responseTxt.equals("true")) { 124 // //////////////////////////////////////////////////////////////////////////////////////// 125 // 請在這裏加上商戶的業務邏輯程序代碼 126 127 // ——請根據您的業務邏輯來編寫程序(如下代碼僅做參考)—— 128 if (trade_status.equals("WAIT_SELLER_SEND_GOODS")) { 129 // 判斷該筆訂單是否在商戶網站中已經作過處理(可參考「集成教程」中「3.4返回數據處理」) 130 // 若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 131 // 若是有作過處理,不執行商戶的業務程序 132 133 // if ("WAIT_BUYER_PAY".equals(memberMoney.getRemark()) 134 // && mMoney == Double.parseDouble(total_fee)) { 135 // memberMoney.setRemark("WAIT_BUYER_CONFIRM_GOODS"); 136 // memberMoneyService.saveOrUpdate(memberMoney); 137 // Members member = memberService.get(mid); 138 // if(member.getIdealMoney()==null){ // 這裏是前人的數據庫設置不合理,沒給金錢這字段默認值,故判斷其是否爲空 139 // member.setIdealMoney(mMoney); 140 // }else{ 141 // member.setIdealMoney(member.getIdealMoney() + mMoney); 142 // } 143 // memberService.saveOrUpdate(member); // 若是訂單狀態爲默認狀態,則添加金錢 144 // } 145 // try { 146 // // 這裏是發貨信息同步 147 // String xmlResult = AlipayService.PostXml( 148 // AlipayConfig.partner, trade_no, "直接充值", 149 // "請到我的中心-個人錢包查看充值貨幣", "EXPRESS", "", 150 // AlipayConfig.input_charset, AlipayConfig.key, 151 // AlipayConfig.sign_type); 152 // } catch (Exception e) { 153 // e.printStackTrace(); 154 // } 155 156 } 157 158 // ——請根據您的業務邏輯來編寫程序(如下代碼僅做參考)—— 159 if (trade_status.equals("TRADE_FINISHED")) { 160 // 判斷該筆訂單是否在商戶網站中已經作過處理(可參考「集成教程」中「3.4返回數據處理」) 161 // 若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 162 // 若是有作過處理,不執行商戶的業務程序 163 164 // if ("WAIT_BUYER_PAY".equals(memberMoney.getRemark()) 165 // && mMoney == Double.parseDouble(total_fee)) { 166 // memberMoney.setRemark("TRADE_FINISHED"); 167 // memberMoneyService.saveOrUpdate(memberMoney); 168 // Members member = memberService.get(mid); 169 // if(member.getIdealMoney()==null){ 170 // member.setIdealMoney(mMoney); 171 // }else{ 172 // member.setIdealMoney(member.getIdealMoney() + mMoney); 173 // } 174 // memberService.saveOrUpdate(member); // 若是訂單狀態爲默認狀態,則添加金錢 175 // 176 // try { 177 // // 這裏是發貨信息同步 178 179 // String xmlResult = AlipayService.PostXml( 180 // AlipayConfig.partner, trade_no, "直接充值", 181 // "我的中心請查看充值貨幣", "EXPRESS", "", 182 // AlipayConfig.input_charset, AlipayConfig.key, 183 // AlipayConfig.sign_type); 184 // } catch (Exception e) { 185 // e.printStackTrace(); 186 // } 187 // } else if ("WAIT_BUYER_CONFIRM_GOODS".equals(memberMoney 188 // .getRemark()) 189 // && mMoney == Double.parseDouble(total_fee)) { 190 // memberMoney.setRemark("TRADE_FINISHED"); 191 // memberMoneyService.saveOrUpdate(memberMoney); 192 // } 193 // 194 } 195 196 verifyStatus = "驗證成功"; 197 // ——請根據您的業務邏輯來編寫程序(以上代碼僅做參考)—— 198 199 // //////////////////////////////////////////////////////////////////////////////////////// 200 } else { 201 verifyStatus = "驗證失敗"; 202 } 203 return SUCCESS; 204 }
4.3 struts.xml網站
1 <!-- 上面略,該action用於頁面跳轉同步通知 --> 2 <action name="payMoney" class="AlipayAction" method="payMoney"> 3 <result name="success">alipayto.jsp</result> 4 <result name="input">exception.jsp</result> 5 </action>
====================== 華麗麗的分割線 ======================編碼
5.alipay 服務器異步通知處理url
5.1 服務器異步通知spa
買家在支付寶中完成交易,付了款後,會出現以下頁面:調試
該頁面作數秒停留後,會跳轉到 AlipayConfig.xml 中的 return_url 屬性所指定的頁面,這稱爲頁面跳轉同步通知(如前所述),而商業網站便在被調用的頁面中,作業務邏輯處理。
可是,買家可能在 Alipay 還沒有跳轉前,便把上面那頁面關閉,這時怎麼辦?
爲解決這問題 ,支付寶便有了服務器異步通知。即每當交易狀態發生變化,Alipay 都會主動通知AlipayConfig.xml 中的 notify_url 屬性所指定的頁面(該action不能有返回值,也不能跳轉)。這樣作確實解決了該問題,但也帶來了可能重複調用,故,咱們須要判斷alipay傳過來的狀態是否被處理過,若處理過,則不重複執行。
5.2 notifyURL
邏輯處理語句略!!!
1 /** 2 * 功能:支付寶主動通知調用的頁面(服務器異步通知頁面) 3 * 4 * @return 5 */ 6 public void notifyURL() { 7 String key = AlipayConfig.key; 8 // 獲取支付寶POST過來反饋信息 9 Map params = new HashMap(); 10 //HttpServletRequest request = ServletActionContext.getRequest(); 11 HttpServletRequest request = MyServletContext.getRequest(); 12 PrintWriter out = null; 13 try { 14 // out = ServletActionContext.getResponse().getWriter(); 15 out = MyServletContext.getResponse().getWriter(); 16 } catch (IOException e) { 17 e.printStackTrace(); 18 } 19 Map requestParams = request.getParameterMap(); 20 for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { 21 String name = (String) iter.next(); 22 String[] values = (String[]) requestParams.get(name); 23 String valueStr = ""; 24 for (int i = 0; i < values.length; i++) { 25 valueStr = (i == values.length - 1) ? valueStr + values[i] 26 : valueStr + values[i] + ","; 27 } 28 // 亂碼解決,這段代碼在出現亂碼時使用。若是mysign和sign不相等也能夠使用這段代碼轉化 29 // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "UTF-8"); 30 params.put(name, valueStr); 31 } 32 33 // 判斷responsetTxt是否爲ture,生成的簽名結果mysign與得到的簽名結果sign是否一致 34 // responsetTxt的結果不是true,與服務器設置問題、合做身份者ID、notify_id一分鐘失效有關 35 // mysign與sign不等,與安全校驗碼、請求時的參數格式(如:帶自定義參數等)、編碼格式有關 36 String mysign = AlipayNotify.GetMysign(params, key); 37 String responseTxt = AlipayNotify.Verify(request 38 .getParameter("notify_id")); 39 String sign = request.getParameter("sign"); 40 41 // 寫日誌記錄(若要調試,請取消下面兩行註釋) 42 String sWord = "responseTxt=" + responseTxt + "\n notify_url_log:sign=" 43 + sign + "&mysign=" + mysign + "\n notify回來的參數:" 44 + AlipayFunction.CreateLinkString(params); 45 AlipayFunction.LogResult(sWord); 46 47 // 獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(如下僅供參考)// 48 String trade_no = request.getParameter("trade_no"); // 支付寶交易號 49 String order_no = request.getParameter("out_trade_no"); // 獲取訂單號 50 String total_fee = request.getParameter("price"); // 獲取總金額 51 String subject = ""; 52 try { 53 subject = new String(request.getParameter("subject").getBytes( 54 "ISO-8859-1"), "UTF-8"); 55 } catch (UnsupportedEncodingException e) { 56 e.printStackTrace(); 57 }// 商品名稱、訂單名稱 58 String body = ""; 59 if (request.getParameter("body") != null) { 60 try { 61 body = new String(request.getParameter("body").getBytes( 62 "ISO-8859-1"), "UTF-8"); 63 } catch (UnsupportedEncodingException e) { 64 e.printStackTrace(); 65 }// 商品描述、訂單備註、描述 66 } 67 String buyer_email = request.getParameter("buyer_email"); // 買家支付寶帳號 68 String receive_name = "";// 收貨人姓名 69 if (request.getParameter("receive_name") != null) { 70 try { 71 receive_name = new String(request.getParameter("receive_name") 72 .getBytes("ISO-8859-1"), "UTF-8"); 73 } catch (UnsupportedEncodingException e) { 74 e.printStackTrace(); 75 } 76 } 77 String receive_address = "";// 收貨人地址 78 if (request.getParameter("receive_address") != null) { 79 try { 80 receive_address = new String(request.getParameter( 81 "receive_address").getBytes("ISO-8859-1"), "UTF-8"); 82 } catch (UnsupportedEncodingException e) { 83 e.printStackTrace(); 84 } 85 } 86 String receive_zip = "";// 收貨人郵編 87 if (request.getParameter("receive_zip") != null) { 88 try { 89 receive_zip = new String(request.getParameter("receive_zip") 90 .getBytes("ISO-8859-1"), "UTF-8"); 91 } catch (UnsupportedEncodingException e) { 92 e.printStackTrace(); 93 } 94 } 95 String receive_phone = "";// 收貨人電話 96 if (request.getParameter("receive_phone") != null) { 97 try { 98 receive_phone = new String(request 99 .getParameter("receive_phone").getBytes("ISO-8859-1"), 100 "UTF-8"); 101 } catch (UnsupportedEncodingException e) { 102 e.printStackTrace(); 103 } 104 } 105 String receive_mobile = "";// 收貨人手機 106 if (request.getParameter("receive_mobile") != null) { 107 try { 108 receive_mobile = new String(request.getParameter( 109 "receive_mobile").getBytes("ISO-8859-1"), "UTF-8"); 110 } catch (UnsupportedEncodingException e) { 111 e.printStackTrace(); 112 } 113 } 114 String trade_status = request.getParameter("trade_status"); // 交易狀態 115 // 獲取支付寶的通知返回參數,可參考技術文檔中頁面跳轉同步通知參數列表(以上僅供參考)// 116 117 if (mysign.equals(sign) && responseTxt.equals("true")) {// 驗證成功 118 // //////////////////////////////////////////////////////////////////////////////////////// 119 // 請在這裏加上商戶的業務邏輯程序代碼 120 121 122 // —— 請根據您的業務邏輯來編寫程序(如下代碼僅做參考)—— 123 if (trade_status.equals("WAIT_BUYER_PAY")) { 124 // 該判斷表示買家已在支付寶交易管理中產生了交易記錄,但沒有付款 125 126 // 判斷該筆訂單是否在商戶網站中已經作過處理(可參考「集成教程」中「3.4返回數據處理」) 127 // 若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 128 // 若是有作過處理,不執行商戶的業務程序 129 // 不作處理 130 out.println("success"); // 請不要修改或刪除 131 } else if (trade_status.equals("WAIT_SELLER_SEND_GOODS")) { 132 // 該判斷表示買家已在支付寶交易管理中產生了交易記錄且付款成功,但賣家沒有發貨 133 134 // 判斷該筆訂單是否在商戶網站中已經作過處理(可參考「集成教程」中「3.4返回數據處理」) 135 // 若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 136 // 若是有作過處理,不執行商戶的業務程序 137 138 139 out.println("success"); // 請不要修改或刪除 140 } else if (trade_status.equals("WAIT_BUYER_CONFIRM_GOODS")) { 141 // 該判斷表示賣家已經發了貨,但買家尚未作確認收貨的操做 142 143 // 判斷該筆訂單是否在商戶網站中已經作過處理(可參考「集成教程」中「3.4返回數據處理」) 144 // 若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 145 // 若是有作過處理,不執行商戶的業務程序 146 147 out.println("success"); // 請不要修改或刪除 148 } else if (trade_status.equals("TRADE_FINISHED")) { 149 // 該判斷表示買家已經確認收貨,這筆交易完成 150 151 // 判斷該筆訂單是否在商戶網站中已經作過處理(可參考「集成教程」中「3.4返回數據處理」) 152 // 若是沒有作過處理,根據訂單號(out_trade_no)在商戶網站的訂單系統中查到該筆訂單的詳細,並執行商戶的業務程序 153 // 若是有作過處理,不執行商戶的業務程序 154 155 156 out.println("success"); // 請不要修改或刪除 157 } else { 158 out.println("success"); // 請不要修改或刪除 159 } 160 // ——請根據您的業務邏輯來編寫程序(以上代碼僅做參考)—— 161 162 // //////////////////////////////////////////////////////////////////////////////////////// 163 }else {// 驗證失敗 164 out.println("fail"); 165 } 166 }
5.3 struts.xml
1 <!-- 上面略,該action不能執行任何跳轉 --> 2 <action name="notifyURL" class="AlipayAction" method="notifyURL" />