zoukankan      html  css  js  c++  java
  • Android中集成第三方支付

    常见的第三方支付解决方案

    • 支付宝支付
    • 微信支付
    • 银联支付
    • Ping++统一支付平台(需要继承服务器端和客户端)
    • 短信支付

    支付宝的集成流程

    • 首先,支付宝支付准备工作
      • 首先登录【支付宝开放平台】http://open.alipay.com/platform/home.htm,创建应用,并给应用添加App支付功能
      • 由于App支付功能需要签约,因此需要上传公司信息和证件等资料进行签约
      • 签约成功后,需要配置秘钥。使用支付宝提供的工具生成RSA公钥和私钥(工具下载地址),公钥需要设置到管理后台,具体操作请登录官网
    • 第二步,拼接符合支付宝规范的请求参数,主要有以下几点:

      • 先拼接订单信息,如下:

        Map<string, string=""> params = OrderInfoUtil2_0.buildOrderParamMap(APPID, rsa2);
        String orderParam = OrderInfoUtil2_0.buildOrderParam(params);
      • 然后并对订单信息使用私钥进行RSA加密,并拼接订单信息:

        String sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2);
        final String orderInfo = orderParam + "&" + sign;
      • 但是,上面的2个步骤,由于涉及到私钥加密,如果写在本地容易暴露私钥,所以一般会让服务器提供一个提交确认订单的接口,客户端将订单相关参数传递给服务器,服务器负责拼接支付宝的请求参数,然后返回给客户端,所以上面的步骤其实不用我们来做。
    • 第三步,调用支付api,传入请求参数进行支付请求:

      // 构造PayTask 对象
      PayTask alipay = new PayTask(PayDemoActivity.this);
      Map<string, string=""> result = alipay.payV2(orderInfo, true);
    • 最后,接收支付结果,根据支付状态进行UI提示:

      String resultInfo = payResult.getResult();// 同步返回需要验证的信息
      String resultStatus = payResult.getResultStatus();
      // 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
      if (TextUtils.equals(resultStatus, "9000")) {
          Toast.makeText(PayDemoActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
      } else {
          // 判断resultStatus 为非"9000"则代表可能支付失败
          // "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
          if (TextUtils.equals(resultStatus, "8000")) {
              Toast.makeText(PayDemoActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show();
          
          } else {
              // 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
              Toast.makeText(PayDemoActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
          
          }
      }

    微信支付的集成流程

    整体步骤可以说,和支付宝一致的

    详情查看:
    1.微信商户接入准备工作
    2.微信支付sdk开发文档 
    3.微信支付sdk详细流程

    • 首先,获取符合微信支付规范的请求参数,demo中是通过一个url获取的,这告诉我们,应该让服务器提供一个接口,来对订单信息进行加密然后返回。代码如下:

      String url = "http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=android";
      byte[] buf = Util.httpGet(url);
    • 第二步,对请求参数进行封装:

      PayReq req = new PayReq();
      //req.appId = "wxf8b4f85f3a794e77";  // 测试用appId
      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
    • 第三步,调用支付api,传入请求参数:

      // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
      api.sendReq(req);
    • 最后,接收支付结果,根据状态码进行UI提示,此处在demo中是在WXPayEntryActivity中进行操作的。

      public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
          private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
          private IWXAPI api;
          @Override
          public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.pay_result);
              api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
              api.handleIntent(getIntent(), this);
          }
          @Override
          protected void onNewIntent(Intent intent) {
              super.onNewIntent(intent);
              setIntent(intent);
              api.handleIntent(intent, this);
          }
          @Override
          public void onReq(BaseReq req) {
          }
          @Override
          public void onResp(BaseResp resp) {
              if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
                  AlertDialog.Builder builder = new AlertDialog.Builder(this);
                  builder.setTitle(R.string.app_tip);
                  builder.setMessage(getString(R.string.pay_result_callback_msg, String.valueOf(resp.errCode)));
                  builder.show();
              }
          }
      }

    银联支付的集成流程

    银联支付最简单,只要有TN(交易流水号)即可发起支付!

    详情查看:
    1.银联支付开发者平台首页
    2.银联手机支付资料下载页 

    • 首先,当要进行支付时,调用自己服务器提供的接口获取流水号,即TN,代码类似这样:

      String tn = HttpHelper.execGet("tn_url");
    • 然后,拿到TN后,调用银联SDK的api向银联发起支付请求,代码类似这样:

      //其中mode参数解释: "00" - 启动银联正式环境 "01" - 连接银联测试环境
      
      UPPayAssistEx.startPay(activity, null, null, tn, mode);
    • 最后,在onActivityResult方法中获取支付结果进行UI提示,代码类似这样:

      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data) {
              /*************************************************
               * 步骤3:处理银联手机支付控件返回的支付结果
               ************************************************/
              if (data == null) {
                  return;
              }
          
              String msg = "";
              /*
               * 支付控件返回字符串:success、fail、cancel 分别代表支付成功,支付失败,支付取消
               */
              String str = data.getExtras().getString("pay_result");
              if (str.equalsIgnoreCase("success")) {
                  
                  // 如果想对结果数据验签,可使用下面这段代码,但建议不验签,直接去商户后台查询交易结果
                  // result_data结构见c)result_data参数说明
                  if (data.hasExtra("result_data")) {
                      // 结果result_data为成功时,去商户后台查询一下再展示成功
                      //注意,此处只是表示客户端收到了支付成功的响应。但是为了保险起见,需要向服务器查询一下是否真的支付功。
                      //具体做法是,让自己服务器提交一个查询订单状态的接口,如果服务器返回的结果也是支付成功,那么就真的提示用户
                  } 
                  msg = "支付成功!";
              } else if (str.equalsIgnoreCase("fail")) {
                  msg = "支付失败!";
              } else if (str.equalsIgnoreCase("cancel")) {
                  msg = "用户取消了支付";
              }
          
              //进行UI提示
              AlertDialog.Builder builder = new AlertDialog.Builder(this);
              builder.setTitle("支付结果通知");
              builder.setMessage(msg);
              builder.setInverseBackgroundForced(true);
              // builder.setCustomTitle();
              builder.setNegativeButton("确定", new DialogInterface.OnClickListener() {
                  @Override
                  public void onClick(DialogInterface dialog, int which) {
                      dialog.dismiss();
                  }
              });
              builder.create().show();
          }
  • 相关阅读:
    比较两个DataTable数据(结构相同),返回新增的,删除的,修改前的,修改后的 DataTable
    通用jig类,用到委托
    网站性能优化之HTTP请求过程简述!
    常见JS效果实现实现之图片减速度滚动
    Firefox中实现的outerHTML
    电子商务网站上的常用的放大镜效果
    div背景半透明,覆盖整个可视区域的遮罩层效果
    Javascript类定义语法,私有成员、受保护成员、静态成员等
    HTML/CSS控制div垂直&&水平居中屏幕
    CSS团队协作开发方式的思考
  • 原文地址:https://www.cnblogs.com/yegong0214/p/6498429.html
Copyright © 2011-2022 走看看