微信、支付宝我的收款的一种实现思路

题目里说的我的收款指的不是普通的扫个码,而是说那种能够支持回调的,例如网上商城支付以后,商城能够知道支付状态而且自动修改订单的状态为“已支付”。这种支付的形式,不管是微信、支付宝仍是银联,目前都是不对我的开放的,必须有企业资质才能申请。可是对于不少开发者而言,有时候就是一个小小的验证性应用,想要拥有支付功能,而本身又没有企业资质,天然无法申请到微信支付宝这种接口,甚至连第三方的聚合支付(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

相关文章
相关标签/搜索