1. 程式人生 > >微信支付非同步回撥,帶你解決微信支付的深坑

微信支付非同步回撥,帶你解決微信支付的深坑

1.首先我們先下載微信支付的伺服器端demo





2.個檔案作用介紹

index.jsp  下單  payRequest.jsp  獲取微信支付prepay_id等。

重點我說說這個payNotifyUrl.jsp


   
  1. <%@ page language= "java" contentType= "text/html; charset=GBK" pageEncoding= "GBK"%>
  2. <%@ page import= "com.tenpay.RequestHandler" %>
  3. <%@ page import= "com.tenpay.ResponseHandler" %>
  4. <%@ page import
    = "com.tenpay.client.ClientResponseHandler" %>
  5. <%@ page import= "com.tenpay.client.TenpayHttpClient" %>
  6. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    "http://www.w3.org/TR/html4/loose.dtd">
  7. <%
  8. //---------------------------------------------------------
  9. //財付通支付通知(後臺通知)示例,商戶按照此文件進行開發即可
  10. //---------------------------------------------------------
  11. //商戶號
  12. String partner = "1900000109";
  13. //金鑰
  14. String key = "8934e7d15453e97507ef794cf7b0519d";
  15. //建立支付應答物件
  16. ResponseHandler resHandler = new ResponseHandler(request, response);
  17. resHandler.setKey(key);
  18. //判斷簽名
  19. if(resHandler.isTenpaySign()) {
  20. //通知id
  21. String notify_id = resHandler.getParameter( "notify_id");
  22. //建立請求物件
  23. RequestHandler queryReq = new RequestHandler( null, null);
  24. //通訊物件
  25. TenpayHttpClient httpClient = new TenpayHttpClient();
  26. //應答物件
  27. ClientResponseHandler queryRes = new ClientResponseHandler();
  28. //通過通知ID查詢,確保通知來至財付通
  29. queryReq.init();
  30. queryReq.setKey(key);
  31. queryReq.setGateUrl( "https://gw.tenpay.com/gateway/verifynotifyid.xml");
  32. queryReq.setParameter( "partner", partner);
  33. queryReq.setParameter( "notify_id", notify_id);
  34. //通訊物件
  35. httpClient.setTimeOut( 5);
  36. //設定請求內容
  37. httpClient.setReqContent(queryReq.getRequestURL());
  38. System.out.println( "queryReq:" + queryReq.getRequestURL());
  39. //後臺呼叫
  40. if(httpClient.call()) {
  41. //設定結果引數
  42. queryRes.setContent(httpClient.getResContent());
  43. System.out.println( "queryRes:" + httpClient.getResContent());
  44. queryRes.setKey(key);
  45. //獲取返回引數
  46. String retcode = queryRes.getParameter( "retcode");
  47. String trade_state = queryRes.getParameter( "trade_state");
  48. String trade_mode = queryRes.getParameter( "trade_mode");
  49. //判斷簽名及結果
  50. if(queryRes.isTenpaySign()&& "0".equals(retcode) && "0".equals(trade_state) && "1".equals(trade_mode)) {
  51. System.out.println( "訂單查詢成功");
  52. //取結果引數做業務處理
  53. System.out.println( "out_trade_no:" + queryRes.getParameter( "out_trade_no")+
  54. " transaction_id:" + queryRes.getParameter( "transaction_id"));
  55. System.out.println( "trade_state:" + queryRes.getParameter( "trade_state")+
  56. " total_fee:" + queryRes.getParameter( "total_fee"));
  57. //如果有使用折扣券,discount有值,total_fee+discount=原請求的total_fee
  58. System.out.println( "discount:" + queryRes.getParameter( "discount")+
  59. " time_end:" + queryRes.getParameter( "time_end"));
  60. //------------------------------
  61. //處理業務開始
  62. //------------------------------
  63. //處理資料庫邏輯
  64. //注意交易單不要重複處理
  65. //注意判斷返回金額
  66. //------------------------------
  67. //處理業務完畢
  68. //------------------------------
  69. resHandler.sendToCFT( "Success");
  70. }
  71. else{
  72. //錯誤時,返回結果未簽名,記錄retcode、retmsg看失敗詳情。
  73. System.out.println( "查詢驗證簽名失敗或業務錯誤");
  74. System.out.println( "retcode:" + queryRes.getParameter( "retcode")+
  75. " retmsg:" + queryRes.getParameter( "retmsg"));
  76. }
  77. } else {
  78. System.out.println( "後臺呼叫通訊失敗");
  79. System.out.println(httpClient.getResponseCode());
  80. System.out.println(httpClient.getErrInfo());
  81. //有可能因為網路原因,請求已經處理,但未收到應答。
  82. }
  83. }
  84. else{
  85. System.out.println( "通知簽名驗證失敗");
  86. }
  87. %>
就是上面的這程式碼。完全沒有用。檢視sdk原始碼才知道 這個非同步回撥是接收微信傳送的所有引數,然後排序  加密 驗籤。  最坑的是  微信 的引數根本不是通過的引數返回的。而是通過的流。所以這個太坑了。下面我把我修改過的原始碼發出來 幫助大家解決回撥問題。

首先是控制器


   
  1. /**
  2. * 非同步回撥介面
  3. * @param request
  4. * @param response
  5. * @throws Exception
  6. */
  7. @RequestMapping(value= "/weixin_parent_notify.do",produces= "text/html;charset=utf-8")
  8. @ResponseBody
  9. public String WeixinParentNotifyPage(HttpServletRequest request,HttpServletResponse response) throws Exception{
  10. ServletInputStream instream = request.getInputStream();
  11. StringBuffer sb = new StringBuffer();
  12. int len = - 1;
  13. byte[] buffer = new byte[ 1024];
  14. while((len = instream.read(buffer)) != - 1){
  15. sb.append( new String(buffer, 0,len));
  16. }
  17. instream.close();
  18. SortedMap<String,String> map = WXRequestUtil.doXMLParseWithSorted(sb.toString()); //接受微信的通知引數
  19. Map<String,String> return_data = new HashMap<String,String>();
  20. //建立支付應答物件
  21. ResponseHandler resHandler = new ResponseHandler(request, response);
  22. resHandler.setAllparamenters(map);
  23. resHandler.setKey(ConstantUtil.PARTNER_KEY[ 0]);
  24. //判斷簽名
  25. if(resHandler.isTenpaySign()){
  26. if(!map.get( "return_code").toString().equals( "SUCCESS")){
  27. return_data.put( "return_code", "FAIL");
  28. return_data.put( "return_msg", "return_code不正確");
  29. } else{
  30. if(!map.get( "result_code").toString().equals( "SUCCESS")){
  31. return_data.put( "return_code", "FAIL");
  32. return_data.put( "return_msg", "result_code不正確");
  33. }
  34. String out_trade_no = map.get( "out_trade_no").toString();
  35. String time_end = map.get( "time_end").toString();
  36. BigDecimal total_fee = new BigDecimal(map.get( "total_fee").toString());
  37. //付款完成後,支付寶系統傳送該交易狀態通知
  38. System.out.println( "交易成功");
  39. Map order = orderdao.PaymentEndGetOrderInfo(out_trade_no);
  40. if(order == null){
  41. System.out.println( "訂單不存在");
  42. return_data.put( "return_code", "FAIL");
  43. return_data.put( "return_msg", "訂單不存在");
  44. return WXRequestUtil.GetMapToXML(return_data);
  45. }
  46. int order_type = ( int) order.get( "order_type");
  47. boolean payment_status = ( boolean) order.get( "payment_status");
  48. int supplier_id = ( int) order.get( "supplier_id");
  49. BigDecimal p = new BigDecimal( "100");
  50. BigDecimal amount = (BigDecimal) order.get( "amount");
  51. amount = amount.multiply(p);
  52. //如果訂單已經支付返回錯誤
  53. if(payment_status){
  54. System.out.println( "訂單已經支付");
  55. return_data.put( "return_code", "SUCCESS");
  56. return_data.put( "return_msg", "OK");
  57. return WXRequestUtil.GetMapToXML(return_data);
  58. }
  59. //如果支付金額不等於訂單金額返回錯誤
  60. if(amount.compareTo(total_fee)!= 0){
  61. System.out.println( "資金異常");
  62. return_data.put( "return_code", "FAIL");
  63. return_data.put( "return_msg", "金額異常");
  64. return WXRequestUtil.GetMapToXML(return_data);
  65. }
  66. //更新訂單資訊
  67. if(orderdao.PaymentEndUpdateOrder(out_trade_no, time_end)){
  68. System.out.println( "更新訂單成功");
  69. //如果該訂單是幼兒產品 並且 存在代理
  70. if(order_type == 2){
  71. if(supplier_id != 0){
  72. Map su = userdao.getSupplierInfo(supplier_id);
  73. String phone = (String) su.get( "phone_number");
  74. String nickname = (String) su.get( "nickname");
  75. String app_token = (String) su.get( "app_token");
  76. String content = "【三盛科創】尊敬的"+ nickname + "您好。您在我們平臺出售的商品有新使用者下單。請您點選該連結檢視發貨資訊。"+Config.WEB_SERVER+ "/order/SupplierOrderInfo.do?order_number="+out_trade_no+ "&sid="+app_token+ ".請您務必妥善包管。";
  77. MessageUtil.SendMessage(phone,content);
  78. }
  79. } else{
  80. orderdao.UpdateOrderStatus(out_trade_no, 3); //更新訂單為已完成
  81. }
  82. return_data.put( "return_code", "SUCCESS");
  83. 相關推薦

    支付非同步解決支付

    1.首先我們先下載微信支付的伺服器端demo 2.個檔案作用介紹 index.jsp  下單  payRequest.jsp  獲取微信支付prepay_id等。 重點我說說這個payNotifyUrl.jsp

    支付非同步 獲取引數值

    import java.io.StringReader; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import

    阿里App支付服務端介面開發(含後臺非同步退款)

    1.引入相關包檔案 maven匯入方式: <dependency> <groupId>com.alipay</groupId> <artifactId>sdk-java</artifactId> <version>

    程式設計師突發奇想如何巧用設計模式來實現【聚合支付非同步

    什麼是模版方法 1.定義了一個操作中的演算法的骨架,而將部分步驟的實現在子類中完成。 模板方法模式使得子類可以不改變一個演算法

    支付支付非同步 302

    APP從測試環境遷移到生產環境,重新測試發現購買時,支付寶支付成功之後,訂單狀態未更新,即非同步回撥介面未執行。檢查發現notify_url是正確的,並且已經支付成功(賬戶有被扣款),登入螞蟻金服開放平臺:https://openmonitor.alipay.com/acce

    支付支付非同步的一些問題

    做了好多次支付寶支付,還是經常掉坑,現在整理下,作為參考1,關於設定公鑰            一定要注意,是“支付寶公鑰”,不要填應用公鑰,不然就坑了2、關於回撥的域名地址       乾淨些,不要有引數,如:http://*****.com/notify.php,千萬不要

    支付驗籤失敗解決辦法

    按照支付寶的文件,呼叫rsaCheckV1的方法,他已經把方法封裝的很透徹了,只需要將取到的引數Map(request.getParameterMap())集合放入即可。但是驗籤一直不通過,查了很多資料,說公鑰不對,應該使用支付寶公鑰,不是應用公鑰,修改之後,還是驗籤不通過。

    小程式支付流程非同步及訊息模板呼叫(php原始碼)

    首先還是老樣子把流程圖給大家發一下 商戶系統和微信支付系統主要互動: 1、小程式內呼叫登入介面,獲取到使用者的openid,api參見公共api【小程式登入API】 2、商戶server呼叫支付統一下單,api參見公共api【統一下單API】 3、商戶server呼叫再次簽

    PHPAPP支付下單處理非同步

    1.下單 其中陣列轉換xml格式,curl傳送請求,xml格式轉換成陣列可單獨封裝成函式。 public function index() { $order = [ 'appid'=>'12345

    PHPAPP支付下單處理非同步——————支付這個

    1.下單 其中陣列轉換xml格式,curl傳送請求,xml格式轉換成陣列可單獨封裝成函式。     public function index() {         $order = [             'appid'=>'123456',     

    處理支付非同步

    /** * 微信支付非同步回撥(只有非同步回撥對訂單進行處理) */ public function wchatUrlBack() { $postStr = file_get_contents('php://input'); i

    掃碼支付功能(2)---使用者掃碼支付成功,非同步商戶介面

    使用者掃碼支付成功,微信非同步回撥商戶 當用戶掃碼支付成功之後,微信會非同步回撥商戶介面,告知使用者支付成功。好讓商戶進行下一步操作。 一、介面說明    1、流程圖 這裡要做的就是使用者支付成功後,微信非同步通知商戶支付結果,商戶收到通知後告知支付通知接收情況。        2、介面說明

    公眾號開發中遇到的問題——支付分享獲取openId(三)

    微信的統一下單介面(https://api.mch.weixin.qq.com/pay/unifiedorder)中,下單時,有這樣一個引數:notify_url,該引數是為接收微信支付非同步通知回撥的地址,通知url必須為直接可訪問的url,不能攜帶引數。之前我做回撥的時

    小程式 - 支付 & 支付完成

    微信支付是小程式一個重要的功能,詳情參考官方文件 文件中必填的引數由後臺人員返回給前端,通常前端攜帶訂單號請求後臺介面,換取這些引數 觸發支付的程式碼如下 wx.requestPayment({ timeStamp: '', nonceStr: '', package:

    小程式 c#後臺支付結果

    public partial class NativeNotifyPage : System.Web.UI.Page { public static string wxJsApiParam { get; set; } //前段顯示 public string r

    python django 支付成功url(notify_url)

    微信官方文件:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7 首先 這個 notify_url 有倆個要求  1.公網能直接訪問的  2.不能攜帶引數 (比如你的訂單id) 返回的內容微信請求的內容,為

    Android利用SDK分享到教程分享結果錯誤解決和注意點

    在正式開始之前這裡要著囉嗦一下,進來的同學一定要看,在申請應用的時候要填一個簽名,這個簽名是由應用的簽名檔案keystore決定的,那麼你在填這個簽名的時候,一定要把你的應用用正式的keyStore生成apk,安裝到手機,然後用微信提供的獲取應用簽名的apk工具獲取你應用

    node egg框架處理支付成功xml資料

    直接上詳細程式碼首先使用egg框架中介軟體,在app目錄建middleware資料夾,再建立一個js檔案如該js中的程式碼:module.exports = () => { return async function (ctx, next) {

    app支付多次以及不解決辦法

    前面一篇文章我是在做app支付的時候寫的,做app支付完成之後寫的,這篇主要是支付完成之後的坑。 首先,支付完成之後,主要就是回撥,我首先遇到的就是支付完成之後,並沒有收到資訊,然後就是各種網上找問答。後面突然發現,資料庫裡面無緣無故的竟然有了回撥的資訊(這個我是在回撥頁面