Merge pull request #19380 from woocommerce/update/19302

Override supports for PayPal to see if credentials exist
This commit is contained in:
Claudio Sanches 2018-04-06 15:44:42 -03:00 committed by GitHub
commit 900c8fc33f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 126 additions and 8 deletions

View File

@ -388,6 +388,18 @@ abstract class WC_Payment_Gateway extends WC_Settings_API {
return apply_filters( 'woocommerce_payment_gateway_supports', in_array( $feature, $this->supports ), $feature, $this );
}
/**
* Can the order be refunded via this gateway?
*
* Should be extended by gateways to do their own checks.
*
* @param WC_Order $order Order object.
* @return bool If false, the automatic refund button is hidden in the UI.
*/
public function can_refund_order( $order ) {
return $order && $this->supports( 'refunds' );
}
/**
* Core credit card form which gateways can used if needed. Deprecated - inherit WC_Payment_Gateway_CC instead.
*

View File

@ -292,12 +292,14 @@ if ( wc_tax_enabled() ) {
<div class="clear"></div>
<div class="refund-actions">
<?php
$refund_amount = '<span class="wc-order-refund-amount">' . wc_price( 0, array( 'currency' => $order->get_currency() ) ) . '</span>';
$gateway_supports_refunds = false !== $payment_gateway && $payment_gateway->supports( 'refunds' );
$gateway_name = false !== $payment_gateway ? ( ! empty( $payment_gateway->method_title ) ? $payment_gateway->method_title : $payment_gateway->get_title() ) : __( 'Payment gateway', 'woocommerce' );
$refund_amount = '<span class="wc-order-refund-amount">' . wc_price( 0, array( 'currency' => $order->get_currency() ) ) . '</span>';
$gateway_name = false !== $payment_gateway ? ( ! empty( $payment_gateway->method_title ) ? $payment_gateway->method_title : $payment_gateway->get_title() ) : __( 'Payment gateway', 'woocommerce' );
if ( false !== $payment_gateway && $payment_gateway->can_refund_order( $order ) ) {
/* translators: refund amount, gateway name */
echo '<button type="button" class="button button-primary do-api-refund">' . sprintf( esc_html__( 'Refund %1$s via %2$s', 'woocommerce' ), wp_kses_post( $refund_amount ), esc_html( $gateway_name ) ) . '</button>';
}
?>
<?php /* translators: refund amount, gateway name */ ?>
<button type="button" class="button <?php echo $gateway_supports_refunds ? 'button-primary do-api-refund' : 'tips disabled'; ?>" <?php echo $gateway_supports_refunds ? '' : 'data-tip="' . esc_attr__( 'The payment gateway used to place this order does not support automatic refunds.', 'woocommerce' ) . '"'; ?>><?php printf( esc_html__( 'Refund %1$s via %2$s', 'woocommerce' ), $refund_amount, $gateway_name ); ?></button>
<?php /* translators: refund amount */ ?>
<button type="button" class="button button-primary do-manual-refund tips" data-tip="<?php esc_attr_e( 'You will need to manually issue a refund through your payment gateway after using this.', 'woocommerce' ); ?>"><?php printf( esc_html__( 'Refund %s manually', 'woocommerce' ), $refund_amount ); ?></button>
<button type="button" class="button cancel-action"><?php esc_html_e( 'Cancel', 'woocommerce' ); ?></button>

View File

@ -294,7 +294,15 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway {
* @return bool
*/
public function can_refund_order( $order ) {
return $order && $order->get_transaction_id();
$has_api_creds = false;
if ( $this->testmode ) {
$has_api_creds = $this->get_option( 'sandbox_api_username' ) && $this->get_option( 'sandbox_api_password' ) && $this->get_option( 'sandbox_api_signature' );
} else {
$has_api_creds = $this->get_option( 'api_username' ) && $this->get_option( 'api_password' ) && $this->get_option( 'api_signature' );
}
return $order && $order->get_transaction_id() && $has_api_creds;
}
/**
@ -321,8 +329,7 @@ class WC_Gateway_Paypal extends WC_Payment_Gateway {
$order = wc_get_order( $order_id );
if ( ! $this->can_refund_order( $order ) ) {
$this->log( 'Refund Failed: No transaction ID', 'error' );
return new WP_Error( 'error', __( 'Refund failed: No transaction ID', 'woocommerce' ) );
return new WP_Error( 'error', __( 'Refund failed.', 'woocommerce' ) );
}
$this->init_api();

View File

@ -105,6 +105,7 @@ class WC_Unit_Tests_Bootstrap {
require_once $this->tests_dir . '/framework/class-wc-mock-session-handler.php';
require_once $this->tests_dir . '/framework/class-wc-mock-wc-data.php';
require_once $this->tests_dir . '/framework/class-wc-mock-wc-object-query.php';
require_once $this->tests_dir . '/framework/class-wc-mock-payment-gateway.php';
require_once $this->tests_dir . '/framework/class-wc-payment-token-stub.php';
require_once $this->tests_dir . '/framework/vendor/class-wp-test-spy-rest-server.php';

View File

@ -0,0 +1,21 @@
<?php
class WC_Mock_Payment_Gateway extends WC_Payment_Gateway {
/**
* Constructor for the gateway.
*/
public function __construct() {
$this->id = 'mock';
$this->has_fields = false;
$this->order_button_text = __( 'Proceed to PayPal', 'woocommerce' );
$this->method_title = 'Mock Gateway';
$this->method_description = 'Mock Gateway for unit tests';
$this->supports = array(
'products',
);
// Load the settings.
$this->init_form_fields();
$this->init_settings();
}
}

View File

@ -0,0 +1,75 @@
<?php
/**
* Unit tests for gateways.
*
* @package WooCommerce\Tests\Gateways
*/
class WC_Tests_Gateways extends WC_Unit_Test_Case {
/**
* Test for supports() method.
*/
public function test_supports() {
$gateway = new WC_Mock_Payment_Gateway();
$this->assertTrue( $gateway->supports( 'products' ) );
$this->assertFalse( $gateway->supports( 'made-up-feature' ) );
}
/**
* Test for supports() method.
*/
public function test_can_refund_order() {
$gateway = new WC_Mock_Payment_Gateway();
$order = WC_Helper_Order::create_order();
$order->set_payment_method( 'mock' );
$order->set_transaction_id( '12345' );
$order->save();
$this->assertFalse( $gateway->can_refund_order( $order ) );
$gateway->supports[] = 'refunds';
$this->assertTrue( $gateway->can_refund_order( $order ) );
// Cleanup.
$order->delete( true );
}
/**
* Test for PayPal supports() method.
*/
public function test_paypal_can_refund_order() {
$gateway = new WC_Gateway_Paypal();
$order = WC_Helper_Order::create_order();
$order->set_payment_method( 'paypal' );
$order->set_transaction_id( '12345' );
$order->save();
// Refunds won't work without credentials.
$this->assertFalse( $gateway->can_refund_order( $order ) );
// Add API credentials.
$settings = array(
'testmode' => 'yes',
'sandbox_api_username' => 'test',
'sandbox_api_password' => 'test',
'sandbox_api_signature' => 'test',
);
update_option( 'woocommerce_paypal_settings ', $settings );
$gateway = new WC_Gateway_Paypal();
$this->assertTrue( $gateway->can_refund_order( $order ) );
// Refund requires transaction ID.
$order->set_transaction_id( '' );
$order->save();
$this->assertFalse( $gateway->can_refund_order( $order ) );
// Cleanup.
delete_option( 'woocommerce_paypal_settings' );
$order->delete( true );
}
}