public function testGetList() { $list = PromisePay::PaymentRestrictions()->getList(); $meta = PromisePay::getMeta(); if ($meta['total'] === 0) { $this->assertEmpty($list); $this->markTestSkipped(); return; } $this->assertTrue(is_array($list)); $this->assertTrue(count($list) <= $meta['limit']); }
public function testListTransactionsIterateAllResults() { $limit = 200; $offset = 0; $batchIds = $meta = null; do { $batches = PromisePay::BatchTransactions()->listTransactions(array('limit' => $limit, 'offset' => $offset)); if ($meta === null) { $meta = PromisePay::getMeta(); } foreach ($batches as $batch) { $batchIds[] = $batch['id']; } $offset += $limit; } while ($meta['total'] > $offset); $this->assertNotNull($batches); $this->assertNotNull($meta); $this->assertTrue(is_array($batches)); $this->assertTrue(is_array($meta)); $this->assertTrue(is_numeric($meta['total'])); $this->assertEquals($meta['total'], count(array_unique($batchIds))); }
/** * Method for performing async requests against PromisePay endpoints. * * In case all requests don't get processed in the same batch, * because the API server has a limit of requests it's willing * to fullfil in a certain amount of time, then this method * will call itself recursively until all requests have been processed, unless: * 1) iterator count exceeds $iteratorMaximum param * 2) not a single new 2xx response is received in the last 2 batches * * @param array $requests A set of requests, in format of [http method, full uri] * @param int $iteratorMaximum Maximum amount of recursive method calls */ public function Client(array $requests, $iteratorMaximum = 1) { $multiHandle = curl_multi_init(); $connections = array(); foreach ($requests as $index => $requestParams) { list($method, $uri) = $requestParams; $connections[$index] = curl_init($uri); if (PromisePay::isDebug()) { fwrite(STDOUT, "#{$index} => {$uri} added." . PHP_EOL); } curl_setopt($connections[$index], CURLOPT_URL, $uri); curl_setopt($connections[$index], CURLOPT_HEADER, true); curl_setopt($connections[$index], CURLOPT_RETURNTRANSFER, true); curl_setopt($connections[$index], CURLOPT_CUSTOMREQUEST, strtoupper($method)); curl_setopt($connections[$index], CURLOPT_USERAGENT, 'promisepay-php-sdk/1.0'); curl_setopt($connections[$index], CURLOPT_USERPWD, sprintf('%s:%s', constant(Functions::getBaseNamespace() . '\\API_LOGIN'), constant(Functions::getBaseNamespace() . '\\API_PASSWORD'))); curl_multi_add_handle($multiHandle, $connections[$index]); } $active = false; do { $multiProcess = curl_multi_exec($multiHandle, $active); } while ($multiProcess === CURLM_CALL_MULTI_PERFORM); while ($active && $multiProcess === CURLM_OK) { if (curl_multi_select($multiHandle) === -1) { // if there's a problem at the moment, delay execution // by 100 miliseconds, as suggested on // https://curl.haxx.se/libcurl/c/curl_multi_fdset.html if (PromisePay::isDebug()) { fwrite(STDOUT, "Pausing for 100 miliseconds." . PHP_EOL); } usleep(100000); } do { $multiProcess = curl_multi_exec($multiHandle, $active); } while ($multiProcess === CURLM_CALL_MULTI_PERFORM); } foreach ($connections as $index => $connection) { $response = curl_multi_getcontent($connection); // we're gonna separate headers and response body $responseHeaders = curl_getinfo($connection); $responseBody = trim(substr($response, $responseHeaders['header_size'])); if (PromisePay::isDebug()) { fwrite(STDOUT, sprintf("#{$index} content: %s" . PHP_EOL, $responseBody)); fwrite(STDOUT, "#{$index} headers: " . print_r($responseHeaders, true) . PHP_EOL); } $jsonArray = json_decode($responseBody, true); if (substr($responseHeaders['http_code'], 0, 1) == '2' && is_array($jsonArray)) { // processed successfully, remove from queue foreach ($requests as $index => $requestParams) { list($method, $url) = $requestParams; if ($url == $responseHeaders['url']) { if (PromisePay::isDebug()) { fwrite(STDOUT, "Unsetting {$index} from requests." . PHP_EOL); } unset($requests[$index]); } } // SCENARIO #1 // Response JSON is self-contained under a master key foreach (PromisePay::$usedResponseIndexes as $responseIndex) { if (isset($jsonArray[$responseIndex])) { $jsonArray = $jsonArray[$responseIndex]; break; } else { unset($responseIndex); } } // SCENARIO #2 // Response JSON is NOT self-contained under a master key if (!isset($responseIndex)) { // for these scenarios, we'll store them under their endpoint name. // for example, requestSessionToken() internally calls getDecodedResponse() // without a key param. $responseIndex = trim(parse_url($responseHeaders['url'], PHP_URL_PATH), '/'); $slashLookup = strpos($responseIndex, '/'); if ($slashLookup !== false) { $responseIndex = substr($responseIndex, 0, $slashLookup); } } } else { if (PromisePay::isDebug()) { fwrite(STDOUT, 'An invalid response was received: ' . PHP_EOL . $responseBody . PHP_EOL); } // handle errors $responseIndex = array_keys($jsonArray); $responseIndex = $responseIndex[0]; } $this->responses[$responseIndex][] = $jsonArray; $this->storageHandler->storeJson($jsonArray); $this->storageHandler->storeMeta(PromisePay::getMeta($jsonArray)); $this->storageHandler->storeLinks(PromisePay::getLinks($jsonArray)); $this->storageHandler->storeDebug($responseHeaders); unset($responseIndex); curl_multi_remove_handle($multiHandle, $connection); } curl_multi_close($multiHandle); $this->pendingRequestsHistoryCounts[] = count($requests); if (PromisePay::isDebug()) { fwrite(STDOUT, sprintf("responses contains %d members." . PHP_EOL, count($this->responses))); } // if a single request hasn't succeeded in the past 2 request batches, // terminate and return result. foreach ($this->pendingRequestsHistoryCounts as $index => $pendingRequestsCount) { if ($index === 0) { continue; } if ($this->pendingRequestsHistoryCounts[$index - 1] == $pendingRequestsCount) { if (PromisePay::isDebug()) { fwrite(STDOUT, 'Server 5xx detected; returning what was obtained thus far.' . PHP_EOL); } return $this->storageHandler; } } $this->iteratorCount++; if (empty($requests) || $this->iteratorCount >= $iteratorMaximum) { return $this->storageHandler; } if (PromisePay::isDebug()) { fwrite(STDOUT, PHP_EOL . '<<STARTING RECURSIVE CALL>>' . PHP_EOL); fwrite(STDOUT, 'REMAINING REQUESTS: ' . print_r($requests, true) . PHP_EOL . 'PROCESSED RESPONSES: ' . print_r($this->responses, true)); } return $this->Client($requests); }
public function testListAllItems() { $itemsList = PromisePay::Item()->getList(array('limit' => 200)); $this->assertNotNull($itemsList); $this->assertTrue(is_array($itemsList)); $meta = PromisePay::getMeta(); if ($meta['total'] < 200) { $this->assertEquals(count($itemsList), $meta['total']); } else { $this->assertEquals(count($itemsList), 200); } }