diff --git a/modules/payment_form/src/Entity/Payment/PaymentForm.php b/modules/payment_form/src/Entity/Payment/PaymentForm.php
index 24fdbd7..4e81361 100644
--- a/modules/payment_form/src/Entity/Payment/PaymentForm.php
+++ b/modules/payment_form/src/Entity/Payment/PaymentForm.php
@@ -12,6 +12,7 @@ use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\StringTranslation\TranslationInterface;
 use Drupal\payment\Plugin\Payment\MethodSelector\PaymentMethodSelectorManagerInterface;
+use Drupal\payment\ResponseInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -101,7 +102,10 @@ class PaymentForm extends ContentEntityForm {
     $payment_method_selector->submitConfigurationForm($form['payment_method'], $form_state);
     $payment->setPaymentMethod($payment_method_selector->getPaymentMethod());
     $payment->save();
-    $payment->execute();
+    $status = $payment->execute();
+    if ($status instanceof ResponseInterface) {
+      $form_state->setRedirectUrl($status->getRedirectUrl());
+    }
   }
 
   /**
diff --git a/modules/payment_form/tests/src/Unit/Entity/Payment/PaymentFormUnitTest.php b/modules/payment_form/tests/src/Unit/Entity/Payment/PaymentFormUnitTest.php
index 5392b1e..f8e3208 100644
--- a/modules/payment_form/tests/src/Unit/Entity/Payment/PaymentFormUnitTest.php
+++ b/modules/payment_form/tests/src/Unit/Entity/Payment/PaymentFormUnitTest.php
@@ -8,6 +8,8 @@
 namespace Drupal\Tests\payment_form\Unit\Entity\Payment;
 
 use Drupal\Core\Form\FormState;
+use Drupal\Core\Url;
+use Drupal\payment\Response;
 use Drupal\payment_form\Entity\Payment\PaymentForm;
 use Drupal\Tests\UnitTestCase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -209,6 +211,9 @@ class PaymentFormUnitTest extends UnitTestCase {
    * @covers ::submitForm
    */
   public function testSubmitForm() {
+    $redirect_url = new Url($this->randomMachineName());
+    $payment_method_execution_status = new Response($redirect_url);
+
     $form = array(
       'payment_method' => array(
         '#type' => $this->randomMachineName(),
@@ -219,6 +224,9 @@ class PaymentFormUnitTest extends UnitTestCase {
       ->method('get')
       ->with('payment_method_selector')
       ->willReturn($this->paymentMethodSelector);
+    $form_state->expects($this->atLeastOnce())
+      ->method('setRedirectUrl')
+      ->with($redirect_url);
 
     $payment_method = $this->getMock('\Drupal\payment\Plugin\Payment\Method\PaymentMethodInterface');
 
@@ -235,7 +243,8 @@ class PaymentFormUnitTest extends UnitTestCase {
     $this->payment->expects($this->once())
       ->method('save');
     $this->payment->expects($this->once())
-      ->method('execute');
+      ->method('execute')
+      ->willReturn($payment_method_execution_status);
 
     $this->form->submitForm($form, $form_state);
   }
diff --git a/payment.routing.yml b/payment.routing.yml
index bc932ff..4ef2fb4 100644
--- a/payment.routing.yml
+++ b/payment.routing.yml
@@ -62,6 +62,14 @@ payment.payment.refund:
   options:
     _admin_route: TRUE
 
+payment.payment.complete:
+  path: '/payment/{payment}/complete'
+  defaults:
+    _entity_form: 'payment.complete'
+    _title: Complete payment
+  requirements:
+    _entity_access: 'payment.complete'
+
 payment.payment.delete:
   path: '/payment/{payment}/delete'
   defaults:
diff --git a/src/Controller/Payment.php b/src/Controller/Payment.php
index c72d6b4..dcc697a 100644
--- a/src/Controller/Payment.php
+++ b/src/Controller/Payment.php
@@ -11,6 +11,8 @@ use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\StringTranslation\TranslationInterface;
 use Drupal\payment\Entity\PaymentInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+use Symfony\Component\HttpFoundation\Response;
 
 /**
  * Returns responses for payment routes.
@@ -60,4 +62,21 @@ class Payment extends ControllerBase {
     ));
   }
 
+  /**
+   * Completes a payment.
+   *
+   * @param \Drupal\payment\Entity\PaymentInterface $payment
+   *
+   * @return \Symfony\Component\HttpFoundation\Response
+   */
+  public function complete(PaymentInterface $payment) {
+    $result = $payment->getPaymentMethod()->getPaymentExecutionResult();
+    if ($result->getCompletionResponse()->getResponse() instanceof Response) {
+      return $result->getCompletionResponse();
+    }
+    else {
+      return new RedirectResponse($result->getCompletionResponse()->getRedirectUrl()->toString());
+    }
+  }
+
 }
diff --git a/src/Entity/Payment.php b/src/Entity/Payment.php
index b81f779..78a1fcb 100644
--- a/src/Entity/Payment.php
+++ b/src/Entity/Payment.php
@@ -54,7 +54,8 @@ use Drupal\user\UserInterface;
  *     "delete-form" = "payment.payment.delete",
  *     "update-status-form" = "payment.payment.update_status",
  *     "capture-form" = "payment.payment.capture",
- *     "refund-form" = "payment.payment.refund"
+ *     "refund-form" = "payment.payment.refund",
+ *     "resume" = "payment.payment.resume"
  *   }
  * )
  */
diff --git a/src/Entity/Payment/PaymentAccessControlHandler.php b/src/Entity/Payment/PaymentAccessControlHandler.php
index 775228c..254be79 100644
--- a/src/Entity/Payment/PaymentAccessControlHandler.php
+++ b/src/Entity/Payment/PaymentAccessControlHandler.php
@@ -50,6 +50,11 @@ class PaymentAccessControlHandler extends EntityAccessControlHandler {
       }
       return AccessResult::forbidden();
     }
+    elseif ($operation == 'complete') {
+      return AccessResult::allowedIf($payment->getOwnerId() == $account->id())
+        ->andIf($payment->getPaymentMethod())
+        ->andIf($payment->getPaymentMethod()->getPaymentExecutionStatus() === TRUE);
+    }
     return $this->checkAccessPermission($payment, $operation, $account);
   }
 
diff --git a/src/Entity/Payment/PaymentListBuilder.php b/src/Entity/Payment/PaymentListBuilder.php
index 219fde6..ac2eb8a 100644
--- a/src/Entity/Payment/PaymentListBuilder.php
+++ b/src/Entity/Payment/PaymentListBuilder.php
@@ -192,6 +192,12 @@ class PaymentListBuilder extends EntityListBuilder {
           'url' => $entity->urlInfo('refund-form'),
         );
     }
+    if ($entity->access('complete')) {
+      $operations['resume'] = array(
+        'title' => $this->t('Complete'),
+        'url' => $entity->urlInfo('complete'),
+      );
+    }
 
     return $operations;
   }
diff --git a/src/PaymentExecutionResultInterface.php b/src/PaymentExecutionResultInterface.php
new file mode 100644
index 0000000..737aa1a
--- /dev/null
+++ b/src/PaymentExecutionResultInterface.php
@@ -0,0 +1,37 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\PaymentExecutionResultInterface.
+ */
+
+namespace Drupal\payment;
+
+/**
+ * Defines a payment execution result.
+ *
+ * This interface has nothing to do with payment statuses. Instead, it provides
+ * information about a payment's execution workflow, during which the payment's
+ * status can, but does not have to be changed.
+ */
+interface PaymentExecutionResultInterface {
+
+  /**
+   * Checks whether the execution process is still in progress.
+   *
+   * @return bool
+   *   Whether the execution process is still in progress. When TRUE is
+   *   returned, self::getCompletionResponse() MUST return a response.
+   */
+  public function isInProgress();
+
+  /**
+   * Gets the response to complete payment execution.
+   *
+   * @return \Drupal\payment\ResponseInterface|null
+   *   A response (only if self::isInProgress() returns TRUE) or NULL if payment
+   *   execution cannot be completed (anymore).
+   */
+  public function getCompletionResponse();
+
+}
diff --git a/src/Plugin/Payment/Method/Basic.php b/src/Plugin/Payment/Method/Basic.php
index ef05cce..2089256 100644
--- a/src/Plugin/Payment/Method/Basic.php
+++ b/src/Plugin/Payment/Method/Basic.php
@@ -39,44 +39,6 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 class Basic extends PaymentMethodBase implements ContainerFactoryPluginInterface, PaymentMethodCapturePaymentInterface, PaymentMethodRefundPaymentInterface, PaymentMethodUpdatePaymentStatusInterface {
 
   /**
-   * The payment status manager.
-   *
-   * @var \Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface
-   */
-  protected $paymentStatusManager;
-
-  /**
-   * Constructs a new class instance.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param array $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
-   *   The event dispatcher.
-   * @param \Drupal\Core\Utility\Token $token
-   *   The token API.
-   * @param \Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface
-   *   The payment status manager.
-   */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher, Token $token, PaymentStatusManagerInterface $payment_status_manager) {
-    $configuration += $this->defaultConfiguration();
-    parent::__construct($configuration, $plugin_id, $plugin_definition, $module_handler, $event_dispatcher, $token);
-    $this->paymentStatusManager = $payment_status_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('event_dispatcher'), $container->get('token'), $container->get('plugin.manager.payment.status'));
-  }
-
-  /**
    * {@inheritdoc}
    */
   public function getSupportedCurrencies() {
@@ -155,7 +117,13 @@ class Basic extends PaymentMethodBase implements ContainerFactoryPluginInterface
   protected function doExecutePayment() {
     $this->getPayment()->setPaymentStatus($this->paymentStatusManager->createInstance($this->getExecuteStatusId()));
     $this->getPayment()->save();
-    $this->getPayment()->getPaymentType()->resumeContext();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPaymentExecutionStatus() {
+    return $this->getPayment()->getPaymentStatus()->getPluginId() == $this->getExecuteStatusId();
   }
 
   /**
diff --git a/src/Plugin/Payment/Method/PaymentMethodBase.php b/src/Plugin/Payment/Method/PaymentMethodBase.php
index 0572b6d..714b3e9 100644
--- a/src/Plugin/Payment/Method/PaymentMethodBase.php
+++ b/src/Plugin/Payment/Method/PaymentMethodBase.php
@@ -18,6 +18,7 @@ use Drupal\payment\Event\PaymentExecuteAccess;
 use Drupal\payment\Event\PaymentPreCapture;
 use Drupal\payment\Event\PaymentPreExecute;
 use Drupal\payment\Event\PaymentPreRefund;
+use Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\EventDispatcher\EventDispatcherInterface;
 
@@ -54,6 +55,13 @@ abstract class PaymentMethodBase extends PluginBase implements ContainerFactoryP
   protected $payment;
 
   /**
+   * The payment status manager.
+   *
+   * @var \Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface
+   */
+  protected $paymentStatusManager;
+
+  /**
    * The token API.
    *
    * @var \Drupal\Core\Utility\Token
@@ -75,12 +83,15 @@ abstract class PaymentMethodBase extends PluginBase implements ContainerFactoryP
    *   The event dispatcher.
    * @param \Drupal\Core\Utility\Token $token
    *   The token API.
+   * @param \Drupal\payment\Plugin\Payment\Status\PaymentStatusManagerInterface
+   *   The payment status manager.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher, Token $token) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, ModuleHandlerInterface $module_handler, EventDispatcherInterface $event_dispatcher, Token $token, PaymentStatusManagerInterface $payment_status_manager) {
     $configuration += $this->defaultConfiguration();
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->eventDispatcher = $event_dispatcher;
     $this->moduleHandler = $module_handler;
+    $this->paymentStatusManager = $payment_status_manager;
     $this->token = $token;
   }
 
@@ -88,7 +99,7 @@ abstract class PaymentMethodBase extends PluginBase implements ContainerFactoryP
    * {@inheritdoc}
    */
   public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('event_dispatcher'), $container->get('token'));
+    return new static($configuration, $plugin_id, $plugin_definition, $container->get('module_handler'), $container->get('event_dispatcher'), $container->get('token'), $container->get('plugin.manager.payment.status'));
   }
 
   /**
@@ -235,6 +246,8 @@ abstract class PaymentMethodBase extends PluginBase implements ContainerFactoryP
     $this->eventDispatcher->dispatch(PaymentEvents::PAYMENT_PRE_EXECUTE, $event);
     // @todo invoke Rules event.
     $this->doExecutePayment();
+
+    return $this->getPaymentExecutionResult();
   }
 
   /**
diff --git a/src/Plugin/Payment/Method/PaymentMethodInterface.php b/src/Plugin/Payment/Method/PaymentMethodInterface.php
index 3e45743..52bb998 100644
--- a/src/Plugin/Payment/Method/PaymentMethodInterface.php
+++ b/src/Plugin/Payment/Method/PaymentMethodInterface.php
@@ -43,21 +43,23 @@ interface PaymentMethodInterface extends PluginInspectionInterface, Configurable
    * Executes the payment.
    *
    * When executing a payment, it may be authorized, or authorized and captured.
+   * After calling this method, more action may be required depending on the
+   * return value of self::getPaymentExecutionResult().
+   * This method MUST set the payment's status to "payment_pending" before it
+   * performs any payment-method-specific logic.
+   *
+   * @return \Drupal\payment\PaymentExecutionResultInterface
    *
    * @see self::executePaymentAccess
    */
   public function executePayment();
 
   /**
-   * Whether payment execution interrupts the payment type's context.
-   *
-   * If payment execution interrupts the context's workflow, this must return
-   * TRUE. An example of an interruption is when the payer must be redirected
-   * off-site.
+   * Gets the payment execution status.
    *
-   * @return bool
+   * @return \Drupal\payment\PaymentExecutionResultInterface
    */
-  public function isPaymentExecutionInterruptive();
+  public function getPaymentExecutionResult();
 
   /**
    * Gets the payment this payment method is for.
diff --git a/src/Plugin/Payment/Method/Unavailable.php b/src/Plugin/Payment/Method/Unavailable.php
index 7ec1fa2..52b000d 100644
--- a/src/Plugin/Payment/Method/Unavailable.php
+++ b/src/Plugin/Payment/Method/Unavailable.php
@@ -93,6 +93,13 @@ class Unavailable extends PluginBase implements PaymentMethodInterface {
   /**
    * {@inheritdoc}
    */
+  public function getPaymentExecutionStatus() {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function capturePaymentAccess(AccountInterface $account) {
     return FALSE;
   }
diff --git a/src/Plugin/Payment/Type/PaymentTypeInterface.php b/src/Plugin/Payment/Type/PaymentTypeInterface.php
index 0aff7d7..fca3d1a 100644
--- a/src/Plugin/Payment/Type/PaymentTypeInterface.php
+++ b/src/Plugin/Payment/Type/PaymentTypeInterface.php
@@ -43,7 +43,7 @@ interface PaymentTypeInterface extends PluginInspectionInterface, ConfigurablePl
   public function paymentDescription($language_code = NULL);
 
   /**
-   * Checks if the payment type context can be resumed..
+   * Checks if the payment type context can be resumed.
    *
    * @param \Drupal\Core\Session\AccountInterface $account
    *
@@ -54,7 +54,14 @@ interface PaymentTypeInterface extends PluginInspectionInterface, ConfigurablePl
   public function resumeContextAccess(AccountInterface $account);
 
   /**
-   * Resumes the payment context's workflow.
+   * Resumes the payer's original workflow.
+   *
+   * The returned response MUST contain all necessary information to return the
+   * payer to where they were when they started payment execution. Because this
+   * method does not always have to be called, it MUST NOT perform any other
+   * critical operations.
+   *
+   * @return \Drupal\payment\ResponseInterface
    *
    * @see self::resumeContextAccess
    */
diff --git a/src/Response.php b/src/Response.php
new file mode 100644
index 0000000..1503f99
--- /dev/null
+++ b/src/Response.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\Response.
+ */
+
+namespace Drupal\payment;
+
+use Drupal\Core\Url;
+use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
+
+/**
+ * Provides a payment response.
+ */
+class Response implements ResponseInterface {
+
+  /**
+   * The redirect URL.
+   *
+   * @var \Drupal\Core\Url
+   */
+  protected $redirectUrl;
+
+  /**
+   * The response.
+   *
+   * @var \Symfony\Component\HttpFoundation\Response|null
+   */
+  protected $response;
+
+  /**
+   * Constructs a new instance.
+   *
+   * @param \Drupal\Core\Url $redirect_url
+   * @param \Symfony\Component\HttpFoundation\Response|null $response
+   */
+  public function __construct(Url $redirect_url, SymfonyResponse $response = NULL) {
+    $this->redirectUrl = $redirect_url;
+    $this->response = $response;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRedirectUrl() {
+    return $this->redirectUrl;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getResponse() {
+    return $this->response;
+  }
+
+}
diff --git a/src/ResponseInterface.php b/src/ResponseInterface.php
new file mode 100644
index 0000000..27aab41
--- /dev/null
+++ b/src/ResponseInterface.php
@@ -0,0 +1,33 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment\ResponseInterface.
+ */
+
+namespace Drupal\payment;
+
+/**
+ * Defines a payment response.
+ *
+ * When returning a instance of a class that implements this interface,
+ * self::getRedirectUrl() MUST return a value and calling code MUST be able to
+ * perform a redirect using this value. All other functionality is optional.
+ */
+interface ResponseInterface {
+
+  /**
+   * Gets the URL the calling code may redirect to after payment execution.
+   *
+   * @return \Drupal\Core\Url
+   */
+  public function getRedirectUrl();
+
+  /**
+   * Gets the response
+   *
+   * @return \Symfony\Component\HttpFoundation\Response|null
+   */
+  public function getResponse();
+
+}
diff --git a/tests/src/Unit/Controller/PaymentUnitTest.php b/tests/src/Unit/Controller/PaymentUnitTest.php
index b7d856c..d9120ba 100644
--- a/tests/src/Unit/Controller/PaymentUnitTest.php
+++ b/tests/src/Unit/Controller/PaymentUnitTest.php
@@ -104,4 +104,32 @@ class PaymentUnitTest extends UnitTestCase {
     $this->assertSame($string, $this->controller->editTitle($payment));
   }
 
+  /**
+   * @covers ::resume
+   */
+  public function testResumeWithCompletedExecution() {
+    $status = TRUE;
+
+    $payment_method = $this->getMock('\Drupal\payment\Plugin\Payment\Method\PaymentMethodInterface');
+    $payment_method->expects($this->atLeastOnce())
+      ->method('getPaymentExecutionStatus')
+      ->willReturn($status);
+
+    $payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $payment->expects($this->once())
+      ->method('id')
+      ->will($this->returnValue($id));
+
+    $this->stringTranslation->expects($this->any())
+      ->method('translate')
+      ->with($string, array(
+        '!payment_id' => $id,
+      ))
+      ->will($this->returnArgument(0));
+
+    $this->assertSame($string, $this->controller->editTitle($payment));
+  }
+
 }
diff --git a/tests/src/Unit/Plugin/Payment/Method/BasicUnitTest.php b/tests/src/Unit/Plugin/Payment/Method/BasicUnitTest.php
index a16042d..69ded14 100644
--- a/tests/src/Unit/Plugin/Payment/Method/BasicUnitTest.php
+++ b/tests/src/Unit/Plugin/Payment/Method/BasicUnitTest.php
@@ -141,19 +141,12 @@ class BasicUnitTest extends PaymentMethodBaseUnitTestBase {
       ->with($this->pluginDefinition['execute_status_id'])
       ->will($this->returnValue($payment_status));
 
-    $payment_type = $this->getMock('\Drupal\payment\Plugin\Payment\Type\PaymentTypeInterface');
-    $payment_type->expects($this->once())
-      ->method('resumeContext');
-
     $payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
       ->disableOriginalConstructor()
       ->getMock();
     $payment->expects($this->once())
       ->method('save');
     $payment->expects($this->once())
-      ->method('getPaymentType')
-      ->will($this->returnValue($payment_type));
-    $payment->expects($this->once())
       ->method('setPaymentStatus')
       ->with($payment_status);
 
@@ -194,6 +187,48 @@ class BasicUnitTest extends PaymentMethodBaseUnitTestBase {
   }
 
   /**
+   * @covers ::getPaymentExecutionStatus
+   */
+  public function testGetPaymentExecutionStatusWithCompletedExecution() {
+    $payment_status = $this->getMock('\Drupal\payment\Plugin\Payment\Status\PaymentStatusInterface');
+    $payment_status->expects($this->atLeastOnce())
+      ->method('getPluginId')
+      ->willReturn($this->pluginDefinition['execute_status_id']);
+
+    $payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $payment->expects($this->once())
+      ->method('getPaymentStatus')
+      ->willReturn($payment_status);
+
+    $this->paymentMethod->setPayment($payment);
+
+    $this->assertTrue($this->paymentMethod->getPaymentExecutionStatus());
+  }
+
+  /**
+   * @covers ::getPaymentExecutionStatus
+   */
+  public function testGetPaymentExecutionStatusWithIncompleteExecution() {
+    $payment_status = $this->getMock('\Drupal\payment\Plugin\Payment\Status\PaymentStatusInterface');
+    $payment_status->expects($this->atLeastOnce())
+      ->method('getPluginId')
+      ->willReturn($this->randomMachineName());
+
+    $payment = $this->getMockBuilder('\Drupal\payment\Entity\Payment')
+      ->disableOriginalConstructor()
+      ->getMock();
+    $payment->expects($this->once())
+      ->method('getPaymentStatus')
+      ->willReturn($payment_status);
+
+    $this->paymentMethod->setPayment($payment);
+
+    $this->assertFalse($this->paymentMethod->getPaymentExecutionStatus());
+  }
+
+  /**
    * @covers ::doCapturePaymentAccess
    *
    * @dataProvider providerDoCapturePaymentAccess
diff --git a/tests/src/Unit/Plugin/Payment/Method/UnavailableUnitTest.php b/tests/src/Unit/Plugin/Payment/Method/UnavailableUnitTest.php
index b61d18d..cacff46 100644
--- a/tests/src/Unit/Plugin/Payment/Method/UnavailableUnitTest.php
+++ b/tests/src/Unit/Plugin/Payment/Method/UnavailableUnitTest.php
@@ -188,4 +188,11 @@ class UnavailableUnitTest extends UnitTestCase {
     $this->plugin->capturePayment();
   }
 
+  /**
+   * @covers ::getPaymentExecutionStatus
+   */
+  public function testGetPaymentExecutionStatus() {
+    $this->assertInternalType('bool', $this->plugin->getPaymentExecutionStatus());
+  }
+
 }
diff --git a/tests/src/Unit/ResponseUnitTest.php b/tests/src/Unit/ResponseUnitTest.php
new file mode 100644
index 0000000..d6f0196
--- /dev/null
+++ b/tests/src/Unit/ResponseUnitTest.php
@@ -0,0 +1,72 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\payment\Unit\ResponseUnitTest.
+ */
+
+namespace Drupal\Tests\payment\Unit;
+
+use Drupal\Core\Url;
+use Drupal\payment\Response;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * @coversDefaultClass \Drupal\payment\Response
+ *
+ * @group Payment
+ */
+class ResponseUnitTest extends UnitTestCase {
+
+  /**
+   * The redirect URL.
+   *
+   * @var \Drupal\Core\Url
+   */
+  protected $redirectUrl;
+
+  /**
+   * The response.
+   *
+   * @var \Symfony\Component\HttpFoundation\Response|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $symfonyResponse;
+
+  /**
+   * The response under test.
+   *
+   * @var \Drupal\payment\Response
+   */
+  protected $response;
+
+  /**
+   * {@inheritdoc}
+   *
+   * @covers ::__construct
+   */
+  public function setUp() {
+    $this->redirectUrl = new Url($this->randomMachineName());
+
+    $this->symfonyResponse = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Response')
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $this->response = new Response($this->redirectUrl, $this->symfonyResponse);
+  }
+
+  /**
+   * @covers ::getRedirectUrl
+   */
+  function testGetRedirectUrl() {
+    $this->assertSame($this->redirectUrl, $this->response->getRedirectUrl());
+  }
+
+  /**
+   * @covers ::getResponse
+   */
+  function testGetResponse() {
+    $this->assertSame($this->symfonyResponse, $this->response->getResponse());
+  }
+
+}
