Repository: shulidata/easyalipay Branch: master Commit: 4013a1e39556 Files: 86 Total size: 139.5 KB Directory structure: gitextract_c_6jyia7/ ├── .gitignore ├── LICENSE.md ├── NOTICE.md ├── README.md ├── composer.json ├── docs/ │ ├── Base/ │ │ └── Oauth.md │ ├── Marketing/ │ │ └── Pass.md │ ├── Mini/ │ │ ├── Identification.md │ │ ├── Qrcode.md │ │ ├── Risk.md │ │ └── TemplateMessage.md │ ├── OpenLife/ │ │ ├── Message.md │ │ └── Template.md │ └── Payment/ │ ├── Cancel.md │ ├── Close.md │ ├── Create.md │ ├── Pay.md │ ├── Query.md │ └── Refund.md ├── src/ │ ├── Base/ │ │ ├── Application.php │ │ ├── Model/ │ │ │ └── AlipaySystemOauthTokenRequest.php │ │ └── Oauth/ │ │ ├── Client.php │ │ └── ServiceProvider.php │ ├── Factory.php │ ├── Kernel/ │ │ ├── AopClient.php │ │ ├── AopRequest.php │ │ ├── Config.php │ │ ├── Providers/ │ │ │ └── ConfigServiceProvider.php │ │ ├── ServiceContainer.php │ │ ├── SignData.php │ │ ├── Support/ │ │ │ └── Str.php │ │ └── Traits/ │ │ └── HasHttpRequests.php │ ├── Marketing/ │ │ ├── Application.php │ │ ├── Model/ │ │ │ ├── AlipayPassInstanceAddContentBuilder.php │ │ │ ├── AlipayPassInstanceUpdateContentBuilder.php │ │ │ ├── AlipayPassTemplateAddContentBuilder.php │ │ │ └── AlipayPassTemplateUpdateContentBuilder.php │ │ └── Pass/ │ │ ├── Client.php │ │ └── ServiceProvider.php │ ├── Mini/ │ │ ├── Application.php │ │ ├── Identification/ │ │ │ ├── Client.php │ │ │ └── ServiceProvider.php │ │ ├── Model/ │ │ │ ├── AlipayOpenAppMiniTemplatemessageSendContentBuilder.php │ │ │ ├── AlipayOpenAppQrcodeCreateContentBuilder.php │ │ │ ├── AlipaySecurityRiskContentDetectContentBuilder.php │ │ │ ├── ZolozIdentificationCustomerCertifyzhubQueryContentBuilder.php │ │ │ └── ZolozIdentificationUserWebQueryContentBuilder.php │ │ ├── Qrcode/ │ │ │ ├── Client.php │ │ │ └── ServiceProvider.php │ │ ├── Risk/ │ │ │ ├── Client.php │ │ │ └── ServiceProvider.php │ │ └── TemplateMessage/ │ │ ├── Client.php │ │ └── ServiceProvider.php │ ├── OpenPublic/ │ │ ├── Application.php │ │ ├── Message/ │ │ │ ├── Client.php │ │ │ └── ServiceProvider.php │ │ ├── Model/ │ │ │ ├── AlipayOpenPublicLifeMsgRecallContentBuilder.php │ │ │ ├── AlipayOpenPublicMessageContentCreateContentBuilder.php │ │ │ ├── AlipayOpenPublicMessageContentModifyContentBuilder.php │ │ │ ├── AlipayOpenPublicMessageQueryContentBuilder.php │ │ │ ├── AlipayOpenPublicMessageSingleSendContentBuilder.php │ │ │ ├── AlipayOpenPublicMessageTotalSendContentBuilder.php │ │ │ ├── AlipayOpenPublicTemplateMessageGetContentBuilder.php │ │ │ └── AlipayOpenPublicTemplateMessageIndustryModifyContentBuilder.php │ │ └── Template/ │ │ ├── Client.php │ │ └── ServiceProvider.php │ └── Payment/ │ ├── Application.php │ ├── Cancel/ │ │ ├── Client.php │ │ └── ServiceProvider.php │ ├── Close/ │ │ ├── Client.php │ │ └── ServiceProvider.php │ ├── Create/ │ │ ├── Client.php │ │ └── ServiceProvider.php │ ├── Model/ │ │ ├── AlipayTradeCancelContentBuilder.php │ │ ├── AlipayTradeCloseContentBuilder.php │ │ ├── AlipayTradeCreateContentBuilder.php │ │ ├── AlipayTradePayContentBuilder.php │ │ ├── AlipayTradeQueryContentBuilder.php │ │ └── AlipayTradeRefundContentBuilder.php │ ├── Pay/ │ │ ├── Client.php │ │ └── ServiceProvider.php │ ├── Query/ │ │ ├── Client.php │ │ └── ServiceProvider.php │ └── Refund/ │ ├── Client.php │ └── ServiceProvider.php └── tests/ └── test.php ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *.DS_Store /vendor sftp-config.json /*.php /.idea /coverage /.split /composer.lock .php_cs.cache ================================================ FILE: LICENSE.md ================================================ 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. ================================================ FILE: NOTICE.md ================================================ # Alibaba Cloud SDK for PHP 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 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 Copyright (c) 2011-2018 Michael Dowling, https://github.com/mtdowling 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. # 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 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 The MIT License (MIT) Copyright (c) overtrue 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. ================================================ FILE: README.md ================================================ ## EasyAlipay 支付宝官方已经推出[Alipay Easy SDK](https://github.com/alipay/alipay-easysdk),可以完全覆盖本SDK的功能,且支持更多编程语言。 故本SDK将不再继续维护,欢迎前往 [Alipay Easy SDK](https://github.com/alipay/alipay-easysdk) 主页了解更多信息。 ## 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 ================================================ FILE: composer.json ================================================ { "name": "shulidata/easyalipay", "description": "支付宝SDK", "keywords": [ "alipay", "easyaliapy", "alipay-sdk", "sdk" ], "license": "MIT", "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\\": "src/" } }, "autoload-dev": { "psr-4": { "EasyAlipay\\Tests\\": "tests/" } } } ================================================ FILE: docs/Base/Oauth.md ================================================ ## 换取授权访问令牌 ##### 配置 ```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。 ================================================ FILE: docs/Marketing/Pass.md ================================================ ## 支付宝卡包 产品文档: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"] } } ``` ================================================ FILE: docs/Mini/Identification.md ================================================ ## 小程序人脸采集与刷脸认证 ##### 配置 ```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。 ================================================ FILE: docs/Mini/Qrcode.md ================================================ ## 小程序二维码 产品文档地址: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。 ================================================ FILE: docs/Mini/Risk.md ================================================ ## 小程序文本风险识别 产品文档地址: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。例如:代办毕业证,我们最专业 ================================================ FILE: docs/Mini/TemplateMessage.md ================================================ ## 小程序模版消息 产品文档地址: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" : "支付宝"}} ================================================ FILE: docs/OpenLife/Message.md ================================================ ## 生活号消息 #### 配置 ```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 ================================================ FILE: docs/OpenLife/Template.md ================================================ ## 生活号消息模版 #### 配置 ```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。 ================================================ FILE: docs/Payment/Cancel.md ================================================ ## 交易取消 ##### 配置 ```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。 ================================================ FILE: docs/Payment/Close.md ================================================ ## 交易关闭 用于交易创建后,用户在一定时间内未进行支付,可调用该接口直接将未付款的交易进行关闭。 ##### 配置 ```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。 ================================================ FILE: docs/Payment/Create.md ================================================ ## 交易创建 #### 配置 ```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位纯数字) ================================================ FILE: docs/Payment/Pay.md ================================================ ## 交易支付 #### 配置 ```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位的数字,实际字符串长度以开发者获取的付款码长度为准 ================================================ FILE: docs/Payment/Query.md ================================================ ## 交易查询 #### 配置 ```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。 ================================================ FILE: docs/Payment/Refund.md ================================================ ## 交易退款 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,卖家可以通过退款接口将支付款退还给买家,支付宝将在收到退款请求并且验证成功之后,按照退款规则将支付款按原路退到买家帐号上。 交易超过约定时间(签约时设置的可退款时间)的订单无法进行退款。一笔退款失败后重新提交,要采用原来的退款单号。总退款金额不能超过用户实际支付金额。 ##### 配置 ```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:需要退款的金额,该金额不能大于订单金额,单位为元,支持两位小数 ================================================ FILE: src/Base/Application.php ================================================ 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; } } ================================================ FILE: src/Base/Oauth/Client.php ================================================ setGrantType($grant_type); $alipaySystemOauthTokenRequest->setCode($code); $alipaySystemOauthTokenRequest->setRefreshToken($refresh_token); return($this->execute($alipaySystemOauthTokenRequest, NULL, NULL)) ; } } ================================================ FILE: src/Base/Oauth/ServiceProvider.php ================================================ 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 = "
"; while (list ($key, $val) = each ($para_temp)) { if (false === $this->checkEmpty($val)) { //$val = $this->characet($val, $this->postCharset); $val = str_replace("'","'",$val); //$val = str_replace("\"",""",$val); $sHtml.= ""; } } //submit按钮控件请不要含有name属性 $sHtml = $sHtml."
"; $sHtml = $sHtml.""; 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 "
checkSign failure
"; 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 = "$encryptedRSA$sign$signType"; return $response; } // 加密,不签名 if ($isEncrypt && (!$isSign)) { $encrypted = $this->rsaEncrypt($bizContent, $rsaPublicKeyPem, $charset); $response = "$encrypted$signType"; return $response; } // 不加密,但签名 if ((!$isEncrypt) && $isSign) { $sign = $this->sign($bizContent, $signType); $response = "$bizContent$sign$signType"; return $response; } // 不加密,不签名 $response = "$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 "
" . openssl_error_string() . "
"; } $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 "
" . openssl_error_string() . "
"; } $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 = "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="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 "
" . $content; } } } ================================================ FILE: src/Kernel/AopRequest.php ================================================ 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; } } ================================================ FILE: src/Kernel/Config.php ================================================ '', //支付宝公钥 '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", // ... ]; } ================================================ FILE: src/Kernel/Providers/ConfigServiceProvider.php ================================================ getConfig(); }; } } ================================================ FILE: src/Kernel/ServiceContainer.php ================================================ 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()); } } } ================================================ FILE: src/Kernel/SignData.php ================================================ [ 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(); } } ================================================ FILE: src/Marketing/Application.php ================================================ 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; } } ================================================ FILE: src/Marketing/Model/AlipayPassInstanceUpdateContentBuilder.php ================================================ 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; } } ================================================ FILE: src/Marketing/Model/AlipayPassTemplateAddContentBuilder.php ================================================ 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; } } ================================================ FILE: src/Marketing/Model/AlipayPassTemplateUpdateContentBuilder.php ================================================ 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; } } ================================================ FILE: src/Marketing/Pass/Client.php ================================================ 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)) ; } } ================================================ FILE: src/Marketing/Pass/ServiceProvider.php ================================================ 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)) ; } } ================================================ FILE: src/Mini/Identification/ServiceProvider.php ================================================ 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; } } ?> ================================================ FILE: src/Mini/Model/AlipayOpenAppQrcodeCreateContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/Mini/Model/AlipaySecurityRiskContentDetectContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/Mini/Model/ZolozIdentificationCustomerCertifyzhubQueryContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/Mini/Model/ZolozIdentificationUserWebQueryContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/Mini/Qrcode/Client.php ================================================ 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)) ; } } ================================================ FILE: src/Mini/Qrcode/ServiceProvider.php ================================================ setContent($content); $request = new AopRequest (); $request->setBizContent($riskContentBuilder->getBizContent()); $request->setApiMethodName("alipay.security.risk.content.detect"); return($this->execute($request, NULL, NULL)) ; } } ================================================ FILE: src/Mini/Risk/ServiceProvider.php ================================================ 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)) ; } } ================================================ FILE: src/Mini/TemplateMessage/ServiceProvider.php ================================================ 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)) ; } } ================================================ FILE: src/OpenPublic/Message/ServiceProvider.php ================================================ 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; } } ?> ================================================ FILE: src/OpenPublic/Model/AlipayOpenPublicMessageContentCreateContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/OpenPublic/Model/AlipayOpenPublicMessageContentModifyContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/OpenPublic/Model/AlipayOpenPublicMessageQueryContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/OpenPublic/Model/AlipayOpenPublicMessageSingleSendContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/OpenPublic/Model/AlipayOpenPublicMessageTotalSendContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/OpenPublic/Model/AlipayOpenPublicTemplateMessageGetContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/OpenPublic/Model/AlipayOpenPublicTemplateMessageIndustryModifyContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/OpenPublic/Template/Client.php ================================================ 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)) ; } } ================================================ FILE: src/OpenPublic/Template/ServiceProvider.php ================================================ setOutTradeNo($out_trade_no); $request = new AopRequest (); $request->setBizContent($cancelContentBuilder->getBizContent()); $request->setApiMethodName("alipay.trade.cancel"); return($this->execute($request, NULL, NULL)) ; } } ================================================ FILE: src/Payment/Cancel/ServiceProvider.php ================================================ setOutTradeNo($out_trade_no); $request = new AopRequest (); $request->setBizContent($closeContentBuilder->getBizContent()); $request->setApiMethodName("alipay.trade.close"); return($this->execute($request, NULL, NULL)) ; } } ================================================ FILE: src/Payment/Close/ServiceProvider.php ================================================ 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)) ; } } ================================================ FILE: src/Payment/Create/ServiceProvider.php ================================================ 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; } } ?> ================================================ FILE: src/Payment/Model/AlipayTradeCloseContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/Payment/Model/AlipayTradeCreateContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/Payment/Model/AlipayTradePayContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/Payment/Model/AlipayTradeQueryContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/Payment/Model/AlipayTradeRefundContentBuilder.php ================================================ 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; } } ?> ================================================ FILE: src/Payment/Pay/Client.php ================================================ 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)) ; } } ================================================ FILE: src/Payment/Pay/ServiceProvider.php ================================================ setOutTradeNo($out_trade_no); $request = new AopRequest (); $request->setBizContent($queryContentBuilder->getBizContent()); $request->setApiMethodName("alipay.trade.query"); return($this->execute($request, NULL, NULL)) ; } } ================================================ FILE: src/Payment/Query/ServiceProvider.php ================================================ 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)) ; } } ================================================ FILE: src/Payment/Refund/ServiceProvider.php ================================================ '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"));