最近有小伙伴有這方面的需求,市場上又沒有十分靠譜的現成的解決方案,於是花了一天的時間把微信和支付寶的POS集成模塊做了出來。這里記錄一下開發的大概流程和使用介紹。
支付寶
我們之前是對接過支付寶在線支付的,而且因為支付寶有沙箱環境,因此,對接的比較流暢。我們先去支付寶開發中心注冊一個開發者賬號,然后可以拿到支付寶的沙箱環境賬號和密鑰。這里需要一部安卓手機,因為支付寶的沙箱錢包只有安卓版沒有蘋果版本。
沙箱應用中可以找到 APPID,設置密鑰 和商家密鑰等關鍵參數。
根據我們之前對接支付寶在線支付的經驗,我們需要的參數有一下幾個:
- App Seller Id: 支付寶商家ID
- Alipay App Id: 支付寶應用ID
- Mechant Private Key: 商戶私鑰
- Alipay Public Key: 支付寶RSA公鑰
- Sign Type: 加密方式
其中支付寶RSA公鑰可以通過支付寶提供的生成工具生成,也可以直接自己生成,具體方法參考官方文檔,這里不贅述了。
接下來,我們開始對接。首先,我們要搞清楚POS條碼支付的流程(區別於用戶主動掃碼支付,這里稱之為條碼支付):
- 用戶出示條碼/二維碼,實際是出示了自己條碼支付的授權碼
- 商戶在通過掃描到自己的系統中之后,系統通過條碼支付接口發起扣款請求
- 用戶在手機端確認金額
- 商戶系統扣款成功
- 用戶收到扣款通知
其中第3步,通常為了支付的便捷,小額支付通常會跳過這一步。
因為支付過程中可能會碰到失敗的情況,因此需要商戶在系統中獲取到用戶支付中這個狀態的時候,進行主動查詢確認,一般經過三次嘗試如果仍舊支付不成功時,調用撤銷接口取消交易。對應到后台,我們需要三個接口:
- 支付接口
- 查詢接口
- 撤銷接口
支付接口
def barcode_pay(self, order_no, subject, auth_code, amount): """條碼支付""" # 條碼支付 alipay = self._get_alipay_client() _logger.debug(f"POS支付寶條碼支付:{order_no},{subject},{amount}") res = alipay.pay.trade_pay( order_no, 'bar_code', auth_code, subject, total_amount=amount) _logger.debug(f"POS支付寶支付結果:{res}") return res
查詢接口
def query_payment(self, trade_no): """查詢支付結果""" alipay = self._get_alipay_client() res = alipay.pay.trade_query(trade_no=trade_no) _logger.debug(f"POS支付寶交易查詢結果:{res}") return res
撤銷接口
def cancel_payment(self, trade_no): """取消交易""" alipay = self._get_alipay_client() res = alipay.pay.trade_cancel(trade_no=trade_no) _logger.debug(f"POS支付寶交易取消:{trade_no}") return res
為了在POS系統中新增一個支付方法,我們需要新增一個支付方法,支付寶,並將我們之前講到的參數放到設置里:其中,查詢和取消接口均可以使用商戶訂單號或者支付寶流水號,這里我們為了方便起見統一用的時支付寶流水號。
然后我們在門店的設置里新增這個支付方法:
新增之后,我們就可以在POS界面看到新增的支付方法了。
前端的對接相對比較復雜,我們要繼承PaymentInterface對象,新生成一個PaymentAlipay 對象,負責處理前端的業務請求。
其中最主要的方法是處理后端傳過來的響應並作出合適的反饋:
_alipay_handle_response: function (response) { var line = this.pos.get_order().selected_paymentline; var self = this; if (response.code == '10000') { self._alipay_success(response.trade_no) self.pos.gui.close_popup(); } else if (response.code == '10003') { line.set_payment_status("pending") this.pos.gui.show_popup('confirm', { 'title': '支付中', 'body': '等待用戶付款', 'confirm': this.check_payment, 'cancel': this.cancel_payment, 'payment_method': line.payment_method, 'trade_no': response.trade_no }); } else if (response.code = '40004') { line.set_payment_status("pending") this.pos.gui.show_popup('error', { 'title': '支付失敗', "body": response.sub_msg }); } },
10000: 支付成功支付寶在支付以后,通常會返回一下幾種狀態的結果:
- 10003: 用戶支付中
- 40004: 支付失敗
其中 10003代表等待用戶確認支付,一般出現在大額支付或者長期未使用的客戶中,此時商戶應該等待用戶支付完成后,進行查詢操作,然后完成后續的業務處理。
微信支付
微信支付的整體流程與支付寶一致,區別在於微信支付的金額單位是分,因此我們需要在處理過程中做一些處理,另外,微信的商戶訂單號並部支持空格,因此對於odoo默認的”Order 12345”這種訂單號也需要做適配,同樣地,我們在交易查詢和交易撤銷的接口中也應該使用微信的交易號而不是商戶訂單號。
效果展示
支付成功:
支付失敗:
需要的同學歡迎到我的淘寶購買哦