最近公司有一個應用,用戶可以在微信公眾號上面下單,也可以在APP 中下單。
當用戶在公共號上面下單時,微信支付成功可以返回微信支付單號,但是在APP 中用戶微信支付時,個別時候會出現用戶已經付款成功,卻沒有執行訂單支付成功后的回調邏輯(比如修改業務系統中的訂單狀態為已付款).
顯然在APP中微信支付的這種回調邏輯是不可靠的。
(1)首先說明下為什么要拿到微信支付訂單號
微信支付訂單號是微信系統在支付成功后返回的訂單號,比如這樣的訂單號:4007322001201705049543255213, 拿到這個訂單號可以調用微信查詢接口(當然也可以使用自己應用中定義的訂單號來調用微信訂單查詢接口,但是微信推薦優先使用這個微信支付訂單號來查詢)
,更重要的是,在實際的業務邏輯中,有些用戶下單成功后,后來要求退款(比如收到貨后用戶不滿意,要求訂單退款),這樣在調用微信的退款接口(https://api.mch.weixin.qq.com/secapi/pay/refund)時,必須要提供這個微信支付訂單號。
(2)APP 中的微信支付如何提高微信支付的可靠性
這個主要就是用戶在APP 中使用微信支付時,每當支付成功后,在執行的回調邏輯(比如是這樣的邏輯:往自己的系統里面修改訂單狀態為已支付,發送支付成功的通知消息等)前,調用微信提供的訂單查詢接口(https://api.mch.weixin.qq.com/pay/orderquery),僅當這個訂單查詢接口返回該筆訂單已經支付成功(主要是trade_state="SUCESS"),則才執行后面的回調邏輯。
/// <summary> /// 調用微信支付的查詢訂單接口,以確認是否訂單已經支付成功 /// </summary> /// <param name="entity"></param> /// <param name="loggingSessionInfo"></param> /// <param name="OrderID"></param> /// <param name="ChannelID"></param> /// <param name="WeixinTransactionID"></param> /// <returns></returns> private bool CheckIfOrderPaid(OrderEntity entity, LoggingSessionInfo loggingSessionInfo, string OrderID, string ChannelId, ref string WeixinTransactionID) { WxPayData inputObj = new WxPayData(); // APP 中的微信支付(paymentcenter_id值為空), 根據業務系統中的訂單號out_trade_no 來調用微信的訂單查詢接口,以確認是否該訂單已經支付成功 if (string.IsNullOrEmpty(entity.paymentcenter_id)) { var common = new CommonBLL(); // APP 中使用微信支付時,微信系統設定的APP 相關賬戶信息(partner,partnerkey) AccessTokenEntity wxInfo = common.GetAppInfo(loggingSessionInfo); inputObj.SetValue("out_trade_no", OrderID); // 調用微信的訂單查詢接口 WxPayData result = WxPayApi.OrderQuery(inputObj, wxInfo.AppID, wxInfo.Partner, wxInfo.Partnerkey); if (!result.IsSet("trade_state") || result.GetValue("trade_state").ToString() != "SUCCESS") { return false; } WeixinTransactionID = result.GetValue("transaction_id").ToString(); } else { // 微信公眾號支付 if (!string.IsNullOrEmpty(WeixinTransactionID)) { inputObj.SetValue("transaction_id", WeixinTransactionID); } else { inputObj.SetValue("out_trade_no", entity.paymentcenter_id); } // 獲取微信公眾號的相關賬戶信息(MerchantID,SignKey,APPId等) TPaymentTypeCustomerMappingEntity[] mappings = new TPaymentTypeCustomerMappingBLL(this.CurrentUserInfo).QueryByEntity( new TPaymentTypeCustomerMappingEntity() { ChannelId = ChannelId, CustomerId = entity.customer_id } , null ); // 調用微信支付查詢接口,這次inputobj 的取值要么是微信系統的transaction_id(微信推薦使用transaction_id 來查詢訂單),要么是我們自己業務系統的訂單號(out_trade_no)。 WxPayData result = WxPayApi.OrderQuery(inputObj, mappings[0].APPId, mappings[0].MerchantID, mappings[0].SignKey); if (!result.IsSet("trade_state") || result.GetValue("trade_state").ToString() != "SUCCESS") { return false; } } return true; }
(3)更多詳細的微信訂單查詢接口,可以參考如下的微信官方鏈接:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_2&index=4