android 支付宝的植入 《曾经踩过的坑》

来源:互联网 发布:html砸金蛋源码下载 编辑:程序博客网 时间:2024/05/17 03:40
最近公司有需求在项目中要植入支付宝支付等功能。 在完成植入的过程中,遇到了一些坑,今天趁趁任务不多做了个总结。分享给大家,希望以小伙伴不要陷入这些坑中以免浪费很多的时间。
首先说一下遇到的坑及其碰到的问题
1.java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag ClassCastException: com.android.org.bouncycastle.asn1.DLSequence cannot be cast to com.android.org.bouncycastle.asn1.ASN1Integer
原因:
public class SignUtils {   private static final String ALGORITHM = "RSA";   private static final String SIGN_ALGORITHMS = "SHA1WithRSA";   private static final String DEFAULT_CHARSET = "UTF-8";   public static String sign(String content, String privateKey) {      try {         java.security.Signature signature = java.security.Signature               .getInstance(SIGN_ALGORITHMS);PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(PayBase64.decode(privateKey));      KeyFactory keyf = KeyFactory.getInstance(ALGORITHM);      PrivateKey priKey = keyf.generatePrivate(priPKCS8);         PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(PayBase64.decode(privateKey));         KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");         PrivateKey priKey = keyFactory.generatePrivate(privSpec);         signature.initSign(priKey);         signature.update(content.getBytes(DEFAULT_CHARSET));         byte[] signed = signature.sign();         return PayBase64.encode(signed);      } catch (Exception e) {         e.printStackTrace();      }      return null;   }
修改之后,发现
com.android.org.bouncycastle.jcajce.provider.asymmetric.util.ExtendedInvalidKeySpecException: unable to process key spec: java.lang.ClassCastException: com.android.org.bouncycastle.asn1.DLSequence cannot be cast to com.android.org.bouncycastle.asn1.ASN1Integer
又这个错误,总么办?
最终是因为:
最终因为传入私钥错误。需要重新生成私钥:


2.在handler里面接受消息的时候,PayResult 转换失败,原因是你在进行
调用支付宝接口的时候,所发送的参数类型不一致导致的。eg:
PayTask payTask = new PayTask(DocPayConunselActivity.this);// String result = payTask.pay(signInfo, true);Map<String, String> result = payTask.payV2(signInfo, true);Message message = mHandler.obtainMessage();message.what = SDK_PAY_FLAG;message.obj = result;mHandler.sendMessage(message);
另外 如果返回的resultStatus是6002的时候,网络出错,或者是手机没有安装支付宝的时候,弹不出来网页版的支付登录框 这个时候也是会提示网络错误 。这时候你要查找你的配置文件看一下是否配置了以下文件:
<activityandroid:name="com.alipay.sdk.app.H5PayActivity"android:configChanges="orientation|keyboardHidden|navigation"android:exported="false"android:screenOrientation="behind" ></activity><activityandroid:name="com.alipay.sdk.auth.AuthActivity"android:configChanges="orientation|keyboardHidden|navigation"android:exported="false"android:screenOrientation="behind" ></activity>添加必要权限<uses-permissionandroid:name="android.permission.INTERNET" /><uses-permissionandroid:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permissionandroid:name="android.permission.ACCESS_WIFI_STATE" /><uses-permissionandroid:name="android.permission.READ_PHONE_STATE" /><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Android快捷支付SDK Demo resultStatus={4001};memo={参数错误};result={}问题
分析:填写的支付宝pkcs8编码的私钥 有问题,或者对应的公钥没有上传至支付宝造成的。 
后台处理的必须有这个步骤。上传公钥到支付宝
java.lang.NoClassDefFoundError: com.alipay.android.app.lib.ResourceMap
分析:没有加入android_lib 没有加入项目依赖项
resultStatus={7001};memo={商户没有开通移动快捷支付服务,请使用其他支付工具};result={}!
集成的基本流程如下:
第一步:2.1 导入jar包资源
目前最新版支付宝开发jar包下载地址:androidstarjack_支付宝集成过程详解— 运行DEMO.zip
下载后将之拷贝libs目录,Eclipse会自动添加依赖,Android Studio需在app的gradle中添加一行
compilefiles('libs/alipaySdk-20160223.jar')
点击右上角:Sync Now,稍等片刻
第二步:修改AndroidManifest.xml清单
声明必要Activity
<!--支付相关-->
 <activity
     android:name="com.alipay.sdk.app.H5PayActivity" android:configChanges="orientation|keyboardHidden|navigation"
     android:exported="false" android:screenOrientation="behind" />
 <activity
     android:name="com.alipay.sdk.auth.AuthActivity" android:configChanges="orientation|keyboardHidden|navigation"
     android:exported="false" android:screenOrientation="behind" />
添加必要权限
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
第四步:
private void payToOrderService(final String signInfo){
    new Thread() {
        @Override
        public void run() {
            super.run();
            PayTask payTask = new PayTask(DocPayConunselActivity.this);
            // String result = payTask.pay(signInfo, true);
            Map<String, String> result = payTask.payV2(signInfo, true);
            Message message = mHandler.obtainMessage();
            message.what = SDK_PAY_FLAG;
            message.obj = result;
            mHandler.sendMessage(message);
        }
    }.start();
}
app携带支付信息调用支付接口请求支付宝客户端调起支付界面;
用户操作,输入密码支付,支付成功;直接返回取消支付;出现错误,支付失败;进入支付界面,但输入密码支付,支付待确认;
支付宝客户端将支付结果告诉app客户端,商户服务器通知app服务器支付结果;
app客户端处理支付结果;
app服务器处理支付结果。
注意请求是异步的:x
<pre name="code" class="java">PayTask payTask = new PayTask(DocPayConunselActivity.this);// String result = payTask.pay(signInfo, true);Map<String, String> result = payTask.payV2(signInfo, true);Message message = mHandler.obtainMessage();message.what = SDK_PAY_FLAG;message.obj = result;mHandler.sendMessage(message)


返回的结果:
private Handler mHandler =new Handler(){    @Override    public void handleMessage(Message msg) {        super.handleMessage(msg);        switch (msg.what){            case SDK_PAY_FLAG:                PayResult payResult = null;                        try{                            payResult = new PayResult((Map<String, String>) msg.obj);                        }catch (Exception e){                            e.printStackTrace();                        }                /**                 对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。                 */                String resultInfo = payResult.getResult();// 同步返回需要验证的信息                String resultStatus = payResult.getResultStatus();                // 判断resultStatus 为9000则代表支付成功                if (TextUtils.equals(resultStatus, PAY_OK)) {//----------------------------------->支付成功                    // 该笔订单是否真实支付成功,需要依赖服务端的异步通知。                    GetToast.useString(DocPayConunselActivity.this, "购买服务成功");                } else if (TextUtils.equals(resultStatus, PAY_FAILED)) {//------------------------->支付失败                    // 该笔订单真实的支付结果,需要依赖服务端的异步通知。                    GetToast.useString(DocPayConunselActivity.this, ""+payResult.getMemo());                } else if (TextUtils.equals(resultStatus, PAY_CANCLE)) {//-------------------------->交易取消                    GetToast.useString(DocPayConunselActivity.this, ""+payResult.getMemo());                } else if (TextUtils.equals(resultStatus, PAY_NET_ERR)) {//------------------------->网络出现错误                    GetToast.useString(DocPayConunselActivity.this, ""+payResult.getMemo());                } else if (TextUtils.equals(resultStatus, PAY_WAIT_CONFIRM)) {//--------------------->交替等待                }                break;        }    }};
最后注意的是,有些手机没有安装支付宝客户端,如牵扯到支付功能的时候,我们直接天转到网页版的支付进行去输入密码去支付 。当然你也可以判断利用支付的sdk进行判断,如没有安装支付宝,提示去安装支付宝模块也是可以的。          
这样就完美无缺了。
QQ交流群 :232203809,欢迎入群 
这里写图片描述 
微信公众号:终端研发部 
(欢迎关注学习和交流)
0 0
原创粉丝点击