diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..adbc151 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# This file is for unifying the coding style for different editors and IDEs +# editorconfig.org + +# PHP PSR-2 Coding Standards +# http://www.php-fig.org/psr/psr-2/ + +root = true + +[*.php] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 4 \ No newline at end of file diff --git a/README.md b/README.md index c22dcc0..65425e2 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ require_once("/path/to/Finix/Bootstrap.php"); ```php require(__DIR__ . '/src/Finix/Settings.php'); -Finix\Settings::configure('http://b.papi.staging.finix.io', '$USERNAME', '$PASSWORD'); +Finix\Settings::configure('https://api-staging.finix.io/', '$USERNAME', '$PASSWORD'); require(__DIR__ . '/src/Finix/Bootstrap.php'); \Finix\Bootstrap::init(); ``` diff --git a/bootstrap.php b/bootstrap.php index 3dcad25..cdc5242 100644 --- a/bootstrap.php +++ b/bootstrap.php @@ -1,17 +1,15 @@ Fixtures::$apiUrl +]); -Bootstrap::init(); \ No newline at end of file +Bootstrap::init(); diff --git a/circle.yml b/circle.yml index f374688..8d224ed 100644 --- a/circle.yml +++ b/circle.yml @@ -14,4 +14,5 @@ dependencies: test: override: - mkdir -p $CIRCLE_TEST_REPORTS/phpunit - - ./vendor/bin/phpunit --log-junit $CIRCLE_TEST_REPORTS/phpunit/junit.xml \ No newline at end of file + - ./vendor/bin/phpunit --log-junit $CIRCLE_TEST_REPORTS/phpunit/junit.xml: + timeout: 1200 \ No newline at end of file diff --git a/composer.json b/composer.json index e818647..0b57a59 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "finix/processing-php", - "version": "1.0.1", + "version": "1.0.2", "description": "A PHP HTTP Client conforming to the HAL hypermedia type for the Finix processing API", "license": "Apache2", "authors": [ diff --git a/src/Finix/Bootstrap.php b/src/Finix/Bootstrap.php index ae6dd1a..076e22d 100644 --- a/src/Finix/Bootstrap.php +++ b/src/Finix/Bootstrap.php @@ -53,11 +53,13 @@ private static function _autoload($base, $classname) */ private static function initializeResources() { - if (self::$initialized) + if (self::$initialized) { return; + } Resource::init(); + Resources\User::init(); Resources\Application::init(); Resources\Identity::init(); Resources\Processor::init(); diff --git a/src/Finix/Http/Auth/BasicAuthentication.php b/src/Finix/Http/Auth/BasicAuthentication.php index 4e5cc9f..8cbf20e 100644 --- a/src/Finix/Http/Auth/BasicAuthentication.php +++ b/src/Finix/Http/Auth/BasicAuthentication.php @@ -3,6 +3,7 @@ namespace Finix\Http\Auth; use Finix\Http; +use Finix\Settings; use Finix\Http\AbstractClient; use GuzzleHttp\Message\RequestInterface; @@ -86,7 +87,8 @@ private function isRequestAuthorized(RequestInterface $httpRequest) */ private function getCredentials() { - $basic = base64_encode($this->user_id . ':' . $this->password); + $basic = base64_encode(Settings::$username . ':' . Settings::$password); +// $basic = base64_encode($this->user_id . ':' . $this->password); return $basic; } } diff --git a/src/Finix/Resource.php b/src/Finix/Resource.php index 16ee27d..221dcc9 100644 --- a/src/Finix/Resource.php +++ b/src/Finix/Resource.php @@ -4,6 +4,7 @@ use Finix\Http\Auth\BasicAuthentication; use Finix\Http\JsonBody; use Finix\Http\Request; +use Finix\Resources\Verification; use Finix\Utils\ArrayProxy; use \stdClass; @@ -15,7 +16,8 @@ abstract class Resource protected $state; protected static $href; - protected static $client; + protected $client; +// protected static $client; protected static $registry; /** @@ -24,10 +26,10 @@ abstract class Resource */ public static function getHrefSpec($resource = null) { - if(is_null($resource)){ + if (is_null($resource)) { $resource = get_called_class(); } - if(!is_string($resource)) { + if (!is_string($resource)) { $resource = get_class($resource); } return self::getRegistry()->getHrefSpecForResource($resource); @@ -36,9 +38,9 @@ public static function getHrefSpec($resource = null) /** * @return Hal\Client */ - public static function getClient() + public function getClient() { - return self::$client; + return $this->client; } /** @@ -51,23 +53,33 @@ public static function getRegistry() public static function init() { - self::$client = new Hal\Client( - Settings::$url_root, - '/', - null, - new BasicAuthentication(Settings::$username, Settings::$password)); self::$registry = new Registry(); } public function __construct(array $state = null, array $links = null) { + $this->client = self::createClient(); $this->setResource(new Hal\Resource($state, $links)); } + private static function createClient() + { + if (Settings::$username == null || Settings::$password == null) { + $client = new Hal\Client(Settings::$url_root, '/'); + } + else { + $client = new Hal\Client( + Settings::$url_root, + '/', + null, + new BasicAuthentication(Settings::$username, Settings::$password)); + } + return $client; + } + public function __get($name) { - if($this->state->has_key($name)) - { + if ($this->state->has_key($name)) { return $this->state[$name]; } @@ -92,8 +104,8 @@ public function __set($name, $value) public function __isset($name) { if (array_key_exists($name, $this->resource->getAllLinks()) || - array_key_exists($name, $this->resource->getState())) - { + array_key_exists($name, $this->resource->getState()) + ) { return true; } @@ -111,11 +123,21 @@ public function __isset($name) public static function retrieve($id) { $uri = self::getHrefSpec()->collection_uri . '/' . $id; - $resource = self::getClient()->sendRequest(new Request($uri)); + $resource = self::createClient()->sendRequest(new Request($uri)); $class = get_called_class(); return new $class($resource->getState(), $resource->getAllLinks()); } + public function refresh() { + $request = new Request( + $this->resource->getLink("self")->getHref(), + 'GET' + ); + $resource = $this->getClient()->sendRequest($request); + $this->setResource($resource); + return $this; + } + /** * @return \Finix\Resource * @throws Hal\Exception\HalClientErrorException @@ -128,12 +150,11 @@ public static function retrieve($id) public function save() { if (empty($this->state["tags"])) { - $this->state["tags"] = new stdClass(); + $this->state["tags"] = new stdClass(); } $payload = new JsonBody(iterator_to_array($this->state)); - if($this->isUpdate()) - { + if ($this->isUpdate()) { $request = new Request( $this->resource->getLink("self")->getHref(), 'PUT', @@ -199,5 +220,9 @@ private function setResource($resource) $this->state = new ArrayProxy($resource->getState()); } - -} \ No newline at end of file + public function verifyOn(Verification $verification) + { + $verifyLink = $this->resource->getLink("verifications")->getHref(); + return $verification->create($verifyLink); + } +} diff --git a/src/Finix/Resources/Application.php b/src/Finix/Resources/Application.php index 7a021e3..7158c01 100644 --- a/src/Finix/Resources/Application.php +++ b/src/Finix/Resources/Application.php @@ -11,4 +11,13 @@ public static function init() self::getRegistry()->add(get_called_class(), new HrefSpec('applications', 'id', '/')); } -} \ No newline at end of file + public function createPartnerUser(User $user) + { + return $user->create($this->resource->getLink("users")->getHref()); + } + + public function createProcessor(Processor $processor) + { + return $processor->create($this->resource->getLink("processors")->getHref()); + } +} diff --git a/src/Finix/Resources/Authorization.php b/src/Finix/Resources/Authorization.php index 4598877..ea29b91 100644 --- a/src/Finix/Resources/Authorization.php +++ b/src/Finix/Resources/Authorization.php @@ -11,4 +11,16 @@ public static function init() self::getRegistry()->add(get_called_class(), new HrefSpec('authorizations', 'id', '/')); } -} \ No newline at end of file + public function capture($amount, $fee = 0) + { + $this->state["capture_amount"] = $amount; + $this->state["fee"] = $fee; + return $this->save(); + } + + public function void($voidMe) + { + $this->state["void_me"] = $voidMe; + return $this->save(); + } +} diff --git a/src/Finix/Resources/BankAccount.php b/src/Finix/Resources/BankAccount.php new file mode 100644 index 0000000..84cdc0a --- /dev/null +++ b/src/Finix/Resources/BankAccount.php @@ -0,0 +1,13 @@ +add(get_called_class(), new HrefSpec('identities', 'id', '/')); } - /** - * @param string $processor the processor to underwrite the merchant on - * @return \Finix\Resources\Merchant - * @throws \Finix\Hal\Exception\LinkNotUniqueException - * @throws \Finix\Hal\Exception\RelNotFoundException - */ - public function provisionMerchantOn(array $args) + public function provisionMerchantOn(Merchant $merchant) { - $merchant = new Merchant(["processor"=>$args['processor']]); - return $merchant->create($this->resource->getLink("underwriting")->getHref()); + return $merchant->create($this->resource->getLink("merchants")->getHref()); } + public function createSettlement(Settlement $settlement) + { + return $settlement->create($this->resource->getLink("settlements")->getHref()); + } - /** - * @param string $processor the processor to settle the funds out to - * @param string $currency the currency for the settlment - * @return \Finix\Resources\Settlement - * @throws \Finix\Hal\Exception\LinkNotUniqueException - * @throws \Finix\Hal\Exception\RelNotFoundException - */ - public function createSettlement(array $args) + public function createPaymentCard(PaymentCard $card) { - // TODO passing identity field by default bc it's redudant, users shouldn't need to pass this. remove once bug is fixed - $settlement = new Settlement(["processor"=>$args['processor'], "currency"=>$args['currency'], "identity"=>$this->resource->getState()["id"]]); - // TODO shouldn't this link should not be construcuted, update when identity resource is fixed - return $settlement->create($this->resource->getLink("self")->getHref() . "/settlements"); + $card->state["identity"] = $this->id; + return $card->create($this->resource->getLink("payment_instruments")->getHref()); } - /** - * @param string $processor the processor to settle the funds out to - * @param string $currency the currency for the settlment - * @return \Finix\Resources\Settlement - * @throws \Finix\Hal\Exception\LinkNotUniqueException - * @throws \Finix\Hal\Exception\RelNotFoundException - */ - public function verifyOn(array $args) + public function createBankAccount(BankAccount $bankAccount) { - $verification = new Verification(["processor"=>$args['processor']]); - // TODO shouldn't this link should not be construcuted, update when identity resource is fixed - return $verification->create($this->resource->getLink("verifications")->getHref()); + $bankAccount->state["identity"] = $this->id; + return $bankAccount->create($this->resource->getLink("payment_instruments")->getHref()); } -} \ No newline at end of file +} diff --git a/src/Finix/Resources/Merchant.php b/src/Finix/Resources/Merchant.php index 7271874..f7fc928 100644 --- a/src/Finix/Resources/Merchant.php +++ b/src/Finix/Resources/Merchant.php @@ -6,11 +6,9 @@ class Merchant extends Resource { + public static function init() { - self::getRegistry()->add( - get_called_class(), - new HrefSpec('merchants', 'id', '/')); + self::getRegistry()->add(get_called_class(), new HrefSpec('merchants', 'id', '/')); } - -} \ No newline at end of file +} diff --git a/src/Finix/Resources/PaymentCard.php b/src/Finix/Resources/PaymentCard.php new file mode 100644 index 0000000..ee95e9c --- /dev/null +++ b/src/Finix/Resources/PaymentCard.php @@ -0,0 +1,14 @@ +add(get_called_class(), new HrefSpec('payment_instruments', 'id', '/')); } -} \ No newline at end of file +} diff --git a/src/Finix/Resources/Transfer.php b/src/Finix/Resources/Transfer.php index df28873..15ce249 100644 --- a/src/Finix/Resources/Transfer.php +++ b/src/Finix/Resources/Transfer.php @@ -19,8 +19,7 @@ public static function init() */ public function reverse($amount) { - // TODO shouldn't this field be named: "reverse_amount" or "amount_to_reverse" $reversal = new Reversal(["refund_amount"=>$amount]); return $reversal->create($this->resource->getLink("reversals")->getHref()); } -} \ No newline at end of file +} diff --git a/src/Finix/Resources/User.php b/src/Finix/Resources/User.php new file mode 100644 index 0000000..287549e --- /dev/null +++ b/src/Finix/Resources/User.php @@ -0,0 +1,19 @@ +add(get_called_class(), new HrefSpec('users', 'id', '/')); + } + + public function createApplication(Application $application) + { + return $application->create($this->resource->getLink("applications")->getHref()); + } +} diff --git a/src/Finix/Settings.php b/src/Finix/Settings.php index be45a38..d6fc66e 100644 --- a/src/Finix/Settings.php +++ b/src/Finix/Settings.php @@ -2,6 +2,8 @@ namespace Finix; +use Finix\Resource; + /** * Configurable settings. * @@ -24,26 +26,27 @@ */ class Settings { - const VERSION = '1.0.0'; - - public static $url_root = 'https://api-staging.finix.io/', + public static $url_root = null, $username = null, $password = null, $agent = 'finix-php', - $version = Settings::VERSION, $accept = 'application/vnd.json+api'; - /** - * Configure all settings. - * - * @param string $url_root The root (schema://hostname[:port]) to use when constructing api URLs. - * @param string $username The username to identify the client - * @param string $password The api key secret to use for authenticating when talking to the api. If null then api usage is limited to unauthenticated endpoints. - */ - public static function configure($url_root, $username, $password) + public static function configure(array $args) { - self::$url_root= $url_root; - self::$username= $username; - self::$password = $password; + if (array_key_exists("root_url", $args)) + { + self::$url_root = $args["root_url"]; + } + + if (array_key_exists("username", $args)) + { + self::$username = $args["username"]; + } + + if (array_key_exists("password", $args)) + { + self::$password = $args["password"]; + } } -} \ No newline at end of file +} diff --git a/tests/Finix/ClientTest.php b/tests/Finix/ClientTest.php deleted file mode 100644 index 76046ef..0000000 --- a/tests/Finix/ClientTest.php +++ /dev/null @@ -1,24 +0,0 @@ -client = new Client( - SampleData::$apiUrl, - '/', - SampleData::$apiUrl, - new Auth\BasicAuthentication(SampleData::$username, SampleData::$password) - ); - } - - public function test_clientCommunicatesToAPI() { - $this->assertNotNull($this->client->getEntryPointResource()); - } - -} diff --git a/tests/Finix/Fixtures.php b/tests/Finix/Fixtures.php new file mode 100644 index 0000000..51a07b7 --- /dev/null +++ b/tests/Finix/Fixtures.php @@ -0,0 +1,224 @@ + true]); + $user = $user->save(); + self::assertNotEmpty($user->id); + self::assertNotEmpty($user->password); + self::assertTrue($user->enabled); + self::assertEquals($user->role, "ROLE_ADMIN"); + return $user; + } + + public static function createPartnerUser($application) + { + $user = $application->createPartnerUser(new User(["enabled" => true])); + self::assertNotEmpty($user->id); + self::assertNotEmpty($user->password); + self::assertTrue($user->enabled); + self::assertEquals($user->role, "ROLE_PARTNER"); + return $user; + } + + public static function createApplication(User $user) + { + $application = new Application([ + "entity" => self::sampleEntity() + ]); + $application = $user->createApplication($application); + self::assertNotEmpty($application->id); + return $application; + } + + public static function sampleEntity() + { + return [ + "max_transaction_amount" => 1, + "settlement_currency" => "USD", + "settlement_bank_account" => "CORPORATE", + "url" => "http://sample.company.com", + "annual_card_volume" => 100, + "default_statement_descriptor" => "sample", + "incorporation_date" => ["day" => date("d"), "month" => date("m"), "year" => date("Y") - 1], + "mcc" => 7399, + "principal_percentage_ownership" => 10, + "business_type" => "LIMITED_LIABILITY_COMPANY", + "business_phone" => "+1 (408) 756-4497", + "first_name" => "xdwayne", + "last_name" => "Sunkhronos", + "dob" => [ + "month" => 5, + "day" => 27, + "year" => 1978 + ], + "business_address" => [ + "line1" => "741 Douglass St", + "line2" => "Apartment 7", + "city" => "San Mateo", + "region" => "CA", + "postal_code" => "94114", + "country" => "USA" + ], + "doing_business_as" => "xdoingBusinessAs", + "phone" => "1234567890", + "personal_address" => [ + "line1" => "741 Douglass St", + "line2" => "Apartment 7", + "city" => "San Mateo", + "region" => "CA", + "postal_code" => "94114", + "country" => "USA" + ], + "business_name" => "business inc 2", + "business_tax_id" => "x123456789", + "email" => "xuser@example.org", + "tax_id" => "x123456789" + ]; + } + + public static function dummyProcessor($application) + { + $processor = new Processor([ + "name" => "DUMMY_V1", + "type" => "DUMMY_V1", + "config" => ["key1" => "value-1", "key2" => "value-2"] + ]); + $processor = $application->createProcessor($processor); + self::assertTrue($processor->enabled); + return $processor; + } + + public static function createIdentity() + { + $identity = new Identity(["entity" => self::sampleEntity()]); + $identity = $identity->save(); + self::assertNotEmpty($identity->id); + return $identity; + } + + public static function provisionMerchant($identity) + { + $merchant = $identity->provisionMerchantOn(new Merchant(["processor" => "DUMMY_V1"])); + self::assertEquals($merchant->identity, $identity->id, "Invalid merchant identity"); + return $merchant; + } + + public static function createCard($identity) + { + $card = $identity->createPaymentCard(new PaymentCard([ + "name" => "Joe Doe", + "expiration_month" => 12, + "expiration_year" => 2030, + "number" => "4111 1111 1111 1111", + "security_code" => 231 + ])); + self::assertEquals($card->identity, $identity->id, "Invalid card identity"); + return $card; + } + + public static function waitFor($condition) + { + $time = 5; + $timeout = 60 * 20; // 20 mins + while (!$condition()) { + $timeout -= $time; + if ($timeout <= 0) { + throw new \Exception("Execution timeout expired"); + } + print "waiting for " . $time . " seconds\n"; + sleep($time); + } + } + + public static function createTransfer(array $args = []) + { + $transfer = new Transfer([ + "merchant_identity" => $args["identity"], + "currency" => "USD", + "amount" => $args["amount"], + "tags" => ["_source" => "php_client"], + "processor" => "DUMMY_V1" + ]); + + if (array_key_exists('destination', $args)) { + $transfer->destination = $args["destination"]; + } + + if (array_key_exists('source', $args)) { + $transfer->source = $args["source"]; + } + + $transfer = $transfer->save(); + self::assertEquals($transfer->state, "PENDING", "Transfer not created successful"); + return $transfer; + } + + public static function createBankAccount($identity) + { + $bankAccount = $identity->createBankAccount(new BankAccount([ + "name" => "Joe Doe", + "account_number" => "84012312415", + "bank_code" => "840123124", + "account_type" => "SAVINGS", + "company_name" => "sample company", + "country" => "USA", + "currency" => "USD" + ])); + self::assertEquals($bankAccount->identity, $identity->id, "Invalid card identity"); + return $bankAccount; + } + + public static function createWebhook($url) + { + $webhook = new Webhook(["url" => $url]); + $webhook = $webhook->save(); + self::assertTrue($webhook->enabled, "Webhook for url='" . $url . " not enabled"); + return $webhook; + } + + public static function createAuthorization($paymentInstrument, $amount) + { + $authorization = new Authorization([ + "amount" => $amount, + "currency" => "USD", + "processor" => "DUMMY_V1", + "source" => $paymentInstrument->id, + "merchant_identity" => $paymentInstrument->identity + ]); + $authorization = $authorization->save(); + self::assertEquals($authorization->state, "SUCCEEDED", "Authorization of '" . $paymentInstrument->id . "' not succeeded"); + return $authorization; + } + + public static function createSettlement($identity) + { + $settlement = new Settlement([ + "processor" => "DUMMY_V1", + "currency" => "USD" + ]); + $settlement = $identity->createSettlement($settlement); + self::assertNotNull($settlement->id, "Settlement not created"); + return $settlement; + } +} diff --git a/tests/Finix/ResourceTest.php b/tests/Finix/ResourceTest.php index a64a79f..eb78f12 100644 --- a/tests/Finix/ResourceTest.php +++ b/tests/Finix/ResourceTest.php @@ -54,7 +54,7 @@ class ResourceTest extends \PHPUnit_Framework_TestCase { * - embedded resources * - links in embedded resources */ - public function test_parseJsonRepresentation() { + public function testParseJsonRepresentation() { $resource = Resource::fromJson(self::JSON_REPRESENTATION); @@ -94,7 +94,7 @@ public function test_parseJsonRepresentation() { $this->assertEquals(0, count($order1->getAllEmbeddedResources())); } - public function test_equalResources() { + public function testEqualResources() { $resource1 = Resource::fromJson(self::JSON_REPRESENTATION); $resource2 = Resource::fromJson(self::JSON_REPRESENTATION); diff --git a/tests/Finix/Resources/AuthorizationTest.php b/tests/Finix/Resources/AuthorizationTest.php deleted file mode 100644 index 1ebe42a..0000000 --- a/tests/Finix/Resources/AuthorizationTest.php +++ /dev/null @@ -1,84 +0,0 @@ -id; - $card = new PaymentInstrument($card); - $card->save(); - self::$card = $card; - - } - - public function setUp() { - $this->auth = json_decode(self::AUTHORIZATION_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - } - - private function fillAuthorization($auth) - { - $auth['merchant_identity'] = self::$identity->id; - $auth['source'] = self::$card->id; - return $auth; - } - - public function test_createAuthorization() { - $auth_state = $this->fillAuthorization($this->auth); - $auth = new Authorization($auth_state); - $auth->save(); - $this->assertStringStartsWith('AU', $auth->id); - $this->assertEquals($auth->state, 'SUCCEEDED'); - } - - public function test_updateAuthorization() { - $auth_state = $this->fillAuthorization($this->auth); - $auth = new Authorization($auth_state); - $auth->save(); - $old_id = $auth->id; - $auth->capture_amount = 50; - $auth->save(); - $this->assertEquals($old_id, $auth->id); - $this->assertEquals($auth->state, 'SUCCEEDED'); - $this->assertNotNull($auth->transfer); - } -} diff --git a/tests/Finix/Resources/DisputeTest.php b/tests/Finix/Resources/DisputeTest.php deleted file mode 100644 index 6741102..0000000 --- a/tests/Finix/Resources/DisputeTest.php +++ /dev/null @@ -1,91 +0,0 @@ -id; - $card = new PaymentInstrument($card); - $card->save(); - self::$card = $card; - } - - public function setUp() { - $this->receiptImage = realpath("../../data/receipt.jpg"); - $this->transfer = json_decode(self::TRANSFER_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - } - - private function fillSourceTransfer($transfer) - { - $transfer['identity'] = self::$identity->id; - $transfer['source'] = self::$card->id; - return $transfer; - } - - public function disputedTransferCreateFromPaymentCard() { - $transfer_state = $this->fillSourceTransfer($this->transfer); - $transfer = new Transfer($transfer_state); - $transfer->save(); - $this->assertStringStartsWith('TR', $transfer->id); - $this->assertEquals($transfer->state, 'PENDING'); // transfers are async - } - - public function test_disputeRetrieve() { - $dispute = Dispute::retrieve(SampleData::$disputeId); - $this->assertEquals(SampleData::$disputeId, $dispute->id); -// $this->assertEquals($dispute->reason, "FRAUD"); - } - - public function test_uploadDispute() { - $dispute = Dispute::retrieve(SampleData::$disputeId); - /** @var Dispute $dispute */ - $file = $dispute->uploadEvidence($this->receiptImage); - $this->assertStringStartsWith("DF", $file->id); - $this->assertEquals($file->dispute, $dispute->id); - } - -} diff --git a/tests/Finix/Resources/IdentityTest.php b/tests/Finix/Resources/IdentityTest.php deleted file mode 100644 index 0fe0752..0000000 --- a/tests/Finix/Resources/IdentityTest.php +++ /dev/null @@ -1,88 +0,0 @@ -state = json_decode(self::IDENTITY_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - } - - public function test_createIdentity() { - $identity = new Identity($this->state); - $this->assertFalse(isset($identity->id)); - $identity->save(); - $this->assertTrue(isset($identity->id)); - $this->assertStringStartsWith('ID', $identity->id); - } - - public function test_retrieveIdentity() { - $identity = new Identity($this->state); - $identity->save(); - - $fetchedIdentity = Identity::retrieve($identity->id); - $this->assertStringEndsWith($identity->id, $fetchedIdentity->getHref()); - } - - public function test_updateIdentity() { - $this->markTestSkipped("Ignored until Identity can be updated"); - - $identity = new Identity($this->state); - $identity->save(); - $this->assertEquals($identity->entity['tax_id'], $this->state['entity']['tax_id']); - $entity = $identity->entity; - $entity['tax_id'] = '991111'; - $identity->entity = $entity; - $identity->save(); - $this->assertEquals($identity->entity['tax_id'], '991111'); - } -} diff --git a/tests/Finix/Resources/MerchantTest.php b/tests/Finix/Resources/MerchantTest.php deleted file mode 100644 index dd94085..0000000 --- a/tests/Finix/Resources/MerchantTest.php +++ /dev/null @@ -1,26 +0,0 @@ -state = json_decode(self::MERCHANT_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - } - - public function test_merchantCreate() { - - } - -} diff --git a/tests/Finix/Resources/PaymentInstrumentTest.php b/tests/Finix/Resources/PaymentInstrumentTest.php deleted file mode 100644 index 7ff2220..0000000 --- a/tests/Finix/Resources/PaymentInstrumentTest.php +++ /dev/null @@ -1,108 +0,0 @@ -card = json_decode(self::PAYMENT_CARD_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - $this->bank = json_decode(self::BANK_ACCOUNT_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - } - - public function test_paymentCardCreate() { - $this->card['identity'] = self::$identity->id; - $paymentInstrument = new PaymentInstrument($this->card); - $paymentInstrument->save(); - $this->assertTrue(isset($paymentInstrument->id)); - // security code does not come back - $this->assertFalse(isset($paymentInstrument->security_code)); - - // check fields - $this->assertEquals($paymentInstrument->expiration_month, $this->card['expiration_month']); - $this->assertEquals($paymentInstrument->expiration_year, $this->card['expiration_year']); - $this->assertEquals($paymentInstrument->last_four, substr($this->card['number'], -4)); - } - - public function test_retrievePaymentInstrument() { - $this->bank['identity'] = self::$identity->id; - $this->card['identity'] = self::$identity->id; - - $bank = (new PaymentInstrument($this->bank))->save(); - $card = (new PaymentInstrument($this->card))->save(); - - $retrievedBank= PaymentInstrument::retrieve($bank->id); - $this->assertEquals($retrievedBank->id, $bank->id); - - $retrievedCard = PaymentInstrument::retrieve($card->id); - $this->assertEquals($retrievedCard->id, $card->id); - } - - public function test_bankAccountCreate() { - $this->bank['identity'] = self::$identity->id; - $paymentInstrument = new PaymentInstrument($this->bank); - $paymentInstrument->save(); - print_r($paymentInstrument); - $this->assertTrue(isset($paymentInstrument->id)); - - // account number comes back as last 4 - // TODO: account number last four should come back - //$this->assertEquals($paymentInstrument->account_number, substr($this->bank['number'], -4)); - - // check fields - $this->assertEquals($paymentInstrument->bank_code, $this->bank['bank_code']); - $this->assertEquals($paymentInstrument->currency, $this->bank['currency']); - } - -} diff --git a/tests/Finix/Resources/SettlementTest.php b/tests/Finix/Resources/SettlementTest.php deleted file mode 100644 index 4a1b923..0000000 --- a/tests/Finix/Resources/SettlementTest.php +++ /dev/null @@ -1,143 +0,0 @@ -save(); - self::$identity = $identity; - $payload = array( - "processor" => "DUMMY_V1"); - $identity->provisionMerchantOn($payload); - - $card = json_decode(self::PAYMENT_CARD_PAYLOAD, true); - $card['identity'] = $identity->id; - $card = new PaymentInstrument($card); - $card->save(); - self::$card = $card; - - $transfer = json_decode(self::TRANSFER_PAYLOAD, true); - $transfer['source'] = self::$card->id; - $transfer['merchant_identity'] = $identity->id; - - $transfer = new Transfer($transfer); - $transfer = $transfer->save(); - self::$transfer = $transfer; - } - - public function setUp() { - $this->settlement = json_decode(self::SETTLEMENT_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - } - - private function fillSettlement($settlement) - { - $settlement['identity'] = self::$identity->id; - return $settlement; - } - - public function test_createSettlement() { - // Sleep for 1 min for transfer to transition states - sleep(60); - $settlement_state = $this->fillSettlement($this->settlement); - $settlement = self::$identity->createSettlement($settlement_state); - $this->assertStringStartsWith('ST', $settlement->id); - $this->assertEquals($settlement->identity, self::$identity->id); - $this->assertEquals($settlement->transfer, null); - } -} \ No newline at end of file diff --git a/tests/Finix/Resources/TransferTest.php b/tests/Finix/Resources/TransferTest.php deleted file mode 100644 index 7d978b8..0000000 --- a/tests/Finix/Resources/TransferTest.php +++ /dev/null @@ -1,126 +0,0 @@ -id; - $bank = new PaymentInstrument($bank); - $bank->save(); - self::$bank = $bank; - - // setup card - $card = json_decode(self::PAYMENT_CARD_PAYLOAD, true); - $card['identity'] = self::$identity->id; - $card = new PaymentInstrument($card); - $card->save(); - self::$card = $card; - } - - public function setUp() { - $this->transfer = json_decode(self::TRANSFER_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - } - - private function fillDestinationTransfer($transfer) - { - $transfer['merchant_identity'] = self::$identity->id; - $transfer['destination'] = self::$bank->id; - return $transfer; - } - - private function fillSourceTransfer($transfer) - { - $transfer['merchant_identity'] = self::$identity->id; - $transfer['source'] = self::$card->id; - return $transfer; - } - - public function test_transferCreateToBankAccount() { - $transfer_state = $this->fillDestinationTransfer($this->transfer); - $transfer = new Transfer($transfer_state); - $transfer->save(); - $this->assertStringStartsWith('TR', $transfer->id); - $this->assertEquals($transfer->state, 'PENDING'); // transfers are async - } - - public function test_transferCreateFromPaymentCard() { - $transfer_state = $this->fillSourceTransfer($this->transfer); - $transfer = new Transfer($transfer_state); - $transfer->save(); - $this->assertStringStartsWith('TR', $transfer->id); - $this->assertEquals($transfer->state, 'PENDING'); // transfers are async - } - -public function test_reversalCreate() - { - $transfer_state = $this->fillSourceTransfer($this->transfer); - $transfer = new Transfer($transfer_state); - $transfer->save(); - $reversal = $transfer->reverse(100); - // reversals are transfers in opp. direction, so are also async - $this->assertEquals($reversal->state, 'PENDING'); - $this->assertStringEndsWith($transfer->id, $reversal->getParentTransferHref()); - } -} diff --git a/tests/Finix/Resources/VerificationTest.php b/tests/Finix/Resources/VerificationTest.php deleted file mode 100644 index 3ae1eb6..0000000 --- a/tests/Finix/Resources/VerificationTest.php +++ /dev/null @@ -1,78 +0,0 @@ -state = json_decode(self::IDENTITY_PAYLOAD, true); - - $this->verify_payload = json_decode(self::VERIFICATION_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - } - - public function test_verifyIdentity() { - $identity = new Identity($this->state); - $identity->save(); - $verification = $identity->verifyOn($this->verify_payload); - $this->assertStringStartsWith('VI', $verification ->id); - $this->assertEquals($verification->state, "PENDING"); - $this->assertEquals($verification->processor, "DUMMY_V1"); - } -} diff --git a/tests/Finix/Resources/WebhookTest.php b/tests/Finix/Resources/WebhookTest.php deleted file mode 100644 index a250cc3..0000000 --- a/tests/Finix/Resources/WebhookTest.php +++ /dev/null @@ -1,37 +0,0 @@ -webhook = json_decode(self::WEBHOOK_PAYLOAD, true); - $this->assertEquals(json_last_error(), 0); - } - - public function test_webhookCreate() { - $webhook = new Webhook($this->webhook); - $webhook->save(); - $this->assertTrue(isset($webhook->id)); - - // check fields - $this->assertEquals($webhook->url, $this->webhook['url']); - } - - public function test_retrievePaymentInstrument() { - $webhook = (new Webhook($this->webhook))->save(); - - $retrievedWebhook= Webhook::retrieve($webhook->id); - $this->assertEquals($retrievedWebhook->id, $webhook->id); - } -} diff --git a/tests/Finix/SampleData.php b/tests/Finix/SampleData.php deleted file mode 100644 index 93af9a1..0000000 --- a/tests/Finix/SampleData.php +++ /dev/null @@ -1,12 +0,0 @@ - null, "password" => null]); -class ScenariosTest extends \PHPUnit_Framework_TestCase { + date_default_timezone_set("UTC"); - public function test_Scenario() - { - $identity = $this->createIdentity(); - $this->createMerchant($identity); - $card = $this->createCard($identity); - $bank = $this->createBank($identity); + $this->user = Fixtures::createAdminUser(); - // auth + capture - $auth = $this->createAuthorization($identity, $card); - $captured = $this->captureAuthorization($auth); + Settings::configure(["username" => $this->user->id, "password" => $this->user->password]); - // create sale directly - $srcTxfr = $this->createSourceTransfer($identity, $card); + $this->application = Fixtures::createApplication($this->user); + $this->application->processing_enabled = true; + $this->application->settlement_enabled = true; + $this->application = $this->application->save(); - // credit a bank account - $destTxfr = $this->createDestinationTransfer($identity, $bank); + $this->dummyProcessor = Fixtures::dummyProcessor($this->application); - // reverse a sale ("issue a refund") - $reversal = $this->reverseTransfer($srcTxfr); - } + $this->partnerUser = Fixtures::createPartnerUser($this->application); - /** - * @return \Finix\Resources\Identity - */ - private function createIdentity() - { - $IDENTITY_PAYLOAD = <<assertEquals(json_last_error(), 0); - $identity = new Identity($state); - return $identity->save(); - } + Settings::configure(["username" => $this->partnerUser->id, "password" => $this->partnerUser->password]); - /** - * @param \Finix\Resources\Identity $identity - * @return \Finix\Resources\Merchant - */ - private function createMerchant($identity) - { - $payload = array( - "processor" => "DUMMY_V1"); - return $identity->provisionMerchantOn($payload); - } + $this->identity = Fixtures::createIdentity(); - private function createCard($identity) - { - $PAYMENT_CARD_PAYLOAD = <<assertEquals(json_last_error(), 0); - $state['identity'] = $identity->id; - $card = new PaymentInstrument($state); - return $card->save(); - } + $this->merchant = Fixtures::provisionMerchant($this->identity); - private function createBank($identity) - { - $BANK_ACCOUNT_PAYLOAD = <<assertEquals(json_last_error(), 0); - $state['identity'] = $identity->id; - $bank = new PaymentInstrument($state); - return $bank->save(); - } + $this->card = Fixtures::createCard($this->identity); - private function createAuthorization($identity, $card) - { - $state = [ - "processor" => "DUMMY_V1", - "amount" => 100, - "merchant_identity" => $identity->id, - "source" => $card->id, - "tags" => [ - "name" => "a random test name" - ] - ]; - $auth = new Authorization($state); - return $auth->save(); + $this->cardVerification = $this->card->verifyOn(new Verification(["processor" => "DUMMY_V1"])); + + $this->pushFundTransfer = Fixtures::createTransfer([ + "identity" => $this->card->identity, + "amount" => Fixtures::$disputeAmount, + "source" => $this->card->id, + "tags" => ["_source" => "php_client"] + ]); + + self::assertEquals($this->pushFundTransfer->state, "PENDING", "Transfer not in pending state"); + + Fixtures::waitFor(function () { + $this->pushFundTransfer = $this->pushFundTransfer->refresh(); + return $this->pushFundTransfer->state == "SUCCEEDED"; + }); + + $this->bankAccount = Fixtures::createBankAccount($this->identity); + + $this->webhook = Fixtures::createWebhook("https://tools.ietf.org/html/rfc2606"); } - /** - * @param \Finix\Resources\Authorization $auth - * @return \Finix\Resources\Authorization - */ - private function captureAuthorization($auth) + public function testCaptureAuthorization() { - $auth->capture_amount = 50; - return $auth->save(); + $this->markTestSkipped('must be revisited, see https://github.com/verygoodgroup/processing/issues/2330#issue-190787250'); + $this->authorization = Fixtures::createAuthorization($this->card, 100); + $this->authorization = $this->authorization->capture(10); + self::assertEquals($this->authorization->state, "SUCCEEDED", "Capture amount $10 of '" . $this->card->id . "' not succeeded"); } - private function createSourceTransfer($identity, $card) + public function testReverseFunds() { - $state = [ - "processor" => "DUMMY_V1", - "amount" => 1000, - "currency" => "USD", - "merchant_identity" => $identity->id, - "source" => $card->id - ]; - $srcTxfr = new Transfer($state); - return $srcTxfr->save(); + $this->pushFundTransferReversal = $this->pushFundTransfer->reverse(50); + self::assertEquals($this->pushFundTransferReversal->state, "PENDING", "Reverse not in pending state"); } - private function createDestinationTransfer($identity, $bank) + public function testVoidAuthorization() { - $state = [ - "processor" => "DUMMY_V1", - "amount" => 1000, - "currency" => "USD", - "merchant_identity" => $identity->id, - "destination" => $bank->id - ]; - $destTxfr = new Transfer($state); - return $destTxfr->save(); + $this->markTestSkipped('must be revisited, see https://github.com/verygoodgroup/processing/issues/2330#issue-190787250'); + $this->identityVerification = $this->identity->verifyOn(new Verification(["processor" => "DUMMY_V1"])); + $this->authorization = Fixtures::createAuthorization($this->card, 100); + $this->authorization = $this->authorization->void(true); + self::assertTrue($this->authorization->is_void, "Authorization not void"); } - /** - * @param \Finix\Resources\Transfer $srcTxfr - * @return \Finix\Resources\Reversal - */ - private function reverseTransfer($srcTxfr) + public function testSettlement() { - return $srcTxfr->reverse(100); + $this->markTestSkipped('must be revisited, ready_to_settle_at now too long to be completed'); + $this->pushFundTransfer1 = Fixtures::createTransfer([ + "identity" => $this->card->identity, + "amount" => 500, + "source" => $this->card->id + ]); + + $this->pushFundTransfer2 = Fixtures::createTransfer([ + "identity" => $this->card->identity, + "amount" => 300, + "source" => $this->card->id + ]); + + Fixtures::waitFor(function () { + $this->pushFundTransfer1 = $this->pushFundTransfer1->refresh(); + $this->pushFundTransfer2 = $this->pushFundTransfer2->refresh(); + + return $this->pushFundTransfer1->state == "SUCCEEDED" and + $this->pushFundTransfer2->state == "SUCCEEDED" and + $this->pushFundTransfer1->ready_to_settle_at != null and + $this->pushFundTransfer2->ready_to_settle_at != null; + }); + + $this->settlement = Fixtures::createSettlement($this->identity); + var_dump($this->settlement); } - -} \ No newline at end of file +}