Android集成第三方支付

作者: LogosLi | 来源:发表于2017-07-02 20:53 被阅读575次
    支付平台排名

    关于支付平台

    支付宝可以说是一早就占据了支付平台的半壁江山,微信借助自身的社交平台的优势也成功对接自身的支付平台进行引流,可是要说这两个大佬已经站稳了自身的位置这是不太现实的,毕竟还有百度钱包,京东钱包,翼支付,沃支付,龙支付,在此我就不一一例举了,关于支付平台的搭建在技术上和审批上全部已经走向成熟,为未来肯定有一战,各自的平台发挥自身的优势,谁也不想轻易地放弃这块蛋糕,对于我们而言引入每一个支付平台显然是不现实的,可是每一个平台全部由自身的客户群体,这是我们不想放弃的,我们肯定回去设想一个问题,比方说我们早期去集成第三方登录的SDK,是否有一个服务商提供一个统一的引入方案,这里我们又必须一下ping++和连连科技,这部分的工作主要还是考验一个后端的服务器搭建,如同构建一个协议一样去处理处理不同支付平台的支付信息,如同写一个自己的长连接协议,就是这样一种难度,之后提供一个统一的SDK接口给别人集成和使用,关于这种服务的构建已经让太多的互联网企业开始盈利。

    支付相关知识

    什么是移动支付

    移动支付指的是用户使用移动的设备,完成对所购买商品或者服务的支付功能。

    移动支付分为:

    l远程支付(网上支付,短信支付)

    l近场支付(刷卡,pos机)

    常见的支付厂商

    支付宝——阿里出品,使用量比较多

    微信——腾讯出品,使用量也是越来越多

    易付宝——苏宁易购

    财付通——腾讯出品,使用量不大

    银联——不属于某一个公司,是指中国的银行卡联合组织

    百付宝——百度出品

    支付宝钱包——阿里的

    百度钱包——百度

    快钱

    ping++——三方聚合支付平台,整合了很多支付平台,类似SharedSDK在分享中的作用

    三方支付安不安全

    市面上常见的三方支付都是类似BAT这种大公司的产品,各大公司都有自己的安全策略,并且三方支付平台出现了很久,一直没有出什么问题,因此相对来说是比较安全的。

    支付流程—— 从用户角度

    1. 选择商品

    2.选择支付方式(支付宝、微信…)

    3.处理支付结果(成功、失败、取消)

    支付流程—— 从APP开发角度

    1.用户选择要购买的商品,选择好支付方式

    2.拼接支付信息,以post请求的方式将信息发送到自己家的服务器端

    3.服务器端返回一个付款信息(付款信息的内容根据支付平台的不同而有所不同)

    4. APP端拿着付款信息,调用第三方支付SDK

    5. 处理支付结果:

    l同步返回:支付后通知我们自己的APP

    l异步通知:支付后通知我们的Server

    集成支付宝支付

    支付宝支付

    支付宝支付的1&2

    调用支付宝支付前,需先完成支付流程的前两步:

    1.拼接支付信息,以post请求的方式将信息发送到自己家的服务器端

    2.接收服务器端返回一个付款信息(付款信息的内容根据支付平台的不同而有所不同)

    紧接着,我们需要进行支付宝SDK的集成。

    支付宝开放平台

    支付宝开放平台:

    https://open.alipay.com/platform/home.htm

    支付宝接入文档地址:

    https://doc.open.alipay.com/doc2/detail.htm?treeId=59&articleId=104352&docType=1

    下载支付宝官方的文档、SDK和Demo,查看集成文档和Demo。

    支付宝接入的前提

    支付宝SDK接入前,必须要进行商户签约和秘钥上传。

    商户签约:

    公司需找支付宝进行签约,签约后,就可以用签约支付宝账号登录“商家服务”平台,获取自己的合作者身份ID(PID),并上传自己的秘钥信息。

    秘钥上传:

    接入支付宝前,商家需上传自己的秘钥信息(公钥),实现公钥互换。

    加密方式可选RSA、DSA2种,我们一般都采用RSA加密方式。

    (DES加密算法特点:分组比较短、密钥太短、密码生命周期短、运算速度较慢)

    RSA秘钥生成:

    秘钥可以通过一个OpenSSL工具来生成:

    https://doc.open.alipay.com/doc2/detail.htm?treeId=58&articleId=103242&docType=1

    商户签约和秘钥上传这两个大前提准备完成之后,我们就有的PID号和商户的私钥,可以开始后续的集成步骤。

    支付宝支付的3 &4

    3.APP端拿着付款信息,调用第三方支付SDK


    /*** 完整的符合支付宝参数规范的订单信息(为了保证秘钥的安全性,这里应由服务器返回,也就是我们支付宝支付的第2步)*/finalString payInfo = orderInfo +"&sign=\""+ sign +"\"&"+ getSignType();

    Runnable payRunnable =newRunnable() {

    @Override

    public voidrun() {

    // 构造PayTask 对象PayTask alipay = new PayTask(PayDemoActivity.this);// 调用支付接口,获取支付结果String result = alipay.pay(payInfo, true);

    Message msg =newMessage();

    msg.what=SDK_PAY_FLAG;

    msg.obj= result;

    mHandler.sendMessage(msg);

    }

    };

    // 必须异步调用

    Thread payThread =newThread(payRunnable);

    payThread.start();

    4. 处理支付结果:

    l同步返回:支付后通知我们自己的APP

    l异步通知:支付后通知我们的Server

    private HandlermHandler=newHandler() {

    public voidhandleMessage(Message msg) {

    switch(msg.what) {

    caseSDK_PAY_FLAG: {

    PayResult payResult =newPayResult((String) msg.obj);

    /*** 同步返回的结果必须放置到服务端进行验证(验证的规则请看https://doc.open.alipay.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(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();

    }

    }

    break;

    }

    default:

    break;

    }

    };

    };

    注意:

    APP端接到支付宝SDK同步返回的结果后,必须对结果进行校验(校验应由服务器端来做),或者干脆依赖服务器端的异步通知的结果。

    验证规则:

    https://doc.open.alipay.com/doc2/detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&docType=1

    银联支付

    银联支付和支付宝支付的前两步是没有区别的,所有的三方支付的前两步一般都没什么区别,都是先与自己家的服务器做交互,拿到服务器返回的订单信息。但是每种支付的订单信息肯定是不同的(字段,数据…)。

    对于银联支付来说,它的付款信息中只需要一个东西:银联流水号(TN号)

    注意:银联强制要求获取TN号的过程必须交给服务端去做。

    https://open.unionpay.com/ajweb/help/file/techFile?cateLog=Development_kit

    添加Jar包和各种配置

    1. 把UPPayAssistEx.jar,UPPayPluginEx.jar拷贝到libs目录下

    2. 把libentryex.so拷贝到libs\armeabi\目录下

    3. 把style.xml拷贝到res\values目录下

    4. 在清单文件中添加:

    android:name="com.unionpay.uppay.PayActivityEx"

    android:screenOrientation="portrait"

    android:configChanges="orientation|keyboardHidden|screenSize"

    android:excludeFromRecents="true"

    android:windowSoftInputMode="adjustResize"/>

    android:name="com.unionpay.uppay.PayActivity"

    android:screenOrientation="portrait"

    android:configChanges="orientation|keyboardHidden|screenSize"

    android:excludeFromRecents="true"

    android:theme="@style/Theme.UPPay"/>

    发起支付

    /**activity  用来启动一个activity的context,比如传入当前的activitypayCls  银联Activity,固定PayActivity.classspId  保留使用,这里输入nullsysProvider  保留使用,这里输入nulltn  提交订单银联返回的交易流水号tnmode  调用插件模式,01是测试,00是正式*/
    UPPayAssistEx.startPayByJAR(this,PayActivity.class, null, null,tn,payMode);

    处理支付的结果

    @Override

    protected voidonActivityResult(intrequestCode, intresultCode,Intent data) {

    /*************************************************** 处理银联手机支付控件返回的支付结果*************************************************/if(data ==null) {

    return;

    }

    String msg ="";

    /*

    * 支付控件返回字符串:success、fail、cancel 分别代表支付成功,支付失败,支付取消

    */

    String str = data.getExtras().getString("pay_result");

    if(str.equalsIgnoreCase("success")) {

    msg ="支付成功!";

    }else if(str.equalsIgnoreCase("fail")) {

    msg ="支付失败!";

    }else if(str.equalsIgnoreCase("cancel")) {

    msg ="用户取消了支付";

    }

    AlertDialog.Builder builder =newAlertDialog.Builder(this);

    builder.setTitle("支付结果通知");

    builder.setMessage(msg);

    builder.setInverseBackgroundForced(true);

    builder.setNegativeButton("确定", newDialogInterface.OnClickListener() {

    @Override

    public voidonClick(DialogInterface dialog, intwhich) {

    dialog.dismiss();

    }

    });

    builder.create().show();

    }

    微信支付

    微信开放平台:

    https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN&token=45d03ca3d373290873f97498194a7da8a7356fed

    获取签名信息:

    http://lbsyun.baidu.com/index.php?title=androidsdk/guide/key

    注意事项

    l微信支付的前提是手机上已经安装了微信客户端

    l注意应用的签名,必须与微信支付开放平台注册应用时填的签名信息一致,否则无法发起支付(微信后台会去校验发起支付请求的应用的签名+包名是否与在微信平台注册的是一致的,如果不一致,则认为验证失败,无法发起支付请求

    l在支付之前,如果应用没有注册到微信,应该先调用IWXAPI.registerApp方法将应用注册到微信

    支付步骤(文档)

    微信支付官方Demo提供的支付步骤:

    1. 获取 access_token

    2. 成预支付订单,需要用到第一步的access_token,得到的是prepayId

    3.发起微信支付

    4. 处理支付结果

    但是实际上,出于安全性的考虑,前2步我们都是放到服务器端去做的,因此,我们只需关注后2步就够了。

    发起支付

    PayReq req =newPayReq();

    req.appId= Constants.APP_ID;// APP ID

    req.partnerId= Constants.PARTNER_ID;// 商家id

    req.prepayId= result.prepayId;//预支付id

    req.nonceStr=nonceStr;//32位内的随机串,防止重复发送

    req.timeStamp= String.valueOf(timeStamp);//时间戳

    req.packageValue="Sign="+packageValue;

    req.sign= sign;

    api.sendReq(req);

    注意:PayReq所需字段,应由服务器端返回,不要放到Android客户端来做处理

    处理支付的结果

    微信支付的结果需在一个WXPayEntryActivity中去实现。

    注意:

    WXPayEntryActivity的全路径必须是: 包名.wxapi. WXPayEntryActivity,否则微信SDK无法调用此页面。

    别忘记在清单文件中注册这个Activity:

    android:name="net.sourceforge.simcpux.wxapi.WXPayEntryActivity"

    android:exported="true"

    android:launchMode="singleTop"/>

    WXPayEntryActivity.java:

    public classWXPayEntryActivityextendsActivityimplementsIWXAPIEventHandler{

    privateIWXAPIapi;

    @Override

    public voidonCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.pay_result);

    api= WXAPIFactory.createWXAPI(this,Constants.APP_ID);

    api.handleIntent(getIntent(), this);

    }

    @Override

    protected voidonNewIntent(Intent intent) {

    super.onNewIntent(intent);

    setIntent(intent);

    api.handleIntent(intent, this);

    }

    @Override

    public voidonReq(BaseReq req) {

    }

    /*** 四、接收支付返回结果:*/@Override

    public voidonResp(BaseResp resp) {

    Log.d("WXPayEntryActivity","onPayFinish, errCode = "+ resp.errCode);

    if(resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {

    AlertDialog.Builder builder =newAlertDialog.Builder(this);

    builder.setTitle(R.string.app_tip);

    builder.setMessage(getString(R.string.pay_result_callback_msg,String.valueOf(resp.errCode)));

    builder.show();

    }

    }

    }

    结束标记,希望对第一次集成支付平台的同学有帮助

    相关文章

      网友评论

      • pokerfaceCmy:麻烦将代码放到代码块中...这样看真的很辣眼睛
        LogosLi:@从未变过 哈哈,比较懒
      • 乘风破浪的程序员:楼主,有没有用过 Visa 信用卡 支付集成啊
        LogosLi:@O黑山小妖精儿O 你可以去官方查询一下SDK,支付宝不是支持部门信用卡的支付

      本文标题:Android集成第三方支付

      本文链接:https://www.haomeiwen.com/subject/dhdocxtx.html