├── .gitignore ├── src ├── EchoBool │ └── AlipayLaravel │ │ ├── aop │ │ ├── SignData.php │ │ ├── EncryptResponseData.php │ │ ├── EncryptParseItem.php │ │ ├── AopEncrypt.php │ │ ├── request │ │ │ ├── AlipayTradeAppPayRequest.php │ │ │ ├── AlipayTradeCancelRequest.php │ │ │ ├── AlipayTradeWapPayRequest.php │ │ │ ├── AlipayTradeCreateRequest.php │ │ │ ├── AlipayTradePayRequest.php │ │ │ ├── AlipayTradeCustomsQueryRequest.php │ │ │ ├── AlipayTradeOrderSettleRequest.php │ │ │ ├── AlipayTradeCustomsDeclareRequest.php │ │ │ ├── AlipayTradeCloseRequest.php │ │ │ ├── AlipayTradeRefundRequest.php │ │ │ ├── AlipayTradePagePayRequest.php │ │ │ ├── AlipayTradeQueryRequest.php │ │ │ ├── AlipayTradePrecreateRequest.php │ │ │ ├── AlipayTradeVendorpayDevicedataUploadRequest.php │ │ │ ├── AlipayTradeFastpayRefundQueryRequest.php │ │ │ └── AlipayDataDataserviceBillDownloadurlQueryRequest.php │ │ ├── AlipayMobilePublicMultiMediaExecute.php │ │ ├── test │ │ │ └── TestImage.php │ │ ├── AlipayMobilePublicMultiMediaClient.php │ │ └── AopClient.php │ │ ├── Facades │ │ └── Alipay.php │ │ ├── AlipayServiceProvider.php │ │ ├── buildermodel │ │ ├── AlipayTradeQueryContentBuilder.php │ │ ├── AlipayTradeCloseContentBuilder.php │ │ ├── AlipayTradeFastpayRefundQueryContentBuilder.php │ │ ├── AlipayTradeRefundContentBuilder.php │ │ └── AlipayTradePagePayContentBuilder.php │ │ ├── AlipaySdk.php │ │ └── service │ │ └── AlipayTradeService.php └── config │ └── config.php ├── composer.json ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor 2 | composer.phar 3 | composer.lock 4 | .DS_Store 5 | .settings 6 | .buildpath 7 | .project -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/SignData.php: -------------------------------------------------------------------------------- 1 | =5.4.0", 21 | "illuminate/support": "5.*", 22 | "illuminate/config": "5.*" 23 | }, 24 | "autoload": { 25 | "psr-4": { 26 | "EchoBool\\AlipayLaravel\\": "src/EchoBool/AlipayLaravel/" 27 | } 28 | }, 29 | "minimum-stability": "stable" 30 | } -------------------------------------------------------------------------------- /src/config/config.php: -------------------------------------------------------------------------------- 1 | "", 12 | 13 | //商户私钥 不能用pkcs8.pem中的密钥!!!!! 14 | 'merchant_private_key' => "", 15 | 16 | //异步通知地址 17 | 'notify_url' => "http://外网可访问网关地址/alipay.trade.page.pay-PHP-UTF-8/notify_url.php", 18 | 19 | //同步跳转 20 | 'return_url' => "http://外网可访问网关地址/alipay.trade.page.pay-PHP-UTF-8/return_url.php", 21 | 22 | //编码格式 23 | 'charset' => "UTF-8", 24 | 25 | //签名方式 26 | 'sign_type' => "RSA2", 27 | 28 | //支付宝网关 29 | 'gatewayUrl' => "https://openapi.alipay.com/gateway.do", 30 | 31 | //支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。 32 | 'alipay_public_key' => "", 33 | 34 | //支付时提交方式 true 为表单提交方式成功后跳转到return_url, 35 | //false 时为Curl方式 返回支付宝支付页面址址 自己跳转上去 支付成功不会跳转到return_url上, 我也不知道为什么,有人发现可以跳转请告诉 我一下 谢谢 36 | // email: 40281612@qq.com 37 | 'trade_pay_type' => false, 38 | ]; -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 echobool 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/AlipayServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 32 | __DIR__ . '/../../config/config.php' => config_path('alipay-web.php'), 33 | ]); 34 | } 35 | 36 | /** 37 | * Register the application services. 38 | * 39 | * @return void 40 | */ 41 | public function register() 42 | { 43 | $this->app->singleton('Alipay', function ($app) { 44 | return new AlipaySdk($app['config']['alipay-web']);//config 45 | }); 46 | } 47 | 48 | /** 49 | * Get the services provided by the provider. 50 | * 51 | * @return array 52 | */ 53 | public function provides() 54 | { 55 | return ['Alipay']; 56 | } 57 | 58 | } -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/buildermodel/AlipayTradeQueryContentBuilder.php: -------------------------------------------------------------------------------- 1 | bizContentarr)){ 28 | $this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE); 29 | } 30 | return $this->bizContent; 31 | } 32 | 33 | public function getTradeNo() 34 | { 35 | return $this->tradeNo; 36 | } 37 | 38 | public function setTradeNo($tradeNo) 39 | { 40 | $this->tradeNo = $tradeNo; 41 | $this->bizContentarr['trade_no'] = $tradeNo; 42 | } 43 | 44 | public function getOutTradeNo() 45 | { 46 | return $this->outTradeNo; 47 | } 48 | 49 | public function setOutTradeNo($outTradeNo) 50 | { 51 | $this->outTradeNo = $outTradeNo; 52 | $this->bizContentarr['out_trade_no'] = $outTradeNo; 53 | } 54 | } 55 | 56 | ?> -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/buildermodel/AlipayTradeCloseContentBuilder.php: -------------------------------------------------------------------------------- 1 | bizContentarr)){ 30 | $this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE); 31 | } 32 | return $this->bizContent; 33 | } 34 | 35 | public function getTradeNo() 36 | { 37 | return $this->tradeNo; 38 | } 39 | 40 | public function setTradeNo($tradeNo) 41 | { 42 | $this->tradeNo = $tradeNo; 43 | $this->bizContentarr['trade_no'] = $tradeNo; 44 | } 45 | 46 | public function getOutTradeNo() 47 | { 48 | return $this->outTradeNo; 49 | } 50 | 51 | public function setOutTradeNo($outTradeNo) 52 | { 53 | $this->outTradeNo = $outTradeNo; 54 | $this->bizContentarr['out_trade_no'] = $outTradeNo; 55 | } 56 | public function getOperatorId() 57 | { 58 | return $this->operatorId; 59 | } 60 | 61 | public function setOperatorId($operatorId) 62 | { 63 | $this->operatorId = $operatorId; 64 | $this->bizContentarr['operator_id'] = $operatorId; 65 | } 66 | 67 | } 68 | 69 | ?> -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/buildermodel/AlipayTradeFastpayRefundQueryContentBuilder.php: -------------------------------------------------------------------------------- 1 | bizContentarr)){ 29 | $this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE); 30 | } 31 | return $this->bizContent; 32 | } 33 | 34 | public function getTradeNo() 35 | { 36 | return $this->tradeNo; 37 | } 38 | 39 | public function setTradeNo($tradeNo) 40 | { 41 | $this->tradeNo = $tradeNo; 42 | $this->bizContentarr['trade_no'] = $tradeNo; 43 | } 44 | 45 | public function getOutTradeNo() 46 | { 47 | return $this->outTradeNo; 48 | } 49 | 50 | public function setOutTradeNo($outTradeNo) 51 | { 52 | $this->outTradeNo = $outTradeNo; 53 | $this->bizContentarr['out_trade_no'] = $outTradeNo; 54 | } 55 | public function getOutRequestNo() 56 | { 57 | return $this->outRequestNo; 58 | } 59 | public function setOutRequestNo($outRequestNo) 60 | { 61 | $this->outRequestNo = $outRequestNo; 62 | $this->bizContentarr['out_request_no'] = $outRequestNo; 63 | } 64 | } 65 | 66 | ?> -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/AopEncrypt.php: -------------------------------------------------------------------------------- 1 | bizContentarr)){ 36 | $this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE); 37 | } 38 | return $this->bizContent; 39 | } 40 | 41 | public function getTradeNo() 42 | { 43 | return $this->tradeNo; 44 | } 45 | 46 | public function setTradeNo($tradeNo) 47 | { 48 | $this->tradeNo = $tradeNo; 49 | $this->bizContentarr['trade_no'] = $tradeNo; 50 | } 51 | 52 | public function getOutTradeNo() 53 | { 54 | return $this->outTradeNo; 55 | } 56 | 57 | public function setOutTradeNo($outTradeNo) 58 | { 59 | $this->outTradeNo = $outTradeNo; 60 | $this->bizContentarr['out_trade_no'] = $outTradeNo; 61 | } 62 | 63 | public function getRefundAmount() 64 | { 65 | return $this->refundAmount; 66 | } 67 | 68 | public function setRefundAmount($refundAmount) 69 | { 70 | $this->refundAmount = $refundAmount; 71 | $this->bizContentarr['refund_amount'] = $refundAmount; 72 | } 73 | 74 | public function getRefundReason() 75 | { 76 | return $this->refundReason; 77 | } 78 | 79 | public function setRefundReason($refundReason) 80 | { 81 | $this->refundReason = $refundReason; 82 | $this->bizContentarr['refund_reason'] = $refundReason; 83 | } 84 | 85 | public function getOutRequestNo() 86 | { 87 | return $this->outRequestNo; 88 | } 89 | 90 | public function setOutRequestNo($outRequestNo) 91 | { 92 | $this->outRequestNo = $outRequestNo; 93 | $this->bizContentarr['out_request_no'] = $outRequestNo; 94 | } 95 | } 96 | 97 | ?> -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeAppPayRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 28 | $this->apiParas["biz_content"] = $bizContent; 29 | } 30 | 31 | public function getBizContent() 32 | { 33 | return $this->bizContent; 34 | } 35 | 36 | public function getApiMethodName() 37 | { 38 | return "alipay.trade.app.pay"; 39 | } 40 | 41 | public function setNotifyUrl($notifyUrl) 42 | { 43 | $this->notifyUrl=$notifyUrl; 44 | } 45 | 46 | public function getNotifyUrl() 47 | { 48 | return $this->notifyUrl; 49 | } 50 | 51 | public function setReturnUrl($returnUrl) 52 | { 53 | $this->returnUrl=$returnUrl; 54 | } 55 | 56 | public function getReturnUrl() 57 | { 58 | return $this->returnUrl; 59 | } 60 | 61 | public function getApiParas() 62 | { 63 | return $this->apiParas; 64 | } 65 | 66 | public function getTerminalType() 67 | { 68 | return $this->terminalType; 69 | } 70 | 71 | public function setTerminalType($terminalType) 72 | { 73 | $this->terminalType = $terminalType; 74 | } 75 | 76 | public function getTerminalInfo() 77 | { 78 | return $this->terminalInfo; 79 | } 80 | 81 | public function setTerminalInfo($terminalInfo) 82 | { 83 | $this->terminalInfo = $terminalInfo; 84 | } 85 | 86 | public function getProdCode() 87 | { 88 | return $this->prodCode; 89 | } 90 | 91 | public function setProdCode($prodCode) 92 | { 93 | $this->prodCode = $prodCode; 94 | } 95 | 96 | public function setApiVersion($apiVersion) 97 | { 98 | $this->apiVersion=$apiVersion; 99 | } 100 | 101 | public function getApiVersion() 102 | { 103 | return $this->apiVersion; 104 | } 105 | 106 | public function setNeedEncrypt($needEncrypt) 107 | { 108 | 109 | $this->needEncrypt=$needEncrypt; 110 | 111 | } 112 | 113 | public function getNeedEncrypt() 114 | { 115 | return $this->needEncrypt; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeCancelRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 28 | $this->apiParas["biz_content"] = $bizContent; 29 | } 30 | 31 | public function getBizContent() 32 | { 33 | return $this->bizContent; 34 | } 35 | 36 | public function getApiMethodName() 37 | { 38 | return "alipay.trade.cancel"; 39 | } 40 | 41 | public function setNotifyUrl($notifyUrl) 42 | { 43 | $this->notifyUrl=$notifyUrl; 44 | } 45 | 46 | public function getNotifyUrl() 47 | { 48 | return $this->notifyUrl; 49 | } 50 | 51 | public function setReturnUrl($returnUrl) 52 | { 53 | $this->returnUrl=$returnUrl; 54 | } 55 | 56 | public function getReturnUrl() 57 | { 58 | return $this->returnUrl; 59 | } 60 | 61 | public function getApiParas() 62 | { 63 | return $this->apiParas; 64 | } 65 | 66 | public function getTerminalType() 67 | { 68 | return $this->terminalType; 69 | } 70 | 71 | public function setTerminalType($terminalType) 72 | { 73 | $this->terminalType = $terminalType; 74 | } 75 | 76 | public function getTerminalInfo() 77 | { 78 | return $this->terminalInfo; 79 | } 80 | 81 | public function setTerminalInfo($terminalInfo) 82 | { 83 | $this->terminalInfo = $terminalInfo; 84 | } 85 | 86 | public function getProdCode() 87 | { 88 | return $this->prodCode; 89 | } 90 | 91 | public function setProdCode($prodCode) 92 | { 93 | $this->prodCode = $prodCode; 94 | } 95 | 96 | public function setApiVersion($apiVersion) 97 | { 98 | $this->apiVersion=$apiVersion; 99 | } 100 | 101 | public function getApiVersion() 102 | { 103 | return $this->apiVersion; 104 | } 105 | 106 | public function setNeedEncrypt($needEncrypt) 107 | { 108 | 109 | $this->needEncrypt=$needEncrypt; 110 | 111 | } 112 | 113 | public function getNeedEncrypt() 114 | { 115 | return $this->needEncrypt; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeWapPayRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 28 | $this->apiParas["biz_content"] = $bizContent; 29 | } 30 | 31 | public function getBizContent() 32 | { 33 | return $this->bizContent; 34 | } 35 | 36 | public function getApiMethodName() 37 | { 38 | return "alipay.trade.wap.pay"; 39 | } 40 | 41 | public function setNotifyUrl($notifyUrl) 42 | { 43 | $this->notifyUrl=$notifyUrl; 44 | } 45 | 46 | public function getNotifyUrl() 47 | { 48 | return $this->notifyUrl; 49 | } 50 | 51 | public function setReturnUrl($returnUrl) 52 | { 53 | $this->returnUrl=$returnUrl; 54 | } 55 | 56 | public function getReturnUrl() 57 | { 58 | return $this->returnUrl; 59 | } 60 | 61 | public function getApiParas() 62 | { 63 | return $this->apiParas; 64 | } 65 | 66 | public function getTerminalType() 67 | { 68 | return $this->terminalType; 69 | } 70 | 71 | public function setTerminalType($terminalType) 72 | { 73 | $this->terminalType = $terminalType; 74 | } 75 | 76 | public function getTerminalInfo() 77 | { 78 | return $this->terminalInfo; 79 | } 80 | 81 | public function setTerminalInfo($terminalInfo) 82 | { 83 | $this->terminalInfo = $terminalInfo; 84 | } 85 | 86 | public function getProdCode() 87 | { 88 | return $this->prodCode; 89 | } 90 | 91 | public function setProdCode($prodCode) 92 | { 93 | $this->prodCode = $prodCode; 94 | } 95 | 96 | public function setApiVersion($apiVersion) 97 | { 98 | $this->apiVersion=$apiVersion; 99 | } 100 | 101 | public function getApiVersion() 102 | { 103 | return $this->apiVersion; 104 | } 105 | 106 | public function setNeedEncrypt($needEncrypt) 107 | { 108 | 109 | $this->needEncrypt=$needEncrypt; 110 | 111 | } 112 | 113 | public function getNeedEncrypt() 114 | { 115 | return $this->needEncrypt; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeCreateRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 28 | $this->apiParas["biz_content"] = $bizContent; 29 | } 30 | 31 | public function getBizContent() 32 | { 33 | return $this->bizContent; 34 | } 35 | 36 | public function getApiMethodName() 37 | { 38 | return "alipay.trade.create"; 39 | } 40 | 41 | public function setNotifyUrl($notifyUrl) 42 | { 43 | $this->notifyUrl=$notifyUrl; 44 | } 45 | 46 | public function getNotifyUrl() 47 | { 48 | return $this->notifyUrl; 49 | } 50 | 51 | public function setReturnUrl($returnUrl) 52 | { 53 | $this->returnUrl=$returnUrl; 54 | } 55 | 56 | public function getReturnUrl() 57 | { 58 | return $this->returnUrl; 59 | } 60 | 61 | public function getApiParas() 62 | { 63 | return $this->apiParas; 64 | } 65 | 66 | public function getTerminalType() 67 | { 68 | return $this->terminalType; 69 | } 70 | 71 | public function setTerminalType($terminalType) 72 | { 73 | $this->terminalType = $terminalType; 74 | } 75 | 76 | public function getTerminalInfo() 77 | { 78 | return $this->terminalInfo; 79 | } 80 | 81 | public function setTerminalInfo($terminalInfo) 82 | { 83 | $this->terminalInfo = $terminalInfo; 84 | } 85 | 86 | public function getProdCode() 87 | { 88 | return $this->prodCode; 89 | } 90 | 91 | public function setProdCode($prodCode) 92 | { 93 | $this->prodCode = $prodCode; 94 | } 95 | 96 | public function setApiVersion($apiVersion) 97 | { 98 | $this->apiVersion=$apiVersion; 99 | } 100 | 101 | public function getApiVersion() 102 | { 103 | return $this->apiVersion; 104 | } 105 | 106 | public function setNeedEncrypt($needEncrypt) 107 | { 108 | 109 | $this->needEncrypt=$needEncrypt; 110 | 111 | } 112 | 113 | public function getNeedEncrypt() 114 | { 115 | return $this->needEncrypt; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradePayRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 29 | $this->apiParas["biz_content"] = $bizContent; 30 | } 31 | 32 | public function getBizContent() 33 | { 34 | return $this->bizContent; 35 | } 36 | 37 | public function getApiMethodName() 38 | { 39 | return "alipay.trade.pay"; 40 | } 41 | 42 | public function setNotifyUrl($notifyUrl) 43 | { 44 | $this->notifyUrl=$notifyUrl; 45 | } 46 | 47 | public function getNotifyUrl() 48 | { 49 | return $this->notifyUrl; 50 | } 51 | 52 | public function setReturnUrl($returnUrl) 53 | { 54 | $this->returnUrl=$returnUrl; 55 | } 56 | 57 | public function getReturnUrl() 58 | { 59 | return $this->returnUrl; 60 | } 61 | 62 | public function getApiParas() 63 | { 64 | return $this->apiParas; 65 | } 66 | 67 | public function getTerminalType() 68 | { 69 | return $this->terminalType; 70 | } 71 | 72 | public function setTerminalType($terminalType) 73 | { 74 | $this->terminalType = $terminalType; 75 | } 76 | 77 | public function getTerminalInfo() 78 | { 79 | return $this->terminalInfo; 80 | } 81 | 82 | public function setTerminalInfo($terminalInfo) 83 | { 84 | $this->terminalInfo = $terminalInfo; 85 | } 86 | 87 | public function getProdCode() 88 | { 89 | return $this->prodCode; 90 | } 91 | 92 | public function setProdCode($prodCode) 93 | { 94 | $this->prodCode = $prodCode; 95 | } 96 | 97 | public function setApiVersion($apiVersion) 98 | { 99 | $this->apiVersion=$apiVersion; 100 | } 101 | 102 | public function getApiVersion() 103 | { 104 | return $this->apiVersion; 105 | } 106 | 107 | public function setNeedEncrypt($needEncrypt) 108 | { 109 | 110 | $this->needEncrypt=$needEncrypt; 111 | 112 | } 113 | 114 | public function getNeedEncrypt() 115 | { 116 | return $this->needEncrypt; 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/AlipayMobilePublicMultiMediaExecute.php: -------------------------------------------------------------------------------- 1 | 'jpg', //+ 22 | "text/plain" => 'text' 23 | ); 24 | 25 | /* 26 | * @$header : 头部 27 | * */ 28 | function __construct( $header, $body, $httpCode ){ 29 | $this -> code = $httpCode; 30 | $this -> msg = ''; 31 | $this -> params = $header ; 32 | $this -> body = $body; 33 | } 34 | 35 | /** 36 | * 37 | * @return text | bin 38 | */ 39 | public function getCode(){ 40 | return $this -> code ; 41 | } 42 | 43 | /** 44 | * 45 | * @return text | bin 46 | */ 47 | public function getMsg(){ 48 | return $this -> msg ; 49 | } 50 | 51 | /** 52 | * 53 | * @return text | bin 54 | */ 55 | public function getType(){ 56 | $subject = $this -> params ; 57 | $pattern = '/Content\-Type:([^;]+)/'; 58 | preg_match($pattern, $subject, $matches); 59 | if( $matches ){ 60 | $type = $matches[1]; 61 | }else{ 62 | $type = 'application/download'; 63 | } 64 | 65 | return str_replace( ' ', '', $type ); 66 | } 67 | 68 | /** 69 | * 70 | * @return text | bin 71 | */ 72 | public function getContentLength(){ 73 | $subject = $this -> params ; 74 | $pattern = '/Content-Length:\s*([^\n]+)/'; 75 | preg_match($pattern, $subject, $matches); 76 | return (int)( isset($matches[1] ) ? $matches[1] : '' ); 77 | } 78 | 79 | 80 | public function getFileSuffix( $fileType ){ 81 | $type = isset( $this -> fileSuffix[ $fileType ] ) ? $this -> fileSuffix[ $fileType ] : 'text/plain' ; 82 | if( !$type ){ 83 | $type = 'json'; 84 | } 85 | return $type; 86 | } 87 | 88 | 89 | 90 | /** 91 | * 92 | * @return text | bin 93 | */ 94 | public function getBody(){ 95 | //header('Content-type: image/jpeg'); 96 | return $this -> body ; 97 | } 98 | 99 | /** 100 | * 获取参数 101 | * @return text | bin 102 | */ 103 | public function getParams(){ 104 | return $this -> params ; 105 | } 106 | 107 | 108 | } 109 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeCustomsQueryRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 28 | $this->apiParas["biz_content"] = $bizContent; 29 | } 30 | 31 | public function getBizContent() 32 | { 33 | return $this->bizContent; 34 | } 35 | 36 | public function getApiMethodName() 37 | { 38 | return "alipay.trade.customs.query"; 39 | } 40 | 41 | public function setNotifyUrl($notifyUrl) 42 | { 43 | $this->notifyUrl=$notifyUrl; 44 | } 45 | 46 | public function getNotifyUrl() 47 | { 48 | return $this->notifyUrl; 49 | } 50 | 51 | public function setReturnUrl($returnUrl) 52 | { 53 | $this->returnUrl=$returnUrl; 54 | } 55 | 56 | public function getReturnUrl() 57 | { 58 | return $this->returnUrl; 59 | } 60 | 61 | public function getApiParas() 62 | { 63 | return $this->apiParas; 64 | } 65 | 66 | public function getTerminalType() 67 | { 68 | return $this->terminalType; 69 | } 70 | 71 | public function setTerminalType($terminalType) 72 | { 73 | $this->terminalType = $terminalType; 74 | } 75 | 76 | public function getTerminalInfo() 77 | { 78 | return $this->terminalInfo; 79 | } 80 | 81 | public function setTerminalInfo($terminalInfo) 82 | { 83 | $this->terminalInfo = $terminalInfo; 84 | } 85 | 86 | public function getProdCode() 87 | { 88 | return $this->prodCode; 89 | } 90 | 91 | public function setProdCode($prodCode) 92 | { 93 | $this->prodCode = $prodCode; 94 | } 95 | 96 | public function setApiVersion($apiVersion) 97 | { 98 | $this->apiVersion=$apiVersion; 99 | } 100 | 101 | public function getApiVersion() 102 | { 103 | return $this->apiVersion; 104 | } 105 | 106 | public function setNeedEncrypt($needEncrypt) 107 | { 108 | 109 | $this->needEncrypt=$needEncrypt; 110 | 111 | } 112 | 113 | public function getNeedEncrypt() 114 | { 115 | return $this->needEncrypt; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeOrderSettleRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 28 | $this->apiParas["biz_content"] = $bizContent; 29 | } 30 | 31 | public function getBizContent() 32 | { 33 | return $this->bizContent; 34 | } 35 | 36 | public function getApiMethodName() 37 | { 38 | return "alipay.trade.order.settle"; 39 | } 40 | 41 | public function setNotifyUrl($notifyUrl) 42 | { 43 | $this->notifyUrl=$notifyUrl; 44 | } 45 | 46 | public function getNotifyUrl() 47 | { 48 | return $this->notifyUrl; 49 | } 50 | 51 | public function setReturnUrl($returnUrl) 52 | { 53 | $this->returnUrl=$returnUrl; 54 | } 55 | 56 | public function getReturnUrl() 57 | { 58 | return $this->returnUrl; 59 | } 60 | 61 | public function getApiParas() 62 | { 63 | return $this->apiParas; 64 | } 65 | 66 | public function getTerminalType() 67 | { 68 | return $this->terminalType; 69 | } 70 | 71 | public function setTerminalType($terminalType) 72 | { 73 | $this->terminalType = $terminalType; 74 | } 75 | 76 | public function getTerminalInfo() 77 | { 78 | return $this->terminalInfo; 79 | } 80 | 81 | public function setTerminalInfo($terminalInfo) 82 | { 83 | $this->terminalInfo = $terminalInfo; 84 | } 85 | 86 | public function getProdCode() 87 | { 88 | return $this->prodCode; 89 | } 90 | 91 | public function setProdCode($prodCode) 92 | { 93 | $this->prodCode = $prodCode; 94 | } 95 | 96 | public function setApiVersion($apiVersion) 97 | { 98 | $this->apiVersion=$apiVersion; 99 | } 100 | 101 | public function getApiVersion() 102 | { 103 | return $this->apiVersion; 104 | } 105 | 106 | public function setNeedEncrypt($needEncrypt) 107 | { 108 | 109 | $this->needEncrypt=$needEncrypt; 110 | 111 | } 112 | 113 | public function getNeedEncrypt() 114 | { 115 | return $this->needEncrypt; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeCustomsDeclareRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 28 | $this->apiParas["biz_content"] = $bizContent; 29 | } 30 | 31 | public function getBizContent() 32 | { 33 | return $this->bizContent; 34 | } 35 | 36 | public function getApiMethodName() 37 | { 38 | return "alipay.trade.customs.declare"; 39 | } 40 | 41 | public function setNotifyUrl($notifyUrl) 42 | { 43 | $this->notifyUrl=$notifyUrl; 44 | } 45 | 46 | public function getNotifyUrl() 47 | { 48 | return $this->notifyUrl; 49 | } 50 | 51 | public function setReturnUrl($returnUrl) 52 | { 53 | $this->returnUrl=$returnUrl; 54 | } 55 | 56 | public function getReturnUrl() 57 | { 58 | return $this->returnUrl; 59 | } 60 | 61 | public function getApiParas() 62 | { 63 | return $this->apiParas; 64 | } 65 | 66 | public function getTerminalType() 67 | { 68 | return $this->terminalType; 69 | } 70 | 71 | public function setTerminalType($terminalType) 72 | { 73 | $this->terminalType = $terminalType; 74 | } 75 | 76 | public function getTerminalInfo() 77 | { 78 | return $this->terminalInfo; 79 | } 80 | 81 | public function setTerminalInfo($terminalInfo) 82 | { 83 | $this->terminalInfo = $terminalInfo; 84 | } 85 | 86 | public function getProdCode() 87 | { 88 | return $this->prodCode; 89 | } 90 | 91 | public function setProdCode($prodCode) 92 | { 93 | $this->prodCode = $prodCode; 94 | } 95 | 96 | public function setApiVersion($apiVersion) 97 | { 98 | $this->apiVersion=$apiVersion; 99 | } 100 | 101 | public function getApiVersion() 102 | { 103 | return $this->apiVersion; 104 | } 105 | 106 | public function setNeedEncrypt($needEncrypt) 107 | { 108 | 109 | $this->needEncrypt=$needEncrypt; 110 | 111 | } 112 | 113 | public function getNeedEncrypt() 114 | { 115 | return $this->needEncrypt; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeCloseRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 30 | $this->apiParas["biz_content"] = $bizContent; 31 | } 32 | 33 | public function getBizContent() 34 | { 35 | return $this->bizContent; 36 | } 37 | 38 | public function getApiMethodName() 39 | { 40 | return "alipay.trade.close"; 41 | } 42 | 43 | public function setNotifyUrl($notifyUrl) 44 | { 45 | $this->notifyUrl=$notifyUrl; 46 | } 47 | 48 | public function getNotifyUrl() 49 | { 50 | return $this->notifyUrl; 51 | } 52 | 53 | public function setReturnUrl($returnUrl) 54 | { 55 | $this->returnUrl=$returnUrl; 56 | } 57 | 58 | public function getReturnUrl() 59 | { 60 | return $this->returnUrl; 61 | } 62 | 63 | public function getApiParas() 64 | { 65 | return $this->apiParas; 66 | } 67 | 68 | public function getTerminalType() 69 | { 70 | return $this->terminalType; 71 | } 72 | 73 | public function setTerminalType($terminalType) 74 | { 75 | $this->terminalType = $terminalType; 76 | } 77 | 78 | public function getTerminalInfo() 79 | { 80 | return $this->terminalInfo; 81 | } 82 | 83 | public function setTerminalInfo($terminalInfo) 84 | { 85 | $this->terminalInfo = $terminalInfo; 86 | } 87 | 88 | public function getProdCode() 89 | { 90 | return $this->prodCode; 91 | } 92 | 93 | public function setProdCode($prodCode) 94 | { 95 | $this->prodCode = $prodCode; 96 | } 97 | 98 | public function setApiVersion($apiVersion) 99 | { 100 | $this->apiVersion=$apiVersion; 101 | } 102 | 103 | public function getApiVersion() 104 | { 105 | return $this->apiVersion; 106 | } 107 | 108 | public function setNeedEncrypt($needEncrypt) 109 | { 110 | 111 | $this->needEncrypt=$needEncrypt; 112 | 113 | } 114 | 115 | public function getNeedEncrypt() 116 | { 117 | return $this->needEncrypt; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeRefundRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 30 | $this->apiParas["biz_content"] = $bizContent; 31 | } 32 | 33 | public function getBizContent() 34 | { 35 | return $this->bizContent; 36 | } 37 | 38 | public function getApiMethodName() 39 | { 40 | return "alipay.trade.refund"; 41 | } 42 | 43 | public function setNotifyUrl($notifyUrl) 44 | { 45 | $this->notifyUrl=$notifyUrl; 46 | } 47 | 48 | public function getNotifyUrl() 49 | { 50 | return $this->notifyUrl; 51 | } 52 | 53 | public function setReturnUrl($returnUrl) 54 | { 55 | $this->returnUrl=$returnUrl; 56 | } 57 | 58 | public function getReturnUrl() 59 | { 60 | return $this->returnUrl; 61 | } 62 | 63 | public function getApiParas() 64 | { 65 | return $this->apiParas; 66 | } 67 | 68 | public function getTerminalType() 69 | { 70 | return $this->terminalType; 71 | } 72 | 73 | public function setTerminalType($terminalType) 74 | { 75 | $this->terminalType = $terminalType; 76 | } 77 | 78 | public function getTerminalInfo() 79 | { 80 | return $this->terminalInfo; 81 | } 82 | 83 | public function setTerminalInfo($terminalInfo) 84 | { 85 | $this->terminalInfo = $terminalInfo; 86 | } 87 | 88 | public function getProdCode() 89 | { 90 | return $this->prodCode; 91 | } 92 | 93 | public function setProdCode($prodCode) 94 | { 95 | $this->prodCode = $prodCode; 96 | } 97 | 98 | public function setApiVersion($apiVersion) 99 | { 100 | $this->apiVersion=$apiVersion; 101 | } 102 | 103 | public function getApiVersion() 104 | { 105 | return $this->apiVersion; 106 | } 107 | 108 | public function setNeedEncrypt($needEncrypt) 109 | { 110 | 111 | $this->needEncrypt=$needEncrypt; 112 | 113 | } 114 | 115 | public function getNeedEncrypt() 116 | { 117 | return $this->needEncrypt; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradePagePayRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 29 | $this->apiParas["biz_content"] = $bizContent; 30 | } 31 | 32 | public function getBizContent() 33 | { 34 | return $this->bizContent; 35 | } 36 | 37 | public function getApiMethodName() 38 | { 39 | return "alipay.trade.page.pay"; 40 | } 41 | 42 | public function setNotifyUrl($notifyUrl) 43 | { 44 | $this->notifyUrl=$notifyUrl; 45 | } 46 | 47 | public function getNotifyUrl() 48 | { 49 | return $this->notifyUrl; 50 | } 51 | 52 | public function setReturnUrl($returnUrl) 53 | { 54 | $this->returnUrl=$returnUrl; 55 | } 56 | 57 | public function getReturnUrl() 58 | { 59 | return $this->returnUrl; 60 | } 61 | 62 | public function getApiParas() 63 | { 64 | return $this->apiParas; 65 | } 66 | 67 | public function getTerminalType() 68 | { 69 | return $this->terminalType; 70 | } 71 | 72 | public function setTerminalType($terminalType) 73 | { 74 | $this->terminalType = $terminalType; 75 | } 76 | 77 | public function getTerminalInfo() 78 | { 79 | return $this->terminalInfo; 80 | } 81 | 82 | public function setTerminalInfo($terminalInfo) 83 | { 84 | $this->terminalInfo = $terminalInfo; 85 | } 86 | 87 | public function getProdCode() 88 | { 89 | return $this->prodCode; 90 | } 91 | 92 | public function setProdCode($prodCode) 93 | { 94 | $this->prodCode = $prodCode; 95 | } 96 | 97 | public function setApiVersion($apiVersion) 98 | { 99 | $this->apiVersion=$apiVersion; 100 | } 101 | 102 | public function getApiVersion() 103 | { 104 | return $this->apiVersion; 105 | } 106 | 107 | public function setNeedEncrypt($needEncrypt) 108 | { 109 | 110 | $this->needEncrypt=$needEncrypt; 111 | 112 | } 113 | 114 | public function getNeedEncrypt() 115 | { 116 | return $this->needEncrypt; 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeQueryRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 31 | $this->apiParas["biz_content"] = $bizContent; 32 | } 33 | 34 | public function getBizContent() 35 | { 36 | return $this->bizContent; 37 | } 38 | 39 | public function getApiMethodName() 40 | { 41 | return "alipay.trade.query"; 42 | } 43 | 44 | public function setNotifyUrl($notifyUrl) 45 | { 46 | $this->notifyUrl=$notifyUrl; 47 | } 48 | 49 | public function getNotifyUrl() 50 | { 51 | return $this->notifyUrl; 52 | } 53 | 54 | public function setReturnUrl($returnUrl) 55 | { 56 | $this->returnUrl=$returnUrl; 57 | } 58 | 59 | public function getReturnUrl() 60 | { 61 | return $this->returnUrl; 62 | } 63 | 64 | public function getApiParas() 65 | { 66 | return $this->apiParas; 67 | } 68 | 69 | public function getTerminalType() 70 | { 71 | return $this->terminalType; 72 | } 73 | 74 | public function setTerminalType($terminalType) 75 | { 76 | $this->terminalType = $terminalType; 77 | } 78 | 79 | public function getTerminalInfo() 80 | { 81 | return $this->terminalInfo; 82 | } 83 | 84 | public function setTerminalInfo($terminalInfo) 85 | { 86 | $this->terminalInfo = $terminalInfo; 87 | } 88 | 89 | public function getProdCode() 90 | { 91 | return $this->prodCode; 92 | } 93 | 94 | public function setProdCode($prodCode) 95 | { 96 | $this->prodCode = $prodCode; 97 | } 98 | 99 | public function setApiVersion($apiVersion) 100 | { 101 | $this->apiVersion=$apiVersion; 102 | } 103 | 104 | public function getApiVersion() 105 | { 106 | return $this->apiVersion; 107 | } 108 | 109 | public function setNeedEncrypt($needEncrypt) 110 | { 111 | 112 | $this->needEncrypt=$needEncrypt; 113 | 114 | } 115 | 116 | public function getNeedEncrypt() 117 | { 118 | return $this->needEncrypt; 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradePrecreateRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 29 | $this->apiParas["biz_content"] = $bizContent; 30 | } 31 | 32 | public function getBizContent() 33 | { 34 | return $this->bizContent; 35 | } 36 | 37 | public function getApiMethodName() 38 | { 39 | return "alipay.trade.precreate"; 40 | } 41 | 42 | public function setNotifyUrl($notifyUrl) 43 | { 44 | $this->notifyUrl=$notifyUrl; 45 | } 46 | 47 | public function getNotifyUrl() 48 | { 49 | return $this->notifyUrl; 50 | } 51 | 52 | public function setReturnUrl($returnUrl) 53 | { 54 | $this->returnUrl=$returnUrl; 55 | } 56 | 57 | public function getReturnUrl() 58 | { 59 | return $this->returnUrl; 60 | } 61 | 62 | public function getApiParas() 63 | { 64 | return $this->apiParas; 65 | } 66 | 67 | public function getTerminalType() 68 | { 69 | return $this->terminalType; 70 | } 71 | 72 | public function setTerminalType($terminalType) 73 | { 74 | $this->terminalType = $terminalType; 75 | } 76 | 77 | public function getTerminalInfo() 78 | { 79 | return $this->terminalInfo; 80 | } 81 | 82 | public function setTerminalInfo($terminalInfo) 83 | { 84 | $this->terminalInfo = $terminalInfo; 85 | } 86 | 87 | public function getProdCode() 88 | { 89 | return $this->prodCode; 90 | } 91 | 92 | public function setProdCode($prodCode) 93 | { 94 | $this->prodCode = $prodCode; 95 | } 96 | 97 | public function setApiVersion($apiVersion) 98 | { 99 | $this->apiVersion=$apiVersion; 100 | } 101 | 102 | public function getApiVersion() 103 | { 104 | return $this->apiVersion; 105 | } 106 | 107 | public function setNeedEncrypt($needEncrypt) 108 | { 109 | 110 | $this->needEncrypt=$needEncrypt; 111 | 112 | } 113 | 114 | public function getNeedEncrypt() 115 | { 116 | return $this->needEncrypt; 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeVendorpayDevicedataUploadRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 28 | $this->apiParas["biz_content"] = $bizContent; 29 | } 30 | 31 | public function getBizContent() 32 | { 33 | return $this->bizContent; 34 | } 35 | 36 | public function getApiMethodName() 37 | { 38 | return "alipay.trade.vendorpay.devicedata.upload"; 39 | } 40 | 41 | public function setNotifyUrl($notifyUrl) 42 | { 43 | $this->notifyUrl=$notifyUrl; 44 | } 45 | 46 | public function getNotifyUrl() 47 | { 48 | return $this->notifyUrl; 49 | } 50 | 51 | public function setReturnUrl($returnUrl) 52 | { 53 | $this->returnUrl=$returnUrl; 54 | } 55 | 56 | public function getReturnUrl() 57 | { 58 | return $this->returnUrl; 59 | } 60 | 61 | public function getApiParas() 62 | { 63 | return $this->apiParas; 64 | } 65 | 66 | public function getTerminalType() 67 | { 68 | return $this->terminalType; 69 | } 70 | 71 | public function setTerminalType($terminalType) 72 | { 73 | $this->terminalType = $terminalType; 74 | } 75 | 76 | public function getTerminalInfo() 77 | { 78 | return $this->terminalInfo; 79 | } 80 | 81 | public function setTerminalInfo($terminalInfo) 82 | { 83 | $this->terminalInfo = $terminalInfo; 84 | } 85 | 86 | public function getProdCode() 87 | { 88 | return $this->prodCode; 89 | } 90 | 91 | public function setProdCode($prodCode) 92 | { 93 | $this->prodCode = $prodCode; 94 | } 95 | 96 | public function setApiVersion($apiVersion) 97 | { 98 | $this->apiVersion=$apiVersion; 99 | } 100 | 101 | public function getApiVersion() 102 | { 103 | return $this->apiVersion; 104 | } 105 | 106 | public function setNeedEncrypt($needEncrypt) 107 | { 108 | 109 | $this->needEncrypt=$needEncrypt; 110 | 111 | } 112 | 113 | public function getNeedEncrypt() 114 | { 115 | return $this->needEncrypt; 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayTradeFastpayRefundQueryRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 29 | $this->apiParas["biz_content"] = $bizContent; 30 | } 31 | 32 | public function getBizContent() 33 | { 34 | return $this->bizContent; 35 | } 36 | 37 | public function getApiMethodName() 38 | { 39 | return "alipay.trade.fastpay.refund.query"; 40 | } 41 | 42 | public function setNotifyUrl($notifyUrl) 43 | { 44 | $this->notifyUrl=$notifyUrl; 45 | } 46 | 47 | public function getNotifyUrl() 48 | { 49 | return $this->notifyUrl; 50 | } 51 | 52 | public function setReturnUrl($returnUrl) 53 | { 54 | $this->returnUrl=$returnUrl; 55 | } 56 | 57 | public function getReturnUrl() 58 | { 59 | return $this->returnUrl; 60 | } 61 | 62 | public function getApiParas() 63 | { 64 | return $this->apiParas; 65 | } 66 | 67 | public function getTerminalType() 68 | { 69 | return $this->terminalType; 70 | } 71 | 72 | public function setTerminalType($terminalType) 73 | { 74 | $this->terminalType = $terminalType; 75 | } 76 | 77 | public function getTerminalInfo() 78 | { 79 | return $this->terminalInfo; 80 | } 81 | 82 | public function setTerminalInfo($terminalInfo) 83 | { 84 | $this->terminalInfo = $terminalInfo; 85 | } 86 | 87 | public function getProdCode() 88 | { 89 | return $this->prodCode; 90 | } 91 | 92 | public function setProdCode($prodCode) 93 | { 94 | $this->prodCode = $prodCode; 95 | } 96 | 97 | public function setApiVersion($apiVersion) 98 | { 99 | $this->apiVersion=$apiVersion; 100 | } 101 | 102 | public function getApiVersion() 103 | { 104 | return $this->apiVersion; 105 | } 106 | 107 | public function setNeedEncrypt($needEncrypt) 108 | { 109 | 110 | $this->needEncrypt=$needEncrypt; 111 | 112 | } 113 | 114 | public function getNeedEncrypt() 115 | { 116 | return $this->needEncrypt; 117 | } 118 | 119 | } 120 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/request/AlipayDataDataserviceBillDownloadurlQueryRequest.php: -------------------------------------------------------------------------------- 1 | bizContent = $bizContent; 30 | $this->apiParas["biz_content"] = $bizContent; 31 | } 32 | 33 | public function getBizContent() 34 | { 35 | return $this->bizContent; 36 | } 37 | 38 | public function getApiMethodName() 39 | { 40 | return "alipay.data.dataservice.bill.downloadurl.query"; 41 | } 42 | 43 | public function setNotifyUrl($notifyUrl) 44 | { 45 | $this->notifyUrl=$notifyUrl; 46 | } 47 | 48 | public function getNotifyUrl() 49 | { 50 | return $this->notifyUrl; 51 | } 52 | 53 | public function setReturnUrl($returnUrl) 54 | { 55 | $this->returnUrl=$returnUrl; 56 | } 57 | 58 | public function getReturnUrl() 59 | { 60 | return $this->returnUrl; 61 | } 62 | 63 | public function getApiParas() 64 | { 65 | return $this->apiParas; 66 | } 67 | 68 | public function getTerminalType() 69 | { 70 | return $this->terminalType; 71 | } 72 | 73 | public function setTerminalType($terminalType) 74 | { 75 | $this->terminalType = $terminalType; 76 | } 77 | 78 | public function getTerminalInfo() 79 | { 80 | return $this->terminalInfo; 81 | } 82 | 83 | public function setTerminalInfo($terminalInfo) 84 | { 85 | $this->terminalInfo = $terminalInfo; 86 | } 87 | 88 | public function getProdCode() 89 | { 90 | return $this->prodCode; 91 | } 92 | 93 | public function setProdCode($prodCode) 94 | { 95 | $this->prodCode = $prodCode; 96 | } 97 | 98 | public function setApiVersion($apiVersion) 99 | { 100 | $this->apiVersion=$apiVersion; 101 | } 102 | 103 | public function getApiVersion() 104 | { 105 | return $this->apiVersion; 106 | } 107 | 108 | public function setNeedEncrypt($needEncrypt) 109 | { 110 | 111 | $this->needEncrypt=$needEncrypt; 112 | 113 | } 114 | 115 | public function getNeedEncrypt() 116 | { 117 | return $this->needEncrypt; 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/buildermodel/AlipayTradePagePayContentBuilder.php: -------------------------------------------------------------------------------- 1 | bizContentarr)){ 41 | $this->bizContent = json_encode($this->bizContentarr,JSON_UNESCAPED_UNICODE); 42 | } 43 | return $this->bizContent; 44 | } 45 | 46 | public function __construct() 47 | { 48 | $this->bizContentarr['product_code'] = "FAST_INSTANT_TRADE_PAY"; 49 | } 50 | 51 | public function AlipayTradeWapPayContentBuilder() 52 | { 53 | $this->__construct(); 54 | } 55 | 56 | public function getBody() 57 | { 58 | return $this->body; 59 | } 60 | 61 | public function setBody($body) 62 | { 63 | $this->body = $body; 64 | $this->bizContentarr['body'] = $body; 65 | } 66 | 67 | public function setSubject($subject) 68 | { 69 | $this->subject = $subject; 70 | $this->bizContentarr['subject'] = $subject; 71 | } 72 | 73 | /** 74 | * @param mixed $passback_params 75 | */ 76 | public function setPassbackParams($passback_params) 77 | { 78 | $this->passback_params = $passback_params; 79 | $this->bizContentarr['passback_params'] = $passback_params; 80 | } 81 | 82 | /** 83 | * @return mixed 84 | */ 85 | public function getPassbackParams() 86 | { 87 | return $this->passback_params; 88 | } 89 | 90 | 91 | 92 | public function getSubject() 93 | { 94 | return $this->subject; 95 | } 96 | 97 | public function getOutTradeNo() 98 | { 99 | return $this->outTradeNo; 100 | } 101 | 102 | public function setOutTradeNo($outTradeNo) 103 | { 104 | $this->outTradeNo = $outTradeNo; 105 | $this->bizContentarr['out_trade_no'] = $outTradeNo; 106 | } 107 | 108 | public function setTimeExpress($timeExpress) 109 | { 110 | $this->timeExpress = $timeExpress; 111 | $this->bizContentarr['timeout_express'] = $timeExpress; 112 | } 113 | 114 | public function getTimeExpress() 115 | { 116 | return $this->timeExpress; 117 | } 118 | 119 | public function setTotalAmount($totalAmount) 120 | { 121 | $this->totalAmount = $totalAmount; 122 | $this->bizContentarr['total_amount'] = $totalAmount; 123 | } 124 | 125 | public function getTotalAmount() 126 | { 127 | return $this->totalAmount; 128 | } 129 | 130 | } 131 | 132 | ?> -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/test/TestImage.php: -------------------------------------------------------------------------------- 1 | serverUrl, 42 | $this -> appId, 43 | $this -> partner_private_key, 44 | $this -> format, 45 | $this -> charset 46 | ); 47 | $response = null; 48 | $outputStream = null; 49 | $request = $alipayClient -> getContents() ; 50 | 51 | //200 52 | //echo( '状态码:'. $request -> getCode() .', '); 53 | //echo '



'; 54 | 55 | $fileType = $request -> getType(); 56 | //echo( '类型:'. $fileType .', '); 57 | if( $fileType == 'text/plain'){ 58 | //出错,返回 json 59 | echo $request -> getBody(); 60 | 61 | }else{ 62 | 63 | $type = $request -> getFileSuffix( $fileType ); 64 | 65 | //echo $this -> getParams(); 66 | //exit(); 67 | 68 | //返回 文件流 69 | header("Content-type: ". $fileType ); //类型 70 | 71 | 72 | header("Accept-Ranges: bytes");//告诉客户端浏览器返回的文件大小是按照字节进行计算的 73 | header("Accept-Length: ". $request -> getContentLength() );//文件大小 74 | header("Content-Length: ". $request -> getContentLength() );//文件大小 75 | header('Content-Disposition: attachment; filename="'. time() .'.'. $type .'"'); //文件名 76 | echo $request -> getBody() ; 77 | exit ( ) ; 78 | } 79 | 80 | //echo( '内容: , '. $request -> getContentLength() ); 81 | 82 | //echo '



'; 83 | //echo '参数:
';
84 | 
85 | 		//echo ($request -> getParams());
86 | 
87 | 		//echo '
' ; 88 | } 89 | } 90 | 91 | 92 | 93 | 94 | 95 | // 测试 96 | $test1 = new TestImage(); 97 | $test1 -> load(); 98 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/AlipaySdk.php: -------------------------------------------------------------------------------- 1 | config = $config; 29 | $this->aop = new AlipayTradeService($config); 30 | } 31 | 32 | /** 33 | * 支付接口 支持自定义数据传输 34 | * @param $subject 35 | * @param $body 36 | * @param $out_trade_no 37 | * @param $total_amount 38 | * @param $customData 自定义数据 39 | * @return bool|提交表单HTML文本|mixed|\SimpleXMLElement|string 40 | */ 41 | public function tradePagePay($subject, $body, $out_trade_no, $total_amount, $customData) 42 | { 43 | $payRequestBuilder = new AlipayTradePagePayContentBuilder(); 44 | $payRequestBuilder->setBody($body); 45 | $payRequestBuilder->setSubject($subject); 46 | $payRequestBuilder->setTotalAmount($total_amount); 47 | $payRequestBuilder->setOutTradeNo($out_trade_no); 48 | $payRequestBuilder->setPassbackParams($customData); 49 | $response = $this->aop->pagePay($payRequestBuilder, $this->config['return_url'], $this->config['notify_url'], $this->config['trade_pay_type']); 50 | 51 | return $response; 52 | } 53 | 54 | /** 55 | * 退款接口 56 | * @param $out_trade_no//商户订单号,商户网站订单系统中唯一订单号 57 | * @param $refund_amount//需要退款的金额,该金额不能大于订单金额,必填 58 | * @param $refund_reason//退款的原因说明 59 | * @param string $out_request_no//标识一次退款请求,同一笔交易多次退款需要保证唯一,如需部分退款,则此参数必传 60 | * @return bool|提交表单HTML文本|mixed|\SimpleXMLElement|\SimpleXMLElement[]|string 61 | */ 62 | public function tradeRefund($out_trade_no, $refund_amount, $refund_reason, $out_request_no = '') 63 | { 64 | $RequestBuilder = new AlipayTradeRefundContentBuilder(); 65 | 66 | $RequestBuilder->setOutTradeNo($out_trade_no); 67 | //$RequestBuilder->setTradeNo($trade_no); 68 | $RequestBuilder->setRefundAmount($refund_amount); 69 | $RequestBuilder->setOutRequestNo($out_request_no); 70 | $RequestBuilder->setRefundReason($refund_reason); 71 | 72 | $response = $this->aop->Refund($RequestBuilder); 73 | return $response; 74 | } 75 | 76 | /** 77 | * 支付交易查询接口,用于查询交易是否交易成功 78 | * @param $out_trade_no 79 | * @return bool|提交表单HTML文本|mixed|\SimpleXMLElement|\SimpleXMLElement[]|string 80 | */ 81 | public function tradePayQuery($out_trade_no) 82 | { 83 | $RequestBuilder = new AlipayTradeQueryContentBuilder(); 84 | $RequestBuilder->setOutTradeNo($out_trade_no); 85 | //$RequestBuilder->setTradeNo($trade_no); 86 | 87 | $response = $this->aop->Query($RequestBuilder); 88 | return $response; 89 | } 90 | 91 | /** 92 | * 退款查询接口 93 | * @param $out_trade_no//商户订单号,商户网站订单系统中唯一订单号 94 | * @param $out_request_no//请求退款接口时,传入的退款请求号,如果在退款请求时未传入,则该值为创建交易时的外部交易号,必填 95 | * @return bool|提交表单HTML文本|mixed|\SimpleXMLElement|string 96 | */ 97 | public function refundQuery($out_trade_no, $out_request_no) 98 | { 99 | $RequestBuilder=new AlipayTradeFastpayRefundQueryContentBuilder(); 100 | $RequestBuilder->setOutTradeNo($out_trade_no); 101 | //$RequestBuilder->setTradeNo($trade_no); 102 | $RequestBuilder->setOutRequestNo($out_request_no); 103 | 104 | $response = $this->aop->refundQuery($RequestBuilder); 105 | return $response; 106 | } 107 | 108 | /** 109 | * 关闭订单接口 110 | * @param $out_trade_no 111 | * @return bool|提交表单HTML文本|mixed|\SimpleXMLElement|\SimpleXMLElement[]|string 112 | */ 113 | public function Close($out_trade_no) 114 | { 115 | $RequestBuilder=new AlipayTradeCloseContentBuilder(); 116 | $RequestBuilder->setOutTradeNo($out_trade_no); 117 | //$RequestBuilder->setTradeNo($trade_no); 118 | 119 | $response = $this->aop->Close($RequestBuilder); 120 | return $response; 121 | } 122 | 123 | /** 124 | * 异步通知验证 125 | * @param $requestData 126 | * @return bool 127 | */ 128 | public function notify($requestData) 129 | { 130 | $this->aop->writeLog(var_export($requestData,true)); 131 | return $this->aop->check($requestData); 132 | } 133 | } -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/AlipayMobilePublicMultiMediaClient.php: -------------------------------------------------------------------------------- 1 | serverUrl = $serverUrl; 42 | $this -> appId = $appId; 43 | $this -> privateKey = $partner_private_key; 44 | $this -> format = $format; 45 | $this -> charset = $charset; 46 | } 47 | 48 | /** 49 | * getContents 获取网址内容 50 | * @param $request 51 | * @return text | bin 52 | */ 53 | public function getContents(){ 54 | //自己的服务器如果没有 curl,可用:fsockopen() 等 55 | 56 | 57 | //1: 58 | //2: 私钥格式 59 | $datas = array( 60 | "app_id" => $this -> appId, 61 | "method" => $this -> METHOD_POST, 62 | "sign_type" => $this -> sign_type, 63 | "version" => $this -> apiVersion, 64 | "timestamp" => date('Y-m-d H:i:s') ,//yyyy-MM-dd HH:mm:ss 65 | "biz_content" => '{"mediaId":"'. $this -> media_id .'"}', 66 | "charset" => $this -> charset 67 | ); 68 | 69 | 70 | 71 | //要提交的数据 72 | $data_sign = $this -> buildGetUrl( $datas ); 73 | 74 | $post_data = $data_sign; 75 | //初始化 curl 76 | $ch = curl_init(); 77 | //设置目标服务器 78 | curl_setopt($ch, CURLOPT_URL, $this -> serverUrl ); 79 | curl_setopt($ch, CURLOPT_HEADER, TRUE); 80 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 81 | //超时时间 82 | curl_setopt($ch, CURLOPT_TIMEOUT, $this-> timeout); 83 | 84 | if( $this-> METHOD_POST == 'POST'){ 85 | // post数据 86 | curl_setopt($ch, CURLOPT_POST, 1); 87 | // post的变量 88 | curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); 89 | } 90 | 91 | 92 | 93 | 94 | $output = curl_exec($ch); 95 | $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 96 | curl_close($ch); 97 | 98 | echo $output; 99 | 100 | //分离头部 101 | //list($header, $body) = explode("\r\n\r\n", $output, 2); 102 | $datas = explode("\r\n\r\n", $output, 2); 103 | $header = $datas[0]; 104 | 105 | if( $httpCode == '200'){ 106 | $body = $datas[1]; 107 | }else{ 108 | $body = ''; 109 | 110 | } 111 | 112 | 113 | 114 | 115 | return $this -> execute( $header, $body, $httpCode ); 116 | } 117 | 118 | /** 119 | * 120 | * @param $request 121 | * @return text | bin 122 | */ 123 | public function execute( $header = '', $body = '', $httpCode = '' ){ 124 | $exe = new AlipayMobilePublicMultiMediaExecute( $header, $body, $httpCode ); 125 | return $exe; 126 | } 127 | 128 | public function buildGetUrl( $query = array() ){ 129 | 130 | if( ! is_array( $query ) ){ 131 | //exit; 132 | } 133 | 134 | //排序参数, 135 | $data = $this -> buildQuery( $query ); 136 | 137 | 138 | 139 | // 私钥密码 140 | $passphrase = ''; 141 | $key_width = 64; 142 | 143 | //私钥 144 | $privateKey = $this -> privateKey; 145 | $p_key = array(); 146 | //如果私钥是 1行 147 | if( ! stripos( $privateKey, "\n" ) ){ 148 | $i = 0; 149 | while( $key_str = substr( $privateKey , $i * $key_width , $key_width) ){ 150 | $p_key[] = $key_str; 151 | $i ++ ; 152 | } 153 | }else{ 154 | //echo '一行?'; 155 | } 156 | $privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" . implode("\n", $p_key) ; 157 | $privateKey = $privateKey ."\n-----END RSA PRIVATE KEY-----"; 158 | 159 | // echo "\n\n私钥:\n"; 160 | // echo( $privateKey ); 161 | // echo "\n\n\n"; 162 | 163 | //私钥 164 | $private_id = openssl_pkey_get_private( $privateKey , $passphrase); 165 | 166 | 167 | // 签名 168 | $signature = ''; 169 | 170 | if("RSA2"==$this->sign_type){ 171 | 172 | openssl_sign($data, $signature, $private_id, OPENSSL_ALGO_SHA256 ); 173 | }else{ 174 | 175 | openssl_sign($data, $signature, $private_id, OPENSSL_ALGO_SHA1 ); 176 | } 177 | 178 | openssl_free_key( $private_id ); 179 | 180 | //加密后的内容通常含有特殊字符,需要编码转换下 181 | $signature = base64_encode($signature); 182 | 183 | $signature = urlencode( $signature ); 184 | 185 | //$signature = 'XjUN6YM1Mc9HXebKMv7GTLy7gmyhktyOgKk2/Jf+cz4DtP6udkzTdpkjW2j/Z4ZSD7xD6CNYI1Spz4yS93HPT0a5X9LgFWYY8SaADqe+ArXg+FBSiTwUz49SE//Xd9+LEiIRsSFkbpkuiGoO6mqJmB7vXjlD5lx6qCM3nb41wb8='; 186 | 187 | $out = $data .'&'. $this -> SIGN .'='. $signature; 188 | 189 | // echo "\n\n 加密后:\n"; 190 | // echo( $out ); 191 | // echo "\n\n\n"; 192 | 193 | return $out ; 194 | } 195 | 196 | /* 197 | * 查询参数排序 a-z 198 | * */ 199 | public function buildQuery( $query ){ 200 | if ( !$query ) { 201 | return null; 202 | } 203 | 204 | //将要 参数 排序 205 | ksort( $query ); 206 | 207 | //重新组装参数 208 | $params = array(); 209 | foreach($query as $key => $value){ 210 | $params[] = $key .'='. $value ; 211 | } 212 | $data = implode('&', $params); 213 | 214 | return $data; 215 | 216 | } 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | } 232 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # alipay-laravel5 支付宝电脑网站支付 2 | **根据支付宝最新版 电脑网站支付接口SDK 整合laravel5** 3 | 4 | 5 | ## 安装 6 | 7 | 首先安装 [Composer](http://getcomposer.org/). 已安装请忽略。 8 | 在 `composer.json` 文件中添加: 9 | 10 | "echobool/alipay-laravel5": "dev-master" 11 | 12 | 然后执行composer进行安装: 13 | 14 | $ composer update -vvv 15 | 或直接: 16 | 17 | $ composer require "echobool/alipay-laravel5:dev-master" 18 | 在app.php中加上 19 | 20 | EchoBool\AlipayLaravel\AlipayServiceProvider::class, 21 | 22 | 更新配置 23 | 24 | php artisan config:cache 25 | 26 | 发布配置文件 27 | 28 | $ php artisan vendor:publish --provider="EchoBool\AlipayLaravel\AlipayServiceProvider" 29 | 30 | 如果出现 EchoBool\AlipayLaravel\AlipayServiceProvider not found 则运行下面代码再发布 31 | 32 | $ composer dump-autoload --optimize 33 | 34 | ## 支持 35 | 支付支持表单提交和Curl后台提交方式 36 | 37 | 当配置文件中 trade_pay_type=>true 时为表单提交 默认CURL提交。 38 | 39 | 支持交易查询操作 40 | 41 | 支持退款操作 42 | 43 | 支持退款查询操作 44 | 45 | 支持交易关闭操作 46 | 47 | ## 用法 48 | 49 | 先将config/alipay-web.php 中各项配置好 50 | 51 | ```php 52 | //文件头use一下 53 | use EchoBool\AlipayLaravel\Facades\Alipay; 54 | 55 | /** 56 | * 支付 57 | * @param Request $request 58 | * @return mixed 59 | */ 60 | public function goPay(Request $request) 61 | { 62 | //商户订单号,商户网站订单系统中唯一订单号,必填 63 | $out_trade_no = date('YmdHis') . '00045623'; 64 | //订单名称,必填 65 | $subject = '锁贸通任务ID448'; 66 | //付款金额,必填 67 | $total_amount = 0.01; 68 | //商品描述,可空 69 | $body = 'macbook pro2'; 70 | 71 | $customData = json_encode(['model_name' => 'ewrwe', 'id' => 121]);//自定义参数 72 | $response = Alipay::tradePagePay($subject, $body, $out_trade_no, $total_amount, $customData); 73 | //输出表单 74 | return $response['redirect_url']; 75 | } 76 | 77 | 78 | /** 79 | * 退款 80 | * @param Request $request 81 | */ 82 | public function refund(Request $request) 83 | { 84 | //商户订单号 85 | $out_trade_no = $request->get('trade_no'); 86 | $refund_amount = 0.01; 87 | $refund_reason = '任务取消退款'; 88 | $out_request_no = '201'; 89 | $response = Alipay::tradeRefund($out_trade_no, $refund_amount, $refund_reason, $out_request_no); 90 | dd($response); 91 | } 92 | 93 | /** 94 | * 退款查询 95 | * @param Request $request 96 | */ 97 | public function refundQuery(Request $request) 98 | { 99 | //商户订单号 100 | $out_trade_no = $request->get('trade_no'); 101 | $out_request_no = $request->get('out_request_no'); 102 | 103 | $response = Alipay::refundQuery($out_trade_no,$out_request_no); 104 | dd($response); 105 | } 106 | 107 | /** 108 | * 交易是否成功查询 109 | * @param Request $request 110 | */ 111 | public function tradePayQuery(Request $request) 112 | { 113 | //商户订单号 114 | $out_trade_no = $request->get('trade_no'); 115 | $response = Alipay::tradePayQuery($out_trade_no); 116 | dd($response); 117 | } 118 | 119 | /** 120 | * 交易关闭 121 | * @param Request $request 122 | */ 123 | public function tradeClose(Request $request) 124 | { 125 | //商户订单号 126 | $out_trade_no = $request->get('trade_no'); 127 | $response = Alipay::Close($out_trade_no); 128 | dd($response); 129 | } 130 | 131 | /** 132 | * 异步通知 133 | * @param Request $request 134 | */ 135 | public function notify(Request $request) 136 | { 137 | $result = Alipay::notify($_POST); 138 | /* 实际验证过程建议商户添加以下校验。 139 | 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号, 140 | 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 141 | 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email) 142 | 4、验证app_id是否为该商户本身。 143 | */ 144 | if ($result) {//验证成功 145 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 146 | //请在这里加上商户的业务逻辑程序代 147 | 148 | 149 | //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— 150 | 151 | //获取支付宝的通知返回参数,可参考技术文档中服务器异步通知参数列表 152 | 153 | //商户订单号 154 | 155 | $out_trade_no = $_POST['out_trade_no']; 156 | 157 | //支付宝交易号 158 | 159 | $trade_no = $_POST['trade_no']; 160 | 161 | //交易状态 162 | $trade_status = $_POST['trade_status']; 163 | 164 | 165 | if ($_POST['trade_status'] == 'TRADE_FINISHED') { 166 | 167 | //判断该笔订单是否在商户网站中已经做过处理 168 | //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 169 | //请务必判断请求时的total_amount与通知时获取的total_fee为一致的 170 | //如果有做过处理,不执行商户的业务程序 171 | 172 | //注意: 173 | //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 174 | } else if ($_POST['trade_status'] == 'TRADE_SUCCESS') { 175 | //判断该笔订单是否在商户网站中已经做过处理 176 | //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 177 | //请务必判断请求时的total_amount与通知时获取的total_fee为一致的 178 | //如果有做过处理,不执行商户的业务程序 179 | //注意: 180 | //付款完成后,支付宝系统发送该交易状态通知 181 | } 182 | //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— 183 | echo "success"; //请不要修改或删除 184 | } else { 185 | //验证失败 186 | echo "fail"; 187 | 188 | } 189 | } 190 | 191 | 192 | /** 193 | * 同步通知 即支付成功后跳转到return_url 上时进行验证 如果支付方式是CURL方式将不会跳转 请注意 194 | * @param Request $request 195 | */ 196 | public function returnUrl(Request $request) 197 | { 198 | $result = Alipay::notify($_GET); 199 | /* 实际验证过程建议商户添加以下校验。 200 | 1、商户需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号, 201 | 2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额), 202 | 3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email) 203 | 4、验证app_id是否为该商户本身。 204 | */ 205 | 206 | if ($result) {//验证成功 207 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 208 | //请在这里加上商户的业务逻辑程序代码 209 | 210 | //——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— 211 | //获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表 212 | 213 | //商户订单号 214 | $out_trade_no = htmlspecialchars($_GET['out_trade_no']); 215 | 216 | //支付宝交易号 217 | $trade_no = htmlspecialchars($_GET['trade_no']); 218 | 219 | echo "验证成功
支付宝交易号:" . $trade_no; 220 | 221 | //——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— 222 | 223 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 224 | } else { 225 | //验证失败 226 | echo "验证失败"; 227 | } 228 | } 229 | ``` 230 | 231 | 232 | -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/service/AlipayTradeService.php: -------------------------------------------------------------------------------- 1 | gateway_url = $alipay_config['gatewayUrl']; 51 | $this->appid = $alipay_config['app_id']; 52 | $this->private_key = $alipay_config['merchant_private_key']; 53 | $this->alipay_public_key = $alipay_config['alipay_public_key']; 54 | $this->charset = $alipay_config['charset']; 55 | $this->signtype = $alipay_config['sign_type']; 56 | 57 | if (empty($this->appid) || trim($this->appid) == "") { 58 | throw new \Exception("appid should not be NULL!"); 59 | } 60 | if (empty($this->private_key) || trim($this->private_key) == "") { 61 | throw new \Exception("private_key should not be NULL!"); 62 | } 63 | if (empty($this->alipay_public_key) || trim($this->alipay_public_key) == "") { 64 | throw new \Exception("alipay_public_key should not be NULL!"); 65 | } 66 | if (empty($this->charset) || trim($this->charset) == "") { 67 | throw new \Exception("charset should not be NULL!"); 68 | } 69 | if (empty($this->gateway_url) || trim($this->gateway_url) == "") { 70 | throw new \Exception("gateway_url should not be NULL!"); 71 | } 72 | 73 | } 74 | 75 | /** 76 | * alipay.trade.page.pay 77 | * @param $builder 业务参数,使用buildmodel中的对象生成。 78 | * @param $return_url 同步跳转地址,公网可以访问 79 | * @param $notify_url 异步通知地址,公网可以访问 80 | * @return $response 支付宝返回的信息 81 | */ 82 | function pagePay($builder, $return_url, $notify_url, $ispage = false) 83 | { 84 | 85 | $biz_content = $builder->getBizContent(); 86 | //打印业务参数 87 | $this->writeLog($biz_content); 88 | 89 | $request = new AlipayTradePagePayRequest(); 90 | $request->setNotifyUrl($notify_url); 91 | $request->setReturnUrl($return_url); 92 | $request->setBizContent($biz_content); 93 | 94 | // 首先调用支付api 95 | $response = $this->aopclientRequestExecute($request, 'tradePay', $ispage); 96 | // $response = $response->alipay_trade_wap_pay_response; 97 | return $response; 98 | } 99 | 100 | /** 101 | * sdkClient 102 | * @param $request 接口请求参数对象。 103 | * @param $ispage 是否是页面接口,电脑网站支付是页面表单接口。 104 | * @return $response 支付宝返回的信息 105 | */ 106 | function aopclientRequestExecute($request, $action = '', $ispage = false) 107 | { 108 | $aop = new AopClient (); 109 | $aop->gatewayUrl = $this->gateway_url; 110 | $aop->appId = $this->appid; 111 | $aop->rsaPrivateKey = $this->private_key; 112 | $aop->alipayrsaPublicKey = $this->alipay_public_key; 113 | $aop->apiVersion = "1.0"; 114 | $aop->postCharset = $this->charset; 115 | $aop->format = $this->format; 116 | $aop->signType = $this->signtype; 117 | // 开启页面信息输出 118 | $aop->debugInfo = true; 119 | if ($ispage) { 120 | $result = $aop->pageExecute($request, "post"); 121 | echo $result; 122 | } else { 123 | if ($action == 'tradePay') { 124 | $result = $aop->smtExecute($request); 125 | } else { 126 | $result = $aop->execute($request); 127 | } 128 | 129 | } 130 | 131 | //打开后,将报文写入log文件 132 | $this->writeLog("romotresponse: " . var_export($result, true)); 133 | return $result; 134 | } 135 | 136 | /** 137 | * alipay.trade.query (统一收单线下交易查询) 138 | * @param $builder 业务参数,使用buildmodel中的对象生成。 139 | * @return $response 支付宝返回的信息 140 | */ 141 | function Query($builder) 142 | { 143 | $biz_content = $builder->getBizContent(); 144 | //打印业务参数 145 | $this->writeLog($biz_content); 146 | $request = new AlipayTradeQueryRequest(); 147 | $request->setBizContent($biz_content); 148 | 149 | $response = $this->aopclientRequestExecute($request); 150 | $response = $response->alipay_trade_query_response; 151 | return $response; 152 | } 153 | 154 | /** 155 | * alipay.trade.refund (统一收单交易退款接口) 156 | * @param $builder 业务参数,使用buildmodel中的对象生成。 157 | * @return $response 支付宝返回的信息 158 | */ 159 | function Refund($builder) 160 | { 161 | $biz_content = $builder->getBizContent(); 162 | //打印业务参数 163 | $this->writeLog($biz_content); 164 | $request = new AlipayTradeRefundRequest(); 165 | $request->setBizContent($biz_content); 166 | 167 | $response = $this->aopclientRequestExecute($request); 168 | 169 | $response = $response->alipay_trade_refund_response; 170 | return $response; 171 | } 172 | 173 | /** 174 | * alipay.trade.close (统一收单交易关闭接口) 175 | * @param $builder 业务参数,使用buildmodel中的对象生成。 176 | * @return $response 支付宝返回的信息 177 | */ 178 | function Close($builder) 179 | { 180 | $biz_content = $builder->getBizContent(); 181 | //打印业务参数 182 | $this->writeLog($biz_content); 183 | $request = new AlipayTradeCloseRequest(); 184 | $request->setBizContent($biz_content); 185 | 186 | $response = $this->aopclientRequestExecute($request); 187 | $response = $response->alipay_trade_close_response; 188 | return $response; 189 | } 190 | 191 | /** 192 | * 退款查询 alipay.trade.fastpay.refund.query (统一收单交易退款查询) 193 | * @param $builder 业务参数,使用buildmodel中的对象生成。 194 | * @return $response 支付宝返回的信息 195 | */ 196 | function refundQuery($builder) 197 | { 198 | $biz_content = $builder->getBizContent(); 199 | //打印业务参数 200 | $this->writeLog($biz_content); 201 | $request = new AlipayTradeFastpayRefundQueryRequest(); 202 | $request->setBizContent($biz_content); 203 | 204 | $response = $this->aopclientRequestExecute($request); 205 | return $response; 206 | } 207 | 208 | /** 209 | * alipay.data.dataservice.bill.downloadurl.query (查询对账单下载地址) 210 | * @param $builder 业务参数,使用buildmodel中的对象生成。 211 | * @return $response 支付宝返回的信息 212 | */ 213 | function downloadurlQuery($builder) 214 | { 215 | $biz_content = $builder->getBizContent(); 216 | //打印业务参数 217 | $this->writeLog($biz_content); 218 | $request = new AlipayDataDataserviceBillDownloadurlQueryRequest(); 219 | $request->setBizContent($biz_content); 220 | 221 | $response = $this->aopclientRequestExecute($request); 222 | $response = $response->alipay_data_dataservice_bill_downloadurl_query_response; 223 | return $response; 224 | } 225 | 226 | /** 227 | * 验签方法 228 | * @param $arr 验签支付宝返回的信息,使用支付宝公钥。 229 | * @return boolean 230 | */ 231 | function check($arr) 232 | { 233 | $aop = new AopClient(); 234 | $aop->alipayrsaPublicKey = $this->alipay_public_key; 235 | $result = $aop->rsaCheckV1($arr, $this->alipay_public_key, $this->signtype); 236 | 237 | return $result; 238 | } 239 | 240 | /** 241 | * 请确保项目文件有可写权限,不然打印不了日志。 242 | */ 243 | function writeLog($text) 244 | { 245 | \Illuminate\Support\Facades\Log::info($text); 246 | } 247 | } 248 | 249 | ?> -------------------------------------------------------------------------------- /src/EchoBool/AlipayLaravel/aop/AopClient.php: -------------------------------------------------------------------------------- 1 | sign($this->getSignContent($params), $signType); 65 | } 66 | 67 | public function rsaSign($params, $signType = "RSA") { 68 | return $this->sign($this->getSignContent($params), $signType); 69 | } 70 | 71 | public function getSignContent($params) { 72 | ksort($params); 73 | 74 | $stringToBeSigned = ""; 75 | $i = 0; 76 | foreach ($params as $k => $v) { 77 | if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { 78 | 79 | // 转换成目标字符集 80 | $v = $this->characet($v, $this->postCharset); 81 | 82 | if ($i == 0) { 83 | $stringToBeSigned .= "$k" . "=" . "$v"; 84 | } else { 85 | $stringToBeSigned .= "&" . "$k" . "=" . "$v"; 86 | } 87 | $i++; 88 | } 89 | } 90 | 91 | unset ($k, $v); 92 | return $stringToBeSigned; 93 | } 94 | 95 | 96 | //此方法对value做urlencode 97 | public function getSignContentUrlencode($params) { 98 | ksort($params); 99 | 100 | $stringToBeSigned = ""; 101 | $i = 0; 102 | foreach ($params as $k => $v) { 103 | if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { 104 | 105 | // 转换成目标字符集 106 | $v = $this->characet($v, $this->postCharset); 107 | 108 | if ($i == 0) { 109 | $stringToBeSigned .= "$k" . "=" . urlencode($v); 110 | } else { 111 | $stringToBeSigned .= "&" . "$k" . "=" . urlencode($v); 112 | } 113 | $i++; 114 | } 115 | } 116 | 117 | unset ($k, $v); 118 | return $stringToBeSigned; 119 | } 120 | 121 | protected function sign($data, $signType = "RSA") { 122 | if($this->checkEmpty($this->rsaPrivateKeyFilePath)){ 123 | $priKey=$this->rsaPrivateKey; 124 | $res = "-----BEGIN RSA PRIVATE KEY-----\n" . 125 | wordwrap($priKey, 64, "\n", true) . 126 | "\n-----END RSA PRIVATE KEY-----"; 127 | }else { 128 | $priKey = file_get_contents($this->rsaPrivateKeyFilePath); 129 | $res = openssl_get_privatekey($priKey); 130 | } 131 | 132 | ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); 133 | 134 | if ("RSA2" == $signType) { 135 | openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); 136 | } else { 137 | openssl_sign($data, $sign, $res); 138 | } 139 | 140 | if(!$this->checkEmpty($this->rsaPrivateKeyFilePath)){ 141 | openssl_free_key($res); 142 | } 143 | $sign = base64_encode($sign); 144 | return $sign; 145 | } 146 | 147 | /** 148 | * RSA单独签名方法,未做字符串处理,字符串处理见getSignContent() 149 | * @param $data 待签名字符串 150 | * @param $privatekey 商户私钥,根据keyfromfile来判断是读取字符串还是读取文件,false:填写私钥字符串去回车和空格 true:填写私钥文件路径 151 | * @param $signType 签名方式,RSA:SHA1 RSA2:SHA256 152 | * @param $keyfromfile 私钥获取方式,读取字符串还是读文件 153 | * @return string 154 | * @author mengyu.wh 155 | */ 156 | public function alonersaSign($data,$privatekey,$signType = "RSA",$keyfromfile=false) { 157 | 158 | if(!$keyfromfile){ 159 | $priKey=$privatekey; 160 | $res = "-----BEGIN RSA PRIVATE KEY-----\n" . 161 | wordwrap($priKey, 64, "\n", true) . 162 | "\n-----END RSA PRIVATE KEY-----"; 163 | } 164 | else{ 165 | $priKey = file_get_contents($privatekey); 166 | $res = openssl_get_privatekey($priKey); 167 | } 168 | 169 | ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); 170 | 171 | if ("RSA2" == $signType) { 172 | openssl_sign($data, $sign, $res, OPENSSL_ALGO_SHA256); 173 | } else { 174 | openssl_sign($data, $sign, $res); 175 | } 176 | 177 | if($keyfromfile){ 178 | openssl_free_key($res); 179 | } 180 | $sign = base64_encode($sign); 181 | return $sign; 182 | } 183 | 184 | 185 | protected function curl($url, $postFields = null) { 186 | $ch = curl_init(); 187 | curl_setopt($ch, CURLOPT_URL, $url); 188 | curl_setopt($ch, CURLOPT_FAILONERROR, false); 189 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 190 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 191 | 192 | $postBodyString = ""; 193 | $encodeArray = Array(); 194 | $postMultipart = false; 195 | 196 | 197 | if (is_array($postFields) && 0 < count($postFields)) { 198 | 199 | foreach ($postFields as $k => $v) { 200 | if ("@" != substr($v, 0, 1)) //判断是不是文件上传 201 | { 202 | 203 | $postBodyString .= "$k=" . urlencode($this->characet($v, $this->postCharset)) . "&"; 204 | $encodeArray[$k] = $this->characet($v, $this->postCharset); 205 | } else //文件上传用multipart/form-data,否则用www-form-urlencoded 206 | { 207 | $postMultipart = true; 208 | $encodeArray[$k] = new \CURLFile(substr($v, 1)); 209 | } 210 | 211 | } 212 | unset ($k, $v); 213 | curl_setopt($ch, CURLOPT_POST, true); 214 | if ($postMultipart) { 215 | curl_setopt($ch, CURLOPT_POSTFIELDS, $encodeArray); 216 | } else { 217 | curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1)); 218 | } 219 | } 220 | 221 | if ($postMultipart) { 222 | 223 | $headers = array('content-type: multipart/form-data;charset=' . $this->postCharset . ';boundary=' . $this->getMillisecond()); 224 | } else { 225 | 226 | $headers = array('content-type: application/x-www-form-urlencoded;charset=' . $this->postCharset); 227 | } 228 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 229 | 230 | $reponse = curl_exec($ch); 231 | 232 | if (curl_errno($ch)) { 233 | 234 | throw new \Exception(curl_error($ch), 0); 235 | } else { 236 | $httpStatusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 237 | if (200 !== $httpStatusCode) { 238 | throw new \Exception($reponse, $httpStatusCode); 239 | } 240 | } 241 | 242 | curl_close($ch); 243 | return $reponse; 244 | } 245 | 246 | protected function smt_curl($url, $postFields = null) { 247 | $ch = curl_init(); 248 | curl_setopt($ch, CURLOPT_URL, $url); 249 | curl_setopt($ch, CURLOPT_FAILONERROR, false); 250 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 251 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 252 | 253 | $postBodyString = ""; 254 | $encodeArray = Array(); 255 | $postMultipart = false; 256 | 257 | 258 | if (is_array($postFields) && 0 < count($postFields)) { 259 | 260 | foreach ($postFields as $k => $v) { 261 | if ("@" != substr($v, 0, 1)) //判断是不是文件上传 262 | { 263 | 264 | $postBodyString .= "$k=" . urlencode($this->characet($v, $this->postCharset)) . "&"; 265 | $encodeArray[$k] = $this->characet($v, $this->postCharset); 266 | } else //文件上传用multipart/form-data,否则用www-form-urlencoded 267 | { 268 | $postMultipart = true; 269 | $encodeArray[$k] = new \CURLFile(substr($v, 1)); 270 | } 271 | 272 | } 273 | unset ($k, $v); 274 | curl_setopt($ch, CURLOPT_POST, true); 275 | if ($postMultipart) { 276 | curl_setopt($ch, CURLOPT_POSTFIELDS, $encodeArray); 277 | } else { 278 | curl_setopt($ch, CURLOPT_POSTFIELDS, substr($postBodyString, 0, -1)); 279 | } 280 | } 281 | 282 | if ($postMultipart) { 283 | 284 | $headers = array('content-type: multipart/form-data;charset=' . $this->postCharset . ';boundary=' . $this->getMillisecond()); 285 | } else { 286 | 287 | $headers = array('content-type: application/x-www-form-urlencoded;charset=' . $this->postCharset); 288 | } 289 | curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); 290 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');//获取跳转后的址址 291 | $reponse = curl_exec($ch); 292 | 293 | if (curl_errno($ch)) { 294 | 295 | throw new \Exception(curl_error($ch), 0); 296 | } else { 297 | $curl_info = curl_getinfo($ch); 298 | 299 | } 300 | 301 | curl_close($ch); 302 | return $curl_info; 303 | } 304 | 305 | protected function getMillisecond() { 306 | list($s1, $s2) = explode(' ', microtime()); 307 | return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000); 308 | } 309 | 310 | 311 | protected function logCommunicationError($apiName, $requestUrl, $errorCode, $responseTxt) { 312 | $localIp = isset ($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"] : "CLI"; 313 | 314 | $logData = array( 315 | date("Y-m-d H:i:s"), 316 | $apiName, 317 | $this->appId, 318 | $localIp, 319 | PHP_OS, 320 | $this->alipaySdkVersion, 321 | $requestUrl, 322 | $errorCode, 323 | str_replace("\n", "", $responseTxt) 324 | ); 325 | Log::info($logData); 326 | } 327 | 328 | /** 329 | * 生成用于调用收银台SDK的字符串 330 | * @param $request SDK接口的请求参数对象 331 | * @return string 332 | * @author guofa.tgf 333 | */ 334 | public function sdkExecute($request) { 335 | 336 | $this->setupCharsets($request); 337 | 338 | $params['app_id'] = $this->appId; 339 | $params['method'] = $request->getApiMethodName(); 340 | $params['format'] = $this->format; 341 | $params['sign_type'] = $this->signType; 342 | $params['timestamp'] = date("Y-m-d H:i:s"); 343 | $params['alipay_sdk'] = $this->alipaySdkVersion; 344 | $params['charset'] = $this->postCharset; 345 | 346 | $version = $request->getApiVersion(); 347 | $params['version'] = $this->checkEmpty($version) ? $this->apiVersion : $version; 348 | 349 | if ($notify_url = $request->getNotifyUrl()) { 350 | $params['notify_url'] = $notify_url; 351 | } 352 | 353 | $dict = $request->getApiParas(); 354 | $params['biz_content'] = $dict['biz_content']; 355 | 356 | ksort($params); 357 | 358 | $params['sign'] = $this->generateSign($params, $this->signType); 359 | 360 | foreach ($params as &$value) { 361 | $value = $this->characet($value, $params['charset']); 362 | } 363 | 364 | return http_build_query($params); 365 | } 366 | 367 | /* 368 | 页面提交执行方法 369 | @param:跳转类接口的request; $httpmethod 提交方式。两个值可选:post、get 370 | @return:构建好的、签名后的最终跳转URL(GET)或String形式的form(POST) 371 | auther:笙默 372 | */ 373 | public function pageExecute($request,$httpmethod = "POST") { 374 | 375 | $this->setupCharsets($request); 376 | 377 | if (strcasecmp($this->fileCharset, $this->postCharset)) { 378 | 379 | // writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为postCharset!"); 380 | throw new \Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!"); 381 | } 382 | 383 | $iv=null; 384 | 385 | if(!$this->checkEmpty($request->getApiVersion())){ 386 | $iv=$request->getApiVersion(); 387 | }else{ 388 | $iv=$this->apiVersion; 389 | } 390 | 391 | //组装系统参数 392 | $sysParams["app_id"] = $this->appId; 393 | $sysParams["version"] = $iv; 394 | $sysParams["format"] = $this->format; 395 | $sysParams["sign_type"] = $this->signType; 396 | $sysParams["method"] = $request->getApiMethodName(); 397 | $sysParams["timestamp"] = date("Y-m-d H:i:s"); 398 | $sysParams["alipay_sdk"] = $this->alipaySdkVersion; 399 | $sysParams["terminal_type"] = $request->getTerminalType(); 400 | $sysParams["terminal_info"] = $request->getTerminalInfo(); 401 | $sysParams["prod_code"] = $request->getProdCode(); 402 | $sysParams["notify_url"] = $request->getNotifyUrl(); 403 | $sysParams["return_url"] = $request->getReturnUrl(); 404 | $sysParams["charset"] = $this->postCharset; 405 | 406 | //获取业务参数 407 | $apiParams = $request->getApiParas(); 408 | 409 | if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ 410 | 411 | $sysParams["encrypt_type"] = $this->encryptType; 412 | 413 | if ($this->checkEmpty($apiParams['biz_content'])) { 414 | 415 | throw new \Exception(" api request Fail! The reason : encrypt request is not supperted!"); 416 | } 417 | 418 | if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) { 419 | 420 | throw new \Exception(" encryptType and encryptKey must not null! "); 421 | } 422 | 423 | if ("AES" != $this->encryptType) { 424 | 425 | throw new \Exception("加密类型只支持AES"); 426 | } 427 | 428 | // 执行加密 429 | $enCryptContent = AopEncrypt::encrypt($apiParams['biz_content'], $this->encryptKey); 430 | $apiParams['biz_content'] = $enCryptContent; 431 | 432 | } 433 | 434 | //print_r($apiParams); 435 | $totalParams = array_merge($apiParams, $sysParams); 436 | 437 | //待签名字符串 438 | $preSignStr = $this->getSignContent($totalParams); 439 | 440 | //签名 441 | $totalParams["sign"] = $this->generateSign($totalParams, $this->signType); 442 | 443 | if ("GET" == strtoupper($httpmethod)) { 444 | 445 | //value做urlencode 446 | $preString=$this->getSignContentUrlencode($totalParams); 447 | //拼接GET请求串 448 | $requestUrl = $this->gatewayUrl."?".$preString; 449 | 450 | return $requestUrl; 451 | } else { 452 | //拼接表单字符串 453 | return $this->buildRequestForm($totalParams); 454 | } 455 | 456 | 457 | } 458 | 459 | 460 | 461 | /** 462 | * 建立请求,以表单HTML形式构造(默认) 463 | * @param $para_temp 请求参数数组 464 | * @return 提交表单HTML文本 465 | */ 466 | protected function buildRequestForm($para_temp) { 467 | 468 | $sHtml = "
"; 469 | while (list ($key, $val) = each ($para_temp)) { 470 | if (false === $this->checkEmpty($val)) { 471 | //$val = $this->characet($val, $this->postCharset); 472 | $val = str_replace("'","'",$val); 473 | //$val = str_replace("\"",""",$val); 474 | $sHtml.= ""; 475 | } 476 | } 477 | 478 | //submit按钮控件请不要含有name属性 479 | $sHtml = $sHtml."
"; 480 | 481 | $sHtml = $sHtml.""; 482 | 483 | return $sHtml; 484 | } 485 | 486 | 487 | public function execute($request, $authToken = null, $appInfoAuthtoken = null) { 488 | 489 | $this->setupCharsets($request); 490 | 491 | // // 如果两者编码不一致,会出现签名验签或者乱码 492 | if (strcasecmp($this->fileCharset, $this->postCharset)) { 493 | 494 | // writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为postCharset!"); 495 | throw new \Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!"); 496 | } 497 | 498 | $iv = null; 499 | 500 | if (!$this->checkEmpty($request->getApiVersion())) { 501 | $iv = $request->getApiVersion(); 502 | } else { 503 | $iv = $this->apiVersion; 504 | } 505 | 506 | 507 | //组装系统参数 508 | $sysParams["app_id"] = $this->appId; 509 | $sysParams["version"] = $iv; 510 | $sysParams["format"] = $this->format; 511 | $sysParams["sign_type"] = $this->signType; 512 | $sysParams["method"] = $request->getApiMethodName(); 513 | $sysParams["timestamp"] = date("Y-m-d H:i:s"); 514 | $sysParams["auth_token"] = $authToken; 515 | $sysParams["alipay_sdk"] = $this->alipaySdkVersion; 516 | $sysParams["terminal_type"] = $request->getTerminalType(); 517 | $sysParams["terminal_info"] = $request->getTerminalInfo(); 518 | $sysParams["prod_code"] = $request->getProdCode(); 519 | $sysParams["notify_url"] = $request->getNotifyUrl(); 520 | $sysParams["charset"] = $this->postCharset; 521 | $sysParams["app_auth_token"] = $appInfoAuthtoken; 522 | 523 | 524 | //获取业务参数 525 | $apiParams = $request->getApiParas(); 526 | 527 | if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ 528 | 529 | $sysParams["encrypt_type"] = $this->encryptType; 530 | 531 | if ($this->checkEmpty($apiParams['biz_content'])) { 532 | 533 | throw new \Exception(" api request Fail! The reason : encrypt request is not supperted!"); 534 | } 535 | 536 | if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) { 537 | 538 | throw new \Exception(" encryptType and encryptKey must not null! "); 539 | } 540 | 541 | if ("AES" != $this->encryptType) { 542 | 543 | throw new \Exception("加密类型只支持AES"); 544 | } 545 | 546 | // 执行加密 547 | $enCryptContent = AopEncrypt::encrypt($apiParams['biz_content'], $this->encryptKey); 548 | $apiParams['biz_content'] = $enCryptContent; 549 | 550 | } 551 | 552 | 553 | //签名 554 | $sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams), $this->signType); 555 | 556 | 557 | //系统参数放入GET请求串 558 | $requestUrl = $this->gatewayUrl . "?"; 559 | foreach ($sysParams as $sysParamKey => $sysParamValue) { 560 | $requestUrl .= "$sysParamKey=" . urlencode($this->characet($sysParamValue, $this->postCharset)) . "&"; 561 | } 562 | $requestUrl = substr($requestUrl, 0, -1); 563 | 564 | 565 | //发起HTTP请求 566 | try { 567 | $resp = $this->curl($requestUrl, $apiParams); 568 | } catch (\Exception $e) { 569 | 570 | $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_ERROR_" . $e->getCode(), $e->getMessage()); 571 | return false; 572 | } 573 | 574 | //解析AOP返回结果 575 | $respWellFormed = false; 576 | 577 | 578 | // 将返回结果转换本地文件编码 579 | $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); 580 | 581 | 582 | 583 | $signData = null; 584 | 585 | if ("json" == $this->format) { 586 | 587 | $respObject = json_decode($r); 588 | if (null !== $respObject) { 589 | $respWellFormed = true; 590 | $signData = $this->parserJSONSignData($request, $resp, $respObject); 591 | } 592 | } else if ("xml" == $this->format) { 593 | 594 | $respObject = @ simplexml_load_string($resp); 595 | if (false !== $respObject) { 596 | $respWellFormed = true; 597 | 598 | $signData = $this->parserXMLSignData($request, $resp); 599 | } 600 | } 601 | 602 | 603 | //返回的HTTP文本不是标准JSON或者XML,记下错误日志 604 | if (false === $respWellFormed) { 605 | $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_RESPONSE_NOT_WELL_FORMED", $resp); 606 | return false; 607 | } 608 | 609 | // 验签 610 | $this->checkResponseSign($request, $signData, $resp, $respObject); 611 | 612 | // 解密 613 | if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ 614 | 615 | if ("json" == $this->format) { 616 | 617 | 618 | $resp = $this->encryptJSONSignSource($request, $resp); 619 | 620 | // 将返回结果转换本地文件编码 621 | $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); 622 | $respObject = json_decode($r); 623 | }else{ 624 | 625 | $resp = $this->encryptXMLSignSource($request, $resp); 626 | 627 | $r = iconv($this->postCharset, $this->fileCharset . "//IGNORE", $resp); 628 | $respObject = @ simplexml_load_string($r); 629 | 630 | } 631 | } 632 | 633 | return $respObject; 634 | } 635 | 636 | public function smtExecute($request, $authToken = null, $appInfoAuthtoken = null) { 637 | 638 | $this->setupCharsets($request); 639 | 640 | // // 如果两者编码不一致,会出现签名验签或者乱码 641 | if (strcasecmp($this->fileCharset, $this->postCharset)) { 642 | 643 | // writeLog("本地文件字符集编码与表单提交编码不一致,请务必设置成一样,属性名分别为postCharset!"); 644 | throw new \Exception("文件编码:[" . $this->fileCharset . "] 与表单提交编码:[" . $this->postCharset . "]两者不一致!"); 645 | } 646 | 647 | $iv = null; 648 | 649 | if (!$this->checkEmpty($request->getApiVersion())) { 650 | $iv = $request->getApiVersion(); 651 | } else { 652 | $iv = $this->apiVersion; 653 | } 654 | 655 | 656 | //组装系统参数 657 | $sysParams["app_id"] = $this->appId; 658 | $sysParams["version"] = $iv; 659 | $sysParams["format"] = $this->format; 660 | $sysParams["sign_type"] = $this->signType; 661 | $sysParams["method"] = $request->getApiMethodName(); 662 | $sysParams["timestamp"] = date("Y-m-d H:i:s"); 663 | $sysParams["auth_token"] = $authToken; 664 | $sysParams["alipay_sdk"] = $this->alipaySdkVersion; 665 | $sysParams["terminal_type"] = $request->getTerminalType(); 666 | $sysParams["terminal_info"] = $request->getTerminalInfo(); 667 | $sysParams["prod_code"] = $request->getProdCode(); 668 | $sysParams["notify_url"] = $request->getNotifyUrl(); 669 | $sysParams["charset"] = $this->postCharset; 670 | $sysParams["app_auth_token"] = $appInfoAuthtoken; 671 | 672 | 673 | //获取业务参数 674 | $apiParams = $request->getApiParas(); 675 | 676 | if (method_exists($request,"getNeedEncrypt") &&$request->getNeedEncrypt()){ 677 | 678 | $sysParams["encrypt_type"] = $this->encryptType; 679 | 680 | if ($this->checkEmpty($apiParams['biz_content'])) { 681 | 682 | throw new \Exception(" api request Fail! The reason : encrypt request is not supperted!"); 683 | } 684 | 685 | if ($this->checkEmpty($this->encryptKey) || $this->checkEmpty($this->encryptType)) { 686 | 687 | throw new \Exception(" encryptType and encryptKey must not null! "); 688 | } 689 | 690 | if ("AES" != $this->encryptType) { 691 | 692 | throw new \Exception("加密类型只支持AES"); 693 | } 694 | 695 | // 执行加密 696 | $enCryptContent = AopEncrypt::encrypt($apiParams['biz_content'], $this->encryptKey); 697 | $apiParams['biz_content'] = $enCryptContent; 698 | 699 | } 700 | 701 | 702 | //签名 703 | $sysParams["sign"] = $this->generateSign(array_merge($apiParams, $sysParams), $this->signType); 704 | 705 | 706 | //系统参数放入GET请求串 707 | $requestUrl = $this->gatewayUrl . "?"; 708 | foreach ($sysParams as $sysParamKey => $sysParamValue) { 709 | $requestUrl .= "$sysParamKey=" . urlencode($this->characet($sysParamValue, $this->postCharset)) . "&"; 710 | } 711 | $requestUrl = substr($requestUrl, 0, -1); 712 | 713 | 714 | //发起HTTP请求 715 | try { 716 | $resp = $this->smt_curl($requestUrl, $apiParams); 717 | } catch (\Exception $e) { 718 | $this->logCommunicationError($sysParams["method"], $requestUrl, "HTTP_ERROR_" . $e->getCode(), $e->getMessage()); 719 | return false; 720 | } 721 | 722 | return $resp; 723 | } 724 | 725 | /** 726 | * 转换字符集编码 727 | * @param $data 728 | * @param $targetCharset 729 | * @return string 730 | */ 731 | function characet($data, $targetCharset) { 732 | 733 | if (!empty($data)) { 734 | $fileType = $this->fileCharset; 735 | if (strcasecmp($fileType, $targetCharset) != 0) { 736 | $data = mb_convert_encoding($data, $targetCharset, $fileType); 737 | // $data = iconv($fileType, $targetCharset.'//IGNORE', $data); 738 | } 739 | } 740 | 741 | return $data; 742 | } 743 | 744 | public function exec($paramsArray) { 745 | if (!isset ($paramsArray["method"])) { 746 | trigger_error("No api name passed"); 747 | } 748 | $inflector = new LtInflector; 749 | $inflector->conf["separator"] = "."; 750 | $requestClassName = ucfirst($inflector->camelize(substr($paramsArray["method"], 7))) . "Request"; 751 | if (!class_exists($requestClassName)) { 752 | trigger_error("No such api: " . $paramsArray["method"]); 753 | } 754 | 755 | $session = isset ($paramsArray["session"]) ? $paramsArray["session"] : null; 756 | 757 | $req = new $requestClassName; 758 | foreach ($paramsArray as $paraKey => $paraValue) { 759 | $inflector->conf["separator"] = "_"; 760 | $setterMethodName = $inflector->camelize($paraKey); 761 | $inflector->conf["separator"] = "."; 762 | $setterMethodName = "set" . $inflector->camelize($setterMethodName); 763 | if (method_exists($req, $setterMethodName)) { 764 | $req->$setterMethodName ($paraValue); 765 | } 766 | } 767 | return $this->execute($req, $session); 768 | } 769 | 770 | /** 771 | * 校验$value是否非空 772 | * if not set ,return true; 773 | * if is null , return true; 774 | **/ 775 | protected function checkEmpty($value) { 776 | if (!isset($value)) 777 | return true; 778 | if ($value === null) 779 | return true; 780 | if (trim($value) === "") 781 | return true; 782 | 783 | return false; 784 | } 785 | 786 | /** rsaCheckV1 & rsaCheckV2 787 | * 验证签名 788 | * 在使用本方法前,必须初始化AopClient且传入公钥参数。 789 | * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 790 | **/ 791 | public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType='RSA') { 792 | $sign = $params['sign']; 793 | $params['sign_type'] = null; 794 | $params['sign'] = null; 795 | return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType); 796 | } 797 | public function rsaCheckV2($params, $rsaPublicKeyFilePath, $signType='RSA') { 798 | $sign = $params['sign']; 799 | $params['sign'] = null; 800 | return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath, $signType); 801 | } 802 | 803 | function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') { 804 | 805 | if($this->checkEmpty($this->alipayPublicKey)){ 806 | 807 | $pubKey= $this->alipayrsaPublicKey; 808 | $res = "-----BEGIN PUBLIC KEY-----\n" . 809 | wordwrap($pubKey, 64, "\n", true) . 810 | "\n-----END PUBLIC KEY-----"; 811 | }else { 812 | //读取公钥文件 813 | $pubKey = file_get_contents($rsaPublicKeyFilePath); 814 | //转换为openssl格式密钥 815 | $res = openssl_get_publickey($pubKey); 816 | } 817 | 818 | ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); 819 | 820 | //调用openssl内置方法验签,返回bool值 821 | 822 | if ("RSA2" == $signType) { 823 | $result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256); 824 | } else { 825 | $result = (bool)openssl_verify($data, base64_decode($sign), $res); 826 | } 827 | 828 | if(!$this->checkEmpty($this->alipayPublicKey)) { 829 | //释放资源 830 | openssl_free_key($res); 831 | } 832 | 833 | return $result; 834 | } 835 | 836 | /** 837 | * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 838 | * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 839 | **/ 840 | public function checkSignAndDecrypt($params, $rsaPublicKeyPem, $rsaPrivateKeyPem, $isCheckSign, $isDecrypt, $signType='RSA') { 841 | $charset = $params['charset']; 842 | $bizContent = $params['biz_content']; 843 | if ($isCheckSign) { 844 | if (!$this->rsaCheckV2($params, $rsaPublicKeyPem, $signType)) { 845 | echo "
checkSign failure
"; 846 | exit; 847 | } 848 | } 849 | if ($isDecrypt) { 850 | return $this->rsaDecrypt($bizContent, $rsaPrivateKeyPem, $charset); 851 | } 852 | 853 | return $bizContent; 854 | } 855 | 856 | /** 857 | * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 858 | * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 859 | **/ 860 | public function encryptAndSign($bizContent, $rsaPublicKeyPem, $rsaPrivateKeyPem, $charset, $isEncrypt, $isSign, $signType='RSA') { 861 | // 加密,并签名 862 | if ($isEncrypt && $isSign) { 863 | $encrypted = $this->rsaEncrypt($bizContent, $rsaPublicKeyPem, $charset); 864 | $sign = $this->sign($encrypted, $signType); 865 | $response = "$encryptedRSA$sign$signType"; 866 | return $response; 867 | } 868 | // 加密,不签名 869 | if ($isEncrypt && (!$isSign)) { 870 | $encrypted = $this->rsaEncrypt($bizContent, $rsaPublicKeyPem, $charset); 871 | $response = "$encrypted$signType"; 872 | return $response; 873 | } 874 | // 不加密,但签名 875 | if ((!$isEncrypt) && $isSign) { 876 | $sign = $this->sign($bizContent, $signType); 877 | $response = "$bizContent$sign$signType"; 878 | return $response; 879 | } 880 | // 不加密,不签名 881 | $response = "$bizContent"; 882 | return $response; 883 | } 884 | 885 | /** 886 | * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 887 | * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 888 | **/ 889 | public function rsaEncrypt($data, $rsaPublicKeyPem, $charset) { 890 | if($this->checkEmpty($this->alipayPublicKey)){ 891 | //读取字符串 892 | $pubKey= $this->alipayrsaPublicKey; 893 | $res = "-----BEGIN PUBLIC KEY-----\n" . 894 | wordwrap($pubKey, 64, "\n", true) . 895 | "\n-----END PUBLIC KEY-----"; 896 | }else { 897 | //读取公钥文件 898 | $pubKey = file_get_contents($rsaPublicKeyFilePath); 899 | //转换为openssl格式密钥 900 | $res = openssl_get_publickey($pubKey); 901 | } 902 | 903 | ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); 904 | $blocks = $this->splitCN($data, 0, 30, $charset); 905 | $chrtext  = null; 906 | $encodes  = array(); 907 | foreach ($blocks as $n => $block) { 908 | if (!openssl_public_encrypt($block, $chrtext , $res)) { 909 | echo "
" . openssl_error_string() . "
"; 910 | } 911 | $encodes[] = $chrtext ; 912 | } 913 | $chrtext = implode(",", $encodes); 914 | 915 | return base64_encode($chrtext); 916 | } 917 | 918 | /** 919 | * 在使用本方法前,必须初始化AopClient且传入公私钥参数。 920 | * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 921 | **/ 922 | public function rsaDecrypt($data, $rsaPrivateKeyPem, $charset) { 923 | 924 | if($this->checkEmpty($this->rsaPrivateKeyFilePath)){ 925 | //读字符串 926 | $priKey=$this->rsaPrivateKey; 927 | $res = "-----BEGIN RSA PRIVATE KEY-----\n" . 928 | wordwrap($priKey, 64, "\n", true) . 929 | "\n-----END RSA PRIVATE KEY-----"; 930 | }else { 931 | $priKey = file_get_contents($this->rsaPrivateKeyFilePath); 932 | $res = openssl_get_privatekey($priKey); 933 | } 934 | ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置'); 935 | //转换为openssl格式密钥 936 | $decodes = explode(',', $data); 937 | $strnull = ""; 938 | $dcyCont = ""; 939 | foreach ($decodes as $n => $decode) { 940 | if (!openssl_private_decrypt($decode, $dcyCont, $res)) { 941 | echo "
" . openssl_error_string() . "
"; 942 | } 943 | $strnull .= $dcyCont; 944 | } 945 | return $strnull; 946 | } 947 | 948 | function splitCN($cont, $n = 0, $subnum, $charset) { 949 | //$len = strlen($cont) / 3; 950 | $arrr = array(); 951 | for ($i = $n; $i < strlen($cont); $i += $subnum) { 952 | $res = $this->subCNchar($cont, $i, $subnum, $charset); 953 | if (!empty ($res)) { 954 | $arrr[] = $res; 955 | } 956 | } 957 | 958 | return $arrr; 959 | } 960 | 961 | function subCNchar($str, $start = 0, $length, $charset = "gbk") { 962 | if (strlen($str) <= $length) { 963 | return $str; 964 | } 965 | $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/"; 966 | $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/"; 967 | $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/"; 968 | $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/"; 969 | preg_match_all($re[$charset], $str, $match); 970 | $slice = join("", array_slice($match[0], $start, $length)); 971 | return $slice; 972 | } 973 | 974 | function parserResponseSubCode($request, $responseContent, $respObject, $format) { 975 | 976 | if ("json" == $format) { 977 | 978 | $apiName = $request->getApiMethodName(); 979 | $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; 980 | $errorNodeName = $this->ERROR_RESPONSE; 981 | 982 | $rootIndex = strpos($responseContent, $rootNodeName); 983 | $errorIndex = strpos($responseContent, $errorNodeName); 984 | 985 | if ($rootIndex > 0) { 986 | // 内部节点对象 987 | $rInnerObject = $respObject->$rootNodeName; 988 | } elseif ($errorIndex > 0) { 989 | 990 | $rInnerObject = $respObject->$errorNodeName; 991 | } else { 992 | return null; 993 | } 994 | 995 | // 存在属性则返回对应值 996 | if (isset($rInnerObject->sub_code)) { 997 | 998 | return $rInnerObject->sub_code; 999 | } else { 1000 | 1001 | return null; 1002 | } 1003 | 1004 | 1005 | } elseif ("xml" == $format) { 1006 | 1007 | // xml格式sub_code在同一层级 1008 | return $respObject->sub_code; 1009 | 1010 | } 1011 | 1012 | 1013 | } 1014 | 1015 | function parserJSONSignData($request, $responseContent, $responseJSON) { 1016 | 1017 | $signData = new SignData(); 1018 | 1019 | $signData->sign = $this->parserJSONSign($responseJSON); 1020 | $signData->signSourceData = $this->parserJSONSignSource($request, $responseContent); 1021 | 1022 | 1023 | return $signData; 1024 | 1025 | } 1026 | 1027 | function parserJSONSignSource($request, $responseContent) { 1028 | 1029 | $apiName = $request->getApiMethodName(); 1030 | $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; 1031 | 1032 | $rootIndex = strpos($responseContent, $rootNodeName); 1033 | $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); 1034 | 1035 | 1036 | if ($rootIndex > 0) { 1037 | 1038 | return $this->parserJSONSource($responseContent, $rootNodeName, $rootIndex); 1039 | } else if ($errorIndex > 0) { 1040 | 1041 | return $this->parserJSONSource($responseContent, $this->ERROR_RESPONSE, $errorIndex); 1042 | } else { 1043 | 1044 | return null; 1045 | } 1046 | 1047 | 1048 | } 1049 | 1050 | function parserJSONSource($responseContent, $nodeName, $nodeIndex) { 1051 | $signDataStartIndex = $nodeIndex + strlen($nodeName) + 2; 1052 | $signIndex = strpos($responseContent, "\"" . $this->SIGN_NODE_NAME . "\""); 1053 | // 签名前-逗号 1054 | $signDataEndIndex = $signIndex - 1; 1055 | $indexLen = $signDataEndIndex - $signDataStartIndex; 1056 | if ($indexLen < 0) { 1057 | 1058 | return null; 1059 | } 1060 | 1061 | return substr($responseContent, $signDataStartIndex, $indexLen); 1062 | 1063 | } 1064 | 1065 | function parserJSONSign($responseJSon) { 1066 | 1067 | return $responseJSon->sign; 1068 | } 1069 | 1070 | function parserXMLSignData($request, $responseContent) { 1071 | 1072 | 1073 | $signData = new SignData(); 1074 | 1075 | $signData->sign = $this->parserXMLSign($responseContent); 1076 | $signData->signSourceData = $this->parserXMLSignSource($request, $responseContent); 1077 | 1078 | 1079 | return $signData; 1080 | 1081 | 1082 | } 1083 | 1084 | function parserXMLSignSource($request, $responseContent) { 1085 | 1086 | 1087 | $apiName = $request->getApiMethodName(); 1088 | $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; 1089 | 1090 | 1091 | $rootIndex = strpos($responseContent, $rootNodeName); 1092 | $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); 1093 | // $this->echoDebug("
rootNodeName:" . $rootNodeName); 1094 | // $this->echoDebug("
responseContent:" . $responseContent . ""); 1095 | 1096 | 1097 | if ($rootIndex > 0) { 1098 | 1099 | return $this->parserXMLSource($responseContent, $rootNodeName, $rootIndex); 1100 | } else if ($errorIndex > 0) { 1101 | 1102 | return $this->parserXMLSource($responseContent, $this->ERROR_RESPONSE, $errorIndex); 1103 | } else { 1104 | 1105 | return null; 1106 | } 1107 | 1108 | 1109 | } 1110 | 1111 | function parserXMLSource($responseContent, $nodeName, $nodeIndex) { 1112 | $signDataStartIndex = $nodeIndex + strlen($nodeName) + 1; 1113 | $signIndex = strpos($responseContent, "<" . $this->SIGN_NODE_NAME . ">"); 1114 | // 签名前-逗号 1115 | $signDataEndIndex = $signIndex - 1; 1116 | $indexLen = $signDataEndIndex - $signDataStartIndex + 1; 1117 | 1118 | if ($indexLen < 0) { 1119 | return null; 1120 | } 1121 | 1122 | 1123 | return substr($responseContent, $signDataStartIndex, $indexLen); 1124 | 1125 | 1126 | } 1127 | 1128 | function parserXMLSign($responseContent) { 1129 | $signNodeName = "<" . $this->SIGN_NODE_NAME . ">"; 1130 | $signEndNodeName = "SIGN_NODE_NAME . ">"; 1131 | 1132 | $indexOfSignNode = strpos($responseContent, $signNodeName); 1133 | $indexOfSignEndNode = strpos($responseContent, $signEndNodeName); 1134 | 1135 | 1136 | if ($indexOfSignNode < 0 || $indexOfSignEndNode < 0) { 1137 | return null; 1138 | } 1139 | 1140 | $nodeIndex = ($indexOfSignNode + strlen($signNodeName)); 1141 | 1142 | $indexLen = $indexOfSignEndNode - $nodeIndex; 1143 | 1144 | if ($indexLen < 0) { 1145 | return null; 1146 | } 1147 | 1148 | // 签名 1149 | return substr($responseContent, $nodeIndex, $indexLen); 1150 | 1151 | } 1152 | 1153 | /** 1154 | * 验签 1155 | * @param $request 1156 | * @param $signData 1157 | * @param $resp 1158 | * @param $respObject 1159 | * @throws Exception 1160 | */ 1161 | public function checkResponseSign($request, $signData, $resp, $respObject) { 1162 | 1163 | if (!$this->checkEmpty($this->alipayPublicKey) || !$this->checkEmpty($this->alipayrsaPublicKey)) { 1164 | 1165 | 1166 | if ($signData == null || $this->checkEmpty($signData->sign) || $this->checkEmpty($signData->signSourceData)) { 1167 | 1168 | throw new \Exception(" check sign Fail! The reason : signData is Empty"); 1169 | } 1170 | 1171 | 1172 | // 获取结果sub_code 1173 | $responseSubCode = $this->parserResponseSubCode($request, $resp, $respObject, $this->format); 1174 | 1175 | 1176 | if (!$this->checkEmpty($responseSubCode) || ($this->checkEmpty($responseSubCode) && !$this->checkEmpty($signData->sign))) { 1177 | 1178 | $checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType); 1179 | 1180 | 1181 | if (!$checkResult) { 1182 | 1183 | if (strpos($signData->signSourceData, "\\/") > 0) { 1184 | 1185 | $signData->signSourceData = str_replace("\\/", "/", $signData->signSourceData); 1186 | 1187 | $checkResult = $this->verify($signData->signSourceData, $signData->sign, $this->alipayPublicKey, $this->signType); 1188 | 1189 | if (!$checkResult) { 1190 | throw new \Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]"); 1191 | } 1192 | 1193 | } else { 1194 | 1195 | throw new \Exception("check sign Fail! [sign=" . $signData->sign . ", signSourceData=" . $signData->signSourceData . "]"); 1196 | } 1197 | 1198 | } 1199 | } 1200 | 1201 | 1202 | } 1203 | } 1204 | 1205 | private function setupCharsets($request) { 1206 | if ($this->checkEmpty($this->postCharset)) { 1207 | $this->postCharset = 'UTF-8'; 1208 | } 1209 | $str = preg_match('/[\x80-\xff]/', $this->appId) ? $this->appId : print_r($request, true); 1210 | $this->fileCharset = mb_detect_encoding($str, "UTF-8, GBK") == 'UTF-8' ? 'UTF-8' : 'GBK'; 1211 | } 1212 | 1213 | // 获取加密内容 1214 | 1215 | private function encryptJSONSignSource($request, $responseContent) { 1216 | 1217 | $parsetItem = $this->parserEncryptJSONSignSource($request, $responseContent); 1218 | 1219 | $bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex); 1220 | $bodyEndContent = substr($responseContent, $parsetItem->endIndex, strlen($responseContent) + 1 - $parsetItem->endIndex); 1221 | 1222 | $bizContent = AopEncrypt::decrypt($parsetItem->encryptContent, $this->encryptKey); 1223 | return $bodyIndexContent . $bizContent . $bodyEndContent; 1224 | 1225 | } 1226 | 1227 | 1228 | private function parserEncryptJSONSignSource($request, $responseContent) { 1229 | 1230 | $apiName = $request->getApiMethodName(); 1231 | $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; 1232 | 1233 | $rootIndex = strpos($responseContent, $rootNodeName); 1234 | $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); 1235 | 1236 | 1237 | if ($rootIndex > 0) { 1238 | 1239 | return $this->parserEncryptJSONItem($responseContent, $rootNodeName, $rootIndex); 1240 | } else if ($errorIndex > 0) { 1241 | 1242 | return $this->parserEncryptJSONItem($responseContent, $this->ERROR_RESPONSE, $errorIndex); 1243 | } else { 1244 | 1245 | return null; 1246 | } 1247 | 1248 | 1249 | } 1250 | 1251 | 1252 | private function parserEncryptJSONItem($responseContent, $nodeName, $nodeIndex) { 1253 | $signDataStartIndex = $nodeIndex + strlen($nodeName) + 2; 1254 | $signIndex = strpos($responseContent, "\"" . $this->SIGN_NODE_NAME . "\""); 1255 | // 签名前-逗号 1256 | $signDataEndIndex = $signIndex - 1; 1257 | 1258 | if ($signDataEndIndex < 0) { 1259 | 1260 | $signDataEndIndex = strlen($responseContent)-1 ; 1261 | } 1262 | 1263 | $indexLen = $signDataEndIndex - $signDataStartIndex; 1264 | 1265 | $encContent = substr($responseContent, $signDataStartIndex+1, $indexLen-2); 1266 | 1267 | 1268 | $encryptParseItem = new EncryptParseItem(); 1269 | 1270 | $encryptParseItem->encryptContent = $encContent; 1271 | $encryptParseItem->startIndex = $signDataStartIndex; 1272 | $encryptParseItem->endIndex = $signDataEndIndex; 1273 | 1274 | return $encryptParseItem; 1275 | 1276 | } 1277 | 1278 | // 获取加密内容 1279 | 1280 | private function encryptXMLSignSource($request, $responseContent) { 1281 | 1282 | $parsetItem = $this->parserEncryptXMLSignSource($request, $responseContent); 1283 | 1284 | $bodyIndexContent = substr($responseContent, 0, $parsetItem->startIndex); 1285 | $bodyEndContent = substr($responseContent, $parsetItem->endIndex, strlen($responseContent) + 1 - $parsetItem->endIndex); 1286 | $bizContent = AopEncrypt::decrypt($parsetItem->encryptContent, $this->encryptKey); 1287 | 1288 | return $bodyIndexContent . $bizContent . $bodyEndContent; 1289 | 1290 | } 1291 | 1292 | private function parserEncryptXMLSignSource($request, $responseContent) { 1293 | 1294 | 1295 | $apiName = $request->getApiMethodName(); 1296 | $rootNodeName = str_replace(".", "_", $apiName) . $this->RESPONSE_SUFFIX; 1297 | 1298 | 1299 | $rootIndex = strpos($responseContent, $rootNodeName); 1300 | $errorIndex = strpos($responseContent, $this->ERROR_RESPONSE); 1301 | // $this->echoDebug("
rootNodeName:" . $rootNodeName); 1302 | // $this->echoDebug("
responseContent:" . $responseContent . ""); 1303 | 1304 | 1305 | if ($rootIndex > 0) { 1306 | 1307 | return $this->parserEncryptXMLItem($responseContent, $rootNodeName, $rootIndex); 1308 | } else if ($errorIndex > 0) { 1309 | 1310 | return $this->parserEncryptXMLItem($responseContent, $this->ERROR_RESPONSE, $errorIndex); 1311 | } else { 1312 | 1313 | return null; 1314 | } 1315 | 1316 | 1317 | } 1318 | 1319 | private function parserEncryptXMLItem($responseContent, $nodeName, $nodeIndex) { 1320 | 1321 | $signDataStartIndex = $nodeIndex + strlen($nodeName) + 1; 1322 | 1323 | $xmlStartNode="<".$this->ENCRYPT_XML_NODE_NAME.">"; 1324 | $xmlEndNode="ENCRYPT_XML_NODE_NAME.">"; 1325 | 1326 | $indexOfXmlNode=strpos($responseContent,$xmlEndNode); 1327 | if($indexOfXmlNode<0){ 1328 | 1329 | $item = new EncryptParseItem(); 1330 | $item->encryptContent = null; 1331 | $item->startIndex = 0; 1332 | $item->endIndex = 0; 1333 | return $item; 1334 | } 1335 | 1336 | $startIndex=$signDataStartIndex+strlen($xmlStartNode); 1337 | $bizContentLen=$indexOfXmlNode-$startIndex; 1338 | $bizContent=substr($responseContent,$startIndex,$bizContentLen); 1339 | 1340 | $encryptParseItem = new EncryptParseItem(); 1341 | $encryptParseItem->encryptContent = $bizContent; 1342 | $encryptParseItem->startIndex = $signDataStartIndex; 1343 | $encryptParseItem->endIndex = $indexOfXmlNode+strlen($xmlEndNode); 1344 | 1345 | return $encryptParseItem; 1346 | 1347 | } 1348 | 1349 | 1350 | function echoDebug($content) { 1351 | 1352 | if ($this->debugInfo) { 1353 | echo "
" . $content; 1354 | } 1355 | 1356 | } 1357 | 1358 | 1359 | } --------------------------------------------------------------------------------