支付宝服务窗API接口开发php版本

时间:2022-11-20 16:08:48

支付宝服务窗API接口的开发对于许多网站要充值的朋友来讲是非常的重要的,今天我们就一起来看一篇关于php版本的支付宝服务窗API接口的开发例子。

这两天没事要接入支付宝服务窗,看支付宝的DEMO,我的神,我怎么评价好呢?阅读性不是很好,很阻碍简单的开发。所以我就根据提供的API简单的开发了点,接口还有很多不完善,有兴趣的可以自己完善一下,下边我就把代码贴出来,有时间再写如何使用。

?
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
<?php
 
class AlipayService{
 /**
 - 服务接口信息
 */
 public $service = null;
 /**
 - 签名信息
 */
 public $sign = null;
 /**
 - 签名类型
 */
 public $sign_type = null;
 /**
 - 字符集
 */
 public $charset = null;
 /**
 - 解析的biz_content数据
 */
 public $request = null;
 /**
 - 用户openid
 */
 public $from_user_id = null;
 /**
 - 消息类型
 */
 public $msg_type = null;
 /**
 - 事件类型
 */
 public $event_type = null;
 /**
 - 行为参数
 */
 public $action_param = null;
 /**
 - 支付宝用户信息
 */
 public $user_info = null;
 /**
 - 文本消息内容
 */
 public $text = null;
 /**
 - 图片媒体id
 */
 public $media_id = null;
 /**
 - 图片格式
 */
 public $format = null;
 /**
 - 是否开启调试
 */
 private $debug = false;
 /**
 - 接口类型
 */
 private $interface_type = array(
  'qrcode' => 'alipay.mobile.public.qrcode.create',
  'follow' => 'alipay.mobile.public.follow.list',
  'gis_get' => 'alipay.mobile.public.gis.get',
  'menu_get' => 'alipay.mobile.public.menu.get'
  'menu_add' => 'alipay.mobile.public.menu.add',
  'down_media' => 'alipay.mobile.public.multimedia.download',
  'menu_update' => 'alipay.mobile.public.menu.update',
  'info_query' => 'alipay.mobile.public.info.query',
  'info_modify' => 'alipay.mobile.public.info.modify',
  'shortlink' => 'alipay.mobile.public.shortlink.create',
  'label_add' => 'alipay.mobile.public.label.add',
  'label_del' => 'alipay.mobile.public.label.delete',
  'label_update' => 'alipay.mobile.public.label.update',
  'label_query'  => 'alipay.mobile.public.label.query',
  'label_user_add' => 'alipay.mobile.public.label.user.add',
  'label_user_del' => 'alipay.mobile.public.label.user.delete',
  'label_user_query' => 'alipay.mobile.public.label.user.query',
  'message_custom' => 'alipay.mobile.public.message.custom.send',
  'message_total' => 'alipay.mobile.public.message.total.send',
  'message_single' => 'alipay.mobile.public.message.single.send',
  'message_label_send' => 'alipay.mobile.public.message.label.send',
 );
 /**
 - 私有密钥地址,替换为你自己的
 */
 private $private_rsa_key_path ='rsa_private_key.pem';
 /**
 - 私有密钥地址,替换为你自己的
 */
 private $public_rsa_key_path ='rsa_public_key.pem';
 /**
 - 支付宝窗的app id 替换成你自己的
 */
 private $app_id = '2015120200901652';
 /**
 - 开启DEBUG参数
 - @params bool debug true 开启调试 false 关闭调试
 - @author widuu <admin@widuu.com>
 */
 public function __construct( $debug = false ){
 /* 是否开启DEBUG */
 if( $debug ) $this->debug = true;
 }
 /**
 - 获取参数,解析请求参数
 -
 - @author widuu <admin@widuu.com>
 */
 public function get_request(){
 if( !emptyempty($_POST) ){
  // 请求的服务接口
  $this->service = $_POST['service'];
  // 获取请求字符集
  $this->charset = $_POST['charset'];
  // 获取请求的biz_content
  $request_biz_content = $_POST['biz_content'];
  // 加密算法
  $this->sign_type = $_POST['sign_type'];
  // 加密字符串
  $this->sign = $_POST['sign'];
  // 如果请求格式不是Utf-8 转换格式为Utf-8
  if( strtolower($this->charset) != 'utf-8' ){
  $request_biz_content = iconv('GBK', 'utf-8', $request_biz_content);
  }
  // 解析字符串为xml
  $request_xml = @simplexml_load_string($request_biz_content, "SimpleXMLElement" , LIBXML_NOCDATA );
  // 解析为数组
  $request_array = json_decode(json_encode($request_xml),true);
  $this->request = $request_array;
  /* 解析 */
  $this->analysis($request_array);
  if($this->debug) $this->write_log('REQUEST_INFO',var_export($request_array,true));
  // 默认验证方法
  if( $this->service == 'alipay.service.check'){
  $this->verify($_POST);
  exit();
  }
  /* 返回结果 */
  return $request_array;
 }
 }
 /**
 - 回复文本内容
 - @params string content 文本数据
 - @params bool mass ture为群发
 - @author widuu <admin@widuu.com>
 */
 public function text($content,$mass=false){
 $info['text'] = array( 'content' => $content );
 /* 组织内容 */
 $biz_content = $this->common_response('text',$info,$mass);
 /* 判断是否为群发 */
 if($mass){
  $method = 'message_total';
 }else{
  $method = 'message_custom';
 }
 $sys_params = $this->common_system($method,$biz_content);
 $sys_params['sign'] = $this->rsa_sign($this->build_query($sys_params));
 /* 返回结果 结果是JSON数据 */
 $result = $this->response_post($sys_params);
 return $result;
 }
 /**
 - 回复图文内容
 - @params array articles 拼接的图文消息数组
 - @params bool mass ture为群发
 - @author widuu <admin@widuu.com>
 */
 public function articles($articles,$mass=false){
 $info['articles'] = array($articles);
 /* 组织内容 */
 $biz_content = $this->common_response('image-text',$info,$mass);
 /* 判断是否群发 */
 if($mass){
  $method = 'message_total';
 }else{
  $method = 'message_custom';
 }
 /* 加密参数 */
 $sys_params = $this->common_system($method,$biz_content);
 /* 加密字符 */
 $sys_params['sign'] = $this->rsa_sign($this->build_query($sys_params));
 /* 返回结果 结果是JSON数据 */
 $result = $this->response_post($sys_params);
 return $result;
 }
 /**
 - 关注事件
 -
 - @author widuu <admin@widuu.com>
 */
 public function is_follow(){
 $request = $this->request;
 if( $request['MsgType'] == 'event' && $request['EventType'] == 'follow' ){
  return true;
 }else{
  return false;
 }
 }
 /**
 - 取消关注事件
 -
 - @author widuu <admin@widuu.com>
 */
 public function is_unfollow(){
 $request = $this->request;
 if( $request['MsgType'] == 'event' && $request['EventType'] == 'unfollow' ){
  return true;
 }else{
  return false;
 }
 }
 /**
 - 下载用户发来的图片
 - @param media_id string 图片id
 - @param filename string 保存图片地址和名称
 - @author widuu <admin@widuu.com>
 */
 public function down_media($media_id,$filename){
 $sys_params = $this->common_system('down_media',array('mediaId'=>$media_id));
 $sys_params['sign'] = $this->rsa_sign($this->build_query($sys_params));
 /* 返回数据 */
 $result = $this->response_post($sys_params,true);
 $result = file_put_contents($filename, $result);
 if( $this->debug ){
  $this->write_log('SAVE_IMAGE','保存图片'.(string)$result);
 }
 return $result;
 }
 /**
 - (添加|更新|获取)自定义菜单
 - @param string $type (add|update|get)
 - @param array $menu 菜单数组,如果是获取菜单可以留空
 - @author widuu <admin@widuu.com>
 */
 public function menu( $type,$menu = array() ){
 if( !in_array( $type, array('get','update','add')) ){
  if( $this->debug ){
  $this->write_log('ERROR','菜单操作方法错误');
  }
  return false;
 }
 /* 拼接接口方法 */
 $method = 'menu_'.$type;
 $sys_params = $this->common_system($method,$menu);
 /* 加密字符串 */
 $sys_params['sign'] = $this->rsa_sign($this->build_query($sys_params));
 /* 请求获取结果 */
 $result = $this->response_post($sys_params);
 /* 转义并解析JSON 数据 */
 $menu_json = json_decode(iconv('GBK', 'utf-8', $result),true);
 /* 组织接口信息 */
 $interface = 'alipay_mobile_public_'.$method.'_response';
 /* 遇到错误返回 */
 if( $menu_json[$interface]['code'] != 200 ){
  if( $this->debug ){
  $this->write_log('GET_MENU_ERROR',$menu_json[$interface]['msg']);
  }
  return false;
 }
 /* 根据类型不同返回不同的结果 */
 if( $type == 'get' ){
  return $menu_json[$interface]['menu_content'];
 }else{
  return $menu_json[$interface]['msg'];
 }
 }
 
 /**
 - POST数据方法
 - @param array params 参数数组
 - @author widuu <admin@widuu.com>
 */
 private function response_post($params,$type=false){
 // 下载媒体和请求网关
 if($down){
  $url = 'https://openfile.alipay.com/chat/multimedia.do';
 }else{
  $url = 'https://openapi.alipay.com/gateway.do';
 }
 $ch = curl_init();
 curl_setopt($ch, CURLOPT_URL, $url);
 curl_setopt($ch, CURLOPT_HEADER, 0);
 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
 curl_setopt($ch, CURLOPT_POST, 1);
 curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
 curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
 curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
 $curl = curl_exec($ch);
 curl_close($ch);
 return $curl;
 }
 /**
 - 拼接回复数据
 - @param string $type 回复类型
 - @param array $info 回复内容
 - @param bool $mass 是否为群发
 - @author widuu <admin@widuu.com>
 */
 private function common_response($type,$info,$mass=false){
 $request = $this->request;
 $params = array();
 // 如果不是群发
 if( !$mass ) $params['toUserId'] = $request['FromUserId'];
 $params['msgType'] = $type;
 $params['createTime'] = time();
 $content = array_merge($params,$info);
 return $content;
 }
 /**
 - 拼接加密参数
 - @param string $interface_type 接口类型
 - @param array $biz_content 返回biz_content的数组
 - @author widuu <admin@widuu.com>
 */
 
 private function common_system($interface_type,$biz_content){
 /* 接口集合 */
 $type = $this->interface_type;
 $method = $type[$interface_type];
 /* 公共参数 */
 $params = array (
  'method' => $method,
  'charset' => 'UTF-8',
  'sign_type' => 'RSA',
  'app_id' => $this->app_id,
  'timestamp' => date ( 'Y-m-d H:i:s', time () ),
  'version'=>'1.0',
 );
 /* 获取某些接口时没有biz_content参数 */
 if( count($biz_content) > 0 ){
  $params['biz_content'] = json_encode($biz_content);
 }
 /* 返回系统参数 */
 return $params;
 }
 /**
 - 服务验证
 - @params array params 是自动获的验证信息
 - @author widuu <admin@widuu.com>
 */
 private function verify($params){
 /* 参数为空 */
 if( emptyempty($params) ){
  if( $this->debug ){
  $this->write_log('ERROR','验证参数为空');
  }
 }
 /* 构建参数,使用字典排序再拼接字符串 */
 $query_data = $this->build_query($params);
 /* 验证信息,有可能php版本BUG不支持验证 */
 $verify_result = $this->ras_verify($query_data);
 /* 返回验证结果 */
 if( $verify_result ){
  /* 取公有密钥的字符串合并为一行 */
  $public_rsa_string = file_get_contents($this->public_rsa_key_path);
  $public_rsa_string = str_replace ( "-----BEGIN PUBLIC KEY-----", "", $public_rsa_string );
  $public_rsa_string = str_replace ( "-----END PUBLIC KEY-----", "", $public_rsa_string );
  $public_rsa_string = str_replace ( "\r", "", $public_rsa_string );
  $public_rsa_string = str_replace ( "\n", "", $public_rsa_string );
  /* 构建加密字符串 */
  $response_xml = "<success>true</success><biz_content>$public_rsa_string</biz_content>";
  /* 生成验证信息 */
  $sign = $this->rsa_sign ( $response_xml );
  /* 构建返回数据 */
  $response = "<?xml version=\"1.0\" encoding=\"GBK\"?><alipay><response>$response_xml</response><sign>$sign</sign><sign_type>RSA</sign_type></alipay>";
  if( $this->debug ){
  $this->write_log('CHECK_RESPONSE',$response);
  }
  /* 输出返回信息 */
  echo $response;
  exit();
 }else{
  if( $this->debug ){
  $this->write_log('ERROR','验证失败');
  }
 }
 }
 /**
 - 拼接为字符串函数
 - @params array params 拼接函数
 - @author widuu <admin@widuu.com>
 */
 private function build_query($params){
 /* 删除sign字符串 */
 unset($params['sign']);
 /* 字典排序 */
 ksort($params);
 /* 拼接 */
 $query_array = array();
 foreach ($params as $k => $v) {
  $query_array[] = "$k"."="."$v";
 }
 $query_data = implode("&", $query_array);
 /* 返回拼接好的字符串 */
 return $query_data;
 }
 /**
 - 验证加密sign,有些PHP版本不支持,不支持情况直接返回true
 - @params string query_data 加密字符串
 - @author widuu <admin@widuu.com>
 */
 private function ras_verify($query_data){
 /* 读取公钥文件,PEM格式 */
 $pubKey = file_get_contents($this->public_rsa_key_path);
 /* 转换为openssl格式密钥 */
 $res = openssl_get_publickey($pubKey);
 /* 调用openssl内置方法验签 */
 $result = (bool) openssl_verify($query_data, base64_decode($this->sign), $res);
 /* 释放资源 */
 openssl_free_key($res);
 /* 有些PHP版本错误,直接返回true */
 if( strpos( openssl_error_string(),'PEM_read_bio' ) ){
  return true;
 }
 /* 返回验签结果 */
 return $result;
 }
 /**
 - 通过私有密钥加密数据
 - @params string data 加密数据
 - @author widuu <admin@widuu.com>
 */
 private function rsa_sign($data) {
 /* 读取私钥 */
 $priKey = file_get_contents ( $this->private_rsa_key_path );
 /* 转换为openssl格式密钥 */
 $res = openssl_get_privatekey ( $priKey );
 /* 调用openssl 加密 */
 openssl_sign ( $data, $sign, $res );
 /* 释放资源 */
 openssl_free_key ( $res );
 /* Base64加密 */
 $sign = base64_encode ( $sign );
 /* 返回加密参数 */
 return $sign;
 }
 private function analysis($params){
 switch($params['MsgType']){
  case 'image':
  $this->media_id = $params['Image']['MediaId'];
  $this->format = $params['Image']['Format'];
  break;
  case 'text':
  $this->text = $params['Text']['Content'];
  break;
  case 'event':
  $this->event_type = $params['EventType'];
  $this->action_param = $params['ActionParam'];
  break;
  default:
  break;
 }
 $this->msg_type = $params['MsgType'];
 $this->user_info = json_decode($params['UserInfo'],true);
 }
 /**
 - DEBUG 为true时的拼接字符串
 - @param string $level 自定义标识符
 - @param string $info 自定义内容
 - @param string $log_path 自定义日志路径
 - @author widuu <admin@widuu.com>
 */
 public function write_log($level,$info,$log_path = '' ){
 if( emptyempty($log_path) ){ //phpfensi.com
  $log_path = dirname ( __FILE__ ) . "/log.txt";
 }
 file_put_contents($log_path, "[$level]".date ( "Y-m-d H:i:s" ) . " " . $info . "\r\n", FILE_APPEND );
 }
}

好了以上就是小编为各位整理的一篇关于支付宝服务窗API接口的开发例子,这个有前提条件的就是我们必须要申请一个权限才可以,这个官方可以申请小编就不介绍。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。