Android常用第三方支付
Posted threenerd
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android常用第三方支付相关的知识,希望对你有一定的参考价值。
移动支付
用户使用移动的终端完成对所购买商品或者服务的支付功能;分为近场支付(蓝牙支付,刷卡,滴卡),和远程支付(网上支付,短信支付)
app支付模块
常见的支付厂商-->常见的支付方式
- 支付宝:阿里公司
- 微信:腾讯公司
- 银联:联合起来的结构
- 财付通:腾讯公司
- 支付宝钱包:阿里公司
- 百度钱包:百度公司
支付安全吗?
都是比较安全.都是大公司的产品.而且这个和金钱之前挂钩;
支付难不难?
支付不难.因为是第三方平台的东西.
支付集成大概需要多长时间?(如果之前做过)
- 支付宝:5-10分钟
- 银联:5-10分钟
- 微信:10-20分钟
支付流程_从生活出发
- 1. 选择商品-->goodName,goodId,price,count
- 2. 选择支付方式-->payType:1,支付宝;2,银联;3:微信
- 3. 处理支付结果-->支付成功(购物流程),支付失败(重试,放弃)
支付流程_从程序角度出发
- 选择商品,组装支付数据-->拼接请求的jsonString
- 把支付数据post到后台server-->发送一个请求request
- 后台server(支付宝的服务)生成支付串码--->处理第二步的reponse
-
在客户端使用第三方平台的api调用插件完成支付-->调用第三方平台jar包里面的方法(集成过程),这一步才用到支付宝sdk
- 处理支付结果-->利用没有平台特有的通知机制处理支付结果
支付串码是啥?
支付方法需要的支付参数
支付流程_简明说法
- 发起支付请求
- 拿到支付串码
- 调用api支付
- 处理支付结果
- 同步返回:支付后通知我们自己的apk
- 异步通知:支付后通知我们的server
支付宝
- demo运行问题:需要ALIPAYPartnerID,ALIPAYSellerID,ALIPAYMD5KEY,ALIPAYPartnerPrivKey,ALIPAYPubKey才可以运行.但是如果直接下载的demo.这些字段都是"",无法看到效果,这些数据的获得.是用公司运行去做;
- 支付宝demo的流程和实际开发不一致.实际开发.生成支付串码的过程应该交给服务器.因为sign需要支付宝的privatekey,如果放到apk里面是会泄露privatekey的,所以最后简化之后的支付宝集成就几行代码;
- RSA:RSA是一种公钥加密算法。能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。主要用于公钥加密私钥解密、私钥签名公钥验签。
- 支付宝公钥:开发者请求支付宝并获得返回时,开发者用于验签使用的公钥
- 我们自己要和支付宝签约(商户签约).-->运营
- 秘钥配置-->协助运营完成秘钥的配置(公钥互换),可能程序员会参与
- 集成支付宝-->必须是程序员去做.
MainActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
public
class
MainActivity
extends
Activity
private
Button btn_zfb;
/**
* 支付宝通过hanlder机制发送支付结果出来,这个过程我们理解为"同步返回".因为只要支付宝支付成功.客户端就可以通过handler收到消息
*/
private
Handler handler =
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;
*/
;
;
@Override
protected
void
onCreate(Bundle savedInstanceState)
super
.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initListener();
private
void
initView()
btn_zfb = (Button) findViewById(R.id.btn1);
private
void
initListener()
/**
* 支付宝支付
*/
btn_zfb.setOnClickListener(
new
OnClickListener()
@Override
public
void
onClick(View v)
//1. 选择商品,把**支付数据**post到后台server-->发送一个请求
final
String goodInfoJsonString =
"\\"goodInfos\\":[\\"goodCounts\\":\\"1\\",\\"goodExtInfo\\":,\\"goodIDs\\":\\"965\\",\\"goodType\\":\\"1\\"],\\"loginFlag\\":\\"0\\",\\"mobile\\":\\"18682036558\\",\\"orderId\\":\\"0\\",\\"otherInfo\\":\\"agentID\\":\\"0-maizuo\\",\\"channelID\\":\\"31\\",\\"clientID\\":\\"31\\",\\"payDatas\\":\\"discountInfo\\":\\"activeID\\":\\"0\\",\\"discountID\\":\\"0\\",\\"discountPrice\\":\\"\\",\\"payInfo\\":[\\"bankType\\":\\"7\\",\\"payCount\\":\\"3800\\",\\"payTicketCount\\":\\"1\\",\\"payType\\":\\"1\\"],\\"payPass\\":\\"\\",\\"returnUrl\\":\\"\\",\\"totalPrice\\":\\"3800\\",\\"processPath\\":\\"1\\",\\"sessionKey\\":\\"chfrlczgtomqsiurzzyo\\",\\"userID\\":\\"200394160\\""
;
//2.把支付数据post到后台server-->发送一个请求
new
Thread(
new
Runnable()
@Override
public
void
run()
// TODO
try
DefaultHttpClient httpClient =
new
DefaultHttpClient();
HttpPost post =
new
HttpPost(
"http://mobileif.maizuo.com/version3/orderform/order?version=2"
);
post.addHeader(
"Content-Type"
,
"application/json"
);
post.setEntity(
new
StringEntity(goodInfoJsonString));
HttpResponse response = httpClient.execute(post);
if
(response.getStatusLine().getStatusCode() ==
200
)
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity);
System.out.println(result);
//-->bean-->getAlipayVerifyKey();
//3.在客户端使用第三方平台的api调用插件完成支付
//获取Alipay对象,构造参数为当前Activity和Handler实例对象
//mHandler就是一会处理我们支付结果的hanlder
AliPay alipay =
new
AliPay(MainActivity.
this
, handler);
//调用pay方法,将订单信息传入
String orderInfo =
"_input_charset=\\"UTF-8\\"&body=\\"卖座网电子影票\\"&it_b_pay=\\"1h\\"¬ify_url=\\"http%3A%2F%2Fpay.maizuo.com%2FmobileBack.htm\\"&out_trade_no=\\"201503283783092428\\"&partner=\\"2088411628331920\\"&payment_type=\\"1\\"&seller_id=\\"2088411628331920\\"&service=\\"mobile.securitypay.pay\\"&subject=\\"海岸影城(2D通兑票1张)\\"&total_fee=\\"38.00\\"&sign=\\"KDhXG0I8T1VZCgg3tfmYbnhF91I6marCQ0yWgmIe1ZGJ9z6MHFwwV7O156%2FkTecKikrIwRnrPNOI%0Ac8h6bUPRX9DIoHF3Yamj1NCi%2B5j0e16uRy5VtyhLFPx608stqjLlaepBsRZYPblyikuts67W9IJ%2B%0AyNrrG8cZ6ltgulZTFH4%3D\\"&sign_type=\\"RSA\\""
;
//支付串码
String payResult = alipay.pay(orderInfo);
catch
(Exception e)
e.printStackTrace();
).start();
);
// “00” – 银联正式环境
// “01” – 银联测试环境,该环境中不发生真实交易
String serverMode =
"00"
;
/**
* 银联支付
*/
public
void
uupay(View v)
//通过支付请求.拿到支付串码
String tn =
"201503281059506568548"
;
//发起支付请求
int
ret = UPPayAssistEx.startPay(MainActivity.
this
,
null
,
null
, tn, serverMode);
if
(ret == UPPayAssistEx.PLUGIN_NOT_FOUND)
//安装Asset中提供的UPPayPlugin.apk
// 此处可根据实际情况,添加相应的处理逻辑
UPPayAssistEx.installUPPayPlugin(
this
);
/**
* uupay处理支付结果
*/
protected
void
onActivityResult(
int
requestCode,
int
resultCode, Intent data)
if
(data ==
null
)
return
;
String str = data.getExtras().getString(
"pay_result"
);
String msg =
""
;
/*
* 支付控件返回字符串:success、fail、cancel 分别代表支付成功,支付失败,支付取消
*/
if
(str.equalsIgnoreCase(
"success"
))
msg =
"支付成功!"
;
else
if
(str.equalsIgnoreCase(
"fail"
))
msg =
"支付失败!"
;
else
if
(str.equalsIgnoreCase(
"cancel"
))
msg =
"用户取消了支付"
;
//下面就是进行用户提示
Toast.makeText(getApplicationContext(), msg,
0
).show();
|
RSA密钥生成命令
生成RSA私钥 openssl>genrsa -out rsa_private_key.pem 1024 生成RSA公钥 openssl>rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem 将RSA私钥转换成PKCS8格式 openssl>pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt 注意:“>”符号后面的才是需要输入的命令。 E:\\支付\\支付宝\\支付宝钱包支付接口开发包2.0标准版(20160120)\\DEMO\\openssl\\bin\\1目录下有俩个文件 开发者将私钥保留,将公钥提交给支付宝网关,用于信息加密及解密。银联
- demo运行问题:只需要tnno就可以
- 银联提供了测试环境和正式环境,而且还有测试账号
-
关键方法:
//通过支付请求.拿到支付串码 String tn = "201503281059506568548"; //发起支付请求 int ret = UPPayAssistEx.startPay(MainActivity.this, null, null, tn, serverMode); if (ret == UPPayAssistEx.PLUGIN_NOT_FOUND) //安装Asset中提供的UPPayPlugin.apk // 此处可根据实际情况,添加相应的处理逻辑 UPPayAssistEx.installUPPayPlugin(this);
-
处理支付结果:在onactivityForResult中处理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
@Override
protected
void
onActivityResult(
int
requestCode,
int
resultCode, Intent data)
initData();
if
(data ==
null
)
return
;
String uupayResult = data.getExtras().getString(
"pay_result"
);
Logger.i(TAG,
"pay_result:"
+ uupayResult);
if
(uupayResult !=
null
&& !
""
.equals(uupayResult))
Logger.i(TAG,
"pay_result:"
+ uupayResult);
Message msg =
new
Message();
if
(uupayResult.equalsIgnoreCase(
"success"
))
msg.what = UUPAYSUCCESS;
else
if
(uupayResult.equalsIgnoreCase(
"fail"
))
msg.what = UUPAYFAIL;
/*else if (uupayResult.equalsIgnoreCase("cancel"))
msg = "用户取消了支付";
*/
handler.sendMessage(msg);
super
.onActivityResult(requestCode, resultCode, data);
|
微信
- 步骤
- 一、获取 access_token
- 二、生成预支付订单
- 三、调起微信支付
- 四、接收支付返回结果
-
关键方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 private
void
sendPayReq(WXPayData info)
api = WXAPIFactory.createWXAPI(
this
, info.getAppid());
PayReq req =
new
PayReq();
req.appId = info.getAppid();
req.partnerId = info.getPartnerid();
req.prepayId = info.getPrepayid();
//预支付id
req.nonceStr = info.getNoncestr();
//32位内的随机串,防重发
req.timeStamp = String.valueOf(info.getTimestamp());
//时间戳,为 1970 年 1 月 1 日 00:00 到请求发起时间的秒数
req.packageValue = info.getPackage1();
req.sign = info.getApp_signature();
// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
api.sendReq(req);
处理支付结果:在WXPayEntryActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
errCode = resp.errCode;
Logger.i(TAG,
"微信支付结果:"
+ String.valueOf(resp.errCode));
if
(resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX)
/*AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.app_tip);
builder.setMessage(getString(R.string.pay_result_callback_msg, String.valueOf(resp.errCode)));
builder.show();*/
Message msg =
new
Message();
if
(errCode ==
0
)
msg.what = PayActivity.WEIXINPAYSUCCESS;
else
msg.what = PayActivity.WEIXINPAYFAIL;
PayActivity.instance.handler.sendMessage(msg);
finish();
|
-
安全码:
数字签名+";"+包名; 输入“安全码”。安全码的组成规则为:Android签名证书的sha1值+“;”+packagename(即:数字签名+分号+包名),例如: BB:0D:AC:74:D3:21:E1:43:67:71:9B:62:91:AF:A1:66:6E:44:5D:75;com.baidumap.dem
- 作用:保证app唯一性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
public
class
PayDemoActivity
extends
FragmentActivity
// 商户PID
public
static
final
String PARTNER =
"2016012501118845"
;
// 商户收款账号
public
static
final
String SELLER =
"6225757524716173"
;
// 商户私钥,pkcs8格式
public
static
final
String RSA_PRIVATE =
"MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALTam792ATycFFDXWg6VEQofa3lT4qWkmcyXLnbSZVHV/brDdDNfeHMJWwvsvuJYNxEDZOYL/AA7/WuBLI+KklXhFUnu/NjQWmXzndiQI15Mfq+2TDh1Cf9H7ypUHah8RrcTwaM9H1/SWP7f2o2QOucB2Y/bI4Faq3ISwONXztTvAgMBAAECgYEAjK4cRwOhFKeIehX6XKuB9LDaJielfxoZ9PaI0y74V38w/q15X1jdVgaqBw2ismjSdO6B9xzNatU/XPe/VO0CxHFZ3/5Qhc/b724MsTxGyVC8TMI/oHMgAlVE3cR4/fwj0fhsYUYbSy9yCTqyinpdLZcNkUpMBJaeaM4jQJZvaSECQQDm7TrKPyJ1mgkKZADco+/HzcX1OnLvGtjFnSxD4LUShFfpYW5bWthy+869Jt9iIbOVDkvrfANMKhOuk0sEany/AkEAyH2SUFJUA1r+csi6WDf694npi6gtY0MhcNgGmoVr3g1daWf3cbx81VUE9y4ffqH91mdxWlVMVsCQetNYywdD0QJAAKQsA5/FQrpYyBSbBAHYip+BqzqsUwmqDHJxSwb2ucRwUg+ZNNu9uiQE4PWYrTcWvpU5lL/VaoK7Z0K1dJ+vFQJBAKV78F7X9XxniQqZYCYc3sufS+P4Rq5d5KZNyPWWFvjLs0SjifyZBbjYWibkLR7K+sgTzd4v9bjNbPPUqr+6GWECQAk6JYzWuS8D7ns/JEbI1fuUzm2U8/Q2R60dq7EFtbw+Po1dxZzUJ+V5JhW9exvhrr7lVII/0aB8nv/LUE+2XCo="
;
// 支付宝公钥
public
static
final
String RSA_PUBLIC =
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDDI6d306Q8fIfCOaTXyiUeJHkrIvYISRcc73s3vF1ZT7XN8RNPwJxo8pWaJMmvyTn9N4HQ632qJBVHf8sxHi/fEsraprwCtzvzQETrNRwVxLO5jVmRGi60j8Ue1efIlzPXV9je9mkjzOmdssymZkh2QhUrCmZYI/FCEa3/cNMW0QIDAQAB"
;
private
static
final
int
SDK_PAY_FLAG =
1
;
private
static
final
int
SDK_CHECK_FLAG =
2
;
private
Handler mHandler =
new
Handler()
public
void
handleMessage(Message msg)
switch
(msg.what)
case
SDK_PAY_FLAG:
PayResult payResult =
new
PayResult((String) msg.obj);
/**
* 同步返回的结果必须放置到服务端进行验证(验证的规则请看https://doc.open.alipay.com/doc2/
* detail.htm?spm=0.0.0.0.xdvAU6&treeId=59&articleId=103665&
* docType=1) 建议商户依赖异步通知
*/
String resultInfo = payResult.getResult();
// 同步返回需要验证的信息
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档
if
(TextUtils.equals(resultStatus,
"9000"
))
Toast.makeText(PayDemoActivity.
this
,
"支付成功"
,
Toast.LENGTH_SHORT).show();
else
// 判断resultStatus 为非"9000"则代表可能支付失败
// "8000"代表支付结果因为支付渠道原因或者系统原因还在等待支付结果确认,最终交易是否成功以服务端异步通知为准(小概率状态)
if
(TextUtils.equals(resultStatus,
"8000"
))
Toast.makeText(PayDemoActivity.
this
,
"支付结果确认中"
IJPay 让支付触手可及,封装了微信支付QQ 支付支付宝支付京东支付银联支付PayPal 支付等常用的支付方式以及各种常用的接口。不依赖任何第三方 mvc 框架,仅仅作为工具使用简单快速完 |