diff --git a/src/Endpoints/MethodIssuerEndpoint.php b/src/Endpoints/MethodIssuerEndpoint.php new file mode 100644 index 00000000..2cb661b9 --- /dev/null +++ b/src/Endpoints/MethodIssuerEndpoint.php @@ -0,0 +1,85 @@ +profileId = $profileId; + $this->methodId = $methodId; + $this->issuerId = $issuerId; + + $response = $this->rest_create([], []); + + $this->resetResourceIds(); + + return $response; + } + + public function disable(string $profileId, string $methodId, string $issuerId) + { + $this->profileId = $profileId; + $this->methodId = $methodId; + + return $this->rest_delete($issuerId); + } + + protected function resetResourceIds() + { + $this->profileId = null; + $this->methodId = null; + $this->issuerId = null; + } + + /** + * @return string + * @throws ApiException + */ + public function getResourcePath() + { + if (! $this->profileId) { + throw new ApiException("No profileId provided."); + } + + if (! $this->methodId) { + throw new ApiException("No methodId provided."); + } + + $path = "profiles/{$this->profileId}/methods/{$this->methodId}/issuers"; + + if ($this->issuerId) { + $path .= "/$this->issuerId"; + } + + return $path; + } + + /** + * Get the object that is used by this API endpoint. Every API endpoint uses one type of object. + * + * @return Issuer + */ + protected function getResourceObject() + { + return new Issuer($this->client); + } +} diff --git a/src/Endpoints/SubscriptionPaymentEndpoint.php b/src/Endpoints/SubscriptionPaymentEndpoint.php new file mode 100644 index 00000000..b65e0682 --- /dev/null +++ b/src/Endpoints/SubscriptionPaymentEndpoint.php @@ -0,0 +1,79 @@ +customerId = $customerId; + $this->subscriptionId = $subscriptionId; + + return $this->rest_list($from, $limit, $parameters); + } + + /** + * Get the object that is used by this API endpoint. Every API endpoint uses one type of object. + * + * @return Payment + */ + protected function getResourceObject() + { + return new Payment($this->client); + } + + /** + * Get the collection object that is used by this API endpoint. Every API endpoint uses one type of collection object. + * + * @param int $count + * @param \stdClass $_links + * + * @return PaymentCollection + */ + protected function getResourceCollectionObject($count, $_links) + { + return new PaymentCollection($this->client, $count, $_links); + } + + public function getResourcePath() + { + if (is_null($this->customerId)) { + throw new ApiException('No customerId provided.'); + } + + if (is_null($this->subscriptionId)) { + throw new ApiException('No subscriptionId provided.'); + } + + return "customers/{$this->customerId}/subscriptions/{$this->subscriptionId}/payments"; + } +} diff --git a/src/MollieApiClient.php b/src/MollieApiClient.php index c5b3f3f5..d78ccf24 100644 --- a/src/MollieApiClient.php +++ b/src/MollieApiClient.php @@ -13,6 +13,7 @@ use Mollie\Api\Endpoints\InvoiceEndpoint; use Mollie\Api\Endpoints\MandateEndpoint; use Mollie\Api\Endpoints\MethodEndpoint; +use Mollie\Api\Endpoints\MethodIssuerEndpoint; use Mollie\Api\Endpoints\OnboardingEndpoint; use Mollie\Api\Endpoints\OrderEndpoint; use Mollie\Api\Endpoints\OrderLineEndpoint; @@ -38,6 +39,7 @@ use Mollie\Api\Endpoints\SettlementsEndpoint; use Mollie\Api\Endpoints\ShipmentEndpoint; use Mollie\Api\Endpoints\SubscriptionEndpoint; +use Mollie\Api\Endpoints\SubscriptionPaymentEndpoint; use Mollie\Api\Endpoints\TerminalEndpoint; use Mollie\Api\Endpoints\WalletEndpoint; use Mollie\Api\Exceptions\ApiException; @@ -100,6 +102,11 @@ class MollieApiClient */ public $profileMethods; + /** + * @var \Mollie\Api\Endpoints\MethodIssuerEndpoint + */ + public $methodIssuers; + /** * RESTful Customers resource. * @@ -156,6 +163,13 @@ class MollieApiClient */ public $subscriptions; + /** + * RESTful Subscription Payments resource. + * + * @var SubscriptionPaymentEndpoint + */ + public $subscriptionPayments; + /** * RESTful Mandate resource. * @@ -403,6 +417,7 @@ public function initializeEndpoints() $this->invoices = new InvoiceEndpoint($this); $this->mandates = new MandateEndpoint($this); $this->methods = new MethodEndpoint($this); + $this->methodIssuers = new MethodIssuerEndpoint($this); $this->onboarding = new OnboardingEndpoint($this); $this->orderLines = new OrderLineEndpoint($this); $this->orderPayments = new OrderPaymentEndpoint($this); @@ -427,6 +442,7 @@ public function initializeEndpoints() $this->settlementRefunds = new SettlementRefundEndpoint($this); $this->settlements = new SettlementsEndpoint($this); $this->shipments = new ShipmentEndpoint($this); + $this->subscriptionPayments = new SubscriptionPaymentEndpoint($this); $this->subscriptions = new SubscriptionEndpoint($this); $this->terminals = new TerminalEndpoint($this); $this->wallets = new WalletEndpoint($this); diff --git a/tests/Mollie/API/Endpoints/MethodIssuerEndpointTest.php b/tests/Mollie/API/Endpoints/MethodIssuerEndpointTest.php new file mode 100644 index 00000000..a251c2b1 --- /dev/null +++ b/tests/Mollie/API/Endpoints/MethodIssuerEndpointTest.php @@ -0,0 +1,57 @@ +mockApiCall( + new Request( + 'POST', + 'https://api.mollie.com/v2/profiles/pfl_QkEhN94Ba/methods/ideal/issuers/festivalcadeau' + ), + new Response( + 201, + [], + '{ + "resource": "issuer", + "id": "festivalcadeau", + "name": "Festival Cadeau", + "method": "ideal", + "image": { + "size1x": "https://www.mollie.com/images/payscreen/methods/ideal.png", + "size2x": "https://www.mollie.com/images/payscreen/methods/ideal%402x.png" + } + }' + ) + ); + + $response = $this->apiClient->methodIssuers->enable('pfl_QkEhN94Ba', 'ideal', 'festivalcadeau'); + $this->assertInstanceOf(Issuer::class, $response); + $this->assertEquals('festivalcadeau', $response->id); + } + + /** @test */ + public function testDisableIssuer() + { + $this->mockApiCall( + new Request( + 'DELETE', + 'https://api.mollie.com/v2/profiles/pfl_QkEhN94Ba/methods/ideal/issuers/festivalcadeau' + ), + new Response(204) + ); + + $response = $this->apiClient->methodIssuers->disable('pfl_QkEhN94Ba', 'ideal', 'festivalcadeau'); + + $this->assertNull($response); + } +} diff --git a/tests/Mollie/API/Endpoints/SubscriptionPaymentEndpointTest.php b/tests/Mollie/API/Endpoints/SubscriptionPaymentEndpointTest.php new file mode 100644 index 00000000..72991f1a --- /dev/null +++ b/tests/Mollie/API/Endpoints/SubscriptionPaymentEndpointTest.php @@ -0,0 +1,86 @@ +mockApiCall( + new Request( + 'GET', + '/v2/customers/cst_stTC2WHAuS/subscriptions/sub_8JfGzs6v3K/payments?limit=25' + ), + new Response( + 200, + [], + '{ + "count": 1, + "_embedded": { + "payments": [ + { + "resource": "payment", + "id": "tr_7UhSN1zuXS", + "mode": "live", + "amount": { + "currency": "EUR", + "value": "25.00" + }, + "description": "Quarterly payment", + "method": "creditcard", + "sequenceType": "recurring", + "status": "paid", + "isCancelable": false, + "webhookUrl": "https://webshop.example.org/payments/webhook", + "profileId": "pfl_QkEhN94Ba", + "customerId": "cst_stTC2WHAuS", + "mandateId": "mdt_38HS4fsS", + "createdAt": "2023-09-01T03:58:35.0Z", + "paidAt": "2023-09-01T04:02:01.0Z", + "_links": { + "self": { + "href": "...", + "type": "application/hal+json" + }, + "dashboard": { + "href": "https://www.mollie.com/dashboard/org_12345678/payments/tr_7UhSN1zuXS", + "type": "text/html" + } + } + } + ] + }, + "_links": { + "self": { + "href": "https://api.mollie.com/v2/customers/cst_stTC2WHAuS/subscriptions/sub_8JfGzs6v3K/payments?limit=25", + "type": "application/hal+json" + }, + "previous": null, + "next": null, + "documentation": { + "href": "https://docs.mollie.com/reference/list-subscription-payments", + "type": "text/html" + } + } + }' + ) + ); + + $response = $this->apiClient->subscriptionPayments->pageForIds( + 'cst_stTC2WHAuS', + 'sub_8JfGzs6v3K', + null, + 25 + ); + + $this->assertInstanceOf(PaymentCollection::class, $response); + } +}