Skip to content

Commit

Permalink
card on file standard merchant flow
Browse files Browse the repository at this point in the history
  • Loading branch information
konradkozaczenko committed May 15, 2024
1 parent 4f82750 commit de9630f
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 22 deletions.
37 changes: 37 additions & 0 deletions src/Action/CaptureAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Answear\Payum\PayU\Action;

use Answear\Payum\Model\Payment;
use Answear\Payum\PayU\Enum\CardOnFileEnum;
use Answear\Payum\PayU\Enum\PayMethodType;
use Answear\Payum\PayU\Enum\RecurringEnum;
use Answear\Payum\PayU\Exception\PayUException;
Expand All @@ -17,6 +18,7 @@
use Answear\Payum\PayU\ValueObject\Request\OrderRequest;
use Answear\Payum\PayU\ValueObject\Response\OrderCreated\StatusCode;
use Answear\Payum\PayU\ValueObject\Response\OrderCreatedResponse;
use Answear\Payum\PayU\ValueObject\Response\OrderTransactions\ByCreditCard;
use Payum\Core\Action\ActionInterface;
use Payum\Core\Exception\RequestNotSupportedException;
use Payum\Core\GatewayAwareInterface;
Expand Down Expand Up @@ -59,10 +61,15 @@ public function execute($request): void

$configKey = PaymentHelper::getConfigKey($model, $firstModel);
$orderRequest = $this->prepareOrderRequest($request, $token, $model);

if (RecurringEnum::Standard === $model->recurring()) {
$this->setRecurringStandardPayment($orderRequest, $model, $configKey);
}

if (CardOnFileEnum::StandardMerchant === $model->cardOnFile()) {
$this->setCardOnFileStandardMerchantPayment($orderRequest, $model, $configKey);
}

$orderCreatedResponse = $this->orderRequestService->create($orderRequest, $configKey);
$model->setPayUResponse($orderCreatedResponse);
if (StatusCode::Success === $orderCreatedResponse->status->statusCode) {
Expand Down Expand Up @@ -157,6 +164,36 @@ private function prepareOrderRequest(Capture $request, TokenInterface $token, Mo
);
}

private function setCardOnFileStandardMerchantPayment(OrderRequest $orderRequest, Model $model, ?string $configKey): void
{
$payMethods = $this->payMethodsRequestService->retrieveForUser($model->clientEmail(), $model->clientId(), $configKey);
if (empty($payMethods->cardTokens)) {
throw new \InvalidArgumentException('Cannot make this payment. Token for user does not exist.');
}

$transactions = $this->orderRequestService->retrieveTransactions($model->orderId(), $configKey);
$cardToken = null;
foreach ($transactions as $transaction) {
if (!$transaction instanceof ByCreditCard) {
continue;
}

$cardToken = $this->findPreferredToken($payMethods->cardTokens, $transaction->cardData->cardNumberMasked);
if (null !== $cardToken) {
break;
}
}

if (null === $cardToken) {
throw new \InvalidArgumentException('Cannot make this payment. Token for user does not exist.');
}

$orderRequest->setCardOnFile(
$model->cardOnFile() ?? CardOnFileEnum::StandardMerchant,
new PayMethod(PayMethodType::CardToken, $cardToken['value'])
);
}

private function setRecurringStandardPayment(OrderRequest $orderRequest, Model $model, ?string $configKey): void
{
$payMethods = $this->payMethodsRequestService->retrieveForUser($model->clientEmail(), $model->clientId(), $configKey);
Expand Down
6 changes: 6 additions & 0 deletions src/ValueObject/Request/OrderRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,4 +74,10 @@ public function setRequiring(?RecurringEnum $recurring, PayMethod $payMethod): v
$this->recurring = $recurring?->value;
$this->payMethod = $payMethod;
}

public function setCardOnFile(CardOnFileEnum $cardOnFile, PayMethod $payMethod): void
{
$this->cardOnFile = $cardOnFile;
$this->payMethod = $payMethod;
}
}
6 changes: 4 additions & 2 deletions src/ValueObject/Response/OrderTransactions/ByCreditCard.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ class ByCreditCard implements OrderRetrieveTransactionsResponseInterface
public function __construct(
public readonly PayMethod $payMethod,
public readonly string $paymentFlow,
public readonly ?array $card,
public readonly CardData $cardData,
public readonly array $cardInstallmentProposal,
) {
}

Expand All @@ -25,7 +26,8 @@ public static function fromResponse(array $response): self
return new self(
PayMethod::fromResponse($response['payMethod']),
$response['paymentFlow'],
$response['card'] ?? null,
CardData::fromResponse($response['card']['cardData']),
$response['cardInstallmentProposal'],
);
}
}
42 changes: 42 additions & 0 deletions src/ValueObject/Response/OrderTransactions/CardData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php

declare(strict_types=1);

namespace Answear\Payum\PayU\ValueObject\Response\OrderTransactions;

class CardData
{
public function __construct(
public readonly string $cardNumberMasked,
public readonly string $cardScheme,
public readonly string $cardProfile,
public readonly string $cardClassification,
public readonly string $cardResponseCode,
public readonly string $cardResponseCodeDesc,
public readonly string $cardEciCode,
public readonly string $card3DsStatus,
public readonly string $card3DsFrictionlessIndicator,
public readonly string $card3DsStatusDescription,
public readonly string $cardBinCountry,
public readonly string $firstTransactionId,
) {
}

public static function fromResponse(array $response): self
{
return new self(
$response['cardNumberMasked'] ?? '',
$response['cardScheme'] ?? '',
$response['cardProfile'] ?? '',
$response['cardClassification'] ?? '',
$response['cardResponseCode'] ?? '',
$response['cardResponseCodeDesc'] ?? '',
$response['cardEciCode'] ?? '',
$response['card3DsStatus'] ?? '',
$response['card3DsFrictionlessIndicator'] ?? '',
$response['card3DsStatusDescription'] ?? '',
$response['cardBinCountry'] ?? '',
$response['firstTransactionId'] ?? '',
);
}
}
39 changes: 22 additions & 17 deletions tests/Integration/Request/OrderRetrieveTransactionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Answear\Payum\PayU\ValueObject\PayMethod;
use Answear\Payum\PayU\ValueObject\Response\OrderTransactions\ByCreditCard;
use Answear\Payum\PayU\ValueObject\Response\OrderTransactions\ByPBL;
use Answear\Payum\PayU\ValueObject\Response\OrderTransactions\CardData;
use GuzzleHttp\Psr7\Response;
use Psr\Log\NullLogger;

Expand All @@ -33,26 +34,30 @@ public function retrieveByCardTest(): void
$transaction->getPayMethod()
);
self::assertSame('FIRST_ONE_CLICK_CARD', $transaction->paymentFlow);

$expectedCardData = CardData::fromResponse(
[
'cardNumberMasked' => '543402******4014',
'cardScheme' => 'MC',
'cardProfile' => 'CONSUMER',
'cardClassification' => 'DEBIT',
'cardResponseCode' => '000',
'cardResponseCodeDesc' => '000 - OK',
'cardEciCode' => '2',
'card3DsStatus' => 'Y',
'card3DsStatusDescription' => 'MessageVersion=2.1.0,browser flow,3DS method not available,dynamic authentication,no cancel indicator,no status reason',
'cardBinCountry' => 'PL',
'firstTransactionId' => 'MCC0111LL1121',
]
);

self::assertEquals($expectedCardData, $transaction->cardData);

self::assertSame(
[
'cardData' => [
'cardNumberMasked' => '543402******4014',
'cardScheme' => 'MC',
'cardProfile' => 'CONSUMER',
'cardClassification' => 'DEBIT',
'cardResponseCode' => '000',
'cardResponseCodeDesc' => '000 - OK',
'cardEciCode' => '2',
'card3DsStatus' => 'Y',
'card3DsStatusDescription' => 'MessageVersion=2.1.0,browser flow,3DS method not available,dynamic authentication,no cancel indicator,no status reason',
'cardBinCountry' => 'PL',
'firstTransactionId' => 'MCC0111LL1121',
],
'cardInstallmentProposal' => [
'proposalId' => '5aff3ba8-0c37-4da1-ba4a-4ff24bcc2eed',
],
'proposalId' => '5aff3ba8-0c37-4da1-ba4a-4ff24bcc2eed',
],
$transaction->card
$transaction->cardInstallmentProposal
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
"card3DsStatusDescription": "MessageVersion=2.1.0,browser flow,3DS method not available,dynamic authentication,no cancel indicator,no status reason",
"cardBinCountry": "PL",
"firstTransactionId": "MCC0111LL1121"
},
"cardInstallmentProposal": {
"proposalId": "5aff3ba8-0c37-4da1-ba4a-4ff24bcc2eed"
}
},
"cardInstallmentProposal": {
"proposalId": "5aff3ba8-0c37-4da1-ba4a-4ff24bcc2eed"
}
}
]
Expand Down

0 comments on commit de9630f

Please sign in to comment.