快速集成支付宝支付和微信支付

吐槽一句微信的api真的是坑

参考文章:https://juejin.im/post/5833975961ff4b006c249067

支付宝支付

​ 1. 合理的支付流程

支付宝流程

  1. 导入sdk

    • 从官网下载jar包放在libs文件夹下alipaySdk-20170725.jar
    • manifest.xml下添加权限
    1
    2
    3
    4
    5
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    • manifest.xml下添加activity支付宝入口
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    <!--支付宝activity,当没有安装支付宝时打开-->
    <activity
    android:name="com.alipay.sdk.app.H5PayActivity"
    android:configChanges="orientation|keyboardHidden|navigation|screenSize"
    android:exported="false"
    android:screenOrientation="behind"
    android:windowSoftInputMode="adjustResize|stateHidden" >
    </activity>
    <activity
    android:name="com.alipay.sdk.app.H5AuthActivity"
    android:configChanges="orientation|keyboardHidden|navigation"
    android:exported="false"
    android:screenOrientation="behind"
    android:windowSoftInputMode="adjustResize|stateHidden" >
    </activity>
  2. 发起支付

    这里的订单(orderInfo)又服务端生成,我们负责调用支付宝app

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    /**
    * 支付宝支付 必须在异步线程
    *
    * @param orderInfo app支付请求参数字符串,主要包含商户的订单信息,
    * key=value形式,以&连接,由服务端生成
    */
    private void alipay(final String orderInfo) {
    Runnable payRunnable = new Runnable() {
    @Override
    public void run() {
    PayTask alipay = new PayTask(MainActivity.this);
    //传入支付订单信息,设置ture表示显示支付的loading
    Map<String, String> result = alipay.payV2(orderInfo, true);
    Message msg = new Message();
    msg.what = ALI_PAY_FLAG;
    msg.obj = result;
    handler.sendMessage(msg);
    }
    };
    Thread payThread = new Thread(payRunnable);
    payThread.start();
    }
  3. 处理结果

    这里处理的是支付宝支付的结果,完成支付后还应该请求服务器,同步服务器结果

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    private Handler handler = new Handler() {
    public void handleMessage(Message msg) {
    switch (msg.what) {
    case ALI_PAY_FLAG: {
    //PayResult非常简单的工具类,把map里的结果取出来(来自支付宝demo)
    PayResult payResult = new PayResult((Map<String, String>) msg.obj);
    //对于支付结果,请商户依赖服务端的异步通知结果
    //同步通知结果,仅作为支付结束的通知
    String resultInfo = payResult.getResult();// 同步返回需要验证的信息
    String resultStatus = payResult.getResultStatus();//状态码
    String memo = payResult.getMemo();//附加信息,如果不为空可以提示该内容
    switch (resultStatus) {
    case "9000":
    //支付成功
    break;
    case "8000":
    //支付结果确认中
    break;
    case "4000":
    //订单支付失败
    break;
    case "5000":
    //重复请求
    break;
    case "6001":
    //用户中途取消
    break;
    case "6002":
    //网络连接出错
    break;
    case "6004":
    //支付结果未知,请查询订单
    break;
    default:
    //其它支付错误
    break;
    }
    Log.e("TAG", "handleMessage: " + payResult.toString());
    break;
    }
    default:
    break;
    }
    }
    };

微信支付

注意:微信支付需要签名和申请的时候填入的签名一直才能成功

ps:第一次调用可以成功,就算没有签名没有申请支付功能也能成功,应该是微信的小心思

  1. 导入sdk

    • 从官网下载jar包放在libs文件夹下libammsdk.jar
    • manifest.xml下添加权限
    1
    2
    3
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    • manifest.xml下添加activity微信支付入口
    1
    2
    3
    4
    5
    <!-- 微信支付 -->
    <activity
    android:name=".wxapi.WXPayEntryActivity"
    android:exported="true"
    android:launchMode="singleTop"/>
    • 从官方sdk中拷贝WXPayEntryActivity到项目中

    拷贝的路径是你的包名/wxapi/WXPayEntryActivity,可以测试下是否能调起界面

  2. 配置WXPayEntryActivity

    • onCreate
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // 去除界面直接跳转,也可以定义
    // setContentView();
    // 传入自己的appid
    api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
    api.handleIntent(getIntent(), this);
    }
    • 重写onResp()根据成功失败做出相应操作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    @Override
    public void onResp(BaseResp resp) {
    Log.e(TAG, "onPayFinish, errCode = " + resp.errCode);
    //判断状态
    if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
    if (resp.errCode == 0) {
    Toast.makeText(this, "支付成功", Toast.LENGTH_SHORT).show();
    } else if (resp.errCode == -2) {
    Toast.makeText(this, "用户取消", Toast.LENGTH_SHORT).show();
    } else {//-1的状态
    Toast.makeText(this, "支付失败,请重试", Toast.LENGTH_SHORT).show();
    }
    }
    //记得关闭
    finish();
    }
  3. 发起请求

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    /**
    * 微信支付
    *
    * @param data 接口返回的订单信息,是一个json
    */
    private void weixinPay(String data) {
    // 通过WXAPIFactory工厂,获取IWXAPI的实例,记得修改为自己的appid
    IWXAPI api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
    // 将该app注册到微信
    api.registerApp(Constants.APP_ID);
    Log.e("TAG", "weixinPay: " + data);
    try {
    JSONObject json = new JSONObject(data);
    PayReq req = new PayReq();
    req.appId = json.getString("appid");
    req.partnerId = json.getString("partnerid");
    req.prepayId = json.getString("prepayid");
    req.nonceStr = json.getString("noncestr");
    req.timeStamp = json.getString("timestamp");
    req.packageValue = json.getString("package");
    req.sign = json.getString("sign");
    req.extData = "app data"; // optional
    // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
    boolean b = api.sendReq(req);
    Log.e("TAG", "weixinPay: " + (b ? "true" : "false"));
    } catch (JSONException e) {
    e.printStackTrace();
    }
    }