Skip to content

Instantly share code, notes, and snippets.

@steveoliver
Created October 21, 2016 20:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save steveoliver/3135b75b573d0fb902ebc7cf23426505 to your computer and use it in GitHub Desktop.
Save steveoliver/3135b75b573d0fb902ebc7cf23426505 to your computer and use it in GitHub Desktop.
Testing creating payments upon order checkout (post 'place' transition)
services:
// ...
commerce_payment.payment_listener:
class: Drupal\commerce_payment\EventSubscriber\PaymentListener
arguments: []
tags:
- { name: event_subscriber }
<?php
namespace Drupal\Tests\commerce_payment\Functional;
use Drupal\commerce_order\Entity\Order;
use Drupal\commerce_order\Entity\OrderItem;
use Drupal\commerce_order\Entity\OrderItemType;
use Drupal\commerce_store\StoreCreationTrait;
use Drupal\profile\Entity\Profile;
use Drupal\Tests\commerce\Functional\CommerceBrowserTestBase;
/**
* Tests the payment events.
*
* @group commerce
*/
class PaymentEventTest extends CommerceBrowserTestBase {
use StoreCreationTrait;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $account;
/**
* The product.
*
* @var \Drupal\commerce_product\Entity\ProductInterface
*/
protected $product;
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['system', 'field', 'user', 'text',
'entity', 'views', 'address', 'profile', 'commerce', 'inline_entity_form',
'commerce_price', 'commerce_store', 'commerce_product', 'commerce_cart',
'commerce_checkout', 'commerce_order', 'commerce_payment_example', 'views_ui',
// @see https://www.drupal.org/node/2807567
'editor',
];
/**
* {@inheritdoc}
*/
protected function getAdministratorPermissions() {
return array_merge([
'administer commerce_payment_gateway',
'administer commerce_payment'
], parent::getAdministratorPermissions());
}
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->placeBlock('commerce_cart');
$store = $this->createStore('Demo', 'demo@example.com', 'default', TRUE);
$variation = $this->createEntity('commerce_product_variation', [
'type' => 'default',
'sku' => strtolower($this->randomMachineName()),
'price' => [
'number' => 9.99,
'currency_code' => 'USD',
],
]);
/** @var \Drupal\commerce_product\Entity\ProductInterface $product */
$this->product = $this->createEntity('commerce_product', [
'type' => 'default',
'title' => 'My product',
'variations' => [$variation],
'stores' => [$store],
]);
// Create payment gateway plugin.
$this->drupalGet('admin/commerce/config/payment-gateways');
$this->getSession()->getPage()->clickLink('Add payment gateway');
$this->assertSession()->addressEquals('admin/commerce/config/payment-gateways/add');
$values = [
'id' => 'example',
'label' => 'Example',
'plugin' => 'example_onsite',
];
$this->submitForm($values, 'Save');
$this->assertSession()->addressEquals('admin/commerce/config/payment-gateways/manage/example');
$this->assertSession()->responseContains('Saved');
$values += [
'configuration[api_key]' => 'bunny',
'configuration[mode]' => 'test',
'status' => '1',
];
$this->submitForm($values, 'Save');
$this->assertSession()->addressEquals('admin/commerce/config/payment-gateways');
$this->assertSession()->responseContains('Example');
$this->assertSession()->responseContains('Test');
}
/**
* Tests creating a payment gateway.
*/
public function testPostOrderPaymentCreation() {
$user = $this->loggedInUser;
OrderItemType::create([
'id' => 'test',
'label' => 'Test',
'orderType' => 'default',
])->save();
$profile = Profile::create([
'type' => 'customer',
'address' => [
'country' => 'FR',
'postal_code' => '75002',
'locality' => 'Paris',
'address_line1' => 'A french street',
'given_name' => 'John',
'family_name' => 'LeSmith',
],
]);
$profile->save();
$order_item = OrderItem::create([
'type' => 'test',
]);
$order_item->save();
$order = Order::create([
'type' => 'default',
'state' => 'in_checkout',
'mail' => $user->getEmail(),
'uid' => $user->id(),
'ip_address' => '127.0.0.1',
'billing_profile' => $profile,
'order_items' => [$order_item],
]);
$order->save();
// Checkout
$this->drupalGet('checkout/' . $order->id());
$this->assertSession()->pageTextContains('Card number');
$checkout_values = [
'payment_information[payment_method]' => 'new_credit_card',
'payment_information[add_payment_method][payment_details][number]' => '41111111111111111',
'payment_information[add_payment_method][payment_details][expiration][month]' => date('m'),
'payment_information[add_payment_method][payment_details][expiration][year]' => date('Y') + 1,
'payment_information[add_payment_method][payment_details][security_code]' => '111',
];
$this->submitForm($checkout_values, 'Continue to review');
$this->drupalGet('checkout/' . $order->id() . '/review');
$this->submitForm([], 'Pay and complete purchase');
$this->drupalGet('checkout/' . $order->id() . '/complete');
$this->assertSession()->pageTextContains('Your order number is ' . $order->id() . '. You can view your order on your account page when logged in.');
// Check for payments
$this->drupalGet('admin/commerce/orders/' . $order->id() . '/payments');
$order = Order::load($order->id());
$this->assertEquals('completed', $order->getState()->value);
$this->assertSession()->pageTextNotContains('There is no Payment yet.');
}
}
<?php
namespace Drupal\commerce_payment\EventSubscriber;
use Drupal\commerce_payment\Entity\Payment;
use Drupal\state_machine\Event\WorkflowTransitionEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class PaymentListener implements EventSubscriberInterface {
/**
* @inheritdoc
*/
public static function getSubscribedEvents() {
return [
'commerce_order.place.post_transition' => 'onOrderPostPlace',
];
}
/**
* Responds to commerce_order.place.post_transition workflow transition event.
*
* @param \Drupal\state_machine\Event\WorkflowTransitionEvent $event
* The workflow transition event.
*/
public function onOrderPostPlace(WorkflowTransitionEvent $event) {
drupal_set_message('trying to create payment');
/** @var \Drupal\commerce_order\Entity\Order $order */
$order = $event->getEntity();
/** @var \Drupal\commerce_payment\Entity\PaymentMethod $payment_method */
$payment_method = $order->payment_method->entity;
/** @var \Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\PaymentGatewayInterface $payment_gateway */
$payment_gateway = $payment_method->getPaymentGateway();
/** @var \Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\PaymentGatewayBase $payment_gateway_plugin */
$payment_gateway_plugin = $payment_gateway->getPlugin();
// @todo Restict payment creation by gateway type / configuration?
// if (get_class($payment_gateway_plugin) instanceof OnsitePaymentGatewayInterface == FALSE) {
// return;
// }
/** @var \Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\OnsitePaymentGatewayInterface $payment_gateway_plugin */
$config = $payment_gateway_plugin->getConfiguration();
/** @var \Drupal\commerce_price\Price $amount */
// @todo Get orderBalance()?
// @see https://github.com/drupalcommerce/commerce/pull/508
$amount = $order->getTotalPrice();
/** @var \Drupal\commerce_payment\Entity\PaymentInterface $payment */
$payment = Payment::create([
'state' => 'new',
'amount' => $amount,
'payment_gateway' => $payment_gateway->getPluginId(),
'payment_method' => $payment_method,
'order_id' => $order->getOrderNumber(),
]);
// @todo Determine capture somehow?
// transaction_type currently does not exist in the payment gateway config.
// transaction_type comes from the payment capture form submit handler.
$capture = TRUE; // ($config['transaction_type'] == 'capture');
$payment_gateway_plugin->createPayment($payment, $capture);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment