移动支付--银联,支付宝,微信(android)
来源:互联网 发布:智联招聘java 编辑:程序博客网 时间:2024/06/05 10:29
银联支付
简介
银联手机支付控件(以下简称支付控件),主要为合作商户的手机客户端提供安全、便捷的支付服务。用户通过在支付控件中输入银行卡卡号、手机号、密码(借记卡和预付卡)或者CVN2(信用卡背面的数字)、有效期(信用卡)、验证码等要素完成支付。
支付流程介绍
其实银联,支付宝,微信的支付流程都差不多,这里先说银联的支付流程。流程图说明:
(1)用户在客户端中点击购买商品,客户端发起订单生成请求到商户后台;
(2)商户后台收到订单生成请求后,按照《手机控件支付产品接口规范》组织并推送订单信息至银联后台;
(3)银联后台接收订单信息并检查通过后,生成对应交易流水号(即TN),并回复交易流水号至商户后台(应答要素:交易流水号等);
(4)商户后台接收到交易流水号,将交易流水号返回给客户端;
(5)客户端通过交易流水号(TN)调用支付控件;
(6)用户在支付控件中输入相关支付信息后,由支付控件向银联后台发起支付请求;
(7)支付成功后,银联后台将支付结果通知给商户后台;
(8)银联将支付结果通知支付控件;
(9)支付控件显示支付结果并将支付结果返回给客户端;
在客户端的操作是(1)首先将商品的id传递给后台服务器,步骤(2)-(4)是服务器端完成的,所有客户端不需要做其他操作。在本篇文章中直接产生一个模拟的流水号(TN),直接调用支付控件,完成步骤(5)-(9)的操作。下面的代码就是一个简单的使用银联支付的demo
- package com.example.unionpay;
- import java.io.ByteArrayOutputStream;
- import java.io.InputStream;
- import java.net.URL;
- import java.net.URLConnection;
- import org.json.JSONException;
- import org.json.JSONObject;
- import com.unionpay.UPPayAssistEx;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.app.ProgressDialog;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Handler.Callback;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class MainActivity extends Activity implements Callback,Runnable{
- /**
- * mMode参数解释: "00" - 启动银联正式环境 "01" - 连接银联测试环境
- */
- private final String mMode = "01";
- //银联官方测试环境提供的访问接口 可供测试使用,在实际开发当中可以替换成自己的服务端的接口地址 用于生产流水号(TN)
- private static final String TN_URL_01 = "http://101.231.204.84:8091/sim/getacptn";
- private Button btn;
- private Context mContext = null;
- private Handler mHandler = null;
- private ProgressDialog mLoadingDialog = null;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- mContext = this;
- mHandler = new Handler(this);
- btn = (Button) findViewById(R.id.submit);
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- //这里做具体的提交数据 访问网络的操作
- mLoadingDialog = ProgressDialog.show(mContext,"", "正在努力的获取tn中,请稍候...",true); // 进度是否是不确定的,这只和创建进度条有关
- // 步骤1:从网络开始,获取交易流水号即TN
- new Thread(MainActivity.this).start();
- }
- });
- }
- @Override
- public void run() {
- //这里主要做的是模拟将从商品ID传递给服务端 让服务端生产订单 最后银联后台生成支付的流水号
- //此处直接返回流水号
- String tn = null;
- InputStream is;
- try {
- String url = TN_URL_01;
- URL myURL = new URL(url);
- URLConnection ucon = myURL.openConnection();
- ucon.setConnectTimeout(120000);
- is = ucon.getInputStream();
- int i = -1;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- while ((i = is.read()) != -1) {
- baos.write(i);
- }
- tn = baos.toString();
- is.close();
- baos.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- Message msg = mHandler.obtainMessage();
- msg.obj = tn;
- mHandler.sendMessage(msg);
- }
- @Override
- public boolean handleMessage(Message msg) {
- //callback的回调函数
- if (mLoadingDialog.isShowing()) {
- mLoadingDialog.dismiss();
- }
- String tn = "";
- if (msg.obj == null || ((String) msg.obj).length() == 0) {
- AlertDialog.Builder builder = new AlertDialog.Builder(this);
- builder.setTitle("错误提示");
- builder.setMessage("网络连接失败,请重试!");
- builder.setNegativeButton("确定",
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- builder.create().show();
- } else {
- tn = (String) msg.obj;
- //步骤2:通过银联工具类启动支付插件
- doStartUnionPayPlugin(this, tn, mMode);
- }
- return false;
- }
- public void doStartUnionPayPlugin(Activity activity, String tn, String mode) {
- UPPayAssistEx.startPay(activity, null, null, tn, mode);
- }
- @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")) {
- // 支付成功后,extra中如果存在result_data,取出校验
- // result_data结构见c)result_data参数说明
- if (data.hasExtra("result_data")) {
- String result = data.getExtras().getString("result_data");
- try {
- JSONObject resultJson = new JSONObject(result);
- String sign = resultJson.getString("sign");
- String dataOrg = resultJson.getString("data");
- // 验签证书同后台验签证书
- // 此处的verify,商户需送去商户后台做验签
- boolean ret = verify(dataOrg, sign, mMode);
- if (ret) {
- // 验证通过后,显示支付结果
- msg = "支付成功!";
- } else {
- // 验证不通过后的处理
- // 建议通过商户后台查询支付结果
- msg = "支付失败!";
- }
- } catch (JSONException e) {
- }
- } else {
- // 未收到签名信息
- // 建议通过商户后台查询支付结果
- msg = "支付成功!";
- }
- } else if (str.equalsIgnoreCase("fail")) {
- msg = "支付失败!";
- } else if (str.equalsIgnoreCase("cancel")) {
- msg = "用户取消了支付";
- }
- 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();
- }
- private boolean verify(String msg, String sign64, String mode) {
- // 此处的verify,商户需送去商户后台做验签
- return true;
- }
- }
1.在xml文件中添加所需要的权限,这里直接复制粘贴就ok
- <uses-permission android:name="android.permission.INTERNET" />
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
- <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="org.simalliance.openmobileapi.SMARTCARD" />
- <uses-permission android:name="android.permission.NFC" />
- <uses-feature android:name="android.hardware.nfc.hce"/>
- <uses-library android:name="org.simalliance.openmobileapi" android:required="false"/>
- <activity
- android:name="com.unionpay.uppay.PayActivity"
- android:configChanges="orientation|keyboardHidden|keyboard"
- android:screenOrientation="portrait"
- android:excludeFromRecents="true"
- id:windowSoftInputMode="adjustResize">
- </activity>
- <activity
- android:name="com.unionpay.UPPayWapActivity"
- android:configChanges="orientation|keyboardHidden|fontScale"
- android:screenOrientation="portrait"
- android:windowSoftInputMode="adjustResize" >
- </activity>
(1). 打开https://open.unionpay.com/
(2). 下载规范和开发包。帮助中心-下载-产品接口规范-手机控件支付产品接口规范,帮助中心-下载-产品接口规范-手机控件支付产品技术开发包(安卓版的)。
5.开发我们自己的activity,处理客户端应该处理的逻辑,例如上面的mainActivity。
支付宝支付
蚂蚁金服也的确很牛逼哈。支付宝支付的接入应该是在这三种支付接入方式中最简单的一种吧。有详细的文档和demo。文档,sdk,demo下载地址。就支付宝,微信支付而言我们都需要注册成为商家才能进行支付宝,微信支付方式的接入。一般的普通用户是没有这种功能的,估计是微信或者支付宝要对这一部分人收取额外的费用 吧,所以要走这样一个流程。支付宝商家支付中心的申请也需要一堆审核。呵呵 ,如果你真的想去试试可以按照官网上的步骤一步一步走下去,下面所写的例子中,我用的是一个实际当中的商户ID,所有会真实的支付0.01元。还是按照我们习惯的一般步骤来看:- <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" />
- <uses-permission android:name="android.permission.READ_PHONE_STATE" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
- <!-- alipay sdk begin -->
- <activity
- android:name="com.alipay.sdk.app.H5PayActivity"
- android:configChanges="orientation|keyboardHidden|navigation"
- android:exported="false"
- android:screenOrientation="behind"
- android:windowSoftInputMode="adjustResize|stateHidden" >
- </activity>
- <!-- alipay sdk end -->
- import java.io.UnsupportedEncodingException;
- import java.net.URLEncoder;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import java.util.Random;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.text.TextUtils;
- import android.view.View;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.alipay.sdk.app.PayTask;
- import com.tz.aplipay.utils.Constants;
- import com.tz.aplipay.utils.PayResult;
- import com.tz.aplipay.utils.SignUtils;
- public class PayActivity extends Activity {
- //商户ID
- public static final String PARTNER = Constants.PARTNER;
- //商户收款账号
- public static final String SELLER = Constants.SELLER;
- //商户私钥
- //私钥用于对数据进行签名加密
- //公钥用于对签名进行验证
- public static final String RSA_PRIVATE = Constants.RSA_PRIVATE;
- private String name;
- private String price;
- private String desc;
- private final static int MESSAGE_PAY = 1;
- private Handler handler = new Handler(){
- public void handleMessage(android.os.Message msg) {
- switch (msg.what) {
- case MESSAGE_PAY:
- String result = (String) msg.obj;
- PayResult payResult = new PayResult(result);
- //支付状态码
- String resultStatus = payResult.getResultStatus();
- if (TextUtils.equals(resultStatus, "9000")) {
- Toast.makeText(PayActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
- }else if (TextUtils.equals(resultStatus, "8000")) {
- Toast.makeText(PayActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show();
- }else{
- Toast.makeText(PayActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
- }
- break;
- default:
- break;
- }
- }
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.pay);
- //获取商品的详细信息
- Intent intent = getIntent();
- name = intent.getStringExtra("name");
- price = intent.getStringExtra("price");
- desc = intent.getStringExtra("desc");
- TextView product_name = (TextView) findViewById(R.id.product_name);
- TextView product_price = (TextView) findViewById(R.id.product_price);
- TextView product_desc = (TextView) findViewById(R.id.product_desc);
- product_name.setText(name);
- product_price.setText(price);
- product_desc.setText(desc);
- }
- //支付
- public void pay(View btn){
- //1.构建订单数据
- String orderInfo = getOrderInfo(name, desc, price);
- //2.对订单进行签名
- String sign = sign(orderInfo);
- try {
- //转码
- sign = URLEncoder.encode(sign, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- //3.构建一个符合支付宝参数规范的订单数据
- final String payInfo = orderInfo + "&sign=\""+sign +"\"&sign_type=\"RSA\"" ;
- //4.调用支付接口
- new Thread(){
- public void run() {
- //支付任务
- PayTask task = new PayTask(PayActivity.this);
- String result = task.pay(payInfo);
- //按照支付宝的规则进行支付结果的解析
- Message msg = handler.obtainMessage(MESSAGE_PAY);
- msg.obj = result;
- handler.sendMessage(msg);
- }
- }.start();
- //5.处理支付结果
- }
- /**
- * 对订单进行签名
- * @param orderInfo
- * @return
- */
- private String sign(String orderInfo) {
- return SignUtils.sign(orderInfo, RSA_PRIVATE);
- }
- /**
- * 构建订单信息
- * @param subject 商品名称
- * @param body 商品详情
- * @param price 商品金额
- * @return
- */
- public String getOrderInfo(String subject, String body, String price) {
- // 签约合作者身份ID
- String orderInfo = "partner=" + "\"" + PARTNER + "\"";
- // 签约卖家支付宝账号
- orderInfo += "&seller_id=" + "\"" + SELLER + "\"";
- // 商户网站唯一订单号
- orderInfo += "&out_trade_no=" + "\"" + getOutTradeNo() + "\"";
- // 商品名称
- orderInfo += "&subject=" + "\"" + subject + "\"";
- // 商品详情
- orderInfo += "&body=" + "\"" + body + "\"";
- // 商品金额
- orderInfo += "&total_fee=" + "\"" + price + "\"";
- // 服务器异步通知页面路径
- orderInfo += "¬ify_url=" + "\"" + "http://notify.msp.hk/notify.htm"
- + "\"";
- // 服务接口名称, 固定值
- 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\"";
- return orderInfo;
- }
- /**
- * 产生一个包含时间的随机的订单号
- * @return
- */
- private String getOutTradeNo() {
- SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
- Date date = new Date();
- String key = sdf.format(date);
- Random random = new Random();
- key = key + random.nextInt();
- key = key.substring(0, 15);
- return key;
- }
- }
- public class Constants {
- public static final String PARTNER = "2088111984427922";
- public static final String SELLER = "zf@159cai.com";
- public static final String RSA_PRIVATE = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBANcUPyx/lkokBOM1UfnFF1UckLs2Z2nh7RPMyhiMrats6LqsEhkCi4CiWS4ha6GuZcDtKzK2bfzd61IS1l6Ae4Qt+VZcdSpG+5vu875awBgiBCnbCP6YBm81vcAdSJYlOpizgS4JCuIalUqqaWN3hSP4tThuQcRAeHFwDi/ImJyDAgMBAAECgYBo2MnjG19cTSrEyB1qMRYqu34ihWbsSuKToGV0ij+vLaxWM8OuxXrT/lCTGF+rtaSM5BEG67+6YURyAhTWhLOw2mcEakFfVY0uTGadtsFODwHPkmDzL/kIhi99rB2gg0ota+FNVfd2oAmc//UvgHAeMA2bW+kxt9Y73XQE8yjbgQJBAP4kEemsgUtMo4y9lP8lkmwfK7pAWBiT2zajM6m///kfPG3NLJdJ4E4R026RBcZmL9WVxs2isX4o6TgLXtAmHpMCQQDYpwaT4RpkXIiSw124TlwrJF786c/OOtXm30kUuqWdMnbb6NFXDFMeeAPNN0bLLquR5X+XCIsroltpmLRi+VBRAkAuJGhoL9ztygVr2UQDK1Qxc1tiHqqgE8BaZDlOGcEk/ynemcD92vjx08S6r3QH+Ke4tM/6qA5n5I+rkEzvp+wnAkB2tG1CMSAIxTp/T1PWW/jcGn2BDYqycEIq0UR1ex6q1q+RJistCq+wDgnnMtYzFUskER6rXh8CtV5oqSaM5BVBAkBUqxfm8ro7eNagEnnWZidMrUIwesp1TQsQjtLFZTC9mVnpgLMj0IIaggojEBTQR6SvW7Sm7MqgqzYNUxlP0eoG";
- public static final String RSA_PUBLIC = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnxj/9qwVfgoUh/y2W89L6BkRAFljhNhgPdyPuBV64bfQNN1PjbCzkIM6qRdKBoLPXmKKMiFYnkd6rAoprih3/PrQEB/VsW8OoM8fxn67UDYuyBTqA23MML9q1+ilIZwBC2AQ2UBVOrFXfFl75p6/B5KsiNG9zpgmLCUYuLkxpLQIDAQAB";
- }
微信支付
- 移动支付--银联,支付宝,微信(android)
- 移动支付--银联,支付宝,微信(android)
- Android 支付宝 微信 银联 支付
- android中移动支付 微信支付和支付宝支付的学习
- 【Android实战】移动支付(微信、支付宝、银联)集成
- Android支付宝、微信支付阐述
- android集成支付,支付宝,微信
- Android 支付宝,微信支付实现
- android 微信、支付宝支付总结
- Android 接入微信支付宝支付
- Android 接入微信支付宝支付
- Android 接入微信支付宝支付
- Android 接入微信支付宝支付
- Android 接入微信支付宝支付
- Android 接入微信支付宝支付
- Android 接入微信支付宝支付
- android微信和支付宝支付
- Android 支付宝和微信支付
- Vuex 模块化与项目实例 (2.0)
- android 播放器支持302跳转
- java 反射机制
- 理解指针
- 探讨:测试中所谓的并发指的是同一时间点还是···
- 移动支付--银联,支付宝,微信(android)
- css
- 如何在C++中调用C程序?
- 一个模拟手机手指滑动事件的jquery插件
- vc检测usb设备的拔插状态
- Liferay DXP 中 OSGi注解(Annotation)
- honeymap FATAL can't find command '/opt/honeymap/server/server'
- xfire client Retrying request
- jetty对于包的加载顺序的处理