Browse Source

first commit

master
“junying.wjy” 5 years ago
parent
commit
9d0fbba61c
  1. 21
      LICENSE.md
  2. 114
      NOTICE.md
  3. 83
      README.md
  4. 27
      docs/Base/Oauth.md
  5. 162
      docs/Marketing/Pass.md
  6. 43
      docs/Mini/Identification.md
  7. 27
      docs/Mini/Qrcode.md
  8. 24
      docs/Mini/Risk.md
  9. 33
      docs/Mini/TemplateMessage.md
  10. 107
      docs/OpenLife/Message.md
  11. 44
      docs/OpenLife/Template.md
  12. 22
      docs/Payment/Cancel.md
  13. 24
      docs/Payment/Close.md
  14. 29
      docs/Payment/Create.md
  15. 29
      docs/Payment/Pay.md
  16. 23
      docs/Payment/Query.md
  17. 26
      docs/Payment/Refund.md
  18. 4
      sdk/README.md
  19. 23
      sdk/composer.json
  20. 23
      sdk/src/Base/Application.php
  21. 150
      sdk/src/Base/Model/AlipaySystemOauthTokenRequest.php
  22. 19
      sdk/src/Base/Oauth/Client.php
  23. 19
      sdk/src/Base/Oauth/ServiceProvider.php
  24. 41
      sdk/src/Factory.php
  25. 974
      sdk/src/Kernel/AopClient.php
  26. 116
      sdk/src/Kernel/AopRequest.php
  27. 27
      sdk/src/Kernel/Config.php
  28. 26
      sdk/src/Kernel/Providers/ConfigServiceProvider.php
  29. 72
      sdk/src/Kernel/ServiceContainer.php
  30. 11
      sdk/src/Kernel/SignData.php
  31. 184
      sdk/src/Kernel/Support/Str.php
  32. 215
      sdk/src/Kernel/Traits/HasHttpRequests.php
  33. 21
      sdk/src/Marketing/Application.php
  34. 80
      sdk/src/Marketing/Model/AlipayPassInstanceAddContentBuilder.php
  35. 109
      sdk/src/Marketing/Model/AlipayPassInstanceUpdateContentBuilder.php
  36. 50
      sdk/src/Marketing/Model/AlipayPassTemplateAddContentBuilder.php
  37. 50
      sdk/src/Marketing/Model/AlipayPassTemplateUpdateContentBuilder.php
  38. 70
      sdk/src/Marketing/Pass/Client.php
  39. 20
      sdk/src/Marketing/Pass/ServiceProvider.php
  40. 27
      sdk/src/Mini/Application.php
  41. 39
      sdk/src/Mini/Identification/Client.php
  42. 16
      sdk/src/Mini/Identification/ServiceProvider.php
  43. 95
      sdk/src/Mini/Model/AlipayOpenAppMiniTemplatemessageSendContentBuilder.php
  44. 66
      sdk/src/Mini/Model/AlipayOpenAppQrcodeCreateContentBuilder.php
  45. 38
      sdk/src/Mini/Model/AlipaySecurityRiskContentDetectContentBuilder.php
  46. 82
      sdk/src/Mini/Model/ZolozIdentificationCustomerCertifyzhubQueryContentBuilder.php
  47. 68
      sdk/src/Mini/Model/ZolozIdentificationUserWebQueryContentBuilder.php
  48. 25
      sdk/src/Mini/Qrcode/Client.php
  49. 16
      sdk/src/Mini/Qrcode/ServiceProvider.php
  50. 23
      sdk/src/Mini/Risk/Client.php
  51. 20
      sdk/src/Mini/Risk/ServiceProvider.php
  52. 26
      sdk/src/Mini/TemplateMessage/Client.php
  53. 16
      sdk/src/Mini/TemplateMessage/ServiceProvider.php
  54. 23
      sdk/src/OpenPublic/Application.php
  55. 96
      sdk/src/OpenPublic/Message/Client.php
  56. 16
      sdk/src/OpenPublic/Message/ServiceProvider.php
  57. 38
      sdk/src/OpenPublic/Model/AlipayOpenPublicLifeMsgRecallContentBuilder.php
  58. 129
      sdk/src/OpenPublic/Model/AlipayOpenPublicMessageContentCreateContentBuilder.php
  59. 142
      sdk/src/OpenPublic/Model/AlipayOpenPublicMessageContentModifyContentBuilder.php
  60. 38
      sdk/src/OpenPublic/Model/AlipayOpenPublicMessageQueryContentBuilder.php
  61. 53
      sdk/src/OpenPublic/Model/AlipayOpenPublicMessageSingleSendContentBuilder.php
  62. 66
      sdk/src/OpenPublic/Model/AlipayOpenPublicMessageTotalSendContentBuilder.php
  63. 38
      sdk/src/OpenPublic/Model/AlipayOpenPublicTemplateMessageGetContentBuilder.php
  64. 80
      sdk/src/OpenPublic/Model/AlipayOpenPublicTemplateMessageIndustryModifyContentBuilder.php
  65. 46
      sdk/src/OpenPublic/Template/Client.php
  66. 16
      sdk/src/OpenPublic/Template/ServiceProvider.php
  67. 31
      sdk/src/Payment/Application.php
  68. 21
      sdk/src/Payment/Cancel/Client.php
  69. 16
      sdk/src/Payment/Cancel/ServiceProvider.php
  70. 21
      sdk/src/Payment/Close/Client.php
  71. 16
      sdk/src/Payment/Close/ServiceProvider.php
  72. 24
      sdk/src/Payment/Create/Client.php
  73. 16
      sdk/src/Payment/Create/ServiceProvider.php
  74. 52
      sdk/src/Payment/Model/AlipayTradeCancelContentBuilder.php
  75. 66
      sdk/src/Payment/Model/AlipayTradeCloseContentBuilder.php
  76. 92
      sdk/src/Payment/Model/AlipayTradeCreateContentBuilder.php
  77. 96
      sdk/src/Payment/Model/AlipayTradePayContentBuilder.php
  78. 66
      sdk/src/Payment/Model/AlipayTradeQueryContentBuilder.php
  79. 66
      sdk/src/Payment/Model/AlipayTradeRefundContentBuilder.php
  80. 25
      sdk/src/Payment/Pay/Client.php
  81. 16
      sdk/src/Payment/Pay/ServiceProvider.php
  82. 23
      sdk/src/Payment/Query/Client.php
  83. 16
      sdk/src/Payment/Query/ServiceProvider.php
  84. 22
      sdk/src/Payment/Refund/Client.php
  85. 16
      sdk/src/Payment/Refund/ServiceProvider.php
  86. 24
      sdk/tests/test.php

21
LICENSE.md

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) wjunying
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

114
NOTICE.md

@ -0,0 +1,114 @@
# Alibaba Cloud SDK for PHP
<https://www.alibabacloud.com/>
Copyright 1999-2019 Alibaba Group. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License").
You may not use this file except in compliance with the License.
A copy of the License is located at
<http://www.apache.org/licenses/LICENSE-2.0>
or in the "license" file accompanying this file. This file is distributed
on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied. See the License for the specific language governing
permissions and limitations under the License.
# Guzzle
<https://github.com/guzzle/guzzle>
Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling <mtdowling@gmail.com>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
#
<https://github.com/silexphp/Pimple>
Copyright (c) 2009-2018 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# Symfony
<https://github.com/symfony/symfony>
Copyright (c) 2004-2019 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
# EasyWeChat
<https://github.com/overtrue/wechat>
The MIT License (MIT)
Copyright (c) overtrue <i@overtrue.me>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

83
README.md

@ -0,0 +1,83 @@
## EasyAlipay
EasyAlipay 是基于支付宝OpenAPI开源的PHP语言版本SDK。使用本SDK前你需要具备基础的PHP相关能力,掌握自动加载,[Composer](https://getcomposer.org/)的使用等,并了解[支付宝的相关业务](https://docs.open.alipay.com/api)。
## 1.0.0 🎉🎉🎉
EsayAlipay 1.0.0 首次发布,欢迎加入下方的钉钉群一起交流,我们致力于打造一个方便开发者快速接入支付宝业务的SDK。本SDK针对通用授权、支付、小程序、生活号、营销等场景做了业务模型封装,并在持续增加中。同时对API参数做了最简单处理,以最少可用原则精简了参数,方便开发者更快的使用,降低开发者门槛。
## 一、背景
开发者在接入支付宝的过程中经常遇到想开发一个功能但是不清楚应该使用哪个API,找到对应API后参数又过于复杂不清楚哪些参数是自己真正要使用的。针对这种情况EsayAlipay主要在方法层面对API进行模型化归类,在参数层面对复杂参数进行简化,用最少的参数覆盖最高频的调用,不求百分百覆盖所有场景。
## 二、功能简介
EasyAlipay 提供了以下的能力:
### 2.1 纯PHP语言开发不采用任何框架
提供给开发者一个最干净的SDK,开发者在使用时候可以直接引入到任何PHP框架中。
### 2.2 Composer管理
本SDK相关依赖全部采用Composer管理。
### 2.3 业务场景封装
对通用授权、支付、小程序、生活号、营销等场景做了简单业务封装,并在持续增加中。
### 2.4 参数精简
基于最少可用原则对参数做了精简,每个方法对应对原生OpenAPI都在对应场景目录下Model目录中的每个文件中做了注释说明,如果精简后的参数不能满足您的使用需求,可直接在文件中添加对应参数。
## 三、环境需求
```php
PHP >= 7.0
PHP cURL 扩展
PHP OpenSSL 扩展
PHP fileinfo 扩展
```
## 四、快速开始
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '你的应用APPID',
'gateway_url' => "网关地址",//沙箱环境网关gateway_url:https://openapi.alipaydev.com/gateway.do,线上网关gateway_url:https://openapi.alipay.com/gateway.do
'sign_type' => "RSA2",
'charset' => "UTF-8",
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
//通用基础
$app = Factory::base($options);
//营销
$app = Factory::marketing($options);
//小程序
$app = Factory::mini($options);
//生活号
$app = Factory::openPublic($options);
//支付
$app = Factory::payment($options);
```
支付宝公钥与应用私钥配置请参考:[三步搞定签名](https://docs.open.alipay.com/291/106103/)
创建应用地址:[支付宝开放平台](https://openhome.alipay.com)
支付宝小程序门户:[小程序开发平台](https://mini.open.alipay.com)
## 五、文档与示例
请参考 docs目录下的相关文档,里面有具体每个方法每个参数的详细说明,文档目录与代码结构保持一致方便开发者理解。在工程的 tests 目录下 test.php文件中提供了一个沙箱环境交易查询的示例。
## 六、开源许可
EasyAlipay 参考依赖了一些三方组件,在NOTICE中引入了他们的开源协议。
## 七、信息交流
欢迎加入EasyAlipay钉钉交流群:23311489
<img src="https://gw.alipayobjects.com/mdn/rms_1e5ba1/afts/img/A*7sA8Tpin7f0AAAAAAAAAAABkARQnAQ" width=256 height=256>

27
docs/Base/Oauth.md

@ -0,0 +1,27 @@
## 换取授权访问令牌
##### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::base($options);
$app['oauth']->getToken($grant_type, $code,$refresh_token);
```
参数说明
grant_type:值为authorization_code时,代表用code换取;值为refresh_token时,代表用refresh_token换取
code:授权码,用户对应用授权后得到。
refresh_token:刷刷新令牌,上次换取访问令牌时得到。见出参的refresh_token字段,可传null。

162
docs/Marketing/Pass.md

@ -0,0 +1,162 @@
## 支付宝卡包
产品文档:https://docs.alipay.com/mini/introduce/voucher
#### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::marketing($options);
```
#### 卡券模板创建
```php
$app['pass']->createTemplate($tpl_id,$tpl_content);
```
参数说明
tpl_id:商户用于控制模版的唯一性,长度不超过999。(可以使用时间戳保证唯一性),长度不超过30。例如:20140709150010
tpl_content:模板内容信息,遵循JSON规范,长度不超过99999。详情参见:[tpl_content参数说明](https://doc.open.alipay.com/doc2/detail.htm?treeId=193&articleId=105249&docType=1#tpl_content)
#### 卡券模板更新
```php
$app['pass']->updateTemplate($tpl_id,$tpl_content);
```
tpl_id:商户用于控制模版的唯一性,长度不超过999。(可以使用时间戳保证唯一性),长度不超过30。例如:20140709150010
tpl_content:模板内容信息,遵循JSON规范,长度不超过99999。详情参见:[tpl_content参数说明](https://doc.open.alipay.com/doc2/detail.htm?treeId=193&articleId=105249&docType=1#tpl_content)
#### 卡券实例发放
```php
$app['pass']->addInstance($tpl_id,$tpl_params,$recognition_type,$recognition_info);
```
tpl_id:商户用于控制模版的唯一性,长度不超过999。例如:20140709150010
tpl_params:模版动态参数信息:对应模板中$变量名$的动态参数,见模板创建接口返回值中的tpl_params字段,长度不超过99999。
recognition_type:Alipass添加对象识别类型:1–订单信息。长度不超过999。
recognition_info:支付宝用户识别信息,长度不超过999。 包括partner_id(商户的签约账号)和out_trade_no(某笔订单号)。例如:{"partner_id":"2088102114633762","out_trade_no":"1234567"}
#### 卡券实例更新
```php
$app['pass']->updateInstance($serial_number,$channel_id,$tpl_params,$status,$verify_code,$verify_type);
```
参数说明
serial_number:商户指定卡券唯一值,卡券JSON模板中fileInfo->serialNumber字段对应的值,长度不超过999。
channel_id:代理商代替商户发放卡券后,再代替商户更新卡券时,此值为商户的pid/appid,长度不超过999。
tpl_params:对应模板中$变量名$的动态参数,见模板创建接口返回值中的tpl_params字段,长度不超过99999。
status:券状态,支持更新为USED、CLOSED两种状态
verify_code:核销码串值【当状态变更为USED时,建议传】。该值正常为模板中核销区域(Operation)对应的message值。长度不超过999。
verify_type:核销方式,该值正常为模板中核销区域(Operation)对应的format值。verify_code和verify_type需同时传入,长度不超过99999。
#### tpl_content示例
```php
{
"logo": "https://alipass.alipay.com//temps/free/logo.png",
"strip": "https://alipass.alipay.com//temps/free/strip.png",
"icon": "http://alipassprod.test.alipay.net/temps/free/icon.png",
"content": {
"evoucherInfo": {
"title": "优惠券",
"type": "boardingPass",
"product": "free",
"startDate": "2019-07-25 15:05:22",
"endDate": "2029-12-31 23:59:59",
"operation": [{
"message": "$ackCode$",
"messageEncoding": "UTF-8",
"format": "barcode",
"altText": "$ackCode$"
}],
"einfo": {
"logoText": "优惠券",
"headFields": [{
"key": "status",
"label": "状态",
"value": "可使用",
"type": "text"
}],
"primaryFields": [{
"key": "strip",
"label": "",
"value": "凭此券即可抵扣1元",
"type": "text"
}],
"secondaryFields": [{
"key": "validDate",
"label": "有效期至:",
"value": "2029-12-31 23:59:59",
"type": "text"
}],
"auxiliaryFields": [{
"key": "key_1",
"label": "",
"value": "卡券Demo演示",
"type": "text"
}],
"backFields": [{
"key": "description",
"label": "详情描述",
"value": "1.该优惠有效期:截止至2029年12月31日;2.凭此券可以享受以下优惠:享门抵扣1元不与其他优惠同享。详询商家。",
"type": "text"
}]
},
"locations": [],
"remindInfo": {
"offset": "2"
}
},
"merchant": {
"mname": "君泓测试",
"mtel": "",
"minfo": ""
},
"platform": {
"channelID": "2088201564809153",
"webServiceUrl": "https://alipass.alipay.com/builder/syncRecord.htm?tempId=2019030622051381011176571"
},
"style": {
"backgroundColor": "RGB(255,126,0)"
},
"fileInfo": {
"formatVersion": "2",
"canShare": true,
"canBuy": false,
"canPresent": false,
"serialNumber": "$serialNumber$",
"supportTaxi": "false",
"taxiSchemaUrl": "alipays://platformapi/startapp?appId=20000778&bizid=260&channel=71322"
},
"appInfo": {
"app": {
"android_appid": "com.taobao.ecoupon",
"ios_appid": "taobaolife://",
"android_launch": "com.taobao.ecoupon",
"ios_launch": "taobaolife://",
"android_download": "http://download.taobaocdn.com/freedom/17988/andriod/Ecoupon_2.0.1_taobao_wap.apk",
"ios_download": "https://itunes.apple.com/cn/app/id583295537"
},
"label": "券券APP",
"message": "点击调起APP"
},
"source": "alipassprod",
"alipayVerify": ["qrcode", "barcode", "text", "wave"]
}
}
```

43
docs/Mini/Identification.md

@ -0,0 +1,43 @@
## 小程序人脸采集与刷脸认证
##### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::mini($options);
```
##### 人脸采集
产品文档地址:https://docs.alipay.com/mini/introduce/facecapture
```php
$app['identification']->queryUserWeb($biz_id,$zim_id,$extern_param);
```
参数说明
biz_id:业务流水号,需要保证唯一性,长度不超过64。例如:5456897876546767654
zim_id:刷脸认证标识,长度不超过64。例如:731be7f204a962b0486a9b64ea3050ae
extern_param:扩展参数,长度不超过1024。
##### 刷脸认证
产品文档地址:https://docs.alipay.com/mini/introduce/alipay-face-verify
```php
$app['identification']->queryCertifyzhub($biz_id,$zim_id,$face_type,$need_img);
```
参数说明
biz_id:业务流水号,需要保证唯一性,长度不超过64。
zim_id:刷脸认证标识,长度不超过64。

27
docs/Mini/Qrcode.md

@ -0,0 +1,27 @@
## 小程序二维码
产品文档地址:https://docs.alipay.com/mini/introduce/qrcode
##### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::mini($options);
$app['qrcode']->create($url_param,$query_param,$describe);
```
参数说明
url_param:小程序中能访问到的页面路径,长度不超过256。例如:page/component/component-pages/view/view
query_param:小程序的启动参数,打开小程序的query ,在小程序 onLaunch的方法中获取,长度不超过256。例如:x=1
describe:对应的二维码描述,长度不超过32。

24
docs/Mini/Risk.md

@ -0,0 +1,24 @@
## 小程序文本风险识别
产品文档地址:https://docs.alipay.com/mini/introduce/text-identification
基于alipay.security.risk.content.detect接口进行封装
##### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::mini($options);
$app['risk']->detectContent($content);
```
参数说明
content:需要识别的文本,不要包含特殊字符以及双引号等可能引起json格式化错误问题的字符,长度不超过2000。例如:代办毕业证,我们最专业

33
docs/Mini/TemplateMessage.md

@ -0,0 +1,33 @@
## 小程序模版消息
产品文档地址:https://docs.alipay.com/mini/introduce/message
##### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::mini($options);
$app['templateMessage']->send($to_user_id,$form_id,$user_template_id,$page,$data);
```
参数说明
to_user_id:发送消息的用户userid,长度不超过20。例如:2088102122458832
form_id:用户发生的交易行为的交易号,或者用户在小程序产生表单提交的表单号,用于信息发送的校验,长度不超过64。例如:2017010100000000580012345678
user_template_id:用户申请的模板id号,固定的模板id会发送固定的消息,长度不超过64。例如:MDI4YzIxMDE2M2I5YTQzYjUxNWE4MjA4NmU1MTIyYmM=
page:小程序的跳转页面,用于消息中心用户点击之后详细跳转的小程序页面,长度不超过128。例如:page/component/index
data:开发者需要发送模板消息中的自定义部分来替换模板的占位符,长度不超过2048。例如:{"keyword1": {"value" : "12:00"},"keyword2": {"value" : "20180808"},"keyword3": {"value" : "支付宝"}}

107
docs/OpenLife/Message.md

@ -0,0 +1,107 @@
## 生活号消息
#### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::openPublic($options);
```
#### 创建图文消息内容
```php
$app['message']->createImageTextContent($title, $cover, $content, $could_comment, $ctype, $benefit, $ext_tags, $login_ids);
```
参数说明
title:标题,长度不超过32。
cover:封面图url,长度不超过255,图片尺寸为996*450,最大不超过3M,支持格式:.jpg、.png ,请先调用图片上传接口获得图片url https://oalipay-dl-django.alicdn.com/rest/1.0/image?fileIds=xxx&zoom=xxx
content:消息正文(支持富文本),长度不超过10000。
could_comment:是否允许评论 T:允许 F:不允许,默认不允许 T
ctype:图文类型 activity: 活动图文,不填默认普通图文
benefit:活动利益点,图文类型ctype为activity类型时才需要传,长度不超过10。例如:满**减**
ext_tags:关键词列表,英文逗号分隔,最多不超过5个,长度不超过50。例如:关键,热度
login_ids:可预览支付宝账号列表,需要预览时才填写, 英文逗号分隔,最多不超过10个,长度不超过10000。例如:13434343432,xxx@163.com
#### 更新图文消息内容
```php
$app['message']->modifyImageTextContent($content_id, $title, $cover, $content, $could_comment, $ctype, $benefit, $ext_tags, $login_ids);
```
参数说明
content_id:内容id,长度不超过100。
title:标题,长度不超过32。
cover:封面图url,长度不超过255,图片尺寸为996*450,最大不超过3M,支持格式:.jpg、.png ,请先调用图片上传接口获得图片url https://docs.open.alipay.com/api_3/alipay.offline.material.image.upload
content:消息正文(支持富文本),长度不超过10000。
could_comment:是否允许评论 T:允许 F:不允许,默认不允许 T
ctype:图文类型 activity: 活动图文,不填默认普通图文
benefit:活动利益点,图文类型ctype为activity类型时才需要传,长度不超过10。例如:满**减**
ext_tags:关键词列表,英文逗号分隔,最多不超过5个,长度不超过50。例如:关键,热度
login_ids:可预览支付宝账号列表,需要预览时才填写, 英文逗号分隔,最多不超过10个,长度不超过10000。例如:13434343432,xxx@163.com
#### 群发文本消息
```php
$app['message']->sendText($text);
```
参数说明
text:文本消息内容
#### 群发图文消息
```php
$app['message']->sendImageText($articles);
```
参数说明
articles示例如下
```php
"articles":[{
"title":"图文消息标题(长度不超过100)",
"desc":"图文消息内容(长度不超过512)",
"image_url":"图片链接,例如:http://example.com/abc.jpg(长度不超过100)",
"url":"点击图文消息跳转的链接,例如:https://www.example.com/b.php(长度不超过100)",
"action_name":"链接文字,例如:查看详情"
}]
```
#### 查询已发送消息
```php
$app['message']->query($message_ids);
```
参数说明
message_ids:消息id集,长度不超过64,限制最多传入20个message_id。message_id在调用群发、组发消息接口时会返回,需调用方保存。例如:2017080301329810fa9f7ca2-4634-481b-bca2-54092fd4be72
#### 消息撤回
```php
$app['message']->recall($message_id);
```
参数说明
message_id:消息id,长度不超过64。例如:2016000000000000

44
docs/OpenLife/Template.md

@ -0,0 +1,44 @@
## 生活号消息模版
#### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::openPublic($options);
```
#### 模板消息行业设置修改
```php
$app['template']->setIndustry($primary_industry_name,$primary_industry_code,$secondary_industry_code,$secondary_industry_name);
```
参数说明
primary_industry_name:服务窗消息模板所属主行业一/二级名称,长度不超过30。例如:IT科技/IT软件与服务。查看行业信息:https://alipay.open.taobao.com/doc2/detail?treeId=197&docType=1&articleId=105043
primary_industry_code:服务窗消息模板所属主行业一/二级编码,长度不超过20。例如:10001/20102
secondary_industry_code:服务窗消息模板所属副行业一/二级编码,长度不超过20。例如:10001/20102
secondary_industry_name:服务窗消息模板所属副行业一/二级名称,长度不超过30。例如:IT科技/IT软件与服务
#### 查询行业设置
```php
$app['template']->getIndustry();
```
#### 消息模板领取
```php
$app['template']->getTemplate($template_id);
```
参数说明
template_id:消息母板id,长度不超过20。登陆生活号后台(fuwu.alipay.com),点击菜单“模板消息”,点击“模板库”,即可看到相应模板的消息母板id。

22
docs/Payment/Cancel.md

@ -0,0 +1,22 @@
## 交易取消
##### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::payment($options);
$app['cancel']->cancel($out_trade_no);
```
参数说明
out_trade_no:订单支付时传入的商户订单号,长度不超过64。

24
docs/Payment/Close.md

@ -0,0 +1,24 @@
## 交易关闭
用于交易创建后,用户在一定时间内未进行支付,可调用该接口直接将未付款的交易进行关闭。
##### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::payment($options);
$app['close']->close($out_trade_no);
```
参数说明
out_trade_no:订单支付时传入的商户订单号,长度不超过64。

29
docs/Payment/Create.md

@ -0,0 +1,29 @@
## 交易创建
#### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::payment($options);
$app['create']-> create($subject,$out_trade_no,$total_amount,$buyer_id);
```
参数说明
subject:订单标题,长度不超过256。
out_trade_no:订单支付时传入的商户订单号,长度不超过64。
total_amount:订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]
buyer_id:买家的支付宝唯一用户号(2088开头的16位纯数字)

29
docs/Payment/Pay.md

@ -0,0 +1,29 @@
## 交易支付
#### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::payment($options);
$app['pay']->pay($subject,$out_trade_no,$total_amount,$auth_code);
```
参数说明
subject:订单标题,长度不超过256。
out_trade_no:订单支付时传入的商户订单号,长度不超过64。
total_amount:订单总金额,单位为元,精确到小数点后两位,取值范围[0.01,100000000]
auth_code:支付授权码,25~30开头的长度为16~24位的数字,实际字符串长度以开发者获取的付款码长度为准

23
docs/Payment/Query.md

@ -0,0 +1,23 @@
## 交易查询
#### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::payment($options);
$app['query']->query($out_trade_no));`
```
参数说明
out_trade_no:out_trade_no:订单支付时传入的商户订单号,长度不超过64。

26
docs/Payment/Refund.md

@ -0,0 +1,26 @@
## 交易退款
当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,支付宝将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。 交易超过约定时间(签约时设置的可退款时间)的订单无法进行退款。一笔退款失败后重新提交,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。
##### 配置
```php
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'alipay_public_key' => '支付宝公钥',
'merchant_private_key' => '应用私钥',
// ...
];
$app = Factory::payment($options);
$app['refund']->refund($out_trade_no, $refund_amount);
```
参数说明
out_trade_no:订单支付时传入的商户订单号,长度不超过64。
refund_amount:需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数

4
sdk/README.md

@ -0,0 +1,4 @@
1、安装PHP7以上版本
2、安装composer:https://getcomposer.org/
3、安装项目依赖:composer install 在sdk目录下生成依赖的vendor目录文件
4、运行sdk/tests/test.php文件,可以获取沙箱环境下一笔交易查询结果

23
sdk/composer.json

@ -0,0 +1,23 @@
{
"require": {
"php": ">=7.0",
"ext-fileinfo": "*",
"ext-openssl": "*",
"ext-simplexml": "*",
"guzzlehttp/guzzle": "^6.2",
"pimple/pimple": "^3.0",
"symfony/cache": "^3.3 || ^4.0",
"symfony/http-foundation": "^2.7 || ^3.0 || ^4.0",
"symfony/psr-http-message-bridge": "^0.3 || ^1.0"
},
"autoload": {
"psr-4": {
"EasyAlipay\\": "sdk/src/"
}
},
"autoload-dev": {
"psr-4": {
"EasyAlipay\\Tests\\": "tests/"
}
}
}

23
sdk/src/Base/Application.php

@ -0,0 +1,23 @@
<?php
namespace EasyAlipay\Base;
use EasyAlipay\Kernel\ServiceContainer;
/**
* Class Application.
*
* @property \EasyAlipay\Base\Image\Client $image
* @property \EasyAlipay\Base\Oauth\Client $oauth
* @property \EasyAlipay\Base\Video\Client $video
*
*/
class Application extends ServiceContainer
{
/**
* @var array
*/
protected $providers = [
Oauth\ServiceProvider::class,
];
}

150
sdk/src/Base/Model/AlipaySystemOauthTokenRequest.php

@ -0,0 +1,150 @@
<?php
namespace EasyAlipay\Base\Model;
/* *
* 功能:alipay.system.oauth.token(换取授权访问令牌接口)业务参数封装
*/
class AlipaySystemOauthTokenRequest
{
/**
* 授权码,用户对应用授权后得到。
**/
private $code;
/**
* 值为authorization_code时,代表用code换取;值为refresh_token时,代表用refresh_token换取
**/
private $grantType;
/**
* 刷新令牌,上次换取访问令牌时得到。见出参的refresh_token字段
**/
private $refreshToken;
private $apiParas = array();
private $terminalType;
private $terminalInfo;
private $prodCode;
private $apiVersion="1.0";
private $notifyUrl;
private $returnUrl;
private $needEncrypt=false;
public function setCode($code)
{
$this->code = $code;
$this->apiParas["code"] = $code;
}
public function getCode()
{
return $this->code;
}
public function setGrantType($grantType)
{
$this->grantType = $grantType;
$this->apiParas["grant_type"] = $grantType;
}
public function getGrantType()
{
return $this->grantType;
}
public function setRefreshToken($refreshToken)
{
$this->refreshToken = $refreshToken;
$this->apiParas["refresh_token"] = $refreshToken;
}
public function getRefreshToken()
{
return $this->refreshToken;
}
public function getApiMethodName()
{
return "alipay.system.oauth.token";
}
public function setNotifyUrl($notifyUrl)
{
$this->notifyUrl=$notifyUrl;
}
public function getNotifyUrl()
{
return $this->notifyUrl;
}
public function setReturnUrl($returnUrl)
{
$this->returnUrl=$returnUrl;
}
public function getReturnUrl()
{
return $this->returnUrl;
}
public function getApiParas()
{
return $this->apiParas;
}
public function getTerminalType()
{
return $this->terminalType;
}
public function setTerminalType($terminalType)
{
$this->terminalType = $terminalType;
}
public function getTerminalInfo()
{
return $this->terminalInfo;
}
public function setTerminalInfo($terminalInfo)
{
$this->terminalInfo = $terminalInfo;
}
public function getProdCode()
{
return $this->prodCode;
}
public function setProdCode($prodCode)
{
$this->prodCode = $prodCode;
}
public function setApiVersion($apiVersion)
{
$this->apiVersion=$apiVersion;
}
public function getApiVersion()
{
return $this->apiVersion;
}
public function setNeedEncrypt($needEncrypt)
{
$this->needEncrypt=$needEncrypt;
}
public function getNeedEncrypt()
{
return $this->needEncrypt;
}
}

19
sdk/src/Base/Oauth/Client.php

@ -0,0 +1,19 @@
<?php
namespace EasyAlipay\Base\Oauth;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Base\Model\AlipaySystemOauthTokenRequest;
class Client extends AopClient
{
public function getToken(string $grant_type, string $code, string $refresh_token)
{
//构造查询业务请求参数对象
$alipaySystemOauthTokenRequest = new AlipaySystemOauthTokenRequest();
$alipaySystemOauthTokenRequest->setGrantType($grant_type);
$alipaySystemOauthTokenRequest->setCode($code);
$alipaySystemOauthTokenRequest->setRefreshToken($refresh_token);
return($this->execute($alipaySystemOauthTokenRequest, NULL, NULL)) ;
}
}

19
sdk/src/Base/Oauth/ServiceProvider.php

@ -0,0 +1,19 @@
<?php
namespace EasyAlipay\Base\Oauth;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
$app['oauth'] = function ($app) {
return new Client($app);
};
}
}

41
sdk/src/Factory.php

@ -0,0 +1,41 @@
<?php
namespace EasyAlipay;
/**
* Class Factory.
*
* @method static \EasyAlipay\Payment\Application payment(array $config)
* @method static \EasyAlipay\Mini\Application mini(array $config)
* @method static \EasyAlipay\OpenPublic\Application openPublic(array $config)
* @method static \EasyAlipay\Marketing\Application marketing(array $config)
* @method static \EasyAlipay\BasicService\Application basicService(array $config)
*/
class Factory
{
/**
* @param string $name
* @param array $config
*
* @return \EasyAlipay\Kernel\ServiceContainer
*/
public static function make($name, array $config)
{
$namespace = Kernel\Support\Str::studly($name);
$application = "\\EasyAlipay\\{$namespace}\\Application";
return new $application($config);
}
/**
* Dynamically pass methods to the application.
*
* @param string $name
* @param array $arguments
*
* @return mixed
*/
public static function __callStatic($name, $arguments)
{
return self::make($name, ...$arguments);
}
}

974
sdk/src/Kernel/AopClient.php

@ -0,0 +1,974 @@
<?php
namespace EasyAlipay\Kernel;
use Exception;
use EasyAlipay\Kernel\SignData;
class AopClient
{
//应用ID
private $appId;
//商户私钥值
private $rsaPrivateKey;
//支付宝公钥值
private $alipayrsaPublicKey;
//网关
private $gatewayUrl = "https://openapi.alipay.com/gateway.do";
//返回数据格式
private $format = "json";
//签名类型
private $signType = "RSA";
// 表单提交字符集编码
private $postCharset = "UTF-8";
//api版本
private $apiVersion = "1.0";
//私钥文件路径
private $rsaPrivateKeyFilePath;
private $alipayPublicKey = null;
private $debugInfo = false;
private $fileCharset = "UTF-8";
private $RESPONSE_SUFFIX = "_response";
private $ERROR_RESPONSE = "error_response";
private $SIGN_NODE_NAME = "sign";
//加密XML节点名称
private $ENCRYPT_XML_NODE_NAME = "response_encrypted";
//加密密钥和类型
private $encryptKey;
private $needEncrypt = false;
private $encryptType = "AES";
protected $alipaySdkVersion = "alipay-sdk-php-easyalipay-20190820";
public function __construct(ServiceContainer $app){
$this->appId = $app['config']['app_id'];
$this->rsaPrivateKey = $app['config']['merchant_private_key'];
$this->alipayrsaPublicKey = $app['config']['alipay_public_key'];
$this->postCharset = $app['config']['charset'];
$this->signType=$app['config']['sign_type'];
$this->gatewayUrl = $app['config']['gateway_url'];
if(empty($this->appId)||trim($this->appId)==""){
throw new Exception("appId should not be NULL!");
}
if(empty($this->rsaPrivateKey)||trim($this->rsaPrivateKey)==""){
throw new Exception("rsaPrivateKey should not be NULL!");
}
if(empty($this->alipayrsaPublicKey)||trim($this->alipayrsaPublicKey)==""){
throw new Exception("alipayPublicKey should not be NULL!");
}
if(empty($this->postCharset)||trim($this->postCharset)==""){
throw new Exception("postCharset should not be NULL!");
}
if(empty($this->signType)||trim($this->signType)==""){
throw new Exception("signType should not be NULL!");
}
if(empty($this->gatewayUrl)||trim($this->gatewayUrl)==""){
throw new Exception("gatewayUrl should not be NULL!");
}
}
public function execute($request, $authToken = null, $appInfoAuthtoken = null) {
$this->setupCharsets($request);
//如果两者编码不一致,会出现签名验签或者乱码
if (strcasecmp($this->fileCharset, $this->postCharset)) {
// writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为postCharset!");
throw new Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!");
}
$iv = null;
if (!$this->checkEmpty($request->getApiVersion())) {
$iv = $request->getApiVersion();
} else {
$iv = $this->apiVersion;
}
//组装系统参数
$sysParams["app_id"] = $this->appId;
$sysParams["version"] = $iv;
$sysParams["format"] = $this->format;
$sysParams["sign_type"] = $this->signType;
$sysParams["method"] = $request->getApiMethodName();
$sysParams["timestamp"] = date("Y-m-d H:i:s");
$sysParams["auth_token"] = $authToken;
$sysParams["alipay_sdk"] = $this->alipaySdkVersion;
$sysParams["terminal_type"] = $request->getTerminalType();
$sysParams["terminal_info"] = $request->getTerminalInfo();
$sysParams["prod_code"] = $request->getProdCode();
$sysParams["notify_url"] = $request->getNotifyUrl();
$sysParams["charset"] = $this->postCharset;
$sysParams["app_auth_token"] = $appInfoAuthtoken;
//获取业务参数
$apiParams = $request->getApiParas();
if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){
$sysParams["encrypt_type"] = $this->encryptType;
if ($this->checkEmpty($apiParams['biz_content'])) {
throw new Exception(" api request Fail! The reason : encrypt request is not supperted!");
}
if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) {
throw new Exception(" encryptType and encryptKey must not null! ");
}
if ("AES" != $this->encryptType) {
throw new Exception("加密类型只支持AES");
}
// 执行加密
$enCryptContent = encrypt($apiParams['biz_content'], $this->encryptKey);
$apiParams['biz_content'] = $enCryptContent;
}
//签名
$sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams), $this->signType);
//系统参数放入GET请求串
$requestUrl = $this->gatewayUrl . "?";
foreach ($sysParams as $sysParamKey => $sysParamValue) {
$requestUrl .= "$sysParamKey=" . urlencode($this->characet($sysParamValue, $this->postCharset)) . "&";
}
$requestUrl = substr($requestUrl, 0, -1);
//发起HTTP请求
try {
$resp = $this->curl($requestUrl, $apiParams);
} catch (Exception $e) {
var_dump("HTTP_ERROR_" . $e->getCode(), $e->getMessage());
return false;
}
//解析AOP返回结果
$respWellFormed = false;
// 将返回结果转换本地文件编码
$r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp);
$signData = null;
if ("json" == $this->format) {
$respObject = json_decode($r);
if (null !== $respObject) {
$respWellFormed = true;
$signData = $this->parserJSONSignData($request, $resp, $respObject);
}
} else if ("xml" == $this->format) {
$disableLibxmlEntityLoader = libxml_disable_entity_loader(true);
$respObject = @ simplexml_load_string($resp);
if (false !== $respObject) {
$respWellFormed = true;
$signData = $this->parserXMLSignData($request, $resp);
}
libxml_disable_entity_loader($disableLibxmlEntityLoader);
}
//返回的HTTP文本不是标准JSON或者XML,记下错误日志
if (false === $respWellFormed) {
var_dump("HTTP_RESPONSE_NOT_WELL_FORMED_".$resp);
return false;
}
// 验签
$this->checkResponseSign($request, $signData, $resp, $respObject);
// 解密
if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){
if ("json" == $this->format) {
$resp = $this->encryptJSONSignSource($request, $resp);
// 将返回结果转换本地文件编码
$r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp);
$respObject = json_decode($r);
}else{
$resp = $this->encryptXMLSignSource($request, $resp);
$r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp);
$disableLibxmlEntityLoader = libxml_disable_entity_loader(true);
$respObject = @ simplexml_load_string($r);
libxml_disable_entity_loader($disableLibxmlEntityLoader);
}
}
return $respObject;
}
/**
* 生成用于调用收银台SDK的字符串
* @param $request SDK接口的请求参数对象
* @param $appAuthToken 三方应用授权token
* @return string
* @author guofa.tgf
*/
public function sdkExecute($request, $appAuthToken = null) {
$this->setupCharsets($request);
$params['app_id'] = $this->appId;
$params['method'] = $request->getApiMethodName();
$params['format'] = $this->format;
$params['sign_type'] = $this->signType;
$params['timestamp'] = date("Y-m-d H:i:s");
$params['alipay_sdk'] = $this->alipaySdkVersion;
$params['charset'] = $this->postCharset;
$version = $request->getApiVersion();
$params['version'] = $this->checkEmpty($version) ? $this->apiVersion : $version;
if ($notify_url = $request->getNotifyUrl()) {
$params['notify_url'] = $notify_url;
}
$params['app_auth_token'] = $appAuthToken;
$dict = $request->getApiParas();
$params['biz_content'] = $dict['biz_content'];
ksort($params);
$params['sign'] = $this->generateSign($params, $this->signType);
foreach ($params as &$value) {
$value = $this->characet($value, $params['charset']);
}
return http_build_query($params);
}
/**
* 页面提交执行方法
* @param $request 跳转类接口的request
* @param string $httpmethod 提交方式,两个值可选:post、get;
* @param null $appAuthToken 三方应用授权token
* @return 构建好的、签名后的最终跳转URL(GET)或String形式的form(POST)
* @throws Exception
*/
public function pageExecute($request, $httpmethod = "POST", $appAuthToken = null) {
$this->setupCharsets($request);
if (strcasecmp($this->fileCharset, $this->postCharset)) {
// writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为postCharset!");
throw new Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!");
}
$iv=null;
if(!$this->checkEmpty($request->getApiVersion())){
$iv=$request->getApiVersion();
}else{
$iv=$this->apiVersion;
}
//组装系统参数
$sysParams["app_id"] = $this->appId;
$sysParams["version"] = $iv;
$sysParams["format"] = $this->format;
$sysParams["sign_type"] = $this->signType;
$sysParams["method"] = $request->getApiMethodName();
$sysParams["timestamp"] = date("Y-m-d H:i:s");
$sysParams["alipay_sdk"] = $this->alipaySdkVersion;
$sysParams["terminal_type"] = $request->getTerminalType();
$sysParams["terminal_info"] = $request->getTerminalInfo();
$sysParams["prod_code"] = $request->getProdCode();
$sysParams["notify_url"] = $request->getNotifyUrl();
$sysParams["return_url"] = $request->getReturnUrl();
$sysParams["charset"] = $this->postCharset;
$sysParams["app_auth_token"] = $appAuthToken;
//获取业务参数
$apiParams = $request->getApiParas();
if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){
$sysParams["encrypt_type"] = $this->encryptType;
if ($this->checkEmpty($apiParams['biz_content'])) {
throw new Exception(" api request Fail! The reason : encrypt request is not supperted!");
}
if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) {
throw new Exception(" encryptType and encryptKey must not null! ");
}
if ("AES" != $this->encryptType) {
throw new Exception("加密类型只支持AES");
}
// 执行加密
$enCryptContent = encrypt($apiParams['biz_content'], $this->encryptKey);
$apiParams['biz_content'] = $enCryptContent;
}
$totalParams = array_merge($apiParams, $sysParams);
//待签名字符串
$preSignStr = $this->getSignContent($totalParams);
//签名
$totalParams["sign"] = $this->generateSign($totalParams, $this->signType);
if ("GET" == strtoupper($httpmethod)) {
//value做urlencode
$preString=$this->getSignContentUrlencode($totalParams);
//拼接GET请求串
$requestUrl = $this->gatewayUrl."?".$preString;
return $requestUrl;
} else {
//拼接表单字符串
return $this->buildRequestForm($totalParams);
}
}
public function generateSign($params, $signType = "RSA") {
return $this->sign($this->getSignContent($params), $signType);
}
public function rsaSign($params, $signType = "RSA") {
return $this->sign($this->getSignContent($params), $signType);
}
public function getSignContent($params) {
ksort($params);
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
// 转换成目标字符集
$v = $this->characet($v, $this->postCharset);
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . "$v";
} else {
$stringToBeSigned .= "&" . "$k" . "=" . "$v";
}
$i++;
}
}
unset ($k, $v);
return $stringToBeSigned;
}
//此方法对value做urlencode
public function getSignContentUrlencode($params) {
ksort($params);
$stringToBeSigned = "";
$i = 0;
foreach ($params as $k => $v) {
if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
// 转换成目标字符集
$v = $this->characet($v, $this->postCharset);
if ($i == 0) {
$stringToBeSigned .= "$k" . "=" . urlencode($v);
} else {
$stringToBeSigned .= "&" . "$k" . "=" . urlencode($v);
}
$i++;
}
}
unset ($k, $v);
return $stringToBeSigned;
}
protected function sign($data, $signType = "RSA") {
if($this->checkEmpty($this->rsaPrivateKeyFilePath)){
$priKey=$this->rsaPrivateKey;
$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($priKey, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
}else {
$priKey = file_get_contents($this->rsaPrivateKeyFilePath);
$res = openssl_get_privatekey($priKey);
}
($res) or die('您使用的私钥格式错误,请检查RSA私钥配置');
if ("RSA2" == $signType) {
openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);
} else {
openssl_sign($data, $sign, $res);
}
if(!$this->checkEmpty($this->rsaPrivateKeyFilePath)){
openssl_free_key($res);
}
$sign = base64_encode($sign);
return $sign;
}
/**
* RSA单独签名方法,未做字符串处理,字符串处理见getSignContent()
* @param $data 待签名字符串
* @param $privatekey 商户私钥,根据keyfromfile来判断是读取字符串还是读取文件,false:填写私钥字符串去回车和空格 true:填写私钥文件路径
* @param $signType 签名方式,RSA:SHA1 RSA2:SHA256
* @param $keyfromfile 私钥获取方式,读取字符串还是读文件
* @return string
* @author mengyu.wh
*/
public function alonersaSign($data,$privatekey,$signType = "RSA",$keyfromfile=false) {
if(!$keyfromfile){
$priKey=$privatekey;
$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($priKey, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
}
else{
$priKey = file_get_contents($privatekey);
$res = openssl_get_privatekey($priKey);
}
($res) or die('您使用的私钥格式错误,请检查RSA私钥配置');
if ("RSA2" == $signType) {
openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256);
} else {
openssl_sign($data, $sign, $res);
}
if($keyfromfile){
openssl_free_key($res);
}
$sign = base64_encode($sign);
return $sign;
}
protected function curl($url, $postFields = null) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FAILONERROR, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
$postBodyString = "";
$encodeArray = Array();
$postMultipart = false;
if (is_array($postFields) && 0 < count($postFields)) {
foreach ($postFields as $k => $v) {
if ("@" != substr($v, 0, 1)) //判断是不是文件上传
{
$postBodyString .= "$k=" . urlencode($this->characet($v, $this->postCharset)) . "&";
$encodeArray[$k] = $this->characet($v, $this->postCharset);
} else //文件上传用multipart/form-data,否则用www-form-urlencoded
{
$postMultipart = true;
$encodeArray[$k] = new \CURLFile(substr($v, 1));
}
}
unset ($k, $v);
curl_setopt($ch, CURLOPT_POST, true);
if ($postMultipart) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $encodeArray);
} else {
curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1));
}
}
if ($postMultipart) {
$headers = array('content-type: multipart/form-data;charset=' . $this->postCharset . ';boundary=' . $this->getMillisecond());
} else {
$headers = array('content-type: application/x-www-form-urlencoded;charset=' . $this->postCharset);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$reponse = curl_exec($ch);
if (curl_errno($ch)) {
throw new Exception(curl_error($ch), 0);
} else {
$httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (200 !== $httpStatusCode) {
throw new Exception($reponse, $httpStatusCode);
}
}
curl_close($ch);
return $reponse;
}
protected function getMillisecond() {
list($s1, $s2) = explode(' ', microtime());
return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000);
}
protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt) {
$localIp = isset ($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"] : "CLI";
$logger = new LtLogger;
$logger->conf["log_file"] = rtrim(AOP_SDK_WORK_DIR, '\\/') . '/' . "logs/aop_comm_err_" . $this->appId . "_" . date("Y-m-d") . ".log";
$logger->conf["separator"] = "^_^";
$logData = array(
date("Y-m-d H:i:s"),
$apiName,
$this->appId,
$localIp,
PHP_OS,
$this->alipaySdkVersion,
$requestUrl,
$errorCode,
str_replace("\n", "", $responseTxt)
);
$logger->log($logData);
}
/**
* 建立请求,以表单HTML形式构造(默认)
* @param $para_temp 请求参数数组
* @return 提交表单HTML文本
*/
protected function buildRequestForm($para_temp) {
$sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='".$this->gatewayUrl."?charset=".trim($this->postCharset)."' method='POST'>";
while (list ($key, $val) = each ($para_temp)) {
if (false === $this->checkEmpty($val)) {
//$val = $this->characet($val, $this->postCharset);
$val = str_replace("'","&apos;",$val);
//$val = str_replace("\"","&quot;",$val);
$sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>";
}
}
//submit按钮控件请不要含有name属性
$sHtml = $sHtml."<input type='submit' value='ok' style='display:none;''></form>";
$sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";
return $sHtml;
}
/**
* 转换字符集编码
* @param $data
* @param $targetCharset
* @return string
*/
function characet($data, $targetCharset) {
if (!empty($data)) {
$fileType = $this->fileCharset;
if (strcasecmp($fileType, $targetCharset) != 0) {
$data = mb_convert_encoding($data, $targetCharset, $fileType);
// $data = iconv($fileType, $targetCharset.'//IGNORE', $data);
}
}
return $data;
}
public function exec($paramsArray) {
if (!isset ($paramsArray["method"])) {
trigger_error("No api name passed");
}
$inflector = new LtInflector;
$inflector->conf["separator"] = ".";
$requestClassName = ucfirst($inflector->camelize(substr($paramsArray["method"], 7))) . "Request";
if (!class_exists($requestClassName)) {
trigger_error("No such api: " . $paramsArray["method"]);
}
$session = isset ($paramsArray["session"]) ? $paramsArray["session"] : null;
$req = new $requestClassName;
foreach ($paramsArray as $paraKey => $paraValue) {
$inflector->conf["separator"] = "_";
$setterMethodName = $inflector->camelize($paraKey);
$inflector->conf["separator"] = ".";
$setterMethodName = "set" . $inflector->camelize($setterMethodName);
if (method_exists($req, $setterMethodName)) {
$req->$setterMethodName ($paraValue);
}
}
return $this->execute($req, $session);
}
/**
* 校验$value是否非空
* if not set ,return true;
* if is null , return true;
**/
protected function checkEmpty($value) {
if (!isset($value))
return true;
if ($value === null)
return true;
if (trim($value) === "")
return true;
return false;
}
/** rsaCheckV1 & rsaCheckV2
* 验证签名
* 在使用本方法前,必须初始化AopClient且传入公钥参数。
* 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。
**/
public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType='RSA') {
$sign = $params['sign'];
$params['sign_type'] = null;
$params['sign'] = null;
return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType);
}
public function rsaCheckV2($params, $rsaPublicKeyFilePath, $signType='RSA') {
$sign = $params['sign'];
$params['sign'] = null;
return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath, $signType);
}
function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') {
if($this->checkEmpty($this->alipayPublicKey)){
$pubKey= $this->alipayrsaPublicKey;
$res = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($pubKey, 64, "\n", true) .
"\n-----END PUBLIC KEY-----";
}else {
//读取公钥文件
$pubKey = file_get_contents($rsaPublicKeyFilePath);
//转换为openssl格式密钥
$res = openssl_get_publickey($pubKey);
}
($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确');
//调用openssl内置方法验签,返回bool值
$result = FALSE;
if ("RSA2" == $signType) {
$result = (openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256)===1);
} else {
$result = (openssl_verify($data, base64_decode($sign), $res)===1);
}
if(!$this->checkEmpty($this->alipayPublicKey)) {
//释放资源
openssl_free_key($res);
}
return $result;
}
/**
* 在使用本方法前,必须初始化AopClient且传入公私钥参数。
* 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。
**/
public function checkSignAndDecrypt($params, $rsaPublicKeyPem, $rsaPrivateKeyPem, $isCheckSign, $isDecrypt, $signType='RSA') {
$charset = $params['charset'];
$bizContent = $params['biz_content'];
if ($isCheckSign) {
if (!$this->rsaCheckV2($params, $rsaPublicKeyPem, $signType)) {
echo "<br/>checkSign failure<br/>";
exit;
}
}
if ($isDecrypt) {
return $this->rsaDecrypt($bizContent, $rsaPrivateKeyPem, $charset);
}
return $bizContent;
}
/**
* 在使用本方法前,必须初始化AopClient且传入公私钥参数。
* 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。
**/
public function encryptAndSign($bizContent, $rsaPublicKeyPem, $rsaPrivateKeyPem, $charset, $isEncrypt, $isSign, $signType='RSA') {
// 加密,并签名
if ($isEncrypt && $isSign) {
$encrypted = $this->rsaEncrypt($bizContent, $rsaPublicKeyPem, $charset);
$sign = $this->sign($encrypted, $signType);
$response = "<?xml version=\"1.0\" encoding=\"$charset\"?><alipay><response>$encrypted</response><encryption_type>RSA</encryption_type><sign>$sign</sign><sign_type>$signType</sign_type></alipay>";
return $response;
}
// 加密,不签名
if ($isEncrypt && (!$isSign)) {
$encrypted = $this->rsaEncrypt($bizContent, $rsaPublicKeyPem, $charset);
$response = "<?xml version=\"1.0\" encoding=\"$charset\"?><alipay><response>$encrypted</response><encryption_type>$signType</encryption_type></alipay>";
return $response;
}
// 不加密,但签名
if ((!$isEncrypt) && $isSign) {
$sign = $this->sign($bizContent, $signType);
$response = "<?xml version=\"1.0\" encoding=\"$charset\"?><alipay><response>$bizContent</response><sign>$sign</sign><sign_type>$signType</sign_type></alipay>";
return $response;
}
// 不加密,不签名
$response = "<?xml version=\"1.0\" encoding=\"$charset\"?>$bizContent";
return $response;
}
/**
* 在使用本方法前,必须初始化AopClient且传入公私钥参数。
* 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。
**/
public function rsaEncrypt($data, $rsaPublicKeyPem, $charset) {
if($this->checkEmpty($this->alipayPublicKey)){
//读取字符串
$pubKey= $this->alipayrsaPublicKey;
$res = "-----BEGIN PUBLIC KEY-----\n" .
wordwrap($pubKey, 64, "\n", true) .
"\n-----END PUBLIC KEY-----";
}else {
//读取公钥文件
$pubKey = file_get_contents($rsaPublicKeyFilePath);
//转换为openssl格式密钥
$res = openssl_get_publickey($pubKey);
}
($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确');
$blocks = $this->splitCN($data, 0, 30, $charset);
$chrtext  = null;
$encodes  = array();
foreach ($blocks as $n => $block) {
if (!openssl_public_encrypt($block, $chrtext , $res)) {
echo "<br/>" . openssl_error_string() . "<br/>";
}
$encodes[] = $chrtext ;
}
$chrtext = implode(",", $encodes);
return base64_encode($chrtext);
}
/**
* 在使用本方法前,必须初始化AopClient且传入公私钥参数。
* 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。
**/
public function rsaDecrypt($data, $rsaPrivateKeyPem, $charset) {
if($this->checkEmpty($this->rsaPrivateKeyFilePath)){
//读字符串
$priKey=$this->rsaPrivateKey;
$res = "-----BEGIN RSA PRIVATE KEY-----\n" .
wordwrap($priKey, 64, "\n", true) .
"\n-----END RSA PRIVATE KEY-----";
}else {
$priKey = file_get_contents($this->rsaPrivateKeyFilePath);
$res = openssl_get_privatekey($priKey);
}
($res) or die('您使用的私钥格式错误,请检查RSA私钥配置');
//转换为openssl格式密钥
$decodes = explode(',', $data);
$strnull = "";
$dcyCont = "";
foreach ($decodes as $n => $decode) {
if (!openssl_private_decrypt($decode, $dcyCont, $res)) {
echo "<br/>" . openssl_error_string() . "<br/>";
}
$strnull .= $dcyCont;
}
return $strnull;
}
function splitCN($cont, $n = 0, $subnum, $charset) {
//$len = strlen($cont) / 3;
$arrr = array();
for ($i = $n; $i < strlen($cont); $i += $subnum) {
$res = $this->subCNchar($cont, $i, $subnum, $charset);
if (!empty ($res)) {
$arrr[] = $res;
}
}
return $arrr;
}
function subCNchar($str, $start = 0, $length, $charset = "gbk") {
if (strlen($str) <= $length) {
return $str;
}
$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
preg_match_all($re[$charset], $str, $match);
$slice = join("", array_slice($match[0], $start, $length));
return $slice;
}
function parserResponseSubCode($request, $responseContent, $respObject, $format) {
if ("json" == $format) {
$apiName = $request->getApiMethodName();
$rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX;
$errorNodeName = $this->ERROR_RESPONSE;
$rootIndex = strpos($responseContent, $rootNodeName);
$errorIndex = strpos($responseContent, $errorNodeName);
if ($rootIndex > 0) {
// 内部节点对象
$rInnerObject = $respObject->$rootNodeName;
} elseif ($errorIndex > 0) {
$rInnerObject = $respObject->$errorNodeName;
} else {
return null;
}
// 存在属性则返回对应值
if (isset($rInnerObject->sub_code)) {
return $rInnerObject->sub_code;
} else {
return null;
}
} elseif ("xml" == $format) {
// xml格式sub_code在同一层级
return $respObject->sub_code;
}
}
function parserJSONSignData($request, $responseContent, $responseJSON) {
$signData = new SignData();
$signData->sign = $this->parserJSONSign($responseJSON);
$signData->signSourceData = $this->parserJSONSignSource($request, $responseContent);
return $signData;
}
function parserJSONSignSource($request, $responseContent) {
$apiName = $request->getApiMethodName();
$rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX;
$rootIndex = strpos($responseContent, $rootNodeName);
$errorIndex = strpos($responseContent, $this->ERROR_RESPONSE);
if ($rootIndex > 0) {
return $this->parserJSONSource($responseContent, $rootNodeName, $rootIndex);
} else if ($errorIndex > 0) {
return $this->parserJSONSource($responseContent, $this->ERROR_RESPONSE, $errorIndex);
} else {
return null;
}
}
function parserJSONSource($responseContent, $nodeName, $nodeIndex) {
$signDataStartIndex = $nodeIndex + strlen($nodeName) + 2;
$signIndex = strrpos($responseContent, "\"" . $this->SIGN_NODE_NAME . "\"");
// 签名前-逗号
$signDataEndIndex = $signIndex - 1;
$indexLen = $signDataEndIndex - $signDataStartIndex;
if ($indexLen < 0) {
return null;
}
return substr($responseContent, $signDataStartIndex, $indexLen);
}
function parserJSONSign($responseJSon) {
return $responseJSon->sign;
}
function parserXMLSignData($request, $responseContent) {
$signData = new SignData();
$signData->sign = $this->parserXMLSign($responseContent);
$signData->signSourceData = $this->parserXMLSignSource($request, $responseContent);
return $signData;
}
function parserXMLSignSource($request, $responseContent) {
$apiName = $request->getApiMethodName();
$rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX;
$rootIndex = strpos($responseContent, $rootNodeName);
$errorIndex = strpos($responseContent, $this->ERROR_RESPONSE);
if ($rootIndex > 0) {
return $this->parserXMLSource($responseContent, $rootNodeName, $rootIndex);
} else if ($errorIndex > 0) {
return $this->parserXMLSource($responseContent, $this->ERROR_RESPONSE, $errorIndex);
} else {
return null;
}
}
function parserXMLSource($responseContent, $nodeName, $nodeIndex) {
$signDataStartIndex = $nodeIndex + strlen($nodeName) + 1;
$signIndex = strrpos($responseContent, "<" . $this->SIGN_NODE_NAME . ">");
// 签名前-逗号
$signDataEndIndex = $signIndex - 1;
$indexLen = $signDataEndIndex - $signDataStartIndex + 1;
if ($indexLen < 0) {
return null;
}
return substr($responseContent, $signDataStartIndex, $indexLen);
}
function parserXMLSign($responseContent) {
$signNodeName = "<" . $this->SIGN_NODE_NAME . ">";
$signEndNodeName = "</" . $this->SIGN_NODE_NAME . ">";
$indexOfSignNode = strpos($responseContent, $signNodeName);
$indexOfSignEndNode = strpos($responseContent, $signEndNodeName);
if ($indexOfSignNode < 0 || $indexOfSignEndNode < 0) {
return null;
}
$nodeIndex = ($indexOfSignNode + strlen($signNodeName));
$indexLen = $indexOfSignEndNode - $nodeIndex;
if ($indexLen < 0) {
return null;
}
// 签名
return substr($responseContent, $nodeIndex, $indexLen);
}
/**
* 验签
* @param $request
* @param $signData
* @param $resp
* @param $respObject
* @throws Exception
*/
public function checkResponseSign($request, $signData, $resp, $respObject) {
if (!$this->checkEmpty($this->alipayPublicKey) || !$this->checkEmpty($this->alipayrsaPublicKey)) {
if ($signData == null || $this->checkEmpty($signData->sign) || $this->checkEmpty($signData->signSourceData)) {
throw new Exception(" check sign Fail! The reason : signData is Empty");
}
// 获取结果sub_code
$responseSubCode = $this->parserResponseSubCode($request, $resp, $respObject, $this->format);
if (!$this->checkEmpty($responseSubCode) || ($this->checkEmpty($responseSubCode) && !$this->checkEmpty($signData->sign))) {
$checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType);
if (!$checkResult) {
if (strpos($signData->signSourceData, "\\/") > 0) {
$signData->signSourceData = str_replace("\\/", "/", $signData->signSourceData);
$checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType);
if (!$checkResult) {
throw new Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]");
}
} else {
throw new Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]");
}
}
}
}
}
private function setupCharsets($request) {
if ($this->checkEmpty($this->postCharset)) {
$this->postCharset = 'UTF-8';
}
$str = preg_match('/[\x80-\xff]/', $this->appId) ? $this->appId : print_r($request, true);
$this->fileCharset = mb_detect_encoding($str, "UTF-8, GBK") == 'UTF-8' ? 'UTF-8' : 'GBK';
}
// 获取加密内容
private function encryptJSONSignSource($request, $responseContent) {
$parsetItem = $this->parserEncryptJSONSignSource($request, $responseContent);
$bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex);
$bodyEndContent = substr($responseContent, $parsetItem->endIndex, strlen($responseContent) + 1 - $parsetItem->endIndex);
$bizContent = decrypt($parsetItem->encryptContent, $this->encryptKey);
return $bodyIndexContent . $bizContent . $bodyEndContent;
}
private function parserEncryptJSONSignSource($request, $responseContent) {
$apiName = $request->getApiMethodName();
$rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX;
$rootIndex = strpos($responseContent, $rootNodeName);
$errorIndex = strpos($responseContent, $this->ERROR_RESPONSE);
if ($rootIndex > 0) {
return $this->parserEncryptJSONItem($responseContent, $rootNodeName, $rootIndex);
} else if ($errorIndex > 0) {
return $this->parserEncryptJSONItem($responseContent, $this->ERROR_RESPONSE, $errorIndex);
} else {
return null;
}
}
private function parserEncryptJSONItem($responseContent, $nodeName, $nodeIndex) {
$signDataStartIndex = $nodeIndex + strlen($nodeName) + 2;
$signIndex = strpos($responseContent, "\"" . $this->SIGN_NODE_NAME . "\"");
// 签名前-逗号
$signDataEndIndex = $signIndex - 1;
if ($signDataEndIndex < 0) {
$signDataEndIndex = strlen($responseContent)-1 ;
}
$indexLen = $signDataEndIndex - $signDataStartIndex;
$encContent = substr($responseContent, $signDataStartIndex+1, $indexLen-2);
$encryptParseItem = new EncryptParseItem();
$encryptParseItem->encryptContent = $encContent;
$encryptParseItem->startIndex = $signDataStartIndex;
$encryptParseItem->endIndex = $signDataEndIndex;
return $encryptParseItem;
}
// 获取加密内容
private function encryptXMLSignSource($request, $responseContent) {
$parsetItem = $this->parserEncryptXMLSignSource($request, $responseContent);
$bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex);
$bodyEndContent = substr($responseContent, $parsetItem->endIndex, strlen($responseContent) + 1 - $parsetItem->endIndex);
$bizContent = decrypt($parsetItem->encryptContent, $this->encryptKey);
return $bodyIndexContent . $bizContent . $bodyEndContent;
}
private function parserEncryptXMLSignSource($request, $responseContent) {
$apiName = $request->getApiMethodName();
$rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX;
$rootIndex = strpos($responseContent, $rootNodeName);
$errorIndex = strpos($responseContent, $this->ERROR_RESPONSE);
if ($rootIndex > 0) {
return $this->parserEncryptXMLItem($responseContent, $rootNodeName, $rootIndex);
} else if ($errorIndex > 0) {
return $this->parserEncryptXMLItem($responseContent, $this->ERROR_RESPONSE, $errorIndex);
} else {
return null;
}
}
private function parserEncryptXMLItem($responseContent, $nodeName, $nodeIndex) {
$signDataStartIndex = $nodeIndex + strlen($nodeName) + 1;
$xmlStartNode="<".$this->ENCRYPT_XML_NODE_NAME.">";
$xmlEndNode="</".$this->ENCRYPT_XML_NODE_NAME.">";
$indexOfXmlNode=strpos($responseContent,$xmlEndNode);
if($indexOfXmlNode<0){
$item = new EncryptParseItem();
$item->encryptContent = null;
$item->startIndex = 0;
$item->endIndex = 0;
return $item;
}
$startIndex=$signDataStartIndex+strlen($xmlStartNode);
$bizContentLen=$indexOfXmlNode-$startIndex;
$bizContent=substr($responseContent,$startIndex,$bizContentLen);
$encryptParseItem = new EncryptParseItem();
$encryptParseItem->encryptContent = $bizContent;
$encryptParseItem->startIndex = $signDataStartIndex;
$encryptParseItem->endIndex = $indexOfXmlNode+strlen($xmlEndNode);
return $encryptParseItem;
}
function echoDebug($content) {
if ($this->debugInfo) {
echo "<br/>" . $content;
}
}
}

116
sdk/src/Kernel/AopRequest.php

@ -0,0 +1,116 @@
<?php
namespace EasyAlipay\Kernel;
class AopRequest
{
private $apiMethodName;
private $bizContent;
private $apiParas = array();
private $terminalType;
private $terminalInfo;
private $prodCode;
private $apiVersion="1.0";
private $notifyUrl;
private $returnUrl;
private $needEncrypt=false;
public function getApiMethodName()
{
return $this->apiMethodName;
}
public function setApiMethodName($apiMethodName)
{
$this->apiMethodName=$apiMethodName;
}
public function setBizContent($bizContent)
{
$this->bizContent = $bizContent;
$this->apiParas["biz_content"] = $bizContent;
}
public function getBizContent()
{
return $this->bizContent;
}
public function setNotifyUrl($notifyUrl)
{
$this->notifyUrl=$notifyUrl;
}
public function getNotifyUrl()
{
return $this->notifyUrl;
}
public function setReturnUrl($returnUrl)
{
$this->returnUrl=$returnUrl;
}
public function getReturnUrl()
{
return $this->returnUrl;
}
public function getApiParas()
{
return $this->apiParas;
}
public function getTerminalType()
{
return $this->terminalType;
}
public function setTerminalType($terminalType)
{
$this->terminalType = $terminalType;
}
public function getTerminalInfo()
{
return $this->terminalInfo;
}
public function setTerminalInfo($terminalInfo)
{
$this->terminalInfo = $terminalInfo;
}
public function getProdCode()
{
return $this->prodCode;
}
public function setProdCode($prodCode)
{
$this->prodCode = $prodCode;
}
public function setApiVersion($apiVersion)
{
$this->apiVersion=$apiVersion;
}
public function getApiVersion()
{
return $this->apiVersion;
}
public function setNeedEncrypt($needEncrypt)
{
$this->needEncrypt=$needEncrypt;
}
public function getNeedEncrypt()
{
return $this->needEncrypt;
}
}

27
sdk/src/Kernel/Config.php

@ -0,0 +1,27 @@
<?php
namespace EasyAlipay\Kernel;
class Config
{
public $config = [
//应用ID
'app_id' => '',
//支付宝公钥
'alipay_public_key' => '',
//商户私钥
'merchant_private_key' => '',
//网管地址
'gateway_url' => "https://openapi.alipay.com/gateway.do",
//异步通知地址
'notify_url' => "",
//同步跳转
'return_url' => "",
//编码格式
'charset' => "UTF-8",
//签名方式,默认为RSA2(RSA2048)
'sign_type' =>"RSA2",
// ...
];
}

26
sdk/src/Kernel/Providers/ConfigServiceProvider.php

@ -0,0 +1,26 @@
<?php
namespace EasyAlipay\Kernel\Providers;
use EasyAlipay\Kernel\Config;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ConfigServiceProvider implements ServiceProviderInterface
{
/**
* Registers services on the given container.
*
* This method should only be used to configure services and parameters.
* It should not get services.
*
* @param Container $pimple A container instance
*/
public function register(Container $pimple)
{
$pimple['config'] = function ($app) {
return $app->getConfig();
};
}
}

72
sdk/src/Kernel/ServiceContainer.php

@ -0,0 +1,72 @@
<?php
namespace EasyAlipay\Kernel;
use EasyAlipay\Kernel\Config;
use EasyAlipay\Kernel\Providers\ConfigServiceProvider;
use Pimple\Container;
/**
* Class ServiceContainer
*
* @property \EasyAlipay\Kernel\Config $config
*/
class ServiceContainer extends Container
{
/**
* @var array
*/
protected $providers = [];
/**
* @var array
*/
protected $defaultConfig = [];
/**
* @var array
*/
protected $userConfig = [];
/**
* Constructor.
*
* @param array $config
*/
public function __construct(array $config = [])
{
$this->registerProviders($this->getProviders());
parent::__construct();
$this->userConfig = $config;
$config = new config();
$this->defaultConfig = $config->config;
}
public function getConfig()
{
return array_replace_recursive($this->defaultConfig, $this->userConfig);
}
/**
* Return all providers.
*
* @return array
*/
public function getProviders()
{
return array_merge([
ConfigServiceProvider::class,
], $this->providers);
}
/**
* @param array $providers
*/
public function registerProviders(array $providers)
{
foreach ($providers as $provider) {
parent::register(new $provider());
}
}
}

11
sdk/src/Kernel/SignData.php

@ -0,0 +1,11 @@
<?php
namespace EasyAlipay\Kernel;
class SignData {
public $signSourceData=null;
public $sign=null;
}

184
sdk/src/Kernel/Support/Str.php

@ -0,0 +1,184 @@
<?php
namespace EasyAlipay\Kernel\Support;
use EasyAlipay\Kernel\Exceptions\RuntimeException;
/**
* Class Str.
*/
class Str
{
/**
* The cache of snake-cased words.
*
* @var array
*/
protected static $snakeCache = [];
/**
* The cache of camel-cased words.
*
* @var array
*/
protected static $camelCache = [];
/**
* The cache of studly-cased words.
*
* @var array
*/
protected static $studlyCache = [];
/**
* Convert a value to camel case.
*
* @param string $value
*
* @return string
*/
public static function camel($value)
{
if (isset(static::$camelCache[$value])) {
return static::$camelCache[$value];
}
return static::$camelCache[$value] = lcfirst(static::studly($value));
}
/**
* Generate a more truly "random" alpha-numeric string.
*
* @param int $length
*
* @return string
*
* @throws \RuntimeException
*/
public static function random($length = 16)
{
$string = '';
while (($len = strlen($string)) < $length) {
$size = $length - $len;
$bytes = static::randomBytes($size);
$string .= substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $size);
}
return $string;
}
/**
* Generate a more truly "random" bytes.
*
* @param int $length
*
* @return string
*
* @throws RuntimeException
*
* @codeCoverageIgnore
*
* @throws \Exception
*/
public static function randomBytes($length = 16)
{
if (function_exists('random_bytes')) {
$bytes = random_bytes($length);
} elseif (function_exists('openssl_random_pseudo_bytes')) {
$bytes = openssl_random_pseudo_bytes($length, $strong);
if (false === $bytes || false === $strong) {
throw new RuntimeException('Unable to generate random string.');
}
} else {
throw new RuntimeException('OpenSSL extension is required for PHP 5 users.');
}
return $bytes;
}
/**
* Generate a "random" alpha-numeric string.
*
* Should not be considered sufficient for cryptography, etc.
*
* @param int $length
*
* @return string
*/
public static function quickRandom($length = 16)
{
$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
return substr(str_shuffle(str_repeat($pool, $length)), 0, $length);
}
/**
* Convert the given string to upper-case.
*
* @param string $value
*
* @return string
*/
public static function upper($value)
{
return mb_strtoupper($value);
}
/**
* Convert the given string to title case.
*
* @param string $value
*
* @return string
*/
public static function title($value)
{
return mb_convert_case($value, MB_CASE_TITLE, 'UTF-8');
}
/**
* Convert a string to snake case.
*
* @param string $value
* @param string $delimiter
*
* @return string
*/
public static function snake($value, $delimiter = '_')
{
$key = $value.$delimiter;
if (isset(static::$snakeCache[$key])) {
return static::$snakeCache[$key];
}
if (!ctype_lower($value)) {
$value = strtolower(preg_replace('/(.)(?=[A-Z])/', '$1'.$delimiter, $value));
}
return static::$snakeCache[$key] = trim($value, '_');
}
/**
* Convert a value to studly caps case.
*
* @param string $value
*
* @return string
*/
public static function studly($value)
{
$key = $value;
if (isset(static::$studlyCache[$key])) {
return static::$studlyCache[$key];
}
$value = ucwords(str_replace(['-', '_'], ' ', $value));
return static::$studlyCache[$key] = str_replace(' ', '', $value);
}
}

215
sdk/src/Kernel/Traits/HasHttpRequests.php

@ -0,0 +1,215 @@
<?php
namespace EasyAlipay\Kernel\Traits;
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\HandlerStack;
use Psr\Http\Message\ResponseInterface;
trait HasHttpRequests
{
use ResponseCastable;
/**
* @var \GuzzleHttp\ClientInterface
*/
protected $httpClient;
/**
* @var array
*/
protected $middlewares = [];
/**
* @var \GuzzleHttp\HandlerStack
*/
protected $handlerStack;
/**
* @var array
*/
protected static $defaults = [
'curl' => [
CURLOPT_IPRESOLVE => CURL_IPRESOLVE_V4,
],
];
/**
* Set guzzle default settings.
*
* @param array $defaults
*/
public static function setDefaultOptions($defaults = [])
{
self::$defaults = $defaults;
}
/**
* Return current guzzle default settings.
*
* @return array
*/
public static function getDefaultOptions(): array
{
return self::$defaults;
}
/**
* Set GuzzleHttp\Client.
*
* @param \GuzzleHttp\ClientInterface $httpClient
*
* @return $this
*/
public function setHttpClient(ClientInterface $httpClient)
{
$this->httpClient = $httpClient;
return $this;
}
/**
* Return GuzzleHttp\ClientInterface instance.
*
* @return ClientInterface
*/
public function getHttpClient(): ClientInterface
{
if (!($this->httpClient instanceof ClientInterface)) {
if (property_exists($this, 'app') && $this->app['http_client']) {
$this->httpClient = $this->app['http_client'];
} else {
$this->httpClient = new Client(['handler' => HandlerStack::create($this->getGuzzleHandler())]);
}
}
return $this->httpClient;
}
/**
* Add a middleware.
*
* @param callable $middleware
* @param string|null $name
*
* @return $this
*/
public function pushMiddleware(callable $middleware, string $name = null)
{
if (!is_null($name)) {
$this->middlewares[$name] = $middleware;
} else {
array_push($this->middlewares, $middleware);
}
return $this;
}
/**
* Return all middlewares.
*
* @return array
*/
public function getMiddlewares(): array
{
return $this->middlewares;
}
/**
* Make a request.
*
* @param string $url
* @param string $method
* @param array $options
*
* @return \Psr\Http\Message\ResponseInterface|\EasyWeChat\Kernel\Support\Collection|array|object|string
*/
public function request($url, $method = 'GET', $options = []): ResponseInterface
{
$method = strtoupper($method);
$options = array_merge(self::$defaults, $options, ['handler' => $this->getHandlerStack()]);
$options = $this->fixJsonIssue($options);
if (property_exists($this, 'baseUri') && !is_null($this->baseUri)) {
$options['base_uri'] = $this->baseUri;
}
$response = $this->getHttpClient()->request($method, $url, $options);
$response->getBody()->rewind();
return $response;
}
/**
* @param \GuzzleHttp\HandlerStack $handlerStack
*
* @return $this
*/
public function setHandlerStack(HandlerStack $handlerStack)
{
$this->handlerStack = $handlerStack;
return $this;
}
/**
* Build a handler stack.
*
* @return \GuzzleHttp\HandlerStack
*/
public function getHandlerStack(): HandlerStack
{
if ($this->handlerStack) {
return $this->handlerStack;
}
$this->handlerStack = HandlerStack::create($this->getGuzzleHandler());
foreach ($this->middlewares as $name => $middleware) {
$this->handlerStack->push($middleware, $name);
}
return $this->handlerStack;
}
/**
* @param array $options
*
* @return array
*/
protected function fixJsonIssue(array $options): array
{
if (isset($options['json']) && is_array($options['json'])) {
$options['headers'] = array_merge($options['headers'] ?? [], ['Content-Type' => 'application/json']);
if (empty($options['json'])) {
$options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_FORCE_OBJECT);
} else {
$options['body'] = \GuzzleHttp\json_encode($options['json'], JSON_UNESCAPED_UNICODE);
}
unset($options['json']);
}
return $options;
}
/**
* Get guzzle handler.
*
* @return callable
*/
protected function getGuzzleHandler()
{
if (property_exists($this, 'app') && isset($this->app['guzzle_handler']) && is_string($this->app['guzzle_handler'])) {
$handler = $this->app['guzzle_handler'];
return new $handler();
}
return \GuzzleHttp\choose_handler();
}
}

21
sdk/src/Marketing/Application.php

@ -0,0 +1,21 @@
<?php
namespace EasyAlipay\Marketing;
use EasyAlipay\Kernel\ServiceContainer;
/**
* Class Application.
*
* @property \EasyAlipay\Marketing\Pass\Client $pass
*
*/
class Application extends ServiceContainer
{
/**
* @var array
*/
protected $providers = [
Pass\ServiceProvider::class,
];
}

80
sdk/src/Marketing/Model/AlipayPassInstanceAddContentBuilder.php

@ -0,0 +1,80 @@
<?php
namespace EasyAlipay\Marketing\Model;
/* *
* 功能:alipay.pass.instance.add (卡券实例发放接口)业务参数封装
*/
class AlipayPassInstanceAddContentBuilder
{
// 支付宝pass模版ID,即调用模板创建接口时返回的tpl_id
private $tplId;
// 模版动态参数信息:对应模板中$变量名$的动态参数,见模板创建接口返回值中的tpl_params字段
private $tplParams;
// Alipass添加对象识别类型:1–订单信息
private $recognitionType;
// 支付宝用户识别信息:uid发券组件。对接文档:https://docs.open.alipay.com/199/sy3hs4
private $recognitionInfo;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getTplId()
{
return $this->tplId;
}
public function setTplId($tplId)
{
$this->tplId = $tplId;
$this->bizContentarr['tpl_id'] = $tplId;
}
public function getTplParams()
{
return $this->tplParams;
}
public function setTplParams($tplParams)
{
$this->tplParams = $tplParams;
$this->bizContentarr['tpl_params'] = $tplParams;
}
public function getRecognitionType()
{
return $this->recognitionType;
}
public function setRecognitionType($recognitionType)
{
$this->recognitionType = $recognitionType;
$this->bizContentarr['recognition_type'] = $recognitionType;
}
public function getRecognitionInfo()
{
return $this->recognitionInfo;
}
public function setRecognitionInfo($recognitionInfo)
{
$this->recognitionInfo = $recognitionInfo;
$this->bizContentarr['recognition_info'] = $recognitionInfo;
}
}

109
sdk/src/Marketing/Model/AlipayPassInstanceUpdateContentBuilder.php

@ -0,0 +1,109 @@
<?php
namespace EasyAlipay\Marketing\Model;
/* *
* alipay.pass.instance.update(卡券实例更新接口)业务参数封装
*/
class AlipayPassInstanceUpdateContentBuilder
{
// 商户指定卡券唯一值,卡券JSON模板中fileInfo->serialNumber字段对应的值
private $serialNumber;
// 代理商代替商户发放卡券后,再代替商户更新卡券时,此值为商户的pid/appid
private $channelId;
// 模版动态参数信息:对应模板中$变量名$的动态参数,见模板创建接口返回值中的tpl_params字段
private $tplParams;
// 券状态,支持更新为USED、CLOSED两种状态
private $status;
// 核销码串值【当状态变更为USED时,建议传】。该值正常为模板中核销区域(Operation)对应的message值。
private $verifyCode;
// 核销方式,该值正常为模板中核销区域(Operation)对应的format值。verify_code和verify_type需同时传入。
private $verifyType;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getSerialNumber()
{
return $this->serialNumber;
}
public function setSerialNumber($serialNumber)
{
$this->serialNumber = $serialNumber;
$this->bizContentarr['serial_number'] = $serialNumber;
}
public function getChannelId()
{
return $this->channelId;
}
public function setChannelId($channelId)
{
$this->channelId = $channelId;
$this->bizContentarr['channel_id'] = $channelId;
}
public function getTplParams()
{
return $this->tplParams;
}
public function setTplParams($tplParams)
{
$this->tplParams = $tplParams;
$this->bizContentarr['tpl_params'] = $tplParams;
}
public function getStatus()
{
return $this->status;
}
public function setStatus($status)
{
$this->status = $status;
$this->bizContentarr['status'] = $status;
}
public function getVerifyCode()
{
return $this->verifyCode;
}
public function setVerifyCode($verifyCode)
{
$this->verifyCode = $verifyCode;
$this->bizContentarr['verify_code'] = $verifyCode;
}
public function getVerifyType()
{
return $this->verifyType;
}
public function setVerifyType($verifyType)
{
$this->verifyType = $verifyType;
$this->bizContentarr['verify_type'] = $verifyType;
}
}

50
sdk/src/Marketing/Model/AlipayPassTemplateAddContentBuilder.php

@ -0,0 +1,50 @@
<?php
namespace EasyAlipay\Marketing\Model;
/* *
* 功能:alipay.pass.template.add (卡券模板创建接口)业务参数封装
*/
class AlipayPassTemplateAddContentBuilder
{
// 商户用于控制模版的唯一性。(可以使用时间戳保证唯一性)
private $uniqueId;
// 模板内容信息,遵循JSON规范,详情参见tpl_content参数说明:https://doc.open.alipay.com/doc2/detail.htm?treeId=193&articleId=105249&docType=1#tpl_content
private $tplContent;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getUniqueId()
{
return $this->uniqueId;
}
public function setUniqueId($uniqueId)
{
$this->uniqueId = $uniqueId;
$this->bizContentarr['unique_id'] = $uniqueId;
}
public function getTplContent()
{
return $this->tplContent;
}
public function setTplContent($tplContent)
{
$this->tplContent = $tplContent;
$this->bizContentarr['tpl_content'] = $tplContent;
}
}

50
sdk/src/Marketing/Model/AlipayPassTemplateUpdateContentBuilder.php

@ -0,0 +1,50 @@
<?php
namespace EasyAlipay\Marketing\Model;
/* *
* 功能:alipay.pass.template.update (卡券模板更新接口)业务参数封装
*/
class AlipayPassTemplateUpdateContentBuilder
{
// 商户用于控制模版的唯一性。(可以使用时间戳保证唯一性)
private $tplId;
// 模板内容信息,遵循JSON规范,详情参见tpl_content参数说明:https://doc.open.alipay.com/doc2/detail.htm?treeId=193&articleId=105249&docType=1#tpl_content
private $tplContent;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getTplId()
{
return $this->tplId;
}
public function setTplId($tplId)
{
$this->tplId = $tplId;
$this->bizContentarr['tpl_id'] = $tplId;
}
public function getTplContent()
{
return $this->tplContent;
}
public function setTplContent($tplContent)
{
$this->tplContent = $tplContent;
$this->bizContentarr['tpl_content'] = $tplContent;
}
}

70
sdk/src/Marketing/Pass/Client.php

@ -0,0 +1,70 @@
<?php
namespace EasyAlipay\Marketing\Pass;
use EasyAlipay\Kernel\Support;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Kernel\Config;
use EasyAlipay\Marketing\Model\AlipayPassTemplateAddContentBuilder;
use EasyAlipay\Marketing\Model\AlipayPassTemplateUpdateContentBuilder;
use EasyAlipay\Marketing\Model\AlipayPassInstanceAddContentBuilder;
use EasyAlipay\Marketing\Model\AlipayPassInstanceUpdateContentBuilder;
class Client extends AopClient
{
public function createTemplate(string $unique_id,string $tpl_content)
{
//构造查询业务请求参数对象
$templateAddContentBuilder = new AlipayPassTemplateAddContentBuilder();
$templateAddContentBuilder->setUniqueId($unique_id);
$templateAddContentBuilder->setTplContent($tpl_content);
$request = new AopRequest ();
$request->setBizContent($templateAddContentBuilder->getBizContent());
$request->setApiMethodName("alipay.pass.template.add");
return($this->execute($request, NULL, NULL)) ;
}
public function updateTemplate(string $tpl_id,string $tpl_content)
{
//构造查询业务请求参数对象
$templateUpdateContentBuilder = new AlipayPassTemplateUpdateContentBuilder();
$templateUpdateContentBuilder->setTplId($tpl_id);
$templateUpdateContentBuilder->setTplContent($tpl_content);
$request = new AopRequest ();
$request->setBizContent($templateUpdateContentBuilder->getBizContent());
$request->setApiMethodName("alipay.pass.template.update");
return($this->execute($request, NULL, NULL)) ;
}
public function addInstance(string $tpl_id,string $tpl_params,string $recognition_type,string $recognition_info)
{
//构造查询业务请求参数对象
$addInstanceContentBuilder = new AlipayPassInstanceAddContentBuilder();
$addInstanceContentBuilder->getTplId($tpl_id);
$addInstanceContentBuilder->setTplParams($tpl_params);
$addInstanceContentBuilder->setRecognitionType($recognition_type);
$addInstanceContentBuilder->setRecognitionInfo($recognition_info);
$request = new AopRequest ();
$request->setBizContent($addInstanceContentBuilder->getBizContent());
$request->setApiMethodName("alipay.pass.instance.add");
return($this->execute($request, NULL, NULL)) ;
}
public function updateInstance(string $serial_number,string $channel_id,string $tpl_params,string $status,string $verify_code,string $verify_type)
{
//构造查询业务请求参数对象
$updateInstanceContentBuilder = new AlipayPassInstanceUpdateContentBuilder();
$updateInstanceContentBuilder->setSerialNumber($serial_number);
$updateInstanceContentBuilder->setChannelId($channel_id);
$updateInstanceContentBuilder->setTplParams($tpl_params);
$updateInstanceContentBuilder->setStatus($status);
$updateInstanceContentBuilder->setVerifyCode($verify_code);
$updateInstanceContentBuilder->setVerifyType($verify_type);
$request = new AopRequest ();
$request->setBizContent($updateInstanceContentBuilder->getBizContent());
$request->setApiMethodName("alipay.pass.instance.update");
return($this->execute($request, NULL, NULL)) ;
}
}

20
sdk/src/Marketing/Pass/ServiceProvider.php

@ -0,0 +1,20 @@
<?php
namespace EasyAlipay\Marketing\Pass;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
// var_dump($app);
$app['pass'] = function ($app) {
return new Client($app);
};
}
}

27
sdk/src/Mini/Application.php

@ -0,0 +1,27 @@
<?php
namespace EasyAlipay\Mini;
use EasyAlipay\Kernel\ServiceContainer;
/**
* Class Application.
*
* @property \EasyAlipay\Mini\Identification\Client $identification
* @property \EasyAlipay\Mini\Qrcode\Client $qrcode
* @property \EasyAlipay\Mini\TemplateMessage\Client $templateMessage
* @property \EasyAlipay\Mini\Risk\Client $risk
*
*/
class Application extends ServiceContainer
{
/**
* @var array
*/
protected $providers = [
Identification\ServiceProvider::class,
Qrcode\ServiceProvider::class,
TemplateMessage\ServiceProvider::class,
Risk\ServiceProvider::class,
];
}

39
sdk/src/Mini/Identification/Client.php

@ -0,0 +1,39 @@
<?php
namespace EasyAlipay\Mini\Identification;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Mini\Model\ZolozIdentificationCustomerCertifyzhubQueryContentBuilder;
use EasyAlipay\Mini\Model\ZolozIdentificationUserWebQueryContentBuilder;
class Client extends AopClient
{
public function queryCertifyzhub(string $biz_id,string $zim_id)
{
//构造查询业务请求参数对象
$zhubQueryContentBuilder = new ZolozIdentificationCustomerCertifyzhubQueryContentBuilder();
$zhubQueryContentBuilder->setBizId($biz_id);
$zhubQueryContentBuilder->setZimId($zim_id);
$zhubQueryContentBuilder->setFaceType(2);
$request = new AopRequest ();
$request->setBizContent($zhubQueryContentBuilder->getBizContent());
$request->setApiMethodName("zoloz.identification.customer.certifyzhub.query");
return($this->execute($request, NULL, NULL)) ;
}
public function queryUserWeb(string $biz_id,string $zim_id,string $extern_param)
{
//构造查询业务请求参数对象
$userWebQueryContentBuilder = new ZolozIdentificationUserWebQueryContentBuilder();
$userWebQueryContentBuilder->setBizId($biz_id);
$userWebQueryContentBuilder->setZimId($zim_id);
$userWebQueryContentBuilder->setExternParam($extern_param);
$request = new AopRequest ();
$request->setBizContent($userWebQueryContentBuilder->getBizContent());
$request->setApiMethodName("zoloz.identification.user.web.query");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/Mini/Identification/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\Mini\Identification;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['identification'] = function ($app) {
return new Client($app);
};
}
}

95
sdk/src/Mini/Model/AlipayOpenAppMiniTemplatemessageSendContentBuilder.php

@ -0,0 +1,95 @@
<?php
namespace EasyAlipay\Mini\Model;
/* *
* 功能:alipay.open.app.mini.templatemessage.send(小程序发送模板消息) 业务参数封装
* 前置条件:https://docs.alipay.com/mini/introduce/message
*/
class AlipayOpenAppMiniTemplatemessageSendContentBuilder
{
// 发送消息的用户userid,例如:2088102122458832
private $toUserId;
// 用户发生的交易行为的交易号,或者用户在小程序产生表单提交的表单号,用于信息发送的校验,例如:2017010100000000580012345678
private $formId;
// 用户申请的模板id号,固定的模板id会发送固定的消息,例如:MDI4YzIxMDE2M2I5YTQzYjUxNWE4MjA4NmU1MTIyYmM=
private $userTemplateId;
// 小程序的跳转页面,用于消息中心用户点击之后详细跳转的小程序页面,例如:page/component/index
private $page;
// 开发者需要发送模板消息中的自定义部分来替换模板的占位符,例如:{"keyword1": {"value" : "12:00"},"keyword2": {"value" : "20180808"},"keyword3": {"value" : "支付宝"}}
private $data;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getToUserId()
{
return $this->toUserId;
}
public function setToUserId($toUserId)
{
$this->toUserId = $toUserId;
$this->bizContentarr['to_user_id'] = $toUserId;
}
public function getFormId()
{
return $this->formId;
}
public function setFormId($formId)
{
$this->formId = $formId;
$this->bizContentarr['form_id'] = $formId;
}
public function getUserTemplateId()
{
return $this->userTemplateId;
}
public function setUserTemplateId($userTemplateId)
{
$this->userTemplateId = $userTemplateId;
$this->bizContentarr['user_template_id'] = $userTemplateId;
}
public function getPage()
{
return $this->page;
}
public function setPage($page)
{
$this->page = $page;
$this->bizContentarr['page'] = $page;
}
public function getData()
{
return $this->data;
}
public function setData($data)
{
$this->data = $data;
$this->bizContentarr['data'] = $data;
}
}
?>

66
sdk/src/Mini/Model/AlipayOpenAppQrcodeCreateContentBuilder.php

@ -0,0 +1,66 @@
<?php
namespace EasyAlipay\Mini\Model;
/* *
* 功能:alipay.open.app.qrcode.create (小程序生成推广二维码接口)业务参数封装
*/
class AlipayOpenAppQrcodeCreateContentBuilder
{
// 小程序中能访问到的页面路径,例如:page/component/component-pages/view/view
private $urlParam;
// 小程序的启动参数,打开小程序的query ,在小程序 onLaunch的方法中获取,例如:x=1
private $queryParam;
// 对应的二维码描述
private $describe;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getUrlParam()
{
return $this->urlParam;
}
public function setUrlParam($urlParam)
{
$this->urlParam = $urlParam;
$this->bizContentarr['url_param'] = $urlParam;
}
public function getQueryParam()
{
return $this->queryParam;
}
public function setQueryParam($queryParam)
{
$this->queryParam = $queryParam;
$this->bizContentarr['query_param'] = $queryParam;
}
public function getDescribe()
{
return $this->describe;
}
public function setDescribe($describe)
{
$this->describe = $describe;
$this->bizContentarr['describe'] = $describe;
}
}
?>

38
sdk/src/Mini/Model/AlipaySecurityRiskContentDetectContentBuilder.php

@ -0,0 +1,38 @@
<?php
namespace EasyAlipay\Mini\Model;
/* *
* 功能:alipay.security.risk.content.detect(小程序内容风险检测服务) 业务参数封装
*/
class AlipaySecurityRiskContentDetectContentBuilder
{
// 需要识别的文本,不要包含特殊字符以及双引号等可能引起json格式化错误问题的字符.
private $content;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getContent()
{
return $this->content;
}
public function setContent($content)
{
$this->content = $content;
$this->bizContentarr['content'] = $content;
}
}
?>

82
sdk/src/Mini/Model/ZolozIdentificationCustomerCertifyzhubQueryContentBuilder.php

@ -0,0 +1,82 @@
<?php
namespace EasyAlipay\Mini\Model;
/* *
* 功能:zoloz.identification.customer.certifyzhub.query (人脸结果查询接口)业务参数封装
* 前置条件:https://docs.alipay.com/mini/introduce/alipay-face-verify,需要先调用接口 my.ap.faceVerify,传入入参 bizId 和 bizType 唤起刷脸认证,认证结束后,通过回调函数得到认证结果。确保业务参数 biz_id 和 faceVerify 中的入参 bizId 一致,否则会导致查询失败。
*/
class ZolozIdentificationCustomerCertifyzhubQueryContentBuilder
{
// 业务单据号,用于核对和排查.需要先调用接口 my.ap.faceVerify,传入入参 bizId 和 bizType 唤起刷脸认证,认证结束后,通过回调函数得到认证结果。确保业务参数 biz_id 和 faceVerify 中的入参 bizId 一致,否则会导致查询失败。
private $bizId;
// 刷脸认证的唯一标识,用于查询认证结果
private $zimId;
// 0:匿名注册 1:匿名认证 2:实名认证
private $faceType;
// 是否需要返回人脸图片
private $needImg;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getBizId()
{
return $this->bizId;
}
public function setBizId($bizId)
{
$this->bizId = $bizId;
$this->bizContentarr['biz_id'] = $bizId;
}
public function getZimId()
{
return $this->zimId;
}
public function setZimId($zimId)
{
$this->zimId = $zimId;
$this->bizContentarr['zim_id'] = $zimId;
}
public function getFaceType()
{
return $this->faceType;
}
public function setFaceType($faceType)
{
$this->faceType = $faceType;
$this->bizContentarr['face_type'] = $faceType;
}
public function getNeedImg()
{
return $this->needImg;
}
public function setNeedImg($needImg)
{
$this->needImg = $needImg;
$this->bizContentarr['need_img'] = $needImg;
}
}
?>

68
sdk/src/Mini/Model/ZolozIdentificationUserWebQueryContentBuilder.php

@ -0,0 +1,68 @@
<?php
namespace EasyAlipay\Mini\Model;
/* *
* 功能:zoloz.identification.user.web.query(人脸采集结果查询接口)接口业务参数封装
* 前置条件:https://docs.alipay.com/mini/introduce/facecapture,调用JSAPI(faceVerify)唤起人脸采集,整个采集过程完全由人脸内部实现,采集完成后,通过回调函数返回采集结果。调用查询接口(zoloz.identification.user.web.query)获取可信的采集结果,如果采集成功,可通过此接口获取采集的人脸照片。
*/
class ZolozIdentificationUserWebQueryContentBuilder
{
// 商户请求的唯一标识,须与初始化传入的bizId保持一致。
private $bizId;
// 刷脸认证的唯一标识,用于查询认证结果
private $zimId;
// 扩展参数
private $externParam;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getBizId()
{
return $this->bizId;
}
public function setBizId($bizId)
{
$this->bizId = $bizId;
$this->bizContentarr['biz_id'] = $bizId;
}
public function getZimId()
{
return $this->zimId;
}
public function setZimId($zimId)
{
$this->zimId = $zimId;
$this->bizContentarr['zim_id'] = $zimId;
}
public function getExternParam()
{
return $this->externParam;
}
public function setExternParam($externParam)
{
$this->externParam = $externParam;
$this->bizContentarr['extern_param'] = $externParam;
}
}
?>

25
sdk/src/Mini/Qrcode/Client.php

@ -0,0 +1,25 @@
<?php
namespace EasyAlipay\Mini\Qrcode;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Mini\Model\AlipayOpenAppQrcodeCreateContentBuilder;
class Client extends AopClient
{
public function create(string $url_param,string $query_param,string $describe)
{
//构造查询业务请求参数对象
$qrcodeContentBuilder = new AlipayOpenAppQrcodeCreateContentBuilder();
$qrcodeContentBuilder->setUrlParam($url_param);
$qrcodeContentBuilder->setQueryParam($query_param);
$qrcodeContentBuilder->setDescribe($describe);
$request = new AopRequest ();
$request->setBizContent($qrcodeContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.app.qrcode.create");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/Mini/Qrcode/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\Mini\Qrcode;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['qrcode'] = function ($app) {
return new Client($app);
};
}
}

23
sdk/src/Mini/Risk/Client.php

@ -0,0 +1,23 @@
<?php
namespace EasyAlipay\Mini\Risk;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Mini\Model\AlipaySecurityRiskContentDetectContentBuilder;
class Client extends AopClient
{
public function detectContent(string $content)
{
//构造查询业务请求参数对象
$riskContentBuilder = new AlipaySecurityRiskContentDetectContentBuilder();
$riskContentBuilder->setContent($content);
$request = new AopRequest ();
$request->setBizContent($riskContentBuilder->getBizContent());
$request->setApiMethodName("alipay.security.risk.content.detect");
return($this->execute($request, NULL, NULL)) ;
}
}

20
sdk/src/Mini/Risk/ServiceProvider.php

@ -0,0 +1,20 @@
<?php
namespace EasyAlipay\Mini\Risk;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
/**
* {@inheritdoc}.
*/
public function register(Container $app)
{
// var_dump($app);
$app['risk'] = function ($app) {
return new Client($app);
};
}
}

26
sdk/src/Mini/TemplateMessage/Client.php

@ -0,0 +1,26 @@
<?php
namespace EasyAlipay\Mini\TemplateMessage;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Mini\Model\AlipayOpenAppMiniTemplatemessageSendContentBuilder;
class Client extends AopClient
{
public function send(string $to_user_id,string $form_id,string $user_template_id,string $page,string $data)
{
//构造查询业务请求参数对象
$sendContentBuilder = new AlipayOpenAppMiniTemplatemessageSendContentBuilder();
$sendContentBuilder->setToUserId($to_user_id);
$sendContentBuilder->setFormId($form_id);
$sendContentBuilder->setUserTemplateId($user_template_id);
$sendContentBuilder->setPage($page);
$sendContentBuilder->setData($data);
$request = new AopRequest ();
$request->setBizContent($sendContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.app.mini.templatemessage.send");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/Mini/TemplateMessage/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\Mini\TemplateMessage;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['templateMessage'] = function ($app) {
return new Client($app);
};
}
}

23
sdk/src/OpenPublic/Application.php

@ -0,0 +1,23 @@
<?php
namespace EasyAlipay\OpenPublic;
use EasyAlipay\Kernel\ServiceContainer;
/**
* Class Application.
*
* @property \EasyAlipay\OpenPublic\Message\Client $message
* @property \EasyAlipay\OpenPublic\Template\Client $template
*
*/
class Application extends ServiceContainer
{
/**
* @var array
*/
protected $providers = [
Message\ServiceProvider::class,
Template\ServiceProvider::class,
];
}

96
sdk/src/OpenPublic/Message/Client.php

@ -0,0 +1,96 @@
<?php
namespace EasyAlipay\OpenPublic\Message;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\OpenPublic\Model\AlipayOpenPublicMessageContentCreateContentBuilder;
use EasyAlipay\OpenPublic\Model\AlipayOpenPublicMessageContentModifyContentBuilder;
use EasyAlipay\OpenPublic\Model\AlipayOpenPublicMessageTotalSendContentBuilder;
use EasyAlipay\OpenPublic\Model\AlipayOpenPublicMessageQueryContentBuilder;
use EasyAlipay\OpenPublic\Model\AlipayOpenPublicLifeMsgRecallContentBuilder;
class Client extends AopClient
{
public function createImageTextContent(string $title,string $cover,string $content,string $could_comment,string $ctype,string $benefit,string $ext_tags,string $login_ids)
{
//构造查询业务请求参数对象
$createContentBuilder = new AlipayOpenPublicMessageContentCreateContentBuilder();
$createContentBuilder->setTitle($title);
$createContentBuilder->setCover($cover);
$createContentBuilder->setContent($content);
$createContentBuilder->setCouldComment($could_comment);
$createContentBuilder->setCtype($ctype);
$createContentBuilder->setBenefit($benefit);
$createContentBuilder->setExtTags($ext_tags);
$createContentBuilder->setLoginIds($login_ids);
$request = new AopRequest ();
$request->setBizContent($createContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.public.message.content.create");
return($this->execute($request, NULL, NULL)) ;
}
public function modifyImageTextContent(string $content_id,string $title,string $cover,string $content,string $could_comment,string $ctype,string $benefit,string $ext_tags,string $login_ids)
{
//构造查询业务请求参数对象
$modifyContentBuilder = new AlipayOpenPublicMessageContentModifyContentBuilder();
$modifyContentBuilder->setContentId($content_id);
$modifyContentBuilder->setCover($cover);
$modifyContentBuilder->setContent($content);
$modifyContentBuilder->setCouldComment($could_comment);
$modifyContentBuilder->setCtype($ctype);
$modifyContentBuilder->setBenefit($benefit);
$modifyContentBuilder->setExtTags($ext_tags);
$modifyContentBuilder->setLoginIds($login_ids);
$request = new AopRequest ();
$request->setBizContent($modifyContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.public.message.content.modify");
return($this->execute($request, NULL, NULL)) ;
}
public function sendText(string $text)
{
//构造查询业务请求参数对象
$totalSendContentBuilder = new AlipayOpenPublicMessageTotalSendContentBuilder();
$totalSendContentBuilder->setText($text);
$totalSendContentBuilder->setMsgType("text");
$request = new AopRequest ();
$request->setBizContent($totalSendContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.public.message.total.send");
return($this->execute($request, NULL, NULL)) ;
}
public function sendImageText(string $articles)
{
//构造查询业务请求参数对象
$totalSendContentBuilder = new AlipayOpenPublicMessageTotalSendContentBuilder();
$totalSendContentBuilder->setArticles($articles);
$totalSendContentBuilder->setMsgType("image-text");
$request = new AopRequest ();
$request->setBizContent($totalSendContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.public.message.total.send");
return($this->execute($request, NULL, NULL)) ;
}
public function query(string $message_ids)
{
//构造查询业务请求参数对象
$queryContentBuilder = new AlipayOpenPublicMessageQueryContentBuilder();
$queryContentBuilder->setMessageIds($message_ids);
$request = new AopRequest ();
$request->setBizContent($queryContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.public.message.query");
return($this->execute($request, NULL, NULL)) ;
}
public function recall(string $message_id)
{
//构造查询业务请求参数对象
$recallContentBuilder = new AlipayOpenPublicLifeMsgRecallContentBuilder();
$recallContentBuilder->setMessageId($message_id);
$request = new AopRequest ();
$request->setBizContent($recallContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.public.life.msg.recall");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/OpenPublic/Message/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\OpenPublic\Message;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['message'] = function ($app) {
return new Client($app);
};
}
}

38
sdk/src/OpenPublic/Model/AlipayOpenPublicLifeMsgRecallContentBuilder.php

@ -0,0 +1,38 @@
<?php
namespace EasyAlipay\OpenPublic\Model;
/* *
* 功能:alipay.open.public.life.msg.recall(生活号消息撤回接口)业务参数封装
*/
class AlipayOpenPublicLifeMsgRecallContentBuilder
{
// 消息id
private $messageId;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getMessageId()
{
return $this->messageId;
}
public function setMessageId($messageId)
{
$this->messageId = $messageId;
$this->bizContentarr['message_id'] = $messageId;
}
}
?>

129
sdk/src/OpenPublic/Model/AlipayOpenPublicMessageContentCreateContentBuilder.php

@ -0,0 +1,129 @@
<?php
namespace EasyAlipay\OpenPublic\Model;
/* *
* 功能:alipay.open.public.message.content.create (创建图文消息内容接口)业务参数封装
*/
class AlipayOpenPublicMessageContentCreateContentBuilder
{
// 标题
private $title;
// 封面图url, 尺寸为996*450,最大不超过3M,支持格式:.jpg、.png ,请先调用图片上传接口(https://docs.open.alipay.com/api_3/alipay.offline.material.image.upload)获得图片url
private $cover;
// 消息正文(支持富文本)
private $content;
// 是否允许评论 T:允许 F:不允许,默认不允许
private $couldComment;
// 图文类型 activity: 活动图文,不填默认普通图文
private $ctype;
// 活动利益点,图文类型ctype为activity类型时才需要传,最多10个字符
private $benefit;
// 关键词列表,英文逗号分隔,最多不超过5个
private $extTags;
// 可预览支付宝账号列表,需要预览时才填写, 英文逗号分隔,最多不超过10个
private $loginIds;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getTitle()
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
$this->bizContentarr['title'] = $title;
}
public function getCover()
{
return $this->cover;
}
public function setCover($cover)
{
$this->cover = $cover;
$this->bizContentarr['cover'] = $cover;
}
public function getContent()
{
return $this->content;
}
public function setContent($content)
{
$this->content = $content;
$this->bizContentarr['content'] = $content;
}
public function getCouldComment()
{
return $this->couldComment;
}
public function setCouldComment($couldComment)
{
$this->couldComment = $couldComment;
$this->bizContentarr['could_comment'] = $couldComment;
}
public function getCtype()
{
return $this->ctype;
}
public function setCtype($ctype)
{
$this->ctype = $ctype;
$this->bizContentarr['ctype'] = $ctype;
}
public function getBenefit()
{
return $this->benefit;
}
public function setBenefit($benefit)
{
$this->benefit = $benefit;
$this->bizContentarr['benefit'] = $benefit;
}
public function getExtTags()
{
return $this->extTags;
}
public function setExtTags($extTags)
{
$this->extTags = $extTags;
$this->bizContentarr['ext_tags'] = $extTags;
}
public function getLoginIds()
{
return $this->loginIds;
}
public function setLoginIds($loginIds)
{
$this->loginIds = $loginIds;
$this->bizContentarr['login_ids'] = $loginIds;
}
}
?>

142
sdk/src/OpenPublic/Model/AlipayOpenPublicMessageContentModifyContentBuilder.php

@ -0,0 +1,142 @@
<?php
namespace EasyAlipay\OpenPublic\Model;
/* *
* 功能:alipay.open.public.message.content.modify (更新图文消息内容接口)业务参数封装
*/
class AlipayOpenPublicMessageContentModifyContentBuilder
{
// 内容id
private $contentId;
// 标题
private $title;
// 封面图url, 尺寸为996*450,最大不超过3M,支持格式:.jpg、.png ,请先调用图片上传接口(https://docs.open.alipay.com/api_3/alipay.offline.material.image.upload)获得图片url
private $cover;
// 消息正文(支持富文本)
private $content;
// 是否允许评论 T:允许 F:不允许,默认不允许
private $couldComment;
// 图文类型 activity: 活动图文,不填默认普通图文
private $ctype;
// 活动利益点,图文类型ctype为activity类型时才需要传,最多10个字符
private $benefit;
// 关键词列表,英文逗号分隔,最多不超过5个
private $extTags;
// 可预览支付宝账号列表,需要预览时才填写,英文逗号分隔,最多不超过10个
private $loginIds;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getContentId()
{
return $this->contentId;
}
public function setContentId($contentId)
{
$this->contentId = $contentId;
$this->bizContentarr['content_id'] = $contentId;
}
public function getTitle()
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
$this->bizContentarr['title'] = $title;
}
public function getCover()
{
return $this->cover;
}
public function setCover($cover)
{
$this->cover = $cover;
$this->bizContentarr['cover'] = $cover;
}
public function getContent()
{
return $this->content;
}
public function setContent($content)
{
$this->content = $content;
$this->bizContentarr['content'] = $content;
}
public function getCouldComment()
{
return $this->couldComment;
}
public function setCouldComment($couldComment)
{
$this->couldComment = $couldComment;
$this->bizContentarr['could_comment'] = $couldComment;
}
public function getCtype()
{
return $this->ctype;
}
public function setCtype($ctype)
{
$this->ctype = $ctype;
$this->bizContentarr['ctype'] = $ctype;
}
public function getBenefit()
{
return $this->benefit;
}
public function setBenefit($benefit)
{
$this->benefit = $benefit;
$this->bizContentarr['benefit'] = $benefit;
}
public function getExtTags()
{
return $this->extTags;
}
public function setExtTags($extTags)
{
$this->extTags = $extTags;
$this->bizContentarr['ext_tags'] = $extTags;
}
public function getLoginIds()
{
return $this->loginIds;
}
public function setLoginIds($loginIds)
{
$this->loginIds = $loginIds;
$this->bizContentarr['login_ids'] = $loginIds;
}
}
?>

38
sdk/src/OpenPublic/Model/AlipayOpenPublicMessageQueryContentBuilder.php

@ -0,0 +1,38 @@
<?php
namespace EasyAlipay\OpenPublic\Model;
/* *
* 功能:alipay.open.public.message.query(生活号查询已发送消息接口)业务参数封装
*/
class AlipayOpenPublicMessageQueryContentBuilder
{
// 消息id集,限制最多传入20个message_id。message_id在调用群发、组发消息接口时会返回,需调用方保存
private $messageIds;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getMessageIds()
{
return $this->messageIds;
}
public function setMessageIds($messageIds)
{
$this->messageIds = $messageIds;
$this->bizContentarr['message_ids'] = $messageIds;
}
}
?>

53
sdk/src/OpenPublic/Model/AlipayOpenPublicMessageSingleSendContentBuilder.php

@ -0,0 +1,53 @@
<?php
namespace EasyAlipay\OpenPublic\Model;
/* *
* 功能:alipay.open.public.message.single.send(单发模板消息)业务参数封装
*/
class AlipayOpenPublicMessageSingleSendContentBuilder
{
// 消息接收用户的userid
private $toUserId;
// 消息模板相关参数,其中包括templateId模板ID和context模板上下文
private $template;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getToUserId()
{
return $this->toUserId;
}
public function setToUserId($toUserId)
{
$this->toUserId = $toUserId;
$this->bizContentarr['to_user_id'] = $toUserId;
}
public function getTemplate()
{
return $this->template;
}
public function setTemplate($template)
{
$this->template = $template;
$this->bizContentarr['template'] = $template;
}
}
?>

66
sdk/src/OpenPublic/Model/AlipayOpenPublicMessageTotalSendContentBuilder.php

@ -0,0 +1,66 @@
<?php
namespace EasyAlipay\OpenPublic\Model;
/* *
* 功能:alipay.open.public.message.total.send (群发消息)业务参数封装,详见:https://docs.open.alipay.com/api_6/alipay.open.public.message.total.send
*/
class AlipayOpenPublicMessageTotalSendContentBuilder
{
// 消息类型,text:文本消息,image-text:图文消息
private $msgType;
// 图文消息,当msg_type为image-text,该值必须设置
private $articles;
// 文本消息内容,当msg_type为text,必须设置该值
private $text;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getMsgType()
{
return $this->msgType;
}
public function setMsgType($msgType)
{
$this->msgType = $msgType;
$this->bizContentarr['msg_type'] = $msgType;
}
public function getArticles()
{
return $this->articles;
}
public function setArticles($articles)
{
$this->articles = $articles;
$this->bizContentarr['articles'] = $articles;
}
public function getText()
{
return $this->text;
}
public function setText($text)
{
$this->text = $text;
$this->bizContentarr['text'] = $text;
}
}
?>

38
sdk/src/OpenPublic/Model/AlipayOpenPublicTemplateMessageGetContentBuilder.php

@ -0,0 +1,38 @@
<?php
namespace EasyAlipay\OpenPublic\Model;
/* *
* 功能:alipay.open.public.template.message.get(消息模板领取接口)业务参数封装
*/
class AlipayOpenPublicTemplateMessageGetContentBuilder
{
// 消息母板id,登陆生活号后台(fuwu.alipay.com),点击菜单“模板消息”,点击“模板库”,即可看到相应模板的消息母板id
private $templateId;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getTemplateId()
{
return $this->templateId;
}
public function setTemplateId($templateId)
{
$this->templateId = $templateId;
$this->bizContentarr['template_id'] = $templateId;
}
}
?>

80
sdk/src/OpenPublic/Model/AlipayOpenPublicTemplateMessageIndustryModifyContentBuilder.php

@ -0,0 +1,80 @@
<?php
namespace EasyAlipay\OpenPublic\Model;
/* *
* 功能:alipay.open.public.template.message.industry.modify(模板消息行业设置修改接口)业务参数封装
*/
class AlipayOpenPublicTemplateMessageIndustryModifyContentBuilder
{
// 服务窗消息模板所属主行业一/二级名称,查看行业信息:https://alipay.open.taobao.com/doc2/detail?treeId=197&docType=1&articleId=105043
private $primaryIndustryName;
// 服务窗消息模板所属主行业一/二级编码
private $primaryIndustryCode;
// 服务窗消息模板所属副行业一/二级编码
private $secondaryIndustryCode;
// 服务窗消息模板所属副行业一/二级名称
private $secondaryIndustryName;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getPrimaryIndustryName()
{
return $this->primaryIndustryName;
}
public function setPrimaryIndustryName($primaryIndustryName)
{
$this->primaryIndustryName = $primaryIndustryName;
$this->bizContentarr['primary_industry_name'] = $primaryIndustryName;
}
public function getPrimaryIndustryCode()
{
return $this->primaryIndustryCode;
}
public function setPrimaryIndustryCode($primaryIndustryCode)
{
$this->primaryIndustryCode = $primaryIndustryCode;
$this->bizContentarr['primary_industry_code'] = $primaryIndustryCode;
}
public function getSecondaryIndustryCode()
{
return $this->secondaryIndustryCode;
}
public function setSecondaryIndustryCode($secondaryIndustryCode)
{
$this->secondaryIndustryCode = $secondaryIndustryCode;
$this->bizContentarr['secondary_industry_code'] = $secondaryIndustryCode;
}
public function getSecondaryIndustryName()
{
return $this->secondaryIndustryName;
}
public function setSecondaryIndustryName($secondaryIndustryName)
{
$this->secondaryIndustryName = $secondaryIndustryName;
$this->bizContentarr['secondary_industry_name'] = $secondaryIndustryName;
}
}
?>

46
sdk/src/OpenPublic/Template/Client.php

@ -0,0 +1,46 @@
<?php
namespace EasyAlipay\OpenPublic\Template;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\OpenPublic\Model\AlipayOpenPublicTemplateMessageGetContentBuilder;
use EasyAlipay\OpenPublic\Model\AlipayOpenPublicTemplateMessageIndustryModifyContentBuilder;
class Client extends AopClient
{
public function setIndustry(string $primary_industry_name,string $primary_industry_code,string $secondary_industry_code,string $secondary_industry_name)
{
//构造查询业务请求参数对象
$industryModifyContentBuilder = new AlipayOpenPublicTemplateMessageIndustryModifyContentBuilder();
$industryModifyContentBuilder->setPrimaryIndustryName($primary_industry_name);
$industryModifyContentBuilder->setPrimaryIndustryCode($primary_industry_code);
$industryModifyContentBuilder->setSecondaryIndustryCode($secondary_industry_code);
$industryModifyContentBuilder->setSecondaryIndustryName($secondary_industry_name);
$request = new AopRequest ();
$request->setBizContent($industryModifyContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.public.template.message.industry.modify");
return($this->execute($request, NULL, NULL)) ;
}
public function getIndustry()
{
//构造查询业务请求参数对象
$request = new AopRequest ();
$request->setApiMethodName("alipay.open.public.setting.category.query");
return($this->execute($request, NULL, NULL)) ;
}
public function getTemplate(string $template_id)
{
//构造查询业务请求参数对象
$getContentBuilder = new AlipayOpenPublicTemplateMessageGetContentBuilder();
$getContentBuilder->setTemplateId($template_id);
$request = new AopRequest ();
$request->setBizContent($getContentBuilder->getBizContent());
$request->setApiMethodName("alipay.open.public.template.message.get");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/OpenPublic/Template/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\OpenPublic\Template;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['template'] = function ($app) {
return new Client($app);
};
}
}

31
sdk/src/Payment/Application.php

@ -0,0 +1,31 @@
<?php
namespace EasyAlipay\Payment;
use EasyAlipay\Kernel\ServiceContainer;
/**
* Class Application.
*
* @property \EasyAlipay\Payment\Cancel\Client $cancel
* @property \EasyAlipay\Payment\Close\Client $close
* @property \EasyAlipay\Payment\Create\Client $create
* @property \EasyAlipay\Payment\Pay\Client $pay
* @property \EasyAlipay\Payment\Query\Client $query
* @property \EasyAlipay\Payment\Refund\Client $refund
*
*/
class Application extends ServiceContainer
{
/**
* @var array
*/
protected $providers = [
Cancel\ServiceProvider::class,
Close\ServiceProvider::class,
Create\ServiceProvider::class,
Pay\ServiceProvider::class,
Query\ServiceProvider::class,
Refund\ServiceProvider::class,
];
}

21
sdk/src/Payment/Cancel/Client.php

@ -0,0 +1,21 @@
<?php
namespace EasyAlipay\Payment\Cancel;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Payment\Model\AlipayTradeCancelContentBuilder;
class Client extends AopClient
{
public function cancel(string $out_trade_no)
{
//构造查询业务请求参数对象
$cancelContentBuilder = new AlipayTradeCancelContentBuilder();
$cancelContentBuilder->setOutTradeNo($out_trade_no);
$request = new AopRequest ();
$request->setBizContent($cancelContentBuilder->getBizContent());
$request->setApiMethodName("alipay.trade.cancel");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/Payment/Cancel/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\Payment\Cancel;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['cancel'] = function ($app) {
return new Client($app);
};
}
}

21
sdk/src/Payment/Close/Client.php

@ -0,0 +1,21 @@
<?php
namespace EasyAlipay\Payment\Close;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Payment\Model\AlipayTradeCloseContentBuilder;
class Client extends AopClient
{
public function close(string $out_trade_no)
{
//构造查询业务请求参数对象
$closeContentBuilder = new AlipayTradeCloseContentBuilder();
$closeContentBuilder->setOutTradeNo($out_trade_no);
$request = new AopRequest ();
$request->setBizContent($closeContentBuilder->getBizContent());
$request->setApiMethodName("alipay.trade.close");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/Payment/Close/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\Payment\Close;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['close'] = function ($app) {
return new Client($app);
};
}
}

24
sdk/src/Payment/Create/Client.php

@ -0,0 +1,24 @@
<?php
namespace EasyAlipay\Payment\Create;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Payment\Model\AlipayTradeCreateContentBuilder;
class Client extends AopClient
{
public function create(string $subject,string $out_trade_no,string $total_amount,string $buyer_id)
{
//构造查询业务请求参数对象
$createContentBuilder = new AlipayTradeCreateContentBuilder();
$createContentBuilder->setSubject($subject);
$createContentBuilder->setOutTradeNo($out_trade_no);
$createContentBuilder->setTotalAmount($total_amount);
$createContentBuilder->setBuyerId($buyer_id);
$request = new AopRequest ();
$request->setBizContent($createContentBuilder->getBizContent());
$request->setApiMethodName("alipay.trade.create");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/Payment/Create/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\Payment\Create;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['create'] = function ($app) {
return new Client($app);
};
}
}

52
sdk/src/Payment/Model/AlipayTradeCancelContentBuilder.php

@ -0,0 +1,52 @@
<?php
namespace EasyAlipay\Payment\Model;
/* *
* 功能:alipay.trade.cancel (统一收单交易关闭接口)业务参数封装
*/
class AlipayTradeCancelContentBuilder
{
// 商户订单号.
private $outTradeNo;
// 支付宝交易号
private $tradeNo;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getTradeNo()
{
return $this->tradeNo;
}
public function setTradeNo($tradeNo)
{
$this->tradeNo = $tradeNo;
$this->bizContentarr['trade_no'] = $tradeNo;
}
public function getOutTradeNo()
{
return $this->outTradeNo;
}
public function setOutTradeNo($outTradeNo)
{
$this->outTradeNo = $outTradeNo;
$this->bizContentarr['out_trade_no'] = $outTradeNo;
}
}
?>

66
sdk/src/Payment/Model/AlipayTradeCloseContentBuilder.php

@ -0,0 +1,66 @@
<?php
namespace EasyAlipay\Payment\Model;
/* *
* 功能:alipay.trade.close (统一收单交易关闭接口)业务参数封装
*/
class AlipayTradeCloseContentBuilder
{
// 商户订单号.
private $outTradeNo;
// 支付宝交易号
private $tradeNo;
//卖家端自定义的的操作员 ID
private $operatorId;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getTradeNo()
{
return $this->tradeNo;
}
public function setTradeNo($tradeNo)
{
$this->tradeNo = $tradeNo;
$this->bizContentarr['trade_no'] = $tradeNo;
}
public function getOutTradeNo()
{
return $this->outTradeNo;
}
public function setOutTradeNo($outTradeNo)
{
$this->outTradeNo = $outTradeNo;
$this->bizContentarr['out_trade_no'] = $outTradeNo;
}
public function getOperatorId()
{
return $this->operatorId;
}
public function setOperatorId($operatorId)
{
$this->operatorId = $operatorId;
$this->bizContentarr['operator_id'] = $operatorId;
}
}
?>

92
sdk/src/Payment/Model/AlipayTradeCreateContentBuilder.php

@ -0,0 +1,92 @@
<?php
namespace EasyAlipay\Payment\Model;
/* *
* 功能:alipay.trade.create (统一收单交易关闭接口)业务参数封装
*/
class AlipayTradeCreateContentBuilder
{
// 商户订单号.
private $outTradeNo;
// 订单标题,粗略描述用户的支付目的。
private $subject;
// 订单总金额,整形,此处单位为元,精确到小数点后2位,不能超过1亿元
private $totalAmount;
//买家的支付宝唯一用户号(2088开头的16位纯数字)
private $buyerId;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getTradeNo()
{
return $this->tradeNo;
}
public function setTradeNo($tradeNo)
{
$this->tradeNo = $tradeNo;
$this->bizContentarr['trade_no'] = $tradeNo;
}
public function getOutTradeNo()
{
return $this->outTradeNo;
}
public function setOutTradeNo($outTradeNo)
{
$this->outTradeNo = $outTradeNo;
$this->bizContentarr['out_trade_no'] = $outTradeNo;
}
public function setSubject($subject)
{
$this->subject = $subject;
$this->bizContentarr['subject'] = $subject;
}
public function getSubject()
{
return $this->subject;
}
public function setTotalAmount($totalAmount)
{
$this->totalAmount = $totalAmount;
$this->bizContentarr['total_amount'] = $totalAmount;
}
public function getTotalAmount()
{
return $this->totalAmount;
}
public function getBuyerId()
{
return $this->buyerId;
}
public function setBuyerId($buyerId)
{
$this->buyerId = $buyerId;
$this->bizContentarr['buyer_id'] = $buyerId;
}
}
?>

96
sdk/src/Payment/Model/AlipayTradePayContentBuilder.php

@ -0,0 +1,96 @@
<?php
namespace EasyAlipay\Payment\Model;
/* *
* 功能:alipay.trade.pay(统一收单交易支付接口)接口业务参数封装
*/
class AlipayTradePayContentBuilder
{
// 商户订单号.
private $outTradeNo;
// 支付场景
private $scene;
// 支付授权码
private $authCode;
// 订单标题,粗略描述用户的支付目的。
private $subject;
// 订单总金额,整形,此处单位为元,精确到小数点后2位,不能超过1亿元
private $totalAmount;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getOutTradeNo()
{
return $this->outTradeNo;
}
public function setOutTradeNo($outTradeNo)
{
$this->outTradeNo = $outTradeNo;
$this->bizContentarr['out_trade_no'] = $outTradeNo;
}
public function getScene()
{
return $this->scene;
}
public function setScene($scene)
{
$this->scene = $scene;
$this->bizContentarr['scene'] = $scene;
}
public function getAuthCode()
{
return $this->authCode;
}
public function setAuthCode($authCode)
{
$this->authCode = $authCode;
$this->bizContentarr['authCode'] = $authCode;
}
public function setSubject($subject)
{
$this->subject = $subject;
$this->bizContentarr['subject'] = $subject;
}
public function getSubject()
{
return $this->subject;
}
public function setTotalAmount($totalAmount)
{
$this->totalAmount = $totalAmount;
$this->bizContentarr['total_amount'] = $totalAmount;
}
public function getTotalAmount()
{
return $this->totalAmount;
}
}
?>

66
sdk/src/Payment/Model/AlipayTradeQueryContentBuilder.php

@ -0,0 +1,66 @@
<?php
namespace EasyAlipay\Payment\Model;
/* *
* 功能:alipay.trade.query(统一收单线下交易查询)接口业务参数封装
*/
class AlipayTradeQueryContentBuilder
{
// 商户订单号
private $outTradeNo;
// 支付宝交易号
private $tradeNo;
//银行间联模式下有用,其它场景请不要使用,双联通过该参数指定需要查询的交易所属收单机构的pid;
private $orgPid;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getTradeNo()
{
return $this->tradeNo;
}
public function setTradeNo($tradeNo)
{
$this->tradeNo = $tradeNo;
$this->bizContentarr['trade_no'] = $tradeNo;
}
public function getOutTradeNo()
{
return $this->outTradeNo;
}
public function setOutTradeNo($outTradeNo)
{
$this->outTradeNo = $outTradeNo;
$this->bizContentarr['out_trade_no'] = $outTradeNo;
}
public function getOrgPid()
{
return $this->orgPid;
}
public function setOrgPid($orgPid)
{
$this->orgPid = $orgPid;
$this->bizContentarr['org_pid'] = $orgPid;
}
}
?>

66
sdk/src/Payment/Model/AlipayTradeRefundContentBuilder.php

@ -0,0 +1,66 @@
<?php
namespace EasyAlipay\Payment\Model;
/* *
* 功能:alipay.trade.refund(统一收单交易退款接口)接口业务参数封装
*/
class AlipayTradeRefundContentBuilder
{
// 商户订单号.
private $outTradeNo;
// 支付宝交易号
private $tradeNo;
// 退款的金额
private $refundAmount;
private $bizContentarr = array();
private $bizContent = NULL;
public function getBizContent()
{
if(!empty($this->bizContentarr)){
$this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE);
}
return $this->bizContent;
}
public function getTradeNo()
{
return $this->tradeNo;
}
public function setTradeNo($tradeNo)
{
$this->tradeNo = $tradeNo;
$this->bizContentarr['trade_no'] = $tradeNo;
}
public function getOutTradeNo()
{
return $this->outTradeNo;
}
public function setOutTradeNo($outTradeNo)
{
$this->outTradeNo = $outTradeNo;
$this->bizContentarr['out_trade_no'] = $outTradeNo;
}
public function getRefundAmount()
{
return $this->refundAmount;
}
public function setRefundAmount($refundAmount)
{
$this->refundAmount = $refundAmount;
$this->bizContentarr['refund_amount'] = $refundAmount;
}
}
?>

25
sdk/src/Payment/Pay/Client.php

@ -0,0 +1,25 @@
<?php
namespace EasyAlipay\Payment\Pay;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Payment\Model\AlipayTradePayContentBuilder;
class Client extends AopClient
{
public function pay(string $subject,string $out_trade_no,string $total_amount,string $auth_code)
{
//构造查询业务请求参数对象
$payContentBuilder = new AlipayTradePayContentBuilder();
$payContentBuilder->setSubject($subject);
$payContentBuilder->setOutTradeNo($out_trade_no);
$payContentBuilder->setTotalAmount($total_amount);
$payContentBuilder->setScene("bar_code");
$payContentBuilder->setAuthCode($auth_code);
$request = new AopRequest ();
$request->setBizContent($payContentBuilder->getBizContent());
$request->setApiMethodName("alipay.trade.pay");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/Payment/Pay/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\Payment\Pay;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['pay'] = function ($app) {
return new Client($app);
};
}
}

23
sdk/src/Payment/Query/Client.php

@ -0,0 +1,23 @@
<?php
namespace EasyAlipay\Payment\Query;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Payment\Model\AlipayTradeQueryContentBuilder;
class Client extends AopClient
{
public function query(string $out_trade_no)
{
//构造查询业务请求参数对象
$queryContentBuilder = new AlipayTradeQueryContentBuilder();
$queryContentBuilder->setOutTradeNo($out_trade_no);
$request = new AopRequest ();
$request->setBizContent($queryContentBuilder->getBizContent());
$request->setApiMethodName("alipay.trade.query");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/Payment/Query/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\Payment\Query;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['query'] = function ($app) {
return new Client($app);
};
}
}

22
sdk/src/Payment/Refund/Client.php

@ -0,0 +1,22 @@
<?php
namespace EasyAlipay\Payment\Refund;
use EasyAlipay\Kernel\AopClient;
use EasyAlipay\Kernel\AopRequest;
use EasyAlipay\Payment\Model\AlipayTradeRefundContentBuilder;
class Client extends AopClient
{
public function refund(string $out_trade_no,string $refund_amount)
{
//构造查询业务请求参数对象
$refundContentBuilder = new AlipayTradeRefundContentBuilder();
$refundContentBuilder->setOutTradeNo($out_trade_no);
$refundContentBuilder->setRefundAmount($refund_amount);
$request = new AopRequest ();
$request->setBizContent($refundContentBuilder->getBizContent());
$request->setApiMethodName("alipay.trade.refund");
return($this->execute($request, NULL, NULL)) ;
}
}

16
sdk/src/Payment/Refund/ServiceProvider.php

@ -0,0 +1,16 @@
<?php
namespace EasyAlipay\Payment\Refund;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
class ServiceProvider implements ServiceProviderInterface
{
public function register(Container $app)
{
$app['refund'] = function ($app) {
return new Client($app);
};
}
}

24
sdk/tests/test.php

@ -0,0 +1,24 @@
<?php
require __DIR__.'/../vendor/autoload.php';
use EasyAlipay\Factory;
$options = [
'app_id' => '2016051900098985',
'gateway_url' => "https://openapi.alipaydev.com/gateway.do",//示例中使用的是沙箱环境网关,线上gateway_url:https://openapi.alipay.com/gateway.do
'sign_type' => "RSA",
'charset' => "UTF-8",
'alipay_public_key' => 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIgHnOn7LLILlKETd6BFRJ0GqgS2Y3mn1wMQmyh9zEyWlz5p1zrahRahbXAfCfSqshSNfqOmAQzSHRVjCqjsAw1jyqrXaPdKBmr90DIpIxmIyKXv4GGAkPyJ/6FTFY99uhpiq0qadD/uSzQsefWo0aTvP/65zi3eof7TcZ32oWpwIDAQAB',
'merchant_private_key' => 'MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJlJ7tgZ4vI2Nnxt7DzznbhVwGN8INQ1s/ZnXYgtRMmvbNKLTHZ1SbRmiAKixn3TDbzkHMvo0jY7ldb7puqUJUKZuKfVwaRcAYgI6NamflqtTDWhSq+hPZ5ZrB36lx7N7AxlMD038WvJC5pHbld06DDxhlUslS3pJCGrB9P6HO0RAgMBAAECgYArrFTQXQ+70pZTfT4BX6dgDY5yybrQuzw6x9huI/elPsXSdr2iQmhtbYjyt022K5uOZa+OqRa7PN7EEY7M5sh2cFRX5P77o2vN61Gwklc11iaJIpPgUOZUmAG8jHnj3lf40+YtMwdPxQfbiZ36UOebQYPc8iuJczUNoVtSPP3IwQJBAMZzCSV7pjTQ4mp2MNT/h3/5ZhaQnqlO4wm0etekKDDTrpvUlSN8MjRjhyJhRvulKd0zUdfrjASEUjZhsZydEAMCQQDFviiKquR0TgYK0eircDwR89XHUBKoblPLYi/GSdPXSL92AzyvDIyNF/GPwHOkc1c+BA/4ocuW/T+u4KfYWBRbAkEAvV/Rfp98gDJFnmqjNt+SIqGQtj/T6KWLKxu7jkTsxYt7uOEoYPCHyE6iCkDiSAnY5Wmv1GjG+Rh8i8C2iUmomQJBAIaeVmtQvAaRt3tWO9e6qKpwHXF7Cbiwo0sqpOuRBy7gz7c/rOhe2rCTRFhg5FloTFRj35ucSkWYUupy9tFJ5VECQDyK++bn0ZpJG/HRNJHvuKOSUM8U6LSvQrTGpyvKlj5wLcOniDAYEcCzkapY/wHAUMshD0eoFY2X3F/3PcuIgW4=',
// ...
];
//本测试用例提供的是沙箱环境的配置信息,线上调用请更改为自己应用对应的信息
//app_id,alipay_public_key(支付宝公钥),merchant_private_key(应用私钥)为必填项
//gateway_url不设置就默认线上网关
//sign_type 不设置就默认RSA2(目前线上环境支持RSA)
//charset 不设置就默认UTF-8
//接口测试用例
$app = Factory::payment($options);
var_dump($app['query']->query("1561946980099_demo_pay"));
Loading…
Cancel
Save