View source
<?php
namespace Drupal\Tests\commerce_stripe\Kernel;
use Drupal\commerce_order\Adjustment;
use Drupal\commerce_order\Entity\Order;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_order\Entity\OrderItem;
use Drupal\commerce_payment\Entity\PaymentMethod;
use Drupal\commerce_payment\Entity\PaymentMethodInterface;
use Drupal\commerce_price\Price;
use Drupal\commerce_stripe\Plugin\Commerce\PaymentGateway\StripeInterface;
use Drupal\user\Entity\User;
use Prophecy\Argument;
use Stripe\PaymentIntent;
class PaymentIntentTest extends StripeIntegrationTestBase {
public function testCreatePaymentIntent($payment_method_token, $capture, $initial_status, $confirmed_status) {
$gateway = $this
->generateGateway();
$plugin = $gateway
->getPlugin();
assert($plugin instanceof StripeInterface);
$payment_method = $this
->prophesize(PaymentMethodInterface::class);
$payment_method
->getRemoteId()
->willReturn($payment_method_token);
$order = $this
->prophesize(OrderInterface::class);
$order
->get('payment_method')
->willReturn((object) [
'entity' => $payment_method
->reveal(),
]);
$order
->getTotalPrice()
->willReturn(new Price('15.00', 'USD'));
$order
->getStoreId()
->willReturn(1111);
$order
->id()
->willReturn(9999);
$order
->getCustomer()
->willReturn(User::getAnonymousUser());
$order
->setData('stripe_intent', Argument::containingString('pi_'))
->willReturn($order
->reveal());
$order
->save()
->willReturn(NULL);
$intent = $plugin
->createPaymentIntent($order
->reveal(), $capture);
$this
->assertEquals($capture ? 'automatic' : 'manual', $intent->capture_method);
$this
->assertEquals($initial_status, $intent->status);
$this
->assertEquals($intent->currency, 'usd');
$this
->assertEquals($intent->amount, 1500);
$intent = $intent
->confirm();
$this
->assertEquals($confirmed_status, $intent->status);
}
public function testIntentOrderTotalSync($deleted_gateway) {
$gateway = $this
->generateGateway();
$plugin = $gateway
->getPlugin();
assert($plugin instanceof StripeInterface);
$order = Order::create([
'type' => 'default',
'store_id' => $this->store
->id(),
'uid' => 0,
'state' => 'draft',
]);
$order_item = OrderItem::create([
'type' => 'test',
'quantity' => 1,
'unit_price' => new Price('10.50', 'USD'),
]);
$order_item
->save();
$order
->addItem($order_item);
$payment_method = PaymentMethod::create([
'type' => 'credit_card',
'payment_gateway' => $gateway
->id(),
'payment_gateway_mode' => 'test',
'remote_id' => 'pm_card_threeDSecure2Required|',
]);
$payment_method
->save();
$order
->set('payment_method', $payment_method);
$order
->set('payment_gateway', $gateway);
$order
->save();
$intent = $plugin
->createPaymentIntent($order);
$this
->assertEquals(1050, $intent->amount);
if ($deleted_gateway) {
$gateway
->delete();
}
$order = $this
->reloadEntity($order);
$order
->addAdjustment(new Adjustment([
'type' => 'custom',
'label' => 'Back to school discount',
'amount' => new Price('-5.00', 'USD'),
]));
$order
->save();
$this->container
->get('commerce_stripe.order_events_subscriber')
->destruct();
$this
->assertEquals('5.50', $order
->getTotalPrice()
->getNumber());
$intent = PaymentIntent::retrieve($intent->id);
$this
->assertEquals($deleted_gateway ? 1050 : 550, $intent->amount);
}
public function testIntentEmptyOrderSync() {
$gateway = $this
->generateGateway();
$plugin = $gateway
->getPlugin();
assert($plugin instanceof StripeInterface);
$order = Order::create([
'type' => 'default',
'store_id' => $this->store
->id(),
'uid' => 0,
'state' => 'draft',
]);
$order_item = OrderItem::create([
'type' => 'test',
'quantity' => 1,
'unit_price' => new Price('10.50', 'USD'),
]);
$order_item
->save();
$order
->addItem($order_item);
$payment_method = PaymentMethod::create([
'type' => 'credit_card',
'payment_gateway' => $gateway
->id(),
'payment_gateway_mode' => 'test',
'remote_id' => 'pm_card_threeDSecure2Required|',
]);
$payment_method
->save();
$order
->set('payment_method', $payment_method);
$order
->set('payment_gateway', $gateway);
$order
->save();
$intent = $plugin
->createPaymentIntent($order);
$this
->assertEquals(1050, $intent->amount);
$order
->addAdjustment(new Adjustment([
'type' => 'custom',
'label' => 'Back to school discount',
'amount' => new Price('-5.00', 'USD'),
]));
$order
->save();
$this->container
->get('commerce_stripe.order_events_subscriber')
->destruct();
$this
->assertEquals('5.50', $order
->getTotalPrice()
->getNumber());
$intent = PaymentIntent::retrieve($intent->id);
$this
->assertEquals(550, $intent->amount);
$order
->setAdjustments([]);
$order
->removeItem($order_item);
$order
->save();
$this->container
->get('commerce_stripe.order_events_subscriber')
->destruct();
$this
->assertNull($order
->getTotalPrice());
$intent = PaymentIntent::retrieve($intent->id);
$this
->assertEquals(550, $intent->amount, 'Intent has the same previous value');
$order
->addItem($order_item);
$order
->save();
$this->container
->get('commerce_stripe.order_events_subscriber')
->destruct();
$this
->assertEquals('10.50', $order
->getTotalPrice()
->getNumber());
$intent = PaymentIntent::retrieve($intent->id);
$this
->assertEquals(1050, $intent->amount);
}
public function dataProviderCreatePaymentIntent() {
(yield [
'pm_card_threeDSecure2Required',
TRUE,
PaymentIntent::STATUS_REQUIRES_CONFIRMATION,
PaymentIntent::STATUS_REQUIRES_ACTION,
]);
(yield [
'pm_card_threeDSecure2Required',
FALSE,
PaymentIntent::STATUS_REQUIRES_CONFIRMATION,
PaymentIntent::STATUS_REQUIRES_ACTION,
]);
(yield [
'pm_card_threeDSecureOptional',
TRUE,
PaymentIntent::STATUS_REQUIRES_CONFIRMATION,
PaymentIntent::STATUS_SUCCEEDED,
]);
(yield [
'pm_card_visa',
TRUE,
PaymentIntent::STATUS_REQUIRES_CONFIRMATION,
PaymentIntent::STATUS_SUCCEEDED,
]);
(yield [
'pm_card_amex_threeDSecureNotSupported',
TRUE,
PaymentIntent::STATUS_REQUIRES_CONFIRMATION,
PaymentIntent::STATUS_SUCCEEDED,
]);
}
public function dataProviderOrderSync() {
(yield [
FALSE,
]);
(yield [
TRUE,
]);
}
}