Fix phpcd (WIP)

This commit is contained in:
dinamiko 2022-04-14 17:17:56 +02:00
parent 42ce61de5b
commit e9cf818799
24 changed files with 487 additions and 175 deletions

View file

@ -83,6 +83,7 @@ class Item {
* @param Money|null $tax The tax.
* @param string $sku The SKU.
* @param string $category The category.
* @param float $tax_rate The tax rate.
*/
public function __construct(
string $name,
@ -174,9 +175,8 @@ class Item {
*
* @return float
*/
public function tax_rate():float
{
return round((float) $this->tax_rate, 2);
public function tax_rate():float {
return round( (float) $this->tax_rate, 2 );
}
/**
@ -198,7 +198,7 @@ class Item {
$item['tax'] = $this->tax()->to_array();
}
if ($this->tax_rate()) {
if ( $this->tax_rate() ) {
$item['tax_rate'] = (string) $this->tax_rate();
}

View file

@ -58,7 +58,7 @@ class ItemFactory {
$price_without_tax = (float) wc_get_price_excluding_tax( $product );
$price_without_tax_rounded = round( $price_without_tax, 2 );
$tax = round( $price - $price_without_tax_rounded, 2 );
$tax_rates = WC_Tax::get_rates($product->get_tax_class());
$tax_rates = WC_Tax::get_rates( $product->get_tax_class() );
$tax = new Money( $tax + $shipping_tax, $this->currency );
$tax = new Money( $tax, $this->currency );
return new Item(
@ -69,7 +69,7 @@ class ItemFactory {
$tax,
$product->get_sku(),
( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS,
reset($tax_rates)['rate'] ?? 0
reset( $tax_rates )['rate'] ?? 0
);
},
$cart->get_cart_contents()
@ -141,7 +141,7 @@ class ItemFactory {
$price_without_tax_rounded = round( $price_without_tax, 2 );
$tax = round( $price - $price_without_tax_rounded, 2 );
$tax = new Money( $tax, $currency );
$tax_rates = WC_Tax::get_rates($product->get_tax_class());
$tax_rates = WC_Tax::get_rates( $product->get_tax_class() );
return new Item(
mb_substr( $product->get_name(), 0, 127 ),
@ -151,7 +151,7 @@ class ItemFactory {
$tax,
$product->get_sku(),
( $product->is_virtual() ) ? Item::DIGITAL_GOODS : Item::PHYSICAL_GOODS,
reset($tax_rates)['rate'] ?? 0
reset( $tax_rates )['rate'] ?? 0
);
}

View file

@ -72,6 +72,9 @@ class PartnerReferralsData {
* @return array
*/
public function data(): array {
/**
* Returns the partners referrals data.
*/
return apply_filters(
'ppcp_partner_referrals_data',
array(

View file

@ -187,10 +187,11 @@ return array(
$logger
);
},
'onboarding.endpoint.pui' => static function(ContainerInterface $container) : PayUponInvoiceEndpoint {
'onboarding.endpoint.pui' => static function( ContainerInterface $container ) : PayUponInvoiceEndpoint {
return new PayUponInvoiceEndpoint(
$container->get( 'wcgateway.settings' ),
$container->get( 'button.request-data' )
$container->get( 'button.request-data' ),
$container->get( 'woocommerce.logger.woocommerce' )
);
},
'api.endpoint.partner-referrals-sandbox' => static function ( ContainerInterface $container ) : PartnerReferrals {

View file

@ -9,47 +9,83 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Onboarding\Endpoint;
use Exception;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\Button\Endpoint\EndpointInterface;
use WooCommerce\PayPalCommerce\Button\Endpoint\RequestData;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
/**
* Class PayUponInvoiceEndpoint
*/
class PayUponInvoiceEndpoint implements EndpointInterface {
/**
* The settings.
*
* @var Settings
*/
protected $settings;
/**
* The request data.
*
* @var RequestData
*/
protected $request_data;
public function __construct(Settings $settings, RequestData $request_data)
{
/**
* The logger.
*
* @var LoggerInterface
*/
protected $logger;
/**
* PayUponInvoiceEndpoint constructor.
*
* @param Settings $settings The settings.
* @param RequestData $request_data The request data.
* @param LoggerInterface $logger The logger.
*/
public function __construct( Settings $settings, RequestData $request_data, LoggerInterface $logger ) {
$this->settings = $settings;
$this->request_data = $request_data;
$this->logger = $logger;
}
public static function nonce(): string
{
/**
* The nonce.
*
* @return string
*/
public static function nonce(): string {
return 'ppc-pui';
}
public function handle_request(): bool
{
/**
* * Handles the request.
*
* @return bool
* @throws NotFoundException When order not found or handling failed.
*/
public function handle_request(): bool {
try {
$data = $this->request_data->read_request( $this->nonce() );
$this->settings->set('ppcp-onboarding-pui', $data['checked']);
$this->settings->set( 'ppcp-onboarding-pui', $data['checked'] );
$this->settings->persist();
} catch (\Exception $exception) {
} catch ( Exception $exception ) {
$this->logger->error( $exception->getMessage() );
}
wp_send_json_success([
$this->settings->get('ppcp-onboarding-pui'),
]);
wp_send_json_success(
array(
$this->settings->get( 'ppcp-onboarding-pui' ),
)
);
return true;
}
}

View file

@ -97,7 +97,7 @@ class OnboardingModule implements ModuleInterface {
);
add_action(
'wc_ajax_' . 'ppc-pui',
'wc_ajax_ppc-pui',
static function () use ( $c ) {
$endpoint = $c->get( 'onboarding.endpoint.pui' );
$endpoint->handle_request();

View file

@ -10,6 +10,7 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Onboarding\Render;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
/**
* Class OnboardingRenderer
@ -30,6 +31,8 @@ class OnboardingOptionsRenderer {
private $country;
/**
* The settings.
*
* @var Settings
*/
protected $settings;
@ -39,8 +42,9 @@ class OnboardingOptionsRenderer {
*
* @param string $module_url The module url (for assets).
* @param string $country 2-letter country code of the shop.
* @param Settings $settings The settings.
*/
public function __construct( string $module_url, string $country, Settings $settings) {
public function __construct( string $module_url, string $country, Settings $settings ) {
$this->module_url = $module_url;
$this->country = $country;
$this->settings = $settings;
@ -66,16 +70,22 @@ class OnboardingOptionsRenderer {
</li>
<li>' . $this->render_dcc( $is_shop_supports_dcc ) . '</li>' .
$this->render_pui_option()
. '</ul>';
. '</ul>';
}
/**
* Renders pui option.
*
* @return string
* @throws NotFoundException When setting is not found.
*/
private function render_pui_option(): string {
if($this->country === 'DE') {
if ( 'DE' === $this->country ) {
$checked = 'checked';
if($this->settings->has('ppcp-onboarding-pui') && $this->settings->get('ppcp-onboarding-pui') !== '1') {
if ( $this->settings->has( 'ppcp-onboarding-pui' ) && $this->settings->get( 'ppcp-onboarding-pui' ) !== '1' ) {
$checked = '';
}
return '<label><input type="checkbox" id="ppcp-onboarding-pui" '.$checked.'> ' .
return '<label><input type="checkbox" id="ppcp-onboarding-pui" ' . $checked . '> ' .
__( 'Onboard with Pay Upon Invoice', 'woocommerce-paypal-payments' ) . '
</label>';
}

View file

@ -2176,7 +2176,7 @@ return array(
return new FraudNetSessionId();
},
'wcgateway.pay-upon-invoice-fraudnet-source-website-id' => static function ( ContainerInterface $container ): FraudNetSourceWebsiteId {
return new FraudNetSourceWebsiteId($container->get('api.merchant_id'));
return new FraudNetSourceWebsiteId( $container->get( 'api.merchant_id' ) );
},
'wcgateway.pay-upon-invoice-fraudnet' => static function ( ContainerInterface $container ): FraudNet {
$session_id = $container->get( 'wcgateway.pay-upon-invoice-fraudnet-session-id' );

View file

@ -341,7 +341,7 @@ class PayPalGateway extends \WC_Payment_Gateway {
if ( $this->is_paypal_tab() ) {
return __( 'PayPal Checkout', 'woocommerce-paypal-payments' );
}
if($this->is_pui_tab()) {
if ( $this->is_pui_tab() ) {
return __( 'Pay Upon Invoice', 'woocommerce-paypal-payments' );
}
@ -393,6 +393,11 @@ class PayPalGateway extends \WC_Payment_Gateway {
}
/**
* Whether we are on the PUI tab.
*
* @return bool
*/
private function is_pui_tab():bool {
return is_admin() && PayUponInvoiceGateway::ID === $this->page_id;
}

View file

@ -1,35 +1,59 @@
<?php
/**
* Fraudnet entity.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice;
/**
* Class FraudNet
*/
class FraudNet {
/**
* The session ID.
*
* @var string
*/
protected $session_id;
/**
* The source website ID.
*
* @var string
*/
protected $source_website_id;
/**
* FraudNet constructor.
*
* @param string $session_id The session ID.
* @param string $source_website_id The source website ID.
*/
public function __construct( string $session_id, string $source_website_id ) {
$this->session_id = $session_id;
$this->source_website_id = $source_website_id;
}
/**
* Returns the session ID.
*
* @return string
*/
public function sessionId(): string {
public function session_id(): string {
return $this->session_id;
}
/**
* Returns the source website id.
*
* @return string
*/
public function sourceWebsiteId(): string {
public function source_website_id(): string {
return $this->source_website_id;
}
}

View file

@ -1,11 +1,29 @@
<?php
/**
* Fraudnet session id.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice;
use Exception;
/**
* Class FraudNetSessionId.
*/
class FraudNetSessionId {
/**
* Generates a session ID or use the existing one from WC session.
*
* @return array|string
* @throws Exception When there is a problem with the session ID.
*/
public function __invoke() {
if(WC()->session === null) {
if ( WC()->session === null ) {
return '';
}

View file

@ -1,21 +1,41 @@
<?php
/**
* Fraudnet source website ID.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice;
class FraudNetSourceWebsiteId
{
/**
* Class FraudNetSourceWebsiteId.
*/
class FraudNetSourceWebsiteId {
/**
* The merchant id.
*
* @var string
*/
protected $api_merchant_id;
public function __construct(string $api_merchant_id)
{
/**
* FraudNetSourceWebsiteId constructor.
*
* @param string $api_merchant_id The merchant id.
*/
public function __construct( string $api_merchant_id ) {
$this->api_merchant_id = $api_merchant_id;
}
public function __invoke()
{
/**
* Returns the source website ID.
*
* @return string
*/
public function __invoke() {
return "{$this->api_merchant_id}_checkout-page";
}
}

View file

@ -1,4 +1,9 @@
<?php
/**
* Create order for PUI.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice
*/
declare(strict_types=1);
@ -13,54 +18,80 @@ use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\ApiClient\Factory\OrderFactory;
/**
* Class OrderEndpoint.
*/
class OrderEndpoint {
use RequestTrait;
/**
* The host.
*
* @var string
*/
protected $host;
/**
* The bearer.
*
* @var Bearer
*/
protected $bearer;
/**
* The order factory.
*
* @var OrderFactory
*/
protected $order_factory;
/**
* The FraudNet entity.
*
* @var FraudNet
*/
protected $fraudNet;
protected $fraudnet;
/**
* The logger.
*
* @var LoggerInterface
*/
protected $logger;
/**
* OrderEndpoint constructor.
*
* @param string $host The host.
* @param Bearer $bearer The bearer.
* @param OrderFactory $order_factory The order factory.
* @param FraudNet $fraudnet FrauNet entity.
* @param LoggerInterface $logger The logger.
*/
public function __construct(
string $host,
Bearer $bearer,
OrderFactory $order_factory,
FraudNet $fraudNet,
FraudNet $fraudnet,
LoggerInterface $logger
) {
$this->host = $host;
$this->bearer = $bearer;
$this->order_factory = $order_factory;
$this->logger = $logger;
$this->fraudNet = $fraudNet;
$this->fraudnet = $fraudnet;
}
/**
* Creates an order.
*
* @param PurchaseUnit[] $items The purchase unit items for the order.
* @param PaymentSource $payment_source The payment source.
* @param string $fraudnet_session_id The FrauNet session ID.
* @return Order
* @throws RuntimeException When there is a problem with the payment source.
* @throws PayPalApiException When there is a problem creating the order.
*/
public function create( array $items, PaymentSource $payment_source, $fraudnet_session_id = '' ): Order {
$data = array(
@ -85,7 +116,7 @@ class OrderEndpoint {
'Authorization' => 'Bearer ' . $bearer->token(),
'Content-Type' => 'application/json',
'Prefer' => 'return=representation',
'PayPal-Client-Metadata-Id' => $fraudnet_session_id ?: $this->fraudNet->sessionId(),
'PayPal-Client-Metadata-Id' => $fraudnet_session_id ?: $this->fraudnet->session_id(),
'PayPal-Request-Id' => uniqid( 'ppcp-', true ),
),
'body' => wp_json_encode( $data ),
@ -98,23 +129,22 @@ class OrderEndpoint {
$json = json_decode( $response['body'] );
$status_code = (int) wp_remote_retrieve_response_code( $response );
if ( ! in_array($status_code, [200,201] ) ) {
if ( ! in_array( $status_code, array( 200, 201 ), true ) ) {
$issue = $json->details[0]->issue ?? null;
$site_country_code = explode('-', get_bloginfo("language"))[0] ?? '';
if($issue === 'PAYMENT_SOURCE_INFO_CANNOT_BE_VERIFIED') {
if($site_country_code === 'de') {
throw new RuntimeException('Die Kombination aus Ihrem Namen und Ihrer Anschrift konnte nicht validiert werden. Bitte korrigieren Sie Ihre Daten und versuchen Sie es erneut. Weitere Informationen finden Sie in den Ratepay <a href="https://www.ratepay.com/legal-payment-dataprivacy/?lang=de" target="_blank">Datenschutzbestimmungen</a> oder nutzen Sie das Ratepay <a href="https://www.ratepay.com/kontakt/" target="_blank">Kontaktformular</a>.');
$site_country_code = explode( '-', get_bloginfo( 'language' ) )[0] ?? '';
if ( 'PAYMENT_SOURCE_INFO_CANNOT_BE_VERIFIED' === $issue ) {
if ( 'de' === $site_country_code ) {
throw new RuntimeException( 'Die Kombination aus Ihrem Namen und Ihrer Anschrift konnte nicht validiert werden. Bitte korrigieren Sie Ihre Daten und versuchen Sie es erneut. Weitere Informationen finden Sie in den Ratepay <a href="https://www.ratepay.com/legal-payment-dataprivacy/?lang=de" target="_blank">Datenschutzbestimmungen</a> oder nutzen Sie das Ratepay <a href="https://www.ratepay.com/kontakt/" target="_blank">Kontaktformular</a>.' );
} else {
throw new RuntimeException('The combination of your name and address could not be validated. Please correct your data and try again. You can find further information in the <a href="https://www.ratepay.com/en/ratepay-data-privacy-statement/" target="_blank">Ratepay Data Privacy Statement</a> or you can contact Ratepay using this <a href="https://www.ratepay.com/en/contact/" target="_blank">contact form</a>.');
throw new RuntimeException( 'The combination of your name and address could not be validated. Please correct your data and try again. You can find further information in the <a href="https://www.ratepay.com/en/ratepay-data-privacy-statement/" target="_blank">Ratepay Data Privacy Statement</a> or you can contact Ratepay using this <a href="https://www.ratepay.com/en/contact/" target="_blank">contact form</a>.' );
}
}
if($issue === 'PAYMENT_SOURCE_DECLINED_BY_PROCESSOR') {
if($site_country_code === 'de') {
throw new RuntimeException('Die gewählte Zahlungsart kann nicht genutzt werden. Diese Entscheidung basiert auf einem automatisierten <a href="https://www.ratepay.com/legal-payment-dataprivacy/?lang=de" target="_blank">Datenverarbeitungsverfahren</a>. Weitere Informationen finden Sie in den Ratepay Datenschutzbestimmungen oder nutzen Sie das Ratepay <a href="https://www.ratepay.com/kontakt/" target="_blank">Kontaktformular</a>.');
if ( 'PAYMENT_SOURCE_DECLINED_BY_PROCESSOR' === $issue ) {
if ( 'de' === $site_country_code ) {
throw new RuntimeException( 'Die gewählte Zahlungsart kann nicht genutzt werden. Diese Entscheidung basiert auf einem automatisierten <a href="https://www.ratepay.com/legal-payment-dataprivacy/?lang=de" target="_blank">Datenverarbeitungsverfahren</a>. Weitere Informationen finden Sie in den Ratepay Datenschutzbestimmungen oder nutzen Sie das Ratepay <a href="https://www.ratepay.com/kontakt/" target="_blank">Kontaktformular</a>.' );
} else {
throw new RuntimeException('It is not possible to use the selected payment method. This decision is based on automated data processing. You can find further information in the <a href="https://www.ratepay.com/en/ratepay-data-privacy-statement/" target="_blank">Ratepay Data Privacy Statement</a> or you can contact Ratepay using this <a href="https://www.ratepay.com/en/contact/" target="_blank">contact form</a>.');
throw new RuntimeException( 'It is not possible to use the selected payment method. This decision is based on automated data processing. You can find further information in the <a href="https://www.ratepay.com/en/ratepay-data-privacy-statement/" target="_blank">Ratepay Data Privacy Statement</a> or you can contact Ratepay using this <a href="https://www.ratepay.com/en/contact/" target="_blank">contact form</a>.' );
}
}
@ -124,7 +154,15 @@ class OrderEndpoint {
return $this->order_factory->from_paypal_response( $json );
}
public function order_payment_instructions(string $id): array {
/**
* Get Ratepay payment instructions from PayPal order.
*
* @param string $id The PayPal order ID.
* @return array
* @throws RuntimeException When there is a problem getting the order.
* @throws PayPalApiException When there is a problem getting the order.
*/
public function order_payment_instructions( string $id ): array {
$bearer = $this->bearer->bearer();
$url = trailingslashit( $this->host ) . 'v2/checkout/orders/' . $id;
$args = array(
@ -146,13 +184,9 @@ class OrderEndpoint {
throw new PayPalApiException( $json, $status_code );
}
$this->logger->info('Payment instructions');
$this->logger->info($json->payment_source->pay_upon_invoice->payment_reference);
$this->logger->info(wc_print_r($json->payment_source->pay_upon_invoice->deposit_bank_details, true));
return array(
$json->payment_source->pay_upon_invoice->payment_reference,
$json->payment_source->pay_upon_invoice->deposit_bank_details
$json->payment_source->pay_upon_invoice->deposit_bank_details,
);
}
}

View file

@ -1,4 +1,9 @@
<?php
/**
* PUI integration.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice
*/
declare(strict_types=1);
@ -6,44 +11,68 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice;
use Psr\Log\LoggerInterface;
use WC_Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
use WooCommerce\PayPalCommerce\Button\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\WcGateway\Settings\Settings;
use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
/**
* Class PayUponInvoice.
*/
class PayUponInvoice {
/**
* The module URL.
*
* @var string
*/
protected $module_url;
/**
* The FraudNet entity.
*
* @var FraudNet
*/
protected $fraud_net;
/**
* The order endpoint.
*
* @var OrderEndpoint
*/
protected $order_endpoint;
/**
* The logger.
*
* @var LoggerInterface
*/
protected $logger;
/**
* The settings.
*
* @var Settings
*/
protected $settings;
/**
* The environment.
*
* @var Environment
*/
protected $environment;
/**
* PayUponInvoice constructor.
*
* @param string $module_url The module URL.
* @param FraudNet $fraud_net The FraudNet entity.
* @param OrderEndpoint $order_endpoint The order endpoint.
* @param LoggerInterface $logger The logger.
* @param Settings $settings The settings.
* @param Environment $environment The environment.
*/
public function __construct(
string $module_url,
FraudNet $fraud_net,
@ -60,15 +89,20 @@ class PayUponInvoice {
$this->environment = $environment;
}
/**
* Initializes PUI integration.
*
* @throws NotFoundException When setting is not found.
*/
public function init() {
add_filter(
'ppcp_partner_referrals_data',
function ( $data ) {
if($this->settings->has('ppcp-onboarding-pui') && $this->settings->get('ppcp-onboarding-pui') !== '1') {
if ( $this->settings->has( 'ppcp-onboarding-pui' ) && $this->settings->get( 'ppcp-onboarding-pui' ) !== '1' ) {
return $data;
}
if(in_array( 'PPCP', $data['products'] )) {
if ( in_array( 'PPCP', $data['products'], true ) ) {
$data['products'][] = 'PAYMENT_METHODS';
$data['capabilities'][] = 'PAY_UPON_INVOICE';
}
@ -117,7 +151,7 @@ class PayUponInvoice {
$order_purchase_date = $order_date->date( 'd-m-Y' );
$order_time = $order_date->date( 'H:i:s' );
$order_date = $order_date->date( 'd-m-Y H:i:s' );
$order_date_30d = date( 'd-m-Y', strtotime( $order_date . ' +30 days' ) );
$order_date_30d = gmdate( 'd-m-Y', strtotime( $order_date . ' +30 days' ) );
$payment_reference = $instructions[0] ?? '';
$bic = $instructions[1]->bic ?? '';
@ -166,11 +200,11 @@ class PayUponInvoice {
);
echo '</div><div>';
$site_country_code = explode('-', get_bloginfo("language"))[0] ?? '';
if($site_country_code === 'de') {
_e( 'Mit Klicken auf '.apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ).' akzeptieren Sie die <a href="https://www.ratepay.com/legal-payment-terms" target="_blank">Ratepay Zahlungsbedingungen</a> und erklären sich mit der Durchführung einer <a href="https://www.ratepay.com/legal-payment-dataprivacy" target="_blank">Risikoprüfung durch Ratepay</a>, unseren Partner, einverstanden. Sie akzeptieren auch PayPals <a href="https://www.paypal.com/de/webapps/mpp/ua/privacy-full?locale.x=de_DE&_ga=1.228729434.718583817.1563460395" target="_blank">Datenschutzerklärung</a>. Falls Ihre Transaktion per Kauf auf Rechnung erfolgreich abgewickelt werden kann, wird der Kaufpreis an Ratepay abgetreten und Sie dürfen nur an Ratepay überweisen, nicht an den Händler.', 'woocommerce-paypal-payments' );
$site_country_code = explode( '-', get_bloginfo( 'language' ) )[0] ?? '';
if ( $site_country_code === 'de' ) {
_e( 'Mit Klicken auf ' . apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ) . ' akzeptieren Sie die <a href="https://www.ratepay.com/legal-payment-terms" target="_blank">Ratepay Zahlungsbedingungen</a> und erklären sich mit der Durchführung einer <a href="https://www.ratepay.com/legal-payment-dataprivacy" target="_blank">Risikoprüfung durch Ratepay</a>, unseren Partner, einverstanden. Sie akzeptieren auch PayPals <a href="https://www.paypal.com/de/webapps/mpp/ua/privacy-full?locale.x=de_DE&_ga=1.228729434.718583817.1563460395" target="_blank">Datenschutzerklärung</a>. Falls Ihre Transaktion per Kauf auf Rechnung erfolgreich abgewickelt werden kann, wird der Kaufpreis an Ratepay abgetreten und Sie dürfen nur an Ratepay überweisen, nicht an den Händler.', 'woocommerce-paypal-payments' );
} else {
_e( 'By clicking on '.apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ).', you agree to the <a href="https://www.ratepay.com/legal-payment-terms" target="_blank">terms of payment</a> and <a href="https://www.ratepay.com/legal-payment-dataprivacy">performance of a risk check</a> from the payment partner, Ratepay. You also agree to PayPals <a href="https://www.paypal.com/de/webapps/mpp/ua/privacy-full?locale.x=eng_DE&_ga=1.267010504.718583817.1563460395">privacy statement</a>. If your request to purchase upon invoice is accepted, the purchase price claim will be assigned to Ratepay, and you may only pay Ratepay, not the merchant.', 'woocommerce-paypal-payments' );
_e( 'By clicking on ' . apply_filters( 'woocommerce_order_button_text', __( 'Place order', 'woocommerce' ) ) . ', you agree to the <a href="https://www.ratepay.com/legal-payment-terms" target="_blank">terms of payment</a> and <a href="https://www.ratepay.com/legal-payment-dataprivacy">performance of a risk check</a> from the payment partner, Ratepay. You also agree to PayPals <a href="https://www.paypal.com/de/webapps/mpp/ua/privacy-full?locale.x=eng_DE&_ga=1.267010504.718583817.1563460395">privacy statement</a>. If your request to purchase upon invoice is accepted, the purchase price claim will be assigned to Ratepay, and you may only pay Ratepay, not the merchant.', 'woocommerce-paypal-payments' );
}
echo '</div>';
@ -207,14 +241,20 @@ class PayUponInvoice {
);
}
/**
* Set configuration JSON for FraudNet integration.
*/
public function add_parameter_block() {
$sandbox = $this->environment->current_environment_is(Environment::SANDBOX) ? '"sandbox":true,': '';
$sandbox = $this->environment->current_environment_is( Environment::SANDBOX ) ? '"sandbox":true,' : '';
?>
<script type="application/json" fncls="fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99">{<?php echo $sandbox;?>"f":"<?php echo esc_attr( $this->fraud_net->sessionId() ); ?>","s":"<?php echo esc_attr( $this->fraud_net->sourceWebsiteId() ); ?>"}</script>
<script type="application/json" fncls="fnparams-dede7cc5-15fd-4c75-a9f4-36c430ee3a99">{<?php echo $sandbox; ?>"f":"<?php echo esc_attr( $this->fraud_net->session_id() ); ?>","s":"<?php echo esc_attr( $this->fraud_net->source_website_id() ); ?>"}</script>
<script type="text/javascript" src="https://c.paypal.com/da/r/fb.js"></script>
<?php
}
/**
* Registers PUI assets.
*/
public function register_assets() {
wp_enqueue_script(
'ppcp-pay-upon-invoice',

View file

@ -17,6 +17,9 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
use WooCommerce\PayPalCommerce\Onboarding\Environment;
use WooCommerce\PayPalCommerce\WcGateway\Processor\OrderMetaTrait;
/**
* Class PayUponInvoiceGateway.
*/
class PayUponInvoiceGateway extends WC_Payment_Gateway {
use OrderMetaTrait;
@ -24,30 +27,49 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway {
const ID = 'ppcp-pay-upon-invoice-gateway';
/**
* The order endpoint.
*
* @var OrderEndpoint
*/
protected $order_endpoint;
/**
* The purchase unit factory.
*
* @var PurchaseUnitFactory
*/
protected $purchase_unit_factory;
/**
* The payment source factory.
*
* @var PaymentSourceFactory
*/
protected $payment_source_factory;
/**
* The environment.
*
* @var Environment
*/
protected $environment;
/**
* The logger interface.
*
* @var LoggerInterface
*/
protected $logger;
/**
* PayUponInvoiceGateway constructor.
*
* @param OrderEndpoint $order_endpoint The order endpoint.
* @param PurchaseUnitFactory $purchase_unit_factory The purchase unit factory.
* @param PaymentSourceFactory $payment_source_factory The payment source factory.
* @param Environment $environment The environment.
* @param LoggerInterface $logger The logger.
*/
public function __construct(
OrderEndpoint $order_endpoint,
PurchaseUnitFactory $purchase_unit_factory,
@ -110,7 +132,7 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway {
'description' => __( 'This controls the description which the user sees during checkout.', 'woocommerce-paypal-payments' ),
),
'experience_context' => array(
'title' => __( 'Experience Context', 'woocommerce' ),
'title' => __( 'Experience Context', 'woocommerce-paypal-payments' ),
'type' => 'title',
'description' => __( "Specify brand name, logo and customer service instructions to be presented on Ratepay's payment instructions.", 'woocommerce-paypal-payments' ),
),
@ -138,6 +160,12 @@ class PayUponInvoiceGateway extends WC_Payment_Gateway {
);
}
/**
* Processes the order.
*
* @param int $order_id The WC order ID.
* @return array
*/
public function process_payment( $order_id ) {
$wc_order = wc_get_order( $order_id );
$wc_order->update_status( 'on-hold', __( 'Awaiting Pay Upon Invoice payment.', 'woocommerce-paypal-payments' ) );

View file

@ -1,79 +1,135 @@
<?php
/**
* PUI payment source.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice;
/**
* Class PaymentSource.
*/
class PaymentSource {
/**
* The given name.
*
* @var string
*/
protected $given_name;
/**
* The surname.
*
* @var string
*/
protected $surname;
/**
* The email.
*
* @var string
*/
protected $email;
/**
* The birth date.
*
* @var string
*/
protected $birth_date;
/**
* The phone number.
*
* @var string
*/
protected $national_number;
/**
* The phone country code.
*
* @var string
*/
protected $phone_country_code;
/**
* The address line 1.
*
* @var string
*/
protected $address_line_1;
/**
* The admin area 2.
*
* @var string
*/
protected $admin_area_2;
/**
* The postal code.
*
* @var string
*/
protected $postal_code;
/**
* The country code.
*
* @var string
*/
protected $country_code;
/**
* The locale.
*
* @var string
*/
protected $locale;
/**
* The brand name.
*
* @var string
*/
protected $brand_name;
/**
* The logo URL.
*
* @var string
*/
protected $logo_url;
/**
* The customer service instructions.
*
* @var array
*/
protected $customer_service_instructions;
/**
* PaymentSource constructor.
*
* @param string $given_name The given name.
* @param string $surname The surname.
* @param string $email The email.
* @param string $birth_date The birth date.
* @param string $national_number The phone number.
* @param string $phone_country_code The phone country code.
* @param string $address_line_1 The address line 1.
* @param string $admin_area_2 The admin area 2.
* @param string $postal_code The postal code.
* @param string $country_code The country code.
* @param string $locale The locale.
* @param string $brand_name The brand name.
* @param string $logo_url The logo URL.
* @param array $customer_service_instructions The customer service instructions.
*/
public function __construct(
string $given_name,
string $surname,
@ -107,117 +163,136 @@ class PaymentSource {
}
/**
* Returns the given name.
*
* @return string
*/
public function given_name(): string
{
public function given_name(): string {
return $this->given_name;
}
/**
* Returns the surname.
*
* @return string
*/
public function surname(): string
{
public function surname(): string {
return $this->surname;
}
/**
* Returns the email.
*
* @return string
*/
public function email(): string
{
public function email(): string {
return $this->email;
}
/**
* Returns the birth date.
*
* @return string
*/
public function birth_date(): string
{
public function birth_date(): string {
return $this->birth_date;
}
/**
* Returns the national number.
*
* @return string
*/
public function national_number(): string
{
public function national_number(): string {
return $this->national_number;
}
/**
* Returns the phone country code.
*
* @return string
*/
public function phone_country_code(): string
{
public function phone_country_code(): string {
return $this->phone_country_code;
}
/**
* Returns the address line 1.
*
* @return string
*/
public function address_line_1(): string
{
public function address_line_1(): string {
return $this->address_line_1;
}
/**
* Returns the admin area 2.
*
* @return string
*/
public function admin_area_2(): string
{
public function admin_area_2(): string {
return $this->admin_area_2;
}
/**
* Returns the postal code.
*
* @return string
*/
public function postal_code(): string
{
public function postal_code(): string {
return $this->postal_code;
}
/**
* Returns the country code.
*
* @return string
*/
public function country_code(): string
{
public function country_code(): string {
return $this->country_code;
}
/**
* Returns the locale.
*
* @return string
*/
public function locale(): string
{
public function locale(): string {
return $this->locale;
}
/**
* Returns the brand name.
*
* @return string
*/
public function brand_name(): string
{
public function brand_name(): string {
return $this->brand_name;
}
/**
* The logo URL.
*
* @return string
*/
public function logo_url(): string
{
public function logo_url(): string {
return $this->logo_url;
}
/**
* Returns the customer service instructions.
*
* @return array
*/
public function customer_service_instructions(): array
{
public function customer_service_instructions(): array {
return $this->customer_service_instructions;
}
/**
* Returns payment source as array.
*
* @return array
*/
public function to_array(): array {
return array(
'name' => array(

View file

@ -1,11 +1,27 @@
<?php
/**
* PUI payment source factory.
*
* @package WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice
*/
declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\WcGateway\Gateway\PayUponInvoice;
use WC_Order;
/**
* Class PaymentSourceFactory.
*/
class PaymentSourceFactory {
/**
* Create a PUI payment source from a WC order.
*
* @param WC_Order $order The WC order.
* @return PaymentSource
*/
public function from_wc_order( WC_Order $order ) {
$address = $order->get_address();
$birth_date = filter_input( INPUT_POST, 'billing_birth_date', FILTER_SANITIZE_STRING );
@ -21,8 +37,8 @@ class PaymentSourceFactory {
$address['last_name'] ?? '',
$address['email'] ?? '',
$birth_date ?? '',
preg_replace('/[^0-9]/', '', $address['phone']),
substr($phone_country_code, strlen('+')) ?? '',
preg_replace( '/[^0-9]/', '', $address['phone'] ),
substr( $phone_country_code, strlen( '+' ) ) ?? '',
$address['address_1'] ?? '',
$address['city'] ?? '',
$address['postcode'] ?? '',
@ -30,7 +46,7 @@ class PaymentSourceFactory {
'en-DE',
$merchant_name,
$logo_url,
array($customer_service_instructions)
array( $customer_service_instructions )
);
}
}

View file

@ -67,8 +67,8 @@ class SectionsRenderer {
foreach ( $sections as $id => $label ) {
$url = admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-gateway&' . self::KEY . '=' . $id );
if($id === PayUponInvoiceGateway::ID) {
$url = admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-pay-upon-invoice-gateway');
if ( PayUponInvoiceGateway::ID === $id ) {
$url = admin_url( 'admin.php?page=wc-settings&tab=checkout&section=ppcp-pay-upon-invoice-gateway' );
}
echo '<li><a href="' . esc_url( $url ) . '" class="' . ( $this->page_id === $id ? 'current' : '' ) . '">' . esc_html( $label ) . '</a> ' . ( end( $array_keys ) === $id ? '' : '|' ) . ' </li>';
}

View file

@ -189,7 +189,7 @@ class CheckoutOrderApproved implements RequestHandler {
}
foreach ( $wc_orders as $wc_order ) {
if(PayUponInvoiceGateway::ID === $wc_order->get_payment_method()) {
if ( PayUponInvoiceGateway::ID === $wc_order->get_payment_method() ) {
continue;
}

View file

@ -132,7 +132,7 @@ class CheckoutOrderCompleted implements RequestHandler {
}
foreach ( $wc_orders as $wc_order ) {
if(PayUponInvoiceGateway::ID === $wc_order->get_payment_method()) {
if ( PayUponInvoiceGateway::ID === $wc_order->get_payment_method() ) {
continue;
}

View file

@ -114,7 +114,10 @@ class PaymentCaptureCompleted implements RequestHandler {
$order_id = $resource['supplementary_data']['related_ids']['order_id'] ?? null;
do_action('ppcp_payment_capture_completed_webhook_handler', $wc_order, $order_id);
/**
* Allow access to the webhook logic before updating the WC order.
*/
do_action( 'ppcp_payment_capture_completed_webhook_handler', $wc_order, $order_id );
if ( $wc_order->get_status() !== 'on-hold' ) {
$response['success'] = true;
@ -151,7 +154,6 @@ class PaymentCaptureCompleted implements RequestHandler {
if ( $transaction_id ) {
$this->update_transaction_id( $transaction_id, $wc_order, $this->logger );
}
} catch ( Exception $exception ) {
$this->logger->warning( 'Failed to get transaction ID: ' . $exception->getMessage() );
}