Android支付宝,微信,银联支付支付的集成

移动支付

用户使用移动的终端完成对所购买商品或者服务的支付功能;分为近场支付(蓝牙支付,刷卡,滴卡),和远程支付(网上支付,短信支付)

app支付模块

常见的支付厂商-->常见的支付方式

  • 支付宝:阿里公司
  • 微信:腾讯公司
  • 银联:联合起来的结构
  • 财付通:腾讯公司
  • 支付宝钱包:阿里公司
  • 百度钱包:百度公司

支付安全吗?

都是比较安全.都是大公司的产品.而且这个和金钱之前挂钩;

支付难不难?

支付不难.因为是第三方平台的东西.

支付集成大概需要多长时间?(如果之前做过)

  • 支付宝:5-10分钟
  • 银联:5-10分钟
  • 微信:10-20分钟

支付流程_从生活出发

  • 1. 选择商品-->goodName,goodId,price,count
  • 2. 选择支付方式-->payType:1,支付宝;2,银联;3:微信
  • 3. 处理支付结果-->支付成功(购物流程),支付失败(重试,放弃)

支付流程_从程序角度出发

  1. 选择商品,组装支付数据-->拼接请求的jsonString
  2. 把支付数据post到后台server-->发送一个请求request
  3. 后台server(支付宝的服务)生成支付串码--->处理第二步的reponse
  4. 在客户端使用第三方平台的api调用插件完成支付-->调用第三方平台jar包里面的方法(集成过程),这一步才用到支付宝sdk

  5. 处理支付结果-->利用没有平台特有的通知机制处理支付结果
自己总结一下

 

支付串码是啥?

支付方法需要的支付参数

支付流程_简明说法

  1. 发起支付请求
  2. 拿到支付串码
  3. 调用api支付
  4. 处理支付结果
  • 同步返回:支付后通知我们自己的apk
  • 异步通知:支付后通知我们的server

支付宝

  • demo运行问题:需要ALIPAYPartnerID,ALIPAYSellerID,ALIPAYMD5KEY,ALIPAYPartnerPrivKey,ALIPAYPubKey才可以运行.但是如果直接下载的demo.这些字段都是"",无法看到效果,这些数据的获得.是用公司运行去做;
  • 支付宝demo的流程和实际开发不一致.实际开发.生成支付串码的过程应该交给服务器.因为sign需要支付宝的privatekey,如果放到apk里面是会泄露privatekey的,所以最后简化之后的支付宝集成就几行代码;
  • RSA:RSA是一种公钥加密算法。能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。主要用于公钥加密私钥解密、私钥签名公钥验签。
  • 支付宝公钥:开发者请求支付宝并获得返回时,开发者用于验签使用的公钥
  1. 我们自己要和支付宝签约(商户签约).-->运营
  2. 秘钥配置-->协助运营完成秘钥的配置(公钥互换),可能程序员会参与
  3. 集成支付宝-->必须是程序员去做.
 

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\"&notify_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唯一性
现在的支付宝demo主代码:PayDemoActivity
特别注意,这里的签名逻辑需要放在服务端,切勿将私钥泄露在代码中!,所剩代码就是上面的,把方法换成现在的即可
 
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 += "&notify_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\"" ;
     }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/52541.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.Java接入银联支付(chinapay)教程及避坑点

一、背景及效果展示 现如今,诸多的供应链系统需要使用电子钱包功能,所以接入银联B2B无卡支付,是很多系统应用需要做的事情。银联支付的类型分很多种:网关支付(带token请求实现,下次有空再分享)…

前端直接调用银联支付接口,使用form表单访问银联

直接调转到银联页面 银联支付 <template> <div class"pay"> <form action"https://gateway.95516.com/gateway/api/frontTransReq.do" method"post" id"payUniconSubmit"> <div v-show"false…

PHP接入银联在线网关支付

网站支付&#xff1a;一般接入微信支付、支付宝支付、银联支付&#xff0c;本文介绍的是如何接入中国银联在线网关支付 银联介绍 银联在线支付网关是中国银联联合各商业银行为持卡人提供的集成化、综合性互联网支付工具&#xff0c;主要支持输入卡号付款、用户登录支付、网银支…

移动支付--银联,支付宝,微信(android)

在这个移动互联网高速发展的时代,手机已经成为人们生活或者出行之中不可缺少的设备了&#xff0c;现在很多城市的商户都可以采用支付宝&#xff0c;微信支付了&#xff0c;人们出门只需要随身携带带手机&#xff0c;不用带大量现金就可以放心购物了。现在的很多移动互联网产品都…

微信APP支付之IJpay的使用

写在开始:一个搬砖程序员的随缘记录微信支付相对其他支付&#xff0c;比如支付宝支付坑比较多。一直报签名失败。签名参数顺序、数据类型&#xff0c;加密类型这些都需要注意&#xff0c;用第三方的比较省心。 IJpay介绍&#xff1a; 聚合支付&#xff0c;IJPay 让支付触手可及…

滥用 GPT,被抓了.....

点击上方“Java基基”&#xff0c;选择“设为星标” 做积极的人&#xff0c;而不是积极废人&#xff01; 每天 14:00 更新文章&#xff0c;每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路&#xff0c;很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应…

沉浸式学习

沉浸式就是利用系统状态栏&#xff0c;将背景图片延伸至系统状态栏区域内&#xff0c;效果就是和游戏应用画面那样。 Action1 隐藏状态栏和ActionBar 仅仅是隐藏状态栏和ActionBar&#xff0c;只是粗暴的隐藏了而已 //获取当前界面的DecorViewView decorView getWindow().g…

最全整理反面角色谁更适合饰演老大角色,你认识多少?(已收藏)

https://www.toutiao.com/a6662589985889190412/ 2019-02-27 16:11:54 这些演艺界的大佬&#xff0c;哪位更适合饰演反面角色的老大&#xff0c;你觉得的呢&#xff1f; 排名不分前后 【万梓良】 香港娱乐圈内有很多自带大哥气质的演员&#xff0c;万梓良就是其中之一。 他在…

“引进来,走出去”,锦江国际集团多重创新力引领绿色新发展

2022年12月13日&#xff0c;由南方财经全媒体集团指导&#xff0c;21世纪经济报道主办的“21世纪住宿业高峰论坛&#xff08;2022&#xff09;暨2022&#xff08;第十九届&#xff09;【金枕头】酒店大赏发布典礼”在上海如期举行。锦江国际集团副总裁周维应邀出席并发表“创新…

PDF文档翻译中文的方法

1.如果你的文档容量不大&#xff0c;可以尝试使用谷歌翻译进行文档翻译&#xff0c;可以看到谷歌翻译支持的文档类型有 .doc、.docx、.odf、.pdf、.ppt、.pptx、.ps、.rtf、.txt、.xls 和 .xlsx 不过值得注意的是&#xff0c;谷歌翻译支持的文档容量仅为1MB 2.同样是基于谷歌…

如何将英文PDF翻译成中文且格式不变?(PDF免费翻译攻略)

如何将英文PDF翻译成中文且格式不变 方法1&#xff1a;转换成HTML后再使用谷歌浏览器翻译保存为PDF方法2&#xff1a;使用一些第三方PDF翻译网站最后博主采用了福昕翻译网站在线翻译的方法。 Hello&#xff0c;小伙伴们&#xff01; 博主最近想要将一份英文的pdf帮助文档转换成…

用python写一个PDF翻译软件

前期工作&#xff1a; 注册 百度翻译api的账户&#xff08;个人-高级版&#xff09;&#xff0c;注册后&#xff0c;每个月有2百万的免费翻译字符数。 安装pdfminer3k 一、UI界面设计 点击路径按钮时弹出文件目录选择窗口&#xff0c;参考文章&#xff1a; PYQT5实现文件目…

使用TCPDF插件生成pdf以及pdf的中文处理

做了这么多年项目&#xff0c;以前只是在别人的项目中了解过php生成pdf文件&#xff0c;知道并不难&#xff0c;但是涉及到了pdf开发库&#xff0c;首先介绍pdf库。 多种多样的pdf开发库 1.WKHTMLTOPDF wkhtmltopdf是一个很好的解决方案&#xff0c;基本上可以原样输出html页面…

pdf文件如何进行翻译?pdf文件翻译方法分享。

pdf文件如何进行翻译&#xff1f;在日常的工作和学习当中&#xff0c;很多小伙伴都需要接受到pdf文件&#xff0c;需要我们对pdf文件进行翻译或者处理&#xff0c;那么众所周知dpf文件因为不可编辑性&#xff0c;从而变的特别特别的安全&#xff0c;深受大家的喜爱&#xff0c;…

推荐几种可以直接翻译PDF英文文献的方法

大家在阅读英文文献的时候&#xff0c;可能会经常碰到这样的情况&#xff1a;由于作者使用了各种从句&#xff0c;明明只是一句话&#xff0c;却写成很长的一段&#xff0c;即使其中没有生词&#xff0c;看了几遍也弄不懂它的意思。如果句子里再夹杂了几个看不懂的英文单词&…

英文PDF怎么翻译成中文?两分钟让你学会翻译PDF

现在大部分的文件资料都是以PDF的格式保存的&#xff0c;这是因为PDF格式可以跨设备打开的时候&#xff0c;不会影响到内容的排版格式。在撰写论文的时候&#xff0c;我们常需要查阅各种文献资料&#xff0c;尤其是会参考英文文献。小伙伴们平时遇到不懂的词句&#xff0c;是怎…

pdf翻译器哪个好?这几个pdf翻译软件能支持一键翻译

有没有从事外贸行业的小伙伴经常收到国外客人发送的外文文档呢&#xff1f;通常这些文档除了是外文语言外&#xff0c;还是pdf格式的。外文不熟的朋友&#xff0c;肯定是对文档一窍不通吧。如果我们用一些pdf翻译器来翻译文档的话&#xff0c;我们就不用费心去研究该文档的意思…

推荐几个好用的pdf翻译工具

开始用的是网易有道词典&#xff0c;排版和准确度都不错&#xff0c;效果如下&#xff0c;只是收费 后来在网上找了一下&#xff0c;大部分工具&#xff0c;要不收费要不排版不行&#xff0c;或者只是划词翻译&#xff0c;也没有ocr识别 最后找了两个网站 https://fanyi.atm…

PDF如何翻译成中文?三种方法教你怎样翻译PDF上的文字

小伙伴们在学习或工作中遇到外国文章时是不是会先翻译成中文再阅读呢&#xff1f;如果文章是word或者txt格式&#xff0c;我们可以直接复制文字进行翻译。但是有些文章为了看起来美观可能会生成PDF格式&#xff0c;我们想翻译的话&#xff0c;就需要先把格式转换成word等方便编…

PDF怎么翻译成中文?这些方法值得收藏

小伙伴们平时接触英文PDF文件的机会多吗&#xff1f;虽然可能平时接触的少&#xff0c;可是一旦接触就会很痛苦&#xff0c;因为有的PDF文件里面会充斥着大量深奥的词汇。对于这些深奥的词汇&#xff0c;小伙伴们都是采取什么方法呢&#xff1f;是逐个逐个拿去翻译吗&#xff1…