diff --git a/changelog.txt b/changelog.txt
index 2314e02d4..d6448106d 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,7 +1,7 @@
*** Changelog ***
= 1.6.5 - 2022-01-31 =
-* Fix - Allow guest users to purchase subscription products #422
+* Fix - Allow guest users to purchase subscription products from checkout page #422
* Fix - Transaction ID missing for renewal order #424
* Fix - Save your credit card checkbox should be removed in pay for order for subscriptions #420
* Fix - Null currency error when the Aelia currency switcher plugin is active #426
diff --git a/modules/ppcp-api-client/src/Factory/PayerFactory.php b/modules/ppcp-api-client/src/Factory/PayerFactory.php
index fedeaa5a1..70d33dee3 100644
--- a/modules/ppcp-api-client/src/Factory/PayerFactory.php
+++ b/modules/ppcp-api-client/src/Factory/PayerFactory.php
@@ -9,6 +9,7 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\ApiClient\Factory;
+use WooCommerce\PayPalCommerce\ApiClient\Entity\Address;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PayerName;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PayerTaxInfo;
@@ -147,4 +148,55 @@ class PayerFactory {
$tax_info
);
}
+
+ /**
+ * Returns a Payer object based off the given checkout form fields.
+ *
+ * @param array $form_fields The checkout form fields.
+ * @return Payer
+ */
+ public function from_checkout_form( array $form_fields ): Payer {
+
+ $first_name = $form_fields['billing_first_name'] ?? '';
+ $last_name = $form_fields['billing_last_name'] ?? '';
+ $billing_email = $form_fields['billing_email'] ?? '';
+ $billing_country = $form_fields['billing_country'] ?? '';
+ $billing_address_1 = $form_fields['billing_address_1'] ?? '';
+ $billing_address_2 = $form_fields['billing_address_2'] ?? '';
+ $admin_area_1 = $form_fields['billing_state'] ?? '';
+ $admin_area_2 = $form_fields['billing_city'] ?? '';
+ $billing_postcode = $form_fields['billing_postcode'] ?? '';
+
+ $phone = null;
+ if ( isset( $form_fields['billing_phone'] ) && '' !== $form_fields['billing_phone'] ) {
+ // make sure the phone number contains only numbers and is max 14. chars long.
+ $national_number = $form_fields['billing_phone'];
+ $national_number = preg_replace( '/[^0-9]/', '', $national_number );
+
+ if ( null !== $national_number ) {
+ $national_number = substr( $national_number, 0, 14 );
+
+ $phone = new PhoneWithType(
+ 'HOME',
+ new Phone( $national_number )
+ );
+ }
+ }
+
+ return new Payer(
+ new PayerName( $first_name, $last_name ),
+ $billing_email,
+ '',
+ new Address(
+ $billing_country,
+ $billing_address_1,
+ $billing_address_2,
+ $admin_area_1,
+ $admin_area_2,
+ $billing_postcode
+ ),
+ null,
+ $phone
+ );
+ }
}
diff --git a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php
index 4a7f63348..ec6b55c7a 100644
--- a/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php
+++ b/modules/ppcp-button/src/Endpoint/CreateOrderEndpoint.php
@@ -12,8 +12,10 @@ namespace WooCommerce\PayPalCommerce\Button\Endpoint;
use Exception;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\OrderEndpoint;
+use WooCommerce\PayPalCommerce\ApiClient\Entity\Address;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Payer;
+use WooCommerce\PayPalCommerce\ApiClient\Entity\PayerName;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PaymentMethod;
use WooCommerce\PayPalCommerce\ApiClient\Entity\PurchaseUnit;
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
@@ -337,6 +339,15 @@ class CreateOrderEndpoint implements EndpointInterface {
$payer = $this->payer_factory->from_paypal_response( json_decode( wp_json_encode( $data['payer'] ) ) );
}
+
+ if ( ! $payer && isset( $data['form'] ) ) {
+ parse_str( $data['form'], $form_fields );
+
+ if ( isset( $form_fields['billing_email'] ) && '' !== $form_fields['billing_email'] ) {
+ return $this->payer_factory->from_checkout_form( $form_fields );
+ }
+ }
+
return $payer;
}
diff --git a/modules/ppcp-wc-gateway/services.php b/modules/ppcp-wc-gateway/services.php
index 395f98bca..2eafb4ccb 100644
--- a/modules/ppcp-wc-gateway/services.php
+++ b/modules/ppcp-wc-gateway/services.php
@@ -741,7 +741,7 @@ return array(
'gateway' => 'paypal',
),
'disable_funding' => array(
- 'title' => __( 'Disable funding sources', 'woocommerce-paypal-payments' ),
+ 'title' => __( 'Hide Funding Source(s)', 'woocommerce-paypal-payments' ),
'type' => 'ppcp-multiselect',
'class' => array(),
'input_class' => array( 'wc-enhanced-select' ),
diff --git a/modules/ppcp-wc-gateway/src/Notice/ConnectAdminNotice.php b/modules/ppcp-wc-gateway/src/Notice/ConnectAdminNotice.php
index ce5e9ee96..319f2c844 100644
--- a/modules/ppcp-wc-gateway/src/Notice/ConnectAdminNotice.php
+++ b/modules/ppcp-wc-gateway/src/Notice/ConnectAdminNotice.php
@@ -57,7 +57,7 @@ class ConnectAdminNotice {
$message = sprintf(
/* translators: %1$s the gateway name. */
__(
- 'PayPal Checkout is almost ready. To get started, connect your account.',
+ 'PayPal Payments is almost ready. To get started, connect your account.',
'woocommerce-paypal-payments'
),
admin_url( 'admin.php?page=wc-settings&tab=checkout§ion=ppcp-gateway' )
diff --git a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php
index b3db8d3a6..ba2f4b08c 100644
--- a/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php
+++ b/modules/ppcp-wc-gateway/src/Settings/SettingsListener.php
@@ -14,9 +14,9 @@ use WooCommerce\PayPalCommerce\ApiClient\Authentication\PayPalBearer;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\ApiClient\Helper\Cache;
use WooCommerce\PayPalCommerce\Onboarding\State;
-use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
use WooCommerce\PayPalCommerce\Webhooks\WebhookRegistrar;
+use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
/**
* Class SettingsListener
diff --git a/modules/ppcp-wc-gateway/src/WCGatewayModule.php b/modules/ppcp-wc-gateway/src/WCGatewayModule.php
index 5de6680d6..ee8746ca5 100644
--- a/modules/ppcp-wc-gateway/src/WCGatewayModule.php
+++ b/modules/ppcp-wc-gateway/src/WCGatewayModule.php
@@ -21,6 +21,7 @@ use WooCommerce\PayPalCommerce\WcGateway\Assets\SettingsPageAssets;
use WooCommerce\PayPalCommerce\WcGateway\Checkout\CheckoutPayPalAddressPreset;
use WooCommerce\PayPalCommerce\WcGateway\Checkout\DisableGateways;
use WooCommerce\PayPalCommerce\WcGateway\Endpoint\ReturnUrlEndpoint;
+use WooCommerce\PayPalCommerce\WcGateway\Exception\NotFoundException;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\CreditCardGateway;
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
use WooCommerce\PayPalCommerce\WcGateway\Notice\ConnectAdminNotice;
@@ -132,6 +133,23 @@ class WCGatewayModule implements ModuleInterface {
$endpoint->handle_request();
}
);
+
+ add_action(
+ 'woocommerce_paypal_payments_gateway_migrate',
+ static function () use ( $c ) {
+ $settings = $c->get( 'wcgateway.settings' );
+ assert( $settings instanceof Settings );
+
+ try {
+ if ( $settings->get( '3d_secure_contingency' ) === '3D_SECURE' ) {
+ $settings->set( '3d_secure_contingency', 'SCA_ALWAYS' );
+ $settings->persist();
+ }
+ } catch ( NotFoundException $exception ) {
+ return;
+ }
+ }
+ );
}
/**
diff --git a/modules/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php b/modules/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php
index bc56dd935..ed85bc040 100644
--- a/modules/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php
+++ b/modules/ppcp-webhooks/src/Handler/PaymentCaptureRefunded.php
@@ -10,13 +10,14 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Webhooks\Handler;
use Psr\Log\LoggerInterface;
+use WooCommerce\PayPalCommerce\WcGateway\Processor\TransactionIdHandlingTrait;
/**
* Class PaymentCaptureRefunded
*/
class PaymentCaptureRefunded implements RequestHandler {
- use PrefixTrait;
+ use PrefixTrait, TransactionIdHandlingTrait;
/**
* The logger.
@@ -150,6 +151,11 @@ class PaymentCaptureRefunded implements RequestHandler {
'order' => $wc_order,
)
);
+
+ if ( is_array( $request['resource'] ) && isset( $request['resource']['id'] ) ) {
+ $this->update_transaction_id( $request['resource']['id'], $wc_order, $this->logger );
+ }
+
$response['success'] = true;
return rest_ensure_response( $response );
}
diff --git a/readme.txt b/readme.txt
index f01ee26dd..b607564d9 100644
--- a/readme.txt
+++ b/readme.txt
@@ -2,7 +2,7 @@
Contributors: woocommerce, automattic
Tags: woocommerce, paypal, payments, ecommerce, e-commerce, store, sales, sell, shop, shopping, cart, checkout
Requires at least: 5.3
-Tested up to: 5.8
+Tested up to: 5.9
Requires PHP: 7.1
Stable tag: 1.6.5
License: GPLv2
@@ -82,7 +82,7 @@ Follow the steps below to connect the plugin to your PayPal account:
== Changelog ==
= 1.6.5 =
-* Fix - Allow guest users to purchase subscription products #422
+* Fix - Allow guest users to purchase subscription products from checkout page #422
* Fix - Transaction ID missing for renewal order #424
* Fix - Save your credit card checkbox should be removed in pay for order for subscriptions #420
* Fix - Null currency error when the Aelia currency switcher plugin is active #426