diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..64c7cfd
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+### Composer template
+composer.phar
+vendor/
+composer.lock
+.idea
+
+# Commit your application's lock file http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file
+# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file
+# composer.lock
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..28d2c41
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 Alejandro Labrada Diaz
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..346b72f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,5 @@
+# Soap Client using Curl [![version][packagist-version]][packagist-url]
+
+[![Downloads][packagist-downloads]][packagist-url]
+[![Dependencies][versioneye-image]][versioneye-url]
+[![License][packagist-license]][license-url]
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..c740caa
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,27 @@
+{
+ "name": "aleplusplus/soapclient-curl-php",
+ "description": "Soap Client using Curl",
+ "keywords": ["soap", "curl", "non-wsdl", "client", "sri"],
+ "type": "library",
+ "require": {
+ "php": ">=5.4.0",
+ "ext-curl": "*",
+ "ext-json": "*"
+ },
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Alejandro Labrada Diaz",
+ "email": "aleplusplus@gmail.com"
+ }
+ ],
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-0": {
+ "SoapClientCurl": "src"
+ }
+ },
+ "support": {
+ "email": "aleplusplus@gmail.com"
+ }
+}
diff --git a/src/SoapClientCurl.php b/src/SoapClientCurl.php
new file mode 100644
index 0000000..03a0d42
--- /dev/null
+++ b/src/SoapClientCurl.php
@@ -0,0 +1,4 @@
+ '',
+ 'pass' => '',
+ 'method' => CURLAUTH_BASIC
+ );
+ private static $proxy = array(
+ 'port' => false,
+ 'tunnel' => false,
+ 'address' => false,
+ 'type' => CURLPROXY_HTTP,
+ 'auth' => array (
+ 'user' => '',
+ 'pass' => '',
+ 'method' => CURLAUTH_BASIC
+ )
+ );
+
+ /**
+ * Send a cURL request
+ * @param string $url URL to send the request to
+ * @param mixed $body request body
+ * @param array $headers additional headers to send
+ * @param string $username Authentication username (deprecated)
+ * @param string $password Authentication password (deprecated)
+ * @return SoapClientResponse
+ * @throws \Exception if a cURL error occurs
+ */
+ public static function send($url, $headers = array(), $body = null, $username = null, $password = null)
+ {
+ self::$handle = curl_init();
+
+ curl_setopt_array(self::$handle, array(
+ CURLOPT_URL => self::encodeUrl($url),
+ CURLOPT_POSTFIELDS => $body,
+ CURLOPT_HTTPHEADER => self::getFormattedHeaders($headers),
+ CURLOPT_CONNECTTIMEOUT => 10,
+ CURLOPT_TIMEOUT => 10,
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_SSL_VERIFYPEER => false,
+ CURLOPT_SSL_VERIFYHOST => false,
+ CURLOPT_POST => true,
+ CURLOPT_VERBOSE => true,
+ CURLOPT_HEADER => true
+ ));
+ if (self::$socketTimeout !== null) {
+ curl_setopt(self::$handle, CURLOPT_TIMEOUT, self::$socketTimeout);
+ }
+ // supporting deprecated http auth method
+ if (!empty($username)) {
+ curl_setopt_array(self::$handle, array(
+ CURLOPT_HTTPAUTH => CURLAUTH_BASIC,
+ CURLOPT_USERPWD => $username . ':' . $password
+ ));
+ }
+ if (!empty(self::$auth['user'])) {
+ curl_setopt_array(self::$handle, array(
+ CURLOPT_HTTPAUTH => self::$auth['method'],
+ CURLOPT_USERPWD => self::$auth['user'] . ':' . self::$auth['pass']
+ ));
+ }
+ if (self::$proxy['address'] !== false) {
+ curl_setopt_array(self::$handle, array(
+ CURLOPT_PROXYTYPE => self::$proxy['type'],
+ CURLOPT_PROXY => self::$proxy['address'],
+ CURLOPT_PROXYPORT => self::$proxy['port'],
+ CURLOPT_HTTPPROXYTUNNEL => self::$proxy['tunnel'],
+ CURLOPT_PROXYAUTH => self::$proxy['auth']['method'],
+ CURLOPT_PROXYUSERPWD => self::$proxy['auth']['user'] . ':' . self::$proxy['auth']['pass']
+ ));
+ }
+ $response = curl_exec(self::$handle);
+ $error = curl_error(self::$handle);
+ $info = self::getInfo();
+ if ($error) {
+ throw new \Exception($error);
+ }
+ // Split the full response in its headers and body
+ $header_size = $info['header_size'];
+ $header = substr($response, 0, $header_size);
+ $body = substr($response, $header_size);
+
+ return new SoapClientResponse($info, $header, $body);
+ }
+
+ public static function getInfo()
+ {
+ return curl_getinfo(self::$handle);
+ }
+ public static function getCurlHandle()
+ {
+ return self::$handle;
+ }
+ public static function getFormattedHeaders($headers)
+ {
+ $formattedHeaders = array();
+ $combinedHeaders = array_change_key_case(array_merge((array) $headers, self::$defaultHeaders));
+ foreach ($combinedHeaders as $key => $val) {
+ $formattedHeaders[] = $val;
+ }
+ if (!array_key_exists('user-agent', $combinedHeaders)) {
+ $formattedHeaders[] = 'user-agent: soapclient-request/1.0';
+ }
+ if (!array_key_exists('expect', $combinedHeaders)) {
+ $formattedHeaders[] = 'expect:';
+ }
+ return $formattedHeaders;
+ }
+ private static function getArrayFromQuerystring($query)
+ {
+ $query = preg_replace_callback('/(?:^|(?<=&))[^=[]+/', function ($match) {
+ return bin2hex(urldecode($match[0]));
+ }, $query);
+ parse_str($query, $values);
+ return array_combine(array_map('hex2bin', array_keys($values)), $values);
+ }
+
+ /**
+ * Ensure that a URL is encoded and safe to use with cURL
+ * @param string $url URL to encode
+ * @return string
+ */
+ private static function encodeUrl($url)
+ {
+ $url_parsed = parse_url($url);
+ $scheme = $url_parsed['scheme'] . '://';
+ $host = $url_parsed['host'];
+ $port = (isset($url_parsed['port']) ? $url_parsed['port'] : null);
+ $path = (isset($url_parsed['path']) ? $url_parsed['path'] : null);
+ $query = (isset($url_parsed['query']) ? $url_parsed['query'] : null);
+ if ($query !== null) {
+ $query = '?' . http_build_query(self::getArrayFromQuerystring($query));
+ }
+ if ($port && $port[0] !== ':') {
+ $port = ':' . $port;
+ }
+ $result = $scheme . $host . $port . $path . $query;
+ return $result;
+ }
+}
diff --git a/src/SoapClientCurl/SoapClientResponse.php b/src/SoapClientCurl/SoapClientResponse.php
new file mode 100644
index 0000000..4da675a
--- /dev/null
+++ b/src/SoapClientCurl/SoapClientResponse.php
@@ -0,0 +1,59 @@
+info = $info;
+ $this->headers = $this->parseHeaders($headers);
+ $this->body = $raw_body;
+ }
+
+ /**
+ * if PECL_HTTP is not available use a fall back function
+ *
+ * thanks to ricardovermeltfoort@gmail.com
+ * http://php.net/manual/en/function.http-parse-headers.php#112986
+ */
+ private function parseHeaders($raw_headers)
+ {
+ if (function_exists('http_parse_headers')) {
+ return http_parse_headers($raw_headers);
+ } else {
+ $key = '';
+ $headers = array();
+ foreach (explode("\n", $raw_headers) as $i => $h) {
+ $h = explode(':', $h, 2);
+ if (isset($h[1])) {
+ if (!isset($headers[$h[0]])) {
+ $headers[$h[0]] = trim($h[1]);
+ } elseif (is_array($headers[$h[0]])) {
+ $headers[$h[0]] = array_merge($headers[$h[0]], array(trim($h[1])));
+ } else {
+ $headers[$h[0]] = array_merge(array($headers[$h[0]]), array(trim($h[1])));
+ }
+ $key = $h[0];
+ } else {
+ if (substr($h[0], 0, 1) == "\t") {
+ $headers[$key] .= "\r\n\t" . trim($h[0]);
+ } elseif (!$key) {
+ $headers[0] = trim($h[0]);
+ }
+ }
+ }
+ return $headers;
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/SoapClientRequestTest.php b/tests/SoapClientRequestTest.php
new file mode 100644
index 0000000..d7626b0
--- /dev/null
+++ b/tests/SoapClientRequestTest.php
@@ -0,0 +1,29 @@
+
+
+
+
+
+ '.$claveAccesoComprobante.'
+
+
+ ';
+
+// Cabacera de la peticion
+$headers = array('Content-Type: text/xml; charset=utf-8', 'Content-Length: '.strlen($body));
+
+$result = SoapClientRequest::send($url,$headers, $body);
+
+var_dump($result);
\ No newline at end of file