Android app第三方支付宝支付接入教程

2019-12-10 18:01:15王冬梅
这篇文章主要为大家分享了Android app第三方支付宝支付接入教程,介绍了支付宝支付步骤,对支付宝感兴趣的小伙伴们可以参考一下  

支付宝的接入相对比较简单,看看支付宝官网的文档基本都能搞定,但是切记一点让你们的后台也要搞清楚支付宝的流程,重中之重。

1、注意事项 
开发前一定要阅读支付宝官方文档 
强烈建议签名等处理在后台处理,我这个是测试是在自己本地写的,不要吐槽 
想获取支付宝合作商户ID,及支付宝公钥请点击支付宝链接,生成密钥及PKCS8转码工具在文档中 
添加Android.permission.INTERNET权限和android.permission.ACCESS_NETWORK_STATE权限 
要导入支付宝的包 
2、特别注意事项(坑点) 
下载支付宝的官网之后生成你所需要的密钥及PKCS8转码一定要小心

代码: 
MainActivity中调起支付:Pay pay = new Pay(AffirmOrderActivity.this, paymoney);

Pay 类

 

public class Pay {

                 /**以下四项这些数值机密填入自己申请的就好**/
  // 商户PID
  public static final String PARTNER = "";
  // 商户收款账号
  public static final String SELLER = "";
  // 商户私钥,pkcs8格式
  public static final String RSA_PRIVATE = "";
  // 支付宝公钥
  public static final String RSA_PUBLIC = "";

  private Activity context;
  private String mgoods,mprice,micon;
  private int mtype;
  private String mOutTradeNo;
  public Pay(Activity activity, String goods,String goodsmore,String price,String icon,int type, String outTradeNo) {
    context = activity;
    mprice = price;
    pay(price);
  }


  private Handler mHandler = new Handler() {

    public void handleMessage(Message msg) {
      switch (msg.what) {
        case SDK_PAY_FLAG: {
          PayResult payResult = new PayResult((String) msg.obj);
          /**
           * 同步返回的结果必须放置到服务端进行验证(验证的规则请看https://www.easck.com/doc2/
           * detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
           * docType=1) 建议商户依赖异步通知
           */
          String resultInfo = payResult.getResult();// 同步返回需要验证的信息

          String resultStatus = payResult.getResultStatus();
          // 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
          if (TextUtils.equals(resultStatus, "9000")) {
            Toast.makeText(context, "支付成功", Toast.LENGTH_SHORT).show();

          } else {
            // 判断resultStatus 为非"9000"则代表可能支付失败
            // "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
            if (TextUtils.equals(resultStatus, "8000")) {
              Toast.makeText(context, "支付结果确认中", Toast.LENGTH_SHORT).show();

            } else {
              // 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
              Toast.makeText(context, "支付失败", Toast.LENGTH_SHORT).show();

            }
          }
          break;
        }
        default:
          break;
      }
    };
  };


  /**
   * call alipay sdk pay. 调用SDK支付
   *
   */
  public void pay(String goods,String goodsmore,String price) {
    if (TextUtils.isEmpty(PARTNER) || TextUtils.isEmpty(RSA_PRIVATE) || TextUtils.isEmpty(SELLER)) {
      new AlertDialog.Builder(context).setTitle("警告").setMessage("需要配置PARTNER | RSA_PRIVATE| SELLER")
          .setPositiveButton("确定", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialoginterface, int i) {
              //
//              finish();
            }
          }).show();
      return;
    }
    String orderInfo = getOrderInfo(goods, goodsmore, price);

    String sign = sign(orderInfo);

    try {
      /**
       * 仅需对sign 做URL编码
       */
      sign = URLEncoder.encode(sign, "UTF-8");

    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }

    /**
     * 完整的符合支付宝参数规范的订单信息
     */
    final String payInfo = orderInfo + "&sign="" + sign + ""&" + getSignType();
    Log.i("lff", "orderInfo == " +orderInfo);
    Log.i("lff", "sign == " +sign);    Runnable payRunnable = new Runnable() {

      @Override
      public void run() {
        // 构造PayTask 对象
        PayTask alipay = new PayTask(context);
        // 调用支付接口,获取支付结果
        String result = alipay.pay(payInfo, true);

        Message msg = new Message();
        msg.what = SDK_PAY_FLAG;
        msg.obj = result;
        mHandler.sendMessage(msg);
      }
    };

    // 必须异步调用
    Thread payThread = new Thread(payRunnable);
    payThread.start();
  }

  /**
   * get the sdk version. 获取SDK版本号
   *
   */
  public void getSDKVersion() {
    PayTask payTask = new PayTask(context);
    String version = payTask.getVersion();
    Toast.makeText(context, version, Toast.LENGTH_SHORT).show();
  }




  /**
   * create the order info. 创建订单信息
   *
   */
  private String getOrderInfo(String subject, String body, String price) {

    // 签约合作者身份ID
    String orderInfo = "partner=" + """ + PARTNER + """;

    // 签约卖家支付宝账号
    orderInfo += "&seller_id=" + """ + SELLER + """;

    // 商户网站唯一订单号
    orderInfo += "&out_trade_no=" + """ + getOutTradeNo() + """;

    // 商品名称
    orderInfo += "&subject=" + """ + subject + """;

    // 商品详情
    orderInfo += "&body=" + """ + body + """;

    // 商品金额
    orderInfo += "&total_fee=" + """ + "0.01" + """;

    // 服务器异步通知页面路径
//    orderInfo += "¬ify_url=" + """ + "http://www.easck.com/notify.htm" + """;
    orderInfo += "¬ify_url=" + """ + "http://www.easck.com/new/zfbCallback" + """;
    // 服务接口名称, 固定值
    orderInfo += "&service="mobile.securitypay.pay"";

    // 支付类型, 固定值
    orderInfo += "&payment_type="1"";

    // 参数编码, 固定值
    orderInfo += "&_input_charset="utf-8"";

    // 设置未付款交易的超时时间
    // 默认30分钟,一旦超时,该笔交易就会自动被关闭。
    // 取值范围:1m~15d。
    // m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。
    // 该参数数值不接受小数点,如1.5h,可转换为90m。
    orderInfo += "&it_b_pay="30m"";

    // extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付
    // orderInfo += "&extern_token=" + """ + extern_token + """;

    // 支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空
    orderInfo += "&return_url="m.alipay.com"";

    // 调用银行卡支付,需配置此参数,参与签名, 固定值 (需要签约《无线银行卡快捷支付》才能使用)
    // orderInfo += "&paymethod="expressGateway"";
    return orderInfo;
  }

  /**
   * get the out_trade_no for an order. 生成商户订单号,该值在商户端应保持唯一(可自定义格式规范)
   *
   */
  private String getOutTradeNo() {
//    SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss", Locale.getDefault());
//    Date date = new Date();
//    String key = format.format(date);
//
//    Random r = new Random();
//    key = key + r.nextInt();
//    key = key.substring(0, 15);
//    return key;
    return mOutTradeNo;
  }

  /**
   * sign the order info. 对订单信息进行签名
   *
   * @param content
   *      待签名订单信息
   */
  private String sign(String content) {
    return SignUtils.sign(content, RSA_PRIVATE);
  }

  /**
   * get the sign type we use. 获取签名方式
   *
   */
  private String getSignType() {
    return "sign_type="RSA"";
  }

}