Skip to content

Commit

Permalink
Ensure passed card belongs to given customer (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
lchrusciel authored Oct 31, 2024
2 parents 7124ebf + d4b00ef commit c4d74e5
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 12 deletions.
2 changes: 1 addition & 1 deletion src/Payum/Action/Api/PayWithCardAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ protected function doExecute(Generic $request, PaymentInterface $model, PaymentD

$this->do(
fn () => $this->api->transactions()->createPaymentByTransactionId(
$this->payWithCardActionPayloadMapper->getPayload($paymentDetails),
$this->payWithCardActionPayloadMapper->getPayload($paymentDetails, $model),
$paymentDetails->getTransactionId(),
),
onSuccess: function ($response) use ($paymentDetails) {
Expand Down
15 changes: 13 additions & 2 deletions src/Payum/Mapper/PayWithCardActionPayloadMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
use CommerceWeavers\SyliusTpayPlugin\Model\PaymentDetails;
use CommerceWeavers\SyliusTpayPlugin\Repository\CreditCardRepositoryInterface;
use CommerceWeavers\SyliusTpayPlugin\Tpay\PayGroup;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentInterface;
use Webmozart\Assert\Assert;

class PayWithCardActionPayloadMapper implements PayWithCardActionPayloadMapperInterface
Expand All @@ -19,15 +23,22 @@ public function __construct(private readonly CreditCardRepositoryInterface $cred
/**
* @return array{'groupId': int, 'cardPaymentData': array}
*/
public function getPayload(PaymentDetails $paymentDetails): array
public function getPayload(PaymentDetails $paymentDetails, PaymentInterface $payment): array
{
$payload = [
'groupId' => PayGroup::CARD,
];

if ($paymentDetails->getUseSavedCreditCard() !== null) {
/** @var OrderInterface $order */
$order = $payment->getOrder();
/** @var ChannelInterface $channel */
$channel = $order->getChannel();
/** @var CustomerInterface $customer */
$customer = $order->getCustomer();

/** @var CreditCardInterface|null $creditCard */
$creditCard = $this->creditCardRepository->find($paymentDetails->getUseSavedCreditCard());
$creditCard = $this->creditCardRepository->findOneByIdCustomerAndChannel($paymentDetails->getUseSavedCreditCard(), $customer, $channel);

Assert::notNull($creditCard);

Expand Down
3 changes: 2 additions & 1 deletion src/Payum/Mapper/PayWithCardActionPayloadMapperInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
namespace CommerceWeavers\SyliusTpayPlugin\Payum\Mapper;

use CommerceWeavers\SyliusTpayPlugin\Model\PaymentDetails;
use Sylius\Component\Core\Model\PaymentInterface;

interface PayWithCardActionPayloadMapperInterface
{
/**
* @return array{'groupId': int, 'cardPaymentData': array}
*/
public function getPayload(PaymentDetails $paymentDetails): array;
public function getPayload(PaymentDetails $paymentDetails, PaymentInterface $payment): array;
}
6 changes: 3 additions & 3 deletions tests/Unit/Payum/Action/Api/PayWithCardActionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public function test_it_redirects_a_customer_to_3ds_verification_once_a_transact
$request->getModel()->willReturn($paymentModel->reveal());
$request->getToken()->willReturn($token->reveal());

$this->mapper->getPayload(Argument::type(PaymentDetails::class))->willReturn(['GENERATED' => 'PAYLOAD']);
$this->mapper->getPayload(Argument::type(PaymentDetails::class), $paymentModel->reveal())->willReturn(['GENERATED' => 'PAYLOAD']);

$transactions = $this->prophesize(TransactionsApi::class);
$transactions->createPaymentByTransactionId(['GENERATED' => 'PAYLOAD'], $details['tpay']['transaction_id'])->willReturn($response);
Expand Down Expand Up @@ -136,7 +136,7 @@ public function test_it_marks_payment_as_failed_if_tpay_throws_an_exception(): v

$transactions = $this->prophesize(TransactionsApi::class);

$this->mapper->getPayload(Argument::type(PaymentDetails::class))->willReturn(['GENERATED' => 'PAYLOAD']);
$this->mapper->getPayload(Argument::type(PaymentDetails::class), $paymentModel->reveal())->willReturn(['GENERATED' => 'PAYLOAD']);
$transactions->createPaymentByTransactionId(['GENERATED' => 'PAYLOAD'], $details['tpay']['transaction_id'])->willThrow(new TpayException('Something went wrong'));

$this->api->transactions()->willReturn($transactions);
Expand Down Expand Up @@ -180,7 +180,7 @@ public function test_it_marks_a_payment_status_as_failed_once_a_transaction_stat
'result' => 'failed',
];

$this->mapper->getPayload(Argument::type(PaymentDetails::class))->willReturn(['GENERATED' => 'PAYLOAD']);
$this->mapper->getPayload(Argument::type(PaymentDetails::class), $paymentModel->reveal())->willReturn(['GENERATED' => 'PAYLOAD']);

$transactions = $this->prophesize(TransactionsApi::class);
$transactions->createPaymentByTransactionId(['GENERATED' => 'PAYLOAD'], $details['tpay']['transaction_id'])->willReturn($response);
Expand Down
28 changes: 23 additions & 5 deletions tests/Unit/Payum/Mapper/PayWithCardActionPayloadMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Core\Model\CustomerInterface;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Core\Model\PaymentInterface;

final class PayWithCardActionPayloadMapperTest extends TestCase
{
Expand All @@ -27,13 +31,14 @@ protected function setUp(): void
public function test_it_returns_payload_for_card_payment(): void
{
$paymentDetails = $this->prophesize(PaymentDetails::class);
$payment = $this->prophesize(PaymentInterface::class);

$paymentDetails->getUseSavedCreditCard()->willReturn(null);
$paymentDetails->getEncodedCardData()->willReturn('encoded_card_data');
$paymentDetails->isSaveCreditCardForLater()->willReturn(false);

$mapper = $this->createTestSubject();
$payload = $mapper->getPayload($paymentDetails->reveal());
$payload = $mapper->getPayload($paymentDetails->reveal(), $payment->reveal());

$this->assertSame([
'groupId' => PayGroup::CARD,
Expand All @@ -46,16 +51,28 @@ public function test_it_returns_payload_for_card_payment(): void
public function test_it_returns_payload_for_saved_card_payment(): void
{
$paymentDetails = $this->prophesize(PaymentDetails::class);
$payment = $this->prophesize(PaymentInterface::class);
$order = $this->prophesize(OrderInterface::class);
$channel = $this->prophesize(ChannelInterface::class);
$customer = $this->prophesize(CustomerInterface::class);

$paymentDetails->getUseSavedCreditCard()->willReturn(1);
$payment->getOrder()->willReturn($order);
$order->getChannel()->willReturn($channel);
$order->getCustomer()->willReturn($customer);

$paymentDetails->getUseSavedCreditCard()->willReturn('1a661fba-83df-4e19-bbf0-985506526711');

$creditCard = $this->prophesize(CreditCardInterface::class);
$creditCard->getToken()->willReturn('token');

$this->creditCardRepository->find(1)->willReturn($creditCard->reveal());
$this->creditCardRepository->findOneByIdCustomerAndChannel(
'1a661fba-83df-4e19-bbf0-985506526711',
$customer->reveal(),
$channel->reveal(),
)->willReturn($creditCard->reveal());

$mapper = $this->createTestSubject();
$payload = $mapper->getPayload($paymentDetails->reveal());
$payload = $mapper->getPayload($paymentDetails->reveal(), $payment->reveal());

$this->assertSame([
'groupId' => PayGroup::CARD,
Expand All @@ -68,13 +85,14 @@ public function test_it_returns_payload_for_saved_card_payment(): void
public function test_it_returns_payload_for_card_payment_and_save_for_later(): void
{
$paymentDetails = $this->prophesize(PaymentDetails::class);
$payment = $this->prophesize(PaymentInterface::class);

$paymentDetails->getUseSavedCreditCard()->willReturn(null);
$paymentDetails->isSaveCreditCardForLater()->willReturn(true);
$paymentDetails->getEncodedCardData()->willReturn('encoded_card_data');

$mapper = $this->createTestSubject();
$payload = $mapper->getPayload($paymentDetails->reveal());
$payload = $mapper->getPayload($paymentDetails->reveal(), $payment->reveal());

$this->assertSame([
'groupId' => PayGroup::CARD,
Expand Down

0 comments on commit c4d74e5

Please sign in to comment.