目录

前言:

介绍:

demo:

先看下 我的目录结构

java 代码

activit代码

总结思路:

server  端 开发思路


前言:

最近公司打算做先关android 方面的技术,然后招andirod 还挺贵,老板打算让我来搞搞,那就搞一搞,顺便做些总结,从java后台转型快速入手 android 的小策略支付还是挺总要的一部分毕竟用手机主要一点就是支付所以记录一下经验。

andoird 官网地址 https://developer.android.google.cn/

介绍:

  • 首先查看下支付宝沙箱文档 https://docs.open.alipay.com/200/105311/
  • 这个文档中很详细的介绍了些内容
  • 然后去获取一下appid 等账号,还有加密的秘钥等内容
  • 接下来就是看代码了
  • 官方提供的demo是为了方便把代码都放到了android
  • 这里为了方便我把代码顺便分了下那些放到server那些放到android center

demo:

  • https://download.csdn.net/download/weixin_42749765/10992832
  • 这里为了方便纯开发java后台的朋友 还带上来我之前讲的 webview 混合开发的代码
  • 混合开发的时候就通过js调用java方法 然后启动 alipay 的方法 来实现支付
  • 这里不做太多介绍

先看下 我的目录结构

  • 红色地方都是重点需要关注的

java 代码

package com.example.app002;import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.webkit.WebView;
import android.widget.TextView;
import android.widget.Toast;import com.alipay.sdk.app.AuthTask;
import com.alipay.sdk.app.PayTask;
import com.example.alipay.base.AuthResult;
import com.example.alipay.base.PayResult;
import com.example.alipay.uitl.OrderInfoUtil2_0;import org.json.JSONArray;
import org.json.JSONObject;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** java主启动类**/
public class MainActivity extends AppCompatActivity implements JsBridge{public void MainActivity(){}//定义日志private static final String TAG = "MainActivity";//定义一个webview 操作界面使用private WebView mwebView;//定义一个textview 操作界面文字使用private TextView mtextView;//定义一个 hadlerprivate Handler mHandler;//自带的启动方法@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//初始化添加接口内容initWidgets(savedInstanceState);requestPermission();}/*** 初始化以下** @param savedInstanceState*/private void initWidgets(Bundle savedInstanceState){//链接到activitymain.xml中的配置的id(webview)mwebView = findViewById(R.id.webview);//链接到activitymain.xml中的配置的id(tv_result)mtextView = findViewById(R.id.tv_result);mHandler = new Handler();//允许webview加载jsmwebView.getSettings().setJavaScriptEnabled(true);//给WebView添加js接口 java中new ImoocJsInterface()对象等于js中 imoocJsInterface调用的时候使用mwebView.addJavascriptInterface(new ImoocJsInterface(this),"imoocJsInterface");//加载页面 file:///android_asset/index.htmlmwebView.loadUrl("file:///android_asset/index.html");//调试使用if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {mwebView.setWebContentsDebuggingEnabled(true);}}//实现接口中操作文本及传递数据使用@Overridepublic void setTextViewValue(final String value) {Log.d(TAG, "value2="+value);//通过mHandler.post(方法操作mtextView文本mHandler.post(new Runnable() {@Overridepublic void run() {mtextView.setText(value);}});String cz = value + "vk";Map ma = new HashMap();String sdkver = "";Log.d("liteavsdk", "liteav sdk version is : " + sdkver);ma.put("ab","sss"+sdkver);//调用js方法CallJS(ma);}/*** java调用js方法** @param str 传递的是一个map的数据也可以传递别的类型*/public void CallJS(final Map str){// 通过Handler发送消息//通过mHandler.post(方法操作mwebView并且调用js方法mwebView.post(new Runnable() {@Overridepublic void run() {// 注意调用的JS方法名要对应上// 调用javascript的remo()方法mwebView.loadUrl("javascript:if(window.remo){window.remo('"+str+"');}");}});}//-----------------------------------------支付宝相关--------------------------------------------------------public static final String PID = "";//用于支付宝账户登录授入权业务的参 pid。public static final String TARGET_ID = "";//用于支付宝账户登录授权业务的入参 target_id。private static final int SDK_PAY_FLAG = 1;private static final int SDK_AUTH_FLAG = 2;@SuppressLint("HandlerLeak")private Handler alipayHandler = new Handler() {@SuppressWarnings("unused")public void handleMessage(Message msg) {switch (msg.what) {case SDK_PAY_FLAG: {@SuppressWarnings("unchecked")PayResult payResult = new PayResult((Map<String, String>) msg.obj);/*** 对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。*/String resultInfo = payResult.getResult();// 同步返回需要验证的信息String resultStatus = payResult.getResultStatus();// 判断resultStatus 为9000则代表支付成功if (TextUtils.equals(resultStatus, "9000")) {// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。showAlert(MainActivity.this, getString(R.string.pay_success) + payResult);} else {// 该笔订单真实的支付结果,需要依赖服务端的异步通知。showAlert(MainActivity.this, getString(R.string.pay_failed) + payResult);}break;}case SDK_AUTH_FLAG: {@SuppressWarnings("unchecked")AuthResult authResult = new AuthResult((Map<String, String>) msg.obj, true);String resultStatus = authResult.getResultStatus();// 判断resultStatus 为“9000”且result_code// 为“200”则代表授权成功,具体状态码代表含义可参考授权接口文档if (TextUtils.equals(resultStatus, "9000") && TextUtils.equals(authResult.getResultCode(), "200")) {// 获取alipay_open_id,调支付时作为参数extern_token 的value// 传入,则支付账户为该授权账户showAlert(MainActivity.this, getString(R.string.auth_success) + authResult);} else {// 其他状态值则为授权失败showAlert(MainActivity.this, getString(R.string.auth_failed) + authResult);}break;}default:break;}};};//从这往下和下边那个方法放到服务器上其他的都放在android 中public static final String APPID = "201********";//用于支付宝支付业务的入参 app_id。public static final String RSA2_PRIVATE = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwg************************==";public static final String RSA_PRIVATE = "";/*** 获取 加密内容  这个方法放在 服务器上** @return*/public String getorderParamSgin(){if (TextUtils.isEmpty(APPID) || (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))) {return null;}boolean rsa2 = (RSA2_PRIVATE.length() > 0);Map<String, String> params = OrderInfoUtil2_0.buildOrderParamMap(APPID, rsa2);String orderParam = OrderInfoUtil2_0.buildOrderParam(params);String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;String sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2);String orderInfo = orderParam + "&" +sign;return orderInfo;}/*** 支付宝支付业务示例*/public void payV22(View v) {final String orderInfo = getorderParamSgin();final Runnable payRunnable = new Runnable() {@Overridepublic void run() {PayTask alipay = new PayTask(MainActivity.this);Map<String, String> result = alipay.payV2(orderInfo, true);Log.i("msp", result.toString());Message msg = new Message();msg.what = SDK_PAY_FLAG;msg.obj = result;alipayHandler.sendMessage(msg);}};// 必须异步调用Thread payThread = new Thread(payRunnable);payThread.start();}/*** 支付宝账户授权业务示例*/public void authV2(View v) {if (TextUtils.isEmpty(PID) || TextUtils.isEmpty(APPID)|| (TextUtils.isEmpty(RSA2_PRIVATE) && TextUtils.isEmpty(RSA_PRIVATE))|| TextUtils.isEmpty(TARGET_ID)) {showAlert(this, getString(R.string.error_auth_missing_partner_appid_rsa_private_target_id));return;}/** 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;* 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;* 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;** authInfo 的获取必须来自服务端;*/boolean rsa2 = (RSA2_PRIVATE.length() > 0);Map<String, String> authInfoMap = OrderInfoUtil2_0.buildAuthInfoMap(PID, APPID, TARGET_ID, rsa2);String info = OrderInfoUtil2_0.buildOrderParam(authInfoMap);String privateKey = rsa2 ? RSA2_PRIVATE : RSA_PRIVATE;String sign = OrderInfoUtil2_0.getSign(authInfoMap, privateKey, rsa2);final String authInfo = info + "&" + sign;Runnable authRunnable = new Runnable() {@Overridepublic void run() {// 构造AuthTask 对象AuthTask authTask = new AuthTask(MainActivity.this);// 调用授权接口,获取授权结果Map<String, String> result = authTask.authV2(authInfo, true);Message msg = new Message();msg.what = SDK_AUTH_FLAG;msg.obj = result;alipayHandler.sendMessage(msg);}};// 必须异步调用Thread authThread = new Thread(authRunnable);authThread.start();}/*** 获取支付宝 SDK 版本号。*/public void showSdkVersion(View v) {PayTask payTask = new PayTask(this);String version = payTask.getVersion();showAlert(this, getString(R.string.alipay_sdk_version_is) + version);}/*** 获取权限使用的 RequestCode*/private static final int PERMISSIONS_REQUEST_CODE = 1002;/*** 检查支付宝 SDK 所需的权限,并在必要的时候动态获取。* 在 targetSDK = 23 以上,READ_PHONE_STATE 和 WRITE_EXTERNAL_STORAGE 权限需要应用在运行时获取。* 如果接入支付宝 SDK 的应用 targetSdk 在 23 以下,可以省略这个步骤。*/private void requestPermission() {// Here, thisActivity is the current activityif (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE)!= PackageManager.PERMISSION_GRANTED|| ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_PHONE_STATE,Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSIONS_REQUEST_CODE);} else {showToast(this, getString(R.string.permission_already_granted));}}/*** 权限获取回调*/@Overridepublic void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {switch (requestCode) {case PERMISSIONS_REQUEST_CODE: {// 用户取消了弹权限窗if (grantResults.length == 0) {showToast(this, getString(R.string.permission_rejected));return;}// 用户拒绝了某些权限for (int x : grantResults) {if (x == PackageManager.PERMISSION_DENIED) {showToast(this, getString(R.string.permission_rejected));return;}}// 所需的权限均正常获取showToast(this, getString(R.string.permission_granted));}}}private static void showAlert(Context ctx, String info) {showAlert(ctx, info, null);}private static void showAlert(Context ctx, String info, DialogInterface.OnDismissListener onDismiss) {final AlertDialog show = new AlertDialog.Builder(ctx).setMessage(info).setPositiveButton(R.string.confirm, null)// .setOnDismissListener(onDismiss).show();}private static void showToast(Context ctx, String msg) {Toast.makeText(ctx, msg, Toast.LENGTH_LONG).show();}//-----------------------------------------支付宝相关--------------------------------------------------------}
  • 代码中专门做了表中除了 appid 和秘钥 还有一个方法放到服务端剩下的都放在android 中就ok
  • 对于引用aar包看官方文档就好
  • 在demo中还有些alipay目录下的代码也放到服务端
  • 其中有些 TextUitl 类中的方法 java server中可能没有 可以自己建一个类 然后放上 比较方法和判断为空的方法

activit代码

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><WebViewandroid:id="@+id/webview"android:layout_width="match_parent"android:layout_height="733dp"tools:layout_editor_absoluteX="0dp"tools:layout_editor_absoluteY="0dp" /><TextViewandroid:id="@+id/tv_result"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Hello World!"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/payV2"android:layout_width="match_parent"android:layout_height="wrap_content"android:onClick="payV22"android:text="@string/pay_with_alipay"android:textAllCaps="false"tools:layout_editor_absoluteX="0dp"tools:layout_editor_absoluteY="180dp" /></android.support.constraint.ConstraintLayout>
  • activity 中重要的就是一个button 的点击按钮 别的没啥用是没有删除
  • 里边有个webview 方便开发使用,不需要的key直接删了就好

总结思路:

  • android 集成alipay 的思路就是通过调用 alipay的方法直接就可以启动alipay 支付宝的内容

server  端 开发思路

  • 先看张图

  • 这里专门介绍下server策略
  • 1.通过客户端向服务端发起请求获取 加密的数据和加签
  • 2.服务端获取到请求后解析出用户相关信息
  • 3.然后通过demo中的 代码生成 加密数据和加签数据
  • 4.传回到client 中

ok

文章持续更新!

java后台程序员转android 之《三B》 支付宝支付 client join server 及采坑记录相关推荐

  1. .net程序员转战android第三篇---登录模块之静态登录

    这一篇我将分2个部分记录登录界面,第一部分是静态登录, 这部分将如何从界面布局.控件使用.文件关系.数据验证.登陆实现等5小块记录. 第二部分是动态登录,这块会基于上面的4小块,在数据验证不是静态数据 ...

  2. 决定Java程序员工资高低的三个因素

    因为工资高,吸引了一大批人纷纷加入IT行业.的确,就目前的形势来看,IT行业的平均工资确实高于一般行业,但这并以为只要进入这一行就是高工资,想要获得高工资还是看个人技术和其他因素的. 本篇文章总结了影 ...

  3. Java中高级程序员全程学习路线图

    Java中高级程序员全程学习路线图 第一阶段:基础部分 Java基础 基本语法 变量 运算符 流程控制语句 面向对象特性 属性.方法 构造器 封装 继承 多态 抽象类.接口 高级应用 异常处理 IO流 ...

  4. Java后端程序员技术栈

    Java后端程序员技术栈 它可以是知识提纲,便于快速复习与查阅 它也可以是你的学习规划,帮助小白快速了解学Java要走的路(当然你也可以选择搭配我的学习路线一起享用!) 相关链接: <gitee ...

  5. Java开发程序员前景如何?

    Java开发程序员有前景吗?互联网行业的发展如火如荼,Java在所有编程语言中的领先地位却未动摇,迄今为止这项技术仍然有着不错的前景.然而,相当一部分人对于Java开发程序员的就业问题忧心忡忡,在笔者 ...

  6. 重庆找Java开发工作_重庆【Java开发程序员】

    重庆[Java开发程序员],提倡一切为了学员就业的办学思想,教学过程中坚持以练习企业项目为主,让学员真正能学到技术,毕业就能适应工作岗位. 重庆[Java开发程序员], Java 编程开发.而且很多软 ...

  7. 做为一名java高级程序员,需要了解哪些岗位?

    一.Java高级程序员 要想成为JAVA(高级)程序员也称Java高级工程师,肯定要学习JAVA.一般的程序员或许只需知道一些JAVA的语法结构就可以应付了.但要成为JAVA高级程序员,您要对JAVA ...

  8. @Java web程序员,在保留现场,服务不重启的情况下,执行我们的调试代码(JSP 方式)

    阅读目录 一.前言 二.问题描述 1.问题代码 2.jsp文件代码 3.执行 jsp 三.总结 回到顶部 一.前言 类加载器实战系列的第六篇(悄悄跟你说,这篇比较水),前面5篇在这里: 实战分析Tom ...

  9. 为什么阿里巴巴最爱招Java开发程序员?

    为什么阿里巴巴最爱招Java开发程序员?因为java本身设计特性就是大规模工程语言. 它有三个根本性的特征 1.适应各种业务,你目前知道的几乎所有的业务都可以用java写.有很多语言做不到这一点. 2 ...

最新文章

  1. zookeeper -- Mac 上 Intellij IDEA 配置 zookeeper(3.5.8) 源码阅读、运行、调试环境
  2. cheat engine lua
  3. poj 2739 Sum of Consecutive Prime Numbers
  4. python3 字符串替换 replace translate re.sub
  5. flink 自定义 窗口_《从0到1学习Flink》—— Flink Data transformation(转换)
  6. Java设计模式:命令模式
  7. css三种引入方式以及其优先级的说法
  8. Spring-core-AnnotationAttributes
  9. 每位开发人员都应该阅读的优秀源代码,长啥样?
  10. .ashx文件与.ashx.cs
  11. 使用adb命令启动app
  12. 如何选择产品关键词?
  13. 由IconFont引起的svg、ttf、woff、woff2图标的研究及转换
  14. 20个高效阅读小技巧
  15. java 读取word模板文件路径_Java 读取Word模板替换内容并另存
  16. 比尔·盖茨、UNIX之父等全球14位IT大佬,总结的18句编程名言!
  17. JAVA计算机毕业设计校园线上点餐系统Mybatis+源码+数据库+lw文档+系统+调试部署
  18. python开发跟淘宝有关联微_为什么微商和淘宝卖家不得不做公众号和小程序?
  19. SiT5357:±0.1~±0.25ppm超高精度Stratum 3温补振荡器TCXO,60-220MHz
  20. JavaScript之赛车游戏

热门文章

  1. elementUI tab 切换 table表头消失
  2. animator动画
  3. TexturePacker导入unity后图片还是显示成整图
  4. linux read使用方法,Linux命令: read的使用
  5. 横版格斗——技能动作概念
  6. 线程与蓝牙:物联网连接的 VHS 与 Betamax?
  7. 爬取段子网里面的搞笑段子
  8. Threejs系列--10游戏开发--沙漠赛车游戏【基础事件处理器】
  9. 情不知所起,无以而终
  10. ZAP日志框架lumberjack日志归档库的分析使用