
?大家好,我是小悟
(資料圖片)
在對接支付寶開放平臺的一些常用功能時,常常需要收到支付寶的回調通知結果,才能處理業務邏輯。此文介紹通過WebSocket長連接接入支付寶消息服務,實現消息通知。
包括五部分內容:問題、優勢、配置、代碼接入、總結。
比如接入互聯網平臺直付通二級商戶進件時,需要知道這個進件審核的結果,是審核通過還是審核拒絕,就要用到直付通商戶進件審核通過消息接口和直付通二級商戶進件拒絕消息接口。
再比如接入支付寶小程序模板開發時,需要知道第三應用授權取消結果、小程序審核結果、服務商代創建小程序結果等等,就要用到第三方應用授權取消消息接口、小程序審核通過通知接口、小程序審核駁回通知接口、商戶確認服務商代創建小程序結果通知接口等等。
雖然可以通過對應的查詢接口主動發起查詢結果,但多個業務結果還需開發多個查詢接口,體驗終歸不如由支付寶服務端側直接通知開發者來的好。所以千萬別干“脫褲子放pi,多此一舉”的事情來,哈哈哈。
為了解決通知的問題,支付寶開放平臺消息服務提供兩種通訊協議來接收消息,一種是基于 HTTPS/HTTP,一種是基于 WebSocket 長連接。
選擇WebSocket 長連接有諸多優勢:
官方提供封裝好的SDK,開發者無需考慮通信、驗簽、組裝報文協議,只要專心根據收到的消息處理自身的業務邏輯即可。
無需申請https證書,減少繁瑣的證書申請工作,消息也能觸達。
開發者無需額外開發一個服務來接收開放平臺的消息。
相比之下,WebSocket 長連接有更多的優勢,所以一般選擇使用WebSocket 長連接來接收支付寶服務端發來的消息。
創建好應用后,在產品綁定-綁定產品,添加對應的產品。
然后在開發設置-消息服務-FROM平臺訂閱所需監聽的消息接口,接入方式選擇WebSocket。
以上操作是接入的前提條件,務必檢查清楚再進行代碼的開發。
可使用普通公鑰方式和公鑰證書方式接入,方式不同,SDK的使用也不同,這個取決于設置接口加簽是何種方式,這邊選擇的是公鑰證書方式。
在代碼中引入依賴,這邊有個注意點就是,如果選擇的是公鑰證書模式的話,SDK版本需要使用4.11.54.ALL 及以上版本。
com.alipay.sdk alipay-sdk-java 4.11.54.ALL
這個是重點,開發一個支付寶消息配置類,支付寶服務端有消息通知時會自動觸發。
@Component@Configuration@EnableConfigurationProperties({AliPayProperties.class})public class AliPayMsgConfig { private static Logger logger = LoggerFactory.getLogger(AliPayMsgConfig.class); private AliPayProperties aliPay; public AliPayMsgConfig(AliPayProperties aliPay) { this.aliPay = aliPay; } @Bean public AlipayMsgClient alipayMsgClient() throws Exception { AlipayMsgClient alipayMsgClient = AlipayMsgClient.getInstance(aliPay.getAppId()); alipayMsgClient.setConnector("openchannel.alipay.com"); alipayMsgClient.setSecurityCertConfig(aliPay.getSignType(), FileUtil.readUtf8String(aliPay.getAppCertPrivateKeyPath()), aliPay.getAppCertPublicKeyPath(), aliPay.getAliPayCertPublicKeyPath(), aliPay.getAliPayRootCertPath()); alipayMsgClient.setCharset(aliPay.getChartSet()); alipayMsgClient.setMessageHandler(new MsgHandler() { /** * 客戶端接收到消息后回調此方法 * @param msgApi 接收到的消息的消息api名 * @param msgId 接收到的消息的消息id * @param bizContent 接收到的消息的內容,json格式 */ @Override public void onMessage (String msgApi, String msgId, String bizContent) { logger.info("receive message. msgApi:{},msgId:{},bizContent:{}", msgApi, msgId, bizContent); if (StringUtils.equals("alipay.open.app.api.field.changed", msgApi)) { logger.info("用戶信息申請記錄審核通知,接收到的消息內容:{}", bizContent); } else if (StringUtils.equals("alipay.open.auth.appauth.cancelled", msgApi)) { logger.info("第三方應用授權取消消息,接收到的消息內容:{}", bizContent); } else if (StringUtils.equals("alipay.open.auth.userauth.cancelled", msgApi)) { logger.info("用戶授權取消消息,接收到的消息內容:{}", bizContent); } else if (StringUtils.equals("alipay.open.mini.version.audit.passed", msgApi)) { logger.info("小程序審核通過通知,接收到的消息內容:{}", bizContent); } else if (StringUtils.equals("alipay.open.mini.version.audit.rejected", msgApi)) { logger.info("小程序審核駁回通知,接收到的消息內容:{}", bizContent); } else if (StringUtils.equals("alipay.trade.refund.depositback.completed", msgApi)) { logger.info("收單退款沖退完成通知,接收到的消息內容:{}", bizContent); } else if (StringUtils.equals("alipay.open.mini.merchant.confirmed", msgApi)) { logger.info("商戶確認服務商代創建小程序結果通知,接收到的消息內容:{}", bizContent); } } }); alipayMsgClient.connect(); return alipayMsgClient; }
上面代碼的AliPayProperties類是配置了應用的一些參數信息,包括應用id、加簽類型、應用私鑰證書路徑、應用公鑰證書路徑、支付寶公鑰證書路徑、支付寶根證書路徑、編碼格式。
@Data@ConfigurationProperties(prefix = "alipay")public class AliPayProperties { /** * 加簽類型 */ private String signType; /** * 應用id */ private String appId; /** * 請求使用的編碼格式,如utf-8,gbk,gb2312等 */ private String chartSet; /** * 應用私鑰證書路徑 */ private String appCertPrivateKeyPath; /** * 應用公鑰證書路徑 */ private String appCertPublicKeyPath; /** * 支付寶公鑰證書路徑 */ private String aliPayCertPublicKeyPath; /** * 支付寶根證書路徑 */ private String aliPayRootCertPath;}
當支付寶服務端有給客戶端發送消息時,會回調MsgHandler里面onMessage的實現,因此可以在onMessage中處理接收到的消息,根據msgApi消息名判斷是哪種接口來處理對應的業務邏輯。
但需要注意的是,因各種異常原因,支付寶服務端可能會重復通知,因此為了業務不重復被處理,需要做冪等性的控制,可根據每條消息的唯一msgId或者自身系統的業務id比如uuid來事先查詢。
您的一鍵三連,是我更新的最大動力,謝謝
山水有相逢,來日皆可期,謝謝閱讀,我們再會
我手中的金箍棒,上能通天,下能探海
上一篇:??一不小心,登上支付寶開發者社區熱文榜單Top3??