一篇搞定Android 实现扫码支付:如何对接海外的第三方支付;项目中的真实经验分享;如何高效对接,高效开发

目录

前言

接下来的几篇文章,我会介绍一下,在实际项目中,我们会介绍,如何接入第三方支付(国外),比如纸币、找零、扫码以及刷卡等。

我们将深入探讨在接入这些支付系统前所需的准备工作、接入过程中双方的协作方式,以及接入完成后的交付流程。这些经验均源自我的亲身开发实践。

在这个过程中,我遇到了不少挑战,也浪费了许多宝贵的时间。因此,我迫切希望将这些经验分享给你们,以帮助你们在未来的项目中更加顺利地完成支付系统的接入。

这些支付方式在自动售卖机中尤为常见,特别是在海外,自动售卖机几乎随处可见。为了满足无人值守的支付需求,这些设备迫切需要接入高效、便捷的支付系统。

本篇文章,我将重点介绍扫码支付。


一、需求场景:扫码支付(开发前对接,需要对方提供信息)

当需求来以后我们应该如何对接呢?

今天我们收到需求,客户要我们的自动售卖机,接入一个日本的支付方式。那么我们需要对方提供什么?

  1. 提供对应的API文档。这样我们就可以评估是否可以接入到我们Android程序里面,还是说要建立一个后台系统才行。
  2. 提供测试环境。比如密钥、id等账户信息,用于我们测试使用。不然无法测试对应的流程。
  3. 建立对应的微信群,或whatsApp。因为对方给的信息不一定是正确的,我们调试过程中会遇到各种问题,需要建立这样的一个技术群取进行对接,这样会加快我们的效率,实在不行才会考虑邮箱,但邮箱的回复是非常慢的。
  4. 如果有对应的Android Demo对接实例,会更加快速的加速我们的开发,因为有些支付公司的对接,加密是非常麻烦的,如果能提供可运行的项目,对我们的效率提升非常大。

有了这些大致的信息,我们就可以开始测试,然后进行开发时间的评估。


二、阅读、测试对方提供的API

我们看一个具体的支付公司的案例,比如我们要接入日本的Take Me支付。

官网:docs.takeme.com/references/... 跟客户明确好,我们具体要开发哪一种,因为TakeMe的文档里面有很多种支付 比如我们要开发的是Universal Payment,简单介绍一下这种支付方式的流程如上图,Payment flow

  1. 我们(Shop)要创建一个二维码出来,要给消费者扫码进行支付,所以我们需要发送请求给TakeMe的服务器。需要我们提供金额,这样他才能知道具体要创建多少金额的二维码,也要提供订单号,后面你要根据订单号去查询是否支付成功。
  2. 那么二维码返回后,我们就进行展示,消费者开始扫码。
  3. 接着我们要开始查询订单,是否支付成功,如果支付成功,启动自动售卖机出商品。
  4. 商品出来以后,我们要上传一个信息,告知商品出货成功,如果失败则上传出货失败。

好的,大体的流程,其实就是这样。所以从上面我们也可以得出,具体我们需要对方提供哪些接口,我们看看他的文档。核心的接口:

  1. Create a PredefinedPayment for online usage. :创建一个二维码,TakeMe会返回一个url,我们在代码里面将其转换成一个二维码。
  2. Retrieve a PredefinedPayment:根据订单号查询是否结果如何。 第三个接口,上传出货状态,这里没有,有些支付不提供这个接口。

2.1 开始测试API

这个时候,我们先不要写代码,没错,还不需要写代码。我们要借助Postmen工具或者Apifox工具,进行接口的测试。

为什么要这样呢?为什么不直接写代码呢?

因为在测试过程中,你会遇到千奇百怪的问题,如果你用代码,他们会怀疑写的代码有问题,请求体有问题,接口没有设置好,等等各种怀疑,会导致各种甩锅,尤其是和国外的人交流,语言不通,只能靠翻译,解释起来就更加的麻烦,浪费时间。

所以我们推荐使用Postmen工具或者Apifox工具,大家都在使用,并且参数的设置,全部都摆在那里,究竟是谁的问题,一看便知。

所以写代码之前,一定要使用这个工具先跑一遍。确保对方没有问题后,才进行写代码。


2.2 接口API详解

(1)请求二维码的接口:Create a PredefinedPayment for online usage.

这个官方文档,还是非常的厉害的,提供的信息非常的清晰,连接是怎么样,需要什么请求参数,响应体是什么。 【请求信息】

  1. amount:是金额
  2. custom:是备注信息,你可以填写商品名字,比如你卖出了草莓冰淇淋,就写草莓冰淇淋,菠萝,就菠萝。这样就知道这笔订单做的是什么。
  3. redirection_url:是支付成功后跳转的url
  4. expires_after:是二维码的过期时间

【响应信息】 参数太多了,我们就简单介绍几个关键信息

  1. token:用于查询支付状态的信息,后面我们会用到,我们需要保存起来。
  2. url:二维码url

(2) 根据订单号查询是否结果如何:Retrieve a PredefinedPayment

将第一个接口获取的token带入进去即可。 【响应参数】

  1. fulfilledf返回true就是支付成功

三、代码示例

  1. 使用retrofit发起网络
java 复制代码
japanRetrofit = new Retrofit.Builder()
                .client(builder.build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl("https://stg.ribenmeishi.com/")
                .build();
  1. 创建接口
java 复制代码
 //获取支付二维码
	 /**
     * 创建用于在线使用的 PredefinedPayment。
     *
     * @param params
     * @return
     */
	@POST("v3/predefined_payments/create_online_payment")

    @Headers("Content-Type: application/x-www-form-urlencoded; charset=utf-8")

    Observable<String> createOnlinePayment(
            @QueryMap Map<String, String> params,
            @HeaderMap Map<String, String> headers // 使用@HeaderMap来传递额外的请求头

    );

    //查询是否支付成功
	/**
     * 检索 PredefinedPayment
     *
     * @param token
     * @return
     */
    @GET("v3/predefined_payments/{token}")
    Observable<String> queryPaymentorder(@Path("token") String token);
  1. 发起请求和处理
java 复制代码
		HashMap<String, String> params = new HashMap<>();
        params.put("amount", localPrice);
        params.put("custom", productName);
        params.put("redirection_url", "https://www.example.com");
        params.put("expires_after","3600" );
        params.put("order_no", xxx);
        Map<String, String> headers = new HashMap<>();
        headers.put("X-Auth-API-Key", xxx);
        addSubscription(TakeMePayApi.api.createOnlinePayment(params,headers),
                new HttpResultObserver<String>(mView, mContext) {

                    public void onNext(String baseOrder) {
                        if (TextUtils.isEmpty(baseOrder)) {
                            return;
                        }
                        Gson gson = new Gson();
                        TakeMePayBean takeMePayBean = gson.fromJson(baseOrder, TakeMePayBean.class);
                        String token = takeMePayBean.getPredefined_payment().getToken();
                        String url = takeMePayBean.getUrl();
                        mView.getTakeMeCodeSuccess(url,token);
                    }

                    @Override
                    public void onError(Throwable t) {
                        t.printStackTrace();
                    }
                });

二维码的转换,你可以使用Glide来进行

java 复制代码
this.eventBusCode = eventBusCode;
        Bitmap bitmap = ZXingUtils.createQRImage(url, 600, 600);
        this.msn = token;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] bytes = baos.toByteArray();
        //禁止缓存
        RequestOptions options = new RequestOptions()
                .diskCacheStrategy(DiskCacheStrategy.NONE)
                .skipMemoryCache(true);


        Glide.with(getContext())
                .load(bytes)
                .apply(options)
                .into(ivQrCode);

四、 第三方支付对接的其他信息

上面文章讲解的内容,只是核心部分,还会有一些测试呀,加密呀等流程。

  1. 如果你对结果其他的第三方支付,你也会发现有一些不一样的地方,比如有些会麻烦一些,参数需要排序,需要加密,那么就需要写这些代码,不过有了AI,可以大大节约我们的时间,加密的话就根据对方的规定,使用对应的加密工具,这个就会很花时间了,需要测试,验证加密是否正确,这个就没什么方法,只能测试了。如果对方能提供代码示例,那么问题也会迎刃而解。

  2. 有些第三方支付,我们写好后,需要进行测试验收,也就是需要你提供请求体,响应体给他;还有取消支付会怎么样;支付过程中取消会怎么样,这些都需要做,这样才能确保你写的代码经得起折腾,这些测试也会很花时间。

  3. 有一些第三方开发的好的话,他们会直接给你测试码,直接返回对应不同的错误码,这样你就可以节省很多时间。


五、总结

对接扫码支付,其实并不是难,也就几个接口:

  1. 获取二维码。
  2. 查询支付结果。

难的地方在于对于流程的了解,当你了解了全局后,你就大概知道问题可能会出现在对方的身上,还是我们自己的身上。 难的地方在于沟通,你需要让对方非常清晰明了的了解你发送了什么参数,用到域名是什么,借助大家都是用的工具,那么就会方便很多。

相关推荐
大白要努力!2 小时前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟3 小时前
Android音频采集
android·音视频
小白也想学C4 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程4 小时前
初级数据结构——树
android·java·数据结构
闲暇部落6 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX8 小时前
Android 分区相关介绍
android
大白要努力!9 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee9 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood9 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-12 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记