web-dev-qa-db-ja.com

Laravel 5.8 / Cashier / Stripeでサブスクリプションを設定する際の問題

私はこのチュートリアルを段階的に実行しました: https://appdividend.com/2018/12/05/laravel-stripe-payment-gateway-integration-tutorial-with-example/

しかし、テストしてみると、次のエラーが発生します。

Stripe\Error\InvalidRequest No such payment_method:

いくつかのメモ:

  • Stripeがテストモードであること、ストライプAPIキーが適切に設定されていること、および推奨されるテストカードを使用していることを確認しました:4242 4242 4242 4242 | 04/22 | 222 | 12345

  • 私は記事のコメントをよく読んで、他の人々が「同様の」問題を抱えていることを確認しました。ただし、特に支払い方法に関するエラーではありません。

  • Laravel 5.8がリリースされ、Cashier 10がリリースされたので、「paymentIntents」についての断片が表示されています。それが問題の原因かどうかはわかりません。

このエラーを修正するために私ができることについて誰かが何かアイデアを持っていますか?

ありがとう!

enter image description here

編集:(リクエストごとにコードを追加)

ここに私が使用したコードのさまざまなビットがあります:

ルート(web.php)

Route::group(['middleware' => 'auth'], function() {
  Route::get('/home', 'HomeController@index')->name('home');
  Route::get('/plans', 'PlanController@index')->name('plans.index');
  Route::get('/plan/{plan}', 'PlanController@show')->name('plans.show');
  Route::post('/subscription', 'SubscriptionController@create')- 
>name('subscription.create');
});

計画モデル(plan.php)

<?php
    namespace App;
    use Illuminate\Database\Eloquent\Model;

    class Plan extends Model {
       protected $fillable = [
         'name',
         'slug',
         'stripe_plan',
         'cost',
         'description'
       ];

       public function getRouteKeyName() {
          return 'slug';
       }
    }

Plan Controller(PlanController.php)

<?php
    namespace App\Http\Controllers;
    use Illuminate\Http\Request;
    use App\Plan;

    class PlanController extends Controller {
        public function index() {
            $plans = Plan::all();
            return view('plans.index', compact('plans'));
        }

        public function show(Plan $plan, Request $request) {
            return view('plans.show', compact('plan'));
        }
    }

サブスクリプションコントローラー(SubscriptionController.php)

<?php
    namespace App\Http\Controllers;
    use Illuminate\Http\Request;
    use App\Plan;

    class SubscriptionController extends Controller {
        public function create(Request $request, Plan $plan) {
            $plan = Plan::findOrFail($request->get('plan'));

            $request->user()
                ->newSubscription('main', $plan->stripe_plan)
                ->create($request->stripeToken);

            return redirect()->route('home')->with('success', 'Your plan subscribed successfully');
    }
}

ビューを表示(show.blade.php)

@extends('layouts.app')

@section('content')
    <div class="container">
        <div class="row justify-content-center">
            <div class="col-md-12">
                <div class="">
                    <p>You will be charged ${{ number_format($plan->cost, 2) }} for {{ $plan->name }} Plan</p>
                </div>
                <div class="card">
                    <form action="{{ route('subscription.create') }}" method="post" id="payment-form">
                      @csrf
                      <div class="form-group">
                        <div class="card-header">
                            <label for="card-element">
                                Enter your credit card information
                            </label>
                        </div>

                        <div class="card-body">
                            <label for="card-element">Credit or debit card</label>

                        <div id="card-element">
                          <!-- A Stripe Element will be inserted here. -->
                        </div>

                        <!-- Used to display form errors. -->
                        <div id="card-errors" role="alert"></div>
                            <input type="hidden" name="plan" value="{{ $plan->id }}" />
                        </div>
                  </div>

                  <div class="card-footer">
                    <button class="btn btn-dark" type="submit">Submit Payment</button>
                  </div>
                </form>
            </div>
        </div>
    </div>
</div>
@endsection

@section('scripts')
    <script src="https://js.stripe.com/v3/"></script>
    <script>
        // Create a Stripe client.
        var stripe = Stripe('{{ env("STRIPE_KEY") }}');

        // Create an instance of Elements.
        var elements = stripe.elements();

        // Custom styling can be passed to options when creating an Element.
        // (Note that this demo uses a wider set of styles than the guide below.)
        var style = {
          base: {
            color: '#32325d',
            lineHeight: '18px',
            fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
            fontSmoothing: 'antialiased',
            fontSize: '16px',
            '::placeholder': {
              color: '#aab7c4'
            }
          },
          invalid: {
            color: '#fa755a',
            iconColor: '#fa755a'
          }
        };

        // Create an instance of the card Element.
        var card = elements.create('card', {style: style});

        // Add an instance of the card Element into the `card-element` <div>.
        card.mount('#card-element');

        // Handle real-time validation errors from the card Element.
        card.addEventListener('change', function(event) {
          var displayError = document.getElementById('card-errors');
          if (event.error) {
            displayError.textContent = event.error.message;
          } else {
            displayError.textContent = '';
          }
        });

        // Handle form submission.
        var form = document.getElementById('payment-form');
        form.addEventListener('submit', function(event) {
          event.preventDefault();

          stripe.createToken(card).then(function(result) {
            if (result.error) {
              // Inform the user if there was an error.
              var errorElement = document.getElementById('card-errors');
              errorElement.textContent = result.error.message;
            } else {
              // Send the token to your server.
              stripeTokenHandler(result.token);
            }
          });
        });

        // Submit the form with the token ID.
        function stripeTokenHandler(token) {
          // Insert token ID into the form so it gets submitted to the server
          var form = document.getElementById('payment-form');
          var hiddenInput = document.createElement('input');
          hiddenInput.setAttribute('type', 'hidden');
          hiddenInput.setAttribute('name', 'stripeToken');
          hiddenInput.setAttribute('value', token.id);
          form.appendChild(hiddenInput);

          // Submit the form
              form.submit();
        }
    </script>
@endsection
5
John Hubler

念のため、誰でもこの特定のチュートリアルでこのエラーをどのように修正したかを知りたいです:

1)キャッシャーバージョンをダウングレードしました

composer remove laravel/cashier

その後

composer require "laravel/cashier":"~9.0"

2)次に、別のエラーが発生し始めました:

no plan exists with the name (Basic/Professional)

これを修正するために、1回限りの製品の代わりに新しい定期的な製品を作成し、この新しいプランエントリでプランテーブルを更新しました

3)次に、もう一度別のエラーが発生しました:

no plan id exits

これを修正するには、ステップ2で取得したプランIDを使用してプランテーブルのstrip_plan列のエントリを更新しました

この特定のチュートリアルで機能していますが、他のバージョンについてはわかりません

1
Faiz Akhtar

あなたの問題はcreateメソッドかもしれないと思います。これを試して:

    namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Plan;

class SubscriptionController extends Controller {
    public function create(Request $request, Plan $plan) {
        $plan = Plan::findOrFail($request->get('plan'));

        \Auth::user() //make sure your user is signed in and use the authenticated user
            ->newSubscription('main', $request->plan) //You just send the name of the subscription in Stripe, not the object
            ->create($request->stripeToken);

        return redirect()->route('home')->with('success', 'Your plan subscribed successfully');
}

問題は、無効なユーザーを使用しているか、支払いプランの名前の代わりにプランオブジェクトを送信していることが原因だと思います。たとえば、「Plan 1」と「Plan 2」と呼ばれる価格プランを備えたストライプのMainという名前の製品がある場合、認証されたユーザーをサブスクライブするには、次のようにします。

\Auth::user
    ->newSubscription('Main', 'Plan 1')
    ->create($request->stripeToken);

ストライプ製品は次のようになります。

enter image description here

0
Kevin Daniel