Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: add support for 3d secure to PayPal Commerce Gateway #7858

Open
wants to merge 2 commits into
base: epic/paypal-card-fields-api
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,15 @@ import createSubscriptionPlan from './resources/js/createSubscriptionPlan';
* @unreleased
*/
const cardFieldsOnApproveHandler: PayPalCardFieldsComponentBasics['onApprove'] = async (data) => {
payPalOrderId = data.orderID;
// @ts-ignore
const {orderID, liabilityShift} = data;
payPalOrderId = orderID

if (liabilityShift && !['POSSIBLE', 'YES'].includes(liabilityShift)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonwaldstein I was checking the link you shared in the PR description and couldn't see any response with "YES". Usually, they only return "Y" instead - check the attached screenshot.

Also, I can see in this other link that they said that "YES" is used for the liability_shift property, but as you can see in the screenshot, they API responses are using the "Y" instead.

So, I'm a bit confused about the allowed values here and wondering if we should include the "Y" on this array as well.

Thoughts?

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@glaubersilva good question! I chatted with our PayPal rep about this and they said we can simply use the liability_shift property to check for YES or POSSIBLE. However, as you pointed out there are a lot more responses we could check but that is completely up to what we want to support. To start, i'm happy to accept those simple values and reject the rest 😄

console.log('Liability shift not possible or not accepted.');
throw new Error(__('Card type and issuing bank are not ready to complete a 3D Secure authentication.', 'give'));
}

return;
};

Expand Down
21 changes: 19 additions & 2 deletions src/PaymentGateways/PayPalCommerce/PayPalCommerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,9 @@ public function createPayment(Donation $donation, $gatewayData): GatewayCommand

$transactionId = $payPalOrder->purchase_units[0]->payments->captures[0]->id;

} elseif ($payPalOrder->status === 'APPROVED') {
} elseif ($payPalOrder->status === 'APPROVED' || $payPalOrder->status === 'CREATED') {
$this->validate3dSecure($payPalOrder);

if ($this->shouldUpdateOrder($donation, $payPalOrder)){
$payPalOrderRepository->updateApprovedOrder($payPalOrderId, $donation->amount);
}
Expand All @@ -110,7 +112,7 @@ public function createPayment(Donation $donation, $gatewayData): GatewayCommand

$transactionId = $response->purchase_units[0]->payments->captures[0]->id;
} else {
throw new PaymentGatewayException('PayPal Order status is not approved or completed.');
throw new PaymentGatewayException('PayPal Order status is not found.');
}

give()->payment_meta->update_meta(
Expand Down Expand Up @@ -332,5 +334,20 @@ private function validatePayPalOrder(object $payPalOrder): void

throw new PaymentGatewayException($errorMessage);
}

$this->validate3dSecure($payPalOrder);
}

/**
* @unreleased
*
* @throws PaymentGatewayException
*/
private function validate3dSecure(object $payPalOrder): void
{
// Check if the order is not ready for 3D Secure authentication
if (isset($payPalOrder->payment_source->card->authentication_result->liability_shift) && !in_array($payPalOrder->payment_source->card->authentication_result->liability_shift, ['POSSIBLE', 'YES'])) {
throw new PaymentGatewayException('Card type and issuing bank are not ready to complete a 3D Secure authentication.');
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,13 @@ public function createOrder(array $array, string $intent = 'CAPTURE'): string
],
"email_address" => $array['payer']['email'],
],
'card' => [
'attributes' => [
'verification' => [
'method' => 'SCA_WHEN_REQUIRED'
]
]
]
],
'purchase_units' => [
$purchaseUnits
Expand Down