1: <?php
  2: 
  3:   4:   5:   6:   7: 
  8: class Syspay_Merchant_Client
  9: {
 10:     const BASE_URL_PROD    = 'https://app.syspay.com';
 11:     const BASE_URL_SANDBOX = 'https://app-sandbox.syspay.com';
 12: 
 13:     protected $username;
 14:     protected $secret;
 15:     protected $baseUrl;
 16: 
 17:     protected $responseBody    = null;
 18:     protected  = array();
 19:     protected $responseData    = null;
 20: 
 21:     protected $requestBody     = null;
 22:     protected   = array();
 23:     protected $requestParams   = null;
 24: 
 25:     protected $requestId       = null;
 26: 
 27:      28:  29:  30:  31:  32: 
 33:     public function __construct($username, $secret, $baseUrl = null)
 34:     {
 35:         $this->username = $username;
 36:         $this->secret   = $secret;
 37:         $this->baseUrl  = (null === $baseUrl)?self::BASE_URL_PROD:$baseUrl;
 38:     }
 39: 
 40:      41:  42:  43:  44:  45:  46:  47:  48:  49: 
 50:     protected function ($username, $secret, $nonce = null, DateTime $created = null)
 51:     {
 52:         if (null === $nonce) {
 53:             $nonce = md5(rand(), true);
 54:         }
 55: 
 56:         if (null === $created) {
 57:             $created = new DateTime();
 58:         }
 59: 
 60:         $created = $created->format('U');
 61: 
 62:         $digest = base64_encode(sha1($nonce . $created . $secret, true));
 63:         $b64nonce = base64_encode($nonce);
 64: 
 65:         return sprintf(
 66:             'AuthToken MerchantAPILogin="%s", PasswordDigest="%s", Nonce="%s", Created="%s"',
 67:             $username,
 68:             $digest,
 69:             $b64nonce,
 70:             $created
 71:         );
 72:     }
 73: 
 74:      75:  76:  77:  78:  79:  80: 
 81:     public function request(Syspay_Merchant_Request $request)
 82:     {
 83:         $this->requestBody = $this->responseBody = $this->responseData = $this->requestId = null;
 84:         $this->responseHeaders = $this->requestHeaders = array();
 85: 
 86:         $headers = array(
 87:             'Accept: application/json',
 88:             'X-Wsse: ' . $this->generateAuthHeader($this->username, $this->secret)
 89:         );
 90: 
 91: 
 92:         $url = rtrim($this->baseUrl, '/') . '/' . ltrim($request->getPath(), '/');
 93: 
 94:         $ch = curl_init();
 95:         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 96:         curl_setopt($ch, CURLOPT_HEADER, true);
 97:         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
 98:         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
 99: 
100:         $method = strtoupper($request->getMethod());
101: 
102:         
103:         switch($method) {
104:             case 'PUT':
105:             case 'POST':
106:                 $body = json_encode($request->getData());
107: 
108:                 array_push($headers, 'Content-Type: application/json');
109:                 array_push($headers, 'Content-Length: ' . strlen($body));
110: 
111:                 curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
112:                 $this->requestBody = $body;
113:                 break;
114: 
115:             case 'GET':
116:                 $queryParams = $request->getData();
117:                 if (is_array($queryParams)) {
118:                     $url .= '?' . http_build_query($queryParams);
119:                 }
120:                 $this->requestParams = $queryParams;
121:                 break;
122: 
123:             case 'DELETE':
124:                 break;
125: 
126:             default:
127:                 throw new Exception('Unsupported method given: ' . $method);
128:         }
129: 
130:         curl_setopt($ch, CURLOPT_URL, $url);
131:         curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
132:         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
133:         $this->requestHeaders = $headers;
134: 
135:         $response = curl_exec($ch);
136:         if ($response === false) {
137:             throw new Exception(curl_error($ch), curl_errno($ch));
138:         }
139:         $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
140:         list($headers, $body) = explode("\r\n\r\n", $response, 2);
141:         $this->responseHeaders = explode("\r\n", $headers);
142:         $this->responseBody    = $body;
143:         if (preg_match('/\nx-syspay-request-uuid: (.*?)\r?\n/i', $headers, $m)) {
144:             $this->requestId = $m[1];
145:         }
146: 
147:         if (!in_array($httpCode, array(200, 201))) {
148:             throw new Syspay_Merchant_RequestException($httpCode, $headers, $body);
149:         }
150: 
151:         $decoded = json_decode($body);
152: 
153:         if (($decoded instanceof stdClass) && isset($decoded->data) && ($decoded->data instanceof stdClass)) {
154:             $this->responseData = $decoded->data;
155: 
156:             return $request->buildResponse($decoded->data);
157:         } else {
158:             throw new Syspay_Merchant_UnexpectedResponseException('Unable to decode response from json', $body);
159:         }
160: 
161:         return false;
162:     }
163: 
164:     165: 166: 167: 
168:     public function getResponseBody()
169:     {
170:         return $this->responseBody;
171:     }
172: 
173:     174: 175: 176: 
177:     public function ()
178:     {
179:         return $this->responseHeaders;
180:     }
181: 
182:     183: 184: 185: 
186:     public function getUsername()
187:     {
188:         return $this->username;
189:     }
190: 
191:     192: 193: 194: 
195:     public function getSecret()
196:     {
197:         return $this->secret;
198:     }
199: 
200:     201: 202: 203: 
204:     public function getBaseUrl()
205:     {
206:         return $this->baseUrl;
207:     }
208: 
209:     210: 211: 212: 
213:     public function getResponseData()
214:     {
215:         return $this->responseData;
216:     }
217: 
218:     219: 220: 221: 
222:     public function ()
223:     {
224:         return $this->requestHeaders;
225:     }
226: 
227:     228: 229: 230: 
231:     public function getRequestBody()
232:     {
233:         return $this->requestBody;
234:     }
235: 
236:     237: 238: 239: 
240:     public function getRequestParams()
241:     {
242:         return $this->requestParams;
243:     }
244: 
245:     246: 247: 248: 
249:     public function getRequestId()
250:     {
251:         return $this->requestId;
252:     }
253: }
254: