Android中集成第三方支付
常见的第三方支付解决方案
- 支付宝支付
- 微信支付
- 银联支付
- Ping++统一支付平台(需要继承服务器端和客户端)
- 短信支付
支付宝的集成流程
- 相关资料链接:
- 支付宝支付指引流程:支付指引流程
- 支付宝Android端集成流程:Android端集成流程
- 首先,支付宝支付准备工作
- 首先登录【支付宝开放平台】http://open.alipay.com/platform/home.htm,创建应用,并给应用添加App支付功能
- 由于App支付功能需要签约,因此需要上传公司信息和证件等资料进行签约
- 签约成功后,需要配置秘钥。使用支付宝提供的工具生成RSA公钥和私钥(工具下载地址),公钥需要设置到管理后台,具体操作请登录官网
-
第二步,拼接符合支付宝规范的请求参数,主要有以下几点:
-
先拼接订单信息,如下:
Map<string, string=""> params = OrderInfoUtil2_0.buildOrderParamMap(APPID, rsa2); String orderParam = OrderInfoUtil2_0.buildOrderParam(params);
-
然后并对订单信息使用私钥进行RSA加密,并拼接订单信息:
String sign = OrderInfoUtil2_0.getSign(params, privateKey, rsa2); final String orderInfo = orderParam + "&" + sign;
- 但是,上面的2个步骤,由于涉及到私钥加密,如果写在本地容易暴露私钥,所以一般会让服务器提供一个提交确认订单的接口,客户端将订单相关参数传递给服务器,服务器负责拼接支付宝的请求参数,然后返回给客户端,所以上面的步骤其实不用我们来做。
-
-
第三步,调用支付api,传入请求参数进行支付请求:
// 构造PayTask 对象 PayTask alipay = new PayTask(PayDemoActivity.this); Map<string, string=""> result = alipay.payV2(orderInfo, true);
-
最后,接收支付结果,根据支付状态进行UI提示:
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, "支付结果确认中", Toast.LENGTH_SHORT).show(); } else { // 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误 Toast.makeText(PayDemoActivity.this, "支付失败", Toast.LENGTH_SHORT).show(); } }
微信支付的集成流程
整体步骤可以说,和支付宝一致的
-
首先,获取符合微信支付规范的请求参数,demo中是通过一个url获取的,这告诉我们,应该让服务器提供一个接口,来对订单信息进行加密然后返回。代码如下:
String url = "http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=android"; byte[] buf = Util.httpGet(url);
-
第二步,对请求参数进行封装:
PayReq req = new PayReq(); //req.appId = "wxf8b4f85f3a794e77"; // 测试用appId req.appId = json.getString("appid"); req.partnerId = json.getString("partnerid"); req.prepayId = json.getString("prepayid"); req.nonceStr = json.getString("noncestr"); req.timeStamp = json.getString("timestamp"); req.packageValue = json.getString("package"); req.sign = json.getString("sign"); req.extData = "app data"; // optional
-
第三步,调用支付api,传入请求参数:
// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信 api.sendReq(req);
-
最后,接收支付结果,根据状态码进行UI提示,此处在demo中是在WXPayEntryActivity中进行操作的。
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{ private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity"; private IWXAPI api; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.pay_result); api = WXAPIFactory.createWXAPI(this, Constants.APP_ID); api.handleIntent(getIntent(), this); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); api.handleIntent(intent, this); } @Override public void onReq(BaseReq req) { } @Override public void onResp(BaseResp resp) { 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(); } } }
银联支付的集成流程
银联支付最简单,只要有TN(交易流水号)即可发起支付!
-
首先,当要进行支付时,调用自己服务器提供的接口获取流水号,即TN,代码类似这样:
String tn = HttpHelper.execGet("tn_url");
-
然后,拿到TN后,调用银联SDK的api向银联发起支付请求,代码类似这样:
//其中mode参数解释: "00" - 启动银联正式环境 "01" - 连接银联测试环境 UPPayAssistEx.startPay(activity, null, null, tn, mode);
-
最后,在onActivityResult方法中获取支付结果进行UI提示,代码类似这样:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { /************************************************* * 步骤3:处理银联手机支付控件返回的支付结果 ************************************************/ if (data == null) { return; } String msg = ""; /* * 支付控件返回字符串:success、fail、cancel 分别代表支付成功,支付失败,支付取消 */ String str = data.getExtras().getString("pay_result"); if (str.equalsIgnoreCase("success")) { // 如果想对结果数据验签,可使用下面这段代码,但建议不验签,直接去商户后台查询交易结果 // result_data结构见c)result_data参数说明 if (data.hasExtra("result_data")) { // 结果result_data为成功时,去商户后台查询一下再展示成功 //注意,此处只是表示客户端收到了支付成功的响应。但是为了保险起见,需要向服务器查询一下是否真的支付功。 //具体做法是,让自己服务器提交一个查询订单状态的接口,如果服务器返回的结果也是支付成功,那么就真的提示用户 } msg = "支付成功!"; } else if (str.equalsIgnoreCase("fail")) { msg = "支付失败!"; } else if (str.equalsIgnoreCase("cancel")) { msg = "用户取消了支付"; } //进行UI提示 AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setTitle("支付结果通知"); builder.setMessage(msg); builder.setInverseBackgroundForced(true); // builder.setCustomTitle(); builder.setNegativeButton("确定", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); builder.create().show(); }