Android支付宝支付

来源:互联网 发布:vb自定义任务管理器 编辑:程序博客网 时间:2024/06/10 04:41

接入流程及说明

官方地址: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=12.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,这样的业务请求参数支付宝将会拦截。1partner="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%2BR1KugLrQEZMtG5jmJIe2pbjm%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