全部产品

Android 小程序接入账户通与支付

更新时间:2020-09-21 19:22:19

本文档介绍了在 Android 小程序中接入财付通和支付的操作指导。由于此功能在 10.1.60 及以上版本的基线提供了支持,因此当您的基线版本低于 10.1.60 时,请参照 基线升级 将基线升级至 10.1.60 或以上。

前提条件

  • 已获得账户通 SDK 和快捷支付 SDK。为获得上述 SDK,您需要提供以下信息:
    • 在支付宝开放平台申请的 APPID,详情参见 创建应用
    • 应用名称。在提供后应用名称不可再修改。
    • 携带签名的 APK 包。如果线上和测试使用的签名不同,请分别提供相应的 APK 包。如果无法提供完整 APK 包,可提供 APK 包内的 CERT.RSA 文件。
      说明:只需将上述信息在对接钉钉群中提供给 mPaaS 支持同学即可。
  • 已接入小程序。更多关于接入小程序的信息,请参见 接入 Android
  • 已获得 mPaaS 加密图片。更多关于生成加密图片的信息,请参见 加密图片

接入流程

  1. 将账户通 SDK 和快捷支付 SDK 分别添加到应用中。
    • 如果您采用的是 Portal&Bundle 接入方式,请将 SDK 集成到 Portal 工程中。
    • 如果您当前的应用已集成支付宝快捷支付 SDK,则需要先将其移除。
  2. 将 mPaaS 颁发的加密图片文件拷贝至项目主工程的 res/drawable 文件夹下。请不要重命名该文件。
  3. 如果您使用的是 10.1.68 版本基线,还需要根据您所采用的接入方式,在 mPaaS 插件中点击 mPaaS Inside 接入组件化接入,在弹出的接入面板中,点击 配置/更新组件 下的 开始配置,在弹出的组件管理窗口中,选择安装 账户通 组件。

SDK 混淆配置

如果应用开启了混淆编译,需将以下配置加入到混淆配置文件中:

  1. # for inside
  2. -keep class com.alipay.android.phone.inside.** { *; }
  3. # for rpc
  4. -keep class com.alipay.inside.** { *; }
  5. -keep class org.json.alipay.inside.* { *; }
  6. # for login
  7. -keep class com.ali.user.** { *; }
  8. -keep class com.alipay.** { *; }
  9. # for minipaysdk
  10. -keep class com.alipay.** { *; }
  11. -keep class com.flybird.** { *; }
  12. -keep class org.iffa.** { *; }
  13. # for securitysdk
  14. -keep class com.alipay.** { *; }
  15. # for securityguard sdk
  16. -keep class com.alibaba.** {*;}
  17. -keep class com.taobao.** {*;}
  18. # for thirdparty lib: okio
  19. -keep class okio.** {*;}
  20. # for thirdparty lib: utdid
  21. -keep class com.ut.** {*;}
  22. -keep class com.ta.** {*;}
  23. # for thirdparty lib: pb
  24. -keep class com.squareup.** {*;}
  25. -keep interface mtopsdk.mtop.domain.IMTOPDataObject {*;}
  26. -keep class * implements mtopsdk.mtop.domain.IMTOPDataObject {*;}
  27. -keep class com.ali.user.**{*;}
  28. -keep class com.ali.user.**.*$*{*;}
  29. -keep class mtopsdk.**{*;}

账户授权及支付流程

账户授权及支付流程如下:

authentication+payment

客户端授权登录流程

客户端授权登录流程如下:

login

客户端退出登录或切换用户

接入方退出登录或者切换用户时,需要清除客户端支付宝登录态,否则会造成小程序仍使用前个用户的支付宝登录信息。接入方需在退出登录或者切换用户处调用 AuthGlobal.getInstance().logout 方法。

支付配置

接入方对于支付配置有要求时,请 提交工单 获取活动标识、业务场景标识和应用标识。获取标识后,请在客户端代码中设置,代码示例如下:

  1. MPOpenBizHelper.getInstance().setBizSceneCode("小程序应用ID", "业务场景标识");
  2. MPOpenBizHelper.getInstance().setCampaignIds("小程序应用ID", "活动标识);
  3. MPTinyHelper.getInstance().setAppName("应用标识");

客户端接入 API

AuthProvider.java

  1. package com.mpaas.nebula.adapter.alipay;
  2. /**
  3. * 接入方需实现的接口,用于获取应用的授权配置和授权信息
  4. */
  5. public interface AuthProvider {
  6. /**
  7. * 获取授权配置
  8. * @return 授权配置
  9. */
  10. AuthConfig loadConfig();
  11. /**
  12. * 获取授权信息用于客户端免登,一般在此方法需要访问自己的服务端获取信息。
  13. * 此方法运行在非主线程上,因此接入方不需要创建新线程发送网络请求。
  14. * @param authCode 支付宝返回的授权码
  15. * @return 授权信息用于免登
  16. */
  17. AuthInfo fetchAuthInfoSync(String authCode);
  18. /**
  19. * 获取缓存的授权信息,接入方需要自行缓存支付宝 userId 和 accessToken
  20. * @return 授权信息
  21. */
  22. AuthInfo getCachedAuthInfo();
  23. }

AuthConfig.java

  1. package com.mpaas.nebula.adapter.alipay;
  2. /**
  3. * 授权配置,
  4. */
  5. public class AuthConfig {
  6. /**
  7. * 授权页面请求 url
  8. */
  9. private String authUrl;
  10. }

AuthInfo.java

  1. package com.mpaas.nebula.adapter.alipay;
  2. public class AuthInfo {
  3. /**
  4. * 支付宝用户 ID
  5. */
  6. private final String aliUid;
  7. /**
  8. * 接入端用户统一标识 userId
  9. */
  10. private final String mcUid;
  11. /**
  12. * 访问令牌
  13. */
  14. private final String accessToken;
  15. public AuthInfo(String aliUid, String mcUid, String accessToken) {
  16. this.aliUid = aliUid;
  17. this.mcUid = mcUid;
  18. this.accessToken = accessToken;
  19. }
  20. }

AuthGlobal.java

  1. package com.mpaas.nebula.adapter.alipay;
  2. public class AuthGlobal {
  3. public static AuthGlobal getInstance();
  4. /**
  5. * 初始化接口,在 10.1.68.12 版本中新增
  6. * 须在调用其他方法前调用
  7. */
  8. public void init(Context context);
  9. public void setAuthProvider(AuthProvider authProvider);
  10. /**
  11. * 获取支付宝授权auth code
  12. * 必须在子线程中调用
  13. * @param context
  14. * @return
  15. */
  16. public AuthResult getAuthCode(Context context);
  17. /**
  18. * 清除支付宝登录态或解绑支付宝账户,可在主线程中调用
  19. * @param context
  20. */
  21. public void logout(Context context, boolean unbindAlipay);

示例代码

  1. AuthGlobal.getInstance().init(getApplicationContext());
  2. AuthGlobal.getInstance().setAuthProvider(new AuthProvider() {
  3. @Override
  4. public AuthConfig loadConfig() {
  5. return new AuthConfig.Builder()
  6. .setAuthUrl("https://openapi.alipay.com/gateway.do?alipay_sdk=alipay-sdk-java-3.7.4.ALL&app_id=2019040163782051&biz_content=%7B%22auth_type%22%3A%22MY_PASS_OAUTH%22%2C%22scopes%22%3A%5B%22auth_user%22%5D%2C%22state%22%3A%2210%22%2C%22is_mobile%22%3A%22true%22%7D&charset=UTF-8&format=json&method=alipay.user.info.auth&return_url=http%3A%2F%2Fzhanghutong.yuguozhou.online%2Ffirst&sign=RHLcR%2BbfgW50JgNr5e6MTT08Bnnb3%2Fyt%2B0YIObm%2Fdpq2yJtYzHKgmS2ciVrgFEk6DUKtEmipoLb8xJ8ErFQAtSS7p8AvXGGY63D95N4lm6yasUVCg2kGoofeB9OPk7GBkLkud1CY3oCbK4HgbHHnHIc43GtXuKt0QLMPivZjKgqb5u1zt%2FKscdCt8JrLG4L5vOOFGKRuh3cFq%2BVL%2Bdvaufwbut6B%2B85GjOsnvONICif8r9cxpdzlsRFoSVmYu%2F7AUM34diatlQPvKs5NOeeAg2W8QkBbQYza0f84KYrNAAeX9ITbzvc7ntiL9606qEB1OWj%2Flccm%2B1TSKQjUUjjC6A%3D%3D&sign_type=RSA2&timestamp=2019-04-28+17%3A28%3A04&version=1.0")
  7. .build();
  8. }
  9. @Override
  10. public AuthInfo fetchAuthInfoSync(String authCode) {
  11. try {
  12. URL url = new URL("http://zhanghutong.yuguozhou.online/first?isv_app_id=2019040163782051&app_id=2019040163782051&auth_code=" + authCode
  13. + "&state=10&scope=auth_user");
  14. HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  15. connection.setRequestMethod("GET");
  16. connection.connect();
  17. int responseCode = connection.getResponseCode();
  18. if (responseCode == HttpURLConnection.HTTP_OK) {
  19. InputStream inputStream = connection.getInputStream();
  20. final String resp = readStream(inputStream);
  21. if (null != resp) {
  22. JSONObject jsonObject = JSON.parseObject(resp).getJSONObject("alipay_system_oauth_token_response");
  23. String aliUid = jsonObject.getString("user_id");
  24. String mcUid = jsonObject.getString("mc_user_id");
  25. String accessToken = jsonObject.getString("access_token");
  26. return new AuthInfo(aliUid, mcUid, accessToken);
  27. }
  28. }
  29. } catch (Exception e) {
  30. e.printStackTrace();
  31. }
  32. return null;
  33. }
  34. @Override
  35. public AuthInfo getCachedAuthInfo() {
  36. return new AuthInfo(aliUid, mcUid, accessToken);
  37. }
  38. });

测试验证

接入完成后,可使用测试代码验证是否接入成功,代码示例如下:

  1. Executors.newSingleThreadExecutor().execute(new Runnable() {
  2. @Override
  3. public void run() {
  4. AuthResult result = AuthGlobal.getInstance().getAuthCode(MiniAppActivity.this);
  5. MPLogger.info(TAG, "result " + result.getAuthCode());
  6. AuthInfo authInfo = AuthGlobal.getInstance().loadAuthInfo(result.getAuthCode());
  7. OAuthLoginModel oAuthLoginModel = new OAuthLoginModel();
  8. oAuthLoginModel.setAccessToken(authInfo.getAccessToken());
  9. oAuthLoginModel.setAlipayUid(authInfo.getAliUid());
  10. oAuthLoginModel.setBizSource("InsideDemo");
  11. oAuthLoginModel.setMcUid(MPLogger.getUserId()); // app 自己的 userid
  12. oAuthLoginModel.setOpenAuthLogin(true);
  13. try {
  14. OperationResult<OAuthLoginCode> oResult = InsideOperationService.getInstance().startAction(MiniAppActivity.this, oAuthLoginModel);
  15. MPLogger.info(TAG, "result " + oResult.toJsonString());
  16. } catch (InsideOperationService.RunInMainThreadException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. });

如果以上示例代码输出的结果符合以下内容,则表示接入成功。

  1. {"result":"","code":"account_3rdauthlogin_9000","memo":"登录成功。","op":"alipayOpenAuthLogin"}