mirror of
https://github.com/woocommerce/woocommerce-paypal-payments.git
synced 2025-09-06 13:44:42 +08:00
Merge pull request #2125 from woocommerce/PCP-285-feature-request-more-fraud-prevention-capabilities-by-storing-additional-data-in-the-order
feature request: more fraud prevention capabilities by storing additional data in the order (285)
This commit is contained in:
commit
bb8734d788
13 changed files with 156 additions and 21 deletions
|
@ -990,11 +990,21 @@ document.querySelector("#payment").before(document.querySelector("#ppcp-messages
|
||||||
if ( $this->settings->has( '3d_secure_contingency' ) ) {
|
if ( $this->settings->has( '3d_secure_contingency' ) ) {
|
||||||
$value = $this->settings->get( '3d_secure_contingency' );
|
$value = $this->settings->get( '3d_secure_contingency' );
|
||||||
if ( $value ) {
|
if ( $value ) {
|
||||||
return $value;
|
return $this->return_3ds_contingency( $value );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'SCA_WHEN_REQUIRED';
|
return $this->return_3ds_contingency( 'SCA_WHEN_REQUIRED' );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes and returns the 3D Secure contingency.
|
||||||
|
*
|
||||||
|
* @param string $contingency The ThreeD secure contingency.
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function return_3ds_contingency( string $contingency ): string {
|
||||||
|
return apply_filters( 'woocommerce_paypal_payments_three_d_secure_contingency', $contingency );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -329,6 +329,21 @@ class CreateOrderEndpoint implements EndpointInterface {
|
||||||
if ( 'pay-now' === $data['context'] && is_a( $wc_order, \WC_Order::class ) ) {
|
if ( 'pay-now' === $data['context'] && is_a( $wc_order, \WC_Order::class ) ) {
|
||||||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
$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->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||||
|
|
||||||
|
$payment_source = $order->payment_source();
|
||||||
|
$payment_source_name = $payment_source ? $payment_source->name() : null;
|
||||||
|
$payer = $order->payer();
|
||||||
|
if (
|
||||||
|
$payer
|
||||||
|
&& $payment_source_name
|
||||||
|
&& in_array( $payment_source_name, PayPalGateway::PAYMENT_SOURCES_WITH_PAYER_EMAIL, true )
|
||||||
|
) {
|
||||||
|
$payer_email = $payer->email_address();
|
||||||
|
if ( $payer_email ) {
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYER_EMAIL_META_KEY, $payer_email );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$wc_order->save_meta_data();
|
$wc_order->save_meta_data();
|
||||||
|
|
||||||
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
||||||
|
|
|
@ -159,6 +159,22 @@ class EarlyOrderHandler {
|
||||||
$wc_order = wc_get_order( $order_id );
|
$wc_order = wc_get_order( $order_id );
|
||||||
$wc_order->update_meta_data( PayPalGateway::ORDER_ID_META_KEY, $order->id() );
|
$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->update_meta_data( PayPalGateway::INTENT_META_KEY, $order->intent() );
|
||||||
|
|
||||||
|
$payment_source = $order->payment_source();
|
||||||
|
$payment_source_name = $payment_source ? $payment_source->name() : null;
|
||||||
|
$payer = $order->payer();
|
||||||
|
if (
|
||||||
|
$payer
|
||||||
|
&& $payment_source_name
|
||||||
|
&& in_array( $payment_source_name, PayPalGateway::PAYMENT_SOURCES_WITH_PAYER_EMAIL, true )
|
||||||
|
&& $wc_order instanceof \WC_Order
|
||||||
|
) {
|
||||||
|
$payer_email = $payer->email_address();
|
||||||
|
if ( $payer_email ) {
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYER_EMAIL_META_KEY, $payer_email );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$wc_order->save_meta_data();
|
$wc_order->save_meta_data();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -57,21 +57,24 @@ class ThreeDSecure {
|
||||||
*
|
*
|
||||||
* @link https://developer.paypal.com/docs/business/checkout/add-capabilities/3d-secure/#authenticationresult
|
* @link https://developer.paypal.com/docs/business/checkout/add-capabilities/3d-secure/#authenticationresult
|
||||||
*
|
*
|
||||||
* @param Order $order The order for which the decission is needed.
|
* @param Order $order The order for which the decision is needed.
|
||||||
*
|
*
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function proceed_with_order( Order $order ): int {
|
public function proceed_with_order( Order $order ): int {
|
||||||
|
|
||||||
|
do_action( 'woocommerce_paypal_payments_three_d_secure_before_check', $order );
|
||||||
|
|
||||||
$payment_source = $order->payment_source();
|
$payment_source = $order->payment_source();
|
||||||
if ( ! $payment_source ) {
|
if ( ! $payment_source ) {
|
||||||
return self::NO_DECISION;
|
return $this->return_decision( self::NO_DECISION, $order );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! ( $payment_source->properties()->brand ?? '' ) ) {
|
if ( ! ( $payment_source->properties()->brand ?? '' ) ) {
|
||||||
return self::NO_DECISION;
|
return $this->return_decision( self::NO_DECISION, $order );
|
||||||
}
|
}
|
||||||
if ( ! ( $payment_source->properties()->authentication_result ?? '' ) ) {
|
if ( ! ( $payment_source->properties()->authentication_result ?? '' ) ) {
|
||||||
return self::NO_DECISION;
|
return $this->return_decision( self::NO_DECISION, $order );
|
||||||
}
|
}
|
||||||
|
|
||||||
$authentication_result = $payment_source->properties()->authentication_result ?? null;
|
$authentication_result = $payment_source->properties()->authentication_result ?? null;
|
||||||
|
@ -81,18 +84,31 @@ class ThreeDSecure {
|
||||||
$this->logger->info( '3DS Authentication Result: ' . wc_print_r( $result->to_array(), true ) );
|
$this->logger->info( '3DS Authentication Result: ' . wc_print_r( $result->to_array(), true ) );
|
||||||
|
|
||||||
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_POSSIBLE ) {
|
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_POSSIBLE ) {
|
||||||
return self::PROCCEED;
|
return $this->return_decision( self::PROCCEED, $order );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_UNKNOWN ) {
|
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_UNKNOWN ) {
|
||||||
return self::RETRY;
|
return $this->return_decision( self::RETRY, $order );
|
||||||
}
|
}
|
||||||
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_NO ) {
|
if ( $result->liability_shift() === AuthResult::LIABILITY_SHIFT_NO ) {
|
||||||
return $this->no_liability_shift( $result );
|
return $this->return_decision( $this->no_liability_shift( $result ), $order );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self::NO_DECISION;
|
return $this->return_decision( self::NO_DECISION, $order );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes and returns a ThreeD secure decision.
|
||||||
|
*
|
||||||
|
* @param int $decision The ThreeD secure decision.
|
||||||
|
* @param Order $order The PayPal Order object.
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function return_decision( int $decision, Order $order ) {
|
||||||
|
$decision = apply_filters( 'woocommerce_paypal_payments_three_d_secure_decision', $decision, $order );
|
||||||
|
do_action( 'woocommerce_paypal_payments_three_d_secure_after_check', $order, $decision );
|
||||||
|
return $decision;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -115,17 +115,19 @@ class CardFieldsModule implements ModuleInterface {
|
||||||
$settings = $c->get( 'wcgateway.settings' );
|
$settings = $c->get( 'wcgateway.settings' );
|
||||||
assert( $settings instanceof Settings );
|
assert( $settings instanceof Settings );
|
||||||
|
|
||||||
|
$three_d_secure_contingency =
|
||||||
|
$settings->has( '3d_secure_contingency' )
|
||||||
|
? apply_filters( 'woocommerce_paypal_payments_three_d_secure_contingency', $settings->get( '3d_secure_contingency' ) )
|
||||||
|
: '';
|
||||||
|
|
||||||
if (
|
if (
|
||||||
$settings->has( '3d_secure_contingency' )
|
$three_d_secure_contingency === 'SCA_ALWAYS'
|
||||||
&& (
|
|| $three_d_secure_contingency === 'SCA_WHEN_REQUIRED'
|
||||||
$settings->get( '3d_secure_contingency' ) === 'SCA_ALWAYS'
|
|
||||||
|| $settings->get( '3d_secure_contingency' ) === 'SCA_WHEN_REQUIRED'
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
$data['payment_source']['card'] = array(
|
$data['payment_source']['card'] = array(
|
||||||
'attributes' => array(
|
'attributes' => array(
|
||||||
'verification' => array(
|
'verification' => array(
|
||||||
'method' => $settings->get( '3d_secure_contingency' ),
|
'method' => $three_d_secure_contingency,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -281,7 +281,11 @@ class SavePaymentMethodsModule implements ModuleInterface {
|
||||||
|
|
||||||
$settings = $c->get( 'wcgateway.settings' );
|
$settings = $c->get( 'wcgateway.settings' );
|
||||||
assert( $settings instanceof Settings );
|
assert( $settings instanceof Settings );
|
||||||
$verification_method = $settings->has( '3d_secure_contingency' ) ? $settings->get( '3d_secure_contingency' ) : '';
|
|
||||||
|
$verification_method =
|
||||||
|
$settings->has( '3d_secure_contingency' )
|
||||||
|
? apply_filters( 'woocommerce_paypal_payments_three_d_secure_contingency', $settings->get( '3d_secure_contingency' ) )
|
||||||
|
: '';
|
||||||
|
|
||||||
$change_payment_method = wc_clean( wp_unslash( $_GET['change_payment_method'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
$change_payment_method = wc_clean( wp_unslash( $_GET['change_payment_method'] ?? '' ) ); // phpcs:ignore WordPress.Security.NonceVerification
|
||||||
|
|
||||||
|
|
|
@ -48,12 +48,18 @@ class PayPalGateway extends \WC_Payment_Gateway {
|
||||||
const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
|
const ORDER_ID_META_KEY = '_ppcp_paypal_order_id';
|
||||||
const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
|
const ORDER_PAYMENT_MODE_META_KEY = '_ppcp_paypal_payment_mode';
|
||||||
const ORDER_PAYMENT_SOURCE_META_KEY = '_ppcp_paypal_payment_source';
|
const ORDER_PAYMENT_SOURCE_META_KEY = '_ppcp_paypal_payment_source';
|
||||||
|
const ORDER_PAYER_EMAIL_META_KEY = '_ppcp_paypal_payer_email';
|
||||||
const FEES_META_KEY = '_ppcp_paypal_fees';
|
const FEES_META_KEY = '_ppcp_paypal_fees';
|
||||||
const REFUND_FEES_META_KEY = '_ppcp_paypal_refund_fees';
|
const REFUND_FEES_META_KEY = '_ppcp_paypal_refund_fees';
|
||||||
const REFUNDS_META_KEY = '_ppcp_refunds';
|
const REFUNDS_META_KEY = '_ppcp_refunds';
|
||||||
const THREE_D_AUTH_RESULT_META_KEY = '_ppcp_paypal_3DS_auth_result';
|
const THREE_D_AUTH_RESULT_META_KEY = '_ppcp_paypal_3DS_auth_result';
|
||||||
const FRAUD_RESULT_META_KEY = '_ppcp_paypal_fraud_result';
|
const FRAUD_RESULT_META_KEY = '_ppcp_paypal_fraud_result';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of payment sources wich we are expected to store the payer email in the WC Order metadata.
|
||||||
|
*/
|
||||||
|
const PAYMENT_SOURCES_WITH_PAYER_EMAIL = array( 'paypal', 'paylater', 'venmo' );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Settings Renderer.
|
* The Settings Renderer.
|
||||||
*
|
*
|
||||||
|
|
|
@ -76,7 +76,7 @@ trait CreditCardOrderInfoHandlingTrait {
|
||||||
/**
|
/**
|
||||||
* Fired when the 3DS information is added to WC order.
|
* Fired when the 3DS information is added to WC order.
|
||||||
*/
|
*/
|
||||||
do_action( 'woocommerce_paypal_payments_thee_d_secure_added', $wc_order, $order );
|
do_action( 'woocommerce_paypal_payments_three_d_secure_added', $wc_order, $order );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,8 +96,9 @@ trait CreditCardOrderInfoHandlingTrait {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fraud_responses = $fraud->to_array();
|
$fraud_responses = $fraud->to_array();
|
||||||
$card_brand = $payment_source->properties()->brand ?? __( 'N/A', 'woocommerce-paypal-payments' );
|
$card_brand = $payment_source->properties()->brand ?? __( 'N/A', 'woocommerce-paypal-payments' );
|
||||||
|
$card_last_digits = $payment_source->properties()->last_digits ?? __( 'N/A', 'woocommerce-paypal-payments' );
|
||||||
|
|
||||||
$avs_response_order_note_title = __( 'Address Verification Result', 'woocommerce-paypal-payments' );
|
$avs_response_order_note_title = __( 'Address Verification Result', 'woocommerce-paypal-payments' );
|
||||||
/* translators: %1$s is AVS order note title, %2$s is AVS order note result markup */
|
/* translators: %1$s is AVS order note title, %2$s is AVS order note result markup */
|
||||||
|
@ -109,6 +110,7 @@ trait CreditCardOrderInfoHandlingTrait {
|
||||||
<li>%3$s</li>
|
<li>%3$s</li>
|
||||||
</ul>
|
</ul>
|
||||||
<li>%4$s</li>
|
<li>%4$s</li>
|
||||||
|
<li>%5$s</li>
|
||||||
</ul>';
|
</ul>';
|
||||||
$avs_response_order_note_result = sprintf(
|
$avs_response_order_note_result = sprintf(
|
||||||
$avs_response_order_note_result_format,
|
$avs_response_order_note_result_format,
|
||||||
|
@ -119,7 +121,9 @@ trait CreditCardOrderInfoHandlingTrait {
|
||||||
/* translators: %s is fraud AVS postal match */
|
/* translators: %s is fraud AVS postal match */
|
||||||
sprintf( __( 'Postal Match: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['postal_match'] ) ),
|
sprintf( __( 'Postal Match: %s', 'woocommerce-paypal-payments' ), esc_html( $fraud_responses['postal_match'] ) ),
|
||||||
/* translators: %s is card brand */
|
/* translators: %s is card brand */
|
||||||
sprintf( __( 'Card Brand: %s', 'woocommerce-paypal-payments' ), esc_html( $card_brand ) )
|
sprintf( __( 'Card Brand: %s', 'woocommerce-paypal-payments' ), esc_html( $card_brand ) ),
|
||||||
|
/* translators: %s card last digits */
|
||||||
|
sprintf( __( 'Card Last Digits: %s', 'woocommerce-paypal-payments' ), esc_html( $card_last_digits ) )
|
||||||
);
|
);
|
||||||
$avs_response_order_note = sprintf(
|
$avs_response_order_note = sprintf(
|
||||||
$avs_response_order_note_format,
|
$avs_response_order_note_format,
|
||||||
|
|
|
@ -45,6 +45,18 @@ trait OrderMetaTrait {
|
||||||
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYMENT_SOURCE_META_KEY, $payment_source );
|
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYMENT_SOURCE_META_KEY, $payment_source );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$payer = $order->payer();
|
||||||
|
if (
|
||||||
|
$payer
|
||||||
|
&& $payment_source
|
||||||
|
&& in_array( $payment_source, PayPalGateway::PAYMENT_SOURCES_WITH_PAYER_EMAIL, true )
|
||||||
|
) {
|
||||||
|
$payer_email = $payer->email_address();
|
||||||
|
if ( $payer_email ) {
|
||||||
|
$wc_order->update_meta_data( PayPalGateway::ORDER_PAYER_EMAIL_META_KEY, $payer_email );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$wc_order->save();
|
$wc_order->save();
|
||||||
|
|
||||||
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
do_action( 'woocommerce_paypal_payments_woocommerce_order_created', $wc_order, $order );
|
||||||
|
|
|
@ -448,6 +448,49 @@ class WCGatewayModule implements ModuleInterface {
|
||||||
delete_transient( 'ppcp_reference_transaction_enabled' );
|
delete_transient( 'ppcp_reference_transaction_enabled' );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Param types removed to avoid third-party issues.
|
||||||
|
*
|
||||||
|
* @psalm-suppress MissingClosureParamType
|
||||||
|
*/
|
||||||
|
add_filter(
|
||||||
|
'woocommerce_admin_billing_fields',
|
||||||
|
function ( $fields ) {
|
||||||
|
global $theorder;
|
||||||
|
|
||||||
|
if ( ! is_array( $fields ) ) {
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! $theorder instanceof WC_Order ) {
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
$email = $theorder->get_meta( PayPalGateway::ORDER_PAYER_EMAIL_META_KEY ) ?: '';
|
||||||
|
|
||||||
|
if ( ! $email ) {
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is payment source is paypal exclude all non paypal funding sources.
|
||||||
|
$payment_source = $theorder->get_meta( PayPalGateway::ORDER_PAYMENT_SOURCE_META_KEY ) ?: '';
|
||||||
|
$is_paypal_funding_source = ( strpos( $theorder->get_payment_method_title(), '(via PayPal)' ) === false );
|
||||||
|
|
||||||
|
if ( $payment_source === 'paypal' && ! $is_paypal_funding_source ) {
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fields['paypal_email'] = array(
|
||||||
|
'label' => __( 'PayPal email address', 'woocommerce-paypal-payments' ),
|
||||||
|
'value' => $email,
|
||||||
|
'wrapper_class' => 'form-field-wide',
|
||||||
|
'custom_attributes' => array( 'disabled' => 'disabled' ),
|
||||||
|
);
|
||||||
|
|
||||||
|
return $fields;
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -92,6 +92,8 @@ class VaultedCreditCardHandlerTest extends TestCase
|
||||||
$customer = Mockery::mock(WC_Customer::class);
|
$customer = Mockery::mock(WC_Customer::class);
|
||||||
|
|
||||||
$payer = Mockery::mock(Payer::class);
|
$payer = Mockery::mock(Payer::class);
|
||||||
|
$payer->shouldReceive('email_address');
|
||||||
|
|
||||||
$this->payerFactory->shouldReceive('from_wc_order')
|
$this->payerFactory->shouldReceive('from_wc_order')
|
||||||
->andReturn($payer);
|
->andReturn($payer);
|
||||||
$this->shippingPreferenceFactory->shouldReceive('from_state')
|
$this->shippingPreferenceFactory->shouldReceive('from_state')
|
||||||
|
@ -100,6 +102,7 @@ class VaultedCreditCardHandlerTest extends TestCase
|
||||||
$order = Mockery::mock(Order::class);
|
$order = Mockery::mock(Order::class);
|
||||||
$order->shouldReceive('id')->andReturn('1');
|
$order->shouldReceive('id')->andReturn('1');
|
||||||
$order->shouldReceive('intent')->andReturn('CAPTURE');
|
$order->shouldReceive('intent')->andReturn('CAPTURE');
|
||||||
|
$order->shouldReceive('payer')->andReturn($payer);
|
||||||
|
|
||||||
$paymentSource = Mockery::mock(PaymentSource::class);
|
$paymentSource = Mockery::mock(PaymentSource::class);
|
||||||
$paymentSource->shouldReceive('name')->andReturn('card');
|
$paymentSource->shouldReceive('name')->andReturn('card');
|
||||||
|
|
|
@ -89,6 +89,7 @@ private $testee;
|
||||||
$order->shouldReceive('id')->andReturn('1');
|
$order->shouldReceive('id')->andReturn('1');
|
||||||
$order->shouldReceive('intent');
|
$order->shouldReceive('intent');
|
||||||
$order->shouldReceive('payment_source');
|
$order->shouldReceive('payment_source');
|
||||||
|
$order->shouldReceive('payer');
|
||||||
|
|
||||||
$this->orderEndpoint
|
$this->orderEndpoint
|
||||||
->shouldReceive('create')
|
->shouldReceive('create')
|
||||||
|
|
|
@ -93,6 +93,7 @@ class OrderProcessorTest extends TestCase
|
||||||
$currentOrder
|
$currentOrder
|
||||||
->shouldReceive('payment_source')
|
->shouldReceive('payment_source')
|
||||||
->andReturn(null);
|
->andReturn(null);
|
||||||
|
$currentOrder->shouldReceive('payer');
|
||||||
|
|
||||||
$wcOrder
|
$wcOrder
|
||||||
->shouldReceive('get_meta')
|
->shouldReceive('get_meta')
|
||||||
|
@ -230,6 +231,7 @@ class OrderProcessorTest extends TestCase
|
||||||
$currentOrder
|
$currentOrder
|
||||||
->shouldReceive('payment_source')
|
->shouldReceive('payment_source')
|
||||||
->andReturn(null);
|
->andReturn(null);
|
||||||
|
$currentOrder->shouldReceive('payer');
|
||||||
|
|
||||||
$wcOrder
|
$wcOrder
|
||||||
->shouldReceive('get_meta')
|
->shouldReceive('get_meta')
|
||||||
|
@ -357,6 +359,7 @@ class OrderProcessorTest extends TestCase
|
||||||
$currentOrder
|
$currentOrder
|
||||||
->shouldReceive('purchase_units')
|
->shouldReceive('purchase_units')
|
||||||
->andReturn([$purchaseUnit]);
|
->andReturn([$purchaseUnit]);
|
||||||
|
$currentOrder->shouldReceive('payer');
|
||||||
|
|
||||||
$wcOrder
|
$wcOrder
|
||||||
->shouldReceive('get_meta')
|
->shouldReceive('get_meta')
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue