接支付寶支付, 服務端下載 java sdk, 客戶端接入android sdk, 設置好沙箱。按照官網流程一步步來,最后進行測試
- 服務器生成一個支付參數字符串,傳給客戶端
- 客戶端用服務器給的支付參數,拉起支付寶(沙箱版)
最后支付寶卻傳來一個失敗的map:
{resultStatus=6001, result=, memo=用戶取消}
問題排查
通過使用官方的支付客戶端demo(在demo中生成支付參數),設置好沙箱,私鑰等,結果正常拉起支付寶支付,支付成功。
這里可以確定設置的密鑰是沒有問題的,問題就是在支付參數這里了。
支付參數是由 server-java-sdk 來生成的,對比官網的使用示例,一切都一樣,這樣下來,就確認是 server-java-sdk 生成的字符串不正確了。想來這個問題也只有出現在沙箱版吧,不然正式版出現這個問題早爆炸更新了。所以最大可能是 server-java-sdk 生成的字符串沙箱支付寶不支持。
首先對 server-java-sdk 生成的字符串進行簽名校驗(官方工具),確定簽名正確。然后與官方的支付客戶端demo 生成的字符串仔細比較:
# 官方的支付客戶端demo 生成的字符串
charset=utf-8&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%220414213511-7518%22%7D&method=alipay.trade.app.pay&app_id=2016091500518622&sign_type=RSA2&version=1.0×tamp=2018-04-14+18%3A04%3A03&sign=WnfXnYtpE6%2BtUbq9Zxs3w4n%2Fe%2F%2FQxiN5B1rSsGcNjmbWSVeCHs95a3VksCIt58dRJWj4fza5KwQ0ZHOeLMVEAnZwtjYYSHO96uXYeCG0uf4fm%2FlwWYRuKse5LRW1Sh2QyaVLmn3FcZH9bEnmGaTBHcCcTt%2BPa2KK8cQMNFw6WrLLElmXk4iwXrlwCjoSScots4QIbXK2qBoDPqdHo4i%2BWoNM4V80dPQh0YieNW5AtfOtPeTNBWcvhj9fZ0obrI%2B%2Bd0TQxQzCYyOPnpDOYr9%2FaDsuG4J1SiBPRMzyysPcG9%2BC%2F8kp2iZKQQmuyTGYO9JOZnhix9O2YsGBmx5sKPwbFw%3D%3D
# server-java-sdk 生成的字符串
alipay_sdk=alipay-sdk-java-dynamicVersionNo&app_id=2016091500518622&biz_content=%7B%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%221523714442123-8740%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22subject%22%3A%221%22%2C%22timeout_express%22%3A%2230m%22%2C%22total_amount%22%3A%220.01%22%7D&charset=utf-8&format=json&method=alipay.trade.app.pay&sign=JxVUnDm6I1Pwht%2BknWf6527gyM7zzeGli%2BMm3XWT19YuDcuFuc%2Fr46Qx7rB6m7ckKTPXsK2blEApWTgKvK7uA6sv0nTuCPcLD07DH6wNKygD5F%2By7tZT8M%2BWLugDZx%2BkVBmvNJ4RJDz5KtOx8g%2Fhjs6fWCUH6avWeOLsr9NVP1Jn1hrGL6%2BiCGWO7pPhGHtW7qvibfIAHM5ONBieCZ0xHqlCJDm6NWKJYj7X3avE4uAc%2Fd6TI1rL2i3T30ntAcIqQaj1XGYTJLnPRAqO%2BMDRg4gc6j39Km7lTSiwmaTV2TzHkzZhioOA3gyQa%2FdADuEuuTPEQnf%2FvaqpIzp%2BYcGomg%3D%3D&sign_type=RSA2×tamp=2018-04-14+22%3A00%3A42&version=1.0
發現官方的支付客戶端demo 生成的字符串中 sign 參數總在最后,而 server-java-sdk 生成的卻是在內部,然后對 server-java-sdk 生成的字符串調整:將 sign 參數移動到尾部,測試OK:
(defn trans-alipay-pay-order-string [order-string]
"將支付寶支付參數字符串中 sign 參數移動到尾部,以支持沙箱支付寶測試"
(let [start-index (clojure.string/index-of order-string "&sign=")
end-index (and start-index
(clojure.string/index-of order-string "&" (inc start-index)))]
(if (and start-index end-index)
(str (.substring order-string 0 start-index)
(.substring order-string end-index)
(.substring order-string start-index end-index))
order-string)))
總結
總的來說是沙箱支付寶的一個bug,可能是用的少,大部分開發同學用1分錢測試大法在正式上線應用中測,所以沒有留意這個問題。