Skip to content

Commit

Permalink
Merge pull request #196 from gocardless/template-changes
Browse files Browse the repository at this point in the history
Changes from gocardless/gocardless-pro-php-template
  • Loading branch information
barrucadu authored Jan 28, 2025
2 parents aa05f91 + 05e3a68 commit 4434a05
Show file tree
Hide file tree
Showing 36 changed files with 332 additions and 87 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "gocardless/gocardless-pro",
"description": "GoCardless Pro PHP Client Library",
"version": "6.1.0",
"version": "6.2.0",
"keywords": [
"gocardless",
"direct debit",
Expand Down
4 changes: 2 additions & 2 deletions lib/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ public function __construct($config)
'Content-Type' => 'application/json',
'Authorization' => "Bearer " . $access_token,
'GoCardless-Client-Library' => 'gocardless-pro-php',
'GoCardless-Client-Version' => '6.1.0',
'GoCardless-Client-Version' => '6.2.0',
'User-Agent' => $this->getUserAgent()
),
'http_errors' => false,
Expand Down Expand Up @@ -664,7 +664,7 @@ private function getUserAgent()
{
$curlinfo = curl_version();
$uagent = array();
$uagent[] = 'gocardless-pro-php/6.1.0';
$uagent[] = 'gocardless-pro-php/6.2.0';
$uagent[] = 'schema-version/2015-07-06';
if (defined('\GuzzleHttp\Client::MAJOR_VERSION')) {
$uagent[] = 'GuzzleHttp/' . \GuzzleHttp\Client::MAJOR_VERSION;
Expand Down
6 changes: 6 additions & 0 deletions lib/Resources/MandateImportEntry.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*
* @property-read mixed $created_at
* @property-read mixed $links
* @property-read mixed $processing_errors
* @property-read mixed $record_identifier
*/
class MandateImportEntry extends BaseResource
Expand All @@ -30,6 +31,11 @@ class MandateImportEntry extends BaseResource
*/
protected $links;

/**
* Per-resource processing errors
*/
protected $processing_errors;

/**
* A unique identifier for this entry, which you can use (once the import
* has been
Expand Down
70 changes: 70 additions & 0 deletions lib/Services/BillingRequestsService.php
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,76 @@ public function create($params = array())
return $this->getResourceForResponse($response);
}

/**
* [ACH/PAD only] Create a Billing Request with instalments (with dates)
*
* Example URL: /billing_requests
*
* @param array<string, mixed> $params An associative array for any params
* @return BillingRequest
**/
public function createWithInstalmentsWithDates($params = array())
{
$path = "/billing_requests";
if(isset($params['params'])) {
$params['body'] = json_encode(array($this->envelope_key => (object)$params['params']));

unset($params['params']);
}


try {
$response = $this->api_client->post($path, $params);
} catch(InvalidStateException $e) {
if ($e->isIdempotentCreationConflict()) {
if ($this->api_client->error_on_idempotency_conflict) {
throw $e;
}
return $this->get($e->getConflictingResourceId());
}

throw $e;
}


return $this->getResourceForResponse($response);
}

/**
* [ACH/PAD only] Create a Billing Request with instalments (with schedule)
*
* Example URL: /billing_requests
*
* @param array<string, mixed> $params An associative array for any params
* @return BillingRequest
**/
public function createWithInstalmentsWithSchedule($params = array())
{
$path = "/billing_requests";
if(isset($params['params'])) {
$params['body'] = json_encode(array($this->envelope_key => (object)$params['params']));

unset($params['params']);
}


try {
$response = $this->api_client->post($path, $params);
} catch(InvalidStateException $e) {
if ($e->isIdempotentCreationConflict()) {
if ($this->api_client->error_on_idempotency_conflict) {
throw $e;
}
return $this->get($e->getConflictingResourceId());
}

throw $e;
}


return $this->getResourceForResponse($response);
}

/**
* Collect customer details
*
Expand Down
152 changes: 152 additions & 0 deletions tests/Integration/BillingRequestsIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,158 @@ public function testBillingRequestsCreateWithIdempotencyConflict()
$this->assertEquals($getRequest->getUri()->getPath(), '/billing_requests/ID123');
}

public function testBillingRequestsCreateWithInstalmentsWithDates()
{
$fixture = $this->loadJsonFixture('billing_requests')->create_with_instalments_with_dates;
$this->stub_request($fixture);

$service = $this->client->billingRequests();
$response = call_user_func_array(array($service, 'createWithInstalmentsWithDates'), (array)$fixture->url_params);

$body = $fixture->body->billing_requests;

$this->assertInstanceOf('\GoCardlessPro\Resources\BillingRequest', $response);

$this->assertEquals($body->actions, $response->actions);
$this->assertEquals($body->created_at, $response->created_at);
$this->assertEquals($body->fallback_enabled, $response->fallback_enabled);
$this->assertEquals($body->fallback_occurred, $response->fallback_occurred);
$this->assertEquals($body->id, $response->id);
$this->assertEquals($body->instalment_schedule_request, $response->instalment_schedule_request);
$this->assertEquals($body->links, $response->links);
$this->assertEquals($body->mandate_request, $response->mandate_request);
$this->assertEquals($body->metadata, $response->metadata);
$this->assertEquals($body->payment_request, $response->payment_request);
$this->assertEquals($body->purpose_code, $response->purpose_code);
$this->assertEquals($body->resources, $response->resources);
$this->assertEquals($body->status, $response->status);
$this->assertEquals($body->subscription_request, $response->subscription_request);


$expectedPathRegex = $this->extract_resource_fixture_path_regex($fixture);
$dispatchedRequest = $this->history[0]['request'];
$this->assertMatchesRegularExpression($expectedPathRegex, $dispatchedRequest->getUri()->getPath());
}

public function testBillingRequestsCreateWithInstalmentsWithDatesWithIdempotencyConflict()
{
$fixture = $this->loadJsonFixture('billing_requests')->create_with_instalments_with_dates;

$idempotencyConflictResponseFixture = $this->loadFixture('idempotent_creation_conflict_invalid_state_error');

// The POST request responds with a 409 to our original POST, due to an idempotency conflict
$this->mock->append(new \GuzzleHttp\Psr7\Response(409, [], $idempotencyConflictResponseFixture));

// The client makes a second request to fetch the resource that was already
// created using our idempotency key. It responds with the created resource,
// which looks just like the response for a successful POST request.
$this->mock->append(new \GuzzleHttp\Psr7\Response(200, [], json_encode($fixture->body)));

$service = $this->client->billingRequests();
$response = call_user_func_array(array($service, 'createWithInstalmentsWithDates'), (array)$fixture->url_params);
$body = $fixture->body->billing_requests;

$this->assertInstanceOf('\GoCardlessPro\Resources\BillingRequest', $response);

$this->assertEquals($body->actions, $response->actions);
$this->assertEquals($body->created_at, $response->created_at);
$this->assertEquals($body->fallback_enabled, $response->fallback_enabled);
$this->assertEquals($body->fallback_occurred, $response->fallback_occurred);
$this->assertEquals($body->id, $response->id);
$this->assertEquals($body->instalment_schedule_request, $response->instalment_schedule_request);
$this->assertEquals($body->links, $response->links);
$this->assertEquals($body->mandate_request, $response->mandate_request);
$this->assertEquals($body->metadata, $response->metadata);
$this->assertEquals($body->payment_request, $response->payment_request);
$this->assertEquals($body->purpose_code, $response->purpose_code);
$this->assertEquals($body->resources, $response->resources);
$this->assertEquals($body->status, $response->status);
$this->assertEquals($body->subscription_request, $response->subscription_request);


$expectedPathRegex = $this->extract_resource_fixture_path_regex($fixture);
$conflictRequest = $this->history[0]['request'];
$this->assertMatchesRegularExpression($expectedPathRegex, $conflictRequest->getUri()->getPath());
$getRequest = $this->history[1]['request'];
$this->assertEquals($getRequest->getUri()->getPath(), '/billing_requests/ID123');
}

public function testBillingRequestsCreateWithInstalmentsWithSchedule()
{
$fixture = $this->loadJsonFixture('billing_requests')->create_with_instalments_with_schedule;
$this->stub_request($fixture);

$service = $this->client->billingRequests();
$response = call_user_func_array(array($service, 'createWithInstalmentsWithSchedule'), (array)$fixture->url_params);

$body = $fixture->body->billing_requests;

$this->assertInstanceOf('\GoCardlessPro\Resources\BillingRequest', $response);

$this->assertEquals($body->actions, $response->actions);
$this->assertEquals($body->created_at, $response->created_at);
$this->assertEquals($body->fallback_enabled, $response->fallback_enabled);
$this->assertEquals($body->fallback_occurred, $response->fallback_occurred);
$this->assertEquals($body->id, $response->id);
$this->assertEquals($body->instalment_schedule_request, $response->instalment_schedule_request);
$this->assertEquals($body->links, $response->links);
$this->assertEquals($body->mandate_request, $response->mandate_request);
$this->assertEquals($body->metadata, $response->metadata);
$this->assertEquals($body->payment_request, $response->payment_request);
$this->assertEquals($body->purpose_code, $response->purpose_code);
$this->assertEquals($body->resources, $response->resources);
$this->assertEquals($body->status, $response->status);
$this->assertEquals($body->subscription_request, $response->subscription_request);


$expectedPathRegex = $this->extract_resource_fixture_path_regex($fixture);
$dispatchedRequest = $this->history[0]['request'];
$this->assertMatchesRegularExpression($expectedPathRegex, $dispatchedRequest->getUri()->getPath());
}

public function testBillingRequestsCreateWithInstalmentsWithScheduleWithIdempotencyConflict()
{
$fixture = $this->loadJsonFixture('billing_requests')->create_with_instalments_with_schedule;

$idempotencyConflictResponseFixture = $this->loadFixture('idempotent_creation_conflict_invalid_state_error');

// The POST request responds with a 409 to our original POST, due to an idempotency conflict
$this->mock->append(new \GuzzleHttp\Psr7\Response(409, [], $idempotencyConflictResponseFixture));

// The client makes a second request to fetch the resource that was already
// created using our idempotency key. It responds with the created resource,
// which looks just like the response for a successful POST request.
$this->mock->append(new \GuzzleHttp\Psr7\Response(200, [], json_encode($fixture->body)));

$service = $this->client->billingRequests();
$response = call_user_func_array(array($service, 'createWithInstalmentsWithSchedule'), (array)$fixture->url_params);
$body = $fixture->body->billing_requests;

$this->assertInstanceOf('\GoCardlessPro\Resources\BillingRequest', $response);

$this->assertEquals($body->actions, $response->actions);
$this->assertEquals($body->created_at, $response->created_at);
$this->assertEquals($body->fallback_enabled, $response->fallback_enabled);
$this->assertEquals($body->fallback_occurred, $response->fallback_occurred);
$this->assertEquals($body->id, $response->id);
$this->assertEquals($body->instalment_schedule_request, $response->instalment_schedule_request);
$this->assertEquals($body->links, $response->links);
$this->assertEquals($body->mandate_request, $response->mandate_request);
$this->assertEquals($body->metadata, $response->metadata);
$this->assertEquals($body->payment_request, $response->payment_request);
$this->assertEquals($body->purpose_code, $response->purpose_code);
$this->assertEquals($body->resources, $response->resources);
$this->assertEquals($body->status, $response->status);
$this->assertEquals($body->subscription_request, $response->subscription_request);


$expectedPathRegex = $this->extract_resource_fixture_path_regex($fixture);
$conflictRequest = $this->history[0]['request'];
$this->assertMatchesRegularExpression($expectedPathRegex, $conflictRequest->getUri()->getPath());
$getRequest = $this->history[1]['request'];
$this->assertEquals($getRequest->getUri()->getPath(), '/billing_requests/ID123');
}

public function testBillingRequestsCollectCustomerDetails()
{
$fixture = $this->loadJsonFixture('billing_requests')->collect_customer_details;
Expand Down
5 changes: 5 additions & 0 deletions tests/Integration/MandateImportEntriesIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public function testMandateImportEntriesCreate()

$this->assertEquals($body->created_at, $response->created_at);
$this->assertEquals($body->links, $response->links);
$this->assertEquals($body->processing_errors, $response->processing_errors);
$this->assertEquals($body->record_identifier, $response->record_identifier);


Expand Down Expand Up @@ -68,6 +69,10 @@ public function testMandateImportEntriesList()
$this->assertEquals($body[$num]->links, $record->links);
}

if (isset($body[$num]->processing_errors)) {
$this->assertEquals($body[$num]->processing_errors, $record->processing_errors);
}

if (isset($body[$num]->record_identifier)) {
$this->assertEquals($body[$num]->record_identifier, $record->record_identifier);
}
Expand Down
4 changes: 2 additions & 2 deletions tests/fixtures/bank_authorisations.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
"method": "POST",
"path_template": "/bank_authorisations",
"url_params": {},
"body": {"bank_authorisations":{"authorisation_type":"example authorisation_type 8081","authorised_at":"2020-01-01T12:00:00.000Z","created_at":"2024-12-02T16:42:36.882Z","expires_at":"2024-12-02T16:42:36.882Z","id":"BAU123","last_visited_at":"2020-01-01T12:00:00.000Z","links":{"billing_request":"BRQ123","institution":"monzo"},"qr_code_url":"https://pay.gocardless.com/obauth/BAU123/qr_code","redirect_uri":"https://my-website.com/abc/callback","url":"https://pay.gocardless.com/obauth/BAU123"}}
"body": {"bank_authorisations":{"authorisation_type":"example authorisation_type 8081","authorised_at":"2020-01-01T12:00:00.000Z","created_at":"2025-01-27T15:00:29.881Z","expires_at":"2025-01-27T15:00:29.881Z","id":"BAU123","last_visited_at":"2020-01-01T12:00:00.000Z","links":{"billing_request":"BRQ123","institution":"monzo"},"qr_code_url":"https://pay.gocardless.com/obauth/BAU123/qr_code","redirect_uri":"https://my-website.com/abc/callback","url":"https://pay.gocardless.com/obauth/BAU123"}}
},
"get": {
"method": "GET",
"path_template": "/bank_authorisations/:identity",
"url_params": {"identity": "BAU123"},
"body": {"bank_authorisations":{"authorisation_type":"example authorisation_type 7887","authorised_at":"2020-01-01T12:00:00.000Z","created_at":"2024-12-02T16:42:36.882Z","expires_at":"2024-12-02T16:42:36.882Z","id":"BAU123","last_visited_at":"2020-01-01T12:00:00.000Z","links":{"billing_request":"BRQ123","institution":"monzo"},"qr_code_url":"https://pay.gocardless.com/obauth/BAU123/qr_code","redirect_uri":"https://my-website.com/abc/callback","url":"https://pay.gocardless.com/obauth/BAU123"}}
"body": {"bank_authorisations":{"authorisation_type":"example authorisation_type 7887","authorised_at":"2020-01-01T12:00:00.000Z","created_at":"2025-01-27T15:00:29.881Z","expires_at":"2025-01-27T15:00:29.881Z","id":"BAU123","last_visited_at":"2020-01-01T12:00:00.000Z","links":{"billing_request":"BRQ123","institution":"monzo"},"qr_code_url":"https://pay.gocardless.com/obauth/BAU123/qr_code","redirect_uri":"https://my-website.com/abc/callback","url":"https://pay.gocardless.com/obauth/BAU123"}}
}
}

Loading

0 comments on commit 4434a05

Please sign in to comment.