微信、支付寶我的收款的一種實現思路

題目裏說的我的收款指的不是普通的掃個碼,而是說那種能夠支持回調的,例如網上商城支付以後,商城能夠知道支付狀態而且自動修改訂單的狀態爲「已支付」。這種支付的形式,不管是微信、支付寶仍是銀聯,目前都是不對我的開放的,必須有企業資質才能申請。可是對於不少開發者而言,有時候就是一個小小的驗證性應用,想要擁有支付功能,而本身又沒有企業資質,天然無法申請到微信支付寶這種接口,甚至連第三方的聚合支付(Ping++)也是沒法申請的。本文就介紹一種利用我的支付寶(微信也是能夠的)本身實現支付功能的思路,成本是一部舊的安卓手機,其餘的都是徹底免費的,配合支付寶的收款碼(提現免費),能夠作到零費率api

1、基本思路

這個方案的基本思路是很是簡單的,跟以前你們經常使用的用爬蟲爬取網頁帳單數據相似,可是這裏咱們用的是手機App。相對來講,截取手機App的推送消息更爲簡單,不須要應爲微信支付寶的各類反爬措施;可是缺點是可以獲取到的信息較少,沒有諸如流水號、付款人之類的信息,只有一個金額。服務器

因此,咱們的思路就是:微信

  1. 建立一個訂單,將二維碼(定額或者非定額均可以)展現給用戶
  2. 用戶支付後,商家手機App上收到支付寶的付款推送
  3. 安卓App截取支付寶的付款推送,而後將付款信息發送給服務器
  4. 服務器根據付款金額,肯定究竟是哪一筆訂單,而後將該訂單標記爲「已付款」,而後根據須要進行回調通知之類的操做。

2、關鍵問題及其解決方案

這個方案裏的關鍵問題有如下幾個:網絡

1.支付寶App的通知截取

這個問題其實網上已經有不少的解決方案了,其利用的是Android中的NotificationListenerService這個類,經過註冊這個Listener,能夠在推送通知彈出來的時候,獲取到其發送的App、標題、內容等信息。咱們最關心的就是App和推送內容。併發

判斷髮送App的包爲支付寶的包,而後再從推送的內容中獲取到具體的內容,便可獲得付款金額。ide

示例代碼以下:高併發

public class AlipayNotificationListenerService extends NotificationListenerService {
    public AlipayNotificationListenerService() {
    }

    @Override
    public void onNotificationPosted(StatusBarNotification sbn) {
        // 這裏能夠拿到包名,能夠按照須要判斷。
        String packageName = sbn.getPackageName();
        Notification notification = sbn.getNotification();
        if (notification == null) {
            return;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            Log.e("SevenNLS","in 1");
            Bundle extras = notification.extras;

            if (extras != null) {
                // 這裏是具體的title和content,能夠從中提取金額
                String title = extras.getString(Notification.EXTRA_TITLE, "");
                String content = extras.getString(Notification.EXTRA_TEXT, "");
                Log.d("Zachary", "title:" + title + "   content:" + content);
            }
        }
    }

    @Override
    public void onListenerConnected()
    {
        Log.e("Zachary","connected");
    }


}

固然,爲了讓這個App可以順利進行,還要給它獲取通知的權限,保證它不被清理等等,須要作一些相應的保護措施。微信支付

2.訂單的肯定

剛纔咱們說過,服務器收到App發來的收款信息以後,還須要找到對應的訂單。這一步是相對比較難的一步,由於咱們知道相同金額的訂單可能有不少,到底哪個纔是剛剛支付的訂單呢?網站

這裏,咱們能夠再詳細思考一下,其實這個訂單不只僅是由這個金額肯定的,而是一個多元組共同肯定的。最簡單的一種實現方式就是 (訂單金額-支付狀態)。經過這個二元組能夠肯定一個訂單。其含義是,若是這個訂單已經支付過了,那麼我在查找訂單的時候,就能夠不用理會它了,我只須要查找(指定金額-未支付)的訂單就能夠了。ui

這樣能夠基本解決這個問題。可是,咱們考慮到除了正常支付外,還有可能會有另一些狀況。好比用戶建立了訂單以後,忽然不想支付了,沒有進行接下來的操做。或者說,有人惡意在網站上建立了大量的訂單而且不支付。 這樣的後果是,這些訂單的狀態永遠都是未支付,當你想要繼續建立訂單的時候,就會受到限制,不能建立跟這些訂單相同金額的訂單,不然你的系統將沒法分辨究竟是哪一筆訂單被支付了。

爲了應對這種狀況,咱們想到其實不少的支付都是有時間限制的,也就是說,訂單是有有效期的,一旦過了有效期,訂單就不能被支付了。因此咱們也能夠給訂單加一個有效時間的限制,好比5分鐘,一旦五分鐘內沒有被支付,就認爲這個訂單已經失效了。這時,訂單的肯定方式就變成了一個三元組(訂單金額-支付狀態-是否過時)。查找的時候,只須要查找(指定金額-未支付-未過時)的訂單就能夠了。也就是說,任意一個訂單,最多隻會佔用這個金額5分鐘,一旦超過五分鐘,無論支付與否,你均可以繼續建立相同金額的訂單了。

可是這樣咱們仍是以爲不滿意,特別是對於某些支付金額相對單一的狀況,可能每次都須要建立相同金額的訂單,這樣的話,再最壞狀況下咱們只能每隔五分鐘處理一個訂單,這個效率能夠說是很是低效了。

在這裏,咱們提出了一種trade-off的解決方法。通常的正常支付是不會使用這種方式的,也難以接受,可是對於咱們來講,爲了不企業資質的認證和手續費,在必定程度上是能夠接受的。

這種方式就是,當目前系統中已經有了某一金額的訂單的時候,若是咱們要繼續建立相同金額的訂單,那麼咱們就在指定金額上進行上下浮動,好比下浮一分錢,這樣金額就能夠和以前的訂單區分開來,避免出現不能同時支付的狀況。這樣,雖然咱們在高併發狀況下可能會有必定的損失(同時支付的人越多,差距越大),可是知足了咱們的高併發要求。

友情提示:若是金額發生浮動,能夠告訴用戶這是隨機立減,必定程度上能夠避免訂價和實際支付金額的差距帶來的問題。(這種狀況下就只能下浮,不能上浮,否則就變成隨機立加了)。

3、總結

整體上來講,我認爲這種方案對於普通的我的用戶來講,是一種能夠接受的方案。其優缺點總結以下:

優勢:

  1. 不須要企業資質
  2. 沒有手續費
  3. 不對支付寶進行任何操做,沒有被支付寶進行風控的風險

缺點:

  1. 須要有一部手機一直運行,且要求網絡條件良好,不然會丟失支付數據(能夠有人工解決方案)
  2. 高併發時,訂單金額會產生浮動
  3. 若是金額浮動策略不合理,而且被人探索出規律,可能形成財產損失!!(例如短期內建立大量訂單,這樣訂單價格會不斷降低,須要針對這種狀況作出防範)

參考:
PaysApi: www.paysapi.com

相關文章
相關標籤/搜索