当前位置:   article > 正文

支付宝支付流程_1.houkwx.cn

1.houkwx.cn
1.简介
RSA 是一种非对称的签名算法,即签名密钥(私钥)与验签密钥(公钥)是不一样的, 私钥用于签名,公钥用于验签。

在与支付宝交易中,会有 对公私钥,即商户私钥,支付宝公

商户公私钥:由商户生成,商户私钥用于对商户发往支付宝的数据签名;商户公钥需要上传至支付宝,当支付宝收到商户发来的数据时用该公钥验证签名。

支付宝公:支付宝提供给商户,当商户收到支付宝发来的数据时,用该公钥验签。 


2.流程

 a. 移动端用商户私玥签名,将订单数据传给支付宝客户端,支付宝客户端将订单数据传给支付宝服务器,支付宝服务器根据订单数据中的商户信息,用商户上传的商户公钥验签,成功后进行支付操作;

b. 用户支付成功后,支付宝服务器用支付宝私钥签名回调数据并回调商家服务器(回调URL),同时支付宝客户端回调商家客户端;

c. 商家服务器用支付宝公钥验签,成功后更新商家订单状态等。




支付宝官网参考资料:


如何生成RSA密钥https://cshall.alipay.com/enterprise/help_detail.htm?help_id=474010



如何上传公钥https://cshall.alipay.com/enterprise/help_detail.htm?help_id=473890




1.下载支付宝的支付Demo(Andoird&iOS


解压Demo后是酱紫的:




导入客户端demo的安卓版的,可以看到四个参数都没设置,前两个,在我们支付宝的应用程序的《功能信息》

——>《移动支付》——>点击后面操作的 《查看》页面可以找到(前提是账号经过认证并且成功申请了支付功

能)




那么重要的事情来了,下面的两个参数的生成方法,我们再来自己动手生成。

打开刚才加压出来的DEMO下的openssl文件夹,openssl–>bin –> 双击 openssl.exe文件。这个时候会出现一

个命令框:


———————————————————————————————————————————————————

打开命令框后:输入第一行命令 ,生成私钥,如下:

[plain]  view plain  copy
 print ?
  1. genrsa -out rsa_private_key.pem 1024  

按回车键,接着输入第二行命令,生成公钥:


[plain]  view plain  copy
 print ?
  1. rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem  



按回车键,接着输入第三行命令,将RSA私钥转换成PKCS8格式


[plain]  view plain  copy
 print ?
  1. pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt  

————————————————————————————————————————————————


上面三条命令的截图给你们看看:











注意,注意,注意。重要的事情说三遍。一定要比对下经过PKCS8转码后的私钥,和你

的rsa_private_key.pem里面的私钥是不是一样的,如果不一样,以控制台里面的为

主。把这个复制出来替换掉rsa_private_key.pem里面的私钥。(如果你没换,点击支

付的时候别怪我没告诉你哦!!!感谢技术支持帮我弄好的。)



复制控制台里面私钥的方法:




执行完这三行命令后,就生成了两个以:.pem 结尾的文件。这就是我们生成的公钥与私钥.文件位置就在: bin  目录下。


有两种方法可以打开,

1.复制一份到桌面,改成Txt文件打开;

2.如果装有Notepad可以直接打开查看;

因为我们需要的只是里面的字符串,记住当我们引用这两个长的字符串的时候,需要注意的是:字符串,不能包括,换行,空格,以及其他误加的字符。所以复制的时候一定要小心。

把私钥和公钥字符串,复制到项目里面,这样四个参数就都有了,但是还需要在支付宝里面配置好公钥,

一:  点击“查看PID|KEY”,在新打开的页面(https://b.alipay.com/order/pidAndKey.htm ),可查看到签约支付宝账号、合作者身份ID(PID.


二:输入支付密码,查询key、支付宝公钥。


三:上传RSA公钥,在“合作伙伴密钥管理”下,点击“RSA加密”后的“添加密钥”,把自己的公钥复制进去。注意不能有空格,换行之类的。





移动支付

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

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
特别注意,这里的签名逻辑需要放在服务端,切勿将私钥泄露在代码中!,所剩代码就是上面的,把方法换成现在的即可

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 "支付结果确认中" ,
                                 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\"" ;
     }
}


支付宝官网参考资料:


如何生成RSA密钥https://cshall.alipay.com/enterprise/help_detail.htm?help_id=474010



如何上传公钥https://cshall.alipay.com/enterprise/help_detail.htm?help_id=473890




1.下载支付宝的支付Demo(Andoird&iOS


解压Demo后是酱紫的:




导入客户端demo的安卓版的,可以看到四个参数都没设置,前两个,在我们支付宝的应用程序的《功能信息》

——>《移动支付》——>点击后面操作的 《查看》页面可以找到(前提是账号经过认证并且成功申请了支付功

能)




那么重要的事情来了,下面的两个参数的生成方法,我们再来自己动手生成。

打开刚才加压出来的DEMO下的openssl文件夹,openssl–>bin –> 双击 openssl.exe文件。这个时候会出现一

个命令框:


———————————————————————————————————————————————————

打开命令框后:输入第一行命令 ,生成私钥,如下:

[plain]  view plain  copy
 print ?
  1. genrsa -out rsa_private_key.pem 1024  

按回车键,接着输入第二行命令,生成公钥:


[plain]  view plain  copy
 print ?
  1. rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem  



按回车键,接着输入第三行命令,将RSA私钥转换成PKCS8格式


[plain]  view plain  copy
 print ?
  1. pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt  

————————————————————————————————————————————————


上面三条命令的截图给你们看看:











注意,注意,注意。重要的事情说三遍。一定要比对下经过PKCS8转码后的私钥,和你

的rsa_private_key.pem里面的私钥是不是一样的,如果不一样,以控制台里面的为

主。把这个复制出来替换掉rsa_private_key.pem里面的私钥。(如果你没换,点击支

付的时候别怪我没告诉你哦!!!感谢技术支持帮我弄好的。)



复制控制台里面私钥的方法:




执行完这三行命令后,就生成了两个以:.pem 结尾的文件。这就是我们生成的公钥与私钥.文件位置就在: bin  目录下。


有两种方法可以打开,

1.复制一份到桌面,改成Txt文件打开;

2.如果装有Notepad可以直接打开查看;

因为我们需要的只是里面的字符串,记住当我们引用这两个长的字符串的时候,需要注意的是:字符串,不能包括,换行,空格,以及其他误加的字符。所以复制的时候一定要小心。

把私钥和公钥字符串,复制到项目里面,这样四个参数就都有了,但是还需要在支付宝里面配置好公钥,

一:  点击“查看PID|KEY”,在新打开的页面(https://b.alipay.com/order/pidAndKey.htm ),可查看到签约支付宝账号、合作者身份ID(PID.


二:输入支付密码,查询key、支付宝公钥。


三:上传RSA公钥,在“合作伙伴密钥管理”下,点击“RSA加密”后的“添加密钥”,把自己的公钥复制进去。注意不能有空格,换行之类的。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/675383
推荐阅读
相关标签
  

闽ICP备14008679号