From 4be3a37ec1040c8027b7b1a9ce6cbbab7fc0dd31 Mon Sep 17 00:00:00 2001 From: jbPayLease <31292494+jbPayLease@users.noreply.github.com> Date: Mon, 28 Aug 2017 11:25:22 -0700 Subject: [PATCH 1/9] split-pay Add AccountManagementService to SDK Adding a new service to the SDK for Account Management. This commit includes the functions ping, transferCredit, and transferDebit. Transfer functions can be used to move money between PaySafe master and sub-accounts. The ping function can be used to determine if the Account Management service is available. --- source/Paysafe/AccountManagement/Transfer.php | 46 +++++++++++++ source/Paysafe/AccountManagementService.php | 67 +++++++++++++++++++ source/Paysafe/PaysafeApiClient.php | 9 +++ 3 files changed, 122 insertions(+) create mode 100644 source/Paysafe/AccountManagement/Transfer.php create mode 100644 source/Paysafe/AccountManagementService.php diff --git a/source/Paysafe/AccountManagement/Transfer.php b/source/Paysafe/AccountManagement/Transfer.php new file mode 100644 index 0000000..6b642bc --- /dev/null +++ b/source/Paysafe/AccountManagement/Transfer.php @@ -0,0 +1,46 @@ + 'string', + 'amount' => 'int', + 'detail' => 'string', + 'dupCheck' => 'bool', + 'linkedAccount' => 'string', + 'merchantRefNum' => 'string', + 'error' => '\Paysafe\Error', + 'status' => array( + 'RECEIVED', + 'PENDING', + 'PROCESSING', + 'COMPLETED', + 'FAILED', + 'CANCELLED' + ), + 'links' => 'array:\Paysafe\Link' + ); + + /** + * + * @param type $linkName + * @return \Paysafe\HostedPayment\Link + * @throws PaysafeException + */ + public function getLink( $linkName ) { + if (!empty($this->link)) { + foreach ($this->link as $link) { + if ($link->rel == $linkName) { + return $link; + } + } + } + throw new PaysafeException("Link $linkName not found in purchase."); + } +} \ No newline at end of file diff --git a/source/Paysafe/AccountManagementService.php b/source/Paysafe/AccountManagementService.php new file mode 100644 index 0000000..5bb102a --- /dev/null +++ b/source/Paysafe/AccountManagementService.php @@ -0,0 +1,67 @@ +client = $client; + } + + public function transferDebit(Transfer $transfer) + { + $request = new Request(array( + 'method' => Request::POST, + 'uri' => $this->prepareURI($this->debitPath), + 'body' => $transfer + )); + + $response = $this->client->processRequest($request); + + return new Transfer($response); + } + + public function transferCredit(Transfer $transfer) + { + $request = new Request(array( + 'method' => Request::POST, + 'uri' => $this->prepareURI($this->creditPath), + 'body' => $transfer + )); + + $response = $this->client->processRequest($request); + + return new Transfer($response); + } + + private function prepareURI($path) + { + if (!$this->client->getAccount()) + { + throw new PaysafeException('Missing or invalid account', 500); + } + + return $this->uri . "/accounts/" . $this->client->getAccount() . $path; + } +} diff --git a/source/Paysafe/PaysafeApiClient.php b/source/Paysafe/PaysafeApiClient.php index 04f9574..4e165ec 100644 --- a/source/Paysafe/PaysafeApiClient.php +++ b/source/Paysafe/PaysafeApiClient.php @@ -182,6 +182,15 @@ public function threeDSecureService() { return new ThreeDSecureService($this); } + /** + * Account Management service. + * + * @return \Paysafe\AccountManagementService + */ + public function accountManagementService() { + return new AccountManagementService($this); + } + /** * * @param \Paysafe\Request $request From 0be664584902dd8dafa016fee81aa1df119bd3d1 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Tue, 29 Aug 2017 14:45:10 -0600 Subject: [PATCH 2/9] Revert "split-pay Add AccountManagementService to SDK" This reverts commit 4be3a37ec1040c8027b7b1a9ce6cbbab7fc0dd31. --- source/Paysafe/AccountManagement/Transfer.php | 46 ------------- source/Paysafe/AccountManagementService.php | 67 ------------------- source/Paysafe/PaysafeApiClient.php | 9 --- 3 files changed, 122 deletions(-) delete mode 100644 source/Paysafe/AccountManagement/Transfer.php delete mode 100644 source/Paysafe/AccountManagementService.php diff --git a/source/Paysafe/AccountManagement/Transfer.php b/source/Paysafe/AccountManagement/Transfer.php deleted file mode 100644 index 6b642bc..0000000 --- a/source/Paysafe/AccountManagement/Transfer.php +++ /dev/null @@ -1,46 +0,0 @@ - 'string', - 'amount' => 'int', - 'detail' => 'string', - 'dupCheck' => 'bool', - 'linkedAccount' => 'string', - 'merchantRefNum' => 'string', - 'error' => '\Paysafe\Error', - 'status' => array( - 'RECEIVED', - 'PENDING', - 'PROCESSING', - 'COMPLETED', - 'FAILED', - 'CANCELLED' - ), - 'links' => 'array:\Paysafe\Link' - ); - - /** - * - * @param type $linkName - * @return \Paysafe\HostedPayment\Link - * @throws PaysafeException - */ - public function getLink( $linkName ) { - if (!empty($this->link)) { - foreach ($this->link as $link) { - if ($link->rel == $linkName) { - return $link; - } - } - } - throw new PaysafeException("Link $linkName not found in purchase."); - } -} \ No newline at end of file diff --git a/source/Paysafe/AccountManagementService.php b/source/Paysafe/AccountManagementService.php deleted file mode 100644 index 5bb102a..0000000 --- a/source/Paysafe/AccountManagementService.php +++ /dev/null @@ -1,67 +0,0 @@ -client = $client; - } - - public function transferDebit(Transfer $transfer) - { - $request = new Request(array( - 'method' => Request::POST, - 'uri' => $this->prepareURI($this->debitPath), - 'body' => $transfer - )); - - $response = $this->client->processRequest($request); - - return new Transfer($response); - } - - public function transferCredit(Transfer $transfer) - { - $request = new Request(array( - 'method' => Request::POST, - 'uri' => $this->prepareURI($this->creditPath), - 'body' => $transfer - )); - - $response = $this->client->processRequest($request); - - return new Transfer($response); - } - - private function prepareURI($path) - { - if (!$this->client->getAccount()) - { - throw new PaysafeException('Missing or invalid account', 500); - } - - return $this->uri . "/accounts/" . $this->client->getAccount() . $path; - } -} diff --git a/source/Paysafe/PaysafeApiClient.php b/source/Paysafe/PaysafeApiClient.php index 4e165ec..04f9574 100644 --- a/source/Paysafe/PaysafeApiClient.php +++ b/source/Paysafe/PaysafeApiClient.php @@ -182,15 +182,6 @@ public function threeDSecureService() { return new ThreeDSecureService($this); } - /** - * Account Management service. - * - * @return \Paysafe\AccountManagementService - */ - public function accountManagementService() { - return new AccountManagementService($this); - } - /** * * @param \Paysafe\Request $request From 6c376cd6027ea8b3544199e6c367a1b9269a21f7 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Tue, 12 Dec 2017 10:35:44 -0700 Subject: [PATCH 3/9] test existing StandaloneCredits; fix what tests revealed --- .../Paysafe/DirectDebit/ShippingDetails.php | 2 +- .../Paysafe/DirectDebit/StandaloneCredits.php | 126 ++++----- .../DirectDebit/StandAloneCreditsTest.php | 252 ++++++++++++++++++ 3 files changed, 317 insertions(+), 63 deletions(-) create mode 100644 tests/paysafe/DirectDebit/StandAloneCreditsTest.php diff --git a/source/Paysafe/DirectDebit/ShippingDetails.php b/source/Paysafe/DirectDebit/ShippingDetails.php index 18c6f41..33b3a89 100644 --- a/source/Paysafe/DirectDebit/ShippingDetails.php +++ b/source/Paysafe/DirectDebit/ShippingDetails.php @@ -30,7 +30,7 @@ * @property string $country * @property string $zip */ -class ShippingDetails +class ShippingDetails extends \Paysafe\JSONObject { //put your code here diff --git a/source/Paysafe/DirectDebit/StandaloneCredits.php b/source/Paysafe/DirectDebit/StandaloneCredits.php index f716174..8f03784 100644 --- a/source/Paysafe/DirectDebit/StandaloneCredits.php +++ b/source/Paysafe/DirectDebit/StandaloneCredits.php @@ -17,74 +17,76 @@ * 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. */ - namespace Paysafe\DirectDebit; -/* - * @property string $id - * @property string $merchantRefNum - * @property int $amount - * @property \Paysafe\DirectDebit\ach $ach - * @property \Paysafe\DirectDebit\eft $eft - * @property \Paysafe\DirectDebit\bacs $bacs - * @property \Paysafe\DirectDebit\profile $profile - * @property \Paysafe\DirectDebit\billingDetails $billingDetails - * @property \Paysafe\DirectDebit\ShippingDetails $shippingDetails - * @property string $customerIp - * @property string $dupCheck - * @property string $txnTime - * @property string $currencyCode - * @property \Paysafe\Error $error - * @property string $status - */ +namespace Paysafe\DirectDebit; - class StandaloneCredits extends \Paysafe\JSONObject implements \Paysafe\Pageable { +use Paysafe\PaysafeException; - public static function getPageableArrayKey() { - return "standaloneCredits"; - } +/** + * @property string $id + * @property string $merchantRefNum + * @property int $amount + * @property \Paysafe\DirectDebit\ACH $ach + * @property \Paysafe\DirectDebit\EFT $eft + * @property \Paysafe\DirectDebit\BACS $bacs + * @property \Paysafe\DirectDebit\Profile $profile + * @property \Paysafe\DirectDebit\Filter $filter + * @property \Paysafe\DirectDebit\BillingDetails $billingDetails + * @property \Paysafe\DirectDebit\ShippingDetails $shippingDetails + * @property string $customerIp + * @property bool $dupCheck + * @property string $txnTime + * @property string $currencyCode + * @property \Paysafe\Error $error + * @property string $status + * @property \Paysafe\Link[] $links + */ +class StandaloneCredits extends \Paysafe\JSONObject implements \Paysafe\Pageable +{ + public static function getPageableArrayKey() { + return "standaloneCredits"; + } - protected static $fieldTypes = array( - 'id' => 'string', - 'merchantRefNum' => 'string', - 'amount' => 'int', - 'ach' => '\Paysafe\DirectDebit\ACH', - 'eft' => '\Paysafe\DirectDebit\EFT', - 'bacs' => '\Paysafe\DirectDebit\BACS', - 'profile' => '\Paysafe\DirectDebit\Profile', - 'filter' => '\Paysafe\DirectDebit\Filter', - 'billingDetails' => '\Paysafe\DirectDebit\BillingDetails', - 'shippingDetails' => '\Paysafe\DirectDebit\ShippingDetails', - 'customerIp' => 'string', - 'dupCheck' => 'bool', - 'txnTime' => 'string', - 'currencyCode' => 'string', - 'error' => '\Paysafe\Error', - 'status' => array( - 'RECEIVED', - 'PENDING', - 'PROCESSING', - 'COMPLETED', - 'FAILED', - 'CANCELLED' - ), - 'links' => 'array:\Paysafe\Link' - ); + protected static $fieldTypes = array( + 'id' => 'string', + 'merchantRefNum' => 'string', + 'amount' => 'int', + 'ach' => '\Paysafe\DirectDebit\ACH', + 'eft' => '\Paysafe\DirectDebit\EFT', + 'bacs' => '\Paysafe\DirectDebit\BACS', + 'profile' => '\Paysafe\DirectDebit\Profile', + 'filter' => '\Paysafe\DirectDebit\Filter', + 'billingDetails' => '\Paysafe\DirectDebit\BillingDetails', + 'shippingDetails' => '\Paysafe\DirectDebit\ShippingDetails', + 'customerIp' => 'string', + 'dupCheck' => 'bool', + 'txnTime' => 'string', + 'currencyCode' => 'string', + 'error' => '\Paysafe\Error', + 'status' => array( + 'RECEIVED', + 'PENDING', + 'PROCESSING', + 'COMPLETED', + 'FAILED', + 'CANCELLED' + ), + 'links' => 'array:\Paysafe\Link' + ); - /** - * - * @param type $linkName - * @return \Paysafe\HostedPayment\Link - * @throws PaysafeException - */ - public function getLink( $linkName ) { - if (!empty($this->link)) { - foreach ($this->link as $link) { - if ($link->rel == $linkName) { - return $link; - } + /** + * @param string $linkName + * @return \Paysafe\Link + * @throws \Paysafe\PaysafeException + */ + public function getLink( $linkName ) { + if (!empty($this->links)) { + foreach ($this->links as $link) { + if ($link->rel == $linkName) { + return $link; } } - throw new PaysafeException("Link $linkName not found in purchase."); } - + throw new PaysafeException("Link $linkName not found in stand alone credit."); } +} diff --git a/tests/paysafe/DirectDebit/StandAloneCreditsTest.php b/tests/paysafe/DirectDebit/StandAloneCreditsTest.php new file mode 100644 index 0000000..1c26dca --- /dev/null +++ b/tests/paysafe/DirectDebit/StandAloneCreditsTest.php @@ -0,0 +1,252 @@ +assertThat($sac, $this->isInstanceOf(StandaloneCredits::class)); + } + + public function testGetPageableArrayKey() + { + $pak = StandaloneCredits::getPageableArrayKey(); + $this->assertThat($pak, $this->equalTo('standaloneCredits')); + } + + public function testGetLinkEmpty() + { + $bad_link_name = 'foo'; + $this->expectException(PaysafeException::class); + $this->expectExceptionMessage("Link $bad_link_name not found in stand alone credit"); + $this->expectExceptionCode(0); + + $sac = new StandaloneCredits(); + $sac->getLink($bad_link_name); + } + + public function testGetLink() + { + $link_name = 'bar'; + $link_value = 'gopher://foo.ba'; + $links = [['rel' => $link_name, 'href' => $link_value]]; + $sac = new StandaloneCredits(['links' => $links]); + + $returned_link = $sac->getLink($link_name); + $this->assertThat($returned_link, $this->isInstanceOf(Link::class)); + $this->assertThat($returned_link->href, $this->equalTo($link_value)); + $this->assertThat($returned_link->rel, $this->equalTo($link_name)); + } + + public function testMissingRequiredFields() + { + $sac = new StandaloneCredits(); + $required_fields = ['id', 'merchantRefNum']; + $sac->setRequiredFields($required_fields); + + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(500); + $this->expectExceptionMessage('Missing required properties: ' . join(', ', $required_fields)); + + $sac->checkRequiredFields(); + } + + public function testConstructWithBogusProperty() + { + $sac = new StandaloneCredits(['bogusproperty' => new \stdClass()]); + // when passing a property absent from the fieldTypes array to the constructor, the bogus property should be + // ignored + // we expect to receive an empty JSON object + $this->assertThat($sac->toJson(), $this->equalTo('{}')); + } + + public function testSetBogusProperty() + { + $sac = new StandaloneCredits(); + + // when calling the setter on a property absent from the fieldTypes array, we expect an exception + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(0); + $this->expectExceptionMessage('Invalid property bogusproperty for class ' . StandaloneCredits::class . '.'); + $sac->bogusproperty = new \stdClass(); + } + + public function testConstructWithValidProperty() + { + $sac = new StandaloneCredits(['merchantRefNum' => 'foo']); + $this->assertThat($sac->toJson(), $this->equalTo('{"merchantRefNum":"foo"}')); + } + + public function testConstructWithMultipleValidProperties() + { + $sac = new StandaloneCredits([ + 'merchantRefNum' => 'foo', + 'amount' => 5, + ]); + $this->assertThat($sac->toJson(), $this->equalTo('{"merchantRefNum":"foo","amount":5}')); + } + + public function testConstructWithInvalidValue() + { + $sac_array = [ + 'merchantRefNum' => new \stdClass(), + 'amount' => 5 + ]; + // merchantRefNum should be a string; object should throw an exception + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(0); + $this->expectExceptionMessage('Invalid value for property merchantRefNum for class ' + . StandaloneCredits::class . '. String expected.'); + $refund = new StandaloneCredits($sac_array); + } + + public function testSetInvalidValue() + { + $sac = new StandaloneCredits(); + // merchantRefNum should be a string; object should throw an exception + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(0); + $this->expectExceptionMessage('Invalid value for property merchantRefNum for class ' + . StandaloneCredits::class . '. String expected.'); + $sac->merchantRefNum = new \stdClass(); + } + + public function testAllFieldsValueValues() + { + $id = 'id'; // string + $merchantRefNum = 'merchantRefNum'; // string + $amount = 1; // int + // $ach should be an array acceptable to the Paysafe\DirectDebit\ACH constructor + $ach = [ + 'paymentToken' => 'paymentToken', // string + 'payMethod' => 'WEB', // string - enum + 'paymentDescriptor' => 'paymentDescriptor', // string + 'accountHolderName' => 'accountHolderName', // string + 'accountType' => 'SAVINGS', // string - enum + 'accountNumber' => 'accountNumber', // string + 'routingNumber' => 'routingNumber', // string + 'lastDigits' => 'lastDigits', // string + ]; + // $eft should be an array acceptable to the Paysafe\DirectDebit\EFT constructor + $eft = [ + 'paymentToken' => 'paymentToken', // string + 'paymentDescriptor' => 'paymentDescriptor', // string + 'accountHolderName' => 'accountHolderName', // string + 'accountNumber' => 'accountNumber', // string + 'transitNumber' => 'transitNumber', // string + 'institutionId' => 'institutionId', // string + 'lastDigits' => 'lastDigits', // string + ]; + // $bacs should be an array acceptable to the Paysafe\DirectDebit\BACS constructor + $bacs = [ + 'paymentToken' => 'paymentToken', // string + 'accountHolderName' => 'accountHolderName', // string + 'sortCode' => 'sortCode', // string + 'accountNumber' => 'accountNumber', // string + 'mandateReference' => 'mandateReference', // string + 'lastDigits' => 'lastDigits', // string + ]; + // $profile should be an array acceptable to the Paysafe\DirectDebit\Profile constructor + $profile = [ + 'firstName' => 'firstName', // string + 'lastName' => 'lastName', // string + 'email' => 'email', // string + 'ssn' => 'ssn', // string + 'dateOfBirth' => [ + 'day' => 1, // int + 'month' => 2, // int + 'year' => 3, // int + ] + ]; + // $filter should be an array acceptable to the Paysafe\DirectDebit\Filter constructor + $filter = [ + 'limit' => 1, // int + 'offset' => 2, // int + 'startDate' => 'startDate', // string + 'endDate' => 'endDate', // string + ]; + // $billingDetails should be an array acceptable to the Paysafe\DirectDebit\BillingDetails constructor + $billingDetails = [ + 'street' => 'street', // string + 'street2' => 'street2', // string + 'city' => 'city', // string + 'state' => 'state', // string + 'country' => 'country', // string + 'zip' => 'zip', // string + 'phone' => 'phone', // string + ]; + // $shippingDetails should be an array acceptable to the Paysafe\DirectDebit\ShippingDetails constructor + $shippingDetails = [ + 'carrier' => 'APC', // string - enum + 'shipMethod' => 'N', // string - enum + 'recipientName' => 'string', // string + 'street' => 'street', // string + 'street2' => 'street2', // string + 'city' => 'city', // string + 'state' => 'state', // string + 'country' => 'country', // string + 'zip' => 'zip', // string + ]; + $customerIp = 'customerIp'; // string + $dupCheck = true; // bool + $txnTime = 'txnTime'; // string + $currencyCode = 'currencyCode'; // string + $error = [ // '\Paysafe\Error', + 'code' => 'code',// 'string', + 'message' => 'message', // 'string', + 'details' => ['details1','details2'], // 'array:string', + 'fieldErrors' => [[ // 'array:\Paysafe\FieldError', + 'field' => 'field', // string + 'error' => 'error', // string + ]], + 'links' => [[ // 'array:\Paysafe\Link' + 'rel' => 'rel', // 'string', + 'href' => 'gopher://foo.ba', // 'url' + ]], + ]; + $status = 'RECEIVED'; // string - enum + $links = [[ // 'array:\Paysafe\Link', + 'rel' => 'rel', // 'string', + 'href' => 'gopher://foo.ba', // 'url' + ]]; + + $sac_array = [ + 'id' => $id, + 'merchantRefNum' => $merchantRefNum, + 'amount' => $amount, + 'ach' => $ach, + 'eft' => $eft, + 'bacs' => $bacs, + 'profile' => $profile, + 'filter' => $filter, + 'billingDetails' => $billingDetails, + 'shippingDetails' => $shippingDetails, + 'customerIp' => $customerIp, + 'dupCheck' => $dupCheck, + 'txnTime' => $txnTime, + 'currencyCode' => $currencyCode, + 'error' => $error, + 'status' => $status, + 'links' => $links, + ]; + + $sac = new StandaloneCredits($sac_array); + /* + * This may seem like a trivial test, but behind the scenes toJson triggers data validation. Bad data will + * result in an exception. + * Not only does this test ensure the proper operation of the json encoding in JSONObject, but it validates + * our understanding of the data requirements in Authorization + */ + $this->assertThat($sac->toJson(), $this->equalTo(json_encode($sac_array))); + } +} From 6b0a90b69601bbbfd76731c393339454b99807d0 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Tue, 12 Dec 2017 10:46:25 -0700 Subject: [PATCH 4/9] clean up some copy/paste code comments --- tests/paysafe/AccountManagement/TransferTest.php | 2 +- tests/paysafe/CardPayments/RefundTest.php | 2 +- tests/paysafe/DirectDebit/StandAloneCreditsTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/paysafe/AccountManagement/TransferTest.php b/tests/paysafe/AccountManagement/TransferTest.php index b4a9852..0838581 100644 --- a/tests/paysafe/AccountManagement/TransferTest.php +++ b/tests/paysafe/AccountManagement/TransferTest.php @@ -194,7 +194,7 @@ public function testAllFieldsValidValues() * This may seem like a trivial test, but behind the scenes toJson triggers data validation. Bad data will * result in an exception. * Not only does this test ensure the proper operation of the json encoding in JSONObject, but it validates - * our understanding of the data requirements in Authorization + * our understanding of the data requirements in Transfer */ $this->assertThat($t->toJson(), $this->equalTo(json_encode($t_array))); } diff --git a/tests/paysafe/CardPayments/RefundTest.php b/tests/paysafe/CardPayments/RefundTest.php index 89b2e1b..3bee2c7 100644 --- a/tests/paysafe/CardPayments/RefundTest.php +++ b/tests/paysafe/CardPayments/RefundTest.php @@ -183,7 +183,7 @@ public function testAllFieldsValueValues() * This may seem like a trivial test, but behind the scenes toJson triggers data validation. Bad data will * result in an exception. * Not only does this test ensure the proper operation of the json encoding in JSONObject, but it validates - * our understanding of the data requirements in Authorization + * our understanding of the data requirements in Refund */ $this->assertThat($refund->toJson(), $this->equalTo(json_encode($refund_array))); } diff --git a/tests/paysafe/DirectDebit/StandAloneCreditsTest.php b/tests/paysafe/DirectDebit/StandAloneCreditsTest.php index 1c26dca..a22f2e4 100644 --- a/tests/paysafe/DirectDebit/StandAloneCreditsTest.php +++ b/tests/paysafe/DirectDebit/StandAloneCreditsTest.php @@ -245,7 +245,7 @@ public function testAllFieldsValueValues() * This may seem like a trivial test, but behind the scenes toJson triggers data validation. Bad data will * result in an exception. * Not only does this test ensure the proper operation of the json encoding in JSONObject, but it validates - * our understanding of the data requirements in Authorization + * our understanding of the data requirements in StandAloneCredits */ $this->assertThat($sac->toJson(), $this->equalTo(json_encode($sac_array))); } From bd8f0fcaa704f611b4e590a010c0be597da2e0c7 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Tue, 12 Dec 2017 10:56:17 -0700 Subject: [PATCH 5/9] add splitpay to StandaloneCredits; test --- .../Paysafe/DirectDebit/StandaloneCredits.php | 3 +- .../DirectDebit/StandAloneCreditsTest.php | 92 ++++++++++++++++++- 2 files changed, 93 insertions(+), 2 deletions(-) diff --git a/source/Paysafe/DirectDebit/StandaloneCredits.php b/source/Paysafe/DirectDebit/StandaloneCredits.php index 8f03784..e60c886 100644 --- a/source/Paysafe/DirectDebit/StandaloneCredits.php +++ b/source/Paysafe/DirectDebit/StandaloneCredits.php @@ -71,7 +71,8 @@ public static function getPageableArrayKey() { 'FAILED', 'CANCELLED' ), - 'links' => 'array:\Paysafe\Link' + 'links' => 'array:\Paysafe\Link', + 'splitpay' => 'array:\Paysafe\DirectDebit\SplitPay', ); /** diff --git a/tests/paysafe/DirectDebit/StandAloneCreditsTest.php b/tests/paysafe/DirectDebit/StandAloneCreditsTest.php index a22f2e4..2f17216 100644 --- a/tests/paysafe/DirectDebit/StandAloneCreditsTest.php +++ b/tests/paysafe/DirectDebit/StandAloneCreditsTest.php @@ -107,7 +107,7 @@ public function testConstructWithInvalidValue() $this->expectExceptionCode(0); $this->expectExceptionMessage('Invalid value for property merchantRefNum for class ' . StandaloneCredits::class . '. String expected.'); - $refund = new StandaloneCredits($sac_array); + $sac = new StandaloneCredits($sac_array); } public function testSetInvalidValue() @@ -219,6 +219,17 @@ public function testAllFieldsValueValues() 'rel' => 'rel', // 'string', 'href' => 'gopher://foo.ba', // 'url' ]]; + // array:\Paysafe\DirectDebit\SplitPay + $splitpay = [ + [ + 'linkedAccount' => 'link_account_id_1', + 'amount' => 500, + ], + [ + 'linkedAccount' => 'link_account_id_2', + 'amount' => 600, + ], + ]; $sac_array = [ 'id' => $id, @@ -238,6 +249,7 @@ public function testAllFieldsValueValues() 'error' => $error, 'status' => $status, 'links' => $links, + 'splitpay' => $splitpay, ]; $sac = new StandaloneCredits($sac_array); @@ -249,4 +261,82 @@ public function testAllFieldsValueValues() */ $this->assertThat($sac->toJson(), $this->equalTo(json_encode($sac_array))); } + + public function testConstructEmptySplitPay() + { + $sac = new StandaloneCredits([ + 'splitpay' => [[]], + ]); + + $this->assertThat($sac->toJson(), $this->equalTo('{"splitpay":[{}]}')); + } + + public function testSetEmptySplitPay() + { + $sac = new StandaloneCredits(); + $sac->splitpay = [[]]; + + $this->assertThat($sac->toJson(), $this->equalTo('{"splitpay":[{}]}')); + } + + public function testConstructBadSplitPay() + { + $bad_sp_array = ['linkedAccount' => new \stdClass()]; + + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(0); + $this->expectExceptionMessage('Invalid value for property linkedAccount for class ' . SplitPay::class . '.' + . ' String expected.'); + $sac = new StandaloneCredits([ + 'splitpay' => [$bad_sp_array], + ]); + } + + public function testConstructSingleSPObjInsteadOfArray() + { + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(0); + $this->expectExceptionMessage('Invalid value for property splitpay for class ' . StandaloneCredits::class + . '. Array expected.'); + + $sac = new StandaloneCredits([ + 'splitpay' => new SplitPay(), + ]); + } + + public function testConstructGoodSP() + { + $sac = new StandaloneCredits([ + 'splitpay' => [[ + 'linkedAccount' => 'link_account_id', + 'amount' => 500, + ]] + ]); + + $this->assertThat($sac->toJson(), + $this->equalTo('{"splitpay":[{"linkedAccount":"link_account_id","amount":500}]}')); + } + + public function testSetGoodSP() + { + $sac = new StandaloneCredits(); + $sac->splitpay = [[ + 'linkedAccount' => 'link_account_id', + 'amount' => 500, + ]]; + + $this->assertThat($sac->toJson(), + $this->equalTo('{"splitpay":[{"linkedAccount":"link_account_id","amount":500}]}')); + } + + public function testSetSingleSPObjInsteadOfArray() + { + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(0); + $this->expectExceptionMessage('Invalid value for property splitpay for class ' . StandaloneCredits::class + . '. Array expected.'); + + $sac = new StandaloneCredits(); + $sac->splitpay = new SplitPay(); + } } From 20c223ffa9f6082cad026c55f263b6cf028856fa Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Tue, 12 Dec 2017 11:04:18 -0700 Subject: [PATCH 6/9] rename test to match class name --- .../{StandAloneCreditsTest.php => StandaloneCreditsTest.php} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename tests/paysafe/DirectDebit/{StandAloneCreditsTest.php => StandaloneCreditsTest.php} (99%) diff --git a/tests/paysafe/DirectDebit/StandAloneCreditsTest.php b/tests/paysafe/DirectDebit/StandaloneCreditsTest.php similarity index 99% rename from tests/paysafe/DirectDebit/StandAloneCreditsTest.php rename to tests/paysafe/DirectDebit/StandaloneCreditsTest.php index 2f17216..5f2377b 100644 --- a/tests/paysafe/DirectDebit/StandAloneCreditsTest.php +++ b/tests/paysafe/DirectDebit/StandaloneCreditsTest.php @@ -10,7 +10,7 @@ use Paysafe\Link; use Paysafe\PaysafeException; -class StandAloneCreditsTest extends \PHPUnit_Framework_TestCase +class StandaloneCreditsTest extends \PHPUnit_Framework_TestCase { public function testConstruct() { From aa82a8bb49802bc28c584521727689bce16939d4 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Tue, 12 Dec 2017 15:00:16 -0700 Subject: [PATCH 7/9] test existing DirectDebitService::standaloneCredits --- ...irectDebitServiceStandaloneCreditsTest.php | 352 ++++++++++++++++++ 1 file changed, 352 insertions(+) create mode 100644 tests/paysafe/DirectDebitServiceStandaloneCreditsTest.php diff --git a/tests/paysafe/DirectDebitServiceStandaloneCreditsTest.php b/tests/paysafe/DirectDebitServiceStandaloneCreditsTest.php new file mode 100644 index 0000000..95a2e41 --- /dev/null +++ b/tests/paysafe/DirectDebitServiceStandaloneCreditsTest.php @@ -0,0 +1,352 @@ +mock_api_client = $this->createMock(PaysafeApiClient::class); + $this->mock_api_client->method('getAccount')->willReturn('bogus_account_num'); + } + + /** + * This is a bad test as it simply confirms current undesirable behavior. If no type is specified in the + * StandaloneCredits object (ach, eft, etc), then a PHP Error is generated. Ideally, the code would gracefully + * handle this situation. + * See: https://github.com/paysafegroup/paysafe_sdk_php/issues/13 + */ + public function testMissingBankInfo() + { + /* + * The StandaloneCredits object passed to standaloneCredits() MUST have one of ach, eft, or bacs defined. + */ + $dds = new DirectDebitService($this->mock_api_client); + + /* + * TODO currently standaloneCredits() does not handle this situation gracefully and a PHP Error is emitted for + * and undefined variable. Issue has been reported: https://github.com/paysafegroup/paysafe_sdk_php/issues/13 + */ + $this->expectException(PHPUnit_Framework_Error_Notice::class); + $this->expectExceptionCode(8); + $this->expectExceptionMessage('Undefined variable: return'); + $dds->standaloneCredits(new StandaloneCredits()); + } + + /* + * This is a test to confirm that the DirectDebitService sets the required parameters we expect for a + * standaloneCredits call. + * If no token is specified, the service first checks that required Profile parameters were included. + */ + public function testCreditAchMissingProfileRequiredFields() + { + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(500); + $this->expectExceptionMessage('Missing required properties: firstName, lastName'); + + $dds = new DirectDebitService($this->mock_api_client); + /* + * Note: we have to at least specify an empty ach or there will be a PHP Error. + * See https://github.com/paysafegroup/paysafe_sdk_php/issues/13 + */ + $ach_credit_array = [ 'ach' => [] ]; + $dds->standaloneCredits(new StandaloneCredits($ach_credit_array)); + } + + /* + * This is a test to confirm that the DirectDebitService sets the required parameters we expect for a + * standaloneCredits call. + * If a token is specified we expect to validate merchantRefNum, amount, and ach + */ + public function testCreditAchMissingRequiredFieldsWithToken() + { + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(500); + $this->expectExceptionMessage('Missing required properties: merchantRefNum, amount'); + + $dds = new DirectDebitService($this->mock_api_client); + $ach_credit_array = [ + 'ach' => [ + 'paymentToken' => 'bogus_payment_token', + ] + ]; + $dds->standaloneCredits(new StandaloneCredits($ach_credit_array)); + } + + /* + * This is a test to confirm that the DirectDebitService sets the required parameters we expect for a + * standaloneCredits call. + * If no token is specified, but required Profile params are, we expect to validate merchantRefNum, amount, ach, + * profile, and billingDetails + */ + public function testCreditAchMissingRequiredFieldsNoToken() + { + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(500); + $this->expectExceptionMessage('Missing required properties: merchantRefNum, amount, billingDetails'); + + $dds = new DirectDebitService($this->mock_api_client); + /* + * Note: we have to at least specify an empty ach or there will be a PHP Error. + * See https://github.com/paysafegroup/paysafe_sdk_php/issues/13 + */ + $ach_credit_array = [ + 'ach' => [ ], + 'profile' => [ + 'firstName' => 'firstname', + 'lastName' => 'lastname', + ], + ]; + $dds->standaloneCredits(new StandaloneCredits($ach_credit_array)); + } + + /* + * This is a test to confirm that the DirectDebitService sets expected values for required/optional fields. If a + * parameter is set in the StandaloneCredits obj, but not in the required or optional lists, it will be omitted from + * the JSON created by toJson. (toJson is called by processRequest in the api client). + * + * So, we'll make our mock api client call toJson, and confirm the output lacks the field that doesn't appear in + * required/optional. + * + * This test omits the token and instead includes profile information. The required/optional lists are built + * slightly differently in each case + */ + public function testCreditAchNoTokenInvalidField() + { + $this->mock_api_client + ->expects($this->once()) + ->method('processRequest') + ->with($this->isInstanceOf(Request::class)) + ->will($this->returnCallback(function (Request $param) { + return json_decode($param->body->toJson(), true); + })); + $dds = new DirectDebitService($this->mock_api_client); + + $ach_credit_array = [ + 'id' => 'id is a valid param, but not in required or optional list', + 'ach' => [ + 'accountType' => 'CHECKING', + ], + 'profile' => [ + 'firstName' => 'firstname', + 'lastName' => 'lastname', + ], + 'merchantRefNum' => 'merchantrefnum', + 'amount' => 555, + 'billingDetails' => [ + 'zip' => '10007', + ], + ]; + + $retval = $dds->standaloneCredits(new StandaloneCredits($ach_credit_array)); + $param_no_id = $ach_credit_array; + unset($param_no_id['id']); + $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), + 'Did not receive expected return from DirectDebitService::standaloneCredits'); + } + + /* + * This is a test to confirm that the DirectDebitService sets expected values for required/optional fields. If a + * parameter is set in the StandaloneCredits obj, but not in the required or optional lists, it will be omitted from + * the JSON created by toJson. (toJson is called by processRequest in the api client). + * + * So, we'll make our mock api client call toJson, and confirm the output lacks the field that doesn't appear in + * required/optional. + * + * This test includes the token and omits profile information. The required/optional lists are built + * slightly differently in each case + */ + public function testCreditAchWithTokenInvalidField() + { + $this->mock_api_client + ->expects($this->once()) + ->method('processRequest') + ->with($this->isInstanceOf(Request::class)) + ->will($this->returnCallback(function (Request $param) { + return json_decode($param->body->toJson(), true); + })); + $dds = new DirectDebitService($this->mock_api_client); + + $ach_credit_array = [ + 'id' => 'id is a valid param, but not in required or optional list', + 'ach' => [ + 'paymentToken' => 'myspecialtoken', + ], + 'merchantRefNum' => 'merchantrefnum', + 'amount' => 555, + ]; + + $retval = $dds->standaloneCredits(new StandaloneCredits($ach_credit_array)); + $param_no_id = $ach_credit_array; + unset($param_no_id['id']); + $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), + 'Did not receive expected return from DirectDebitService::standaloneCredits'); + } + /* + * This is a test to confirm that the DirectDebitService sets the required parameters we expect for a + * standaloneCredits call. + * If no token is specified, the service first checks that required Profile parameters were included. + */ + public function testCreditEftMissingProfileRequiredFields() + { + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(500); + $this->expectExceptionMessage('Missing required properties: firstName, lastName'); + + $dds = new DirectDebitService($this->mock_api_client); + /* + * Note: we have to at least specify an empty eft or there will be a PHP Error. + * See https://github.com/paysafegroup/paysafe_sdk_php/issues/13 + */ + $eft_credit_array = [ 'eft' => [] ]; + $dds->standaloneCredits(new StandaloneCredits($eft_credit_array)); + } + + /* + * This is a test to confirm that the DirectDebitService sets the required parameters we expect for a + * standaloneCredits call. + * If a token is specified we expect to validate merchantRefNum, amount, and eft + */ + public function testCreditEftMissingRequiredFieldsWithToken() + { + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(500); + $this->expectExceptionMessage('Missing required properties: merchantRefNum, amount'); + + $dds = new DirectDebitService($this->mock_api_client); + $eft_credit_array = [ + 'eft' => [ + 'paymentToken' => 'bogus_payment_token', + ] + ]; + $dds->standaloneCredits(new StandaloneCredits($eft_credit_array)); + } + + /* + * This is a test to confirm that the DirectDebitService sets the required parameters we expect for a + * standaloneCredits call. + * If no token is specified, but required Profile params are, we expect to validate merchantRefNum, amount, eft, + * profile, and billingDetails + */ + public function testCreditEftMissingRequiredFieldsNoToken() + { + $this->expectException(PaysafeException::class); + $this->expectExceptionCode(500); + $this->expectExceptionMessage('Missing required properties: merchantRefNum, amount, billingDetails'); + + $dds = new DirectDebitService($this->mock_api_client); + /* + * Note: we have to at least specify an empty eft or there will be a PHP Error. + * See https://github.com/paysafegroup/paysafe_sdk_php/issues/13 + */ + $eft_credit_array = [ + 'eft' => [ ], + 'profile' => [ + 'firstName' => 'firstname', + 'lastName' => 'lastname', + ], + ]; + $dds->standaloneCredits(new StandaloneCredits($eft_credit_array)); + } + + /* + * This is a test to confirm that the DirectDebitService sets expected values for required/optional fields. If a + * parameter is set in the StandaloneCredits obj, but not in the required or optional lists, it will be omitted from + * the JSON created by toJson. (toJson is called by processRequest in the api client). + * + * So, we'll make our mock api client call toJson, and confirm the output lacks the field that doesn't appear in + * required/optional. + * + * This test omits the token and instead includes profile information. The required/optional lists are built + * slightly differently in each case + */ + public function testCreditEftNoTokenInvalidField() + { + $this->mock_api_client + ->expects($this->once()) + ->method('processRequest') + ->with($this->isInstanceOf(Request::class)) + ->will($this->returnCallback(function (Request $param) { + return json_decode($param->body->toJson(), true); + })); + $dds = new DirectDebitService($this->mock_api_client); + + $eft_credit_array = [ + 'id' => 'id is a valid param, but not in required or optional list', + 'eft' => [ + 'accountHolderName' => 'accountHolderName', + ], + 'profile' => [ + 'firstName' => 'firstname', + 'lastName' => 'lastname', + ], + 'merchantRefNum' => 'merchantrefnum', + 'amount' => 555, + 'billingDetails' => [ + 'zip' => '10007', + ], + ]; + + $retval = $dds->standaloneCredits(new StandaloneCredits($eft_credit_array)); + $param_no_id = $eft_credit_array; + unset($param_no_id['id']); + $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), + 'Did not receive expected return from DirectDebitService::standaloneCredits'); + } + + /* + * This is a test to confirm that the DirectDebitService sets expected values for required/optional fields. If a + * parameter is set in the StandaloneCredits obj, but not in the required or optional lists, it will be omitted from + * the JSON created by toJson. (toJson is called by processRequest in the api client). + * + * So, we'll make our mock api client call toJson, and confirm the output lacks the field that doesn't appear in + * required/optional. + * + * This test includes the token and omits profile information. The required/optional lists are built + * slightly differently in each case + */ + public function testCreditEftWithTokenInvalidField() + { + $this->mock_api_client + ->expects($this->once()) + ->method('processRequest') + ->with($this->isInstanceOf(Request::class)) + ->will($this->returnCallback(function (Request $param) { + return json_decode($param->body->toJson(), true); + })); + $dds = new DirectDebitService($this->mock_api_client); + + $eft_credit_array = [ + 'id' => 'id is a valid param, but not in required or optional list', + 'eft' => [ + 'paymentToken' => 'myspecialtoken', + ], + 'merchantRefNum' => 'merchantrefnum', + 'amount' => 555, + ]; + + $retval = $dds->standaloneCredits(new StandaloneCredits($eft_credit_array)); + $param_no_id = $eft_credit_array; + unset($param_no_id['id']); + $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), + 'Did not receive expected return from DirectDebitService::standaloneCredits'); + } +} From ce5e5c2b5d638439e5bf1a4552045e00b9e8e221 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Tue, 12 Dec 2017 15:13:29 -0700 Subject: [PATCH 8/9] add splitpay property to StandaloneCredits phpdoc --- source/Paysafe/DirectDebit/StandaloneCredits.php | 1 + 1 file changed, 1 insertion(+) diff --git a/source/Paysafe/DirectDebit/StandaloneCredits.php b/source/Paysafe/DirectDebit/StandaloneCredits.php index e60c886..b436ef6 100644 --- a/source/Paysafe/DirectDebit/StandaloneCredits.php +++ b/source/Paysafe/DirectDebit/StandaloneCredits.php @@ -40,6 +40,7 @@ * @property \Paysafe\Error $error * @property string $status * @property \Paysafe\Link[] $links + * @property \Paysafe\DirectDebit\SplitPay[] $splitpay */ class StandaloneCredits extends \Paysafe\JSONObject implements \Paysafe\Pageable { From d06e25bc6108cd2f5f82a92bfa4d74bfda035aef Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Tue, 12 Dec 2017 15:15:30 -0700 Subject: [PATCH 9/9] add splitpay element to standaloneCredits fcn; test --- source/Paysafe/DirectDebitService.php | 6 +- ...irectDebitServiceStandaloneCreditsTest.php | 163 ++++++++++++++++++ 2 files changed, 167 insertions(+), 2 deletions(-) diff --git a/source/Paysafe/DirectDebitService.php b/source/Paysafe/DirectDebitService.php index dc79da1..8b8bc0d 100644 --- a/source/Paysafe/DirectDebitService.php +++ b/source/Paysafe/DirectDebitService.php @@ -399,7 +399,8 @@ private function standalonecreditsACH( DirectDebit\StandaloneCredits $standalone $standalonecredits->checkRequiredFields(); $standalonecredits->setOptionalFields(array( 'customerIp', - 'dupCheck' + 'dupCheck', + 'splitpay', )); $request = new Request(array( 'method' => Request::POST, @@ -437,7 +438,8 @@ private function standalonecreditsEFT( DirectDebit\StandaloneCredits $standalone $standalonecredits->checkRequiredFields(); $standalonecredits->setOptionalFields(array( 'customerIp', - 'dupCheck' + 'dupCheck', + 'splitpay', )); $request = new Request(array( diff --git a/tests/paysafe/DirectDebitServiceStandaloneCreditsTest.php b/tests/paysafe/DirectDebitServiceStandaloneCreditsTest.php index 95a2e41..ec8e814 100644 --- a/tests/paysafe/DirectDebitServiceStandaloneCreditsTest.php +++ b/tests/paysafe/DirectDebitServiceStandaloneCreditsTest.php @@ -200,6 +200,88 @@ public function testCreditAchWithTokenInvalidField() $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), 'Did not receive expected return from DirectDebitService::standaloneCredits'); } + + /* + * This test builds upon the information we learned in testCreditAchNoTokenInvalidField. This time, we will include + * splitpay in the param list, and we will assert that it is still present in the StandaloneCredits object returned + * by DirectDebitService::standaloneCredits -- thus confirming that standaloneCreditsACH included splitpay in the + * optional field list + */ + public function testCreditAchNoTokenWithSplitPay() + { + $this->mock_api_client + ->expects($this->once()) + ->method('processRequest') + ->with($this->isInstanceOf(Request::class)) + ->will($this->returnCallback(function (Request $param) { + return json_decode($param->body->toJson(), true); + })); + $dds = new DirectDebitService($this->mock_api_client); + + $ach_credit_array = [ + 'id' => 'id is a valid param, but not in required or optional list', + 'ach' => [ + 'accountType' => 'CHECKING', + ], + 'profile' => [ + 'firstName' => 'firstname', + 'lastName' => 'lastname', + ], + 'merchantRefNum' => 'merchantrefnum', + 'amount' => 555, + 'billingDetails' => [ + 'zip' => '10007', + ], + 'splitpay' => [[ + 'linkedAccount' => 'linkedAccount', + 'amount' => 5, + ]], + ]; + + $retval = $dds->standaloneCredits(new StandaloneCredits($ach_credit_array)); + $param_no_id = $ach_credit_array; + unset($param_no_id['id']); + $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), + 'Did not receive expected return from DirectDebitService::standaloneCredits'); + } + + /* + * This test builds upon the information we learned in testCreditAchWithTokenInvalidField. This time, we will include + * splitpay in the param list, and we will assert that it is still present in the StandaloneCredits object returned + * by DirectDebitService::standaloneCredits -- thus confirming that standaloneCreditsACH included splitpay in the + * optional field list + */ + public function testCreditAchWithTokenWithSplitPay() + { + $this->mock_api_client + ->expects($this->once()) + ->method('processRequest') + ->with($this->isInstanceOf(Request::class)) + ->will($this->returnCallback(function (Request $param) { + return json_decode($param->body->toJson(), true); + })); + $dds = new DirectDebitService($this->mock_api_client); + + $ach_credit_array = [ + 'id' => 'id is a valid param, but not in required or optional list', + 'ach' => [ + 'paymentToken' => 'myspecialtoken', + ], + 'merchantRefNum' => 'merchantrefnum', + 'amount' => 555, + 'splitpay' => [[ + 'linkedAccount' => 'linkedAccount', + 'amount' => 5, + ]], + ]; + + $retval = $dds->standaloneCredits(new StandaloneCredits($ach_credit_array)); + $param_no_id = $ach_credit_array; + unset($param_no_id['id']); + $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), + 'Did not receive expected return from DirectDebitService::standaloneCredits'); + } + /* * This is a test to confirm that the DirectDebitService sets the required parameters we expect for a * standaloneCredits call. @@ -349,4 +431,85 @@ public function testCreditEftWithTokenInvalidField() $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), 'Did not receive expected return from DirectDebitService::standaloneCredits'); } + + /* + * This test builds upon the information we learned in testCreditEftNoTokenInvalidField. This time, we will include + * splitpay in the param list, and we will assert that it is still present in the StandaloneCredits object returned + * by DirectDebitService::standaloneCredits -- thus confirming that standaloneCreditsEFT included splitpay in the + * optional field list + */ + public function testCreditEftNoTokenWithSplitPay() + { + $this->mock_api_client + ->expects($this->once()) + ->method('processRequest') + ->with($this->isInstanceOf(Request::class)) + ->will($this->returnCallback(function (Request $param) { + return json_decode($param->body->toJson(), true); + })); + $dds = new DirectDebitService($this->mock_api_client); + + $eft_credit_array = [ + 'id' => 'id is a valid param, but not in required or optional list', + 'eft' => [ + 'accountHolderName' => 'accountHolderName', + ], + 'profile' => [ + 'firstName' => 'firstname', + 'lastName' => 'lastname', + ], + 'merchantRefNum' => 'merchantrefnum', + 'amount' => 555, + 'billingDetails' => [ + 'zip' => '10007', + ], + 'splitpay' => [[ + 'linkedAccount' => 'linkedAccount', + 'amount' => 5, + ]], + ]; + + $retval = $dds->standaloneCredits(new StandaloneCredits($eft_credit_array)); + $param_no_id = $eft_credit_array; + unset($param_no_id['id']); + $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), + 'Did not receive expected return from DirectDebitService::standaloneCredits'); + } + + /* + * This test builds upon the information we learned in testCreditEftWithTokenInvalidField. This time, we will include + * splitpay in the param list, and we will assert that it is still present in the StandaloneCredits object returned + * by DirectDebitService::standaloneCredits -- thus confirming that standaloneCreditsEFT included splitpay in the + * optional field list + */ + public function testCreditEftWithTokenWithSplitPay() + { + $this->mock_api_client + ->expects($this->once()) + ->method('processRequest') + ->with($this->isInstanceOf(Request::class)) + ->will($this->returnCallback(function (Request $param) { + return json_decode($param->body->toJson(), true); + })); + $dds = new DirectDebitService($this->mock_api_client); + + $eft_credit_array = [ + 'id' => 'id is a valid param, but not in required or optional list', + 'eft' => [ + 'paymentToken' => 'myspecialtoken', + ], + 'merchantRefNum' => 'merchantrefnum', + 'amount' => 555, + 'splitpay' => [[ + 'linkedAccount' => 'linkedAccount', + 'amount' => 5, + ]], + ]; + + $retval = $dds->standaloneCredits(new StandaloneCredits($eft_credit_array)); + $param_no_id = $eft_credit_array; + unset($param_no_id['id']); + $this->assertThat($retval->toJson(), $this->equalTo(json_encode($param_no_id)), + 'Did not receive expected return from DirectDebitService::standaloneCredits'); + } }