Android app第三方支付宝支付接入教程
支付宝的接入相对比较简单,看看支付宝官网的文档基本都能搞定,但是切记一点让你们的后台也要搞清楚支付宝的流程,重中之重。
1、注意事项
开发前一定要阅读支付宝官方文档
强烈建议签名等处理在后台处理,我这个是测试是在自己本地写的,不要吐槽
想获取支付宝合作商户ID,及支付宝公钥请点击支付宝链接,生成密钥及PKCS8转码工具在文档中
添加Android.permission.INTERNET权限和android.permission.ACCESS_NETWORK_STATE权限
要导入支付宝的包
2、特别注意事项(坑点)
下载支付宝的官网之后生成你所需要的密钥及PKCS8转码一定要小心
代码:
MainActivity中调起支付:Paypay=newPay(AffirmOrderActivity.this,paymoney);
Pay类
publicclassPay{ /**以下四项这些数值机密填入自己申请的就好**/ //商户PID publicstaticfinalStringPARTNER=""; //商户收款账号 publicstaticfinalStringSELLER=""; //商户私钥,pkcs8格式 publicstaticfinalStringRSA_PRIVATE=""; //支付宝公钥 publicstaticfinalStringRSA_PUBLIC=""; privateActivitycontext; privateStringmgoods,mprice,micon; privateintmtype; privateStringmOutTradeNo; publicPay(Activityactivity,Stringgoods,Stringgoodsmore,Stringprice,Stringicon,inttype,StringoutTradeNo){ context=activity; mprice=price; pay(price); } privateHandlermHandler=newHandler(){ publicvoidhandleMessage(Messagemsg){ switch(msg.what){ caseSDK_PAY_FLAG:{ PayResultpayResult=newPayResult((String)msg.obj); /** *同步返回的结果必须放置到服务端进行验证(验证的规则请看https://doc.open.alipay.com/doc2/ *detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665& *docType=1)建议商户依赖异步通知 */ StringresultInfo=payResult.getResult();//同步返回需要验证的信息 StringresultStatus=payResult.getResultStatus(); //判断resultStatus为“9000”则代表支付成功,具体状态码代表含义可参考接口文档 if(TextUtils.equals(resultStatus,"9000")){ Toast.makeText(context,"支付成功",Toast.LENGTH_SHORT).show(); }else{ //判断resultStatus为非"9000"则代表可能支付失败 //"8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态) if(TextUtils.equals(resultStatus,"8000")){ Toast.makeText(context,"支付结果确认中",Toast.LENGTH_SHORT).show(); }else{ //其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误 Toast.makeText(context,"支付失败",Toast.LENGTH_SHORT).show(); } } break; } default: break; } }; }; /** *callalipaysdkpay.调用SDK支付 * */ publicvoidpay(Stringgoods,Stringgoodsmore,Stringprice){ if(TextUtils.isEmpty(PARTNER)||TextUtils.isEmpty(RSA_PRIVATE)||TextUtils.isEmpty(SELLER)){ newAlertDialog.Builder(context).setTitle("警告").setMessage("需要配置PARTNER|RSA_PRIVATE|SELLER") .setPositiveButton("确定",newDialogInterface.OnClickListener(){ publicvoidonClick(DialogInterfacedialoginterface,inti){ // //finish(); } }).show(); return; } StringorderInfo=getOrderInfo(goods,goodsmore,price); Stringsign=sign(orderInfo); try{ /** *仅需对sign做URL编码 */ sign=URLEncoder.encode(sign,"UTF-8"); }catch(UnsupportedEncodingExceptione){ e.printStackTrace(); } /** *完整的符合支付宝参数规范的订单信息 */ finalStringpayInfo=orderInfo+"&sign=\""+sign+"\"&"+getSignType(); Log.i("lff","orderInfo=="+orderInfo); Log.i("lff","sign=="+sign);RunnablepayRunnable=newRunnable(){ @Override publicvoidrun(){ //构造PayTask对象 PayTaskalipay=newPayTask(context); //调用支付接口,获取支付结果 Stringresult=alipay.pay(payInfo,true); Messagemsg=newMessage(); msg.what=SDK_PAY_FLAG; msg.obj=result; mHandler.sendMessage(msg); } }; //必须异步调用 ThreadpayThread=newThread(payRunnable); payThread.start(); } /** *getthesdkversion.获取SDK版本号 * */ publicvoidgetSDKVersion(){ PayTaskpayTask=newPayTask(context); Stringversion=payTask.getVersion(); Toast.makeText(context,version,Toast.LENGTH_SHORT).show(); } /** *createtheorderinfo.创建订单信息 * */ privateStringgetOrderInfo(Stringsubject,Stringbody,Stringprice){ //签约合作者身份ID StringorderInfo="partner="+"\""+PARTNER+"\""; //签约卖家支付宝账号 orderInfo+="&seller_id="+"\""+SELLER+"\""; //商户网站唯一订单号 orderInfo+="&out_trade_no="+"\""+getOutTradeNo()+"\""; //商品名称 orderInfo+="&subject="+"\""+subject+"\""; //商品详情 orderInfo+="&body="+"\""+body+"\""; //商品金额 orderInfo+="&total_fee="+"\""+"0.01"+"\""; //服务器异步通知页面路径 //orderInfo+="¬ify_url="+"\""+"http://notify.msp.hk/notify.htm"+"\""; orderInfo+="¬ify_url="+"\""+"http://112.74.129.252/new/zfbCallback"+"\""; //服务接口名称,固定值 orderInfo+="&service=\"mobile.securitypay.pay\""; //支付类型,固定值 orderInfo+="&payment_type=\"1\""; //参数编码,固定值 orderInfo+="&_input_charset=\"utf-8\""; //设置未付款交易的超时时间 //默认30分钟,一旦超时,该笔交易就会自动被关闭。 //取值范围:1m~15d。 //m-分钟,h-小时,d-天,1c-当天(无论交易何时创建,都在0点关闭)。 //该参数数值不接受小数点,如1.5h,可转换为90m。 orderInfo+="&it_b_pay=\"30m\""; //extern_token为经过快登授权获取到的alipay_open_id,带上此参数用户将使用授权的账户进行支付 //orderInfo+="&extern_token="+"\""+extern_token+"\""; //支付宝处理完请求后,当前页面跳转到商户指定页面的路径,可空 orderInfo+="&return_url=\"m.alipay.com\""; //调用银行卡支付,需配置此参数,参与签名,固定值(需要签约《无线银行卡快捷支付》才能使用) //orderInfo+="&paymethod=\"expressGateway\""; returnorderInfo; } /** *gettheout_trade_noforanorder.生成商户订单号,该值在商户端应保持唯一(可自定义格式规范) * */ privateStringgetOutTradeNo(){ //SimpleDateFormatformat=newSimpleDateFormat("MMddHHmmss",Locale.getDefault()); //Datedate=newDate(); //Stringkey=format.format(date); // //Randomr=newRandom(); //key=key+r.nextInt(); //key=key.substring(0,15); //returnkey; returnmOutTradeNo; } /** *signtheorderinfo.对订单信息进行签名 * *@paramcontent *待签名订单信息 */ privateStringsign(Stringcontent){ returnSignUtils.sign(content,RSA_PRIVATE); } /** *getthesigntypeweuse.获取签名方式 * */ privateStringgetSignType(){ return"sign_type=\"RSA\""; } }
其它的工具类,原封不动拷贝过去就好
Base64类
packagecom.easyhomework.teacher.ui; publicfinalclassBase64{ privatestaticfinalintBASELENGTH=128; privatestaticfinalintLOOKUPLENGTH=64; privatestaticfinalintTWENTYFOURBITGROUP=24; privatestaticfinalintEIGHTBIT=8; privatestaticfinalintSIXTEENBIT=16; privatestaticfinalintFOURBYTE=4; privatestaticfinalintSIGN=-128; privatestaticcharPAD='='; privatestaticbyte[]base64Alphabet=newbyte[BASELENGTH]; privatestaticchar[]lookUpBase64Alphabet=newchar[LOOKUPLENGTH]; static{ for(inti=0;i<BASELENGTH;++i){ base64Alphabet[i]=-1; } for(inti='Z';i>='A';i--){ base64Alphabet[i]=(byte)(i-'A'); } for(inti='z';i>='a';i--){ base64Alphabet[i]=(byte)(i-'a'+26); } for(inti='9';i>='0';i--){ base64Alphabet[i]=(byte)(i-'0'+52); } base64Alphabet['+']=62; base64Alphabet['/']=63; for(inti=0;i<=25;i++){ lookUpBase64Alphabet[i]=(char)('A'+i); } for(inti=26,j=0;i<=51;i++,j++){ lookUpBase64Alphabet[i]=(char)('a'+j); } for(inti=52,j=0;i<=61;i++,j++){ lookUpBase64Alphabet[i]=(char)('0'+j); } lookUpBase64Alphabet[62]=(char)'+'; lookUpBase64Alphabet[63]=(char)'/'; } privatestaticbooleanisWhiteSpace(charoctect){ return(octect==0x20||octect==0xd||octect==0xa||octect==0x9); } privatestaticbooleanisPad(charoctect){ return(octect==PAD); } privatestaticbooleanisData(charoctect){ return(octect<BASELENGTH&&base64Alphabet[octect]!=-1); } /** *EncodeshexoctectsintoBase64 * *@parambinaryData *ArraycontainingbinaryData *@returnEncodedBase64array */ publicstaticStringencode(byte[]binaryData){ if(binaryData==null){ returnnull; } intlengthDataBits=binaryData.length*EIGHTBIT; if(lengthDataBits==0){ return""; } intfewerThan24bits=lengthDataBits%TWENTYFOURBITGROUP; intnumberTriplets=lengthDataBits/TWENTYFOURBITGROUP; intnumberQuartet=fewerThan24bits!=0?numberTriplets+1 :numberTriplets; charencodedData[]=null; encodedData=newchar[numberQuartet*4]; bytek=0,l=0,b1=0,b2=0,b3=0; intencodedIndex=0; intdataIndex=0; for(inti=0;i<numberTriplets;i++){ b1=binaryData[dataIndex++]; b2=binaryData[dataIndex++]; b3=binaryData[dataIndex++]; l=(byte)(b2&0x0f); k=(byte)(b1&0x03); byteval1=((b1&SIGN)==0)?(byte)(b1>>2) :(byte)((b1)>>2^0xc0); byteval2=((b2&SIGN)==0)?(byte)(b2>>4) :(byte)((b2)>>4^0xf0); byteval3=((b3&SIGN)==0)?(byte)(b3>>6) :(byte)((b3)>>6^0xfc); encodedData[encodedIndex++]=lookUpBase64Alphabet[val1]; encodedData[encodedIndex++]=lookUpBase64Alphabet[val2|(k<<4)]; encodedData[encodedIndex++]=lookUpBase64Alphabet[(l<<2)|val3]; encodedData[encodedIndex++]=lookUpBase64Alphabet[b3&0x3f]; } //formintegralnumberof6-bitgroups if(fewerThan24bits==EIGHTBIT){ b1=binaryData[dataIndex]; k=(byte)(b1&0x03); byteval1=((b1&SIGN)==0)?(byte)(b1>>2) :(byte)((b1)>>2^0xc0); encodedData[encodedIndex++]=lookUpBase64Alphabet[val1]; encodedData[encodedIndex++]=lookUpBase64Alphabet[k<<4]; encodedData[encodedIndex++]=PAD; encodedData[encodedIndex++]=PAD; }elseif(fewerThan24bits==SIXTEENBIT){ b1=binaryData[dataIndex]; b2=binaryData[dataIndex+1]; l=(byte)(b2&0x0f); k=(byte)(b1&0x03); byteval1=((b1&SIGN)==0)?(byte)(b1>>2) :(byte)((b1)>>2^0xc0); byteval2=((b2&SIGN)==0)?(byte)(b2>>4) :(byte)((b2)>>4^0xf0); encodedData[encodedIndex++]=lookUpBase64Alphabet[val1]; encodedData[encodedIndex++]=lookUpBase64Alphabet[val2|(k<<4)]; encodedData[encodedIndex++]=lookUpBase64Alphabet[l<<2]; encodedData[encodedIndex++]=PAD; } returnnewString(encodedData); } /** *DecodesBase64dataintooctects * *@paramencoded *stringcontainingBase64data *@returnArraycontaininddecodeddata. */ publicstaticbyte[]decode(Stringencoded){ if(encoded==null){ returnnull; } char[]base64Data=encoded.toCharArray(); //removewhitespaces intlen=removeWhiteSpace(base64Data); if(len%FOURBYTE!=0){ returnnull;//shouldbedivisiblebyfour } intnumberQuadruple=(len/FOURBYTE); if(numberQuadruple==0){ returnnewbyte[0]; } bytedecodedData[]=null; byteb1=0,b2=0,b3=0,b4=0; chard1=0,d2=0,d3=0,d4=0; inti=0; intencodedIndex=0; intdataIndex=0; decodedData=newbyte[(numberQuadruple)*3]; for(;i<numberQuadruple-1;i++){ if(!isData((d1=base64Data[dataIndex++])) ||!isData((d2=base64Data[dataIndex++])) ||!isData((d3=base64Data[dataIndex++])) ||!isData((d4=base64Data[dataIndex++]))){ returnnull; }//iffound"nodata"justreturnnull b1=base64Alphabet[d1]; b2=base64Alphabet[d2]; b3=base64Alphabet[d3]; b4=base64Alphabet[d4]; decodedData[encodedIndex++]=(byte)(b1<<2|b2>>4); decodedData[encodedIndex++]=(byte)(((b2&0xf)<<4)|((b3>>2)&0xf)); decodedData[encodedIndex++]=(byte)(b3<<6|b4); } if(!isData((d1=base64Data[dataIndex++])) ||!isData((d2=base64Data[dataIndex++]))){ returnnull;//iffound"nodata"justreturnnull } b1=base64Alphabet[d1]; b2=base64Alphabet[d2]; d3=base64Data[dataIndex++]; d4=base64Data[dataIndex++]; if(!isData((d3))||!isData((d4))){//CheckiftheyarePADcharacters if(isPad(d3)&&isPad(d4)){ if((b2&0xf)!=0)//last4bitsshouldbezero { returnnull; } byte[]tmp=newbyte[i*3+1]; System.arraycopy(decodedData,0,tmp,0,i*3); tmp[encodedIndex]=(byte)(b1<<2|b2>>4); returntmp; }elseif(!isPad(d3)&&isPad(d4)){ b3=base64Alphabet[d3]; if((b3&0x3)!=0)//last2bitsshouldbezero { returnnull; } byte[]tmp=newbyte[i*3+2]; System.arraycopy(decodedData,0,tmp,0,i*3); tmp[encodedIndex++]=(byte)(b1<<2|b2>>4); tmp[encodedIndex]=(byte)(((b2&0xf)<<4)|((b3>>2)&0xf)); returntmp; }else{ returnnull; } }else{//NoPADe.g3cQl b3=base64Alphabet[d3]; b4=base64Alphabet[d4]; decodedData[encodedIndex++]=(byte)(b1<<2|b2>>4); decodedData[encodedIndex++]=(byte)(((b2&0xf)<<4)|((b3>>2)&0xf)); decodedData[encodedIndex++]=(byte)(b3<<6|b4); } returndecodedData; } /** *removeWhiteSpacefromMIMEcontainingencodedBase64data. * *@paramdata *thebytearrayofbase64data(withWS) *@returnthenewlength */ privatestaticintremoveWhiteSpace(char[]data){ if(data==null){ return0; } //countcharactersthat'snotwhitespace intnewSize=0; intlen=data.length; for(inti=0;i<len;i++){ if(!isWhiteSpace(data[i])){ data[newSize++]=data[i]; } } returnnewSize; } }
总结一下支付宝支付步骤:1、生成秘钥私钥等(一般是后台处理的);2、支付宝包复制带项目中;3、调用支付(上述MainActivity和pay类)4、添加工具类
以上就是本文的全部内容,希望对大家学习Android软件编程有所帮助。