Readouble

Laravel 8.x Laravel Cashier Mollie

注意Note

このページはlaravel/cashier-mollieパッケージのREADMEを翻訳したものです。Laravel Cashierの日本での利用者が少ないのかビュー数が低いため、このページへ頻繁に原文の変更を取り込む予定はありません。最新版をチェックしたい方は、オリジナル英文のREADMEを直接参照してください。This is a copy from laravel/cashier-mollie, not from laravel/docs repository. If you want to read current version of this documentation, please view original README page[https://github.com/laravel/cashier-mollie]. The reason this page hosted in this site, to show original English documentation of Japanese translation.


Laravel CashierはMollieの光り放つサービスを使った、サブスクリプションの読み書きしやすいインターフェイスを提供します。Laravel Cashier provides an expressive, fluent interface to subscriptions using Mollie[https://www.mollie.com]'s billing services.

インストールInstallation

このパッケージはComposerでインストールできます。You can pull this package in using composer:

composer require laravel/cashier-mollie "^1.0"

準備Setup

パッケージを入れ終わったら、次のように実行します。Once you have pulled in the package:

1. php artisan cashier:installを実行してください。1. Run php artisan cashier:install.

2. 以下のフィールドをBillableモデルのマイグレーションへ追加してください。(通常は、デフォルトの"create_user_table"マイグレーションです。)2. Add these fields to your billable model's migration (typically the default "create_user_table" migration):

    $table->string('mollie_customer_id')->nullable();
    $table->string('mollie_mandate_id')->nullable();
    $table->decimal('tax_percentage', 6, 4)->default(0); // オプション
    $table->dateTime('trial_ends_at')->nullable(); // オプション
    $table->text('extra_billing_information')->nullable(); // オプション

3. php artisan migrateでマイグレーションを実行します。3. Run the migrations: php artisan migrate

4. .envファイルでMOLLIE_KEYを設定します。MollieのダッシュボードからAPIキーを取得できます。4. Set the MOLLIE_KEY in your .env file. You can obtain an API key from the Mollie dashboard[https://www.mollie.com/dashboard/developers/api-keys]:

   MOLLIE_KEY="test_xxxxxxxxxxx"

5. 設定ファイルを用意します。5. Prepare the configuration files:

  • config/cashier_plans.phpへ、最低でも1つのサブスクリプションプランを設定してください。

    configure at least one subscription plan in config/cashier_plans.php.

  • config/cashier_coupons.phpで、全クーポンを管理します。デフォルトでクーポン例が有効になっています。実働環境へデプロイする前に無効へ設定するように注意してください。

    in config/cashier_coupons.php you can manage any coupons. By default an example coupon is enabled. Consider disabling it before deploying to production.

  • 基本的な設定はconfig/cashierです。変更する場合は注意してください。ほとんどの場合は変更の必要がありません。

    the base configuration is in config/cashier. Be careful while modifying this, in most cases you will not need to.

6. Billableモデルを用意します。(通常はデフォルトのLaravel Userモデルです。)6. Prepare the billable model (typically the default Laravel User model):

  • Laravel\Cashier\Billableトレイトを追加します。

    Add the Laravel\Cashier\Billable trait.

  • オプションとしてモバイルの顧客を生成時に、Billableモデルのどのフィールドを保存するかを設定するため、mollieCustomerFields()メソッドをオーバーライドすることもできます。LaravelのUserモデルはデフォルトでmollieCustomerFields()メソッドを始めから使用しています。

    Optionally, override the method mollieCustomerFields() to configure what billable model fields are stored while creating the Mollie Customer. Out of the box the mollieCustomerFields() method uses the default Laravel User model fields:

    public function mollieCustomerFields() {
        return [
            'email' => $this->email,
            'name' => $this->name,
        ];
    }

モバイルの顧客に対するデータ保管の詳細は、こちらで確認してください。Learn more about storing data on the Mollie Customer here[https://docs.mollie.com/reference/v2/customers-api/create-customer#parameters].

  • Laravel\Cashier\Order\Contracts\ProvidesInvoiceInformationを実装します。例をご覧ください。Implement Laravel\Cashier\Order\Contracts\ProvidesInvoiceInformation interface. For example:
   /**
    * インボイス情報のレシーバを取得
    * 通常は名前と(メール/実際の)アドレスのようなものが含まれる
    *
    * @return array 文字列の配列
    */
   public function getInvoiceInformation()
   {
       return [$this->name, $this->email];
   }

   /**
    * インボイスへ表示する追加の情報を取得(典型は顧客が提供した注釈)
    *
    * @return string|null
    */
   public function getExtraBillingInformation()
   {
       return null;
   }

7. 定期ジョブの実行をスケジュールする: Cashier::run().7. Schedule a periodic job to execute Cashier::run().

    $schedule->command('cashier:run')
        ->daily() // 好みの頻度で実行(Daily, monthly, every minuteなど)
        ->withoutOverlapping(); // 必ず指定する

Laravelを使用してジョブをスケジュールする詳細は、こちらにあります。You can find more about scheduling jobs using Laravel here[https://laravel.com/docs/scheduling].

🎉 これで使い始められます。🎉 You're now good to go :).

使用法Usage

サブスクリプションの作成Creating subscriptions

サブスクリプションを作成するには、まずBillableモデルのインスタンスを取得します。これは通常、App \ Userのインスタンスになります。 モデルインスタンスを取得したら、newSubscriptionメソッドを使用してモデルのサブスクリプションを作成できます。To create a subscription, first retrieve an instance of your billable model, which typically will be an instance of App\User. Once you have retrieved the model instance, you may use the newSubscription method to create the model's subscription:

$user = User::find(1);
// config/cashier_plans.phpの中で確実に'premium'プランを設定してください。
$result = $user->newSubscription('main', 'premium')->create();

顧客が有効なMollieの権限をすでに持っている場合、$ resultSubscriptionになります。If the customer already has a valid Mollie mandate, the $result will be a Subscription.

顧客に有効なMollie権限がない場合、$ resultRedirectToCheckoutResponseになり、顧客をMollieの支払いへリダイレクトして最初の支払いを行います。支払いを受け取ると、サブスクリプションが開始されます。If the customer has no valid Mollie mandate yet, the $result will be a RedirectToCheckoutResponse, redirecting the customer to the Mollie checkout to make the first payment. Once the payment has been received the subscription will start.

以下にサブスクリプション作成の基本的なコントローラの例を紹介します。Here's a basic controller example for creating the subscription:

namespace App\Http\Controllers;

use Laravel\Cashier\SubscriptionBuilder\RedirectToCheckoutResponse;
use Illuminate\Support\Facades\Auth;

class CreateSubscriptionController extends Controller
{
    /**
     * @param string $plan
     * @return \Illuminate\Http\RedirectResponse
     */
    public function __invoke(string $plan)
    {
        $user = Auth::user();

        $name = ucfirst($plan) . ' membership';

        if(!$user->subscribed($name, $plan)) {

            $result = $user->newSubscription($name, $plan)->create();

            if(is_a($result, RedirectToCheckoutResponse::class)) {
                return $result; // Mollieの支払いへリダイレクト
            }

            return back()->with('status', 'Welcome to the ' . $plan . ' plan');
        }

        return back()->with('status', 'You are already on the ' . $plan . ' plan');
    }
}

Mollieの支払いページへのリダイレクトを常に適用するには、 newSubscriptionの代わりに newSubscriptionViaMollieCheckoutメソッドを使用します。In order to always enforce a redirect to the Mollie checkout page, use the newSubscriptionViaMollieCheckout method instead of newSubscription:

$redirect = $user->newSubscriptionViaMollieCheckout('main', 'premium')->create(); // config/cashier_plans.phpの中で確実に'premium'プランを設定してください。

クーポンCoupons

Cashier Mollieのクーポン処理は柔軟性を考慮して設計されています。Coupon handling in Cashier Mollie is designed with full flexibility in mind.

クーポンはconfig/cashier_coupons.phpで定義できます。Coupons can be defined in config/cashier_coupons.php.

\Cashier\Discount\BaseCouponHandlerを拡張し、独自のクーポンハンドラを提供できます。You can provide your own coupon handler by extending \Cashier\Discount\BaseCouponHandler.

最初から基本的な"FixedDiscountHandler"を用意しています。Out of the box, a basic FixedDiscountHandler is provided.

既存サブスクリプションに対するクーポン適用Redeeming a coupon for an existing subscription

既存サブスクリプションに対しクーポンを利用するには、Billable traitのredeemCoupon()メソッドを使用します。For redeeming a coupon for an existing subscription, use the redeemCoupon() method on the billable trait:

$user->redeemCoupon('your-coupon-code');

これによりクーポンコードが検証され、クーポンを利用できます。クーポンは次回の注文に適用されます。This will validate the coupon code and redeem it. The coupon will be applied to the upcoming Order.

オプションで、適用するサブスクリプションを指定できます。Optionally, specify the subscription it should be applied to:

$user->redeemCoupon('your-coupon-code', 'main');

デフォルトでは、そのサブスクリプションに対する他の有効な適用済みクーポンはすべて取り消されます。これを防ぐには、$revokeOtherCouponsフラグをfalseに設定します。By default all other active redeemed coupons for the subscription will be revoked. You can prevent this by setting the $revokeOtherCoupons flag to false:

$user->redeemCoupon('your-coupon-code', 'main', false);

サブスクリプション状態のチェックChecking subscription status

ユーザーがアプリケーションのサブスクライブを開始すれば、さまざまな便利な方法を使用してサブスクリプションのステータスを簡単に確認できます。サブスクリプションが現在トライアル期間内であっても、ユーザーに有効なサブスクリプションがあれば、subscribedメソッドはtrueを返します。Once a user is subscribed to your application, you may easily check their subscription status using a variety of convenient methods. First, the subscribed method returns true if the user has an active subscription, even if the subscription is currently within its trial period:

if ($user->subscribed('main')) {
    //
}

subscribedメソッドは[ルートミドルウェア](https://www.laravel.com/docs/middleware)の優れた候補にもなり、ユーザーのサブスクリプション状態に基づいてルートとコントローラーへのアクセスをフィルターすることができます。The subscribed method also makes a great candidate for a route middleware[https://www.laravel.com/docs/middleware], allowing you to filter access to routes and controllers based on the user's subscription status:

public function handle($request, Closure $next)
{
    if ($request->user() && ! $request->user()->subscribed('main')) {
        // このユーザーは支払いを済ませていない顧客
        return redirect('billing');
    }

    return $next($request);
}

ユーザーがまだ試用期間内かどうかを判断する場合は、onTrialメソッドを使用します。このメソッドは、ユーザーがまだ試用期間中であるという警告を表示したいときにべんりです。。If you would like to determine if a user is still within their trial period, you may use the onTrial method. This method can be useful for displaying a warning to the user that they are still on their trial period:

if ($user->subscription('main')->onTrial()) {
    //
}

subscribedToPlanメソッドは、設定したプランに基づきユーザーが指定プランを定期購入しているかを判断するために使用します。この例では、ユーザーのmainサブスクリプションがmonthlyプランに対し、有効に定期購入されているかを判断します。The subscribedToPlan method may be used to determine if the user is subscribed to a given plan based on a configured plan. In this example, we will determine if the user's main subscription is actively subscribed to the monthly plan:

if ($user->subscribedToPlan('monthly', 'main')) {
    //
}

キャンセルしたサブスクリプションの状態Cancelled Subscription Status

そのユーザーが一度有効に定期購入した後に、キャンセルしたことを判定するには、cancelledメソッドを使用します。To determine if the user was once an active subscriber, but has cancelled their subscription, you may use the cancelled method:

if ($user->subscription('main')->cancelled()) {
    //
}

ユーザーがサブスクリプションをキャンセルしたが、それが完全に期限切れになるまで「猶予期間」が続いているかを確認することもできます。 たとえば、3月10日に期限が切れるように予定されていたサブスクリプションを3月5日にキャンセルした場合、ユーザーは3月10日まで「猶予期間」になります。この間も、subscribedメソッドはtrueを返します。You may also determine if a user has cancelled their subscription, but are still on their "grace period" until the subscription fully expires. For example, if a user cancels a subscription on March 5th that was originally scheduled to expire on March 10th, the user is on their "grace period" until March 10th. Note that the subscribed method still returns true during this time:

if ($user->subscription('main')->onGracePeriod()) {
    //
}

プラン変更Changing Plans

ユーザーがアプリケーションを定期購入した後、新しいサブスクリプションプランに変更したくなる場合もあるでしょう。 ユーザーを新しいサブスクリプションに切り替えるには、プランの識別子をswapまたはswapNextCycleメソッドに渡してください。After a user is subscribed to your application, they may occasionally want to change to a new subscription plan. To swap a user to a new subscription, pass the plan's identifier to the swap or swapNextCycle method:

$user = App\User::find(1);

// すぐに変更
$user->subscription('main')->swap('other-plan-id');

// 現在の購入期間が終えた時点で変更
$user->subscription('main')->swapNextCycle('other-plan-id');

ユーザーが試用期間中の場合、試用期間は維持されます。また、サブスクリプションに「購入数」が存在する場合、その購入数も維持されます。If the user is on trial, the trial period will be maintained. Also, if a "quantity" exists for the subscription, that quantity will also be maintained.

サブスクリプション購入数Subscription Quantity

サブスクリプションは「購入数」の影響を受ける場合があります。たとえば、アプリケーションでアカウントのユーザーごとに1か月あたり10ユーロを請求する場合があるでしょう。サブスクリプションの購入数を簡単に増減するには、incrementQuantitydecrementQuantityメソッドを使用します:Sometimes subscriptions are affected by "quantity". For example, your application might charge €10 per month per user on an account. To easily increment or decrement your subscription quantity, use the incrementQuantity and decrementQuantity methods:

$user = User::find(1);

$user->subscription('main')->incrementQuantity();

// 現在の購入数を5個増やす
$user->subscription('main')->incrementQuantity(5);

$user->subscription('main')->decrementQuantity();

// 現在の購入数を5個減らす
$user->subscription('main')->decrementQuantity(5);

もしくは、updateQuantityメソッドで特定の購入数をセットできます。Alternatively, you may set a specific quantity using the updateQuantity method:

$user->subscription('main')->updateQuantity(10);

サブスクリプションの税金Subscription Taxes

サブスクリプション購入でユーザーが支払う税率を指定するには、Billableモデルに対しtaxPercentageメソッドを実装し、数値で0から100の間のパーセンテージで指定します。To specify the tax percentage a user pays on a subscription, implement the taxPercentage method on your billable model, and return a numeric value between 0 and 100, with no more than 2 decimal places.

public function taxPercentage() {
    return 20;
}

taxPercentageメソッドによりモデルごとの税率を適用でき、多国間に渡る複数の税率を利用するユーザーに役立つでしょう。The taxPercentage method enables you to apply a tax rate on a model-by-model basis, which may be helpful for a user base that spans multiple countries and tax rates.

課税パーセントの同期Syncing Tax Percentages

taxPercentageメソッドが返すハードコードされた税率IDを変更しても、ユーザーの既存サブスクリプションの税率設定は同じままです。返されたtaxPercentage値で既存サブスクリプションの税率を更新する場合は、ユーザーのサブスクリプションインスタンスに対し、syncTaxPercentageメソッドを呼び出す必要があります。When changing the hard-coded value returned by the taxPercentage method, the tax settings on any existing subscriptions for the user will remain the same. If you wish to update the tax value for existing subscriptions with the returned taxPercentage value, you should call the syncTaxPercentage method on the user's subscription instance:

$user->subscription('main')->syncTaxPercentage();

サブスクリプション課金日付けSubscription Anchor Date

まだ実装されていません。しかし、毎月特定の日付だけにCashier::run()を実行するようにスケジュールすることで実現できます。Not (yet) implemented, but you could make this work by scheduling Cashier::run() to only execute on a specific day of the month.

サブスクリプションのキャンセルCancelling Subscriptions

サブスクリプションをキャンセルするにはcancelメソッドをユーザーのサブスクリプションに対して使ってください。To cancel a subscription, call the cancel method on the user's subscription:

$user->subscription('main')->cancel();

サブスクリプションがキャンセルされるとCashierは自動的に、データベースのends_atカラムをセットします。このカラムはいつからsubscribedメソッドがfalseを返し始めればよいのか、判定するために使用されています。たとえば、顧客が3月1日にキャンセルしたが、そのサブスクリプションが3月5日に終了するようにスケジュールされていれば、subscribedメソッドは3月5日になるまでtrueを返し続けます。When a subscription is cancelled, Cashier will automatically set the ends_at column in your database. This column is used to know when the subscribed method should begin returning false. For example, if a customer cancels a subscription on March 1st, but the subscription was not scheduled to end until March 5th, the subscribed method will continue to return true until March 5th.

ユーザーがサブスクリプションをキャンセルしたが、まだ「猶予期間」が残っているかどうかを調べるにはonGracePeriodメソッドを使います。You may determine if a user has cancelled their subscription but are still on their "grace period" using the onGracePeriod method:

if ($user->subscription('main')->onGracePeriod()) {
    //
}

サブスクリプションの再開Resuming Subscriptions

ユーザーがキャンセルしたサブスクリプションを、再開したいときには、resumeメソッドを使用してください。サブスクリプションを再開するには、そのユーザーに有効期間が残っている必要がありますIf a user has cancelled their subscription and you wish to resume it, use the resume method. The user must still be on their grace period in order to resume a subscription:

$user->subscription('main')->resume();

ユーザーがサブスクリプションをキャンセルし、それからそのサブスクリプションを再開する場合、そのサブスクリプションの有効期日が完全に切れていなければすぐに課金されません。そのサブスクリプションはシンプルに再度有効になり、元々の支払いサイクルにより課金されます。If the user cancels a subscription and then resumes that subscription before the subscription has fully expired, they will not be billed immediately. Instead, their subscription will be re-activated, and they will be billed on the original billing cycle.

顧客の支払い義務の更新Updating Customer payment mandates

まだ実装されていません。Coming soon.

サブスクリプション使用期限Subscription Trials

支払い登録ありWith Mandate Up Front

顧客へ試用期間を提供し、支払情報を事前に登録してもらう場合、サブスクリプションを作成するときにtrialDaysメソッドを使ってください。If you would like to offer trial periods to your customers while still collecting payment method information up front, you should use the trialDays method when creating your subscriptions:

$user = User::find(1);

$user->newSubscription('main', 'monthly')
            ->trialDays(10)
            ->create();

このメソッドはデータベースのサブスクリプションレコードへ、試用期間の終了日を設定します。This method will set the trial period ending date on the subscription record within the database.

Note: note 顧客は最初の支払い時に支払いを登録するため、Mollieの支払いページへリダイレクトされます。Cashierの設定ファイルで金額を更新できます。{note} The customer will be redirected to the Mollie checkout page to make the first payment in order to register a mandate. You can modify the amount in the cashier config file.

Note: note 顧客のサブスクリプションが試用期間の最後の日までにキャンセルされないと、期限が切れると同時に課金されます。そのため、ユーザーに試用期間の終了日を通知しておくべきでしょう。{note} If the customer's subscription is not cancelled before the trial ending date they will be charged as soon as the trial expires, so you should be sure to notify your users of their trial ending date.

trialUntilメソッドにより、使用期間の終了時を指定する、Carbonインスタンスを渡せますThe trialUntil method allows you to provide a Carbon instance to specify when the trial period should end:

use Carbon\Carbon;

$user->newSubscription('main', 'monthly')
            ->trialUntil(Carbon::now()->addDays(10))
            ->create();

ユーザーが使用期間中であるかを判定するには、ユーザーインスタンスに対しonTrialメソッドを使うか、サブスクリプションインスタンスに対してonTrialを使用してください。次の2つの例は、同じ目的を達します。You may determine if the user is within their trial period using either the onTrial method of the user instance, or the onTrial method of the subscription instance. The two examples below are identical:

if ($user->onTrial('main')) {
    //
}

if ($user->subscription('main')->onTrial()) {
    //
}

支払い登録なしWithout Mandate Up Front

事前にユーザーの支払い方法の情報を登録してもらうことなく、試用期間を提供する場合は、そのユーザーのレコードのtrial_ends_atに、試用の最終日を設定するだけです。典型的な使い方は、ユーザー登録時に設定する方法でしょう。If you would like to offer trial periods without collecting the user's payment method information up front, you may set the trial_ends_at column on the user record to your desired trial ending date. This is typically done during user registration:

$user = User::create([
    // 他のユーザープロパティの設定…
    'trial_ends_at' => now()->addDays(10),
]);

Note: note モデル定義のtrial_ends_atに対する、日付ミューテタを付け加えるのを忘れないでください。{note} Be sure to add a date mutator[https://laravel.com/docs/eloquent-mutators#date-mutators] for trial_ends_at to your model definition.

既存のサブスクリプションと関連付けが行われていないので、Cashierでは、このタイプの試用を「包括的な試用(generic trial)」と呼んでいます。Userインスタンスに対し、onTrialメソッドがtrueを返す場合、現在の日付はtrial_ends_atの値を過ぎていません。Cashier refers to this type of trial as a "generic trial", since it is not attached to any existing subscription. The onTrial method on the User instance will return true if the current date is not past the value of trial_ends_at:

if ($user->onTrial()) {
    // User is within their trial period...
}

とくに、ユーザーが「包括的な試用」期間中であり、まだサブスクリプションが作成されていないことを調べたい場合は、onGenericTrialメソッドが使用できます。You may also use the onGenericTrial method if you wish to know specifically that the user is within their "generic" trial period and has not created an actual subscription yet:

if ($user->onGenericTrial()) {
    // ユーザーは「包括的」な試用期間中
}

ユーザーに実際のサブスクリプションを作成する準備ができたら、通常はnewSubscriptionメソッドを使います。Once you are ready to create an actual subscription for the user, you may use the newSubscription method as usual:

$user = User::find(1);

$user->newSubscription('main', 'monthly')->create();

Webフックハンドラの定義Defining Webhook Event Handlers

Cashierは課金の失敗時に、サブスクリプションを自動的にキャンセル処理します。Cashier automatically handles subscription cancellation on failed charges.

また、Laravel\Cashier\Events名前空間下の以下のイベントをリッスンすることで、アプリケーションへ特定の振る舞いを追加できます。Additionally, listen for the following events (in the Laravel\Cashier\Events namespace) to add app specific behaviour:

  • OrderPaymentPaid and OrderPaymentFailedOrderPaymentPaid and OrderPaymentFailed
  • FirstPaymentPaid and FirstPaymentFailedFirstPaymentPaid and FirstPaymentFailed

一回限りの支払いOne-off charges

まだ実装されていません。Coming soon.

インボイスInvoices

Laravel\Cashier\Events名前空間下のOrderInvoiceAvailableイベントをリッスンしてください。新しい注文が処理されると、次のようにインボイスを取得できます。Listen for the OrderInvoiceAvailable event (in the Laravel\Cashier\Events namespace). When a new order has been processed, you can grab the invoice by

$invoice = $event->order->invoice();
$invoice->view(); // Bladeビューの取得
$invoice->pdf(); // BladeビューのPDF取得
$invoice->download(); // PDFのダウンロードレスポンス取得

ユーザーが注文したインボイスのリストへアクセスするには、$user->orders->invoices()をつかいます。これにはまだ処理されていない注文や、失敗した注文など全注文が含まれます。To list invoices, access the user's orders using: $user->orders->invoices(). This includes invoices for all orders, even unprocessed or failed orders.

払い戻しRefunding Charges

まだ実装されていません。Coming soon.

顧客の差し引き残高Customer balance

たとえばより安いプランへ変更したケースのように、顧客が払いすぎる状況は起きます。払いすぎた金額は、その顧客の差し引き残高へ加算されます。In some cases (i.e. when swapping to a cheaper plan), a customer can have overpaid. The amount that has been overpaid will be added to the customer balance.

顧客の差し引き残高は注文ごとに自動で処理します。The customer balance is automatically processed in each Order.

通貨ごとに別々の差し引き残高が保持されます。A separate balance is kept for each currency.

差し引き残高を直接操作するメソッドは、多少あります。There are a few methods available to interact with the balance directly.

注意深く使用してくださいUse these with care:

$credit = $user->credit('EUR');
$user->addCredit(new Amount(10, 'EUR'); // 10ユーロ追加
$user->hasCredit('EUR');

合計金額がマイナスになる注文が処理されると、その金額がユーザーの残高に加算されます。その時点でユーザーが有効なサブスクリプションを持っていない場合、BalanceTurnedStaleイベントが発生します。残りの残高を返金したい場合や、ユーザーに通知したい場合は、このイベントをリッスンしてください。When an Order with a negative total amount due is processed, that amount is credited to the user balance. A BalanceTurnedStale event will be raised if the user has no active subscriptions at that moment. Listen for this event if you'd like to refund the remaining balance and/or want to notify the user.

顧客のロケールCustomer locale

Mollieは、顧客の地域に合わせたチェックアウトを提供します。このため、訪問者のロケールを推測します。デフォルトのロケールを上書きするには、config/cashier.phpで設定します。これは単一国向けにサービスを提供するのに便利でしょう。Mollie provides a checkout tailored to the customer's locale. For this it guesses the visitor's locale. To override the default locale, configure it in config/cashier.php. This is convenient for servicing a single country.

複数のロケールを扱う場合にMollieのデフォルト動作をオーバーライドしたいときは、BillableモデルにgetLocale()メソッドを実装します。一般的な実現方法は、NULL値可能なlocaleフィールドをuserテーブルに追加し、その値を取得することです。If you're dealing with multiple locales and want to override Mollie's default behaviour, implement the getLocale() method on the billable model. A common way is to add a nullable locale field to the user table and retrieve its value:

class User extends Model
{
    /**
     * @return string
     * @link https://docs.mollie.com/reference/v2/payments-api/create-payment#parameters
     * @example 'nl_NL'
     */
    public function getLocale() {
        return $this->locale;
    }
}

Cashier全イベントAll Cashier Events

リッスンできるLaravel\Cashier\Events名前空間下のイベントを以下に紹介します。You can listen for the following events from the Laravel\Cashier\Events namespace:

BalanceTurnedStaleイベントBalanceTurnedStale event

ユーザーのアカウント残高はプラスですが、有効なサブスクリプションはありません。返金を検討してください。The user has a positive account balance, but no active subscriptions. Consider a refund.

CouponAppliedイベントCouponApplied event

クーポンが注文されたアイテムに適用されました。redeemingクーポンとapplyingクーポンの違いに注意してください。redeemingクーポンは複数の注文に適用できます。たとえば単一のredeemingクーポンを使用して毎月のサブスクリプションへ6ヶ月間割引を適用できます。A coupon was applied to an OrderItem. Note the distinction between redeeming a coupon and applying a coupon. A redeemed coupon can be applied to multiple orders. I.e. applying a 6 month discount on a monthly subscription using a single (redeemed) coupon.

FirstPaymentFailedイベントFirstPaymentFailed event

支払い登録を利用した、最初の支払いに失敗しました。The first payment (used for obtaining a mandate) has failed.

FirstPaymentPaidイベントFirstPaymentPaid event

支払い登録を利用した、最初の支払いに成功しました。The first payment (used for obtaining a mandate) was successful.

MandateClearedFromBillableイベントMandateClearedFromBillable event

mollie_mandate_idがBillableモデルへ作成されました。これは支払い登録が無効だったため、支払いへ失敗した場合に発生します。The mollie_mandate_id was cleared on the billable model. This happens when a payment has failed because of a invalid mandate.

MandateUpdatedイベントMandateUpdated event

Billableモデルの支払い登録が更新されました。これは通常、新しいカードが登録されたことを意味します。The billable model's mandate was updated. This usually means a new payment card was registered.

OrderCreatedイベントOrderCreated event

注文が作成されました。An Order was created.

OrderInvoiceAvailableイベントOrderInvoiceAvailable event

An Invoice is available on the Order. Access it using $event->order->invoice().An Invoice is available on the Order. Access it using $event->order->invoice().

OrderPaymentFailedイベントOrderPaymentFailed event

The payment for an order has failed.The payment for an order has failed.

OrderPaymentPaidイベントOrderPaymentPaid event

The payment for an order was successful.The payment for an order was successful.

OrderProcessedイベントOrderProcessed event

The order has been fully processed.The order has been fully processed.

SubscriptionStartedイベントSubscriptionStarted event

A new subscription was started.A new subscription was started.

SubscriptionCancelledイベントSubscriptionCancelled event

The subscription was cancelled.The subscription was cancelled.

SubscriptionResumedイベントSubscriptionResumed event

The subscription was resumed.The subscription was resumed.

SubscriptionPlanSwappedイベントSubscriptionPlanSwapped event

The subscription plan was swapped.The subscription plan was swapped.

SubscriptionQuantityUpdatedイベントSubscriptionQuantityUpdated event

The subscription quantity was updated.The subscription quantity was updated.

Metered billing with variable amountsMetered billing with variable amounts

Some business cases will require dynamic subscription amounts.Some business cases will require dynamic subscription amounts.

To allow for full flexibility Cashier Mollie allows you to define your own set of Subscription OrderItem preprocessors. These preprocessors are invoked when the OrderItem is due, right before being processed into a Mollie payment.To allow for full flexibility Cashier Mollie allows you to define your own set of Subscription OrderItem preprocessors. These preprocessors are invoked when the OrderItem is due, right before being processed into a Mollie payment.

If you're using metered billing, this is a convenient place to calculate the amount based on the usage statistics and reset any counters for the next billing cycle.If you're using metered billing, this is a convenient place to calculate the amount based on the usage statistics and reset any counters for the next billing cycle.

You can define the preprocessors in the cashier_plans config file.You can define the preprocessors in the cashier_plans config file.

Ok. So how does this all actually work?Ok. So how does this all actually work?

This Cashier implementation schedules triggering payments from the client side, instead of relying on subscription management at Mollie. (Yes, Mollie also offers a Subscription API, but it does not support all of Cashier features, so this package provides its own subscription engine.)This Cashier implementation schedules triggering payments from the client side, instead of relying on subscription management at Mollie. (Yes, Mollie also offers a Subscription API, but it does not support all of Cashier features, so this package provides its own subscription engine.)

From a high level perspective, this is what the process looks like:From a high level perspective, this is what the process looks like:

  1. A Subscription is created using the MandatePaymentSubscriptionBuilder (redirecting to Mollie's checkout to create a Mandate) or PremandatedSubscriptionBuilder (using an existing Mandate).
  2. The Subscription yields a scheduled OrderItem at the beginning of each billing cycle.The Subscription yields a scheduled OrderItem at the beginning of each billing cycle.
  3. OrderItems which are due are preprocessed and bundled into Orders whenever possible by a scheduled job (i.e. daily). This is done so your customer will receive a single payment/invoice for multiple items later on in the chain). Preprocessing the OrderItems may involve applying dynamic discounts or metered billing, depending on your configuration.OrderItems which are due are preprocessed and bundled into Orders whenever possible by a scheduled job (i.e. daily). This is done so your customer will receive a single payment/invoice for multiple items later on in the chain). Preprocessing the OrderItems may involve applying dynamic discounts or metered billing, depending on your configuration.
  4. The Order is processed by the same scheduled job into a payment:
    • First, (if available) the customer's balance is processed in the Order.First, (if available) the customer's balance is processed in the Order.
    • If the total due is positive, a Mollie payment is incurred.If the total due is positive, a Mollie payment is incurred.
    • If the total due is 0, nothing happens.If the total due is 0, nothing happens.
    • If the total due is negative, the amount is added to the user's balance. If the user has no active subscriptions left, the BalanceTurnedStale event will be raised.If the total due is negative, the amount is added to the user's balance. If the user has no active subscriptions left, the BalanceTurnedStale event will be raised.
  5. You can generate an Invoice (html/pdf) for the user.You can generate an Invoice (html/pdf) for the user.

F.A.Q. - Frequently Asked QuestionsF.A.Q. - Frequently Asked Questions

My billable model uses UUIDs, how can I get Cashier Mollie to work with this?My billable model uses UUIDs, how can I get Cashier Mollie to work with this?

By default Cashier Mollie uses unsignedInteger fields for the billable model relationships. If required for your billable model, modify the cashier migrations for UUIDs:By default Cashier Mollie uses unsignedInteger fields for the billable model relationships. If required for your billable model, modify the cashier migrations for UUIDs:

// Replace this:
$table->unsignedInteger('owner_id');

// By this:
$table->uuid('owner_id');

How is prorating handled?How is prorating handled?

Cashier Mollie applies prorating by default. With prorating, customers are billed at the start of each billing cycle.Cashier Mollie applies prorating by default. With prorating, customers are billed at the start of each billing cycle.

This means that when the subscription quantity is updated or is switched to another plan:This means that when the subscription quantity is updated or is switched to another plan:

  1. the billing cycle is resetthe billing cycle is reset
  2. the customer is credited for unused time, meaning that the amount that was overpaid is added to the customer's balance.the customer is credited for unused time, meaning that the amount that was overpaid is added to the customer's balance.
  3. a new billing cycle is started with the new subscription settings. An Order (and payment) is generated to deal with all of the previous, including applying the credited balance to the Order.a new billing cycle is started with the new subscription settings. An Order (and payment) is generated to deal with all of the previous, including applying the credited balance to the Order.

This does not apply to the $subscription->swapNextCycle('other-plan'), which simply waits for the next billing cycle to update the subscription plan. A common use case for this is downgrading the plan at the end of the billing cycle.This does not apply to the $subscription->swapNextCycle('other-plan'), which simply waits for the next billing cycle to update the subscription plan. A common use case for this is downgrading the plan at the end of the billing cycle.

How can I load coupons and/or plans from database?How can I load coupons and/or plans from database?

Because Cashier Mollie uses contracts a lot it's quite easy to extend Cashier Mollie and use your own implementations. You can load coupons/plans from database, a file or even a JSON API.Because Cashier Mollie uses contracts a lot it's quite easy to extend Cashier Mollie and use your own implementations. You can load coupons/plans from database, a file or even a JSON API.

For example a simple implementation of plans from the database:For example a simple implementation of plans from the database:

Firstly you create your own implementation of the plan repository and implement Laravel\Cashier\Plan\Contracts\PlanRepository. Implement the methods according to your needs and make sure you'll return a Laravel\Cashier\Plan\Contracts\Plan.Firstly you create your own implementation of the plan repository and implement Laravel\Cashier\Plan\Contracts\PlanRepository. Implement the methods according to your needs and make sure you'll return a Laravel\Cashier\Plan\Contracts\Plan.

use App\Plan;
use Laravel\Cashier\Exceptions\PlanNotFoundException;
use Laravel\Cashier\Plan\Contracts\PlanRepository;

class DatabasePlanRepository implements PlanRepository
{
    public static function find(string $name)
    {
        $plan = Plan::where('name', $name)->first();

        if (is_null($plan)) {
            return null;
        }

        // Return a \Laravel\Cashier\Plan\Plan by creating one from the database values
        return $plan->buildCashierPlan();

        // Or if your model implements the contract: \Laravel\Cashier\Plan\Contracts\Plan
        return $plan;
    }

    public static function findOrFail(string $name)
    {
        if (($result = self::find($name)) === null) {
            throw new PlanNotFoundException;
        }

        return $result;
    }
}
Example Plan model (app/Plan.php) with buildCashierPlan and returns a \Laravel\Cashier\Plan\Plan
<?php

namespace App;

use Laravel\Cashier\Plan\Plan as CashierPlan;
use Illuminate\Database\Eloquent\Model;

class Plan extends Model
{
    /**
     * Builds a Cashier plan from the current model.
     *
     * @returns \Laravel\Cashier\Plan\Plan
     */
    public function buildCashierPlan(): CashierPlan
    {
        $plan = new CashierPlan($this->name);

        return $plan->setAmount(mollie_array_to_money($this->amount))
            ->setInterval($this->interval)
            ->setDescription($this->description)
            ->setFirstPaymentMethod($this->first_payment_method)
            ->setFirstPaymentAmount(mollie_array_to_money($this->first_payment_amount))
            ->setFirstPaymentDescription($this->first_payment_description)
            ->setFirstPaymentRedirectUrl($this->first_payment_redirect_url)
            ->setFirstPaymentWebhookUrl($this->first_payment_webhook_url)
            ->setOrderItemPreprocessors(Preprocessors::fromArray($this->order_item_preprocessors));
    }
}

Note: In this case you'll need to add accessors for all the values (like amount, interval, fist_payment_method etc.) to make sure you'll use the values from your defaults (config/cashier_plans.php > defaults).Note: In this case you'll need to add accessors for all the values (like amount, interval, fist_payment_method etc.) to make sure you'll use the values from your defaults (config/cashier_plans.php > defaults).

Then you just have to bind your implementation to the Laravel/Illuminate container by registering the binding in a service providerThen you just have to bind your implementation to the Laravel/Illuminate container by registering the binding in a service provider

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->bind(\Laravel\Cashier\Plan\Contracts\PlanRepository::class, DatabasePlanRepository::class);
    }
}

Cashier Mollie will now use your implementation of the PlanRepository. For coupons this is basically the same, just make sure you implement the CouponRepository contract and bind the contract to your own implementation.Cashier Mollie will now use your implementation of the PlanRepository. For coupons this is basically the same, just make sure you implement the CouponRepository contract and bind the contract to your own implementation.

テストTesting

Cashier Mollie is tested against Mollie's test API.Cashier Mollie is tested against Mollie's test API.

Start with copying phpunit.xml.dist into phpunit.xml, and set these environment variables in phpunit.xml:Start with copying phpunit.xml.dist into phpunit.xml, and set these environment variables in phpunit.xml:

Mollie API test keyMollie API test key

You can obtain this key from the dashboard right after signing up.You can obtain this key from the dashboard right after signing up.

<env name="MOLLIE_KEY" value="YOUR_VALUE_HERE"/>

ID of a customer with a valid directdebit mandateID of a customer with a valid directdebit mandate

<env name="MANDATED_CUSTOMER_DIRECTDEBIT" value="YOUR_VALUE_HERE"/>

Mandate's ID (of the previously mentioned customer)Mandate's ID (of the previously mentioned customer)

<env name="MANDATED_CUSTOMER_DIRECTDEBIT_MANDATE_ID" value="YOUR_VALUE_HERE"/>

ID of a successful ("paid) payment by the customerID of a successful ("paid) payment by the customer

Use a 1000 EUR amount.Use a 1000 EUR amount.

<env name="PAYMENT_PAID_ID" value="YOUR_VALUE_HERE"/>

ID of an unsuccessful ("failed") payment by the customerID of an unsuccessful ("failed") payment by the customer

<env name="PAYMENT_FAILED_ID" value="YOUR_VALUE_HERE"/>

Now you can run:Now you can run:

composer test

貢献Contributing

Please see CONTRIBUTING for details.Please see CONTRIBUTING[CONTRIBUTING.md] for details.

脆弱性Security

If you discover any security related issues, please email support@mollie.com instead of using the issue tracker.If you discover any security related issues, please email support@mollie.com[mailto:support@mollie.com] instead of using the issue tracker.

クレジットCredits

ライセンスLicense

The MIT License (MIT). Please see License File for more information.The MIT License (MIT). Please see License File[LICENSE.md] for more information.

章選択

設定

明暗テーマ
light_mode
dark_mode
brightness_auto システム設定に合わせる
テーマ選択
photo_size_select_actual デフォルト
photo_size_select_actual モノクローム(白黒)
photo_size_select_actual Solarized風
photo_size_select_actual GitHub風(青ベース)
photo_size_select_actual Viva(黄緑ベース)
photo_size_select_actual Happy(紫ベース)
photo_size_select_actual Mint(緑ベース)
コードハイライトテーマ選択

明暗テーマごとに、コードハイライトのテーマを指定できます。

テーマ配色確認
スクリーン表示幅
640px
80%
90%
100%

768px以上の幅があるときのドキュメント部分表示幅です。

インデント
無し
1rem
2rem
3rem
原文確認
原文を全行表示
原文を一行ずつ表示
使用しない

※ 段落末のEボタンへカーソルオンで原文をPopupします。

Diff表示形式
色分けのみで区別
行頭の±で区別
削除線と追記で区別

※ [tl!…]形式の挿入削除行の表示形式です。

テストコード表示
両コード表示
Pestのみ表示
PHPUnitのみ表示
和文変換

対象文字列と置換文字列を半角スペースで区切ってください。(最大5組各10文字まで)

本文フォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

コードフォント

総称名以外はCSSと同様に、"〜"でエスケープしてください。

保存内容リセット

localStrageに保存してある設定項目をすべて削除し、デフォルト状態へ戻します。

ヘッダー項目移動

キーボード操作