Skip to content

Commit 39833ab

Browse files
authored
feat(PAR-427): Throw new Canceled exception when trying to capture a payment intent that is already cancelled (#14)
* feat(PAR-427): Throw new `Canceled` exception when trying to capture a payment intent that is already cancelled * chore(PAR-427): Formatting
1 parent 3d8cdb9 commit 39833ab

4 files changed

Lines changed: 37 additions & 11 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ composer require pod-point/payments-php
1616

1717
## Usage
1818

19-
When performing actions using a payment service, a provider-specific exception will be thrown if it's requirements to perform that action are not met. This exception will contain the data received from the provider which can be used by the consuming application to resolve any issues.
19+
When performing actions using a payment service, a provider-specific exception will be thrown if it's requirements to perform that action are not met. This exception will contain the data received from the provider which can be used by the consuming application to resolve any issues.
2020

2121
For example, when trying to make a payment with the Stripe payment service, if authorisation is required, an exception will be thrown with a "payment intent" object which can be used by a clients Stripe SDK to carry out the authorisation.
2222

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace PodPoint\Payments\Providers\Stripe\Payment;
4+
5+
class Canceled extends \Exception
6+
{
7+
public function __construct()
8+
{
9+
parent::__construct('Unable to create payment: The stripe PaymentIntent is already cancelled.');
10+
}
11+
}

src/Providers/Stripe/Payment/Service.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ public function reserve(
162162
);
163163
}
164164

165+
public function retrievePaymentIntent(string $token): PaymentIntent
166+
{
167+
return PaymentIntent::retrieve($token);
168+
}
169+
165170
/**
166171
* Tries to capture funds on a payment intent using the Stripe SDK.
167172
*
@@ -171,13 +176,17 @@ public function reserve(
171176
* @return Payment
172177
*
173178
* @throws AmountTooLarge
179+
* @throws Canceled
174180
* @throws InvalidRequest
175181
* @throws InvalidToken
176182
*/
177183
public function capture(Token $token, int $amount): Payment
178184
{
179185
if ($token->type === StripeToken::PAYMENT_INTENT) {
180-
$intent = PaymentIntent::retrieve($token->value);
186+
$intent = $this->retrievePaymentIntent($token->value);
187+
if ($intent->status == 'canceled') {
188+
throw new Canceled();
189+
}
181190

182191
try {
183192
$response = $intent->capture([

tests/Providers/Stripe/Payment/ServiceTest.php

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
use PodPoint\Payments\Payment;
77
use PodPoint\Payments\Providers\Stripe\Customer\Service as CustomerService;
88
use PodPoint\Payments\Providers\Stripe\Payment\AmountTooLarge;
9+
use PodPoint\Payments\Providers\Stripe\Payment\Canceled;
910
use PodPoint\Payments\Providers\Stripe\Payment\Exception as StripeException;
1011
use PodPoint\Payments\Providers\Stripe\Payment\Service;
1112
use PodPoint\Payments\Providers\Stripe\Refund\Service as RefundService;
1213
use PodPoint\Payments\Providers\Stripe\Token;
1314
use PodPoint\Payments\Tests\TestCase;
15+
use Stripe\PaymentIntent;
1416

1517
class ServiceTest extends TestCase
1618
{
@@ -271,19 +273,23 @@ public function testCorrectExceptionIsThrownWhenCaptureAmountIsHigherThanReserve
271273
*/
272274
public function testPaymentIntentCanBeCancelled()
273275
{
274-
$amount = 1000;
275-
$paymentMethodToken = new Token('pm_card_visa');
276+
$mockPaymentIntent = new PaymentIntent();
277+
$mockPaymentIntent->status = 'canceled';
276278

277-
$payment = $this->service->reserve(
278-
$paymentMethodToken,
279-
$amount
280-
);
279+
$mockService = $this->getMockBuilder(Service::class)
280+
->setMethodsExcept(['capture'])
281+
->disableOriginalConstructor()
282+
->getMock();
281283

282-
$paymentIntentToken = new Token($payment->uid);
284+
$mockService->expects($this->once())
285+
->method('retrievePaymentIntent')
286+
->willReturn($mockPaymentIntent);
283287

284-
$cancelledPayment = $this->service->cancel($paymentIntentToken);
288+
$this->expectException(Canceled::class);
285289

286-
$this->assertEquals($amount, $cancelledPayment->amount);
290+
$token = new Token('some-uid');
291+
$token->type = Token::PAYMENT_INTENT;
292+
$mockService->capture($token, 20);
287293
}
288294

289295
/**

0 commit comments

Comments
 (0)