Skip to content

Commit

Permalink
Changes generated by 0fe868312ff4790bf641573f71b0ec4478393e43
Browse files Browse the repository at this point in the history
This commit was automatically created from gocardless/gocardless-pro-php-template@0fe8683
by the `push-files` action.

Workflow run: https://github.com/gocardless/gocardless-pro-php-template/actions/runs/12713595863
  • Loading branch information
gocardless-ci-robot[bot] committed Jan 10, 2025
1 parent dde41d5 commit dd34c08
Show file tree
Hide file tree
Showing 32 changed files with 317 additions and 83 deletions.
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
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-20T09:38:46.389Z","expires_at":"2024-12-20T09:38:46.389Z","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-10T16:45:29.221Z","expires_at":"2025-01-10T16:45:29.221Z","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-20T09:38:46.389Z","expires_at":"2024-12-20T09:38:46.389Z","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-10T16:45:29.221Z","expires_at":"2025-01-10T16:45:29.221Z","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"}}
}
}

4 changes: 2 additions & 2 deletions tests/fixtures/billing_request_flows.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
"method": "POST",
"path_template": "/billing_request_flows",
"url_params": {},
"body": {"billing_request_flows":{"authorisation_url":"https://monzo.com/abc-123-things","auto_fulfil":false,"created_at":"2024-12-20T09:38:46.401Z","customer_details_captured":true,"exit_uri":"https://my-website.com/abc/callback","expires_at":"2024-12-20T09:38:46.401Z","id":"BRF123","language":"en","links":{"billing_request":"BRQ123"},"lock_bank_account":true,"lock_currency":true,"lock_customer_details":false,"prefilled_bank_account":{"account_type":"savings"},"prefilled_customer":{"address_line1":"221B Baker Street","address_line2":"Marylebone","address_line3":"City of Westminster","city":"London","company_name":"Hamilton Trading Ltd.","country_code":"GB","danish_identity_number":"220550-6218","email":"[email protected]","family_name":"Osborne","given_name":"Frank","postal_code":"NW1 6XE","region":"Greater London","swedish_identity_number":"556564-5404"},"redirect_uri":"https://my-website.com/abc/callback","session_token":"sesh_123","show_redirect_buttons":true,"show_success_redirect_button":false,"skip_success_screen":false}}
"body": {"billing_request_flows":{"authorisation_url":"https://monzo.com/abc-123-things","auto_fulfil":true,"created_at":"2025-01-10T16:45:29.226Z","customer_details_captured":true,"exit_uri":"https://my-website.com/abc/callback","expires_at":"2025-01-10T16:45:29.226Z","id":"BRF123","language":"en","links":{"billing_request":"BRQ123"},"lock_bank_account":false,"lock_currency":false,"lock_customer_details":false,"prefilled_bank_account":{"account_type":"savings"},"prefilled_customer":{"address_line1":"221B Baker Street","address_line2":"Marylebone","address_line3":"City of Westminster","city":"London","company_name":"Hamilton Trading Ltd.","country_code":"GB","danish_identity_number":"220550-6218","email":"[email protected]","family_name":"Osborne","given_name":"Frank","postal_code":"NW1 6XE","region":"Greater London","swedish_identity_number":"556564-5404"},"redirect_uri":"https://my-website.com/abc/callback","session_token":"sesh_123","show_redirect_buttons":true,"show_success_redirect_button":true,"skip_success_screen":false}}
},
"initialise": {
"method": "POST",
"path_template": "/billing_request_flows/:identity/actions/initialise",
"url_params": {"identity": "BRF123"},
"body": {"billing_request_flows":{"authorisation_url":"https://monzo.com/abc-123-things","auto_fulfil":true,"created_at":"2024-12-20T09:38:46.401Z","customer_details_captured":true,"exit_uri":"https://my-website.com/abc/callback","expires_at":"2024-12-20T09:38:46.401Z","id":"BRF123","language":"en","links":{"billing_request":"BRQ123"},"lock_bank_account":false,"lock_currency":false,"lock_customer_details":true,"prefilled_bank_account":{"account_type":"savings"},"prefilled_customer":{"address_line1":"221B Baker Street","address_line2":"Marylebone","address_line3":"City of Westminster","city":"London","company_name":"Hamilton Trading Ltd.","country_code":"GB","danish_identity_number":"220550-6218","email":"[email protected]","family_name":"Osborne","given_name":"Frank","postal_code":"NW1 6XE","region":"Greater London","swedish_identity_number":"556564-5404"},"redirect_uri":"https://my-website.com/abc/callback","session_token":"sesh_123","show_redirect_buttons":false,"show_success_redirect_button":true,"skip_success_screen":false}}
"body": {"billing_request_flows":{"authorisation_url":"https://monzo.com/abc-123-things","auto_fulfil":false,"created_at":"2025-01-10T16:45:29.227Z","customer_details_captured":false,"exit_uri":"https://my-website.com/abc/callback","expires_at":"2025-01-10T16:45:29.227Z","id":"BRF123","language":"en","links":{"billing_request":"BRQ123"},"lock_bank_account":false,"lock_currency":true,"lock_customer_details":false,"prefilled_bank_account":{"account_type":"savings"},"prefilled_customer":{"address_line1":"221B Baker Street","address_line2":"Marylebone","address_line3":"City of Westminster","city":"London","company_name":"Hamilton Trading Ltd.","country_code":"GB","danish_identity_number":"220550-6218","email":"[email protected]","family_name":"Osborne","given_name":"Frank","postal_code":"NW1 6XE","region":"Greater London","swedish_identity_number":"556564-5404"},"redirect_uri":"https://my-website.com/abc/callback","session_token":"sesh_123","show_redirect_buttons":true,"show_success_redirect_button":true,"skip_success_screen":true}}
}
}

Loading

0 comments on commit dd34c08

Please sign in to comment.