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
- 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密钥生成命令
银联
- demo运行问题:只需要tnno就可以
- 银联提供了测试环境和正式环境,而且还有测试账号
关键方法:
- //通过支付请求.拿到支付串码
- String tn = "";
- //发起支付请求
- int ret = UPPayAssistEx.startPay(MainActivity.this, null, null, tn, serverMode);
- if (ret == UPPayAssistEx.PLUGIN_NOT_FOUND) {
- //安装Asset中提供的UPPayPlugin.apk
- // 此处可根据实际情况,添加相应的处理逻辑
- UPPayAssistEx.installUPPayPlugin(this);
- }
- //通过支付请求.拿到支付串码
处理支付结果:在onactivityForResult中处理
- @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
- 二、生成预支付订单
- 三、调起微信支付
- 四、接收支付返回结果
关键方法:
- 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
- private void sendPayReq(WXPayData info) {
- 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唯一性
- 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, "支付结果确认中",
- Toast.LENGTH_SHORT).show();
- } else {
- // 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误
- Toast.makeText(PayDemoActivity.this, "支付失败",
- Toast.LENGTH_SHORT).show();
- }
- }
- break;
- }
- case SDK_CHECK_FLAG: {
- Toast.makeText(PayDemoActivity.this, "检查结果为:" + msg.obj,
- Toast.LENGTH_SHORT).show();
- break;
- }
- default:
- break;
- }
- };
- };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.pay_main);
- }
- /**
- * call alipay sdk pay. 调用SDK支付
- *
- */
- public void pay(View v) {
- if (TextUtils.isEmpty(PARTNER) || TextUtils.isEmpty(RSA_PRIVATE)
- || TextUtils.isEmpty(SELLER)) {
- new AlertDialog.Builder(this)
- .setTitle("警告")
- .setMessage("需要配置PARTNER | RSA_PRIVATE| SELLER")
- .setPositiveButton("确定",
- new DialogInterface.OnClickListener() {
- public void onClick(
- DialogInterface dialoginterface, int i) {
- //
- finish();
- }
- }).show();
- return;
- }
- String orderInfo = getOrderInfo("测试的商品", "该测试商品的详细描述", "0.01");
- /**
- * 特别注意,这里的签名逻辑需要放在服务端,切勿将私钥泄露在代码中!
- */
- String sign = sign(orderInfo);
- try {
- /**
- * 仅需对sign 做URL编码
- */
- sign = URLEncoder.encode(sign, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- e.printStackTrace();
- }
- /**
- * 完整的符合支付宝参数规范的订单信息
- */
- final String payInfo = orderInfo + "&sign=\"" + sign + "\"&"
- + getSignType();
- System.out.println("payInfo===========" + payInfo);
- Runnable payRunnable = new Runnable() {
- @Override
- public void run() {
- // 构造PayTask 对象
- PayTask alipay = new PayTask(PayDemoActivity.this);
- // 调用支付接口,获取支付结果
- String result = alipay.pay(payInfo, true);
- Message msg = new Message();
- msg.what = SDK_PAY_FLAG;
- msg.obj = result;
- mHandler.sendMessage(msg);
- }
- };
- // 必须异步调用
- Thread payThread = new Thread(payRunnable);
- payThread.start();
- }
- /**
- * check whether the device has authentication alipay account.
- * 查询终端设备是否存在支付宝认证账户
- *
- */
- public void check(View v) {
- Runnable checkRunnable = new Runnable() {
- @Override
- public void run() {
- // 构造PayTask 对象
- PayTask payTask = new PayTask(PayDemoActivity.this);
- // 调用查询接口,获取查询结果
- boolean isExist = payTask.checkAccountIfExist();
- Message msg = new Message();
- msg.what = SDK_CHECK_FLAG;
- msg.obj = isExist;
- mHandler.sendMessage(msg);
- }
- };
- Thread checkThread = new Thread(checkRunnable);
- checkThread.start();
- }
- /**
- * get the sdk version. 获取SDK版本号
- *
- */
- public void getSDKVersion() {
- PayTask payTask = new PayTask(this);
- String version = payTask.getVersion();
- Toast.makeText(this, version, Toast.LENGTH_SHORT).show();
- }
- /**
- * 原生的H5(手机网页版支付切natvie支付) 【对应页面网页支付按钮】
- *
- * @param v
- */
- public void h5Pay(View v) {
- Intent intent = new Intent(this, H5PayDemoActivity.class);
- Bundle extras = new Bundle();
- /**
- * url是测试的网站,在app内部打开页面是基于webview打开的,demo中的webview是H5PayDemoActivity,
- * demo中拦截url进行支付的逻辑是在H5PayDemoActivity中shouldOverrideUrlLoading方法实现,
- * 商户可以根据自己的需求来实现
- */
- String url = "http://m.taobao.com";
- // url可以是一号店或者美团等第三方的购物wap站点,在该网站的支付过程中,支付宝sdk完成拦截支付
- extras.putString("url", url);
- intent.putExtras(extras);
- startActivity(intent);
- }
- /**
- * create the order info. 创建订单信息
- *
- */
- private 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;
- }
- /**
- * get the out_trade_no for an order. 生成商户订单号,该值在商户端应保持唯一(可自定义格式规范)
- *
- */
- private String getOutTradeNo() {
- SimpleDateFormat format = new SimpleDateFormat("MMddHHmmss",
- Locale.getDefault());
- Date date = new Date();
- String key = format.format(date);
- Random r = new Random();
- key = key + r.nextInt();
- key = key.substring(0, 15);
- return key;
- }
- /**
- * sign the order info. 对订单信息进行签名,即加密
- *
- * @param content
- * 待签名订单信息
- */
- private String sign(String content) {
- return SignUtils.sign(content, RSA_PRIVATE);
- }
- /**
- * get the sign type we use. 获取签名方式
- *
- */
- private String getSignType() {
- return "sign_type=\"RSA\"";
- }
- }
Android常用第三方支付的更多相关文章
- 7.Android常用第三方支付
移动支付 用户使用移动的终端完成对所购买商品或者服务的支付功能;分为近场支付(蓝牙支付,刷卡,滴卡),和远程支付(网上支付,短信支付) app支付模块 常见的支付厂商-->常见的支付方式 支付宝 ...
- Android常用第三方框架
1.volley (截击) 项目地址 https://github.com/smanikandan14/Volley-demo (1) JSON,图像等的异步下载: (2) 网络请求的排序(sch ...
- android 常用第三方包的代码混淆
首先在:project.properties 文件下,启动代码混淆 proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:pro ...
- Android 常用第三方框架总结
一.导航拦 1. FlycoTabLayout https://github.com/H07000223/FlycoTabLayout 2.CoordinatorTabLayout htt ...
- android 常用第三方github工程
这里有个汇总的网址:http://androidxy.com/zh/page/latest/-1/0 数据库:greenDao 参考:GreenDao3.2的使用 控件注解:Butterknife 图 ...
- Android中集成第三方支付
常见的第三方支付解决方案 支付宝支付 微信支付 银联支付 Ping++统一支付平台(需要继承服务器端和客户端) 短信支付 支付宝的集成流程 相关资料链接: 支付宝支付指引流程:支付指引流程 支付宝An ...
- 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_6-1.常用的第三方支付和聚合支付介绍
笔记 第六章 开发在线教育视频站点核心业务之从零基础接入 微信扫一扫网页支付 1.常用的第三方支付和聚合支付介绍 简介:介绍常用的第三方支付和聚合支付 1.什么是第三方支付 第 ...
- Android常用组件
UI相关 图片 Android-Universal-Image-Loader:com.nostra13.universalimageloader:异步加载.缓存.显示图片 ImageLoader:co ...
- Android常用组件【转】
UI相关 图片 Android-Universal-Image-Loader:com.nostra13.universalimageloader:异步加载.缓存.显示图片 ImageLoader:co ...
随机推荐
- CMakeLists 的使用,大型工程使用cmake 的构件过程
CMakeLists 的使用,大型工程使用cmake 的构件过程 CMakeLists_1 PROJECT(hello_2) cmake_minimum_required(VERSION 2.8) # ...
- Zookeeper使用--命令行
一.前言 在学习了Zookeeper相关的理论知识后,下面接着学习对Zookeeper的相关操作. 二.Zookeeper部署 Zookeeper的部署相对来说还是比较简单. Zookeeper有三种 ...
- 安装mitmproxy
https://www.jianshu.com/p/1dd40826113b 先连接到同一个局域网,再访问官网下载描述文件
- 7E - The sum problem
Given a sequence 1,2,3,......N, your job is to calculate all the possible sub-sequences that the sum ...
- MySQL实现阶段累加的sql写法 ,eq:统计余额
最近项目碰到一个新的需求,统计每日充值/消费之后的余额.对于这种需求,其实也很简单,只需要在每次充值/消费后,计算下余额,然后保存下来就可以了.但是对于这种需求,一条sql就能搞定,都不需要做冗余字段 ...
- Gitlab的安装
# GitLab Server 的搭建 参考 https://about.gitlab.com/installation ## 1. 准备工作 以Centos7为例,准备一台至少内存为4G的机器. # ...
- 字符模式console usb串口安装centos
黄色部分是使用console口安装centos需要使用text模式,可以参考前文,同时镜像路径也是需要指定的,来自/dev/sda4 U盘 setparams 'Install CentOS 7' l ...
- centos 下安装java
yum安装; 查看yum库中的java安装包 :yum -y list java* 安装需要的jdk版本的所有java程序:yum -y install java-1.8.0-openjdk* 查看j ...
- python基础--------字符串的调用详解(2)
Python 字符串的的调用方法~~~@@@ 17. strip : 去除字符串左右两边指定的字符 18. rstrip : 去除字符串右边指定的字符 19 . lstrip : 去除 ...
- Oracle获取异常的具体出处dbms_utility.format_error_backtrace
DBMS_UTILITY.FORMAT_ERROR_BACKTRACE :返回当前异常相应的描述,通过它就能知道异常的最初生成处. 系统为最近一次生成的异常设置了一个栈,并跟踪它的传递过程,而这个 ...