<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 通道對接 ## 通道對接 該文檔適合技術人員閱讀,可以幫助技術人員快速對接上游通道。我們這里將上游通道區分為支付通道和代付通道。 ### 1. 支付通道 #### (1)支付流程 商戶下單后,xxpay-pay項目中的`PayOrderController`類中的`payOrder`方法負責接收商戶下單請求,該方法中會根據商戶的下單請求參數,得到具體的支付通道名稱,然后調用該通道的`pay`方法完成上游通道的下單操作,具體代碼提下如下。 ``` <pre class="calibre25">``` payOrderId <span class="token">=</span> payOrder<span class="token1">.</span><span class="token2">getPayOrderId</span><span class="token1">(</span><span class="token1">)</span><span class="token1">;</span> String channelId <span class="token">=</span> payOrder<span class="token1">.</span><span class="token2">getChannelId</span><span class="token1">(</span><span class="token1">)</span><span class="token1">;</span> String channelName <span class="token">=</span> channelId<span class="token1">.</span><span class="token2">substring</span><span class="token1">(</span><span class="token3">0</span><span class="token1">,</span> channelId<span class="token1">.</span><span class="token2">indexOf</span><span class="token1">(</span><span class="token4">"_"</span><span class="token1">)</span><span class="token1">)</span><span class="token1">;</span> AbstractRes res <span class="token">=</span> localDynamicChannelService<span class="token1">.</span><span class="token2">callPaymentMethod</span><span class="token1">(</span>channelName<span class="token1">,</span> payOrder<span class="token1">,</span> <span class="token3">true</span><span class="token1">)</span><span class="token1">;</span> ``` ``` 通過`localDynamicChannelService.callPaymentMethod(channelName, payOrder, true);`可以從spring容器中得到該通道的實例,然后調用具體的下單方法。 在命名通道類名的時候,格式須為:`通道名稱+PaymentService`,如:`AlipayPaymentService`為支付寶通道。 在XxPay Pro中,已經支持內置支付通道和動態通道(可通過接口商店安裝),具體代碼邏輯參考類`LocalDynamicChannelService`中的業務邏輯。 - 內置支付通道:指在xxpay-pay項目中硬編碼實現,開發好需要部署class文件,重啟項目。 - 動態支付通道:指動態開發的支付接口,打包成jar文件,在運營平臺自動導入即可,項目可不用重啟,直接可使用。 #### (2)內置支付通道實現 在xxpay-pay項目中的`channel`目錄下,須為通道創建一個獨立的目錄。 ![](https://docs.jeequan.com/uploads/201904/attach_1591549553a3e2a7.png "null") 比如這里以威富通為例,威富通就是一個具體的上游通道,給它定義名稱為`swiftpay`,一般名字的定義來自通道的品牌名稱。 然后在該目錄下創建具體的支付實現類,名字為:`SwiftpayPaymentService`,類的名字必須是`通道名稱+PaymentService`,首字母大寫。然后該類繼承自`BasePayment`,重寫`pay`方法即可。 一般一個通道會對應多種支付方式,比如威富通會有微信掃碼支付,支付寶掃碼支付,統一條碼支付等。那么每種支付方式需要對應一個支付接口,我們這樣命名:`通道名稱+_+支付方式`,如威富通微信掃碼支付我們定義為:`swiftpay_wxpay_native`。 在pay方法中,我們會根據商戶選擇的支付方式,對應到上游通道的實現方法中,可以參考威富通的支付對接實現。具體的每種支付方式,需要參考上游通道的接口和demo來實現。 ![](https://docs.jeequan.com/uploads/201808/attach_154cde4a833a3fb3.png "null") #### (3)通道支付回調 一般正規的支付流程,都是在用戶支付成功后,上游通道會回調接口中上傳的回調地址,那么我們需要處理上游過來的回調請求。 同樣的,也是在支付通道目錄下,創建一個支付回調的實現類,類的名字為:`通道名稱+PayNotifyService`,如威富通支付的回調類名為:`SwiftpayPayNotifyService`,該類繼承自`BasePayNotify`,重寫`doNotify`方法即可。 在調用上游通道支付接口時,我們會指定回調地址,那么在我們系統中,通過統一的方式獲取支付回調地址,具體代碼如下。 ``` <pre class="calibre25">``` <span class="token5">// 前端頁面跳轉通知地址</span> paramMap<span class="token1">.</span><span class="token2">put</span><span class="token1">(</span><span class="token4">"returnUrl"</span><span class="token1">,</span> super<span class="token1">.</span><span class="token2">getReturnUrl</span><span class="token1">(</span><span class="token2">getChannelName</span><span class="token1">(</span><span class="token1">)</span><span class="token1">,</span> dbConfig<span class="token1">)</span><span class="token1">)</span><span class="token1">;</span> <span class="token5">// 后臺異步回調通知地址</span> paramMap<span class="token1">.</span><span class="token2">put</span><span class="token1">(</span><span class="token4">"notifyUrl"</span><span class="token1">,</span> super<span class="token1">.</span><span class="token2">getNotifyUrl</span><span class="token1">(</span><span class="token2">getChannelName</span><span class="token1">(</span><span class="token1">)</span><span class="token1">,</span> dbConfig<span class="token1">)</span><span class="token1">)</span><span class="token1">;</span> ``` ``` notify地址格式為:`http://支付系統地址/notify/通道名稱/notify_res.htm`,如威富通的回調地址為:`http://pay.xx.com/notify/swiftpay/notify_res.htm`,每個通道獲取到的通知地址,通道名稱是對應自己的。 通知的入口類為:`NotifyPayController`,實現代碼為: ``` <pre class="calibre25">``` _log<span class="token1">.</span><span class="token2">info</span><span class="token1">(</span><span class="token4">"====== 開始接收{}支付回調通知 ======"</span><span class="token1">,</span> channel<span class="token1">)</span><span class="token1">;</span> <span class="token5">// 驗證回調是否在白名單</span> String notifyIp <span class="token">=</span> IPUtility<span class="token1">.</span><span class="token2">getClientIp</span><span class="token1">(</span>request<span class="token1">)</span><span class="token1">;</span> String checkResult <span class="token">=</span> <span class="token2">notifyCheck</span><span class="token1">(</span>channel<span class="token1">,</span> notifyIp<span class="token1">)</span><span class="token1">;</span> <span class="token6">if</span> <span class="token1">(</span>checkResult <span class="token">!=</span> <span class="token6">null</span><span class="token1">)</span> <span class="token6">return</span> checkResult<span class="token1">;</span> <span class="token5">//獲取通道對象示例</span> Object instance <span class="token">=</span> localDynamicChannelService<span class="token1">.</span><span class="token2">getPayNotifyInterface</span><span class="token1">(</span>channel<span class="token1">.</span><span class="token2">toLowerCase</span><span class="token1">(</span><span class="token1">)</span><span class="token1">)</span><span class="token1">;</span> <span class="token6">if</span><span class="token1">(</span>instance <span class="token6">instanceof</span> <span class="token2">PayNotifyInterface</span><span class="token1">)</span><span class="token1">{</span> PayNotifyInterface payNotifyInterface <span class="token">=</span> <span class="token1">(</span>PayNotifyInterface<span class="token1">)</span>instance<span class="token1">;</span> <span class="token6">if</span><span class="token1">(</span>payNotifyInterface <span class="token">==</span> <span class="token6">null</span><span class="token1">)</span><span class="token1">{</span> <span class="token6">return</span> ApiBuilder<span class="token1">.</span><span class="token2">bizError</span><span class="token1">(</span><span class="token4">"支付渠道類型[channel="</span><span class="token">+</span>channel<span class="token">+</span><span class="token4">"]實例化異常"</span><span class="token1">)</span><span class="token1">.</span><span class="token2">toJSONString</span><span class="token1">(</span><span class="token1">)</span><span class="token1">;</span> <span class="token1">}</span> JSONObject retObj <span class="token">=</span> payNotifyInterface<span class="token1">.</span><span class="token2">doNotify</span><span class="token1">(</span>request<span class="token1">)</span><span class="token1">;</span> String notifyRes <span class="token">=</span> retObj<span class="token1">.</span><span class="token2">getString</span><span class="token1">(</span>PayConstant<span class="token1">.</span>RESPONSE_RESULT<span class="token1">)</span><span class="token1">;</span> _log<span class="token1">.</span><span class="token2">info</span><span class="token1">(</span><span class="token4">"響應給{}:{}"</span><span class="token1">,</span> channel<span class="token1">,</span> notifyRes<span class="token1">)</span><span class="token1">;</span> _log<span class="token1">.</span><span class="token2">info</span><span class="token1">(</span><span class="token4">"====== 完成接收{}支付回調通知 ======"</span><span class="token1">,</span> channel<span class="token1">)</span><span class="token1">;</span> <span class="token6">return</span> notifyRes<span class="token1">;</span> <span class="token1">}</span> ``` ``` 原理同支付下單流程類似,也是得到具體的通道,然后從spring容器中得到具體的通知實例,調用`doNotify`方法。 #### (4)通道參數定義 一般每個支付通道都會對應一些配置,比如商戶ID,私鑰,網關地址等信息。我們需要根據上游通道的接口文檔,抽象出具體的配置字段,然后定義配置類。 一般類的名稱命名為`通道名稱+Config`,比如威富通的配置類為`SwiftpayConfig`。 威富通的配置包括:商戶ID,商戶key,網關請求地址,那么我們的代碼是這樣的。 ``` <pre class="calibre25">``` public class <span class="token2">SwiftpayConfig</span> <span class="token1">{</span> <span class="token5">// 商戶ID</span> private String mchId<span class="token1">;</span> <span class="token5">// 商戶Key</span> private String key<span class="token1">;</span> <span class="token5">// 請求地址</span> private String reqUrl<span class="token1">;</span> public <span class="token2">SwiftpayConfig</span><span class="token1">(</span><span class="token1">)</span><span class="token1">{</span><span class="token1">}</span> public <span class="token2">SwiftpayConfig</span><span class="token1">(</span>String payParam<span class="token1">)</span> <span class="token1">{</span> Assert<span class="token1">.</span><span class="token2">notNull</span><span class="token1">(</span>payParam<span class="token1">,</span> <span class="token4">"init swiftpay config error"</span><span class="token1">)</span><span class="token1">;</span> JSONObject object <span class="token">=</span> JSONObject<span class="token1">.</span><span class="token2">parseObject</span><span class="token1">(</span>payParam<span class="token1">)</span><span class="token1">;</span> this<span class="token1">.</span>mchId <span class="token">=</span> object<span class="token1">.</span><span class="token2">getString</span><span class="token1">(</span><span class="token4">"mchId"</span><span class="token1">)</span><span class="token1">;</span> this<span class="token1">.</span>key <span class="token">=</span> object<span class="token1">.</span><span class="token2">getString</span><span class="token1">(</span><span class="token4">"key"</span><span class="token1">)</span><span class="token1">;</span> this<span class="token1">.</span>reqUrl <span class="token">=</span> object<span class="token1">.</span><span class="token2">getString</span><span class="token1">(</span><span class="token4">"reqUrl"</span><span class="token1">)</span><span class="token1">;</span> <span class="token1">}</span> public String <span class="token2">getMchId</span><span class="token1">(</span><span class="token1">)</span> <span class="token1">{</span> <span class="token6">return</span> mchId<span class="token1">;</span> <span class="token1">}</span> public void <span class="token2">setMchId</span><span class="token1">(</span>String mchId<span class="token1">)</span> <span class="token1">{</span> this<span class="token1">.</span>mchId <span class="token">=</span> mchId<span class="token1">;</span> <span class="token1">}</span> public String <span class="token2">getKey</span><span class="token1">(</span><span class="token1">)</span> <span class="token1">{</span> <span class="token6">return</span> key<span class="token1">;</span> <span class="token1">}</span> public void <span class="token2">setKey</span><span class="token1">(</span>String key<span class="token1">)</span> <span class="token1">{</span> this<span class="token1">.</span>key <span class="token">=</span> key<span class="token1">;</span> <span class="token1">}</span> public String <span class="token2">getReqUrl</span><span class="token1">(</span><span class="token1">)</span> <span class="token1">{</span> <span class="token6">return</span> reqUrl<span class="token1">;</span> <span class="token1">}</span> public void <span class="token2">setReqUrl</span><span class="token1">(</span>String reqUrl<span class="token1">)</span> <span class="token1">{</span> this<span class="token1">.</span>reqUrl <span class="token">=</span> reqUrl<span class="token1">;</span> <span class="token1">}</span> <span class="token1">}</span> ``` ``` 在調用上游通道接口時,當需要使用配置參數時,我們可以這樣使用。 ``` <pre class="calibre25">``` SwiftpayConfig swiftpayConfig <span class="token">=</span> <span class="token6">new</span> <span class="token2">SwiftpayConfig</span><span class="token1">(</span><span class="token2">getPayParam</span><span class="token1">(</span>payOrder<span class="token1">)</span><span class="token1">)</span><span class="token1">;</span> map<span class="token1">.</span><span class="token2">put</span><span class="token1">(</span><span class="token4">"mch_id"</span><span class="token1">,</span> swiftpayConfig<span class="token1">.</span><span class="token2">getMchId</span><span class="token1">(</span><span class="token1">)</span><span class="token1">)</span><span class="token1">;</span> ``` ``` #### (5)通道接口配置 以上支付通道的支付接口,回調接口都已經實現,這時需要在運營平臺創建通道接口配置,才可使用。 `創建支付接口類型` 進入:運營平臺 > 支付配置 > 支付接口類型 > 新增接口類型 ![](https://docs.jeequan.com/uploads/pro4dev/images/m_9cef22240aaaf25ec26ef1bc73ccfacd_r.png "null") - 接口類型代碼:這個和支付通道的通道名稱是一致的,如:swiftpay。 - 接口類型名稱:對應上游支付通道名稱,如:威富通支付。 - 配置定義描述:這里是和我們上面提到的通道配置類對應,內容為json格式,描述了生成該通道配置賬戶界面的表單內容。可使用官方工具生成:<https://www.jeequan.com/dev/tool.html> - 回調IP白名單:如果配置了IP,那么只有該IP下的回調才會通過 - 訂單超時時間:如果配置了,那么過了超時時間,系統會自動將訂單關閉 `創建支付接口` 進入:運營平臺 > 支付配置 > 支付接口 > 新增支付接口 ![](https://docs.jeequan.com/uploads/201808/attach_154ce03417ca7147.png "null") - 接口代碼:這里對應我們我們為每個支付通道定義的支付接口,如威富通的微信掃碼支付,名字為:swiftpay\_wxpay\_native。 - 接口類型:選擇對應的通道名稱。 - 支付類型:根據具體的支付場景,選擇對應的支付類型。 `通道賬號配置` 進入:運營平臺 > 支付配置 > 支付通道 > 子賬戶 ![](https://docs.jeequan.com/uploads/201808/attach_154ce08ae8a152f0.png "null") 賬戶配置的表單,就來自上面配置的支付接口類型的配置定義描述,也對應通道配置類中的屬性。 ### 2. 代付通道 代付通道的實現參考支付通道即可,這里調用的是上游的代付接口。下面給出幾個核心邏輯類,相信聰明你的一定知道如何對接的。 代付下單入口類:`AgentpayController` 轉賬實現類名稱格式:`通道名稱+TransService`,重寫`trans`方法。 轉賬判斷是否成功很關鍵,一定要在`明確成功`或`失敗`時,才可以設置代付最終業務結果。 對接上游通道代付接口時,如果判斷代付接口,一般有三種方式: 1. 調代付接口直接同步響應結果,明確告訴代付已經成功,該種最簡單直接處理業務即可。 2. 調代付接口時,上游通道同步返回申請成功,需要主動查詢代付結果。在我們系統,可通過如下代碼實現。 ``` <pre class="calibre25">``` <span class="token5">// 交易處理中</span> _log<span class="token1">.</span><span class="token2">info</span><span class="token1">(</span><span class="token4">"{} >>> 轉賬處理中"</span><span class="token1">,</span> logPrefix<span class="token1">)</span><span class="token1">;</span> JSONObject msgObj <span class="token">=</span> <span class="token6">new</span> <span class="token2">JSONObject</span><span class="token1">(</span><span class="token1">)</span><span class="token1">;</span> msgObj<span class="token1">.</span><span class="token2">put</span><span class="token1">(</span><span class="token4">"count"</span><span class="token1">,</span> <span class="token3">1</span><span class="token1">)</span><span class="token1">;</span> msgObj<span class="token1">.</span><span class="token2">put</span><span class="token1">(</span><span class="token4">"transOrderId"</span><span class="token1">,</span> transOrderId<span class="token1">)</span><span class="token1">;</span> msgObj<span class="token1">.</span><span class="token2">put</span><span class="token1">(</span><span class="token4">"channelName"</span><span class="token1">,</span> <span class="token2">getChannelName</span><span class="token1">(</span><span class="token1">)</span><span class="token1">)</span><span class="token1">;</span> mq4TransQuery<span class="token1">.</span><span class="token2">send</span><span class="token1">(</span>msgObj<span class="token1">.</span><span class="token2">toJSONString</span><span class="token1">(</span><span class="token1">)</span><span class="token1">,</span> <span class="token3">10</span> <span class="token">*</span> <span class="token3">1000</span><span class="token1">)</span><span class="token1">;</span> <span class="token5">// 10秒后查詢</span> <span class="token6">return</span> QueryRetMsg<span class="token1">.</span><span class="token2">waiting</span><span class="token1">(</span><span class="token1">)</span><span class="token1">;</span> ``` ``` 通過mq方式,設置延遲查詢,直到查詢到成功或失敗。可參考項目中杉德代付的代碼:`SandpayTransService`。 3. 調代付接口時,上游通道同步返回申請成功,需要接收上游通道的異步回調,確認代付結果。在我們系統中,需要實現回調方法接口。 增加回調處理類,名稱格式為:`通道名稱 + TransNotifyService`,重寫doNotify方法。可參考項目中雙乾代付的代碼:`SqpayTransNotifyService`。 `如果還是搞不定,可以聯系售后技術支持哦!`
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看