作為個(gè)人 DIY 玩家,有沒(méi)有辦法在自己的作品上增加掃碼支付相關(guān)的功能呢?比如通過(guò)掃碼支付控制設(shè)備實(shí)現(xiàn)不同的功能呢。想法雖然美好,但現(xiàn)實(shí)卻是殘酷的,因?yàn)榇蠖鄶?shù)支付接口并不針對(duì)個(gè)人開(kāi)放,個(gè)人想要實(shí)現(xiàn)掃碼支付效果,一般只能通過(guò)第三方服務(wù)實(shí)現(xiàn)。本教程中,我將介紹一種第三方服務(wù),它是一個(gè)獨(dú)立開(kāi)發(fā)者個(gè)人即時(shí)到賬收款平臺(tái),可以通過(guò)監(jiān)測(cè)手機(jī)通知從而驗(yàn)證支付狀態(tài),驗(yàn)證支付成功之后,我們就可以 DIY 各種掃碼付費(fèi)項(xiàng)目啦。

本教程中,我給大家制作了一個(gè)掌上 POS 機(jī)為大家演示掃碼收款功能,演示視頻地址如下:

在這個(gè)項(xiàng)目中,我們實(shí)現(xiàn)了類似 POS 機(jī)的效果,不僅可以設(shè)置收款金額,而且還可以選擇收款方式,比如支付寶、微信、QQ等,用戶掃碼后就可以實(shí)現(xiàn)支付。

預(yù)期目標(biāo)及功能

  • 觸摸鍵盤功能;
  • 支付圖標(biāo)顯示;
  • 支付方式選擇;
  • 二維碼生成;
  • 網(wǎng)絡(luò)狀態(tài)反饋;
  • 觸摸震動(dòng)反饋;

所用硬件

  • M5Core2 模塊

M5Core2 具有如下特點(diǎn):

  • 基于 ESP32 開(kāi)發(fā),支持 WiFi,藍(lán)牙;
  • 16M 閃存,8M PSRAM;
  • 內(nèi)置揚(yáng)聲器,電源指示燈,震動(dòng)馬達(dá),RTC,I2S 功放,電容式觸摸屏,電源鍵,復(fù)位鍵;
  • TF 卡插槽(支持最大 16GB);
  • 內(nèi)置鋰電池,配備電源管理芯片;
  • 獨(dú)立小板內(nèi)置 6 軸 IMU,PDM 麥克風(fēng);
  • M-Bus 總線插座。

程序設(shè)計(jì)

下面開(kāi)始詳細(xì)講解程序設(shè)計(jì)過(guò)程。

開(kāi)發(fā)環(huán)境

我們使用 Arduino IDE 來(lái)編寫(xiě)本項(xiàng)目的程序,上傳程序時(shí)開(kāi)發(fā)板選擇 M5Stack-Core2.編程過(guò)程中需要用到的軟件及庫(kù),將會(huì)打包作為附件給大家下載,詳見(jiàn)文末下載說(shuō)明。

程序思路

為了實(shí)現(xiàn)項(xiàng)目的所有功能,我們先根據(jù)預(yù)期的目標(biāo)繪制思維導(dǎo)圖,再根據(jù)思維導(dǎo)圖逐步實(shí)現(xiàn)自制 POS 結(jié)算終端機(jī)的功能。

下面我們將詳細(xì)討論自制結(jié)算終端的各個(gè)子功能是怎么實(shí)現(xiàn)的。

觸摸按鍵測(cè)試程序

我們想要使用觸摸屏實(shí)現(xiàn)金額的輸入以及支付方式的選擇,離不開(kāi)設(shè)計(jì)觸摸按鍵。M5Core2 為我們提供了成熟的解決方案,我們可以輕易地繪制一個(gè)按鍵,并且設(shè)置指定的區(qū)域,觸摸按鍵的使用示例如下:

其中:

ButtonColors on_clrs = {YELLOW, WHITE, WHITE}ButtonColors off_clrs = {BLACK, WHITE, WHITE}Button tl(0, 0, 0, 0, false , "Button", off_clrs, on_clrs, MC_DATUM)doButtons()eventDisplay(Event& e)
M5Core2.h

觸摸按鍵效果測(cè)試

上傳上面的測(cè)試程序,打開(kāi)串口監(jiān)視器,點(diǎn)擊 M5Core2 屏幕上的觸摸按鍵可看到下圖所示內(nèi)容:

可以看到:

  • 當(dāng)點(diǎn)擊程序定義的觸摸按鍵時(shí),串口會(huì)返回按鍵的標(biāo)簽字符串 Button 以及按下的持續(xù)時(shí)間以及坐標(biāo)區(qū)域;
  • 當(dāng)點(diǎn)擊未被程序設(shè)置的區(qū)域時(shí),返回的字符串是 background;
  • 當(dāng)點(diǎn)擊觸摸屏上的此外三個(gè)默認(rèn)觸摸按鍵時(shí),返回 BtnA,BtnB 或 BtnC。
e.typeName()e.objName()E_RELEASE

主界面 UI 設(shè)計(jì)

M5.Lcd.drawRoundRect()

圖標(biāo)顯示

M5.Lcd.drawXBitp()M5.Lcd.drawBitp()

對(duì)于單色圖標(biāo),可以通過(guò)取模軟件 Ige2Lcd 取模。在 Ige2Lcd 軟件中,選擇需要取模的圖片,根據(jù)自己的屏幕類型,調(diào)整取模方式、取模大小、亮度,最后導(dǎo)出取模數(shù)據(jù)。設(shè)置如下:

對(duì)于貨幣符號(hào) ¥ 我們使用 Mixly 軟件中的取模工具獲取字模,取模設(shè)置如下:

對(duì)于彩色圖片,可以使用 IgeConverter 軟件獲取彩色圖片取模數(shù)據(jù),其界面如下,選擇需要取模的圖片并調(diào)整其大小,最后導(dǎo)出為 C 語(yǔ)言取模數(shù)據(jù)即可:

按鍵功能以及 UI 設(shè)計(jì)

Input_data

在上面的程序當(dāng)中,我們還應(yīng)該考慮輸入字符串的特殊問(wèn)題例如,首位不能是小數(shù)點(diǎn),首位不能連續(xù)兩個(gè) 0 等問(wèn)題,其他問(wèn)題請(qǐng)自行分析,此處省略了取模數(shù)據(jù),上傳該程序效果如下:

WiFi 連接反饋

當(dāng)沒(méi)有連接網(wǎng)絡(luò)時(shí),網(wǎng)絡(luò)應(yīng)當(dāng)自動(dòng)連接并且反饋當(dāng)前的連接狀態(tài),實(shí)現(xiàn)代碼如下:

使用此方式連接網(wǎng)絡(luò)比直接初始化連接網(wǎng)絡(luò)更好,其主函數(shù)不會(huì)受網(wǎng)絡(luò)狀況的影響且可以自動(dòng)連接網(wǎng)絡(luò),在以后使用 ESP 系列連接網(wǎng)絡(luò)都建議使用此種方式。加上連網(wǎng)反饋后效果如下:

發(fā)起支付請(qǐng)求

完成上面的程序后,當(dāng)我們輸入金額并確認(rèn)支付方式時(shí),按下 CON 確認(rèn)鍵會(huì)發(fā)出訂單請(qǐng)求,生成訂單號(hào)并顯示支付二維碼。

這里我們用到了第三方服務(wù)奇跡碼支付(http://pay.qj61.cn/login),進(jìn)入官網(wǎng),按提示注冊(cè)以及上傳自己的收款二維碼,并下載安裝其軟件監(jiān)聽(tīng)通知,按提示進(jìn)行設(shè)置,并保證監(jiān)聽(tīng)軟件與收款賬號(hào)為同一個(gè)手機(jī)。微信可以開(kāi)啟店員功能,則無(wú)需保證同一手機(jī),監(jiān)聽(tīng)軟件必須保證不被后臺(tái)清除。完成上面步驟后,再來(lái)簡(jiǎn)單了解下其 API 的構(gòu)成,我們重點(diǎn)查看其訂單生成與支付狀態(tài)驗(yàn)證。

訂單生成

通過(guò)對(duì)文檔分析可以得到訂單生成的 API 為:

http://pay.qj61.cn/createOrder?mid=<mid>&payId=<payId>&type=<type>&price=<price>&sign=<sign>&param=<param>&isHtml=0

其中 sign 為訂單信息與密鑰的 MD5 加密信息,MD5 是一種加密技術(shù),可以通過(guò)百度獲取其加密原理,在這里我們可以通過(guò) MD5 在線加密獲取這個(gè)加密信息,替換參數(shù)就能生成這個(gè)訂單。上面的例子中給我們演示了 MD5 加密和加密后的問(wèn)題,在這里我們通過(guò) MD5 加密庫(kù)文件對(duì)原數(shù)據(jù)進(jìn)行加密,加密程序如下:

DIY掌上POS機(jī)(POS機(jī)做手腳)
md5_string()

訂單返回?cái)?shù)據(jù)

等我們成功生成訂單并返回?cái)?shù)據(jù)后,我們需要對(duì)返回的 JSON 數(shù)據(jù)進(jìn)行分析,從而得到我們想要的數(shù)據(jù)。在反饋的數(shù)據(jù)當(dāng)中,我們希望獲取的是云端訂單號(hào),我們將通過(guò)查詢?cè)撚唵翁?hào)來(lái)獲取是否支付成功,在這里我們通過(guò) ArduinoJson 庫(kù)對(duì)返回的數(shù)據(jù)進(jìn)行分析,我們可以通過(guò) ArduinoJson 助手(https://arduinojson.org/v6/assistant/)在線反序列 JSON 數(shù)據(jù)得到想要的結(jié)果。此處獲得解析結(jié)果的代碼如下:

我們對(duì)以上結(jié)果進(jìn)行分析,刪除無(wú)關(guān)數(shù)據(jù)后處理結(jié)果如下:

訂單狀態(tài)驗(yàn)證

通過(guò)對(duì)文檔的分析可得到查詢訂單狀態(tài)的 API 為:

同理我們用 ArduinoJson 助手解析返回的數(shù)據(jù),可以得到當(dāng)返回的訂單狀態(tài) state,當(dāng) state 大于 0 那么就認(rèn)為支付成功。

發(fā)送 API 請(qǐng)求

ESP32 發(fā)送 get 請(qǐng)求方式如下:

顯示二維碼

通過(guò)對(duì)上面文檔的分析和 ESP32 發(fā)送 get 請(qǐng)求的案例,我們已經(jīng)可以生成訂單并且獲取訂單支付結(jié)果了。當(dāng)訂單生成后,我們需要將訂單轉(zhuǎn)換成二維碼。

訂單驗(yàn)證

顯示完二維碼以后,我們給定一個(gè)超時(shí)時(shí)間,例如 60 秒:

  • 若 60 秒內(nèi)完成付款,應(yīng)當(dāng)顯示付款成功的提示圖標(biāo),并停留一段時(shí)間后返回主界面;
  • 若超時(shí)限定時(shí)間,則顯示付款失敗提示圖標(biāo),并停留一段時(shí)間后返回主界面。
M5.update()

震動(dòng)反饋

M5Core2 內(nèi)置了一個(gè)振動(dòng)馬達(dá),在這里我們按下定義的按鍵以及顯示二維碼時(shí),可以讓振動(dòng)馬達(dá)發(fā)出震動(dòng),增強(qiáng)作品的體感效果,控制振動(dòng)馬達(dá)的主要程序如下:

語(yǔ)音提示

為了增加作品的趣味性,我們可以在收款成功后播放語(yǔ)音提示,ESP32 的 i2s 可以讓我們直接播放簡(jiǎn)短音頻,可以利用 M5Core2 的揚(yáng)聲器播放零錢到賬的聲音,程序如下:

在上面的程序當(dāng)中,M5Core2 將每隔一秒播放一次音頻,這里我們省略了音頻數(shù)據(jù),獲取音頻數(shù)據(jù)方式如下,先準(zhǔn)備一段 W 的簡(jiǎn)短音頻,通過(guò)軟件 HxDSetup 打開(kāi)該音頻,并按下圖所示導(dǎo)出:

該程序及軟件的完整例子請(qǐng)查看附錄文件。

代碼組合

最后,按照上述功能之間的邏輯關(guān)系,將代碼組合在一起即可。由于篇幅限制,這里就不放完整的代碼了,文中的所有案例以及完整程序大家可以通過(guò)下載附件進(jìn)行查看。

小結(jié)

本項(xiàng)目中,我們以近乎零成本的方式實(shí)現(xiàn)了二維碼支付的問(wèn)題,你甚至可以僅通過(guò) 1 塊 ESP8266 開(kāi)發(fā)板而不需要屏幕來(lái)完成本項(xiàng)目。支付方式取決于你使用的第三方服務(wù),在這里僅支持了主流的微信支付與支付寶,在最新一代的第三方服務(wù)當(dāng)中你甚至可以不需要監(jiān)聽(tīng)軟件就可以實(shí)現(xiàn)本項(xiàng)目,但他們可能需要少許的費(fèi)用。

本項(xiàng)目以體驗(yàn)為主,讓大家以最低成本去實(shí)現(xiàn)屬于你自己的共享經(jīng)ji項(xiàng)目。以本項(xiàng)目為基礎(chǔ)可以擴(kuò)展很多共享經(jīng)ji作品,比如自動(dòng)販賣機(jī),或者你也可以制作一個(gè)笑話售賣機(jī),一分錢看一則笑話。你的腦洞決定了你的作品,讓我們一起腦洞大開(kāi)吧!