支付宝、微信Android APP支付接入流程

2023-10-31

支付类型:

一次性支付

自动续费(支付宝周期扣款、微信委托扣款):1.支付并签约 2.先签约后扣费

注:微信委托扣款中先签约后扣费:自动续费、授权扣款、免密支付




支付宝

支付流程中各端交互逻辑

在这里插入图片描述


支付流程中商户APP端交互逻辑

在这里插入图片描述


先签约后扣费流程中各端交互逻辑:

在这里插入图片描述


1. 支付/签约前准备

导入aar集成支付宝客户端SDK,权限声明(网络,网络状态,WiFi状态)

对于先签约后扣费:判断是否安装支付宝。

根据用户ID、商品ID、支付平台等请求后台生成调起支付/签约所需参数:1.一次性支付、支付并签约:String orderInfo,订单号:String orderId。2.先签约后扣费:String signParams

注:一次性支付、支付并签约:对APP调起支付来说没区别。区别在于后台请求生成订单时传入更多参数:如周期规则参数(首次扣费时间、扣费周期单位、扣费周期数量…)

// 判断是否安装支付宝:检查包名com.eg.android.AlipayGphone是否存在
List<PackageInfo> packageInfoList = context.getPackageManager().getInstalledPackages(0);
boolean hasWallet = packageInfoList.stream()
                .map(packageInfo -> packageInfo.packageName)
                .anyMatch(s -> s.equals("com.eg.android.AlipayGphone"));

2. 调起支付/签约

  • 一次性支付 、支付并签约

    根据后台生成的订单信息,子线程中通过同步方法PayTask#payV2(String orderInfo, boolean isShowPayLoading)调起支付,完成同步支付与异步签约。

    String orderInfo:支付参数字符串,主要包含商户的订单信息,key=value形式,以&连接。

    boolean isShowPayLoading:调起支付宝时是否显示一个loading,建议为true

    // 服务器获取的订单信息
    final String orderInfo = info;
    
    // 调起支付逻辑
    Runnable payRunnable = new Runnable() {
        @Override
        public void run() {
            PayTask payTask = new PayTask(activity);
            Map<String, String> result = payTask.payV2(orderInfo, true);
            
            // 支付结果处理......
            // handler.sendMessage()
        }
    };
    
    // 调起支付
    Thread payThread = new Thread(payRunnable);
    payThread.start();
    
  • 先签约后扣费

    将后台生成的签约参数拼接到下面链接之后(该链接里面的appid为固定值,不可修改),APP通过scheme唤起支付宝进行签约。

    “alipays://platformapi/startapp?appId=60000157&appClearTop=false&startMultApp=YES&sign_params=

3. 支付/签约结果处理

  • 一次性支付、支付并签约

    支付完成之后会自动回到app中。

    同步通知PayTask#payV2()方法同步返回的结果Map<String, String>去后台验签解析获取支付结果。

    异步通知:后台创建订单的请求参数包含异步通知地址notify_url、sign_notify_url,支付完成后支付宝服务器会发送异步通知,后台也可查询接口确认结果。

    Map<String, String>

    {
        "memo" : "xxxxx",
        "result" : "{
                        \"alipay_trade_app_pay_response\":{
                            \"code\":\"10000\",
                            \"msg\":\"Success\",
                            \"app_id\":\"2014072300007148\",
                            \"out_trade_no\":\"081622560194853\",
                            \"trade_no\":\"2016081621001004400236957647\",
                            \"total_amount\":\"0.01\",
                            \"seller_id\":\"2088702849871851\",
                            \"charset\":\"utf-8\",
                            \"timestamp\":\"2016-10-11 17:43:36\"
                        },
                        \"sign\":\"NGfStJf3i3ooWBuCDIQSumOpaGBcQz+aoAqyGh3W6EqA/gmyPYwLJ2REFijY9XPTApI9YglZyMw+ZMhd3kb0mh4RAXMrb6mekX4Zu8Nf6geOwIa9kLOnw0IMCjxi4abDIfXhxrXyj********\",
                        \"sign_type\":\"RSA2\"
                    }",
        "resultStatus" : "9000"
    }
    

    resultStatus:

    9000 订单支付成功
    8000 正在处理中,支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态
    4000 订单支付失败
    5000 重复请求
    6001 用户中途取消
    6002 网络连接出错
    6004 支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态
    其它 其它支付错误

    有些时候会出现商户app 在支付宝支付阶段被关闭导致无法正确收到同步结果,此时支付结果可以完全依赖服务端的异步通知。 由于同步通知和异步通知都可以作为支付完成的凭证,且异步通知支付宝一定会确保发送给商户服务端。为了简化集成流程,商户可以将同步结果仅仅作为一个支付结束的通知(忽略执行校验),实际支付是否成功,完全依赖服务端异步通知。

  • 先签约后扣费

    同步通知:后台调用支付宝个人协议页面签约接口时传入return_url;如果没有传入 return_url,那么签约完成后不再返回APP,直接回到支付宝首页。签约成功的情况下,可以在return_url里面设置APP的scheme地址去返回APP。同步通知会在return_url 后面拼接返回参数,可将参数去后台验签。

    异步通知:异步通知(notify_url/应用网关地址)仅当用户签约成功或解约成功时触发。后台也可通过查询接口确认签约结果。




微信

支付流程中各端交互逻辑

在这里插入图片描述


支付流程中商户APP端交互逻辑

在这里插入图片描述


1. 支付/签约前准备

添加依赖:implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+',权限声明:android.permission.INTERNET

判断微信是否可用。

根据用户ID、商品ID、支付平台等请求后台生成调起支付/签约所需参数:1.一次性支付、支付并签约:prepay_id…。2.先签约后扣费:pre_entrustweb_id(两个小时内有效)。

注:一次性支付、支付并签约:对APP调起支付来说没区别。区别在于后台请求不同的接口生成prepay_id。

// 微信接口
IWXAPI wxapi = WXAPIFactory.createWXAPI(context, null);

// 未安装微信
if (!wxapi.isWXAppInstalled()) {}

// 微信版本低不支持支付
if (wxapi.getWXAppSupportAPI() < Build.PAY_SUPPORTED_SDK_INT) {}
// 需要服务器返回的订单信息

// 1.调起支付所需参数
private String appId; // APP ID
private String partnerId; // 商户号
private String prepayId; // 后台去微信服务器请求生成的预支付ID:有效期2小时
private String packageValue; // 扩展字段,暂填写固定值"Sign=WXPay"
private String nonceStr; // 随机字符串
private String timeStamp; // 时间戳:自1970年1月1日 0点0分0秒以来的秒数
private String sign; // 签名:签名方式一定要与统一下单接口使用的一致

// 2.订单号,用于支付结果查询
private String orderId;

2. 调起支付/签约

  • 一次性付费、支付并签约

    根据服务器获取的相关信息,创建PayReq,IWXAPI调起支付

    // 微信API
    IWXAPI wxapi = WXAPIFactory.createWXAPI(context, null);
    // 注册APP
    wxapi.registerApp(appId);
    
    // 调起支付对象PayReq
    PayReq payReq = new PayReq();
    payReq.appId = "";
    payReq.partnerId = "";
    payReq.prepayId = "";
    payReq.packageValue = "";
    payReq.nonceStr = "";
    payReq.timeStamp = "";
    payReq.sign = "";
    payReq.extData = ""; // 可附加的额外数据(如加入订单号)。会在微信回调Activity中返回
    
    // 调起支付
    // PayReq参数不正确会导致调起微信支付失败,返回false;
    // PayReq参数正确则调起微信支付成功,返回true。
    wxapi.sendReq(payReq);
    
  • 先签约后扣费

    后台预签约生成pre_entrustweb_id。

    WXOpenBusinessWebview.Req req = new WXOpenBusinessWebview.Req();
    
    req.businessType = 12; // 固定值
    HashMap queryInfo = new HashMap<>();
    queryInfo.put("pre_entrustweb_id","......";
    req.queryInfo = queryInfo;
    
    api.sendReq(req);
    

3. 支付/签约结果处理

  • 一次性支付、支付并签约

    同步通知:通过微信支付界面返回APP,会回调WXPayEntryActivity,可在此界面处理支付结果。"失败"或"成功"则去后台查询确认结果,“取消"可直接提示。

    异步通知:完成支付后微信将支付结果发送到notify_url,将签约结果发送到contract_notify_url。

    注:未完成支付则签约也失败。

    • 通过WXPayEntryActivity处理支付结果

      1. 目录:申请商户号时提供的包名.wxapi.WXPayEntryActivity

      2. Activity注册

        <activity name=".wxapi.WXPayEntryActivity"
                    android:exported="true"
                    android:launchMode="singleTop" />
        
      3. Activity实现IWXAPIEventHandler重写onResp(BaseResp resp)

        public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
        
            private IWXAPI wxapi;
        
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
        
                wxapi = WXAPIFactory.createWXAPI(getApplicationContext(), null);
                wxapi.handleIntent(getIntent(), this);
            }
        
            @Override
            protected void onNewIntent(Intent intent) {
                super.onNewIntent(intent);
        
                setIntent(intent);
                wxapi.handleIntent(intent, this);
            }
        
            @Override
            public void onReq(BaseReq baseReq) {}
        
            @Override
            public void onResp(BaseResp baseResp) {
                // 微信支付
                if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
                    // 订单号
                    String orderId = ((PayResp) baseResp).extData;
        
                    switch (baseResp.errCode) {
                        case 0: // 支付成功 BaseResp.ErrCode.ERR_OK
                            // 支付结果服务器查询
                            break;
                        case -1: // 支付错误
                            // 支付结果服务器查询
                            break;
                        case -2: // 用户取消 BaseResp.ErrCode.ERR_USER_CANCEL
                            // 支付取消,可通知服务器关闭此订单
                            break;
                        default:
                            break;
                    }
                    // 退出activity
                    finish();
                }
            }
        
        }
        

      在这里插入图片描述

    • 通过WXPayEntryActivity处理支付结果存在一个问题:不通过微信支付界面返回APP,支付结果得不到处理。

      1. 调起支付情况分析:

        微信启动了

        微信返回APP

        ​ onPause() 支付界面 onResume()

        不通过微信返回APP

        ​ onPause() 支付界面 home->onStop() app->onStart() onResume()

        微信未启动

        微信返回APP

        ​ onPause() 微信界面 onStop() 自动返回app->onStart() 支付界面 onResume()

        不通过微信返回APP

        ​ onPause() 微信界面 onStop() 自动返回app->onStart() 支付界面 home->onResume()、onPause()、onStop() app->onStart() onResume()

      2. 解决方法

        发起支付前,存下订单号。

         String orderId = "...";
        

        onResume()生命周期下查询订单支付结果。

         if (orderId == null) {
            return;
        }
        
        // 服务器查询订单
        
        // 重置
        orderId = null;
        

        注意:在“微信未启动”且“不通过微信返回APP”时,在微信支付界面按下home会回调onResume()去服务器查询支付结果。

  • 先签约后扣费

    完成签约后微信将支付结果发送到notify_url,安卓暂不支持返回APP,签约完成后停留在微信内。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

支付宝、微信Android APP支付接入流程 的相关文章

  • 我在布局上看不到任何 FirebaseRecyclerAdapter 项目

    我试图将数据从 Firebase 数据库检索到我的布局 但我看不到任何项目FirebaseRecyclerAdapter在布局中 请帮忙 我按照一个教程展示了如何做到这一点 当我运行应用程序时 我没有看到任何项目 但我可以滚动 public
  • AdapterContextMenuInfo 始终为 null

    我尝试通过 android 开发文档中的书来做到这一点 this didn t create a menu i don t know why registerForContextMenu getListView setListAdapter
  • Android WebView里面的ScrollView只滚动scrollview

    在我的应用程序中 我有一个 ScrollView 其中包含一些线性视图 一些文本视图和一个 Webview 然后是其他线性布局等 问题是 WebView 不滚动 Scroll 仅侦听 ScrollView 有什么建议么
  • 自定义首选项中的android首选项水平分隔线?

    我创建了自己的自定义首选项对象来扩展首选项 我创建它们只是因为这些自定义数据类型没有首选项 一切正常 但我的自定义首选项没有相同的外观 因为它们缺少系统首选项对象具有的水平分隔线 我已经查找了创建水平分隔线的代码 但我找不到它是在哪里完成的
  • 以编程方式将文本颜色设置为主要 Android 文本视图

    如何设置我的文本颜色TextView to android textColorPrimary以编程方式 我已经尝试了下面的代码 但它将 textColorPrimary 和 textColorPrimary Inverse 的文本颜色始终设
  • java.lang.IllegalStateException:应用程序 PagerAdapter 更改了适配器的内容,而没有调用 PagerAdapter#notifyDataSetChanged android

    我正在尝试使用静态类将值传递给视图 而不是使用意图 因为我必须传递大量数据 有时我会收到此错误 但无法找出主要原因是什么 Error java lang IllegalStateException The application s Pag
  • Android 深度链接至 Instagram 应用

    Instagram 已经发布了 iOS 深层链接的 url 方案 但尚未为 Android 创建文档 有没有办法深入链接到 Android 上的 Instagram 应用程序 以转到 Instagram 应用程序中的特定位置 例如 Inst
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • 使用片段时应用程序崩溃

    我正在处理碎片和 我的代码中有一个我找不到的问题 logcat 指向我的一个片段中的这段代码 Override public View onCreateView LayoutInflater inflater ViewGroup conta
  • okhttp 获取失败响应

    我已经在我的 android 客户端中实现了 okhttp 来进行网络调用 当我收到失败响应时 我会收到失败代码以及与该代码相关的文本作为消息 但我没有收到服务器发送给我的自定义失败响应 在我实施的代码中的失败响应中 我收到的消息只是 错误
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • Android 2.3 模拟器在更新位置时崩溃

    我正在使用 Eclipse 编写和调试 Android 应用程序 我需要做的事情之一是更新设备的位置 因此我尝试使用模拟器控制窗口中的位置控制面板 在 手动 选项卡上 我选择 十进制 输入有效的纬度和经度 然后单击 发送 不幸的是 接下来发
  • OnLongClickListener 不工作

    我有一个ImageView 我需要使用onLongClickListener对于图像视图 当我使用这段代码时 什么也没有发生 Code gallery Gallery findViewById R id gall1 gallery setA
  • Dagger 2 没有生成我的组件类

    我正在使用 Dagger 2 创建我的依赖注入 几个小时前它还在工作 但现在不再生成组件 这是我创建组件的地方 public class App extends Application CacheComponent mCacheCompon
  • 如何检查 Android 中的同步设置

    我正在构建一个 Android 应用程序 我需要检查设备中注册的每个单独帐户的同步设置 我知道我可以通过 ContentResolver 类来做到这一点 但我遇到了一些问题 我已设法获取设备上所有帐户的列表 但我不知道在运行时从哪里获取特定
  • Android - 以编程方式选择菜单选项

    有没有办法以编程方式选择菜单选项 基本上 我希望视图中的按钮能够执行与按特定菜单选项相同的操作 我正在考虑尝试调用 onOptionsItemSelected MenuItem item 但我不知道要为菜单项添加什么 是的 有一种方法可以选
  • 没有支持 FEATURE_CAMERA_EXTERNAL 的 Android 设备

    根据this doc https source android com devices camera external usb cameras一些 Android 设备允许使用 Camera2 API 访问外部 USB 摄像头 我检查了大约
  • Android:如何从网络异步获取搜索建议?

    我创建了一个可搜索的活动 现在 我想添加从网络服务获取的搜索建议 我想异步获取这些建议 根据添加自定义建议 http developer android com guide topics search adding custom sugge
  • 错误:(23, 13) 无法解决:com.google.android.gms:play-services:11.2.0“安装存储库和同步项目”不起作用

    我正在尝试在我的 Android 应用程序中获取位置并更新到服务器 这是我的 Gradle 代码 我在这里包含了compile com google android gms play services 11 2 0 这条线是从文档中 htt
  • 有没有任何代码可以在android中设置壁纸而无需裁剪和缩放?

    我正在创建一个画廊应用程序 我的第一个应用程序 这是我的代码 Bitmap bmd BitmapFactory decodeStream is try getApplicationContext setWallpaper bmd catch

随机推荐

  • JavaScript常见的运用场景

    JavaScript是一种相当流行 高效 便捷的脚本语言 它在 web 开发中发挥着重要的作用 下面我们来介绍下 JavaScript 常见的运用场景 1 网页动态效果制作 JavaScript 可以用来制作网页的多种动态效果 包括但不限于
  • 低功耗技术(一)动态功耗与静态功耗

    一 动态功耗 翻转功耗 Switching Power 翻转功耗是由充放电电容引起的动态功耗 其推导过程很简单 但是这个最终的结果却十分重要 1 switching power 和负载电容 电压 0到1变化事件的发生次数 时钟频率有关 2
  • Tomcat任意写入文件漏洞(CVE-2017-12615)

    声明 好好学习 天天向上 漏洞描述 2017年9月19日 Apache Tomcat官方确认并修复了两个高危漏洞 漏洞CVE编号 CVE 2017 12615和CVE 2017 12616 其中 远程代码执行漏洞 CVE 2017 1261
  • CSS——网易云音乐首页导航栏的制作

    文章目录 前言 一 结构的布局 二 实现过程 1 HTML结构 2 CSS样式 总结 前言 本文主要介绍了网易云导航栏的制作过程 这个案例中将会运用到CSS中的浮动 绝对定位等相关知识点 这些在以往的文章里有所介绍 一 结构的布局 示例图
  • js数组去重(9种方法),你都会了吗?

    以下共有九种数组去重的方式和详解 包含对象数组去重 1 利用Array from new Set 去重 1 利用set去重 Set是es6新增的数据结构 似于数组 但它的一大特性就是所有元素都是唯一的 没有重复的值 我们一般称为集合 Arr
  • Qt QSqlQueryModel详解

    背景知识 Qt SQL的API分为不同层 驱动层 驱动层 对于QT是基于C 来实现的框架 该层主要包括QSqlDriver QSqlDriverCreator QSqlDriverCreatorbase QSqlDriverPlugin a
  • C4droid安装使用教程

    1 C4droid简介 手机 Android 上C C 的IDE 编译器 便携 功能强大 足以满足初学者平时的练习 汉化版 更易理解和使用 2 C4droid下载 在我分享的百度网盘链接中下载 https pan baidu com s 1
  • mysql yearweek函数_MySQL的YEARWEEK函数(转)_MySQL

    MySQL的YEARWEEK函数以及查询本周数据MySQL 的 YEARWEEK 是获取年份和周数的一个函数 函数形式为 YEARWEEK date mode 例如 2010 3 14 礼拜天 www bitsCN com SELECT Y
  • numpy:广播机制

    广播是numpy对不同形状的数组进行数值计算的方式 对数组的算术运算通常在相应的元素上进行的 如果两个数组a和b形状相同 即满足a shape b shape 那么a b的结果就是a与b数组对应位相乘 这要求维数相同 且各维度的长度相同 对
  • 2023华为OD机试真题【区块链转储系统】

    题目描述 区块链底层存储是一个链式文件系统 由顺序的N个文件组成 每个文件的大小不一 依次为F1 F2 Fn 随着时间的推移 所占存储会越来越大 云平台考虑将区块链按文件转储到廉价的SATA盘 只有连续的区块链文件才能转储到SATA盘上 且
  • Pandas中inf值替换

    文章目录 问题 出现inf的原因 解决办法 参考文章 问题 今天使用Pandas从MySQL读取数据 在处理之后再写回到数据库时报了一个错误 sqlalchemy exc ProgrammingError MySQLdb exception
  • mysql数据库 期末总结

    目录 数据库基础知识 MySQL命令 字符集 库操作 表操作 创建 查看和删除 修改表 复制表 约束控制 数据操作 插入数据 增 删除数据 删 修改数据 改 查询数据 查 单表查询 分组查询 排序 限制查询结果数量 集合函数 多表查询 1
  • Game of Primes (博弈)

    Game of Primes 题目链接 题意 初始有两个数 x 和 y 每次操作可以选择一个数减1 Alice和Bob轮流操作 指定某人先手 1 如果某时刻 x k 或 y k Bob胜 2 如果某时刻 x y都是素数 Alice胜 3 如
  • shell使用示例

    文章目录 shell使用示例 统计一个文本文件中每个单词出现的频率 打印文本文件的第十行 判断有效的电话号码 输出数字范围内7的倍数 shell使用示例 统计一个文本文件中每个单词出现的频率 cat text tr s n sort uni
  • Win11 文件夹打开慢或卡顿解决方案

    问题 目前是 2023 2 27 我的 Win11 系统点开一个文件夹要等待 2 3 秒才能加载出来 使用体验极差 网上查阅大量资料 有些人在系统更新后这个情况就消失了 但是我这一直存在 系统也是当前的最新版 没有修复 目前得出的结论是 因
  • 修改Maven的本地仓库位置

    最近开始学SSM整合项目视频时 需要用到Maven仓库于是便开始研究起了Maven 首先需要在官网下载Maven的压缩包 然后进行解压 再把其加入到环境变量中 由于主要研究的时Maven的如何修改仓库位置 所以这里就一笔带过 不知道如何配置
  • MySQL复习笔记-一条SQL更新语句是如何执行的?

    前面我们系统了解了一个查询语句的执行流程 并介绍了执行过程中涉及的处理模块 相信你还记得 一条查询语句的执行过程一般是经过连接器 分析器 优化器 执行器等功能模块 最后到达存储引擎 那么 一条更新语句的执行流程又是怎样的呢 之前你可能经常听
  • 简单的Markdown功能实现——marked模块的使用

    marked是一个markdown 解析 编译器 通过引入marked模块 可以实现一个简单的markdown编辑器 使用方式如下 Install 新建一个项目文件夹 在项目中下载marked模块 Usage 新建一个marked js文件
  • java 生成纯色图片_canvas简单实现纯色背景图片抠图(示例代码)

    最近在研究html5 canvas的过程中 发现 canvas为前端对图像的处理开辟了一条新的道路 canvas可以做到很多事情 甚至可以做个类似于PhotoShop的东西 曾经本人在一家软件工作就做类似的工作 可以看一下我之前开发的软件
  • 支付宝、微信Android APP支付接入流程

    支付类型 一次性支付 自动续费 支付宝周期扣款 微信委托扣款 1 支付并签约 2 先签约后扣费 注 微信委托扣款中先签约后扣费 自动续费 授权扣款 免密支付 支付宝 支付流程中各端交互逻辑 支付流程中商户APP端交互逻辑 先签约后扣费流程中