├── src ├── Foundation │ ├── ServiceProvider.php │ ├── Request.php │ ├── Response.php │ ├── PaymentComm.php │ └── Foundation.php ├── AliPay │ ├── AliPayComm.php │ ├── AliPayRequest.php │ ├── AliPayResponse.php │ ├── Pos │ │ └── Pos.php │ ├── Web │ │ └── Web.php │ ├── JSApi │ │ └── JSApi.php │ ├── Qr │ │ └── Qr.php │ └── App │ │ └── App.php └── WeChat │ ├── WeChatComm.php │ ├── WeChatRequest.php │ ├── WeChatResponse.php │ ├── JSApi │ └── JSApi.php │ ├── Pos │ └── Pos.php │ ├── App │ └── App.php │ ├── H5 │ └── H5.php │ └── Native │ └── Native.php ├── composer.json ├── .gitignore ├── README.md ├── LICENSE └── composer.lock /src/Foundation/ServiceProvider.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | interface Request 12 | { 13 | public function isSuccessful(); 14 | 15 | public function getRequestData(); 16 | 17 | } -------------------------------------------------------------------------------- /src/Foundation/Response.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | interface Response 12 | { 13 | public function isSuccessful(); 14 | 15 | public function getRequestData(); 16 | 17 | public function getResponseData(); 18 | 19 | } -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fantasystudio/easypay", 3 | "description": "Wechat and Alipay payment SDK", 4 | "keywords": ["weixin", "wechat", "alipay"], 5 | "license": "Apache-2.0", 6 | "authors": [ 7 | { 8 | "name": "AndyLee", 9 | "email": "leefongyun@gmail.com", 10 | "role": "Developer" 11 | } 12 | ], 13 | "type": "library", 14 | "require": { 15 | "php": ">=5.5.0", 16 | "guzzlehttp/guzzle": "~6.2" 17 | }, 18 | "autoload": { 19 | "psr-4": { 20 | "FantasyStudio\\EasyPay\\": "src/" 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Foundation/PaymentComm.php: -------------------------------------------------------------------------------- 1 | 9 | */ 10 | interface PaymentComm 11 | { 12 | 13 | /** 14 | * 设置支付参数 15 | * @param array $order 订单信息 16 | * @return mixed 17 | */ 18 | public function purchase($order); 19 | 20 | /** 21 | * 发起支付请求 22 | * @return mixed 23 | */ 24 | public function sendPaymentRequest(); 25 | 26 | // /** 27 | // * 处理异步通知 28 | // * @return mixed 29 | // */ 30 | // public function processNotifyRequest(); 31 | 32 | /** 33 | * 查询订单 34 | * @param array $data 35 | * @return mixed 36 | */ 37 | public function queryOrderState($data); 38 | 39 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | 5 | # Files for the ART/Dalvik VM 6 | *.dex 7 | 8 | # Java class files 9 | *.class 10 | 11 | # Generated files 12 | bin/ 13 | gen/ 14 | out/ 15 | 16 | # Gradle files 17 | .gradle/ 18 | build/ 19 | 20 | # Local configuration file (sdk path, etc) 21 | local.properties 22 | 23 | # Proguard folder generated by Eclipse 24 | proguard/ 25 | 26 | # Log Files 27 | *.log 28 | 29 | # Android Studio Navigation editor temp files 30 | .navigation/ 31 | 32 | # Android Studio captures folder 33 | captures/ 34 | 35 | # Intellij 36 | *.iml 37 | .idea/workspace.xml 38 | .idea/tasks.xml 39 | .idea/gradle.xml 40 | .idea/dictionaries 41 | .idea/libraries 42 | .idea/ 43 | # Keystore files 44 | *.jks 45 | 46 | # External native build folder generated in Android Studio 2.2 and later 47 | .externalNativeBuild 48 | 49 | # Google Services (e.g. APIs or Firebase) 50 | google-services.json 51 | 52 | # Freeline 53 | freeline.py 54 | freeline/ 55 | freeline_project_description.json 56 | test.php 57 | composer.phar 58 | /vendor/ 59 | -------------------------------------------------------------------------------- /src/AliPay/AliPayComm.php: -------------------------------------------------------------------------------- 1 | share = $raw; 18 | $this->pub_key = $key; 19 | } 20 | 21 | public function isSuccessful() 22 | { 23 | $status = [ 24 | "TRADE_SUCCESS", //商户支持退款 支付成功返回 25 | "TRADE_FINISHED" //商户不支持退款 或者 已经过期 26 | ]; 27 | 28 | if (in_array($this->share["trade_status"], $status)) { 29 | if ($this->checkAliPayNotifyMessage($this->share, $this->pub_key)) { 30 | return true; 31 | } 32 | } 33 | 34 | return false; 35 | } 36 | 37 | /** 38 | * 支付宝支付處理成功後輸出 39 | * @return bool|string 40 | */ 41 | public function sayOK() 42 | { 43 | return "success"; 44 | } 45 | 46 | public function getRequestData() 47 | { 48 | return $this->share; 49 | } 50 | 51 | } -------------------------------------------------------------------------------- /src/WeChat/WeChatComm.php: -------------------------------------------------------------------------------- 1 | 10 | */ 11 | interface WeChatComm 12 | { 13 | /** 14 | * 设置微信公众账号ID 15 | * @param string $app_id 微信公众号ID 16 | * @return mixed 17 | */ 18 | public function setAppId($app_id); 19 | 20 | /** 21 | * 设置微信商户号 22 | * @param string $mch_id 商户ID 23 | * @return mixed 24 | */ 25 | public function setMchId($mch_id); 26 | 27 | /** 28 | * 设置微信支付密钥 29 | * @param string $key 微信支付密钥 30 | * @return mixed 31 | */ 32 | public function setApiKey($key); 33 | 34 | /** 35 | * 退款 36 | * @param string $ca_path; 37 | * @param array $order; 38 | * @return mixed 39 | */ 40 | public function refundOrder($order, $ca_path); 41 | /** 42 | * 撤销订单 43 | * @param string $ca_path; 44 | * @param array $order; 45 | * @return mixed 46 | */ 47 | public function reverseOrder($order, $ca_path); 48 | 49 | /** 50 | * 查询退款状态 51 | * @param $order 52 | * @return mixed 53 | */ 54 | public function queryRefundState($order); 55 | } -------------------------------------------------------------------------------- /src/WeChat/WeChatRequest.php: -------------------------------------------------------------------------------- 1 | share = $data; 20 | $this->api_key = $key; 21 | } 22 | 23 | public function isSuccessful() 24 | { 25 | if ($this->share["result_code"] == "SUCCESS" and $this->share["return_code"] == "SUCCESS") { 26 | if ($this->checkSignature($this->share, $this->api_key)) { 27 | return true; 28 | } 29 | } 30 | 31 | return false; 32 | } 33 | 34 | /** 35 | * 微信支付處理成功後輸出 36 | * @return bool|string 37 | */ 38 | public function sayOK() 39 | { 40 | $result = []; 41 | $result["return_code"] = "SUCCESS"; 42 | $result["return_msg"] = "OK"; 43 | 44 | return $this->toXML($result); 45 | } 46 | 47 | public function getRequestData() 48 | { 49 | return $this->share; 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /src/WeChat/WeChatResponse.php: -------------------------------------------------------------------------------- 1 | getBody(); 19 | $parse = simplexml_load_string($body, "SimpleXMLElement", LIBXML_NOCDATA); 20 | $json = json_encode($parse); 21 | $response_data = json_decode($json, TRUE); 22 | 23 | $this->response_data = $response_data; 24 | $this->request_data = $request_data; 25 | $this->key = $key; 26 | 27 | if (json_last_error() !== JSON_ERROR_NONE) { 28 | throw new \RuntimeException("Got an runtime error, can't decoded response data," 29 | . "json_last_error is" . json_last_error() 30 | . ", please see http://php.net/manual/en/function.json-last-error.php"); 31 | } 32 | 33 | } 34 | 35 | public function getResponseData() 36 | { 37 | return $this->response_data; 38 | } 39 | 40 | public function getRequestData() 41 | { 42 | return $this->request_data; 43 | } 44 | 45 | public function isSuccessful() 46 | { 47 | if ($this->response_data["return_code"] == "SUCCESS" and $this->response_data["result_code"] == "SUCCESS") { 48 | if ($this->checkSignature($this->response_data, $this->key)) { 49 | return true; 50 | } 51 | 52 | return false; 53 | } 54 | 55 | return false; 56 | } 57 | } -------------------------------------------------------------------------------- /src/AliPay/AliPayResponse.php: -------------------------------------------------------------------------------- 1 | getBody(); 20 | $this->request_data = $request_data; 21 | $response_data = json_decode($body, true); 22 | if (json_last_error() !== JSON_ERROR_NONE) { 23 | throw new \RuntimeException("Got an runtime error, can't decoded response data," 24 | . "json_last_error is " . json_last_error() 25 | . ", please see http://php.net/manual/en/function.json-last-error.php"); 26 | } 27 | 28 | $this->response_data = $response_data; 29 | $this->key = $key; 30 | 31 | } 32 | 33 | public function getResponseData() 34 | { 35 | return $this->response_data; 36 | } 37 | 38 | public function getRequestData() 39 | { 40 | return $this->request_data; 41 | } 42 | 43 | public function isSuccessful() 44 | { 45 | $keys = [ 46 | "alipay.trade.pay" => "alipay_trade_pay_response", 47 | "alipay.trade.query" => "alipay_trade_query_response", 48 | "alipay.trade.refund" => "alipay_trade_refund_response", 49 | "alipay.trade.cancel" => "alipay_trade_cancel_response", 50 | "alipay.trade.fastpay.refund.query" => "alipay_trade_fastpay_refund_query_response", 51 | "alipay.trade.precreate" => "alipay_trade_precreate_response", 52 | "alipay.trade.create" => "alipay_trade_create_response" 53 | ]; 54 | 55 | $method = $this->request_data["method"]; 56 | if (array_key_exists($keys[$method], $this->response_data)) { 57 | if (array_key_exists("code", $this->response_data[$keys[$method]])) { 58 | if ($this->response_data[$keys[$method]]["code"] == "10000" 59 | and $this->response_data[$keys[$method]]["msg"] == "Success" 60 | ) { 61 | return true; 62 | } 63 | } 64 | } 65 | return false; 66 | } 67 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # EasyPay 2 | 3 | 轻松集成支付宝,微信支付 到您的业务逻辑中。 4 | 5 | 6 | #### 我该怎么下载安装 7 | 8 | ```php 9 | composer require fantasystudio/easypay 10 | ``` 11 | 12 | #### 我想看看一些代码 13 | 14 | ```php 15 | use \FantasyStudio\EasyPay\AliPay\Qr\Qr; 16 | 17 | $qr = new Qr(); 18 | $qr->setAppId("201703300571632"); 19 | $qr->setSignType("RSA"); 20 | $qr->setPrivateKey("私钥内容,不要携带-----BEGIN RSA PRIVATE KEY-----"); 21 | $qr->purchase([ 22 | "total_amount" => 0.01, "out_trade_no" => "2120960179264092", "subject" => "subjectaa" 23 | ]); 24 | 25 | $result = $qr->sendPaymentRequest(); //发起扫码支付 26 | 27 | var_dump($result->getRequestData()); //获取请求数据 28 | var_dump($result->getResponseData()); //获取网关响应数据 29 | var_dump($result->isSuccessful()); // 请求是否成功 30 | 31 | 32 | ``` 33 | 34 | 35 | 36 | #### 开始集成 37 | 38 | | 分类 | 网关 | 描述 | 相关链接 | 39 | | ---- | ------ | ------------ | ---------------------------------------- | 40 | | 支付宝 | Qr | 扫码支付 | [官方文档](https://docs.open.alipay.com/194/106078/) \| [使用文档](https://github.com/thefantasystudio/easypay/wiki/%E6%94%AF%E4%BB%98%E5%AE%9D-%E6%89%AB%E7%A0%81%E6%94%AF%E4%BB%98) | 41 | | 支付宝 | Pos | 条码支付 | [官方文档](https://docs.open.alipay.com/194/106039/) \| [使用文档](https://github.com/thefantasystudio/easypay/wiki/%E6%94%AF%E4%BB%98%E5%AE%9D-%E6%9D%A1%E7%A0%81%E6%94%AF%E4%BB%98) | 42 | | 支付宝 | JSApi | 支付宝容器内支付(类似微信JSSDK支付) | [官方文档](https://docs.open.alipay.com/api_1/alipay.trade.create) \| [使用文档](https://github.com/thefantasystudio/easypay/wiki/%E6%94%AF%E4%BB%98%E5%AE%9D-%E5%AE%B9%E5%99%A8%E5%86%85%E6%94%AF%E4%BB%98) | 43 | | 支付宝 | Web | 电脑网站支付 | [官方文档](https://docs.open.alipay.com/270) \| [未完成]() | 44 | | 支付宝 | Wap | 手机网站支付 | [官方文档](https://docs.open.alipay.com/203) \| [未完成]() | 45 | | 支付宝 | App | APP支付 | [官方文档](https://docs.open.alipay.com/204/105465/) \| [使用文档](https://github.com/thefantasystudio/easypay/wiki/%E6%94%AF%E4%BB%98%E5%AE%9DApp%E6%94%AF%E4%BB%98) | 46 | | 微信支付 | Pos | 刷卡支付 | [官方文档](https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=5_1) \| [使用文档](https://github.com/thefantasystudio/easypay/wiki/%E5%BE%AE%E4%BF%A1-%E5%88%B7%E5%8D%A1%E6%94%AF%E4%BB%98) | 47 | | 微信支付 | JSApi | 公众号支付(JSSDK) | [官方文档](https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1) \| [使用文档](https://github.com/thefantasystudio/easypay/wiki/%E5%BE%AE%E4%BF%A1-%E5%85%AC%E4%BC%97%E5%8F%B7%E6%94%AF%E4%BB%98) | 48 | | 微信支付 | Native | 扫码支付 | [官方文档](https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_1) \| [使用文档](https://github.com/thefantasystudio/easypay/wiki/%E5%BE%AE%E4%BF%A1-%E6%89%AB%E7%A0%81%E6%94%AF%E4%BB%98) | 49 | | 微信支付 | App | APP支付 | [官方文档](https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1) \| [使用文档](https://github.com/thefantasystudio/easypay/wiki/%E5%BE%AE%E4%BF%A1-APP%E6%94%AF%E4%BB%98) | 50 | | 微信支付 | H5 | H5支付 | [官方文档](https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_1) \| [使用文档](https://github.com/thefantasystudio/easypay/wiki/%E5%BE%AE%E4%BF%A1-H5%E6%94%AF%E4%BB%98) | 51 | -------------------------------------------------------------------------------- /src/AliPay/Pos/Pos.php: -------------------------------------------------------------------------------- 1 | sign_type = $type; 28 | } 29 | 30 | public function setBaseData($data) 31 | { 32 | $this->base = $data; 33 | } 34 | 35 | public function preProcess() 36 | { 37 | return array_merge([ 38 | "app_id" => $this->app_id, 39 | "format" => "JSON", 40 | "charset" => "utf-8", 41 | "sign_type" => $this->sign_type, 42 | "timestamp" => date("Y-m-d H:i:s"), 43 | "version" => "1.0" 44 | ], $this->base); 45 | } 46 | 47 | public function queryRefundState($order) 48 | { 49 | $this->method = "alipay.trade.fastpay.refund.query"; 50 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 51 | } 52 | 53 | public function purchase($order) 54 | { 55 | $require_field = [ 56 | "out_trade_no", "scene", "auth_code", "subject" 57 | ]; 58 | 59 | foreach ($require_field as $key => $field) { 60 | if (!array_key_exists($field, $order)) { 61 | throw new \InvalidArgumentException("The {$field} field is required, see detail https://docs.open.alipay.com/api_1/alipay.trade.pay"); 62 | } 63 | } 64 | 65 | $this->order = $order; 66 | } 67 | 68 | public function reverseOrder($order) 69 | { 70 | $this->method = "alipay.trade.cancel"; 71 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 72 | } 73 | 74 | public function refundOrder($order) 75 | { 76 | $this->method = "alipay.trade.refund"; 77 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 78 | } 79 | 80 | public function setAppId($app_id) 81 | { 82 | $this->app_id = $app_id; 83 | } 84 | 85 | public function setNotifyUrl($url) 86 | { 87 | $this->notify_url; 88 | } 89 | 90 | public function setPrivateKey($content) 91 | { 92 | $this->private_key = $content; 93 | } 94 | 95 | public function sendPaymentRequest() 96 | { 97 | $this->method = "alipay.trade.pay"; 98 | return $this->sendRequest($this->gateway_url, "POST", $this->order, "", $this->private_key); 99 | } 100 | 101 | public function queryOrderState($data) 102 | { 103 | $this->method = "alipay.trade.query"; 104 | return $this->sendRequest($this->gateway_url, "POST", $data, "", $this->private_key); 105 | } 106 | } -------------------------------------------------------------------------------- /src/AliPay/Web/Web.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class Web implements AliPayComm, PaymentComm 17 | { 18 | use Foundation; 19 | 20 | public $app_id; 21 | public $public_key; 22 | private $private_key; 23 | public $notify_url; 24 | public $order; 25 | public $sign_type; 26 | public $base = []; 27 | public $gateway = "alipay"; 28 | public $postCharset = "UTF-8"; 29 | 30 | 31 | public $gateway_url = "https://openapi.alipay.com/gateway.do"; 32 | 33 | 34 | public function setBaseData($data) 35 | { 36 | $this->base = $data; 37 | } 38 | 39 | public function setSignType($type) 40 | { 41 | $this->sign_type = $type; 42 | } 43 | 44 | public function preProcess() 45 | { 46 | $pre_order = []; 47 | $pre_order["app_id"] = $this->app_id; 48 | $pre_order["method"] = "alipay.trade.page.pay"; 49 | $pre_order["charset"] = "utf-8"; //TODO 仅支持utf8 50 | $pre_order["timestamp"] = date("Y-m-d H:i:s"); 51 | $pre_order["version"] = "1.0"; 52 | $pre_order["sign_type"] = $this->sign_type; 53 | 54 | $base = $this->base; 55 | 56 | return array_merge($pre_order, $base); 57 | } 58 | 59 | 60 | /** 61 | * 建立请求,以表单HTML形式构造(默认) 62 | * @param $form_params 请求参数数组 63 | * @return 提交表单HTML文本 64 | */ 65 | protected function buildRequestForm($form_params) 66 | { 67 | 68 | $form_params["sign"] = $this->makeSignature($form_params, $this->private_key); 69 | $sHtml = "
"; 70 | foreach ($form_params as $key => $val) { 71 | $sHtml .= ""; 72 | } 73 | $sHtml = $sHtml . "
"; 74 | $sHtml = $sHtml . ""; 75 | 76 | return $sHtml; 77 | } 78 | 79 | 80 | public function sendPaymentRequest() 81 | { 82 | return $this->buildRequestForm($this->order); 83 | } 84 | 85 | public function purchase($order) 86 | { 87 | $data = []; 88 | $order["product_code"] = "FAST_INSTANT_TRADE_PAY"; 89 | 90 | $required = [ 91 | "out_trade_no", "total_amount", "subject" 92 | ]; 93 | 94 | foreach ($required as $k => $field) { 95 | if (!array_key_exists($field, $order)) { 96 | throw new \InvalidArgumentException("The {$field} field is required"); 97 | } 98 | } 99 | 100 | $data["biz_content"] = json_encode($order); 101 | $this->order = array_merge($this->preProcess(), $data); 102 | 103 | } 104 | 105 | public function queryOrderState($data) 106 | { 107 | 108 | } 109 | 110 | public function reverseOrder($order) 111 | { 112 | 113 | } 114 | 115 | 116 | public function setPrivateKey($content) 117 | { 118 | $this->private_key = $content; 119 | } 120 | 121 | public function setNotifyUrl($url) 122 | { 123 | 124 | } 125 | 126 | public function setAppId($app_id) 127 | { 128 | $this->app_id = $app_id; 129 | } 130 | 131 | public function refundOrder($order) 132 | { 133 | 134 | } 135 | 136 | } -------------------------------------------------------------------------------- /src/WeChat/JSApi/JSApi.php: -------------------------------------------------------------------------------- 1 | app_id; 48 | $pre_data["mch_id"] = $this->mch_id; 49 | $pre_data["nonce_str"] = $this->random(); 50 | return $pre_data; 51 | } 52 | 53 | public function purchase($data) 54 | { 55 | $pre_data = $this->preProcess(); 56 | 57 | $pre_data["sign_type"] = "MD5"; 58 | $pre_data["spbill_create_ip"] = $this->get_client_ip() == "::1" ? "127.0.0.1" : $this->get_client_ip(); 59 | $order = array_merge($pre_data, $data); 60 | 61 | $require_field = [ 62 | "appid", "mch_id", "nonce_str", "body", "out_trade_no", "total_fee", "spbill_create_ip", "notify_url", 63 | "trade_type" 64 | ]; 65 | 66 | foreach ($require_field as $key => $field) { 67 | if (!array_key_exists($field, $order)) { 68 | throw new \InvalidArgumentException("The {$field} field is required"); 69 | } 70 | } 71 | 72 | $this->order = $order; 73 | } 74 | 75 | public function sendPaymentRequest() 76 | { 77 | return $this->sendRequest($this->unifiedorder_url, "POST", $this->order, ""); 78 | } 79 | 80 | public function queryOrderState($order) 81 | { 82 | return $this->sendRequest($this->orderquery_url, "POST", $order, ""); 83 | } 84 | 85 | public function refundOrder($order, $ca_path) 86 | { 87 | return $this->sendRequest($this->refund_url, "POST", $order, $ca_path); 88 | 89 | } 90 | 91 | 92 | public function reverseOrder($order, $ca_path) 93 | { 94 | return $this->sendRequest($this->closeorder_url, "POST", $order, $ca_path); 95 | } 96 | 97 | public function closeOrder($order, $ca_path) 98 | { 99 | return $this->sendRequest($this->closeorder_url, "POST", $order, $ca_path); 100 | } 101 | 102 | public function refundQuery($order) 103 | { 104 | return $this->sendRequest($this->refund_query_url, "POST", $order, ""); 105 | } 106 | 107 | public function queryRefundState($order) 108 | { 109 | return $this->sendRequest($this->refund_query_url, "POST", $order, ""); 110 | } 111 | 112 | public function processNotifyMessage($raw_data) 113 | { 114 | return new WeChatRequest($raw_data, $this->api_key); 115 | } 116 | 117 | 118 | public function setApiKey($id) 119 | { 120 | $this->api_key = $id; 121 | } 122 | 123 | public function setMchId($mch_id) 124 | { 125 | $this->mch_id = $mch_id; 126 | } 127 | 128 | public function setAppId($app_id) 129 | { 130 | $this->app_id = $app_id; 131 | } 132 | } -------------------------------------------------------------------------------- /src/WeChat/Pos/Pos.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class Pos implements WeChatComm, PaymentComm 17 | { 18 | use Foundation; 19 | 20 | private $app_id; 21 | private $api_key; 22 | private $mch_id; 23 | public $order = []; 24 | public $gateway = "wechat"; 25 | 26 | /** 27 | * 提交刷卡支付URL 28 | * @var string 29 | */ 30 | public $micropay_url = "https://api.mch.weixin.qq.com/pay/micropay"; 31 | 32 | /** 33 | * 查询订单URL 34 | * @var string 35 | */ 36 | public $orderquery_url = "https://api.mch.weixin.qq.com/pay/orderquery"; 37 | /** 38 | * 申请退款URL 39 | * @var string 40 | */ 41 | public $refund_url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; 42 | 43 | /** 44 | * 撤销订单URL 45 | * @var string 46 | */ 47 | public $reverse_url = "https://api.mch.weixin.qq.com/secapi/pay/reverse"; 48 | 49 | /** 50 | * 查询退款 51 | * @var string 52 | */ 53 | public $refund_query_url = "https://api.mch.weixin.qq.com/pay/refundquery"; 54 | 55 | public function preProcess() 56 | { 57 | $pre_data["appid"] = $this->app_id; 58 | $pre_data["mch_id"] = $this->mch_id; 59 | $pre_data["nonce_str"] = $this->random(); 60 | return $pre_data; 61 | } 62 | 63 | public function purchase($data) 64 | { 65 | $pre_data = $this->preProcess(); 66 | 67 | $pre_data["sign_type"] = "MD5"; 68 | $pre_data["spbill_create_ip"] = $this->get_client_ip() == "::1" ? "127.0.0.1" : $this->get_client_ip(); 69 | $order = array_merge($pre_data, $data); 70 | 71 | if (empty($order["appid"])) { 72 | throw new \InvalidArgumentException("The appid field is required"); 73 | } 74 | if (empty($order["mch_id"])) { 75 | throw new \InvalidArgumentException("The mch_id field is required"); 76 | } 77 | 78 | if (empty($order["total_fee"])) { 79 | throw new \InvalidArgumentException("The total_fee field is required"); 80 | } 81 | if (!array_key_exists("auth_code", $order) or empty($order["auth_code"])) { 82 | throw new \InvalidArgumentException("The auth_code field is required"); 83 | } 84 | 85 | if (!array_key_exists("out_trade_no", $order) or empty($order["out_trade_no"])) { 86 | throw new \InvalidArgumentException("The out_trade_no field is required"); 87 | } 88 | 89 | $this->order = $order; 90 | } 91 | 92 | public function sendPaymentRequest() 93 | { 94 | return $this->sendRequest($this->micropay_url, "POST", $this->order, ""); 95 | } 96 | 97 | public function queryOrderState($data) 98 | { 99 | return $this->sendRequest($this->orderquery_url, "POST", $data, ""); 100 | } 101 | 102 | public function queryRefundState($data) 103 | { 104 | return $this->sendPaymentRequest($this->refund_query_url, "POST", $data, ""); 105 | } 106 | 107 | public function refundOrder($order, $ca_path) 108 | { 109 | return $this->sendRequest($this->refund_url, "POST", $order, $ca_path); 110 | } 111 | 112 | 113 | public function reverseOrder($order, $ca_path) 114 | { 115 | return $this->sendRequest($this->reverse_url, "POST", $order, $ca_path); 116 | } 117 | 118 | 119 | public function setApiKey($id) 120 | { 121 | $this->api_key = $id; 122 | } 123 | 124 | public function setMchId($mch_id) 125 | { 126 | $this->mch_id = $mch_id; 127 | } 128 | 129 | public function setAppId($app_id) 130 | { 131 | $this->app_id = $app_id; 132 | } 133 | } -------------------------------------------------------------------------------- /src/WeChat/App/App.php: -------------------------------------------------------------------------------- 1 | sendRequest($this->refund_query_url, "POST", $order, "", $this->api_key); 48 | } 49 | 50 | public function preProcess() 51 | { 52 | $pre_data["appid"] = $this->app_id; 53 | $pre_data["mch_id"] = $this->mch_id; 54 | $pre_data["nonce_str"] = $this->random(); 55 | return $pre_data; 56 | } 57 | 58 | public function purchase($data) 59 | { 60 | $pre_data = $this->preProcess(); 61 | 62 | $pre_data["sign_type"] = "MD5"; 63 | $pre_data["spbill_create_ip"] = $this->get_client_ip() == "::1" ? "127.0.0.1" : $this->get_client_ip(); 64 | $order = array_merge($pre_data, $data); 65 | 66 | $require_field = [ 67 | "appid", "mch_id", "nonce_str", "body", "out_trade_no", "total_fee", "spbill_create_ip", "notify_url", 68 | "trade_type" 69 | ]; 70 | 71 | foreach ($require_field as $key => $field) { 72 | if (!array_key_exists($field, $order)) { 73 | throw new \InvalidArgumentException("The {$field} field is required"); 74 | } 75 | } 76 | $this->order = $order; 77 | } 78 | 79 | public function sendPaymentRequest() 80 | { 81 | return $this->sendRequest($this->unifiedorder_url, "POST", $this->order, "", $this->api_key); 82 | } 83 | 84 | public function queryOrderState($order) 85 | { 86 | return $this->sendRequest($this->orderquery_url, "POST", $order, "", $this->api_key); 87 | } 88 | 89 | public function refundOrder($order, $ca_path) 90 | { 91 | return $this->sendRequest($this->refund_url, "POST", $order, $ca_path, $this->api_key); 92 | 93 | } 94 | 95 | 96 | public function reverseOrder($order, $ca_path) 97 | { 98 | return $this->sendRequest($this->closeorder_url, "POST", $order, $ca_path, $this->api_key); 99 | } 100 | 101 | public function closeOrder($order, $ca_path) 102 | { 103 | return $this->sendRequest($this->closeorder_url, "POST", $order, $ca_path, $this->api_key); 104 | } 105 | 106 | public function refundQuery($order) 107 | { 108 | return $this->sendRequest($this->refund_query_url, "POST", $order, "", $this->api_key); 109 | } 110 | 111 | public function processNotifyMessage($raw_data) 112 | { 113 | return new WeChatRequest($raw_data, $this->api_key); 114 | } 115 | 116 | 117 | public function setApiKey($id) 118 | { 119 | $this->api_key = $id; 120 | } 121 | 122 | public function setMchId($mch_id) 123 | { 124 | $this->mch_id = $mch_id; 125 | } 126 | 127 | public function setAppId($app_id) 128 | { 129 | $this->app_id = $app_id; 130 | } 131 | } -------------------------------------------------------------------------------- /src/WeChat/H5/H5.php: -------------------------------------------------------------------------------- 1 | sendRequest($this->refund_query_url, "POST", $order, "", $this->api_key); 48 | } 49 | 50 | public function preProcess() 51 | { 52 | $pre_data["appid"] = $this->app_id; 53 | $pre_data["mch_id"] = $this->mch_id; 54 | $pre_data["nonce_str"] = $this->random(); 55 | return $pre_data; 56 | } 57 | 58 | public function purchase($data) 59 | { 60 | $pre_data = $this->preProcess(); 61 | 62 | $pre_data["sign_type"] = "MD5"; 63 | $pre_data["spbill_create_ip"] = $this->get_client_ip() == "::1" ? "127.0.0.1" : $this->get_client_ip(); 64 | $order = array_merge($pre_data, $data); 65 | 66 | $require_field = [ 67 | "appid", "mch_id", "nonce_str", "body", "out_trade_no", "total_fee", "spbill_create_ip", "notify_url", 68 | "trade_type","scene_info" 69 | ]; 70 | 71 | foreach ($require_field as $key => $field) { 72 | if (!array_key_exists($field, $order)) { 73 | throw new \InvalidArgumentException("The {$field} field is required"); 74 | } 75 | } 76 | $this->order = $order; 77 | } 78 | 79 | public function sendPaymentRequest() 80 | { 81 | return $this->sendRequest($this->unifiedorder_url, "POST", $this->order, "", $this->api_key); 82 | } 83 | 84 | public function queryOrderState($order) 85 | { 86 | return $this->sendRequest($this->orderquery_url, "POST", $order, "", $this->api_key); 87 | } 88 | 89 | public function refundOrder($order, $ca_path) 90 | { 91 | return $this->sendRequest($this->refund_url, "POST", $order, $ca_path, $this->api_key); 92 | 93 | } 94 | 95 | 96 | public function reverseOrder($order, $ca_path) 97 | { 98 | return $this->sendRequest($this->closeorder_url, "POST", $order, $ca_path, $this->api_key); 99 | } 100 | 101 | public function closeOrder($order, $ca_path) 102 | { 103 | return $this->sendRequest($this->closeorder_url, "POST", $order, $ca_path, $this->api_key); 104 | } 105 | 106 | public function refundQuery($order) 107 | { 108 | return $this->sendRequest($this->refund_query_url, "POST", $order, "", $this->api_key); 109 | } 110 | 111 | public function processNotifyMessage($raw_data) 112 | { 113 | return new WeChatRequest($raw_data, $this->api_key); 114 | } 115 | 116 | 117 | public function setApiKey($id) 118 | { 119 | $this->api_key = $id; 120 | } 121 | 122 | public function setMchId($mch_id) 123 | { 124 | $this->mch_id = $mch_id; 125 | } 126 | 127 | public function setAppId($app_id) 128 | { 129 | $this->app_id = $app_id; 130 | } 131 | } -------------------------------------------------------------------------------- /src/AliPay/JSApi/JSApi.php: -------------------------------------------------------------------------------- 1 | sign_type = $type; 31 | } 32 | 33 | public function setBaseData($data) 34 | { 35 | $this->base = $data; 36 | } 37 | 38 | public function preProcess() 39 | { 40 | $arr = array_merge([ 41 | "app_id" => $this->app_id, 42 | "format" => "JSON", 43 | "charset" => "utf-8", 44 | "sign_type" => $this->sign_type, 45 | "timestamp" => date("Y-m-d H:i:s"), 46 | "version" => "1.0", 47 | "notify_url" => $this->notify_url, 48 | ], $this->base); 49 | 50 | if ($this->enable_koubei_promo == true) { 51 | $arr["promo_params"] = "{\"kborder_flag\":\"order\"}"; 52 | } 53 | return $arr; 54 | } 55 | 56 | public function setPublicKey($key) 57 | { 58 | $this->public_key = $key; 59 | } 60 | 61 | public function queryRefundState($order) 62 | { 63 | $this->method = "alipay.trade.fastpay.refund.query"; 64 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 65 | } 66 | 67 | public function purchase($order) 68 | { 69 | $require_field = [ 70 | "out_trade_no", "total_amount", "subject", "buyer_id" 71 | ]; 72 | 73 | foreach ($require_field as $key => $field) { 74 | if (!array_key_exists($field, $order)) { 75 | throw new \InvalidArgumentException("The {$field} field is required, see detail https://docs.open.alipay.com/api_1/alipay.trade.pay"); 76 | } 77 | } 78 | 79 | $this->order = $order; 80 | } 81 | 82 | public function reverseOrder($order) 83 | { 84 | $this->method = "alipay.trade.cancel"; 85 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 86 | } 87 | 88 | public function refundOrder($order) 89 | { 90 | $this->method = "alipay.trade.refund"; 91 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 92 | } 93 | 94 | public function setAppId($app_id) 95 | { 96 | $this->app_id = $app_id; 97 | } 98 | 99 | public function setNotifyUrl($url) 100 | { 101 | $this->notify_url = $url; 102 | } 103 | 104 | public function setPrivateKey($content) 105 | { 106 | $this->private_key = $content; 107 | } 108 | 109 | public function sendPaymentRequest() 110 | { 111 | $this->method = "alipay.trade.create"; 112 | return $this->sendRequest($this->gateway_url, "POST", $this->order, "", $this->private_key); 113 | } 114 | 115 | public function queryOrderState($data) 116 | { 117 | $this->method = "alipay.trade.query"; 118 | return $this->sendRequest($this->gateway_url, "POST", $data, "", $this->private_key); 119 | } 120 | 121 | public function enableKoubeiPromo($bool) 122 | { 123 | $this->enable_koubei_promo = $bool; 124 | } 125 | 126 | public function processNotifyMessage($message) 127 | { 128 | return new AliPayRequest($message, $this->public_key); 129 | } 130 | } -------------------------------------------------------------------------------- /src/WeChat/Native/Native.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | class Native implements WeChatComm, PaymentComm 17 | { 18 | use Foundation; 19 | 20 | private $app_id; 21 | private $api_key; 22 | private $mch_id; 23 | public $order = []; 24 | public $gateway = "wechat"; 25 | 26 | /** 27 | * 统一下单URL 28 | * @var string 29 | */ 30 | public $unifiedorder_url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; 31 | /** 32 | * 订单查询URL 33 | * @var string 34 | */ 35 | public $orderquery_url = "https://api.mch.weixin.qq.com/pay/orderquery"; 36 | /** 37 | * 关闭订单URL 38 | * @var string 39 | */ 40 | public $closeorder_url = "https://api.mch.weixin.qq.com/pay/closeorder"; 41 | /** 42 | * 申请退款URL 43 | * @var string 44 | */ 45 | public $refund_url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; 46 | /** 47 | * 查询退款URL 48 | * @var string 49 | */ 50 | public $refund_query_url = "https://api.mch.weixin.qq.com/pay/refundquery"; 51 | 52 | public function preProcess() 53 | { 54 | $pre_data["appid"] = $this->app_id; 55 | $pre_data["mch_id"] = $this->mch_id; 56 | $pre_data["nonce_str"] = "uBFpfrllIoFxWQnz";//$this->random(); 57 | return $pre_data; 58 | } 59 | 60 | public function purchase($data) 61 | { 62 | $pre_data = $this->preProcess(); 63 | 64 | $pre_data["sign_type"] = "MD5"; 65 | $pre_data["spbill_create_ip"] = $this->get_client_ip() == "::1" ? "127.0.0.1" : $this->get_client_ip(); 66 | $order = array_merge($pre_data, $data); 67 | 68 | $require_field = [ 69 | "appid", "mch_id", "nonce_str", "body","product_id", "out_trade_no", "total_fee", "spbill_create_ip", "notify_url", 70 | "trade_type" 71 | ]; 72 | 73 | foreach ($require_field as $key => $field) { 74 | if (!array_key_exists($field, $order)) { 75 | throw new \InvalidArgumentException("The {$field} field is required"); 76 | } 77 | } 78 | 79 | $this->order = $order; 80 | } 81 | 82 | public function sendPaymentRequest() 83 | { 84 | return $this->sendRequest($this->unifiedorder_url, "POST", $this->order, ""); 85 | } 86 | 87 | public function queryOrderState($order) 88 | { 89 | return $this->sendRequest($this->orderquery_url, "POST", $order, ""); 90 | } 91 | 92 | public function refundOrder($order, $ca_path) 93 | { 94 | return $this->sendRequest($this->refund_url, "POST", $order, $ca_path); 95 | 96 | } 97 | 98 | public function queryRefundState($order) 99 | { 100 | return $this->sendRequest($this->refund_query_url, "POST", $order); 101 | } 102 | 103 | public function reverseOrder($order, $ca_path) 104 | { 105 | return $this->sendRequest($this->closeorder_url, "POST", $order, $ca_path); 106 | } 107 | 108 | public function closeOrder($order) 109 | { 110 | return $this->sendRequest($this->closeorder_url, "POST", $order); 111 | } 112 | 113 | public function refundQuery($order) 114 | { 115 | return $this->sendRequest($this->refundquery_url, "POST", $order, ""); 116 | } 117 | 118 | public function processNotifyMessage($raw_data) 119 | { 120 | return new WeChatRequest($raw_data, $this->api_key); 121 | } 122 | 123 | 124 | public function setApiKey($id) 125 | { 126 | $this->api_key = $id; 127 | } 128 | 129 | public function setMchId($mch_id) 130 | { 131 | $this->mch_id = $mch_id; 132 | } 133 | 134 | public function setAppId($app_id) 135 | { 136 | $this->app_id = $app_id; 137 | } 138 | } -------------------------------------------------------------------------------- /src/AliPay/Qr/Qr.php: -------------------------------------------------------------------------------- 1 | sign_type = $type; 30 | } 31 | 32 | public function setBaseData($data) 33 | { 34 | $this->base = $data; 35 | } 36 | 37 | 38 | public function preProcess() 39 | { 40 | $query_params = array_merge([ 41 | "app_id" => $this->app_id, 42 | "format" => "JSON", 43 | "charset" => "utf-8", 44 | "sign_type" => $this->sign_type, 45 | "timestamp" => date("Y-m-d H:i:s"), 46 | "version" => "1.0" 47 | ], $this->base); 48 | 49 | if (!empty($this->notify_url)) { 50 | $query_params["notify_url"] = $this->notify_url; 51 | } 52 | 53 | return $query_params; 54 | } 55 | 56 | public function setNotifyUrl($url) 57 | { 58 | $this->notify_url = $url; 59 | } 60 | 61 | public function setPrivateKey($key) 62 | { 63 | $this->private_key = $key; 64 | } 65 | 66 | public function setPublicKey($key) 67 | { 68 | $this->public_key = $key; 69 | } 70 | 71 | 72 | public function queryOrderState($order) 73 | { 74 | $this->method = "alipay.trade.query"; 75 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 76 | } 77 | 78 | public function sendPaymentRequest() 79 | { 80 | $this->method = "alipay.trade.precreate"; 81 | return $this->sendRequest($this->gateway_url, "POST", $this->order, ""); 82 | } 83 | 84 | public function queryRefundState($order) 85 | { 86 | $this->method = "alipay.trade.fastpay.refund.query"; 87 | return $this->sendRequest($this->gateway_url, "POST", $order, ""); 88 | } 89 | 90 | public function purchase($order) 91 | { 92 | $require_field = [ 93 | "out_trade_no", "total_amount", "subject" 94 | ]; 95 | 96 | foreach ($require_field as $key => $field) { 97 | if (!array_key_exists($field, $order)) { 98 | throw new \InvalidArgumentException("The {$field} field is required, see detail https://docs.open.alipay.com/api_1/alipay.trade.precreate"); 99 | } 100 | } 101 | 102 | $this->order = $order; 103 | } 104 | 105 | public function refundOrder($order) 106 | { 107 | $this->method = "alipay.trade.refund"; 108 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 109 | } 110 | 111 | public function reverseOrder($order) 112 | { 113 | $this->method = "alipay.trade.cancel"; 114 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 115 | } 116 | 117 | public function setAppId($app_id) 118 | { 119 | $this->app_id = $app_id; 120 | } 121 | 122 | public function processNotifyMessage($message) 123 | { 124 | return new AliPayRequest($message, $this->public_key); 125 | } 126 | 127 | public function checkSign($param, $key) 128 | { 129 | $sign = $param["sign"]; 130 | $param["sign"] = null; 131 | $param["sign_type"] = null; 132 | ksort($param); 133 | $query_string = urldecode(http_build_query($param)); 134 | 135 | $res = "-----BEGIN PUBLIC KEY-----\n" . 136 | wordwrap($key, 64, "\n", true) . 137 | "\n-----END PUBLIC KEY-----"; 138 | 139 | $result = openssl_verify($query_string, base64_decode($sign), $res); 140 | if ($result == 1) { 141 | return true; 142 | } 143 | return false; 144 | 145 | } 146 | } -------------------------------------------------------------------------------- /src/AliPay/App/App.php: -------------------------------------------------------------------------------- 1 | 14 | */ 15 | class App implements AliPayComm, PaymentComm 16 | { 17 | use Foundation; 18 | 19 | public $app_id; 20 | public $public_key; 21 | private $private_key; 22 | public $notify_url; 23 | public $sign_type; 24 | public $order; 25 | public $base = []; 26 | public $method; 27 | public $gateway = "alipay"; 28 | public $postCharset = "UTF-8"; 29 | 30 | public $enable_koubei_promo = false; //是否开启口碑折扣 @see https://open.koubei.com/#/solution?type=codeServer&no=koubei_qrcode_orderdishes 31 | 32 | public $gateway_url = "https://openapi.alipay.com/gateway.do"; 33 | 34 | public function setSignType($type) 35 | { 36 | $this->sign_type = $type; 37 | } 38 | 39 | public function setBaseData($data) 40 | { 41 | $this->base = $data; 42 | } 43 | 44 | public function preProcess() 45 | { 46 | $arr = array_merge([ 47 | "app_id" => $this->app_id, 48 | "format" => "JSON", 49 | "charset" => "utf-8", 50 | "sign_type" => $this->sign_type, 51 | "timestamp" => date("Y-m-d H:i:s"), 52 | "version" => "1.0", 53 | "notify_url" => $this->notify_url, 54 | ], $this->base); 55 | 56 | if ($this->enable_koubei_promo == true) { 57 | $arr["promo_params"] = "{\"kborder_flag\":\"order\"}"; 58 | } 59 | return $arr; 60 | } 61 | 62 | public function setPublicKey($key) 63 | { 64 | $this->public_key = $key; 65 | } 66 | 67 | public function queryRefundState($order) 68 | { 69 | $this->method = "alipay.trade.fastpay.refund.query"; 70 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 71 | } 72 | 73 | public function purchase($order) 74 | { 75 | $require_field = [ 76 | "out_trade_no", "total_amount", "subject", "product_code" 77 | ]; 78 | 79 | foreach ($require_field as $key => $field) { 80 | if (!array_key_exists($field, $order)) { 81 | throw new \InvalidArgumentException("The {$field} field is required, see detail https://docs.open.alipay.com/api_1/alipay.trade.pay"); 82 | } 83 | } 84 | 85 | $this->order = $order; 86 | } 87 | 88 | public function reverseOrder($order) 89 | { 90 | $this->method = "alipay.trade.cancel"; 91 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 92 | } 93 | 94 | public function refundOrder($order) 95 | { 96 | $this->method = "alipay.trade.refund"; 97 | return $this->sendRequest($this->gateway_url, "POST", $order, "", $this->private_key); 98 | } 99 | 100 | public function setAppId($app_id) 101 | { 102 | $this->app_id = $app_id; 103 | } 104 | 105 | public function setNotifyUrl($url) 106 | { 107 | $this->notify_url = $url; 108 | } 109 | 110 | public function setPrivateKey($content) 111 | { 112 | $this->private_key = $content; 113 | } 114 | 115 | public function sendPaymentRequest() 116 | { 117 | $this->method = "alipay.trade.app.pay"; 118 | $query = $this->preProcess(); 119 | $query["method"] = $this->method; 120 | $query["biz_content"] = json_encode($this->order,JSON_UNESCAPED_UNICODE); 121 | ksort($query); 122 | $query["sign"] = $this->makeSignature($query, $this->private_key); 123 | 124 | return http_build_query($query); 125 | } 126 | 127 | public function queryOrderState($data) 128 | { 129 | $this->method = "alipay.trade.query"; 130 | return $this->sendRequest($this->gateway_url, "POST", $data, "", $this->private_key); 131 | } 132 | 133 | public function enableKoubeiPromo($bool) 134 | { 135 | $this->enable_koubei_promo = $bool; 136 | } 137 | 138 | public function processNotifyMessage($message) 139 | { 140 | return new AliPayRequest($message, $this->public_key); 141 | } 142 | } -------------------------------------------------------------------------------- /src/Foundation/Foundation.php: -------------------------------------------------------------------------------- 1 | 15 | */ 16 | trait Foundation 17 | { 18 | /** 19 | * 随机字符串 20 | * @param int $length 21 | * @return string 22 | */ 23 | function random($length = 16) 24 | { 25 | $characters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 26 | $charactersLength = strlen($characters); 27 | $randomString = ''; 28 | for ($i = 0; $i < $length; $i++) { 29 | $randomString .= $characters[rand(0, $charactersLength - 1)]; 30 | } 31 | return $randomString; 32 | } 33 | 34 | /** 35 | * 发送支付网络请求 36 | * @param string $url 请求的URL 37 | * @param string $method 请求的method 38 | * @param array $data 请求数据 39 | * @param string $ca_path 是否使用证书 40 | * @throws 41 | * @return object 42 | */ 43 | public function sendRequest($url, $method = "POST", $data, $ca_path = "") 44 | { 45 | $client = new Client(); 46 | 47 | if ($this->gateway == "wechat") { 48 | 49 | $pre = $this->preProcess(); 50 | $query = array_merge($pre, $data); 51 | $query["sign"] = $this->makeSignature($query, $this->api_key); 52 | $xml = $this->toXML($query); 53 | $headers = ['body' => $xml, 'Content-Type' => 'text/xml; charset=UTF8']; 54 | if (!empty($ca_path)) { 55 | $headers["cert"] = $ca_path; 56 | } 57 | $response = $client->request($method, $url, $headers); 58 | return new WeChatResponse($response, $query, $this->api_key); 59 | 60 | 61 | } elseif ($this->gateway == "alipay") { 62 | 63 | $query = $this->preProcess(); 64 | $query["method"] = $this->method; 65 | $query["biz_content"] = json_encode($data); 66 | $query["sign"] = $this->makeSignature($query, $this->private_key); 67 | $response = $client->request("POST", $url, [ 68 | "query" => $query 69 | ]); 70 | return new AliPayResponse($response, $query, $this->private_key); 71 | } 72 | 73 | } 74 | 75 | /** 76 | * array to xml 77 | * @param array $data 78 | * @return bool|string 79 | */ 80 | public function toXML($data) 81 | { 82 | if (!is_array($data) || count($data) == 0) { 83 | return false; 84 | } 85 | 86 | $xml = ""; 87 | foreach ($data as $key => $val) { 88 | if (is_numeric($val)) { 89 | $xml .= "<" . $key . ">" . $val . ""; 90 | } else { 91 | $xml .= "<" . $key . ">"; 92 | } 93 | } 94 | $xml .= ""; 95 | return $xml; 96 | } 97 | 98 | 99 | public function getConfig($model) 100 | { 101 | $result = new \stdClass(); 102 | $result->merchant_id = $model->merchant_id; 103 | $result->type = $model->type; 104 | $result->subject = $model->subject; 105 | 106 | if ($this->gateway == "wechat") { 107 | if ($model->type == "partner") { 108 | //服务商类型的账户 109 | if ($model->pid > 0) { 110 | $partner = $model->getPartner; 111 | if ($partner) { 112 | $result->sub_appid = $model->app_id; 113 | $result->sub_mch_id = $model->mch_id; 114 | $result->app_id = $partner->app_id; 115 | $result->mch_id = $partner->mch_id; 116 | $result->secret_key = $partner->secret_key; 117 | $result->pem = $partner->pem; 118 | } 119 | } 120 | 121 | return $result; 122 | } 123 | return $model; 124 | } elseif ($this->gateway == "alipay") { 125 | if ($model->type == "partner") { 126 | if ($model->pid > 0) { 127 | $partner = $model->getPartner; 128 | if ($partner) { 129 | $result->app_id = $model->app_id; 130 | $result->private_key = $model->private_key; 131 | $result->public_key = $model->public_key; 132 | $result->system_id = $partner->app_id; 133 | } 134 | } 135 | return $result; 136 | } 137 | 138 | return $model; 139 | } 140 | 141 | } 142 | 143 | /** 144 | * 生成签名 145 | * @param array $param 146 | * @param string $key 147 | * @return string 148 | */ 149 | public function makeSignature($param, $key) 150 | { 151 | 152 | ksort($param); 153 | 154 | if ($this->gateway == "wechat") { 155 | 156 | $sign_str = urldecode(http_build_query($param)) . "&key=" . $key; 157 | $sign = md5($sign_str); 158 | 159 | } else { 160 | 161 | $stringToBeSigned = ""; 162 | $i = 0; 163 | foreach ($param as $k => $v) { 164 | if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { 165 | 166 | if ($i == 0) { 167 | $stringToBeSigned .= "$k" . "=" . "$v"; 168 | } else { 169 | $stringToBeSigned .= "&" . "$k" . "=" . "$v"; 170 | } 171 | $i++; 172 | } 173 | } 174 | 175 | unset ($k, $v); 176 | $res = "-----BEGIN RSA PRIVATE KEY-----\n" . 177 | wordwrap($key, 64, "\n", true) . 178 | "\n-----END RSA PRIVATE KEY-----"; 179 | 180 | if ($this->sign_type == "RSA") { 181 | openssl_sign($stringToBeSigned, $sign, $res); 182 | } else { 183 | openssl_sign($stringToBeSigned, $sign, $res, OPENSSL_ALGO_SHA256); 184 | } 185 | $sign = base64_encode($sign); 186 | } 187 | 188 | return $sign; 189 | 190 | } 191 | 192 | /** 193 | * 校验$value是否非空 194 | * if not set ,return true; 195 | * if is null , return true; 196 | **/ 197 | protected function checkEmpty($value) 198 | { 199 | if (!isset($value)) 200 | return true; 201 | if ($value === null) 202 | return true; 203 | if (trim($value) === "") 204 | return true; 205 | 206 | return false; 207 | } 208 | 209 | /** 210 | * 格式化返回 211 | * @param $message 212 | * @param $status 213 | * @param $command 214 | * @param string $trade_no 215 | * @return array 216 | * @author Andylee 217 | */ 218 | public function encodeResult($message, $status, $command, $trade_no = "") 219 | { 220 | $result = [ 221 | "message" => $message, 222 | "status" => $status, 223 | "command" => $command, 224 | "trade_no" => $trade_no 225 | ]; 226 | 227 | return $result; 228 | } 229 | 230 | /** 231 | * 检测签名 232 | * @param $param 233 | * @param $key 234 | * @return mixed 235 | * @author Andylee 236 | */ 237 | public function checkSignature($param, $key) 238 | { 239 | $origin_sign = $param["sign"]; 240 | unset($param["sign"]); 241 | ksort($param); 242 | $new_sign = md5(urldecode(http_build_query($param)) . "&key=" . $key); 243 | if ($origin_sign == strtoupper($new_sign)) { 244 | return true; 245 | } else { 246 | return false; 247 | } 248 | } 249 | 250 | public function checkAliPayNotifyMessage($param, $pub_key) 251 | { 252 | $sign = $param["sign"]; 253 | $type = $param["sign_type"]; 254 | $param["sign"] = null; 255 | $param["sign_type"] = null; 256 | ksort($param); 257 | $query_string = urldecode(http_build_query($param)); 258 | 259 | $res = "-----BEGIN PUBLIC KEY-----\n" . 260 | wordwrap($pub_key, 64, "\n", true) . 261 | "\n-----END PUBLIC KEY-----"; 262 | 263 | if ($type == "RSA") { 264 | $result = openssl_verify($query_string, base64_decode($sign), $res); 265 | } else { 266 | $result = openssl_verify($query_string, base64_decode($sign), $res, OPENSSL_ALGO_SHA256); 267 | } 268 | if ($result == 1) { 269 | return true; 270 | } 271 | return false; 272 | } 273 | 274 | public function get_client_ip() 275 | { 276 | $ip_address = ''; 277 | if (isset($_SERVER['HTTP_CLIENT_IP'])) 278 | $ip_address = $_SERVER['HTTP_CLIENT_IP']; 279 | else if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) 280 | $ip_address = $_SERVER['HTTP_X_FORWARDED_FOR']; 281 | else if (isset($_SERVER['HTTP_X_FORWARDED'])) 282 | $ip_address = $_SERVER['HTTP_X_FORWARDED']; 283 | else if (isset($_SERVER['HTTP_FORWARDED_FOR'])) 284 | $ip_address = $_SERVER['HTTP_FORWARDED_FOR']; 285 | else if (isset($_SERVER['HTTP_FORWARDED'])) 286 | $ip_address = $_SERVER['HTTP_FORWARDED']; 287 | else if (isset($_SERVER['REMOTE_ADDR'])) 288 | $ip_address = $_SERVER['REMOTE_ADDR']; 289 | else 290 | $ip_address = '0.0.0.0'; 291 | return $ip_address; 292 | } 293 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /composer.lock: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "190ca4750d72b4ebcb15ef44a2be68ba", 8 | "packages": [ 9 | { 10 | "name": "guzzlehttp/guzzle", 11 | "version": "dev-master", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/guzzle/guzzle.git", 15 | "reference": "065287bc14f3e606fe6aec6ecfeac9616afbd3cb" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://files.phpcomposer.com/files/guzzle/guzzle/065287bc14f3e606fe6aec6ecfeac9616afbd3cb.zip", 20 | "reference": "065287bc14f3e606fe6aec6ecfeac9616afbd3cb", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "guzzlehttp/promises": "^1.0", 25 | "guzzlehttp/psr7": "^1.4", 26 | "php": ">=5.5" 27 | }, 28 | "require-dev": { 29 | "ext-curl": "*", 30 | "phpunit/phpunit": "^4.0 || ^5.0", 31 | "psr/log": "^1.0" 32 | }, 33 | "suggest": { 34 | "psr/log": "Required for using the Log middleware" 35 | }, 36 | "type": "library", 37 | "extra": { 38 | "branch-alias": { 39 | "dev-master": "6.2-dev" 40 | } 41 | }, 42 | "autoload": { 43 | "files": [ 44 | "src/functions_include.php" 45 | ], 46 | "psr-4": { 47 | "GuzzleHttp\\": "src/" 48 | } 49 | }, 50 | "notification-url": "https://packagist.org/downloads/", 51 | "license": [ 52 | "MIT" 53 | ], 54 | "authors": [ 55 | { 56 | "name": "Michael Dowling", 57 | "email": "mtdowling@gmail.com", 58 | "homepage": "https://github.com/mtdowling" 59 | } 60 | ], 61 | "description": "Guzzle is a PHP HTTP client library", 62 | "homepage": "http://guzzlephp.org/", 63 | "keywords": [ 64 | "client", 65 | "curl", 66 | "framework", 67 | "http", 68 | "http client", 69 | "rest", 70 | "web service" 71 | ], 72 | "time": "2017-06-10T14:17:14+00:00" 73 | }, 74 | { 75 | "name": "guzzlehttp/promises", 76 | "version": "dev-master", 77 | "source": { 78 | "type": "git", 79 | "url": "https://github.com/guzzle/promises.git", 80 | "reference": "09e549f5534380c68761260a71f847644d8f65aa" 81 | }, 82 | "dist": { 83 | "type": "zip", 84 | "url": "https://files.phpcomposer.com/files/guzzle/promises/09e549f5534380c68761260a71f847644d8f65aa.zip", 85 | "reference": "09e549f5534380c68761260a71f847644d8f65aa", 86 | "shasum": "" 87 | }, 88 | "require": { 89 | "php": ">=5.5.0" 90 | }, 91 | "require-dev": { 92 | "phpunit/phpunit": "^4.0" 93 | }, 94 | "type": "library", 95 | "extra": { 96 | "branch-alias": { 97 | "dev-master": "1.4-dev" 98 | } 99 | }, 100 | "autoload": { 101 | "psr-4": { 102 | "GuzzleHttp\\Promise\\": "src/" 103 | }, 104 | "files": [ 105 | "src/functions_include.php" 106 | ] 107 | }, 108 | "notification-url": "https://packagist.org/downloads/", 109 | "license": [ 110 | "MIT" 111 | ], 112 | "authors": [ 113 | { 114 | "name": "Michael Dowling", 115 | "email": "mtdowling@gmail.com", 116 | "homepage": "https://github.com/mtdowling" 117 | } 118 | ], 119 | "description": "Guzzle promises library", 120 | "keywords": [ 121 | "promise" 122 | ], 123 | "time": "2017-05-20 23:14:18" 124 | }, 125 | { 126 | "name": "guzzlehttp/psr7", 127 | "version": "dev-master", 128 | "source": { 129 | "type": "git", 130 | "url": "https://github.com/guzzle/psr7.git", 131 | "reference": "8dfe52c2d14a68ff3dce6af82058391c6c4eb9b3" 132 | }, 133 | "dist": { 134 | "type": "zip", 135 | "url": "https://files.phpcomposer.com/files/guzzle/psr7/8dfe52c2d14a68ff3dce6af82058391c6c4eb9b3.zip", 136 | "reference": "8dfe52c2d14a68ff3dce6af82058391c6c4eb9b3", 137 | "shasum": "" 138 | }, 139 | "require": { 140 | "php": ">=5.4.0", 141 | "psr/http-message": "~1.0" 142 | }, 143 | "provide": { 144 | "psr/http-message-implementation": "1.0" 145 | }, 146 | "require-dev": { 147 | "phpunit/phpunit": "~4.0" 148 | }, 149 | "type": "library", 150 | "extra": { 151 | "branch-alias": { 152 | "dev-master": "1.4-dev" 153 | } 154 | }, 155 | "autoload": { 156 | "psr-4": { 157 | "GuzzleHttp\\Psr7\\": "src/" 158 | }, 159 | "files": [ 160 | "src/functions_include.php" 161 | ] 162 | }, 163 | "notification-url": "https://packagist.org/downloads/", 164 | "license": [ 165 | "MIT" 166 | ], 167 | "authors": [ 168 | { 169 | "name": "Michael Dowling", 170 | "email": "mtdowling@gmail.com", 171 | "homepage": "https://github.com/mtdowling" 172 | }, 173 | { 174 | "name": "Tobias Schultze", 175 | "homepage": "https://github.com/Tobion" 176 | } 177 | ], 178 | "description": "PSR-7 message implementation that also provides common utility methods", 179 | "keywords": [ 180 | "http", 181 | "message", 182 | "request", 183 | "response", 184 | "stream", 185 | "uri", 186 | "url" 187 | ], 188 | "time": "2017-06-10 19:55:42" 189 | }, 190 | { 191 | "name": "monolog/monolog", 192 | "version": "1.x-dev", 193 | "source": { 194 | "type": "git", 195 | "url": "https://github.com/Seldaek/monolog.git", 196 | "reference": "35c07a81de6200e5aa0629eacecd11fd925d19dc" 197 | }, 198 | "dist": { 199 | "type": "zip", 200 | "url": "https://files.phpcomposer.com/files/Seldaek/monolog/35c07a81de6200e5aa0629eacecd11fd925d19dc.zip", 201 | "reference": "35c07a81de6200e5aa0629eacecd11fd925d19dc", 202 | "shasum": "" 203 | }, 204 | "require": { 205 | "php": ">=5.3.0", 206 | "psr/log": "~1.0" 207 | }, 208 | "provide": { 209 | "psr/log-implementation": "1.0.0" 210 | }, 211 | "require-dev": { 212 | "aws/aws-sdk-php": "^2.4.9 || ^3.0", 213 | "doctrine/couchdb": "~1.0@dev", 214 | "graylog2/gelf-php": "~1.0", 215 | "jakub-onderka/php-parallel-lint": "0.9", 216 | "php-amqplib/php-amqplib": "~2.4", 217 | "php-console/php-console": "^3.1.3", 218 | "phpunit/phpunit": "~4.5", 219 | "phpunit/phpunit-mock-objects": "2.3.0", 220 | "ruflin/elastica": ">=0.90 <3.0", 221 | "sentry/sentry": "^0.13", 222 | "swiftmailer/swiftmailer": "~5.3" 223 | }, 224 | "suggest": { 225 | "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", 226 | "doctrine/couchdb": "Allow sending log messages to a CouchDB server", 227 | "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", 228 | "ext-mongo": "Allow sending log messages to a MongoDB server", 229 | "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", 230 | "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", 231 | "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", 232 | "php-console/php-console": "Allow sending log messages to Google Chrome", 233 | "rollbar/rollbar": "Allow sending log messages to Rollbar", 234 | "ruflin/elastica": "Allow sending log messages to an Elastic Search server", 235 | "sentry/sentry": "Allow sending log messages to a Sentry server" 236 | }, 237 | "type": "library", 238 | "extra": { 239 | "branch-alias": { 240 | "dev-master": "2.0.x-dev" 241 | } 242 | }, 243 | "autoload": { 244 | "psr-4": { 245 | "Monolog\\": "src/Monolog" 246 | } 247 | }, 248 | "notification-url": "https://packagist.org/downloads/", 249 | "license": [ 250 | "MIT" 251 | ], 252 | "authors": [ 253 | { 254 | "name": "Jordi Boggiano", 255 | "email": "j.boggiano@seld.be", 256 | "homepage": "http://seld.be" 257 | } 258 | ], 259 | "description": "Sends your logs to files, sockets, inboxes, databases and various web services", 260 | "homepage": "http://github.com/Seldaek/monolog", 261 | "keywords": [ 262 | "log", 263 | "logging", 264 | "psr-3" 265 | ], 266 | "time": "2017-05-03 13:17:21" 267 | }, 268 | { 269 | "name": "psr/http-message", 270 | "version": "dev-master", 271 | "source": { 272 | "type": "git", 273 | "url": "https://github.com/php-fig/http-message.git", 274 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 275 | }, 276 | "dist": { 277 | "type": "zip", 278 | "url": "https://files.phpcomposer.com/files/php-fig/http-message/f6561bf28d520154e4b0ec72be95418abe6d9363.zip", 279 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 280 | "shasum": "" 281 | }, 282 | "require": { 283 | "php": ">=5.3.0" 284 | }, 285 | "type": "library", 286 | "extra": { 287 | "branch-alias": { 288 | "dev-master": "1.0.x-dev" 289 | } 290 | }, 291 | "autoload": { 292 | "psr-4": { 293 | "Psr\\Http\\Message\\": "src/" 294 | } 295 | }, 296 | "notification-url": "https://packagist.org/downloads/", 297 | "license": [ 298 | "MIT" 299 | ], 300 | "authors": [ 301 | { 302 | "name": "PHP-FIG", 303 | "homepage": "http://www.php-fig.org/" 304 | } 305 | ], 306 | "description": "Common interface for HTTP messages", 307 | "homepage": "https://github.com/php-fig/http-message", 308 | "keywords": [ 309 | "http", 310 | "http-message", 311 | "psr", 312 | "psr-7", 313 | "request", 314 | "response" 315 | ], 316 | "time": "2016-08-06 14:39:51" 317 | }, 318 | { 319 | "name": "psr/log", 320 | "version": "dev-master", 321 | "source": { 322 | "type": "git", 323 | "url": "https://github.com/php-fig/log.git", 324 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" 325 | }, 326 | "dist": { 327 | "type": "zip", 328 | "url": "https://files.phpcomposer.com/files/php-fig/log/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d.zip", 329 | "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", 330 | "shasum": "" 331 | }, 332 | "require": { 333 | "php": ">=5.3.0" 334 | }, 335 | "type": "library", 336 | "extra": { 337 | "branch-alias": { 338 | "dev-master": "1.0.x-dev" 339 | } 340 | }, 341 | "autoload": { 342 | "psr-4": { 343 | "Psr\\Log\\": "Psr/Log/" 344 | } 345 | }, 346 | "notification-url": "https://packagist.org/downloads/", 347 | "license": [ 348 | "MIT" 349 | ], 350 | "authors": [ 351 | { 352 | "name": "PHP-FIG", 353 | "homepage": "http://www.php-fig.org/" 354 | } 355 | ], 356 | "description": "Common interface for logging libraries", 357 | "homepage": "https://github.com/php-fig/log", 358 | "keywords": [ 359 | "log", 360 | "psr", 361 | "psr-3" 362 | ], 363 | "time": "2016-10-10 12:19:37" 364 | } 365 | ], 366 | "packages-dev": [], 367 | "aliases": [], 368 | "minimum-stability": "dev", 369 | "stability-flags": { 370 | "monolog/monolog": 20 371 | }, 372 | "prefer-stable": false, 373 | "prefer-lowest": false, 374 | "platform": { 375 | "php": ">=5.3.0" 376 | }, 377 | "platform-dev": [] 378 | } 379 | --------------------------------------------------------------------------------