首页 > 解决方案 > 具有以下状态之一的 PaymentIntent:requires_payment_method、requires_confirmation、requires_action

问题描述

所以我对条纹 PaymentIntent 状态有疑问。每次我编辑代码时,我都可以购买,但只能购买一次。如果我再次尝试购买东西,它会显示此错误:

This PaymentIntent's amount could not be updated because it has a status of succeeded. You may only update the amount of a PaymentIntent with one of the following statuses: requires_payment_method, requires_confirmation, requires_action.

它的代码是:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Srmklive\PayPal\Services\ExpressCheckout;

use App\Stock;
use App\OrderItem;
use App\Order;
use App\Coupon;
use App\Package;
use App\Mail\Reciepe;
use RealRashid\SweetAlert\Facades\Alert;
use Cart;
use Auth;
use Session;
use Cache;
use Mail;
class CartController extends Controller
{

  protected $provider;
  public function __construct() {
      $this->provider = new ExpressCheckout();
  }
  // Add Item to Cart
  public function addItem(Request $request)
  {
    $package = Package::where('id', $request->get('id'))->first();

    // make sure there arent any more packages in the cart
    Cart::destroy();
    // add shit
    Cart::add($package->id, $package->name, 1, $package->price, ['type' => 'package', 'fee' => $package->fee]);
    if($request->fast) {
      $this->setMethodCtrl('fast');
    }
    return redirect('/checkout');
  }

  // Add Item to Cart
  public function addItemApi(Request $request)
  {
    $package = Package::where('id', $request->get('id'))->first();

    // make sure there arent any more packages in the cart
    Cart::destroy();
    // add shit
    Cart::add($package->id, $package->name, 1, $package->price, ['type' => 'package', 'fee' => $package->fee]);
    if($request->fast) {
      $this->setMethodCtrl('fast');
    }
  }

  // Remove item from cart
  public function removeItem($id)
  {
    $item = Cart::get($id);

    if($item->options->type != "package") {
      Cart::remove($id);
    } else {
      Cart::destroy();
    }
    return redirect()->back();
  }

  // View checkout page
  public function checkout()
  {
    return view('gold.checkout');
  }

  // Handles bunch of stripe stuff
  public function getStripeIntent() {
    $currency = 'USD';
    $fee = 0;

    // Handle processing fee
    foreach(\Cart::content() as $i) {
      $fee += $i->options->fee;
    }
    $total = ((Cart::subtotal()) + $fee) * 100;

    //Session::forget(Auth::user()->id.'-intent-new');
    if(Cache::get(Auth::user()->id.'-intent-new')) {
      // Update payment intent here
      \Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
      $intent = \Stripe\PaymentIntent::update(
        Cache::get(Auth::user()->id.'-intent-new')->id,
        ['amount' = $total]
      );
    } else {
      \Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
      $intent = \Stripe\PaymentIntent::create([
          'amount' = $total,
          'currency' => 'usd',
      ]);
      Cache::put(Auth::user()->id.'-intent-new', $intent, 60);
    }

    // handle order here
    $order = Order::where('stripe_intent', $intent->client_secret)->first();
    if(!$order) {
      $order = new Order;
      $order->our_tx = uniqid();
      $order->user_id = Auth::user()->id;
      $order->method = 'Stripe';
      $order->currency = $currency;
      $order->coupon = '';
      $order->total = $total / 100;
      $order->stripe_intent = $intent->client_secret;
      $order->status = -1;
      $order->fast_delivery = 0;
      $order->save();

      foreach(Cart::content() as $i) {
        $item = new OrderItem;
        $item->product_id = $i->id;
        $item->order_id = $order->id;
        $item->type = $i->options->type;
        $item->name = $i->name;
        $item->price = $i->price;
        $item->amount = $i->qty;
        $item->total = $i->price * $i->qty;
        $item->save();

        if($i->name == "Fast Delivery") {
          $order->fast_delivery = 1;
          $order->save();
        }
      }
    } else {
      $order->total = $total / 100;
      $order->fast_delivery = 0;
      $order->save();
      $items = OrderItem::where('order_id', $order->id)->get();

      foreach($items as $i) {
        $i->delete();
      }

      foreach(Cart::content() as $i) {
        $item = new OrderItem;
        $item->product_id = $i->id;
        $item->order_id = $order->id;
        $item->type = $i->options->type;
        $item->name = $i->name;
        $item->price = $i->price;
        $item->amount = $i->qty;
        $item->total = $i->price * $i->qty;
        $item->save();
        if($i->name == "Fast Delivery") {
          $order->fast_delivery = 1;
          $order->save();
        }
      }
    }

    // Set intent order_id meta
    $intent = \Stripe\PaymentIntent::update(
      Cache::get(Auth::user()->id.'-intent-new')->id,
      ['metadata' => ['order_id' => $order->id]]
    );


    return $intent;
  }

  // Function for handling the checkout and various gateways
  public function handleCheckout(Request $request)
  {
    $gateway = $request->get('payment_gateway');
    $currency = 'USD';
    $fee = 0;

    // Handle Coupon
    if($request->get('coupon') != "")
    {
      $coupon = Coupon::where('coupon', $request->get('coupon'))->first();
      if(!$coupon)
      {
        $coupon = new Coupon;
        $coupon->discount = 0;
      }
    } else {
      $coupon = new Coupon;
      $coupon->discount = 0;
    }

      // Handle processing fee
      foreach(\Cart::content() as $i) {
        $fee += $i->options->fee;
      }
      $total = Cart::subtotal() + $fee;

      if($gateway == "paypal")
      {
        $provider = new ExpressCheckout;

        $order = new Order;
        $order->our_tx = uniqid();
        $order->user_id = Auth::user()->id;
        $order->method = 'Paypal';
        $order->currency = $currency;
        $order->coupon = '';
        $order->total = $total;
        $order->status = -1;
        $order->fast_delivery = 0;
        $order->save();
        $data = [];
        $data['items'] = array();

        foreach(Cart::content() as $i) {
          $item = new OrderItem;
          $item->product_id = $i->id;
          $item->order_id = $order->id;
          $item->type = $i->options->type;
          $item->name = $i->name;
          $item->price = $i->price;
          $item->amount = $i->qty;
          $item->total = $i->price * $i->qty;
          $item->save();

          if($i->name == "Fast Delivery") {
            $order->fast_delivery = 1;
            $order->save();
          }

          array_push($data['items'], [
            'name' => $item->name,
            'price' => $item->price,
            'qty' => $item->amount
          ]);
        }

        array_push($data['items'], [
          'name' => 'Processing Fee',
          'price' => $fee,
          'qty' => 1
        ]);
        // Paypal stuff
        $options = [
          'BRANDNAME' => env('APP_NAME'),
          'LOGOIMG' => 'http://vaneblox.com/img/logo_desktop.png',
          'CHANNELTYPE' => 'Merchant'
        ];
        $data['invoice_id'] = $order->id;
        $data['invoice_description'] = "Order #{$order->our_tx}";
        $data['return_url'] = url('/success/'.$order->our_tx);
        $data['cancel_url'] = url('/checkout');
        $data['total'] = $order->total;
        $response = $provider->addOptions($options)->setExpressCheckout($data);
        //Cart::destroy();
        return redirect($response['paypal_link']);
      }
    }

  public function paypalSuccess($id, Request $request) {
    $order = Order::where('our_tx', $id)->first();

    // redo data thing
    $data = [];
    $fee = 0;
    $data['items'] = array();
    $items = $order->items;

    foreach($items as $item) {
      array_push($data['items'], [
        'name' => $item->name,
        'price' => $item->price,
        'qty' => $item->amount
      ]);
    }
    foreach(\Cart::content() as $i) {
      $fee += $i->options->fee;
    }

    array_push($data['items'], [
      'name' => 'Processing Fee',
      'price' => $fee,
      'qty' => 1
    ]);

    $data['invoice_id'] = $order->id;
    $data['invoice_description'] = "Order #{$order->our_tx}";
    $data['return_url'] = url('/success/'.$order->our_tx);
    $data['cancel_url'] = url('/checkout');
    $data['total'] = $order->total;

    $token = $request->get('token');
    $PayerID = $request->get('PayerID');
    $response = $this->provider->getExpressCheckoutDetails($token);
    if (!in_array(strtoupper($response['ACK']), ['SUCCESS', 'SUCCESSWITHWARNING'])) {
        return redirect('/');
    }

    // charge the user
    $payment_status = $this->provider->doExpressCheckoutPayment($data, $token, $PayerID);
    $status = $payment_status['PAYMENTINFO_0_PAYMENTSTATUS'];

    $order->status = 1;
    $order->save();
    Cart::destroy();

    // Update Orders
    $user = $order->user;
    $user->orders += 1;
    $user->paid += $order->total;
    $user->save();
    Mail::to($user)->send(new Reciepe($order));

    // Here we check if the user has an old order that is in progress
    if($user->order()->where(function($q) {
      $q->where('status', 3)->orWhere('status', 1);
    })->orderBy('id', 'asc')->count() > 1) {
      $old_order = $user->order()->where(function($q) {
        $q->where('status', 3)->orWhere('status', 1);
      })->orderBy('id', 'asc')->first();

      $items = $order->items;

      foreach($items as $i) {
        $item = new OrderItem;
        $item->product_id = $i->product_id;
        $item->order_id = $old_order->id;
        $item->type = $i->type;
        $item->name = $i->name;
        $item->price = $i->price;
        $item->amount = $i->amount;
        $item->total = $i->total;
        $item->new = 1;
        $item->save();
        if($i->name == "Fast Delivery") {
          $old_order->fast_delivery = 1;
          $old_order->save();
        }
      }
      $old_order->total += $order->total;
      $old_order->save();
      $order->delete();
      return redirect('/track/'.$old_order->our_tx);
    }

    return redirect('/track/'.$order->our_tx);
  }

  public function destroyCart() {
    Cart::destroy();
  }

  // Handle new stripe orders etc.
  public function stripeWebhook(Request $request) {
    $order = Order::where('id', $request->data['object']['metadata']['order_id'])->first();

    // Mark order as paid
    if($order) {
      $order->status = 1;
      $order->save();

      // Update Orders
      $user = $order->user;
      $user->orders += 1;
      $user->paid += $order->total;
      $user->save();
      // mail user
      Mail::to($user)->send(new Reciepe($order));
      Cache::forget($order->user_id.'-intent-new');

      // Here we check if the user has an old order that is in progress
      if($user->order()->where(function($q) {
        $q->where('status', 3)->orWhere('status', 1);
      })->orderBy('id', 'asc')->count() > 1) {
        $old_order = $user->order()->where(function($q) {
          $q->where('status', 3)->orWhere('status', 1);
        })->orderBy('id', 'asc')->first();

        $items = $order->items;

        foreach($items as $i) {
          $item = new OrderItem;
          $item->product_id = $i->product_id;
          $item->order_id = $old_order->id;
          $item->type = $i->type;
          $item->name = $i->name;
          $item->price = $i->price;
          $item->amount = $i->amount;
          $item->total = $i->total;
          $item->new = 1;
          $item->save();
          if($i->name == "Fast Delivery") {
            $old_order->fast_delivery = 1;
            $old_order->save();
          }
        }
        $old_order->total += $order->total;
        $old_order->save();
        $order->delete();
      }
    }
  }

  public function paypalWebhook(Request $request) {
    Log::info($request);
    /*
    $order = Order::where('id', $request->invoice)->first();

    // Mark order as paid
    if($order) {
      $order->status = 1;
      $order->save();
    }
    */
  }

  // For setting delivery method
  public function setMethod($method) {
    if($method == "fast") {
      foreach(Cart::content() as $i) {
        if($i->name == 'Fast Delivery') {
          return redirect('/checkout');
        }
      }
      Cart::add(666, 'Fast Delivery', 1, 15, ['type' => 'delivery']);
    } else {
      foreach(Cart::content() as $i) {
        if($i->name == 'Fast Delivery') {
          Cart::remove($i->rowId);
        }
      }
    }

    return redirect()->back();
  }

  public function setMethodCtrl($method) {
    if($method == "fast") {
      foreach(Cart::content() as $i) {
        if($i->name == 'Fast Delivery') {
          return redirect('/checkout');
        }
      }
      Cart::add(666, 'Fast Delivery', 1, 15, ['type' => 'delivery']);
    } else {
      foreach(Cart::content() as $i) {
        if($i->name == 'Fast Delivery') {
          Cart::remove($i->rowId);
        }
      }
    }
  }
}

我认为这是这部分的一个问题:


foreach(\Cart::content() as $i) {
      $fee += $i->options->fee;
    }
    $total = ((Cart::subtotal()) + $fee) * 100;

    //Session::forget(Auth::user()->id.'-intent-new');
    if(Cache::get(Auth::user()->id.'-intent-new')) {
      // Update payment intent here
      \Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
      $intent = \Stripe\PaymentIntent::update(
        Cache::get(Auth::user()->id.'-intent-new')->id,
        ['amount' = $total]
      );
    } else {
      \Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
      $intent = \Stripe\PaymentIntent::create([
          'amount' = $total,
          'currency' => 'usd',
      ]);
      Cache::put(Auth::user()->id.'-intent-new', $intent, 60);
    }

但我不知道如何解决它,有人可以帮助我吗?

标签: phpstripe-payments

解决方案


虽然您可以更新amount给定的付款意图(例如,当客户修改他们的购物车时),但它们只能用于单次实际付款。

如果您需要收取多笔付款,则需要创建多个付款意图。


推荐阅读