You are here

function commerce_stripe_pi_create_transaction in Commerce Stripe Payment Intent 7

Create a transaction.

Parameters

string $order_id: The commerce order identifier.

\Stripe\PaymentIntent $payment_intent: The payment intent object.

array $payment_method: The drupal payment method.

Return value

bool The transaction status.

3 calls to commerce_stripe_pi_create_transaction()
commerce_stripe_pi_submit_form_submit in ./commerce_stripe_pi.module
Payment method callback: checkout form submission.
commerce_stripe_pi_webhook in ./commerce_stripe_pi.module
Get Stripe async response after payment intent.
hook_commerce_stripe_pi_webhook_alter in ./commerce_stripe_pi.api.php
Make action after webhook call.

File

./commerce_stripe_pi.module, line 1086
Payment intent stripe payment integration.

Code

function commerce_stripe_pi_create_transaction($order_id, PaymentIntent $payment_intent, array $payment_method = NULL) {
  $lock = __FUNCTION__ . '_' . $order_id;

  // Do not create transaction if already exists.
  $transaction_id = _commerce_stripe_pi_get_commerce_payment_transaction_from_remote_id($payment_intent->id);
  if ($transaction_id) {
    return TRUE;
  }

  // Be sure to not create concurrent transactions.
  // It's possible to have two concurrent transactions called from webhook and
  // checkout submit.
  if (lock_acquire($lock)) {
    try {

      // Check a transaction for this remote status does not already exists.
      if ($transaction = _commerce_stripe_pi_get_commerce_payment_transaction_from_remote_id($payment_intent->id)) {
        lock_release($lock);
        return TRUE;
      }
      if (NULL === $payment_method) {
        $payment_method = commerce_payment_method_instance_load('commerce_stripe_pi|commerce_payment_commerce_stripe_pi');
      }
      if (method_exists($payment_intent, '__toJSON')) {
        $payment_intent_json = $payment_intent
          ->__toJSON();
      }
      else {
        $payment_intent_json = $payment_intent
          ->toJSON();
      }

      // If paymentIntent  is succeeded or requires_capture.
      if ($payment_intent->status === COMMERCE_STRIPE_PI_REQUIRES_CAPTURE || $payment_intent->status === COMMERCE_STRIPE_PI_SUCCEEDED) {

        // The payment don't need any additional actions and is completed !
        // Handle post-payment fulfillment.
        $transaction = commerce_payment_transaction_new('commerce_stripe_pi', $order_id);
        $transaction->instance_id = $payment_method['instance_id'];

        // Payment intent is integer in cents, but transaction expect decimal.
        $transaction->currency_code = strtoupper($payment_intent->currency);
        $transaction->remote_id = $payment_intent->id;

        // Set the Commerce Payment Transaction UID from order uid.
        $order = commerce_order_load($order_id);
        $transaction->uid = $order->uid;
        if ($payment_intent->status === COMMERCE_STRIPE_PI_SUCCEEDED) {
          $transaction->status = COMMERCE_PAYMENT_STATUS_SUCCESS;
          $transaction->remote_status = $payment_intent->status;
          $transaction->message = t('Stripe payment intent succeeded.');
        }
        elseif ($payment_intent->status === COMMERCE_STRIPE_PI_REQUIRES_CAPTURE) {
          $transaction->status = COMMERCE_PAYMENT_STATUS_PENDING;
          $transaction->remote_status = 'AUTH_ONLY';
          $transaction->message = t('Stripe payment intent pending capture.');
        }
        $transaction->amount = $payment_intent->amount;
        $transaction->payload[REQUEST_TIME] = $payment_intent_json;
        if (!_commerce_stripe_pi_commerce_payment_transaction_save($transaction)) {
          lock_release($lock);
          return FALSE;
        }
      }
      else {

        // Invalid status.
        drupal_set_message(t('We received the following error processing your card: @error
         Please enter your information again or try a different card.', array(
          '@error' => t('Invalid PaymentIntent status'),
        )), 'error');
        watchdog('commerce_stripe_pi', 'Payment refused using payment intent with Invalid PaymentIntent status for order @order_id : @stripe_pi_error.', array(
          '@order_id' => $order_id,
          '@stripe_pi_error' => $payment_intent_json,
        ), WATCHDOG_NOTICE);
        $transaction = commerce_payment_transaction_new('commerce_stripe_pi', $order_id);
        $transaction->message = t('Payment intent refused.');
        $transaction->status = COMMERCE_PAYMENT_STATUS_FAILURE;
        $transaction->remote_status = $payment_intent->status;
        $transaction->payload[REQUEST_TIME] = $payment_intent_json;
        _commerce_stripe_pi_commerce_payment_transaction_save($transaction);
        lock_release($lock);
        return FALSE;
      }
    } catch (Exception $e) {
      lock_release($lock);
      watchdog('commerce_stripe_pi', 'Following error received when creating transaction for order @order_id : @error.', array(
        '@order_id' => $order_id,
        '@error' => $e
          ->getMessage(),
      ), WATCHDOG_ERROR);
      return FALSE;
    }
  }
  lock_release($lock);
  return TRUE;
}