diff --git a/payment.routing.yml b/payment.routing.yml index 46538a8..4ef2fb4 100644 --- a/payment.routing.yml +++ b/payment.routing.yml @@ -62,13 +62,13 @@ payment.payment.refund: options: _admin_route: TRUE -payment.payment.refund: - path: '/payment/{payment}/resume' +payment.payment.complete: + path: '/payment/{payment}/complete' defaults: - _entity_form: 'payment.refund' - _title: Resume payment + _entity_form: 'payment.complete' + _title: Complete payment requirements: - _entity_access: 'payment.resume' + _entity_access: 'payment.complete' payment.payment.delete: path: '/payment/{payment}/delete' diff --git a/src/Controller/Payment.php b/src/Controller/Payment.php index 7a9be42..dcc697a 100644 --- a/src/Controller/Payment.php +++ b/src/Controller/Payment.php @@ -63,19 +63,19 @@ class Payment extends ControllerBase { } /** - * Resumes a payment. + * Completes a payment. * * @param \Drupal\payment\Entity\PaymentInterface $payment * * @return \Symfony\Component\HttpFoundation\Response */ - public function resume(PaymentInterface $payment) { - $status = $payment->getPaymentMethod()->getPaymentExecutionStatus(); - if ($status->getResponse() instanceof Response) { - return $status->getResponse(); + public function complete(PaymentInterface $payment) { + $result = $payment->getPaymentMethod()->getPaymentExecutionResult(); + if ($result->getCompletionResponse()->getResponse() instanceof Response) { + return $result->getCompletionResponse(); } else { - return new RedirectResponse($status->getRedirectUrl()); + return new RedirectResponse($result->getCompletionResponse()->getRedirectUrl()->toString()); } } diff --git a/src/Entity/Payment/PaymentAccessControlHandler.php b/src/Entity/Payment/PaymentAccessControlHandler.php index a11dd5c..254be79 100644 --- a/src/Entity/Payment/PaymentAccessControlHandler.php +++ b/src/Entity/Payment/PaymentAccessControlHandler.php @@ -50,7 +50,7 @@ class PaymentAccessControlHandler extends EntityAccessControlHandler { } return AccessResult::forbidden(); } - elseif ($operation == 'resume') { + elseif ($operation == 'complete') { return AccessResult::allowedIf($payment->getOwnerId() == $account->id()) ->andIf($payment->getPaymentMethod()) ->andIf($payment->getPaymentMethod()->getPaymentExecutionStatus() === TRUE); diff --git a/src/Entity/Payment/PaymentListBuilder.php b/src/Entity/Payment/PaymentListBuilder.php index d606570..ac2eb8a 100644 --- a/src/Entity/Payment/PaymentListBuilder.php +++ b/src/Entity/Payment/PaymentListBuilder.php @@ -192,10 +192,10 @@ class PaymentListBuilder extends EntityListBuilder { 'url' => $entity->urlInfo('refund-form'), ); } - if ($entity->access('resume')) { + if ($entity->access('complete')) { $operations['resume'] = array( - 'title' => $this->t('Resume'), - 'url' => $entity->urlInfo('resume'), + 'title' => $this->t('Complete'), + 'url' => $entity->urlInfo('complete'), ); } 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 @@ +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() { diff --git a/src/Plugin/Payment/Method/PaymentMethodBase.php b/src/Plugin/Payment/Method/PaymentMethodBase.php index 07a9293..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')); } /** @@ -236,7 +247,7 @@ abstract class PaymentMethodBase extends PluginBase implements ContainerFactoryP // @todo invoke Rules event. $this->doExecutePayment(); - return $this->getPaymentExecutionStatus(); + return $this->getPaymentExecutionResult(); } /** diff --git a/src/Plugin/Payment/Method/PaymentMethodInterface.php b/src/Plugin/Payment/Method/PaymentMethodInterface.php index 3ae65e9..52bb998 100644 --- a/src/Plugin/Payment/Method/PaymentMethodInterface.php +++ b/src/Plugin/Payment/Method/PaymentMethodInterface.php @@ -44,12 +44,11 @@ interface PaymentMethodInterface extends PluginInspectionInterface, Configurable * * 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::getPaymentExecutionStatus(). + * 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\ResponseInterface|bool - * TRUE if payment execution was completed, FALSE if execution failed, or an - * instance of \Drupal\payment\ResponseInterface with information to resume - * execution. + * @return \Drupal\payment\PaymentExecutionResultInterface * * @see self::executePaymentAccess */ @@ -58,23 +57,9 @@ interface PaymentMethodInterface extends PluginInspectionInterface, Configurable /** * Gets the payment execution status. * - * @return \Drupal\payment\ResponseInterface|bool - * TRUE if payment execution was completed, FALSE if execution failed, or an - * instance of \Drupal\payment\ResponseInterface with information to resume - * execution. + * @return \Drupal\payment\PaymentExecutionResultInterface */ - public function getPaymentExecutionStatus(); - - /** - * 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. - * - * @return bool - */ - public function isPaymentExecutionInterruptive(); + public function getPaymentExecutionResult(); /** * Gets the payment this payment method is for.