支付宝androidsdk
① android开发支付宝付款实时通知是怎么实现的
到支付宝官网,下载支付宝集成开发包,看懂里面的关键代码
由于android设备一般用的都是无线支付,所有我们申请的就是支付宝无线快捷支付接口。
如果链接失效,你可以到支付宝官网商家服务模块中找到 快捷支付(无线)这个服务。
下载集成开发包,解压发现里面有客户端的demo即说明文档,在客户端的demo中找到Android_SDK,这个就是你要用到的支付宝接口及demo。
把demo(alipay_sdk_demo)和(alipay_lib)导入到你的eclipse里面,然后你可以试着运行一遍demo(alipay_sdk_demo),只要把这个demo搞懂了,你就会调用这个支付宝接口了。至于到时候如何集成到你的项目里面,文档上说明很详细,按着文档上一步一步来就行了。我的建议是先把这个demo弄懂再设计你的项目,看看调用接口时需要哪些数据,这样也有利于你一开始设计数据。
下面来简单的介绍下接口demo里面的结构。
你打开项目会发现里面有5个类。
java">kagecom.alipay.android.msp.demo;
importjava.io.IOException;
........
........
importcom.alipay.android.app.sdk.AliPay;
,
OnClickListener{
publicstaticfinalStringTAG="alipay-sdk";
privatestaticfinalintRQF_PAY=1;
privatestaticfinalintRQF_LOGIN=2;
privateEditTextmUserId;
privateButtonmLogon;
@Override
publicvoidonCreate(BundlesavedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.external_partner);
initProcts();
initListView();
}
/*
*(non-Javadoc)
*
*@seeandroid.app.Activity#onCreateOptionsMenu(android.view.Menu)
*/
@Override
(Menumenu){
menu.add(Menu.NONE,Menu.FIRST,1,"快速登录");
returntrue;
}
/*
*(non-Javadoc)
*
*@seeandroid.app.Activity#onOptionsItemSelected(android.view.MenuItem)
*/
@Override
(MenuItemitem){
switch(item.getItemId()){
caseMenu.FIRST:
setContentView(R.layout.trustlogin);
mUserId=(EditText)findViewById(R.id.user_id);
mLogon=(Button)findViewById(R.id.get_token);
mLogon.setOnClickListener(this);
break;
}
returnfalse;
}
privatevoidinitProcts(){
if(sProcts!=null)
return;
XmlResourceParserparser=getResources().getXml(R.xml.procts);
ArrayList<Proct>procts=newArrayList<Proct>();
Proctproct=null;
try{
inteventType=parser.getEventType();
while(eventType!=XmlPullParser.END_DOCUMENT){
if(eventType==XmlPullParser.START_TAG
&&parser.getName().equalsIgnoreCase("proct")){
proct=newProct();
proct.subject=parser.getAttributeValue(0);
proct.body=parser.getAttributeValue(1);
proct.price=parser.getAttributeValue(2);
procts.add(proct);
}
eventType=parser.next();
}
sProcts=newProct[procts.size()];
procts.toArray(sProcts);
}catch(XmlPullParserExceptione){
e.printStackTrace();
}catch(IOExceptione){
e.printStackTrace();
}
}
//listview点击事件,里面调用的支付宝接口
@Override
publicvoidonItemClick(AdapterView<?>arg0,Viewarg1,intposition,
longarg3){
try{
Log.i("ExternalPartner","onItemClick");
Stringinfo=getNewOrderInfo(position);//这个是订单信息
Stringsign=Rsa.sign(info,Keys.PRIVATE);//签名加密订单信息什么的
sign=URLEncoder.encode(sign);
info+="&sign=""+sign+""&"+getSignType();
Log.i("ExternalPartner","startpay");
//startthepay.
Log.i(TAG,"info="+info);
finalStringorderInfo=info;
newThread(){
publicvoidrun(){
AliPayalipay=newAliPay(ExternalPartner.this,mHandler);//这个应该就是支付宝接口了,哈哈,支付宝现在把很多功能都封装了,所以省了很多代码
//设置为沙箱模式,不设置默认为线上环境
//alipay.setSandBox(true);
Stringresult=alipay.pay(orderInfo);//这个是返回的结果,你到时候可以根据这个结果加以操作你想操作的,然后基本就完了,其他的你想附加的功能你看着写吧,现在Key.java配置好就能调用快捷支付了
//后面的这些代码可以改成你自己的,也可以在它们的基础上改
Log.i(TAG,"result="+result);
Messagemsg=newMessage();
msg.what=RQF_PAY;
msg.obj=result;
mHandler.sendMessage(msg);
}
}.start();
}catch(Exceptionex){
ex.printStackTrace();
Toast.makeText(ExternalPartner.this,R.string.remote_call_failed,
Toast.LENGTH_SHORT).show();
}
}
//获得订单信息的方法
privateStringgetNewOrderInfo(intposition){
StringBuildersb=newStringBuilder();
sb.append("partner="");
sb.append(Keys.DEFAULT_PARTNER);//合作身份者id
sb.append(""&out_trade_no="");
sb.append(getOutTradeNo());//这个是订单编号
sb.append(""&subject="");
sb.append(sProcts[position].subject);//这个应该是商品名称
sb.append(""&body="");
sb.append(sProcts[position].body);//这个应该是商品的描述,具体你可以参考demo
sb.append(""&total_fee="");
sb.append(sProcts[position].price.replace("一口价:",""));//这个是要付款的金额,到时候你调用的时候改下就行了
sb.append(""¬ify_url="");
//网址需要做URL编码
sb.append(URLEncoder.encode("http://notify.java.jpxx.org/index.jsp"));//服务器异步通知页面,完成交易后通知商家服务器的页面,以post的形式将商品订单信息发送到指定页面,手机客户端不需要可以先放在这不管。是不是,这个类很简单看懂吧,就一listview。调用支付宝接口的方法就在onItemClick()方法里面,如果你是一个按钮的话换成按钮点击事件就行了,主要的细节我注释已写。现在你要想的是,需要哪些数据,提供给onItemClick()方法里面的Stringinfo。demo里面的数据是getNewOrderInfo(intposition)这个方法提供的,你可以自己提供或者在上面修改下。
现在,你已经知道代码是如何调用支付宝接口了。接下来,是如何把这些集成到你的项目中去。
② 接入支付宝支付SDK
接入支付宝支付SDK
可以说支付宝支付接入是所有SDK最好接入的,没有之一。
客户端不用签名,也不用管包名,也不用管签名文件,就接口返回订单,把订单交给支付宝SDK调用就行,成功或者失败都在当前界面返回给你。你迟罩再去通知接口。
支付流程图
官方文档地址
!支付宝支付官方文档地址
按照文档说明接入SDK和相关配置,在这就不重复了
客户端支付关键代码===》支付接口的调用(调起支付弹框)
记住支付接口的调用必须在独立的非ui线禅悔程中执行,即需新开线程里面调用。可以想官方demo一样用new Thread方式。
下面我给出用Observable方式示例代码
在PayUtils中
/**
* desc:支付宝支付
* Created by congge on 2018/8/27 17:20
* @param orderInfo 接口返回的订单
**/
public static void aliPay(final Activity activity, final String orderInfo, final OrderListener orderListener) {
Observable.just(orderInfo)
.map(new Function () {
@Override
public String apply(String orderInfo) throws Exception {
//用户在商户app内部点击付款,是否需要一个loading做为在钱包唤起之前的过渡,这个值设置为true
return new PayTask(activity).pay(orderInfo, true);
}
})
.subscribeOn(Schelers.io())
.observeOn(AndroidSchelers.mainThread())
.subscribe(new Consumer () {
@Override
public void accept(String payResult) throws Exception {
orderListener.onPayResult(payResult);
}
});
}
支付结果返回处理
返回例子:
resultStatus={9000};memo={};result={{"alipay_trade_app_pay_response":{"code":"10000","msg":"Success","app_id":"2016091300503896","auth_app_id":"2016091300503896","charset":"utf-8","timestamp":"2018-08-28 17:51:11","out_trade_no":"nVElbd74TW6WnEyxQwvX8A","total_amount":"0.01","trade_no":"2018082821001004680500208879","seller_id":"2088102175487650"},"sign":"/HIkM97PoBGAVlTmi//vYKmR0VW+2OwGhlRPPMMZtQOEqh8a9/aIijzT6ZLwy9Hl4ayG/fVKhdC1VdckF6++/+8NkoKle/QI+FA==","sign_type":"RSA2"}}
也可以自己打log看看
处码袭闹理示例代码:
//支付宝支付
PayUtils.aliPay(this, result.getSignDataStr(), new PayUtils.OrderListener() {
@Override
public void onPayResult(String payResult) {
PayResult pr = new PayResult(payResult);
String rs = pr.getResultStatus();
String r = pr.getResult();
switch (rs) {
case AliPayResultStatus.PAY_SUCCESS:
ToastUtils.show(R.string.pay_success);
//通知接口支付成功
break;
case AliPayResultStatus.PAY_PROCESSING:
case AliPayResultStatus.PAY_UNKNOWN:
ToastUtils.show(R.string.pay_fail);
//支付可能成功,要接口去查询
break;
default:
ToastUtils.show(R.string.pay_fail);
//通知接口支付失败,取消订单
}
}
});
上面方法中:
//通知接口支付成功 //支付可能成功,要接口去查询 //通知接口支付失败,取消订单。根据你产品需求要不要通知你服务器做的操作。正常是要的,用来改变订单状态
PayResult.class
public class PayResult {
private String resultStatus;
private String result;
private String memo;
public PayResult(String rawResult) {
if (TextUtils.isEmpty(rawResult))
return;
String[] resultParams = rawResult.split(";");
for (String resultParam : resultParams) {
if (resultParam.startsWith("resultStatus")) {
resultStatus = gatValue(resultParam, "resultStatus");
}
if (resultParam.startsWith("result")) {
result = gatValue(resultParam, "result");
}
if (resultParam.startsWith("memo")) {
memo = gatValue(resultParam, "memo");
}
}
}
@Override
public String toString() {
return "resultStatus={" + resultStatus + "};memo={" + memo
+ "};result={" + result + "}";
}
private String gatValue(String content, String key) {
String prefix = key + "={";
return content.substring(content.indexOf(prefix) + prefix.length(),
content.lastIndexOf("}"));
}
public String outOrder() {
String order = ""out_trade_no"";
if (result.contains(order)) {
String begin = result.substring(result.indexOf(order));
String ss = begin.split(",")[0];
String newS = ss.replace(""", "")
.replace("}", "")
.replace(":", "")
.replace("out_trade_no", "");
try {
return newS;
} catch (Exception e) {
e.printStackTrace();
}
}
return "";
}
/**
* @return the resultStatus
*/
public String getResultStatus() {
return resultStatus;
}
/**
* @return the memo
*/
public String getMemo() {
return memo;
}
/**
* @return the result
*/
public String getResult() {
return result;
}}
最后给下支付返回码表
AliPayResultStatus.class
public class AliPayResultStatus {
/**
* 订单支付成功,唯一肯定是支付成功的
*/
public static final String PAY_SUCCESS = "9000";
/**
* 正在处理中,支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态
*/
public static final String PAY_PROCESSING = "8000";
/**
* 订单支付失败
*/
public static final String PAY_FAIL = "4000";
/**
* 重复请求
*/
public static final String PAY_REPEAT = "5000";
/**
* 用户中途取消
*/
public static final String PAY_PROCESS_CANCEL = "6001";
/**
* 网络连接出错
*/
public static final String PAY_NET_ERROR = "6002";
/**
* 支付结果未知(有可能已经支付成功),请查询商户订单列表中订单的支付状态
*/
public static final String PAY_UNKNOWN = "6004";}
还有一个直接弃用沙箱调试模式,否则提示支付失败也有可能不知道错在那,怕金额大,和接口商量,测试服务器就用0.01测试。
③ 手机版的支付宝是用什么语言开发的
手机版的支付宝是Java/C/C++语言开发的。
附注:
Java是一种可以撰写跨平台应用程序的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。
C语言是一种结构化语言。它层次清晰,便于按模块化方式组织程序,易于调试和维护。C语言的表现能力和处理能力极强。它不仅具有丰富的运算符和数据类型,便于实现各类复杂的数据结构。它还可以直接访问内存的物理地址,进行位(bit)一级的操作。由于C语言实现了对硬件的编程操作,因此C语言集高级语言和低级语言的功能于一体。既可用于系统软件的开发,也适合于应用软件的开发。此外,C语言还具有效率高,可移植性强等特点。因此广泛地移植到了各类各型计算机上,从而形成了多种版本的C语言。
C是C++的基础,C++语言和C语言在很多方面是兼容的。因此,掌握了C语言,再进一步学习C++就能以一种熟悉的语法来学习面向对象的语言,从而达到事半功倍的目的。
④ app中使用h5支付
因为苹果爸爸的各种封锁与限制,导致 app 中如果集成支付sdk上架会变得十分困难,总之是想办法去抽成。为了应对这种流氓政策,各小 app 公司纷纷偷梁换柱,通过 h5 支付从而绕开 sdk 支付。
常规的什么申请秘钥,配置回调地址等操作全部忽略了,直接进入核心步骤
支付宝的 h5 支付,返回一个 http 链接,是可以直接在 webview 中使用的,url 会重定向最终指向到支付宝的专属协议上。这里建议直接在 app 上直接通过 new webview 方式实现。
通过微信 h5 支付也是可以生成支付链接的,如果我们直接使用这个 url 的话,一定会抛一个错误“商家参数格式有误,请联系商家解决”, 微信支付的错误解决方案 中已经给出了原因,微信在这里校验了 http 请求中的 referer ,我们直接打开 url 请求头中是没有 referer 字段的,最容易想到的是通过 html 中的 a 标签跳转页面,a 标签会默认携带当前页面的主机地址。
所以就写了一个简单的中转页面,逻辑很简单,在中转链接中添加一个 pay_url 字段,pay_url 就是微信 h5 支付生成的链接,需要进行 encode 编码一下,我们可以在 js 里面重新解码,设置 a 标签的 href 熟悉,执行点击进行跳转。
找个服务器或者 oss 将页面放过去,配置一个域名,因为微信的 h5 支付是绑定了一个主域名,二级域名其实都是可以使用,假如最终配置为 pay.abc.com ,那么我们最终的跳转链接为 http://pay.abc.com?pay_url=http://wechatpay.com?xxxxxx 。
不管是微信支付还是支付宝支付,其实想从浏览器唤醒支付 app,都是通过特有 schema 唤醒的,支付宝的协议是 alipay://,微信的协议是 weixin://,其实和 http 协议一样,例如: http://.com ,浏览器会捕获 http 协议,支付宝和微信都会捕获属于自己的协议,这一点不管在 android 还是 ios 上,也正是利用了这一点,才使我们 app 中唤醒支付宝或者微信成为可能。当然后面很可能也被限制,在将来相当长的一段时间是不会的,正是这些协议使得 h5 和 app 进行交互才使得如今移动操作系统更加繁荣。
⑤ 如何开发android sdk
在APICloud上看到android sdk开发指南,它们平台上叫功能模块,摘要一些下来看你有没有参考价值:
1.开发环境:
PC:Windows XP/Win7/8/Mac OS;
Eclipse3.7及以上;
ADT21及以上;
Android SDK 21(5.0)及以上;
JDK1.6或者1.7。尽量不要使用1.8,存在各种潜在问题;
其中Android环境推荐使用Google整合版的Eclipse:SDK ADT Bundle;
2.开发帮助参考
Android在线API文档:
Javascript规范及入门:
JSON数据在线Viewer:
3. 框架设计
APICloud引擎以实现对操作系统底层能力的封装和扩展,通过系统Webkit浏览器引擎开放API给Javascript调用的形式,实现了HTML+CSS+Javascript开发语言和Object-C/Java/C/C++等Native开发语言之间的桥接,极大的丰富和增强了标准Javascript的能力。令前端开发者通过JS即可调用移动设备的底层功能,如:电话、短信、定位、多媒体、跨域http请求等,并能将如网络地图、支付宝等第三方厂商的SDK很容易的集成至App中来。
本SDK开放桥接机制,方便具有一定Android基础的开发者自由开发定义Native扩展模块,丰富JS的能力,提升App的用户体验。APICloud引擎框架桥接层设计如图(2):
4. 开发设计Native模块
新建用于绑定映射至JS对象的类。在项目中新建Java类(以下以UZMoleDemo类为例,映射的JS对象为moleDemo),继承自引擎Jar包中的APIMole或者UZMole类,并重写相关函数。如下图:
定义并声明将被映射至JS类的Java函数。 若想将Java类中的某个函数映射至JS对象供JS调用,需要将该函数声明以“jsmethod_”开头,并且声明该函数为public,同时接收且仅能接受一个参数:UZMoleContext。
函数声明格式:public void jsmethod_showAlert(final UZMoleContextmoleContext){}