由于android设备一般用的都是无线支付,所有我们申请的就是支付宝无线快捷支付接口。下面是申请的地址,下面还有下载接口开发包的地方
https://b.alipay.com/order/productDetail.htm?productId=2013080604609654
如果链接失效,你可以到支付宝官网商家服务模块中找到 快捷支付(无线)这个服务。
下载集成开发包,解压发现里面有客户端的demo即说明文档,在客户端的demo中找到Android_SDK,这个就是你要用到的支付宝接口及demo。
把demo(alipay_sdk_demo)和(alipay_lib)导入到你的eclipse里面,然后你可以试着运行一遍demo(alipay_sdk_demo),只要把这个demo搞懂了,你就会调用这个支付宝接口了。至于到时候如何集成到你的项目里面,文档上说明很详细,按着文档上一步一步来就行了。我的建议是先把这个demo弄懂再设计你的项目,看看调用接口时需要哪些数据,这样也有利于你一开始设计数据。
下面来简单的介绍下接口demo里面的结构。
你打开项目会发现里面有5个类。
其中,Base64.java、Result.java、Rsa.java这3个类不需要动,需要用到的,到时候直接放到你项目里面就行了,如果你想了解下它们你也可以看看。重点就是ExternalPartner.java和Keys.java这两个类。先来说说Keys.java类吧。打开你会发现这个类很简单,如下所示:
package com.alipay.android.msp.demo; // // 请参考 Android平台安全支付服务(msp)应用开发接口(4.2 RSA算法签名)部分,并使用压缩包中的openssl RSA密钥生成工具,生成一套RSA公私钥。 // 这里签名时,只需要使用生成的RSA私钥。 // Note: 为安全起见,使用RSA私钥进行签名的操作过程,应该尽量放到商家服务器端去进行。 public final class Keys { //合作身份者id,以2088开头的16位纯数字,这个你申请支付宝签约成功后就会看见 public static final String DEFAULT_PARTNER = ""; //这里填写收款支付宝账号,即你付款后到账的支付宝账号 public static final String DEFAULT_SELLER = ""; //商户私钥,自助生成,即rsa_private_key.pem中去掉首行,最后一行,空格和换行最后拼成一行的字符串,rsa_private_key.pem这个文件等你申请支付宝签约成功后,按照文档说明你会生成的.........................如果android版本太高,这里要用PKCS8格式用户私钥,不然调用不会成功的,那个格式你到时候会生成的,表急。 public static final String PRIVATE = ""; //支付宝(RSA)公钥 ,demo自带不用改,或者用签约支付宝账号登录ms.alipay.com后,在密钥管理页面获取;或者文档上也有。 public static final String PUBLIC = "MIGfMA0GCSqGSIb3..................."; }
然后是ExternalPartner.java这个类。这个类其实也很简单,你运行这个demo会发现就是一个listview里面加载的很多商品信息,点击一款商品就调用会支付宝接口(因为Key.java未配置,所以你现在估计调用不成功)。我们找到listview的点击事件的方法就找到调用支付宝的入口了,这个类的代码如下:
package com.alipay.android.msp.demo; import java.io.IOException; ........ ........ import com.alipay.android.app.sdk.AliPay; public class ExternalPartner extends Activity implements OnItemClickListener, OnClickListener { public static final String TAG = "alipay-sdk"; private static final int RQF_PAY = 1; private static final int RQF_LOGIN = 2; private EditText mUserId; private Button mLogon; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.external_partner); initProducts(); initListView(); } /* * (non-Javadoc) * * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) */ @Override public boolean onCreateOptionsMenu(Menu menu) { menu.add(Menu.NONE, Menu.FIRST, 1, "快速登录"); return true; } /* * (non-Javadoc) * * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case Menu.FIRST: setContentView(R.layout.trustlogin); mUserId = (EditText) findViewById(R.id.user_id); mLogon = (Button) findViewById(R.id.get_token); mLogon.setOnClickListener(this); break; } return false; } private void initProducts() { if (sProducts != null) return; XmlResourceParser parser = getResources().getXml(R.xml.products); ArrayList<Product> products = new ArrayList<Product>(); Product product = null; try { int eventType = parser.getEventType(); while (eventType != XmlPullParser.END_DOCUMENT) { if (eventType == XmlPullParser.START_TAG && parser.getName().equalsIgnoreCase("product")) { product = new Product(); product.subject = parser.getAttributeValue(0); product.body = parser.getAttributeValue(1); product.price = parser.getAttributeValue(2); products.add(product); } eventType = parser.next(); } sProducts = new Product[products.size()]; products.toArray(sProducts); } catch (XmlPullParserException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } //listview点击事件,里面调用的支付宝接口 @Override public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) { try { Log.i("ExternalPartner", "onItemClick"); String info = getNewOrderInfo(position);//这个是订单信息 String sign = Rsa.sign(info, Keys.PRIVATE);//签名加密订单信息什么的 sign = URLEncoder.encode(sign); info += "&sign=\"" + sign + "\"&" + getSignType(); Log.i("ExternalPartner", "start pay"); // start the pay. Log.i(TAG, "info = " + info); final String orderInfo = info; new Thread() { public void run() { AliPay alipay = new AliPay(ExternalPartner.this, mHandler);//这个应该就是支付宝接口了,哈哈,支付宝现在把很多功能都封装了,所以省了很多代码 //设置为沙箱模式,不设置默认为线上环境 //alipay.setSandBox(true); String result = alipay.pay(orderInfo);//这个是返回的结果,你到时候可以根据这个结果加以操作你想操作的,然后基本就完了,其他的你想附加的功能你看着写吧,现在Key.java配置好就能调用快捷支付了 //后面的这些代码可以改成你自己的,也可以在它们的基础上改 Log.i(TAG, "result = " + result); Message msg = new Message(); msg.what = RQF_PAY; msg.obj = result; mHandler.sendMessage(msg); } }.start(); } catch (Exception ex) { ex.printStackTrace(); Toast.makeText(ExternalPartner.this, R.string.remote_call_failed, Toast.LENGTH_SHORT).show(); } } //获得订单信息的方法 private String getNewOrderInfo(int position) { StringBuilder sb = new StringBuilder(); sb.append("partner=\""); sb.append(Keys.DEFAULT_PARTNER);// 合作身份者id sb.append("\"&out_trade_no=\""); sb.append(getOutTradeNo());//这个是订单编号 sb.append("\"&subject=\""); sb.append(sProducts[position].subject);//这个应该是商品名称 sb.append("\"&body=\""); sb.append(sProducts[position].body);//这个应该是商品的描述,具体你可以参考demo sb.append("\"&total_fee=\""); sb.append(sProducts[position].price.replace("一口价:", ""));//这个是要付款的金额,到时候你调用的时候改下就行了 sb.append("\"¬ify_url=\""); // 网址需要做URL编码 sb.append(URLEncoder.encode("http://notify.java.jpxx.org/index.jsp"));//服务器异步通知页面,完成交易后通知商家服务器的页面,以post的形式将商品订单信息发送到指定页面,手机客户端不需要可以先放在这不管 sb.append("\"&service=\"mobile.securitypay.pay"); sb.append("\"&_input_charset=\"UTF-8"); sb.append("\"&return_url=\""); sb.append(URLEncoder.encode("http://m.alipay.com")); sb.append("\"&payment_type=\"1"); sb.append("\"&seller_id=\""); sb.append(Keys.DEFAULT_SELLER); // 如果show_url值为空,可不传 // sb.append("\"&show_url=\""); sb.append("\"&it_b_pay=\"1m"); sb.append("\""); return new String(sb); } private String getOutTradeNo() { SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss"); Date date = new Date(); String key = format.format(date); java.util.Random r = new java.util.Random(); key += r.nextInt(); key = key.substring(0, 15); Log.d(TAG, "outTradeNo: " + key); return key; } private String getSignType() { return "sign_type=\"RSA\""; } private void initListView() { ListView lv = (ListView) findViewById(R.id.list_view); lv.setAdapter(new ExternalPartnerAdapter()); lv.setOnItemClickListener(this); } private void doLogin() { final String orderInfo = getUserInfo(); new Thread() { public void run() { String result = new AliPay(ExternalPartner.this, mHandler) .pay(orderInfo); Log.i(TAG, "result = " + result); Message msg = new Message(); msg.what = RQF_LOGIN; msg.obj = result; mHandler.sendMessage(msg); } }.start(); } private String getUserInfo() { String userId = mUserId.getText().toString(); return trustLogin(Keys.DEFAULT_PARTNER, userId); } private String trustLogin(String partnerId, String appUserId) { StringBuilder sb = new StringBuilder(); sb.append("app_name=\"mc\"&biz_type=\"trust_login\"&partner=\""); sb.append(partnerId); Log.d("TAG", "UserID = " + appUserId); if (!TextUtils.isEmpty(appUserId)) { appUserId = appUserId.replace("\"", ""); sb.append("\"&app_id=\""); sb.append(appUserId); } sb.append("\""); String info = sb.toString(); // 请求信息签名 String sign = Rsa.sign(info, Keys.PRIVATE); try { sign = URLEncoder.encode(sign, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } info += "&sign=\"" + sign + "\"&" + getSignType(); return info; } @Override public void onClick(View v) { if (v instanceof Button) { switch (v.getId()) { case R.id.get_token: doLogin(); break; } } } private class ExternalPartnerAdapter extends BaseAdapter { @Override public int getCount() { return sProducts.length; } @Override public Object getItem(int arg0) { return sProducts[arg0]; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { LayoutInflater factory = LayoutInflater .from(ExternalPartner.this); convertView = factory.inflate(R.layout.product_item, null); } Product product = (Product) getItem(position); TextView tv = (TextView) convertView.findViewById(R.id.subject); tv.setText(product.subject); tv = (TextView) convertView.findViewById(R.id.body); tv.setText(product.body); tv = (TextView) convertView.findViewById(R.id.price); tv.setText(product.price); return convertView; } } Handler mHandler = new Handler() { public void handleMessage(android.os.Message msg) { Result result = new Result((String) msg.obj); switch (msg.what) { case RQF_PAY: case RQF_LOGIN: { Toast.makeText(ExternalPartner.this, result.getResult(), Toast.LENGTH_SHORT).show(); } break; default: break; } }; }; public static class Product { public String subject; public String body; public String price; } public static Product[] sProducts; }是不是,这个类很简单看懂吧,就一listview。调用支付宝接口的方法就在onItemClick()方法里面,如果你是一个按钮的话换成按钮点击事件就行了,主要的细节我注释已写。
现在你要想的是,需要哪些数据,提供给onItemClick()方法里面的 String info。demo里面的数据是getNewOrderInfo(int position)这个方法提供的,你可以自己提供或者在上面修改下。
现在,你已经知道代码是如何调用支付宝接口了。接下来,是如何把这些集成到你的项目中去。
1,将alipay.jar这个包复制至商户应用工程的libs 目录下,通过 Java Build Path导入进工程,文档说明上有
2,将 alipay_lib 拷贝到 Eclipse workspace,通过 Eclipse import 该工程,并在此工程的 Properties->Android 中选中为 library 工程,文档上有图有真相
3,修改Manifest ,在商户应用工程的 AndroidManifest.xml 文件里面添加 Activity 声明:
c<activity android:name="com.alipay.android.app.sdk.WapPayActivity" android:screenOrientation="portrait"> </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" /> 至此,SDK 开发资源导入完成。4,proguard配置
4,向支付宝申请签约
进入我文章开头的那个地址,直接点申请就行了。
目的是为了或得PID与密钥,到时候你好按照文档配置你的Key.java文件。
申请要上传你的apk或者产品说明文档,我用的是产品说明文档,里面要包括产品说明(最好有产品截图,我第一次没截图直接没成功)、接口使用场景、资费说明。
申请成功后按文档上说明,做几个密钥什么的哈哈,上传你做的公钥。然后Key.java里面配置。这里要注意的是,String PRIVATE=“”;这里要用PKCS8格式的私钥。
配置成功即可测试啦!
好了,android集成支付宝接口我认为比较快的过程就是这些了,祝你配置成功!