关闭

Android支付宝支付

标签: android支付宝支付
517人阅读 评论(0) 收藏 举报
分类:

接入流程及说明

官方地址:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.erBW90&treeId=59&articleId=103657&docType=1

接入前准备阶段

1.商户签约审核(一般是公司的运营人员来做,生成PID)https://doc.open.alipay.com/doc2/detail.htm?treeId=58&articleId=103542&docType=1
2.RSA私钥及公钥生成(有几种加密方法,这里支付用的是RSA方式)
密钥作用(为了数字签名)
数字签名技术是将信息摘要用发送者的私钥加密,与原文一起传送给接收者。接收者只有用发送者的公钥才能解密被加密的信息摘要,然后接收者用相同的Hash函数
对收到的原文产生一个信息摘要,与解密的信息摘要做比对。如果相同,则说明收到的信息是完整的,在传输过程中没有被修改;不同则说明信息被修改过,因此数字
签名能保证信息的完整性。并且由于只有发送者才有加密摘要的私钥,所以我们可以确定信息一定是发送者发送的。
生成步骤:https://doc.open.alipay.com/doc2/detail?treeId=58&articleId=103242&docType=1
上传步骤:https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.a3hvUz&treeId=58&articleId=103578&docType=1

集成流程详解

SDK付款有两种模式:如果外部存在支付宝钱包,则直接跳转到支付宝钱包付款;没有支付宝钱包的场景下,将触发在SDK内部进行H5支付。商户在测试集成支付是否
正常的时候,建议测试(存在、没有)支付宝钱包的场景。对于测试过程中出现的异常,请联系支付宝技术支持进行处理。

1.导入开发资源
我们上面alipay-sdk-common中的三个jar文件拷贝到我们项目下的libs目录下,结构图如下


2.修改Manifest
    在商户应用工程的AndroidManifest.xml文件里面添加声明:
<activity
            android:name="com.alipay.sdk.app.H5PayActivity"
            android:configChanges="orientation|keyboardHidden|navigation"
            android:exported="false"
            android:screenOrientation="behind" >
</activity>
<activity
            android:name="com.alipay.sdk.auth.AuthActivity"
            android:configChanges="orientation|keyboardHidden|navigation"
            android:exported="false"
            android:screenOrientation="behind" >
 </activity>
和权限声明:
<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" />

3.添加混淆规则
在商户应用工程的proguard-project.txt里添加以下相关规则:
-libraryjars libs/alipaySDK-20150602.jar

-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}
至此,开发包开发资源导入完成。

4.订单数据生成
在调用开发包支付时需要提交订单信息info,其中参数以key=”value”形式呈现,参数之间以“&”分隔,所有参数不可缺。

5.支付接口调用
需要在新线程中调用支付接口。(可参考alipay_demo实现)
获取PayTask支付对象调用支付(支付或者授权的行为需要在独立的非ui线程中执行),代码示例:
final String orderInfo = info;   // 订单信息

        Runnable payRunnable = new Runnable() {

            @Override
            public void run() {
                PayTask alipay = new PayTask(DemoActivity.this);
                String result = alipay.pay(orderInfo,true);

                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };
         // 必须异步调用
        Thread payThread = new Thread(payRunnable);
        payThread.start();

6.支付结果获取和处理
调用pay方法支付后,将通过2种途径获得支付结果:
同步返回
商户应用客户端通过当前调用支付的Activity的Handler对象,通过它的回调函数获取支付结果。(可参考alipay_demo实现)
代码示例:
private Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
        Result result = new Result((String) msg.obj);
        Toast.makeText(DemoActivity.this, result.getResult(),
                    Toast.LENGTH_LONG).show();
    };
};
异步通知
商户需要提供一个http协议的接口,包含在参数里传递给快捷支付,即notify_url。支付宝服务器在支付完成后,
会以POST方式调用notify_url,以xml数据格式传输支付结果。

7.请求参数说明
请求参数是商户在与支付宝进行数据交互时,提供给支付宝的请求数据,以便支付宝根据这些数据进一步处理。

特殊说明(很重要):

商户在请求参数中,自己附属的一些额外参数,不要和支付宝系统中约定的key(下表中)重名,否则将可能导致未知的异常。
比如请求参数格式 out_trade_no="1234566"&total_fee="123.5"&rn_check="TRE" 其中out_trade_no、total_fee、rn_check
都是支付业务处理关键key,这个里面商户自己将out_trade_no、total_fee认为是支付宝必须传输的参数,rn_check=“TRE”是商户自己
的业务数据,但是由于rn_check也是支付宝关键key,支付宝将会认为这个rn_check是支付宝业务的参数,将导致误解析,导致支付出现不可预料的异常。
支付宝建议,商户不要在请求参数中添加除了支付宝指定的关键key外,还有其他的key用&连接。
比如 out_trade_no="1234566"&total_fee="123.5"&homepage="http://www.***.com" ,其中homepage是商户自己的业务key,支付宝建议不要
在请求参数中附带和支付无关的业务系统自身的key相关数据。
商户的请求参数中,所有的key(支付宝关键key或者商户自己的key),其对应的value中都不应该出现支付宝关键key,比如out_trade_no、total_fee、
seller_id等,否则该类交易将可能被支付宝拦截,禁止支付。
比如如下的请求 out_trade_no="1234566"&total_fee="123.5"&homepage="http://www.***.com"&body="这个辣条不错 out_trade_no=123 
total_fee=123.5"&memo="备忘seller_id=2088123213" 这个请求里面的body对应的value值中有支付宝关键key“out_trade_no”以及“total_fee”,
请求中对于memo字段中含有seller_id,这样的业务请求参数支付宝将会拦截。
1
partner="2088101568358171"&seller_id="xxx@alipay.com"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试
"&total_fee="0.01"&notify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&
sign="lBBK2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJIe2p
bjm%2F3kb%2FuGkpG%2BwYQYI51%2BhA3YBbvZHVQBYveBqK%2Bh8mUyb7GM1HxWs9k4%3D"&sign_type="RSA"





案例

获取网络数据

   private void getNetDataForAli(String serviceInstId,String studentId) {
    final TranLoading loading = new TranLoading(mContext);
    loading.show();
    RequestParams params = new RequestParams();
    params.addBodyParameter(Constant.NET_USERID,
            share.getString(Constant.SP_USERID, ""));
    params.addBodyParameter(Constant.NET_TOKEN,
            share.getString(Constant.SP_TOKEN, " "));
    params.addBodyParameter(Constant.NET_STUDENT_ID,studentId);
    params.addBodyParameter(Constant.NET_SERVICEINST_ID, serviceInstId);
    HttpUtils http = new HttpUtils(Constant.HTTP_TIME_OUT_LONG);
    http.send(HttpRequest.HttpMethod.POST, UrlUtis.SERVICE_ORDER_PAY_ALI,
            params, new RequestCallBack<String>() {

                @Override
                public void onSuccess(ResponseInfo<String> responseInfo) {

                    try {
                        JSONObject jsonObject = new JSONObject(
                                responseInfo.result);
                        final String success = jsonObject
                                .getString("success");
                        Log.e(TAG, jsonObject.toString());
                        JSONObject ob = new JSONObject(jsonObject
                                .getString(Constant.NET_OBJ));
                        outTradeNO = ob.getString(Constant.NET_OUTTRADENO);
                        payInfo = ob.getString(Constant.NET_ALI_PAYINFO);
                        if (Constant.NET_ALI_SUCCESS_TRUE.equals(success)) {
                            payForAli();
                        } else if (Constant.NET_ALI_SUCCESS_FSLSE
                                .equals(success)) {
                            final String msg = jsonObject.getString("msg");
                            ViewUtil.shortToast(mContext, msg);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                    loading.dismiss();
                }

                @Override
                public void onFailure(HttpException error, String msg) {
                    loading.dismiss();
                    ViewUtil.shortToast(mContext,
                            mContext.getString(R.string.error_net));
                }
            });

}


异步消息

 private Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
        switch (msg.what) {
        case Constant.SDK_PAY_FLAG: {
            PayResult payResult = new PayResult((String) msg.obj);
            String resultStatus = payResult.getResultStatus();
            if (TextUtils.equals(resultStatus, "9000")) {
                ViewUtil.shortToast(mContext,
                        getString(R.string.pay_success));
                //支付成功后改变存放的权限值
                CommonUtils.getServiceData(mContext);
                Intent intent = new Intent();
                setResult(RESULT_OK, intent.putExtra(
                        Constant.EXTRA_SERVICE_PAY_SUCCESS,
                        Constant.EXTRA_SERVICE_PAY_SUCCESS_TRUE));
                finish();

            } else {
                if (TextUtils.equals(resultStatus, "8000")) {
                    ViewUtil.shortToast(mContext,
                            getString(R.string.pay_be_sure));
                    // 每五秒钟轮循
                    handler.postDelayed(runnable, 5000);
                } else {
                    ViewUtil.shortToast(mContext,
                            getString(R.string.pay_fails));
                }
            }
            break;
        }
        case Constant.SDK_CHECK_FLAG: {
            ViewUtil.shortToast(mContext,
                    getString(R.string.pay_check_result) + msg.obj);
            break;
        }
        default:
            break;
        }
    };
};
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:65317次
    • 积分:1670
    • 等级:
    • 排名:千里之外
    • 原创:109篇
    • 转载:14篇
    • 译文:0篇
    • 评论:8条
    技术交流群
    516298940(互相学习)
    关注一下我的公众号 谢谢
    aaaa
    最新评论