mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-08-30 05:00:51 +08:00
Add passing data between PayPal order and WC order via transient helper.
Add order notes when ditch oor extra line occurs.
This commit is contained in:
parent
a43b93ffff
commit
1a0fa269ef
11 changed files with 245 additions and 7 deletions
|
@ -17,6 +17,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Factory\PaymentPreferencesFactory;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PlanFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ProductFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingOptionFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderTransient;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\PurchaseUnitSanitizer;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
|
@ -817,6 +818,11 @@ return array(
|
|||
'api.order-helper' => static function( ContainerInterface $container ): OrderHelper {
|
||||
return new OrderHelper();
|
||||
},
|
||||
'api.helper.order-transient' => static function( ContainerInterface $container ): OrderTransient {
|
||||
$cache = new Cache( 'ppcp-paypal-bearer' );
|
||||
$purchase_unit_sanitizer = $container->get( 'api.helper.purchase-unit-sanitizer' );
|
||||
return new OrderTransient( $cache, $purchase_unit_sanitizer );
|
||||
},
|
||||
'api.helper.purchase-unit-sanitizer' => static function( ContainerInterface $container ): PurchaseUnitSanitizer {
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
assert( $settings instanceof Settings );
|
||||
|
|
|
@ -9,10 +9,13 @@ declare(strict_types=1);
|
|||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient;
|
||||
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderTransient;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Container\ServiceProvider;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Dhii\Modular\Module\ModuleInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Interop\Container\ServiceProviderInterface;
|
||||
use WooCommerce\PayPalCommerce\Vendor\Psr\Container\ContainerInterface;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
|
||||
/**
|
||||
* Class ApiModule
|
||||
|
@ -40,6 +43,30 @@ class ApiModule implements ModuleInterface {
|
|||
WC()->session->set( 'ppcp_fees', $fees );
|
||||
}
|
||||
);
|
||||
add_action(
|
||||
'woocommerce_paypal_payments_paypal_order_created',
|
||||
function ( Order $order ) use ( $c ) {
|
||||
$transient = $c->has( 'api.helper.order-transient' ) ? $c->get( 'api.helper.order-transient' ) : null;
|
||||
|
||||
if ( $transient instanceof OrderTransient ) {
|
||||
$transient->on_order_created( $order );
|
||||
}
|
||||
},
|
||||
10,
|
||||
1
|
||||
);
|
||||
add_action(
|
||||
'woocommerce_paypal_payments_woocommerce_order_created',
|
||||
function ( WC_Order $wc_order, Order $order ) use ( $c ) {
|
||||
$transient = $c->has( 'api.helper.order-transient' ) ? $c->get( 'api.helper.order-transient' ) : null;
|
||||
|
||||
if ( $transient instanceof OrderTransient ) {
|
||||
$transient->on_woocommerce_order_created( $wc_order, $order );
|
||||
}
|
||||
},
|
||||
10,
|
||||
2
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -281,6 +281,9 @@ class OrderEndpoint {
|
|||
throw $error;
|
||||
}
|
||||
$order = $this->order_factory->from_paypal_response( $json );
|
||||
|
||||
do_action( 'woocommerce_paypal_payments_paypal_order_created', $order );
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
|
|
|
@ -166,8 +166,11 @@ class PayUponInvoiceOrderEndpoint {
|
|||
|
||||
throw new PayPalApiException( $json, $status_code );
|
||||
}
|
||||
$order = $this->order_factory->from_paypal_response( $json );
|
||||
|
||||
return $this->order_factory->from_paypal_response( $json );
|
||||
do_action( 'woocommerce_paypal_payments_paypal_order_created', $order );
|
||||
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
160
modules/ppcp-api-client/src/Helper/OrderTransient.php
Normal file
160
modules/ppcp-api-client/src/Helper/OrderTransient.php
Normal file
|
@ -0,0 +1,160 @@
|
|||
<?php
|
||||
/**
|
||||
* PayPal order transient helper.
|
||||
*
|
||||
* This class is used to pass transient data between the PayPal order and the WooCommerce order.
|
||||
* These two orders can be created on different requests and at different times so this transient
|
||||
* data must be persisted between requests.
|
||||
*
|
||||
* @package WooCommerce\PayPalCommerce\ApiClient\Helper
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace WooCommerce\PayPalCommerce\ApiClient\Helper;
|
||||
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
|
||||
/**
|
||||
* Class OrderHelper
|
||||
*/
|
||||
class OrderTransient {
|
||||
const CACHE_KEY = 'order_transient';
|
||||
const CACHE_TIMEOUT = DAY_IN_SECONDS; // If necessary we can increase this.
|
||||
|
||||
/**
|
||||
* The Cache.
|
||||
*
|
||||
* @var Cache
|
||||
*/
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* The purchase unit sanitizer.
|
||||
*
|
||||
* @var PurchaseUnitSanitizer
|
||||
*/
|
||||
private $purchase_unit_sanitizer;
|
||||
|
||||
/**
|
||||
* OrderTransient constructor.
|
||||
*
|
||||
* @param Cache $cache The Cache.
|
||||
* @param PurchaseUnitSanitizer $purchase_unit_sanitizer The purchase unit sanitizer.
|
||||
*/
|
||||
public function __construct( Cache $cache, PurchaseUnitSanitizer $purchase_unit_sanitizer ) {
|
||||
$this->cache = $cache;
|
||||
$this->purchase_unit_sanitizer = $purchase_unit_sanitizer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the created PayPal order.
|
||||
*
|
||||
* @param Order $order The PayPal order.
|
||||
* @return void
|
||||
*/
|
||||
public function on_order_created( Order $order ): void {
|
||||
$message = $this->purchase_unit_sanitizer->get_last_message();
|
||||
$this->add_order_note( $order, $message );
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the created WooCommerce order.
|
||||
*
|
||||
* @param WC_Order $wc_order The WooCommerce order.
|
||||
* @param Order $order The PayPal order.
|
||||
* @return void
|
||||
*/
|
||||
public function on_woocommerce_order_created( WC_Order $wc_order, Order $order ): void {
|
||||
$cache_key = $this->cache_key( $order );
|
||||
|
||||
if ( ! $cache_key ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->apply_order_notes( $order, $wc_order );
|
||||
$this->cache->delete( $cache_key );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an order note associated with a PayPal order.
|
||||
* It can be added to a WooCommerce order associated with this PayPal order in the future.
|
||||
*
|
||||
* @param Order $order The PayPal order.
|
||||
* @param string $message The message to be added to order notes.
|
||||
* @return void
|
||||
*/
|
||||
private function add_order_note( Order $order, string $message ): void {
|
||||
if ( ! $message ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$cache_key = $this->cache_key( $order );
|
||||
|
||||
if ( ! $cache_key ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transient = $this->cache->get( $cache_key );
|
||||
|
||||
if ( ! is_array( $transient ) ) {
|
||||
$transient = array();
|
||||
}
|
||||
|
||||
if ( ! is_array( $transient['notes'] ) ) {
|
||||
$transient['notes'] = array();
|
||||
}
|
||||
|
||||
$transient['notes'][] = $message;
|
||||
|
||||
$this->cache->set( $cache_key, $transient, self::CACHE_TIMEOUT );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an order note associated with a PayPal order.
|
||||
* It can be added to a WooCommerce order associated with this PayPal order in the future.
|
||||
*
|
||||
* @param Order $order The PayPal order.
|
||||
* @param WC_Order $wc_order The WooCommerce order.
|
||||
* @return void
|
||||
*/
|
||||
private function apply_order_notes( Order $order, WC_Order $wc_order ): void {
|
||||
$cache_key = $this->cache_key( $order );
|
||||
|
||||
if ( ! $cache_key ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$transient = $this->cache->get( $cache_key );
|
||||
|
||||
if ( ! is_array( $transient ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! is_array( $transient['notes'] ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $transient['notes'] as $note ) {
|
||||
if ( ! is_string( $note ) ) {
|
||||
continue;
|
||||
}
|
||||
$wc_order->add_order_note( $note );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Build cache key.
|
||||
*
|
||||
* @param Order $order The PayPal order.
|
||||
* @return string|null
|
||||
*/
|
||||
private function cache_key( Order $order ): ?string {
|
||||
if ( ! $order->id() ) {
|
||||
return null;
|
||||
}
|
||||
return implode( '_', array( self::CACHE_KEY . $order->id() ) );
|
||||
}
|
||||
|
||||
}
|
|
@ -68,6 +68,12 @@ class PurchaseUnitSanitizer {
|
|||
*/
|
||||
private $extra_line_name;
|
||||
|
||||
/**
|
||||
* The last message. To be added to order notes.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $last_message = '';
|
||||
|
||||
/**
|
||||
* PurchaseUnitSanitizer constructor.
|
||||
|
@ -201,6 +207,8 @@ class PurchaseUnitSanitizer {
|
|||
$line_name = $this->extra_line_name;
|
||||
$roundings_money = new Money( $item_mismatch, $this->currency_code() );
|
||||
$this->purchase_unit['items'][] = ( new Item( $line_name, $roundings_money, 1 ) )->to_array();
|
||||
|
||||
$this->last_message = __( 'Item amount mismatch. Extra line added.', 'woocommerce-paypal-payments' );
|
||||
}
|
||||
|
||||
$item_mismatch = $this->calculate_item_mismatch();
|
||||
|
@ -210,6 +218,7 @@ class PurchaseUnitSanitizer {
|
|||
// Ditch items.
|
||||
if ( $this->allow_ditch_items && isset( $this->purchase_unit['items'] ) ) {
|
||||
unset( $this->purchase_unit['items'] );
|
||||
$this->last_message = __( 'Item amount mismatch. Items ditched.', 'woocommerce-paypal-payments' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,6 +260,8 @@ class PurchaseUnitSanitizer {
|
|||
if ( isset( $this->purchase_unit['amount']['breakdown'] ) ) {
|
||||
unset( $this->purchase_unit['amount']['breakdown'] );
|
||||
}
|
||||
|
||||
$this->last_message = __( 'Breakdown mismatch. Items and breakdown ditched.', 'woocommerce-paypal-payments' );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -334,4 +345,14 @@ class PurchaseUnitSanitizer {
|
|||
|
||||
return $amount_str - $amount_total_str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last sanitization message.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_last_message(): string {
|
||||
return $this->last_message;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ return array(
|
|||
$session_handler = $container->get( 'session.handler' );
|
||||
$settings = $container->get( 'wcgateway.settings' );
|
||||
$early_order_handler = $container->get( 'button.helper.early-order-handler' );
|
||||
$registration_needed = $container->get( 'button.current-user-must-register' );
|
||||
$registration_needed = $container->get( 'button.current-user-must-register' );
|
||||
$logger = $container->get( 'woocommerce.logger.woocommerce' );
|
||||
return new CreateOrderEndpoint(
|
||||
$request_data,
|
||||
|
|
|
@ -25,6 +25,7 @@ use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
|
|||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PayerFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\PurchaseUnitFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Factory\ShippingPreferenceFactory;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderTransient;
|
||||
use WooCommerce\PayPalCommerce\Button\Exception\ValidationException;
|
||||
use WooCommerce\PayPalCommerce\Button\Validation\CheckoutFormValidator;
|
||||
use WooCommerce\PayPalCommerce\Button\Helper\EarlyOrderHandler;
|
||||
|
@ -330,6 +331,8 @@ class CreateOrderEndpoint implements EndpointInterface {
|
|||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
||||
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||
$wc_order->save_meta_data();
|
||||
|
||||
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
||||
}
|
||||
|
||||
wp_send_json_success( $this->make_response( $order ) );
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\Button\Helper;
|
|||
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Exception\PayPalApiException;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderTransient;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\State;
|
||||
use WooCommerce\PayPalCommerce\Session\SessionHandler;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
@ -163,6 +164,10 @@ class EarlyOrderHandler {
|
|||
/**
|
||||
* Patch Order so we have the \WC_Order id added.
|
||||
*/
|
||||
return $this->order_processor->patch_order( $wc_order, $order );
|
||||
$order = $this->order_processor->patch_order( $wc_order, $order );
|
||||
|
||||
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
||||
|
||||
return $order;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace WooCommerce\PayPalCommerce\WcGateway\Processor;
|
|||
|
||||
use WC_Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Entity\Order;
|
||||
use WooCommerce\PayPalCommerce\ApiClient\Helper\OrderTransient;
|
||||
use WooCommerce\PayPalCommerce\Onboarding\Environment;
|
||||
use WooCommerce\PayPalCommerce\WcGateway\Gateway\PayPalGateway;
|
||||
|
||||
|
@ -22,14 +23,16 @@ trait OrderMetaTrait {
|
|||
/**
|
||||
* Adds common metadata to the order.
|
||||
*
|
||||
* @param WC_Order $wc_order The WC order to which metadata will be added.
|
||||
* @param Order $order The PayPal order.
|
||||
* @param Environment $environment The environment.
|
||||
* @param WC_Order $wc_order The WC order to which metadata will be added.
|
||||
* @param Order $order The PayPal order.
|
||||
* @param Environment $environment The environment.
|
||||
* @param OrderTransient|null $order_transient The order transient helper.
|
||||
*/
|
||||
protected function add_paypal_meta(
|
||||
WC_Order $wc_order,
|
||||
Order $order,
|
||||
Environment $environment
|
||||
Environment $environment,
|
||||
OrderTransient $order_transient = null
|
||||
): void {
|
||||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
||||
$wc_order->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||
|
@ -43,6 +46,8 @@ trait OrderMetaTrait {
|
|||
}
|
||||
|
||||
$wc_order->save();
|
||||
|
||||
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -259,6 +259,11 @@
|
|||
<code>DAY_IN_SECONDS</code>
|
||||
</UndefinedConstant>
|
||||
</file>
|
||||
<file src="modules/ppcp-api-client/src/Helper/OrderTransient.php">
|
||||
<UndefinedConstant occurrences="1">
|
||||
<code>DAY_IN_SECONDS</code>
|
||||
</UndefinedConstant>
|
||||
</file>
|
||||
<file src="modules/ppcp-button/services.php">
|
||||
<PossiblyFalseArgument occurrences="1">
|
||||
<code>realpath( __FILE__ )</code>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue