Skip to content

Commit

Permalink
Feature/swp 2866 (#12)
Browse files Browse the repository at this point in the history
* WIP.

* adding tests.

* fixing bad merge.

* fixing lint
using cancellation reason in data provider to test them all.

* removing extra line.

* removing the constant for the cancel reason (cause we are always gonna use abandonned)
- fixing order of imports.
  • Loading branch information
adteulade authored May 24, 2021
1 parent 6c9c9b2 commit 3d8cdb9
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 19 deletions.
13 changes: 11 additions & 2 deletions src/Payment/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

namespace PodPoint\Payments\Payment;

use PodPoint\Payments\Card\Service as CardService;
use PodPoint\Payments\Customer\Service as CustomerService;
use PodPoint\Payments\Exceptions\InvalidToken;
use PodPoint\Payments\Payment;
use PodPoint\Payments\Customer\Service as CustomerService;
use PodPoint\Payments\Providers\Stripe\Payment\AmountTooLarge;
use PodPoint\Payments\Providers\Stripe\Payment\Exception;
use PodPoint\Payments\Refund\Service as RefundService;
use PodPoint\Payments\Card\Service as CardService;
use PodPoint\Payments\Token;
use Stripe\Error\InvalidRequest;

Expand Down Expand Up @@ -70,6 +70,15 @@ public function reserve(
*/
public function capture(Token $token, int $amount): Payment;

/**
* Tries to cancel a payment.
*
* @param Token $token
*
* @return Payment
*/
public function cancel(Token $token): Payment;

/**
* Returns card service.
*
Expand Down
61 changes: 47 additions & 14 deletions src/Providers/Stripe/Payment/Service.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@

namespace PodPoint\Payments\Providers\Stripe\Payment;

use PodPoint\Payments\Card\Service as CardServiceInterface;
use PodPoint\Payments\Customer\Service as CustomerServiceInterface;
use PodPoint\Payments\Exceptions\InvalidToken;
use PodPoint\Payments\Payment;
use PodPoint\Payments\Customer\Service as CustomerServiceInterface;
use PodPoint\Payments\Refund\Service as RefundServiceInterface;
use PodPoint\Payments\Card\Service as CardServiceInterface;
use PodPoint\Payments\Payment\Service as ServiceInterface;
use PodPoint\Payments\Providers\Stripe\Card\Service as CardService;
use PodPoint\Payments\Providers\Stripe\Customer\Service as CustomerService;
use PodPoint\Payments\Providers\Stripe\Refund\Service as RefundService;
use PodPoint\Payments\Providers\Stripe\Payment\Exception as StripeException;
use PodPoint\Payments\Payment\Service as ServiceInterface;
use PodPoint\Payments\Providers\Stripe\Refund\Service as RefundService;
use PodPoint\Payments\Providers\Stripe\Token as StripeToken;
use PodPoint\Payments\Refund\Service as RefundServiceInterface;
use PodPoint\Payments\Token;
use Stripe\Charge;
use Stripe\Error\InvalidRequest;
Expand All @@ -21,6 +21,11 @@

class Service implements ServiceInterface
{
/**
* @var string
*/
const CANCELLATION_ABANDONED = 'abandoned';

/**
* @param string $key
*/
Expand Down Expand Up @@ -147,13 +152,13 @@ public function reserve(
$params['capture_method'] = 'manual';

return $this->create(
$token,
$amount,
$currency,
$params['description'] ?? null,
$params['metadata'] ?? [],
$params['customer'] ?? null,
$params
$token,
$amount,
$currency,
$params['description'] ?? null,
$params['metadata'] ?? [],
$params['customer'] ?? null,
$params
);
}

Expand Down Expand Up @@ -182,14 +187,42 @@ public function capture(Token $token, int $amount): Payment
return new Payment($response->id, $response->amount, $response->currency, $response->created);
} catch (InvalidRequest $exception) {
if ($exception->getStripeCode() === 'amount_too_large') {
throw new AmountTooLarge($intent->amount_capturable);
throw new AmountTooLarge($intent->amount_capturable);
}

throw $exception;
}
}

throw new InvalidToken("Provided token type: $token->type is invalid, use " . StripeToken::PAYMENT_INTENT . " type");
throw new InvalidToken(
"Provided token type: $token->type is invalid, use " . StripeToken::PAYMENT_INTENT . " type"
);
}

/**
* Tries to cancel a payment.
*
* @param Token $token
*
* @return Payment
*
* @throws InvalidToken
*/
public function cancel(Token $token): Payment
{
if ($token->type === StripeToken::PAYMENT_INTENT) {
$intent = PaymentIntent::retrieve($token->value);

$response = $intent->cancel([
'cancellation_reason' => self::CANCELLATION_ABANDONED,
]);

return new Payment($response->id, $response->amount, $response->currency, $response->created);
}

throw new InvalidToken(
"Provided token type: $token->type is invalid, use " . StripeToken::PAYMENT_INTENT . " type"
);
}

/**
Expand Down
42 changes: 39 additions & 3 deletions tests/Providers/Stripe/Payment/ServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

use PodPoint\Payments\Exceptions\InvalidToken;
use PodPoint\Payments\Payment;
use PodPoint\Payments\Providers\Stripe\Customer\Service as CustomerService;
use PodPoint\Payments\Providers\Stripe\Payment\AmountTooLarge;
use PodPoint\Payments\Providers\Stripe\Payment\Exception as StripeException;
use PodPoint\Payments\Providers\Stripe\Payment\Service;
use PodPoint\Payments\Providers\Stripe\Refund\Service as RefundService;
use PodPoint\Payments\Providers\Stripe\Token;
use PodPoint\Payments\Tests\TestCase;
use PodPoint\Payments\Providers\Stripe\Payment\Exception as StripeException;
use PodPoint\Payments\Providers\Stripe\Customer\Service as CustomerService;
use PodPoint\Payments\Providers\Stripe\Refund\Service as RefundService;

class ServiceTest extends TestCase
{
Expand Down Expand Up @@ -261,4 +261,40 @@ public function testCorrectExceptionIsThrownWhenCaptureAmountIsHigherThanReserve
$reserveAmount + 500
);
}

/**
* Tests that payment intent can be cancelled.
*
* @throws InvalidToken
* @throws StripeException
* @throws \Stripe\Error\Api
*/
public function testPaymentIntentCanBeCancelled()
{
$amount = 1000;
$paymentMethodToken = new Token('pm_card_visa');

$payment = $this->service->reserve(
$paymentMethodToken,
$amount
);

$paymentIntentToken = new Token($payment->uid);

$cancelledPayment = $this->service->cancel($paymentIntentToken);

$this->assertEquals($amount, $cancelledPayment->amount);
}

/**
* Tests that reserved fund can only be cancelled using payment intent token.
*/
public function testFundsCanBeOnlyCancelledWithPaymentIntentToken()
{
$token = new Token('pm_some_other_token');

$this->expectException(InvalidToken::class);

$this->service->cancel($token);
}
}

0 comments on commit 3d8cdb9

Please sign in to comment.