صندوقدار لاراول (استریپ)
- معرفی
- ارتقاء صندوقدار
- نصب و راه اندازی
- پیکربندی
- شروع سریع
- مشتریان
- روش های پرداخت
- اشتراک ها
- آزمایشات اشتراک
- رسیدگی به قلاب های راه راه
- شارژ تک
- وارسی
- فاکتورها
- رسیدگی به پرداخت های ناموفق
- احراز هویت قوی مشتری (SCA)
- Stripe SDK
- آزمایش کردن
معرفی
Laravel Cashier Stripe یک رابط رسا و روان برای خدمات صورتحساب اشتراک Stripe فراهم می کند. تقریباً تمام کدهای صورتحساب اشتراک دیگ بخار را که از نوشتن آن میترسید مدیریت میکند. علاوه بر مدیریت اشتراک اولیه، Cashier میتواند کوپنها، تعویض اشتراک، «مقدار» اشتراک، دورههای مهلت لغو، و حتی فایلهای PDF فاکتور تولید کند.
ارتقاء صندوقدار
هنگام ارتقاء به نسخه جدید Cashier، مهم است که راهنمای ارتقا را به دقت مرور کنید .
برای جلوگیری از شکستن تغییرات، Cashier از یک نسخه API ثابت Stripe استفاده می کند. Cashier 15 از نسخه Stripe API استفاده می کند
2023-10-16
. نسخه Stripe API در نسخههای کوچک بهروزرسانی میشود تا از ویژگیها و بهبودهای جدید Stripe استفاده کند.
نصب و راه اندازی
ابتدا بسته Cashier را برای Stripe با استفاده از مدیریت بسته Composer نصب کنید:
composer require laravel/cashier
پس از نصب بسته، مهاجرت های Cashier را با استفاده از
vendor:publish
دستور Artisan منتشر کنید:
php artisan vendor:publish --tag="cashier-migrations"
سپس پایگاه داده خود را انتقال دهید:
php artisan migrate
مهاجرت صندوقدار چندین ستون به
users
جدول شما اضافه می کند. آنها همچنین یک
subscriptions
جدول جدید برای نگهداری تمام اشتراک های مشتری شما و یک
subscription_items
جدول برای اشتراک ها با چند قیمت ایجاد می کنند.
در صورت تمایل می توانید فایل پیکربندی Cashier را نیز با استفاده از
vendor:publish
دستور Artisan منتشر کنید:
php artisan vendor:publish --tag="cashier-config"
در نهایت، برای اطمینان از اینکه Cashier به درستی همه رویدادهای Stripe را مدیریت میکند، به یاد داشته باشید که کنترل وبهوک Cashier را پیکربندی کنید .
Stripe توصیه می کند که هر ستونی که برای ذخیره شناسه های Stripe استفاده می شود باید به حروف بزرگ و کوچک حساس باشد. بنابراین، باید اطمینان حاصل کنید که هنگام استفاده از MySQL، ترکیب ستون برای
stripe_id
ستون تنظیم شده استutf8_bin
. اطلاعات بیشتر در مورد این را می توان در مستندات Stripe یافت .
پیکربندی
مدل قابل پرداخت
قبل از استفاده از Cashier، این
Billable
ویژگی را به تعریف مدل قابل پرداخت خود اضافه کنید. به طور معمول، این مدل خواهد بود
App\Models\User
. این ویژگی روشهای مختلفی را ارائه میکند تا به شما امکان میدهد کارهای رایج صورتحساب را انجام دهید، مانند ایجاد اشتراک، اعمال کوپن، و بهروزرسانی اطلاعات روش پرداخت:
use Laravel\Cashier\Billable; class User extends Authenticatable{ use Billable;}
صندوقدار فرض می کند مدل قابل پرداخت شما همان کلاسی است
App\Models\User
که با لاراول ارسال می شود. اگر می خواهید این را تغییر دهید، می توانید مدل دیگری را از طریق
useCustomerModel
روش مشخص کنید. این متد معمولاً باید در
boot
متد کلاس شما
فراخوانی شود
AppServiceProvider
:
use App\Models\Cashier\User;use Laravel\Cashier\Cashier; /** * Bootstrap any application services. */public function boot(): void{ Cashier::useCustomerModel(User::class);}
اگر از مدلی غیر از مدل ارائه شده لاراول استفاده میکنید
App\Models\User
، باید مهاجرتهای Cashier ارائه شده را منتشر کرده و تغییر دهید تا با نام جدول مدل جایگزین شما مطابقت داشته باشد.
کلیدهای API
در مرحله بعد، باید کلیدهای Stripe API خود را در
.env
فایل برنامه خود پیکربندی کنید. می توانید کلیدهای Stripe API خود را از کنترل پنل Stripe بازیابی کنید:
STRIPE_KEY=your-stripe-keySTRIPE_SECRET=your-stripe-secretSTRIPE_WEBHOOK_SECRET=your-stripe-webhook-secret
باید اطمینان حاصل کنید که
STRIPE_WEBHOOK_SECRET
متغیر محیطی در فایل برنامه شما تعریف شده است.env
، زیرا این متغیر برای اطمینان از اینکه وب هوک های ورودی واقعاً از Stripe هستند استفاده می شود.
پیکربندی ارز
واحد پول نقد پیش فرض دلار آمریکا (USD) است. میتوانید با تنظیم
CASHIER_CURRENCY
متغیر محیطی در فایل برنامه، واحد پول پیشفرض را تغییر دهید
.env
:
CASHIER_CURRENCY=eur
علاوه بر پیکربندی واحد پول Cashier، میتوانید محلی را نیز تعیین کنید که هنگام قالببندی مقادیر پول برای نمایش در فاکتورها استفاده شود. در داخل، Cashier از
کلاس
PHP
NumberFormatter
برای تنظیم محلی ارز استفاده می کند:
CASHIER_CURRENCY_LOCALE=nl_BE
به منظور استفاده از زبانهای محلی به غیر از
en
، مطمئن شوید کهext-intl
پسوند PHP روی سرور شما نصب و پیکربندی شده است.
پیکربندی مالیاتی
به لطف
Stripe Tax
، امکان محاسبه خودکار مالیات برای همه فاکتورهای تولید شده توسط Stripe وجود دارد. می توانید محاسبه خودکار مالیات را با فراخوانی
calculateTaxes
روش موجود در
boot
متد کلاس برنامه خود فعال کنید
App\Providers\AppServiceProvider
:
use Laravel\Cashier\Cashier; /** * Bootstrap any application services. */public function boot(): void{ Cashier::calculateTaxes();}
هنگامی که محاسبه مالیات فعال شد، هر اشتراک جدید و هر فاکتور یکباره ای که ایجاد می شود، محاسبه مالیات خودکار دریافت می کند.
برای اینکه این ویژگی به درستی کار کند، جزئیات صورتحساب مشتری، مانند نام، آدرس و شناسه مالیاتی مشتری، باید با Stripe همگامسازی شود. برای انجام این کار میتوانید از روشهای همگامسازی دادههای مشتری و شناسه مالیاتی ارائه شده توسط Cashier استفاده کنید.
هیچ مالیاتی برای شارژ تک یا پرداخت تک شارژ محاسبه نمی شود .
ورود به سیستم
Cashier به شما امکان می دهد کانال ورود به سیستم را برای استفاده در هنگام ثبت خطاهای کشنده Stripe مشخص کنید. میتوانید کانال گزارش را با تعریف
CASHIER_LOGGER
متغیر محیطی در فایل برنامه خود مشخص کنید
.env
:
CASHIER_LOGGER=stack
استثناهایی که توسط فراخوانی های API به Stripe ایجاد می شوند از طریق کانال گزارش پیش فرض برنامه شما ثبت می شوند.
استفاده از مدل های سفارشی
شما آزاد هستید که مدل های مورد استفاده داخلی توسط صندوقدار را با تعریف مدل خود و گسترش مدل صندوقدار مربوطه گسترش دهید:
use Laravel\Cashier\Subscription as CashierSubscription; class Subscription extends CashierSubscription{ // ...}
پس از تعریف مدل خود، ممکن است به Cashier دستور دهید که از مدل سفارشی شما از طریق
Laravel\Cashier\Cashier
کلاس استفاده کند. به طور معمول، شما باید مدل های سفارشی خود را در
boot
روش کلاس برنامه خود به Cashier اطلاع دهید
App\Providers\AppServiceProvider
:
use App\Models\Cashier\Subscription;use App\Models\Cashier\SubscriptionItem; /** * Bootstrap any application services. */public function boot(): void{ Cashier::useSubscriptionModel(Subscription::class); Cashier::useSubscriptionItemModel(SubscriptionItem::class);}
شروع سریع
فروش محصولات
قبل از استفاده از Stripe Checkout، باید محصولاتی را با قیمت های ثابت در داشبورد Stripe خود تعریف کنید. علاوه بر این، باید مدیریت وب هوک Cashier را پیکربندی کنید .
ارائه صورتحساب محصول و اشتراک از طریق برنامه شما می تواند ترسناک باشد. با این حال، به لطف Cashier و Stripe Checkout ، می توانید به راحتی یکپارچه سازی پرداخت مدرن و قوی ایجاد کنید.
برای دریافت هزینه از مشتریان برای محصولات غیر تکراری و تک شارژ، از Cashier استفاده می کنیم تا مشتریان را به Stripe Checkout هدایت کنیم، جایی که آنها جزئیات پرداخت خود را ارائه می دهند و خرید خود را تأیید می کنند. هنگامی که پرداخت از طریق Checkout انجام شد، مشتری به آدرس اینترنتی موفقیت آمیز مورد نظر شما در برنامه شما هدایت می شود:
use Illuminate\Http\Request; Route::get('/checkout', function (Request $request) { $stripePriceId = 'price_deluxe_album'; $quantity = 1; return $request->user()->checkout([$stripePriceId => $quantity], [ 'success_url' => route('checkout-success'), 'cancel_url' => route('checkout-cancel'), ]);})->name('checkout'); Route::view('checkout.success')->name('checkout-success');Route::view('checkout.cancel')->name('checkout-cancel');
همانطور که در مثال بالا می بینید، ما از
checkout
روش ارائه شده توسط Cashier برای هدایت مشتری به Stripe Checkout برای یک "شناسه قیمت" استفاده می کنیم. هنگام استفاده از Stripe، "قیمت ها" به
قیمت های تعریف شده برای محصولات خاص
اشاره دارد .
در صورت لزوم، این
checkout
روش به طور خودکار یک مشتری در Stripe ایجاد می کند و رکورد مشتری Stripe را به کاربر مربوطه در پایگاه داده برنامه شما متصل می کند. پس از اتمام جلسه تسویه حساب، مشتری به صفحه موفقیت یا لغو اختصاصی هدایت می شود که در آن می توانید یک پیام اطلاعاتی برای مشتری نمایش دهید.
ارائه متا داده به Stripe Checkout
هنگام فروش محصولات، پیگیری سفارشات تکمیلشده و محصولات خریداریشده از طریق
Cart
و
Order
مدلهایی که توسط برنامه شخصی شما تعریف شدهاند، معمول است. هنگام هدایت مشتریان به Stripe Checkout برای تکمیل یک خرید، ممکن است لازم باشد یک شناسه سفارش موجود ارائه دهید تا زمانی که مشتری به برنامه شما هدایت می شود، بتوانید خرید تکمیل شده را با سفارش مربوطه مرتبط کنید.
برای انجام این کار، ممکن است آرایه ای از متد ارائه
metadata
دهید
checkout
. بیایید تصور کنیم
Order
زمانی که کاربر فرآیند پرداخت را شروع میکند، در برنامه ما یک معلق ایجاد میشود. به یاد داشته باشید، مدلهای
Cart
و
Order
در این مثال گویا هستند و توسط Cashier ارائه نشدهاند. شما آزاد هستید که این مفاهیم را بر اساس نیازهای برنامه خود پیاده سازی کنید:
use App\Models\Cart;use App\Models\Order;use Illuminate\Http\Request; Route::get('/cart/{cart}/checkout', function (Request $request, Cart $cart) { $order = Order::create([ 'cart_id' => $cart->id, 'price_ids' => $cart->price_ids, 'status' => 'incomplete', ]); return $request->user()->checkout($order->price_ids, [ 'success_url' => route('checkout-success').'?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => route('checkout-cancel'), 'metadata' => ['order_id' => $order->id], ]);})->name('checkout');
همانطور که در مثال بالا می بینید، زمانی که کاربر فرآیند پرداخت را شروع می کند، ما همه شناسه های قیمت Stripe مربوط به سبد خرید/سفارش را به روش ارائه می دهیم
checkout
. البته، اپلیکیشن شما مسئول مرتبط کردن این موارد با «سبد خرید» یا سفارشی است که مشتری آنها را اضافه میکند. همچنین شناسه سفارش را از طریق
metadata
آرایه به جلسه Stripe Checkout ارائه می کنیم. در نهایت
CHECKOUT_SESSION_ID
متغیر قالب را به مسیر موفقیت Checkout
اضافه کرده ایم .
هنگامی که Stripe مشتریان را به برنامه شما هدایت می کند، این متغیر الگو به طور خودکار با شناسه جلسه Checkout پر می شود.
در مرحله بعد، بیایید مسیر موفقیت Checkout را بسازیم. این مسیری است که کاربران پس از تکمیل خرید از طریق Stripe Checkout به آن هدایت خواهند شد. در این مسیر، میتوانیم شناسه جلسه Stripe Checkout و نمونه مربوط به Stripe Checkout را بازیابی کنیم تا بتوانیم به دادههای متا ارائه شده خود دسترسی داشته باشیم و سفارش مشتری خود را بر این اساس بهروزرسانی کنیم:
use App\Models\Order;use Illuminate\Http\Request;use Laravel\Cashier\Cashier; Route::get('/checkout/success', function (Request $request) { $sessionId = $request->get('session_id'); if ($sessionId === null) { return; } $session = Cashier::stripe()->checkout->sessions->retrieve($sessionId); if ($session->payment_status !== 'paid') { return; } $orderId = $session['metadata']['order_id'] ?? null; $order = Order::findOrFail($orderId); $order->update(['status' => 'completed']); return view('checkout-success', ['order' => $order]);})->name('checkout-success');
لطفاً برای اطلاعات بیشتر در مورد داده های موجود در شی جلسه Checkout به مستندات Stripe مراجعه کنید .
فروش اشتراک
قبل از استفاده از Stripe Checkout، باید محصولاتی را با قیمت های ثابت در داشبورد Stripe خود تعریف کنید. علاوه بر این، باید مدیریت وب هوک Cashier را پیکربندی کنید .
ارائه صورتحساب محصول و اشتراک از طریق برنامه شما می تواند ترسناک باشد. با این حال، به لطف Cashier و Stripe Checkout ، می توانید به راحتی یکپارچه سازی پرداخت مدرن و قوی ایجاد کنید.
برای یادگیری نحوه فروش اشتراک با استفاده از Cashier و Stripe Checkout، اجازه دهید سناریوی ساده یک سرویس اشتراک با یک برنامه اولیه ماهانه (
price_basic_monthly
) و سالانه (
price_basic_yearly
) را در نظر بگیریم. این دو قیمت را می توان تحت یک محصول "پایه" (
pro_basic
) در داشبورد Stripe ما گروه بندی کرد. علاوه بر این، خدمات اشتراک ما ممکن است یک طرح متخصص به عنوان ارائه دهد
pro_expert
.
ابتدا، بیایید کشف کنیم که چگونه یک مشتری می تواند در خدمات ما مشترک شود. البته، می توانید تصور کنید که مشتری ممکن است روی دکمه "اشتراک" برای طرح پایه در صفحه قیمت برنامه ما کلیک کند. این دکمه یا پیوند باید کاربر را به مسیر لاراول هدایت کند که جلسه Stripe Checkout را برای برنامه انتخابی او ایجاد می کند:
use Illuminate\Http\Request; Route::get('/subscription-checkout', function (Request $request) { return $request->user() ->newSubscription('default', 'price_basic_monthly') ->trialDays(5) ->allowPromotionCodes() ->checkout([ 'success_url' => route('your-success-route'), 'cancel_url' => route('your-cancel-route'), ]);});
همانطور که در مثال بالا می بینید، ما مشتری را به جلسه Stripe Checkout هدایت می کنیم که به آنها امکان می دهد در طرح اولیه ما مشترک شوند. پس از تسویه حساب یا لغو موفقیت آمیز، مشتری به آدرس اینترنتی که به روش ارائه کرده ایم هدایت می شود
checkout
. برای اینکه بدانیم اشتراک آنها واقعاً چه زمانی شروع شده است (از آنجایی که پردازش برخی از روش های پرداخت به چند ثانیه نیاز دارد)، همچنین باید
مدیریت وب هوک Cashier را نیز پیکربندی
کنیم .
اکنون که مشتریان می توانند اشتراک را شروع کنند، باید بخش های خاصی از برنامه خود را محدود کنیم تا فقط کاربران مشترک بتوانند به آنها دسترسی داشته باشند. البته، ما همیشه میتوانیم وضعیت اشتراک فعلی کاربر را از طریق
subscribed
روش ارائه شده توسط ویژگی Cashier تعیین کنیم
Billable
:
@if ($user->subscribed()) <p>You are subscribed.</p>@endif
ما حتی می توانیم به راحتی تعیین کنیم که آیا کاربر مشترک محصول یا قیمت خاصی است یا خیر:
@if ($user->subscribedToProduct('pro_basic')) <p>You are subscribed to our Basic product.</p>@endif @if ($user->subscribedToPrice('price_basic_monthly')) <p>You are subscribed to our monthly Basic plan.</p>@endif
ساخت میان افزار مشترک
برای راحتی، ممکن است بخواهید یک میان افزار ایجاد کنید که تعیین می کند آیا درخواست دریافتی از یک کاربر مشترک است یا خیر. هنگامی که این میان افزار تعریف شد، می توانید به راحتی آن را به مسیری اختصاص دهید تا از دسترسی کاربرانی که مشترک نیستند به مسیر جلوگیری کنید:
<?php namespace App\Http\Middleware; use Closure;use Illuminate\Http\Request;use Symfony\Component\HttpFoundation\Response; class Subscribed{ /** * Handle an incoming request. */ public function handle(Request $request, Closure $next): Response { if (! $request->user()?->subscribed()) { // Redirect user to billing page and ask them to subscribe... return redirect('/billing'); } return $next($request); }}
هنگامی که میان افزار تعریف شد، می توانید آن را به یک مسیر اختصاص دهید:
use App\Http\Middleware\Subscribed; Route::get('/dashboard', function () { // ...})->middleware([Subscribed::class]);
به مشتریان اجازه می دهد تا برنامه صورتحساب خود را مدیریت کنند
البته ممکن است مشتریان بخواهند طرح اشتراک خود را به محصول یا «سطح» دیگری تغییر دهند. سادهترین راه برای اجازه دادن به این امر، هدایت مشتریان به پورتال صورتحساب مشتری Stripe است که یک رابط کاربری میزبانی شده را ارائه میدهد که به مشتریان امکان میدهد فاکتورها را دانلود کنند، روش پرداخت خود را بهروزرسانی کنند، و طرحهای اشتراک را تغییر دهند.
ابتدا پیوند یا دکمه ای را در برنامه خود تعریف کنید که کاربران را به مسیر لاراول هدایت می کند و ما از آن برای راه اندازی جلسه پورتال صورتحساب استفاده خواهیم کرد:
<a href="{{ route('billing') }}"> Billing</a>
در مرحله بعد، بیایید مسیری را تعریف کنیم که جلسه پورتال صورتحساب مشتری Stripe را آغاز میکند و کاربر را به پورتال هدایت میکند. این
redirectToBillingPortal
روش نشانی اینترنتی را میپذیرد که کاربران باید هنگام خروج از پورتال به آن بازگردانده شوند:
use Illuminate\Http\Request; Route::get('/billing', function (Request $request) { return $request->user()->redirectToBillingPortal(route('dashboard'));})->middleware(['auth'])->name('billing');
تا زمانی که مدیریت وب هوک Cashier را پیکربندی کرده باشید، Cashier به طور خودکار جداول پایگاه داده مربوط به Cashier برنامه شما را با بازرسی وبکهک های ورودی از Stripe همگام نگه می دارد. بنابراین، برای مثال، هنگامی که کاربر اشتراک خود را از طریق پورتال صورتحساب مشتری Stripe لغو میکند، Cashier وب هوک مربوطه را دریافت میکند و اشتراک را به عنوان "لغو شده" در پایگاه داده برنامه شما علامتگذاری میکند.
مشتریان
بازیابی مشتریان
با استفاده از این روش میتوانید یک مشتری را با شناسه Stripe او بازیابی کنید
Cashier::findBillable
. این روش نمونه ای از مدل قابل پرداخت را برمی گرداند:
use Laravel\Cashier\Cashier; $user = Cashier::findBillable($stripeId);
ایجاد مشتریان
گاهی اوقات، ممکن است بخواهید بدون شروع اشتراک، یک مشتری Stripe ایجاد کنید. شما می توانید این کار را با استفاده از
createAsStripeCustomer
روش زیر انجام دهید:
$stripeCustomer = $user->createAsStripeCustomer();
هنگامی که مشتری در Stripe ایجاد شد، می توانید در تاریخ بعد اشتراک خود را شروع کنید. میتوانید یک
$options
آرایه اختیاری برای ارسال هر
پارامتر ایجاد مشتری اضافی که توسط Stripe API پشتیبانی میشود
ارائه کنید :
$stripeCustomer = $user->createAsStripeCustomer($options);
asStripeCustomer
اگر میخواهید شی مشتری Stripe را برای یک مدل قابل صورتحساب برگردانید،
میتوانید از روش استفاده کنید :
$stripeCustomer = $user->asStripeCustomer();
createOrGetStripeCustomer
اگر بخواهید شی مشتری Stripe را برای یک مدل قابل صورتحساب معین بازیابی کنید، اما مطمئن نیستید که آیا مدل قابل صورتحساب قبلاً یک مشتری در Stripe است،
این روش ممکن است استفاده شود.
اگر مشتری از قبل وجود نداشته باشد، این روش یک مشتری جدید در Stripe ایجاد می کند:
$stripeCustomer = $user->createOrGetStripeCustomer();
به روز رسانی مشتریان
گاهی اوقات، ممکن است بخواهید مشتری Stripe را مستقیماً با اطلاعات اضافی به روز کنید. شما می توانید این کار را با استفاده از
updateStripeCustomer
روش انجام دهید. این روش آرایه ای از
گزینه های به روز رسانی مشتری را می پذیرد که توسط Stripe API پشتیبانی می شوند
:
$stripeCustomer = $user->updateStripeCustomer($options);
موازنه
Stripe به شما این امکان را می دهد که "موجودی" مشتری را اعتبار یا بدهی کنید. بعداً این موجودی در فاکتورهای جدید بستانکار یا بدهکار خواهد شد. برای بررسی موجودی کل مشتری می توانید از روشی استفاده کنید
balance
که در مدل قابل پرداخت شما موجود است. این
balance
روش یک نمایش رشته فرمت شده از موجودی در واحد پول مشتری را برمی گرداند:
$balance = $user->balance();
برای اعتبار دادن به موجودی مشتری، ممکن است مقداری برای
creditBalance
روش ارائه دهید. در صورت تمایل می توانید توضیحاتی نیز ارائه دهید:
$user->creditBalance(500, 'Premium customer top-up.');
ارائه یک مقدار به
debitBalance
روش، موجودی مشتری را بدهکار می کند:
$user->debitBalance(300, 'Bad usage penalty.');
این
applyBalance
روش تراکنش های موجودی جدید مشتری را برای مشتری ایجاد می کند. می توانید این سوابق تراکنش را با استفاده از
balanceTransactions
روشی که ممکن است برای ارائه گزارشی از اعتبارات و بدهی ها برای بررسی مشتری مفید باشد، بازیابی کنید:
// Retrieve all transactions...$transactions = $user->balanceTransactions(); foreach ($transactions as $transaction) { // Transaction amount... $amount = $transaction->amount(); // $2.31 // Retrieve the related invoice when available... $invoice = $transaction->invoice();}
شناسه های مالیاتی
صندوقدار یک راه آسان برای مدیریت شناسه مالیاتی مشتری ارائه می دهد. برای مثال، این
taxIds
روش ممکن است برای بازیابی همه
شناسههای مالیاتی
که بهعنوان مجموعه به مشتری اختصاص داده شدهاند استفاده شود:
$taxIds = $user->taxIds();
همچنین میتوانید یک شناسه مالیاتی خاص را برای یک مشتری با شناسه آن بازیابی کنید:
$taxId = $user->findTaxId('txi_belgium');
می توانید با ارائه یک
نوع
و مقدار معتبر برای
createTaxId
روش، یک شناسه مالیاتی جدید ایجاد کنید:
$taxId = $user->createTaxId('eu_vat', 'BE0123456789');
این
createTaxId
روش بلافاصله شناسه مالیات بر ارزش افزوده را به حساب مشتری اضافه می کند.
تایید شناسه های مالیات بر ارزش افزوده نیز توسط Stripe انجام می شود
. با این حال، این یک فرآیند ناهمزمان است. میتوانید با اشتراک در
customer.tax_id.updated
رویداد webhook و بررسی
پارامتر
VAT IDها
verification
از بهروزرسانیهای تأیید مطلع شوید . برای اطلاعات بیشتر در مورد مدیریت وب هوک، لطفاً به
مستندات مربوط به تعریف کنترل کننده های وب هوک
مراجعه کنید .
می توانید شناسه مالیاتی را با استفاده از
deleteTaxId
روش زیر حذف کنید:
$user->deleteTaxId('txi_belgium');
همگام سازی داده های مشتری با Stripe
به طور معمول، زمانی که کاربران برنامه شما نام، آدرس ایمیل یا سایر اطلاعاتی را که توسط Stripe نیز ذخیره شده است به روز می کنند، باید Stripe را از به روز رسانی ها مطلع کنید. با انجام این کار، کپی Stripe از اطلاعات با برنامه شما همگام خواهد شد.
برای خودکارسازی این کار، ممکن است شنونده رویدادی را در مدل قابل پرداخت خود تعریف کنید که به رویداد مدل واکنش نشان میدهد
updated
. سپس، در شنونده رویداد خود، می توانید
syncStripeCustomerDetails
متد را در مدل فراخوانی کنید:
use App\Models\User;use function Illuminate\Events\queueable; /** * The "booted" method of the model. */protected static function booted(): void{ static::updated(queueable(function (User $customer) { if ($customer->hasStripeId()) { $customer->syncStripeCustomerDetails(); } }));}
اکنون، هر بار که مدل مشتری شما بهروزرسانی میشود، اطلاعات آن با Stripe همگامسازی میشود. برای راحتی، Cashier به طور خودکار اطلاعات مشتری شما را با Stripe در ایجاد اولیه مشتری همگام می کند.
میتوانید ستونهایی را که برای همگامسازی اطلاعات مشتری با Stripe استفاده میشوند، با نادیده گرفتن انواع روشهای ارائه شده توسط Cashier سفارشی کنید. برای مثال، میتوانید
stripeName
روش سفارشیسازی ویژگیای را که باید بهعنوان «نام» مشتری در نظر گرفته شود، در زمانی که Cashier اطلاعات مشتری را با Stripe همگامسازی میکند، لغو کنید:
/** * Get the customer name that should be synced to Stripe. */public function stripeName(): string|null{ return $this->company_name;}
به طور مشابه، میتوانید روشهای
stripeEmail
،
stripePhone
و
stripeAddress
، و را لغو کنید
stripePreferredLocales
. این روشها هنگام
بهروزرسانی شی مشتری Stripe،
اطلاعات را با پارامترهای مشتری مربوطه همگامسازی میکنند
. اگر میخواهید کنترل کاملی بر فرآیند همگامسازی اطلاعات مشتری در دست بگیرید، ممکن است این
syncStripeCustomerDetails
روش را لغو کنید.
پورتال صورتحساب
Stripe
یک راه آسان برای راه اندازی یک پورتال صورتحساب
ارائه می دهد تا مشتری شما بتواند اشتراک، روش های پرداخت خود را مدیریت کند و سابقه صورتحساب خود را مشاهده کند. میتوانید با فراخوانی
redirectToBillingPortal
روش روی مدل قابل پرداخت از یک کنترلکننده یا مسیر،
کاربران خود را به درگاه صورتحساب هدایت کنید :
use Illuminate\Http\Request; Route::get('/billing-portal', function (Request $request) { return $request->user()->redirectToBillingPortal();});
به طور پیش فرض، زمانی که کاربر مدیریت اشتراک خود را به پایان رساند، می تواند
home
از طریق پیوندی در پورتال صورتحساب Stripe به مسیر برنامه شما بازگردد. شما می توانید یک URL سفارشی ارائه کنید که کاربر باید با ارسال URL به عنوان آرگومان به
redirectToBillingPortal
روش، به آن بازگردد:
use Illuminate\Http\Request; Route::get('/billing-portal', function (Request $request) { return $request->user()->redirectToBillingPortal(route('billing'));});
اگر می خواهید URL را به درگاه صورتحساب بدون ایجاد پاسخ تغییر مسیر HTTP ایجاد کنید، می توانید
billingPortalUrl
روش زیر را فراخوانی کنید:
$url = $request->user()->billingPortalUrl(route('billing'));
روش های پرداخت
ذخیره سازی روش های پرداخت
برای ایجاد اشتراک یا انجام هزینههای «یکباره» با Stripe، باید یک روش پرداخت را ذخیره کرده و شناسه آن را از Stripe بازیابی کنید. رویکرد مورد استفاده برای انجام این کار بسته به اینکه قصد دارید از روش پرداخت برای اشتراک یا هزینه تکی استفاده کنید متفاوت است، بنابراین در زیر هر دو را بررسی خواهیم کرد.
روش های پرداخت برای اشتراک
هنگام ذخیره اطلاعات کارت اعتباری مشتری برای استفاده در آینده توسط یک اشتراک، باید از Stripe "Setup Intents" API برای جمع آوری ایمن جزئیات روش پرداخت مشتری استفاده شود. یک "نیت راه اندازی" به Stripe نشان می دهد که قصد دارد از روش پرداخت مشتری هزینه کند. ویژگی
Cashier
Billable
شامل
createSetupIntent
روش ایجاد آسان Setup Intent است. شما باید این روش را از مسیر یا کنترلکنندهای فراخوانی کنید که فرمی را که جزئیات روش پرداخت مشتری شما را جمعآوری میکند ارائه میکند:
return view('update-payment-method', [ 'intent' => $user->createSetupIntent()]);
پس از ایجاد Setup Intent و ارسال آن به view، باید راز آن را به عنصری متصل کنید که روش پرداخت را جمع آوری می کند. به عنوان مثال، این فرم "به روز رسانی روش پرداخت" را در نظر بگیرید:
<input id="card-holder-name" type="text"> <!-- Stripe Elements Placeholder --><div id="card-element"></div> <button id="card-button" data-secret="{{ $intent->client_secret }}"> Update Payment Method</button>
در مرحله بعد، کتابخانه Stripe.js ممکن است برای پیوست کردن یک عنصر Stripe به فرم و جمعآوری ایمن جزئیات پرداخت مشتری استفاده شود:
<script src="https://js.stripe.com/v3/"></script> <script> const stripe = Stripe('stripe-public-key'); const elements = stripe.elements(); const cardElement = elements.create('card'); cardElement.mount('#card-element');</script>
در مرحله بعد، کارت را می توان تأیید کرد و یک "شناسه روش پرداخت" ایمن را می توان با استفاده از
روش
Stripe
confirmCardSetup
از Stripe بازیابی کرد :
const cardHolderName = document.getElementById('card-holder-name');const cardButton = document.getElementById('card-button');const clientSecret = cardButton.dataset.secret; cardButton.addEventListener('click', async (e) => { const { setupIntent, error } = await stripe.confirmCardSetup( clientSecret, { payment_method: { card: cardElement, billing_details: { name: cardHolderName.value } } } ); if (error) { // Display "error.message" to the user... } else { // The card has been verified successfully... }});
پس از تأیید کارت توسط Stripe، می توانید
setupIntent.payment_method
شناسه حاصل را به برنامه Laravel خود منتقل کنید، جایی که می توان آن را به مشتری متصل کرد. روش پرداخت را می توان
به عنوان یک روش پرداخت جدید اضافه کرد
یا
برای به روز رسانی روش پرداخت پیش فرض استفاده کرد
. همچنین میتوانید بلافاصله از شناسه روش پرداخت برای
ایجاد اشتراک جدید
استفاده کنید .
اگر میخواهید اطلاعات بیشتری درباره اهداف راهاندازی و جمعآوری جزئیات پرداخت مشتری داشته باشید، لطفاً این نمای کلی ارائهشده توسط Stripe را مرور کنید .
روش های پرداخت هزینه های تکی
البته، زمانی که هزینهای را از روش پرداخت مشتری دریافت میکنیم، فقط یک بار باید از شناسه روش پرداخت استفاده کنیم. به دلیل محدودیتهای Stripe، نمیتوانید از روش پرداخت پیشفرض ذخیرهشده مشتری برای هزینههای تکی استفاده کنید. باید به مشتری اجازه دهید جزئیات روش پرداخت خود را با استفاده از کتابخانه Stripe.js وارد کند. به عنوان مثال، فرم زیر را در نظر بگیرید:
<input id="card-holder-name" type="text"> <!-- Stripe Elements Placeholder --><div id="card-element"></div> <button id="card-button"> Process Payment</button>
پس از تعریف چنین فرمی، کتابخانه Stripe.js ممکن است برای پیوست کردن یک عنصر Stripe به فرم و جمع آوری ایمن جزئیات پرداخت مشتری استفاده شود:
<script src="https://js.stripe.com/v3/"></script> <script> const stripe = Stripe('stripe-public-key'); const elements = stripe.elements(); const cardElement = elements.create('card'); cardElement.mount('#card-element');</script>
در مرحله بعد، کارت را می توان تأیید کرد و یک "شناسه روش پرداخت" ایمن را می توان با استفاده از
روش
Stripe
createPaymentMethod
از Stripe بازیابی کرد :
const cardHolderName = document.getElementById('card-holder-name');const cardButton = document.getElementById('card-button'); cardButton.addEventListener('click', async (e) => { const { paymentMethod, error } = await stripe.createPaymentMethod( 'card', cardElement, { billing_details: { name: cardHolderName.value } } ); if (error) { // Display "error.message" to the user... } else { // The card has been verified successfully... }});
اگر کارت با موفقیت تأیید شود، میتوانید آن را
paymentMethod.id
به برنامه لاراول خود منتقل کنید و یک
بار شارژ را
پردازش کنید .
بازیابی روش های پرداخت
روش
paymentMethods
موجود در نمونه مدل قابل صورتحساب مجموعهای از
Laravel\Cashier\PaymentMethod
نمونهها را برمیگرداند:
$paymentMethods = $user->paymentMethods();
به طور پیشفرض، این روش روشهای پرداخت را از هر نوع برمیگرداند. برای بازیابی روش های پرداخت از یک نوع خاص، می توانید
type
آرگومان را به روش ارسال کنید:
$paymentMethods = $user->paymentMethods('sepa_debit');
برای بازیابی روش پرداخت پیشفرض مشتری،
defaultPaymentMethod
ممکن است از روش زیر استفاده شود:
$paymentMethod = $user->defaultPaymentMethod();
میتوانید روش پرداخت خاصی را که به مدل قابل صورتحساب پیوست شده است، با استفاده از این
findPaymentMethod
روش بازیابی کنید:
$paymentMethod = $user->findPaymentMethod($paymentMethodId);
وجود روش پرداخت
برای تعیین اینکه آیا یک مدل قابل صورتحساب یک روش پرداخت پیشفرض به حساب خود دارد یا خیر،
hasDefaultPaymentMethod
روش را فراخوانی کنید:
if ($user->hasDefaultPaymentMethod()) { // ...}
میتوانید از این
hasPaymentMethod
روش برای تعیین اینکه آیا یک مدل قابل صورتحساب حداقل یک روش پرداخت به حسابش متصل است یا خیر، استفاده کنید:
if ($user->hasPaymentMethod()) { // ...}
این روش تعیین می کند که آیا مدل قابل صورتحساب اصلاً روش پرداختی دارد یا خیر. برای تعیین اینکه آیا یک روش پرداخت از یک نوع خاص برای مدل وجود دارد یا خیر، میتوانید
type
آرگومان را به روش ارسال کنید:
if ($user->hasPaymentMethod('sepa_debit')) { // ...}
به روز رسانی روش پرداخت پیش فرض
این
updateDefaultPaymentMethod
روش ممکن است برای بهروزرسانی اطلاعات روش پرداخت پیشفرض مشتری استفاده شود. این روش یک شناسه روش پرداخت Stripe را میپذیرد و روش پرداخت جدید را به عنوان روش پرداخت صورتحساب پیشفرض اختصاص میدهد:
$user->updateDefaultPaymentMethod($paymentMethod);
برای همگامسازی اطلاعات روش پرداخت پیشفرض خود با اطلاعات روش پرداخت پیشفرض مشتری در Stripe، میتوانید از این
updateDefaultPaymentMethodFromStripe
روش استفاده کنید:
$user->updateDefaultPaymentMethodFromStripe();
روش پرداخت پیشفرض برای مشتری فقط برای صدور صورتحساب و ایجاد اشتراکهای جدید قابل استفاده است. به دلیل محدودیت های اعمال شده توسط Stripe، ممکن است برای شارژ تک استفاده نشود.
اضافه کردن روش های پرداخت
برای افزودن روش پرداخت جدید، میتوانید
addPaymentMethod
با عبور از شناسه روش پرداخت، روش موجود در مدل قابل صورتحساب را فراخوانی کنید:
$user->addPaymentMethod($paymentMethod);
برای یادگیری نحوه بازیابی شناسههای روش پرداخت، لطفاً اسناد ذخیرهسازی روش پرداخت را مرور کنید .
حذف روش های پرداخت
برای حذف یک روش پرداخت، میتوانید
delete
روشی را که
Laravel\Cashier\PaymentMethod
میخواهید حذف کنید تماس بگیرید:
$paymentMethod->delete();
این
deletePaymentMethod
روش یک روش پرداخت خاص را از مدل قابل صورتحساب حذف میکند:
$user->deletePaymentMethod('pm_visa');
این
deletePaymentMethods
روش همه اطلاعات روش پرداخت را برای مدل قابل صورتحساب حذف میکند:
$user->deletePaymentMethods();
به طور پیش فرض، این روش هر نوع روش پرداخت را حذف می کند. برای حذف روشهای پرداخت از یک نوع خاص، میتوانید
type
آرگومان را به روش ارسال کنید:
$user->deletePaymentMethods('sepa_debit');
اگر کاربر اشتراک فعالی دارد، برنامه شما نباید به او اجازه دهد روش پرداخت پیشفرض خود را حذف کند.
اشتراک ها
اشتراک ها راهی برای تنظیم پرداخت های مکرر برای مشتریان شما فراهم می کند. اشتراکهای Stripe که توسط Cashier مدیریت میشوند، از قیمتهای اشتراک چندگانه، مقادیر اشتراک، آزمایشها و موارد دیگر پشتیبانی میکنند.
ایجاد اشتراک
برای ایجاد اشتراک، ابتدا نمونه ای از مدل قابل پرداخت خود را بازیابی کنید که معمولاً نمونه ای از
App\Models\User
. هنگامی که نمونه مدل را بازیابی کردید، می توانید از
newSubscription
روش برای ایجاد اشتراک مدل استفاده کنید:
use Illuminate\Http\Request; Route::post('/user/subscribe', function (Request $request) { $request->user()->newSubscription( 'default', 'price_monthly' )->create($request->paymentMethodId); // ...});
اولین آرگومان ارسال شده به
newSubscription
روش باید نوع داخلی اشتراک باشد. اگر برنامه شما فقط یک اشتراک ارائه می دهد، می توانید با این
default
یا تماس بگیرید
primary
. این نوع اشتراک فقط برای استفاده داخلی برنامه است و قرار نیست به کاربران نشان داده شود. علاوه بر این، نباید دارای فاصله باشد و هرگز نباید پس از ایجاد اشتراک تغییر کند. آرگومان دوم، قیمت خاصی است که کاربر در آن مشترک است. این مقدار باید با شناسه قیمت در Stripe مطابقت داشته باشد.
این
create
روش که
شناسه روش پرداخت Stripe
یا
PaymentMethod
شی Stripe را می پذیرد، اشتراک را آغاز می کند و همچنین پایگاه داده شما را با شناسه مشتری Stripe مدل قابل پرداخت و سایر اطلاعات صورتحساب مرتبط به روز می کند.
ارسال شناسه روش پرداخت به طور مستقیم به
create
روش اشتراک نیز به طور خودکار آن را به روش های پرداخت ذخیره شده کاربر اضافه می کند.
جمع آوری پرداخت های مکرر از طریق ایمیل فاکتور
بهجای جمعآوری خودکار پرداختهای مکرر مشتری، میتوانید به Stripe دستور دهید هر بار که پرداخت مکرر مشتری سررسید میشود، یک فاکتور برای مشتری ایمیل کند. سپس، مشتری ممکن است پس از دریافت فاکتور، آن را به صورت دستی پرداخت کند. مشتری هنگام جمع آوری پرداخت های مکرر از طریق فاکتورها نیازی به ارائه روش پرداخت از قبل ندارد:
$user->newSubscription('default', 'price_monthly')->createAndSendInvoice();
مدت زمانی که مشتری باید صورتحساب خود را قبل از لغو اشتراک خود بپردازد توسط این
days_until_due
گزینه تعیین می شود. به طور پیش فرض، این 30 روز است. با این حال، در صورت تمایل می توانید مقدار خاصی برای این گزینه ارائه دهید:
$user->newSubscription('default', 'price_monthly')->createAndSendInvoice([], [ 'days_until_due' => 30]);
مقادیر
اگر میخواهید هنگام ایجاد اشتراک،
مقدار
خاصی را برای قیمت تعیین کنید، باید
quantity
قبل از ایجاد اشتراک، روش را در سازنده اشتراک فراخوانی کنید:
$user->newSubscription('default', 'price_monthly') ->quantity(5) ->create($paymentMethod);
توضیحات بیشتر
اگر میخواهید گزینههای مشتری
یا
اشتراک دیگری
را که توسط Stripe پشتیبانی میشوند مشخص کنید
، میتوانید این کار را با ارسال آنها به عنوان آرگومانهای دوم و سوم به
create
روش انجام دهید:
$user->newSubscription('default', 'price_monthly')->create($paymentMethod, [ 'email' => $email,], [ 'metadata' => ['note' => 'Some extra information.'],]);
کوپن
اگر می خواهید هنگام ایجاد اشتراک کوپن اعمال کنید، می توانید از
withCoupon
روش زیر استفاده کنید:
$user->newSubscription('default', 'price_monthly') ->withCoupon('code') ->create($paymentMethod);
یا اگر میخواهید
کد تبلیغاتی Stripe را
اعمال کنید ، میتوانید از
withPromotionCode
روش زیر استفاده کنید:
$user->newSubscription('default', 'price_monthly') ->withPromotionCode('promo_code_id') ->create($paymentMethod);
شناسه کد تبلیغاتی داده شده باید شناسه Stripe API اختصاص داده شده به کد تبلیغاتی باشد و نه مشتری که با کد تبلیغاتی روبروست. اگر نیاز به یافتن شناسه کد تبلیغاتی بر اساس کد تبلیغاتی خاص مشتری دارید، میتوانید از
findPromotionCode
روش زیر استفاده کنید:
// Find a promotion code ID by its customer facing code...$promotionCode = $user->findPromotionCode('SUMMERSALE'); // Find an active promotion code ID by its customer facing code...$promotionCode = $user->findActivePromotionCode('SUMMERSALE');
در مثال بالا،
$promotionCode
شیء برگشتی یک نمونه از
Laravel\Cashier\PromotionCode
. این کلاس یک
Stripe\PromotionCode
شی زیرین را تزئین می کند. می توانید کوپن مربوط به کد تبلیغاتی را با فراخوانی
coupon
روش بازیابی کنید:
$coupon = $user->findPromotionCode('SUMMERSALE')->coupon();
نمونه کوپن به شما امکان می دهد میزان تخفیف را تعیین کنید و اینکه آیا کوپن نشان دهنده یک تخفیف ثابت است یا بر اساس درصد:
if ($coupon->isPercentage()) { return $coupon->percentOff().'%'; // 21.5%} else { return $coupon->amountOff(); // $5.99}
همچنین میتوانید تخفیفهایی را که در حال حاضر برای یک مشتری یا اشتراک اعمال میشود، بازیابی کنید:
$discount = $billable->discount(); $discount = $subscription->discount();
نمونه های برگشتی
Laravel\Cashier\Discount
یک نمونه شی زیرین را تزئین می کنند
Stripe\Discount
. می توانید کوپن مربوط به این تخفیف را با استفاده از
coupon
روش زیر بازیابی کنید:
$coupon = $subscription->discount()->coupon();
اگر میخواهید یک کوپن یا کد تبلیغاتی جدید برای مشتری یا اشتراک اعمال کنید، میتوانید این کار را از طریق
applyCoupon
یا
applyPromotionCode
روشهای زیر انجام دهید:
$billable->applyCoupon('coupon_id');$billable->applyPromotionCode('promotion_code_id'); $subscription->applyCoupon('coupon_id');$subscription->applyPromotionCode('promotion_code_id');
به یاد داشته باشید، شما باید از Stripe API ID اختصاص داده شده به کد تبلیغاتی استفاده کنید نه مشتری که با کد تبلیغاتی روبروست. فقط یک کوپن یا کد تبلیغاتی را می توان در یک زمان معین برای مشتری یا اشتراک اعمال کرد.
برای اطلاعات بیشتر در مورد این موضوع، لطفاً به مستندات Stripe در مورد کوپن ها و کدهای تبلیغاتی مراجعه کنید .
اضافه کردن اشتراک ها
اگر میخواهید اشتراکی را به مشتری اضافه کنید که از قبل یک روش پرداخت پیشفرض دارد، میتوانید از این
add
روش در سازنده اشتراک استفاده کنید:
use App\Models\User; $user = User::find(1); $user->newSubscription('default', 'price_monthly')->add();
ایجاد اشتراک از داشبورد Stripe
همچنین می توانید از خود داشبورد Stripe اشتراک ایجاد کنید. هنگام انجام این کار، Cashier اشتراکهای تازه اضافه شده را همگامسازی میکند و به آنها یک نوع اختصاص میدهد
default
. برای سفارشی کردن نوع اشتراکی که به اشتراکهای ایجاد شده داشبورد اختصاص داده میشود،
کنترلکنندههای رویداد webhook را تعریف کنید
.
علاوه بر این، میتوانید فقط یک نوع اشتراک را از طریق داشبورد Stripe ایجاد کنید. اگر برنامه شما چندین اشتراک را ارائه می دهد که از انواع مختلف استفاده می کنند، ممکن است فقط یک نوع اشتراک از طریق داشبورد Stripe اضافه شود.
در نهایت، همیشه باید مطمئن شوید که به ازای هر نوع اشتراکی که توسط برنامه شما ارائه میشود، فقط یک اشتراک فعال اضافه کنید. اگر مشتری دو
default
اشتراک داشته باشد، فقط آخرین اشتراک اضافه شده توسط Cashier استفاده می شود، حتی اگر هر دو با پایگاه داده برنامه شما همگام شوند.
بررسی وضعیت اشتراک
هنگامی که مشتری در برنامه شما مشترک شد، می توانید به راحتی وضعیت اشتراک او را با استفاده از روش های مختلف مناسب بررسی کنید. ابتدا،
اگر مشتری اشتراک فعال داشته باشد،
subscribed
روش برمی گردد ، حتی اگر اشتراک در حال حاضر در دوره آزمایشی خود باشد.
true
متد
subscribed
نوع اشتراک را به عنوان اولین آرگومان خود می پذیرد:
if ($user->subscribed('default')) { // ...}
این
subscribed
روش همچنین یک کاندیدای عالی برای
میانافزار مسیر
است که به شما امکان میدهد دسترسی به مسیرها و کنترلکنندهها را بر اساس وضعیت اشتراک کاربر فیلتر کنید:
<?php namespace App\Http\Middleware; use Closure;use Illuminate\Http\Request;use Symfony\Component\HttpFoundation\Response; class EnsureUserIsSubscribed{ /** * Handle an incoming request. * * @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next */ public function handle(Request $request, Closure $next): Response { if ($request->user() && ! $request->user()->subscribed('default')) { // This user is not a paying customer... return redirect('billing'); } return $next($request); }}
اگر می خواهید تعیین کنید که آیا کاربر هنوز در دوره آزمایشی خود است، می توانید از این
onTrial
روش استفاده کنید. این روش می تواند برای تعیین اینکه آیا باید هشداری را به کاربر نشان دهید که هنوز در دوره آزمایشی خود است مفید باشد:
if ($user->subscription('default')->onTrial()) { // ...}
این
subscribedToProduct
روش ممکن است برای تعیین اینکه آیا کاربر در یک محصول معین بر اساس شناسه محصول Stripe مشترک شده است یا خیر، استفاده شود. در استرایپ، محصولات مجموعه ای از قیمت ها هستند. در این مثال، تعیین خواهیم کرد که آیا اشتراک کاربر
default
به طور فعال در محصول "حق بیمه" برنامه مشترک است یا خیر. شناسه محصول Stripe داده شده باید با یکی از شناسه های محصول شما در داشبورد Stripe مطابقت داشته باشد:
if ($user->subscribedToProduct('prod_premium', 'default')) { // ...}
با ارسال یک آرایه به
subscribedToProduct
روش، می توانید تعیین کنید که آیا اشتراک کاربر
default
به طور فعال در محصول "پایه" یا "حق بیمه" برنامه مشترک است یا خیر:
if ($user->subscribedToProduct(['prod_basic', 'prod_premium'], 'default')) { // ...}
این
subscribedToPrice
روش ممکن است برای تعیین اینکه آیا اشتراک مشتری با یک شناسه قیمت معین مطابقت دارد یا خیر استفاده شود:
if ($user->subscribedToPrice('price_basic_monthly', 'default')) { // ...}
این
recurring
روش ممکن است برای تعیین اینکه آیا کاربر در حال حاضر مشترک است و دیگر در دوره آزمایشی خود نیست استفاده می شود:
if ($user->subscription('default')->recurring()) { // ...}
اگر کاربر دو اشتراک با یک نوع داشته باشد، آخرین اشتراک همیشه با
subscription
روش برگردانده می شود. به عنوان مثال، یک کاربر ممکن است دو رکورد اشتراک با نوعdefault
; با این حال، یکی از اشتراک ها ممکن است یک اشتراک قدیمی و منقضی شده باشد، در حالی که دیگری اشتراک فعلی و فعال باشد. آخرین اشتراک همیشه برگردانده می شود در حالی که اشتراک های قدیمی برای بررسی تاریخی در پایگاه داده نگهداری می شوند.
وضعیت اشتراک لغو شده
برای تعیین اینکه آیا کاربر زمانی مشترک فعال بوده است اما اشتراک خود را لغو کرده است، می توانید از
canceled
روش زیر استفاده کنید:
if ($user->subscription('default')->canceled()) { // ...}
همچنین میتوانید تعیین کنید که آیا کاربر اشتراک خود را لغو کرده است، اما هنوز در «دوره مهلت» خود است تا زمانی که اشتراک به طور کامل منقضی شود. به عنوان مثال، اگر کاربر اشتراکی را در تاریخ 5 مارس لغو کند که در ابتدا قرار بود در 10 مارس منقضی شود، کاربر تا 10 مارس در "مهلت مهلت" خود است. توجه داشته باشید که
subscribed
روش همچنان
true
در این مدت باز می گردد:
if ($user->subscription('default')->onGracePeriod()) { // ...}
برای تعیین اینکه آیا کاربر اشتراک خود را لغو کرده است و دیگر در "دوره مهلت" خود نیست، می توانید از
ended
روش زیر استفاده کنید:
if ($user->subscription('default')->ended()) { // ...}
وضعیت ناقص و سررسید گذشته
اگر یک اشتراک پس از ایجاد به یک اقدام پرداخت ثانویه نیاز داشته باشد، اشتراک به عنوان علامت گذاری می شود
incomplete
. وضعیت اشتراک در
stripe_status
ستون جدول پایگاه داده صندوقدار ذخیره می شود
subscriptions
.
به طور مشابه، اگر در هنگام تعویض قیمت ها به یک اقدام پرداخت ثانویه نیاز باشد، اشتراک به عنوان علامت گذاری می شود
past_due
. هنگامی که اشتراک شما در هر یک از این حالت ها باشد، تا زمانی که مشتری پرداخت خود را تایید نکند، فعال نخواهد بود. تعیین اینکه آیا یک اشتراک دارای پرداخت ناقص است یا خیر، ممکن است با استفاده از
hasIncompletePayment
روش موجود در مدل قابل صورتحساب یا یک نمونه اشتراک انجام شود:
if ($user->hasIncompletePayment('default')) { // ...} if ($user->subscription('default')->hasIncompletePayment()) { // ...}
هنگامی که یک اشتراک پرداخت ناقص دارد، باید کاربر را به صفحه تأیید پرداخت صندوقدار هدایت کنید و
latestPayment
شناسه را ارسال کنید. می توانید از
latestPayment
روش موجود در نمونه اشتراک برای بازیابی این شناسه استفاده کنید:
<a href="{{ route('cashier.payment', $subscription->latestPayment()->id) }}"> Please confirm your payment.</a>
اگر میخواهید اشتراک زمانی که در یک
past_due
یا
incomplete
ایالت است همچنان فعال تلقی شود، میتوانید از روشهای ارائه شده توسط Cashier استفاده
keepPastDueSubscriptionsActive
کنید
keepIncompleteSubscriptionsActive
. به طور معمول، این متدها باید در
register
متد شما
فراخوانی شوند
App\Providers\AppServiceProvider
:
use Laravel\Cashier\Cashier; /** * Register any application services. */public function register(): void{ Cashier::keepPastDueSubscriptionsActive(); Cashier::keepIncompleteSubscriptionsActive();}
هنگامی که یک اشتراک در
incomplete
وضعیتی است، تا زمانی که پرداخت تأیید نشده است، نمی توان آن را تغییر داد. بنابراین، متدهایswap
وupdateQuantity
زمانی که اشتراک در یک وضعیت باشد، استثنا ایجاد میکندincomplete
.
محدوده های اشتراک
اکثر حالت های اشتراک نیز به عنوان محدوده پرس و جو در دسترس هستند، به طوری که می توانید به راحتی پایگاه داده خود را برای اشتراک هایی که در یک وضعیت خاص هستند پرس و جو کنید:
// Get all active subscriptions...$subscriptions = Subscription::query()->active()->get(); // Get all of the canceled subscriptions for a user...$subscriptions = $user->subscriptions()->canceled()->get();
لیست کاملی از دامنه های موجود در زیر موجود است:
Subscription::query()->active();Subscription::query()->canceled();Subscription::query()->ended();Subscription::query()->incomplete();Subscription::query()->notCanceled();Subscription::query()->notOnGracePeriod();Subscription::query()->notOnTrial();Subscription::query()->onGracePeriod();Subscription::query()->onTrial();Subscription::query()->pastDue();Subscription::query()->recurring();
تغییر قیمت ها
پس از اینکه مشتری در برنامه شما مشترک شد، ممکن است گهگاه بخواهد قیمت اشتراک جدیدی را تغییر دهد. برای تعویض مشتری با قیمت جدید، شناسه Stripe price را به
swap
روش ارسال کنید. هنگام مبادله قیمت ها، فرض بر این است که کاربر می خواهد اشتراک خود را در صورتی که قبلا لغو شده بود، دوباره فعال کند. شناسه قیمت داده شده باید با یک شناسه قیمت Stripe موجود در داشبورد Stripe مطابقت داشته باشد:
use App\Models\User; $user = App\Models\User::find(1); $user->subscription('default')->swap('price_yearly');
اگر مشتری در حال آزمایش باشد، دوره آزمایشی حفظ خواهد شد. علاوه بر این، اگر یک "مقدار" برای اشتراک وجود داشته باشد، آن مقدار نیز حفظ خواهد شد.
اگر میخواهید قیمتها را مبادله کنید و هر دوره آزمایشی را که مشتری در حال حاضر در آن است لغو کنید، میتوانید از
skipTrial
روش زیر استفاده کنید:
$user->subscription('default') ->skipTrial() ->swap('price_yearly');
اگر میخواهید به جای منتظر ماندن برای چرخه صورتحساب بعدی مشتری، قیمتها را مبادله کنید و فوراً فاکتور بگیرید، میتوانید از
swapAndInvoice
روش زیر استفاده کنید:
$user = User::find(1); $user->subscription('default')->swapAndInvoice('price_yearly');
تناسب
بهطور پیشفرض، Stripe هزینهها را هنگام مبادله بین قیمتها نسبت میدهد. این
noProrate
روش ممکن است برای بهروزرسانی قیمت اشتراک بدون نسبت هزینهها استفاده شود:
$user->subscription('default')->noProrate()->swap('price_yearly');
برای اطلاعات بیشتر در مورد میزان اشتراک، به مستندات Stripe مراجعه کنید .
اجرای
noProrate
متد قبل ازswapAndInvoice
متد تاثیری در proration نخواهد داشت. همیشه فاکتور صادر می شود.
مقدار اشتراک
گاهی اوقات اشتراک ها تحت تأثیر "کمیت" قرار می گیرند. به عنوان مثال، یک برنامه مدیریت پروژه ممکن است 10 دلار در ماه برای هر پروژه هزینه کند. میتوانید از روشها
incrementQuantity
و
decrementQuantity
روشها برای افزایش یا کاهش آسان تعداد اشتراک خود استفاده کنید:
use App\Models\User; $user = User::find(1); $user->subscription('default')->incrementQuantity(); // Add five to the subscription's current quantity...$user->subscription('default')->incrementQuantity(5); $user->subscription('default')->decrementQuantity(); // Subtract five from the subscription's current quantity...$user->subscription('default')->decrementQuantity(5);
از طرف دیگر، میتوانید مقدار خاصی را با استفاده از
updateQuantity
روش زیر تنظیم کنید:
$user->subscription('default')->updateQuantity(10);
این
noProrate
روش ممکن است برای به روز رسانی مقدار اشتراک بدون نسبت هزینه ها استفاده شود:
$user->subscription('default')->noProrate()->updateQuantity(10);
برای اطلاعات بیشتر در مورد مقدار اشتراک، به مستندات Stripe مراجعه کنید .
مقادیر برای اشتراک با چندین محصول
اگر اشتراک شما اشتراکی با چندین محصول است ، باید شناسه قیمتی را که میخواهید مقدار آن را افزایش یا کاهش دهید، به عنوان آرگومان دوم برای روشهای افزایش/کاهش ارسال کنید:
$user->subscription('default')->incrementQuantity(1, 'price_chat');
اشتراک با چندین محصول
اشتراک با چندین محصول
به شما امکان می دهد چندین محصول صورتحساب را به یک اشتراک اختصاص دهید. به عنوان مثال، تصور کنید که در حال ساختن یک برنامه «خدمات راهنمایی» برای خدمات مشتری هستید که قیمت اشتراک پایه آن 10 دلار در ماه است اما یک محصول افزودنی چت زنده را با 15 دلار اضافی در ماه ارائه می دهد. اطلاعات مربوط به اشتراک با چندین محصول در جدول پایگاه داده صندوقدار ذخیره می شود
subscription_items
.
شما می توانید چندین محصول را برای یک اشتراک مشخص با ارسال آرایه ای از قیمت ها به عنوان آرگومان دوم به
newSubscription
روش مشخص کنید:
use Illuminate\Http\Request; Route::post('/user/subscribe', function (Request $request) { $request->user()->newSubscription('default', [ 'price_monthly', 'price_chat', ])->create($request->paymentMethodId); // ...});
در مثال بالا، مشتری دو قیمت به
default
اشتراک خود خواهد داشت. هر دو قیمت در فواصل صورتحساب مربوطه محاسبه می شوند. در صورت لزوم، می توانید از
quantity
روش برای نشان دادن مقدار خاصی برای هر قیمت استفاده کنید:
$user = User::find(1); $user->newSubscription('default', ['price_monthly', 'price_chat']) ->quantity(5, 'price_chat') ->create($paymentMethod);
اگر میخواهید قیمت دیگری به اشتراک موجود اضافه کنید، میتوانید از
addPrice
روش اشتراک استفاده کنید:
$user = User::find(1); $user->subscription('default')->addPrice('price_chat');
مثال بالا قیمت جدید را اضافه می کند و مشتری برای آن در چرخه صورتحساب بعدی خود صورتحساب دریافت می کند. اگر می خواهید بلافاصله صورتحساب مشتری را دریافت کنید، می توانید از
addPriceAndInvoice
روش زیر استفاده کنید:
$user->subscription('default')->addPriceAndInvoice('price_chat');
اگر میخواهید قیمتی را با یک مقدار مشخص اضافه کنید، میتوانید مقدار را به عنوان آرگومان دوم متدهای
addPrice
یا ارسال کنید
addPriceAndInvoice
:
$user = User::find(1); $user->subscription('default')->addPrice('price_chat', 5);
می توانید با استفاده از
removePrice
روش زیر قیمت ها را از اشتراک ها حذف کنید:
$user->subscription('default')->removePrice('price_chat');
نمی توانید آخرین قیمت اشتراک را حذف کنید. در عوض، شما باید به سادگی اشتراک را لغو کنید.
معاوضه قیمت ها
همچنین میتوانید قیمتهای پیوست شده به اشتراکی را با چندین محصول تغییر دهید. به عنوان مثال، تصور کنید یک مشتری
price_basic
با یک
price_chat
محصول افزودنی اشتراک دارد و شما می خواهید مشتری را از قیمت
price_basic
به قیمت ارتقا دهید
price_pro
:
use App\Models\User; $user = User::find(1); $user->subscription('default')->swap(['price_pro', 'price_chat']);
هنگام اجرای مثال بالا، آیتم اشتراک زیرین با علامت
price_basic
حذف می شود و موردی که دارای the
price_chat
است حفظ می شود. علاوه بر این، یک آیتم اشتراک جدید برای آن
price_pro
ایجاد می شود.
همچنین میتوانید با ارسال آرایهای از جفتهای کلید/مقدار به
swap
روش، گزینههای آیتم اشتراک را مشخص کنید. برای مثال، ممکن است لازم باشد مقادیر قیمت اشتراک را مشخص کنید:
$user = User::find(1); $user->subscription('default')->swap([ 'price_pro' => ['quantity' => 5], 'price_chat']);
اگر میخواهید یک قیمت واحد را با اشتراک عوض کنید، میتوانید این کار را با استفاده از
swap
روش موجود در خود مورد اشتراک انجام دهید. این رویکرد به ویژه در صورتی مفید است که میخواهید تمام ابردادههای موجود را در قیمتهای دیگر اشتراک حفظ کنید:
$user = User::find(1); $user->subscription('default') ->findItemOrFail('price_basic') ->swap('price_pro');
تناسب
بهطور پیشفرض، Stripe هنگام افزودن یا حذف قیمتها از اشتراکی با چندین محصول، هزینهها را به نسبت هزینهها محاسبه میکند. اگر میخواهید یک تعدیل قیمت را بدون تناسب انجام دهید، باید این
noProrate
روش را به عملیات قیمت خود زنجیره بزنید:
$user->subscription('default')->noProrate()->removePrice('price_chat');
مقادیر
اگر میخواهید مقادیر را در قیمتهای اشتراک فردی بهروزرسانی کنید، میتوانید این کار را با استفاده از روشهای کمیت موجود با ارسال شناسه قیمت به عنوان یک آرگومان اضافی برای روش انجام دهید:
$user = User::find(1); $user->subscription('default')->incrementQuantity(5, 'price_chat'); $user->subscription('default')->decrementQuantity(3, 'price_chat'); $user->subscription('default')->updateQuantity(10, 'price_chat');
هنگامی که یک اشتراک چند قیمت داشته باشد، ویژگی ها
stripe_price
وquantity
ویژگی های مدلSubscription
خواهد بودnull
. برای دسترسی به ویژگیهای قیمت جداگانه، باید ازitems
رابطه موجود درSubscription
مدل استفاده کنید.
اقلام اشتراک
هنگامی که یک اشتراک چندین قیمت دارد، چندین "اقلام" اشتراک در جدول پایگاه داده شما ذخیره می شود
subscription_items
. می توانید از طریق
items
رابطه موجود در اشتراک به این موارد دسترسی داشته باشید:
use App\Models\User; $user = User::find(1); $subscriptionItem = $user->subscription('default')->items->first(); // Retrieve the Stripe price and quantity for a specific item...$stripePrice = $subscriptionItem->stripe_price;$quantity = $subscriptionItem->quantity;
همچنین می توانید با استفاده از
findItemOrFail
روش زیر قیمت خاصی را بازیابی کنید:
$user = User::find(1); $subscriptionItem = $user->subscription('default')->findItemOrFail('price_chat');
اشتراک های متعدد
Stripe به مشتریان شما اجازه می دهد تا چندین اشتراک را به طور همزمان داشته باشند. به عنوان مثال، شما ممکن است باشگاهی را اداره کنید که اشتراک شنا و وزنه برداری را ارائه می دهد و هر اشتراک ممکن است قیمت متفاوتی داشته باشد. البته، مشتریان باید بتوانند در یکی یا هر دو طرح مشترک شوند.
هنگامی که برنامه شما اشتراک ایجاد می کند، می توانید نوع اشتراک را در
newSubscription
روش ارائه دهید. نوع ممکن است هر رشته ای باشد که نشان دهنده نوع اشتراکی است که کاربر شروع می کند:
use Illuminate\Http\Request; Route::post('/swimming/subscribe', function (Request $request) { $request->user()->newSubscription('swimming') ->price('price_swimming_monthly') ->create($request->paymentMethodId); // ...});
در این مثال، ما اشتراک ماهیانه شنا را برای مشتری آغاز کردیم. با این حال، آنها ممکن است بخواهند در زمان دیگری به اشتراک سالانه مبادله کنند. هنگام تنظیم اشتراک مشتری، می توانیم به سادگی قیمت
swimming
اشتراک را تعویض کنیم:
$user->subscription('swimming')->swap('price_swimming_yearly');
البته، شما همچنین می توانید اشتراک را به طور کامل لغو کنید:
$user->subscription('swimming')->cancel();
صورتحساب اندازه گیری شده
صورتحساب اندازهگیری شده به شما این امکان را میدهد که از مشتریان بر اساس استفاده از محصولشان در طول یک چرخه صورتحساب، هزینه دریافت کنید. به عنوان مثال، ممکن است از مشتریان بر اساس تعداد پیامهای متنی یا ایمیلهایی که در ماه ارسال میکنند، هزینه دریافت کنید.
برای شروع استفاده از صورتحساب اندازهگیری شده، ابتدا باید یک محصول جدید در داشبورد Stripe خود با قیمت اندازهگیری شده ایجاد کنید. سپس،
meteredPrice
برای افزودن شناسه قیمت اندازهگیری شده به اشتراک مشتری از علامت استفاده کنید:
use Illuminate\Http\Request; Route::post('/user/subscribe', function (Request $request) { $request->user()->newSubscription('default') ->meteredPrice('price_metered') ->create($request->paymentMethodId); // ...});
همچنین میتوانید از طریق Stripe Checkout یک اشتراک اندازهگیری شده شروع کنید :
$checkout = Auth::user() ->newSubscription('default', []) ->meteredPrice('price_metered') ->checkout(); return view('your-checkout-view', [ 'checkout' => $checkout,]);
گزارش استفاده
همانطور که مشتری شما از برنامه شما استفاده می کند، استفاده از آنها را به Stripe گزارش می دهید تا به طور دقیق صورتحساب آنها دریافت شود. برای افزایش استفاده از اشتراک اندازهگیری شده، میتوانید از
reportUsage
روش زیر استفاده کنید:
$user = User::find(1); $user->subscription('default')->reportUsage();
به طور پیش فرض، یک "مقدار استفاده" 1 به دوره صورتحساب اضافه می شود. از طرف دیگر، میتوانید مقدار خاصی از «استفاده» را برای افزودن به میزان استفاده مشتری برای دوره صورتحساب ارسال کنید:
$user = User::find(1); $user->subscription('default')->reportUsage(15);
اگر برنامه شما چندین قیمت را در یک اشتراک ارائه می دهد، باید از روشی
reportUsageFor
برای تعیین قیمت اندازه گیری شده ای که می خواهید استفاده را برای آن گزارش دهید استفاده کنید:
$user = User::find(1); $user->subscription('default')->reportUsageFor('price_metered', 15);
گاهی اوقات، ممکن است لازم باشد استفاده ای را که قبلاً گزارش کرده اید به روز کنید. برای انجام این کار، می توانید یک مهر زمانی یا یک
DateTimeInterface
نمونه را به عنوان پارامتر دوم به
reportUsage
. هنگام انجام این کار، Stripe استفاده ای را که در آن زمان گزارش شده بود به روز می کند. میتوانید به بهروزرسانی سوابق استفاده قبلی ادامه دهید زیرا تاریخ و زمان معین هنوز در دوره صورتحساب فعلی است:
$user = User::find(1); $user->subscription('default')->reportUsage(5, $timestamp);
بازیابی سوابق استفاده
برای بازیابی استفاده قبلی مشتری، می توانید از
usageRecords
روش نمونه اشتراک استفاده کنید:
$user = User::find(1); $usageRecords = $user->subscription('default')->usageRecords();
اگر برنامه شما چندین قیمت را برای یک اشتراک ارائه می دهد، می توانید از روشی
usageRecordsFor
برای تعیین قیمت اندازه گیری شده استفاده کنید که می خواهید سوابق استفاده را برای آن بازیابی کنید:
$user = User::find(1); $usageRecords = $user->subscription('default')->usageRecordsFor('price_metered');
و
متدها یک نمونه Collection حاوی یک آرایه انجمنی از سوابق استفاده را برمیگردانند
usageRecords
.
usageRecordsFor
برای نمایش کل مصرف مشتری، میتوانید روی این آرایه تکرار کنید:
@foreach ($usageRecords as $usageRecord) - Period Starting: {{ $usageRecord['period']['start'] }} - Period Ending: {{ $usageRecord['period']['end'] }} - Total Usage: {{ $usageRecord['total_usage'] }}@endforeach
برای مرجع کامل همه دادههای استفاده برگردانده شده و نحوه استفاده از صفحهبندی مبتنی بر مکاننما Stripe، لطفاً به اسناد رسمی Stripe API مراجعه کنید .
مالیات اشتراک
بهجای محاسبه دستی نرخهای مالیات، میتوانید بهطور خودکار مالیاتها را با استفاده از Stripe Tax محاسبه کنید
برای تعیین نرخ مالیاتی که کاربر برای اشتراک می پردازد، باید این
taxRates
روش را در مدل قابل پرداخت خود پیاده کنید و آرایه ای حاوی شناسه های نرخ مالیاتی Stripe را برگردانید. می توانید این نرخ های مالیاتی را در
داشبورد Stripe خود
تعریف کنید :
/** * The tax rates that should apply to the customer's subscriptions. * * @return array<int, string> */public function taxRates(): array{ return ['txr_id'];}
این
taxRates
روش به شما امکان می دهد نرخ مالیات را بر اساس مشتری به مشتری اعمال کنید، که ممکن است برای یک پایگاه کاربری که چندین کشور و نرخ مالیات را در بر می گیرد مفید باشد.
اگر اشتراکهایی با چندین محصول ارائه میدهید، میتوانید با اجرای روشی
priceTaxRates
در مدل قابل پرداخت خود، نرخهای مالیات متفاوتی را برای هر قیمت تعریف کنید:
/** * The tax rates that should apply to the customer's subscriptions. * * @return array<string, array<int, string>> */public function priceTaxRates(): array{ return [ 'price_monthly' => ['txr_id'], ];}
این
taxRates
روش فقط برای هزینه های اشتراک اعمال می شود. اگر از Cashier برای ایجاد هزینه های "یک بار" استفاده می کنید، باید نرخ مالیات را در آن زمان به صورت دستی مشخص کنید.
همگام سازی نرخ های مالیاتی
هنگام تغییر شناسههای نرخ مالیاتی کدگذاریشدهای که با این
taxRates
روش بازگردانده میشوند، تنظیمات مالیاتی روی هر اشتراک موجود برای کاربر یکسان باقی میماند. اگر میخواهید ارزش مالیات اشتراکهای موجود را با
taxRates
مقادیر جدید بهروزرسانی کنید، باید
syncTaxRates
روش موجود در نمونه اشتراک کاربر را فراخوانی کنید:
$user->subscription('default')->syncTaxRates();
این همچنین نرخ مالیات موردی را برای یک اشتراک با چندین محصول همگام میکند. اگر برنامه شما اشتراک هایی با چندین محصول ارائه می دهد، باید مطمئن شوید که مدل قابل پرداخت شما
priceTaxRates
روشی را
که در بالا توضیح داده شد
اجرا می کند .
معافیت مالیاتی
صندوقدار همچنین روش های , و را برای تعیین معافیت مالیاتی مشتری ارائه
isNotTaxExempt
می
isTaxExempt
دهد
reverseChargeApplies
. این روشها برای تعیین وضعیت معافیت مالیاتی مشتری، Stripe API را فراخوانی میکنند:
use App\Models\User; $user = User::find(1); $user->isTaxExempt();$user->isNotTaxExempt();$user->reverseChargeApplies();
این روش ها بر روی هر شی نیز موجود است
Laravel\Cashier\Invoice
. با این حال، هنگامی که روی یکInvoice
شیء فراخوانی می شود، متدها وضعیت معافیت را در زمان ایجاد فاکتور تعیین می کنند.
تاریخ لنگر اشتراک
بهطور پیشفرض، لنگر چرخه صورتحساب، تاریخی است که اشتراک ایجاد شده است یا، در صورت استفاده از دوره آزمایشی، تاریخی است که دوره آزمایشی به پایان میرسد. اگر میخواهید تاریخ لنگر صورتحساب را تغییر دهید، میتوانید از
anchorBillingCycleOn
روش زیر استفاده کنید:
use Illuminate\Http\Request; Route::post('/user/subscribe', function (Request $request) { $anchor = Carbon::parse('first day of next month'); $request->user()->newSubscription('default', 'price_monthly') ->anchorBillingCycleOn($anchor->startOfDay()) ->create($request->paymentMethodId); // ...});
برای اطلاعات بیشتر در مورد مدیریت چرخههای صورتحساب اشتراک، به مستندات چرخه صورتحساب Stripe مراجعه کنید
لغو اشتراک ها
برای لغو اشتراک، با
cancel
روش موجود در اشتراک کاربر تماس بگیرید:
$user->subscription('default')->cancel();
هنگامی که یک اشتراک لغو می شود، صندوقدار به طور خودکار
ends_at
ستون را در جدول پایگاه داده شما تنظیم می کند
subscriptions
. از این ستون برای دانستن زمان
subscribed
شروع بازگشت متد استفاده می شود
false
.
به عنوان مثال، اگر مشتری در تاریخ 1 مارس اشتراک خود را لغو کند، اما قرار نبود اشتراک تا 5 مارس پایان یابد، این روش
تا 5 مارس
subscribed
ادامه خواهد داشت .
true
این کار به این دلیل انجام می شود که کاربر معمولاً مجاز است تا پایان چرخه صورتحساب خود از یک برنامه استفاده کند.
onGracePeriod
با استفاده از این روش
میتوانید تعیین کنید که آیا کاربر اشتراک خود را لغو کرده است اما هنوز در «دوره مهلت» خود است :
if ($user->subscription('default')->onGracePeriod()) { // ...}
اگر می خواهید اشتراک را فوراً لغو کنید، با
cancelNow
روش موجود در اشتراک کاربر تماس بگیرید:
$user->subscription('default')->cancelNow();
اگر میخواهید اشتراک را فوراً لغو کنید و هرگونه استفاده اندازهگیریشده بدون صورتحساب باقیمانده یا موارد جدید/درانتظار صورتحساب فاکتور را فاکتور کنید، با
cancelNowAndInvoice
روش روی اشتراک کاربر تماس بگیرید:
$user->subscription('default')->cancelNowAndInvoice();
همچنین می توانید انتخاب کنید که اشتراک در یک لحظه خاص لغو شود:
$user->subscription('default')->cancelAt( now()->addDays(10));
در نهایت، همیشه باید قبل از حذف مدل کاربر مرتبط، اشتراک کاربر را لغو کنید:
$user->subscription('default')->cancelNow(); $user->delete();
از سرگیری اشتراک ها
اگر مشتری اشتراک خود را لغو کرده است و شما می خواهید آن را از سر بگیرید، می توانید از
resume
روش موجود در اشتراک استفاده کنید. مشتری برای ازسرگیری اشتراک باید همچنان در "دوره مهلت" خود باشد:
$user->subscription('default')->resume();
اگر مشتری یک اشتراک را لغو کند و سپس آن اشتراک را قبل از اتمام کامل اشتراک از سر بگیرد، بلافاصله صورتحساب مشتری دریافت نخواهد شد. در عوض، اشتراک آنها مجدداً فعال می شود و در چرخه صورتحساب اصلی صورتحساب دریافت می شود.
آزمایشات اشتراک
با روش پرداخت از قبل
اگر میخواهید در حین جمعآوری اطلاعات روش پرداخت، دورههای آزمایشی را به مشتریان خود ارائه دهید،
trialDays
هنگام ایجاد اشتراکهای خود باید از این روش استفاده کنید:
use Illuminate\Http\Request; Route::post('/user/subscribe', function (Request $request) { $request->user()->newSubscription('default', 'price_monthly') ->trialDays(10) ->create($request->paymentMethodId); // ...});
این روش تاریخ پایان دوره آزمایشی را در سابقه اشتراک در پایگاه داده تنظیم می کند و به Stripe دستور می دهد که تا بعد از این تاریخ شروع به صدور صورت حساب مشتری نکند. هنگام استفاده از
trialDays
روش، Cashier هر دوره آزمایشی پیشفرضی را که برای قیمت در Stripe پیکربندی شده است، بازنویسی میکند.
اگر اشتراک مشتری قبل از تاریخ پایان دوره آزمایشی لغو نشود، به محض انقضای دوره آزمایشی هزینه از آنها کسر می شود، بنابراین باید حتماً کاربران خود را از تاریخ پایان دوره آزمایشی مطلع کنید.
این
trialUntil
روش به شما امکان می دهد نمونه ای را ارائه دهید
DateTime
که مشخص می کند دوره آزمایشی چه زمانی باید به پایان برسد:
use Carbon\Carbon; $user->newSubscription('default', 'price_monthly') ->trialUntil(Carbon::now()->addDays(10)) ->create($paymentMethod);
onTrial
میتوانید با استفاده از روش نمونه کاربر یا
onTrial
روش نمونه اشتراک
تعیین کنید که آیا کاربر در دوره آزمایشی خود است .
دو مثال زیر معادل هستند:
if ($user->onTrial('default')) { // ...} if ($user->subscription('default')->onTrial()) { // ...}
میتوانید از این
endTrial
روش برای پایان فوری یک دوره آزمایشی اشتراک استفاده کنید:
$user->subscription('default')->endTrial();
برای تعیین اینکه آیا دوره آزمایشی موجود منقضی شده است، می توانید از
hasExpiredTrial
روش های زیر استفاده کنید:
if ($user->hasExpiredTrial('default')) { // ...} if ($user->subscription('default')->hasExpiredTrial()) { // ...}
تعریف روزهای آزمایشی در Stripe / Cashier
میتوانید تعیین کنید که قیمت شما چند روز آزمایشی در داشبورد Stripe دریافت میکند یا همیشه آنها را با استفاده از Cashier به صراحت ارسال کنید. اگر انتخاب میکنید روزهای آزمایشی قیمت خود را در Stripe تعریف کنید، باید بدانید که اشتراکهای جدید، از جمله اشتراکهای جدید برای مشتری که در گذشته اشتراک داشتهاند، همیشه یک دوره آزمایشی دریافت میکنند، مگر اینکه صریحاً با روش تماس بگیرید
skipTrial()
.
بدون روش پرداخت از قبل
اگر میخواهید دورههای آزمایشی را بدون جمعآوری اطلاعات روش پرداخت کاربر از قبل ارائه دهید، میتوانید ستون
trial_ends_at
روی سابقه کاربر را روی تاریخ پایان آزمایشی مورد نظر خود تنظیم کنید. این معمولاً در هنگام ثبت نام کاربر انجام می شود:
use App\Models\User; $user = User::create([ // ... 'trial_ends_at' => now()->addDays(10),]);
مطمئن شوید که یک تاریخ ارسال برای
trial_ends_at
ویژگی در تعریف کلاس مدل قابل پرداخت خود اضافه کنید.
صندوقدار به این نوع آزمایش به عنوان یک "آزمایش عمومی" اشاره می کند، زیرا به هیچ اشتراک موجود متصل نیست.
اگر تاریخ فعلی از مقدار زیر گذشته نباشد،
روش
onTrial
موجود در نمونه مدل قابل صورتحساب برمیگردد
:
true
trial_ends_at
if ($user->onTrial()) { // User is within their trial period...}
هنگامی که آماده ایجاد یک اشتراک واقعی برای کاربر هستید، می توانید
newSubscription
طبق معمول از روش زیر استفاده کنید:
$user = User::find(1); $user->newSubscription('default', 'price_monthly')->create($paymentMethod);
برای بازیابی تاریخ پایان آزمایشی کاربر، می توانید از این
trialEndsAt
روش استفاده کنید. این روش در صورتی که کاربر در حال آزمایش باشد یا
null
نباشد، یک نمونه تاریخ کربن را برمی گرداند. همچنین اگر میخواهید تاریخ پایان آزمایشی برای یک اشتراک خاص غیر از اشتراک پیشفرض را دریافت کنید، میتوانید یک پارامتر نوع اشتراک اختیاری را ارسال کنید:
if ($user->onTrial()) { $trialEndsAt = $user->trialEndsAt('main');}
onGenericTrial
همچنین اگر میخواهید به طور خاص بدانید که کاربر در دوره آزمایشی "عمومی" خود است و هنوز اشتراک واقعی ایجاد نکرده است،
میتوانید از این روش استفاده کنید :
if ($user->onGenericTrial()) { // User is within their "generic" trial period...}
تمدید آزمایشات
این
extendTrial
روش به شما امکان می دهد تا دوره آزمایشی یک اشتراک را پس از ایجاد اشتراک تمدید کنید. اگر دوره آزمایشی قبلاً منقضی شده است و مشتری قبلاً برای اشتراک صورتحساب دریافت میکند، همچنان میتوانید یک دوره آزمایشی طولانیتر را به او پیشنهاد دهید. زمان صرف شده در دوره آزمایشی از فاکتور بعدی مشتری کسر می شود:
use App\Models\User; $subscription = User::find(1)->subscription('default'); // End the trial 7 days from now...$subscription->extendTrial( now()->addDays(7)); // Add an additional 5 days to the trial...$subscription->extendTrial( $subscription->trial_ends_at->addDays(5));
رسیدگی به قلاب های راه راه
میتوانید از Stripe CLI برای کمک به آزمایش وبکهکها در طول توسعه محلی استفاده کنید.
Stripe می تواند برنامه شما را از رویدادهای مختلف از طریق وب هوک ها مطلع کند. به طور پیش فرض، مسیری که به کنترلر وب هوک Cashier اشاره می کند، به طور خودکار توسط ارائه دهنده خدمات Cashier ثبت می شود. این کنترلر تمام درخواست های وب هوک دریافتی را رسیدگی می کند.
بهطور پیشفرض، کنترلکننده وبهوک Cashier بهطور خودکار لغو اشتراکهایی را که هزینههای ناموفق زیادی دارند (همانطور که تنظیمات Stripe شما تعریف کردهاند)، بهروزرسانیهای مشتری، حذفهای مشتری، بهروزرسانیهای اشتراک و تغییرات روش پرداخت را کنترل میکند. با این حال، همانطور که به زودی متوجه خواهیم شد، میتوانید این کنترلر را برای مدیریت هر رویداد Stripe webhook که دوست دارید گسترش دهید.
برای اطمینان از اینکه برنامه شما می تواند وب هوک های Stripe را مدیریت کند، حتماً URL وب هوک را در کنترل پنل Stripe پیکربندی کنید. به طور پیش فرض، کنترلر وب هوک Cashier به
/stripe/webhook
مسیر URL پاسخ می دهد. لیست کامل تمام وبکهک هایی که باید در کنترل پنل Stripe فعال کنید عبارتند از:
-
customer.subscription.created
-
customer.subscription.updated
-
customer.subscription.deleted
-
customer.updated
-
customer.deleted
-
payment_method.automatically_updated
-
invoice.payment_action_required
-
invoice.payment_succeeded
برای راحتی، Cashier شامل یک
cashier:webhook
فرمان Artisan است. این دستور یک webhook در Stripe ایجاد می کند که به تمام رویدادهای مورد نیاز Cashier گوش می دهد:
php artisan cashier:webhook
به طور پیش فرض، وب هوک ایجاد شده به URL تعریف شده توسط
APP_URL
متغیر محیطی و
cashier.webhook
مسیری که با Cashier ارائه شده است اشاره می کند.
--url
اگر میخواهید از URL دیگری استفاده کنید،
میتوانید هنگام فراخوانی دستور، این گزینه را ارائه دهید :
php artisan cashier:webhook --url "https://example.com/stripe/webhook"
وب هوکی که ایجاد می شود از نسخه Stripe API استفاده می کند که نسخه Cashier شما با آن سازگار است. اگر می خواهید از نسخه Stripe دیگری استفاده کنید، می توانید این
--api-version
گزینه را ارائه دهید:
php artisan cashier:webhook --api-version="2019-12-03"
پس از ایجاد، وب هوک بلافاصله فعال خواهد شد. اگر میخواهید وبهوک را ایجاد کنید، اما آن را تا زمانی که آماده شوید غیرفعال کنید، میتوانید
--disabled
هنگام فراخوانی دستور، این گزینه را ارائه دهید:
php artisan cashier:webhook --disabled
مطمئن شوید که از درخواستهای وبکهوک ورودی Stripe با میانافزار تأیید امضای وبهوک شامل Cashier محافظت میکنید .
Webhooks و CSRF Protection
از آنجایی که وب هوک های Stripe نیاز به دور زدن حفاظت CSRF
لاراول دارند
، باید اطمینان حاصل کنید که لاراول برای اعتبار سنجی توکن CSRF برای وب هوک های Stripe ورودی اقدام نمی کند. برای انجام این کار، باید
stripe/*
از حفاظت CSRF در فایل برنامه خود حذف کنید
bootstrap/app.php
:
->withMiddleware(function (Middleware $middleware) { $middleware->validateCsrfTokens(except: [ 'stripe/*', ]);})
تعریف مدیریت رویداد Webhook
Cashier به طور خودکار لغو اشتراک را برای هزینه های ناموفق و سایر رویدادهای متداول Stripe webhook کنترل می کند. با این حال، اگر رویدادهای webhook دیگری دارید که میخواهید مدیریت کنید، میتوانید این کار را با گوش دادن به رویدادهای زیر که توسط Cashier ارسال میشود انجام دهید:
-
Laravel\Cashier\Events\WebhookReceived
-
Laravel\Cashier\Events\WebhookHandled
هر دو رویداد حاوی بار کامل وب هوک Stripe هستند. برای مثال، اگر میخواهید
invoice.payment_succeeded
وب هوک را مدیریت کنید، میتوانید
شنوندهای را
ثبت کنید که رویداد را مدیریت کند:
<?php namespace App\Listeners; use Laravel\Cashier\Events\WebhookReceived; class StripeEventListener{ /** * Handle received Stripe webhooks. */ public function handle(WebhookReceived $event): void { if ($event->payload['type'] === 'invoice.payment_succeeded') { // Handle the incoming event... } }}
تأیید امضاهای Webhook
برای ایمن سازی وب هوک های خود، می توانید از امضاهای وب هوک Stripe استفاده کنید . برای راحتی، Cashier به طور خودکار یک میان افزار را شامل می شود که اعتبار درخواست وب هوک Stripe دریافتی را تأیید می کند.
برای فعال کردن تأیید وب هوک، مطمئن شوید که
STRIPE_WEBHOOK_SECRET
متغیر محیط در فایل برنامه شما تنظیم شده است
.env
. وب هوک
secret
ممکن است از داشبورد حساب Stripe شما بازیابی شود.
شارژ تک
شارژ ساده
اگر میخواهید یک بار هزینه از مشتری دریافت کنید، میتوانید از این
charge
روش در نمونهای از مدل قابل پرداخت استفاده کنید. شما باید
یک شناسه روش پرداخت را
به عنوان آرگومان دوم برای
charge
روش ارائه دهید:
use Illuminate\Http\Request; Route::post('/purchase', function (Request $request) { $stripeCharge = $request->user()->charge( 100, $request->paymentMethodId ); // ...});
این
charge
روش یک آرایه را به عنوان آرگومان سوم خود می پذیرد و به شما این امکان را می دهد که هر گزینه ای را که می خواهید به ایجاد شارژ Stripe زیربنایی منتقل کنید. اطلاعات بیشتر در مورد گزینههایی که هنگام ایجاد هزینهها در دسترس شما هستند را میتوانید در
مستندات Stripe
پیدا کنید :
$user->charge(100, $paymentMethod, [ 'custom_option' => $value,]);
همچنین می توانید از این
charge
روش بدون مشتری یا کاربر اساسی استفاده کنید. برای انجام این کار،
charge
روش را در یک نمونه جدید از مدل قابل پرداخت برنامه خود فراخوانی کنید:
use App\Models\User; $stripeCharge = (new User)->charge(100, $paymentMethod);
این
charge
روش در صورت عدم موفقیت شارژ، یک استثنا ایجاد می کند. در صورت موفقیت آمیز بودن شارژ، نمونه ای
Laravel\Cashier\Payment
از متد برگردانده می شود:
try { $payment = $user->charge(100, $paymentMethod);} catch (Exception $e) { // ...}
این
charge
روش مبلغ پرداختی را در کمترین مخرج ارز مورد استفاده برنامه شما می پذیرد. به عنوان مثال، اگر مشتریان به دلار ایالات متحده پرداخت می کنند، مبالغ باید به پنی مشخص شود.
شارژ با فاکتور
گاهی اوقات ممکن است لازم باشد یک بار شارژ کنید و یک فاکتور PDF به مشتری خود ارائه دهید. این
invoicePrice
روش به شما امکان می دهد این کار را انجام دهید. به عنوان مثال، بیایید یک مشتری برای پنج پیراهن جدید فاکتور کنیم:
$user->invoicePrice('price_tshirt', 5);
فاکتور بلافاصله از روش پرداخت پیش فرض کاربر کسر می شود. متد
invoicePrice
همچنین یک آرایه را به عنوان آرگومان سوم خود می پذیرد. این آرایه شامل گزینه های صورتحساب برای مورد فاکتور است. آرگومان چهارم پذیرفته شده توسط متد نیز آرایه ای است که باید شامل گزینه های صورتحساب برای خود فاکتور باشد:
$user->invoicePrice('price_tshirt', 5, [ 'discounts' => [ ['coupon' => 'SUMMER21SALE'] ],], [ 'default_tax_rates' => ['txr_id'],]);
به طور مشابه
invoicePrice
، میتوانید از این
tabPrice
روش برای ایجاد شارژ یکباره برای چندین مورد (حداکثر 250 مورد در هر فاکتور) با افزودن آنها به "برگه" مشتری و سپس صورتحساب مشتری استفاده کنید. به عنوان مثال، ممکن است برای مشتری پنج پیراهن و دو لیوان فاکتور کنیم:
$user->tabPrice('price_tshirt', 5);$user->tabPrice('price_mug', 2);$user->invoice();
از طرف دیگر، میتوانید از این
invoiceFor
روش برای ایجاد هزینه «یکباره» از روش پرداخت پیشفرض مشتری استفاده کنید:
$user->invoiceFor('One Time Fee', 500);
اگرچه این
invoiceFor
روش برای شما در دسترس است، اما توصیه می شود از روش های
invoicePrice
و
tabPrice
با قیمت های از پیش تعیین شده استفاده کنید. با انجام این کار، به تجزیه و تحلیل و داده های بهتری در داشبورد Stripe خود در رابطه با فروش خود بر اساس محصول دسترسی خواهید داشت.
روش های
invoice
,invoicePrice
, وinvoiceFor
یک فاکتور Stripe ایجاد می کند که تلاش های صورتحساب ناموفق را دوباره امتحان می کند. اگر نمیخواهید فاکتورها هزینههای ناموفق را دوباره امتحان کنند، باید آنها را با استفاده از Stripe API پس از اولین شارژ ناموفق ببندید.
ایجاد اهداف پرداخت
میتوانید با فراخوانی
pay
روش در نمونهای از مدل قابل صورتحساب، یک هدف پرداخت Stripe جدید ایجاد کنید. فراخوانی این روش یک هدف پرداخت ایجاد می کند که در یک
Laravel\Cashier\Payment
نمونه پیچیده می شود:
use Illuminate\Http\Request; Route::post('/pay', function (Request $request) { $payment = $request->user()->pay( $request->get('amount') ); return $payment->client_secret;});
پس از ایجاد قصد پرداخت، می توانید رمز مشتری را به جلوی برنامه خود برگردانید تا کاربر بتواند پرداخت را در مرورگر خود انجام دهد. برای مطالعه بیشتر درباره ایجاد کل جریان های پرداخت با استفاده از اهداف پرداخت Stripe، لطفاً به مستندات Stripe مراجعه کنید .
هنگام استفاده از این
pay
روش، روشهای پرداخت پیشفرض که در داشبورد Stripe شما فعال هستند در دسترس مشتری قرار میگیرند. از طرف دیگر، اگر فقط میخواهید استفاده از برخی روشهای پرداخت خاص را مجاز کنید، میتوانید از
payWith
روش زیر استفاده کنید:
use Illuminate\Http\Request; Route::post('/pay', function (Request $request) { $payment = $request->user()->payWith( $request->get('amount'), ['card', 'bancontact'] ); return $payment->client_secret;});
و روشها مبلغ پرداختی
pay
راpayWith
در کمترین مخرج ارز مورد استفاده برنامه شما میپذیرند. به عنوان مثال، اگر مشتریان به دلار ایالات متحده پرداخت می کنند، مبالغ باید به پنی مشخص شود.
هزینه های بازپرداخت
اگر نیاز به بازپرداخت هزینه Stripe دارید، میتوانید از این
refund
روش استفاده کنید. این روش
شناسه هدف پرداخت
Stripe را
به عنوان اولین آرگومان خود می پذیرد:
$payment = $user->charge(100, $paymentMethodId); $user->refund($payment->id);
فاکتورها
بازیابی فاکتورها
شما می توانید به راحتی آرایه ای از فاکتورهای یک مدل قابل پرداخت را با استفاده از این
invoices
روش بازیابی کنید. متد
invoices
مجموعه ای از
Laravel\Cashier\Invoice
نمونه ها را برمی گرداند:
$invoices = $user->invoices();
اگر می خواهید فاکتورهای معلق را در نتایج لحاظ کنید، می توانید از
invoicesIncludingPending
روش زیر استفاده کنید:
$invoices = $user->invoicesIncludingPending();
می توانید از
findInvoice
روش برای بازیابی یک فاکتور خاص با شناسه آن استفاده کنید:
$invoice = $user->findInvoice($invoiceId);
نمایش اطلاعات فاکتور
هنگام فهرست کردن فاکتورها برای مشتری، می توانید از روش های فاکتور برای نمایش اطلاعات فاکتور مربوطه استفاده کنید. به عنوان مثال، ممکن است بخواهید همه فاکتورها را در یک جدول فهرست کنید و به کاربر اجازه دهید به راحتی هر یک از آنها را دانلود کند:
<table> @foreach ($invoices as $invoice) <tr> <td>{{ $invoice->date()->toFormattedDateString() }}</td> <td>{{ $invoice->total() }}</td> <td><a href="/user/invoice/{{ $invoice->id }}">Download</a></td> </tr> @endforeach</table>
فاکتورهای آینده
برای بازیابی فاکتور آینده برای مشتری، می توانید از
upcomingInvoice
روش زیر استفاده کنید:
$invoice = $user->upcomingInvoice();
به طور مشابه، اگر مشتری چندین اشتراک داشته باشد، می توانید فاکتور آینده را برای یک اشتراک خاص نیز بازیابی کنید:
$invoice = $user->subscription('default')->upcomingInvoice();
پیش نمایش فاکتورهای اشتراک
با استفاده از این
previewInvoice
روش، می توانید پیش نمایش فاکتور را قبل از تغییر قیمت مشاهده کنید. این به شما این امکان را می دهد که تعیین کنید هنگام تغییر قیمت مشخص، فاکتور مشتری شما چگونه خواهد بود:
$invoice = $user->subscription('default')->previewInvoice('price_yearly');
میتوانید مجموعهای از قیمتها را به
previewInvoice
روش ارسال کنید تا پیشنمایش صورتحسابها را با چندین قیمت جدید مشاهده کنید:
$invoice = $user->subscription('default')->previewInvoice(['price_yearly', 'price_metered']);
تولید پی دی اف فاکتور
قبل از تولید فایلهای PDF فاکتور، باید از Composer برای نصب کتابخانه Dompdf استفاده کنید، که رندر پیشفرض فاکتور برای Cashier است:
composer require dompdf/dompdf
از داخل یک مسیر یا کنترلکننده، میتوانید از این
downloadInvoice
روش برای ایجاد دانلود PDF از یک فاکتور معین استفاده کنید. این روش به طور خودکار پاسخ HTTP مناسب مورد نیاز برای دانلود فاکتور را ایجاد می کند:
use Illuminate\Http\Request; Route::get('/user/invoice/{invoice}', function (Request $request, string $invoiceId) { return $request->user()->downloadInvoice($invoiceId);});
به طور پیشفرض، تمام دادههای فاکتور از مشتری و دادههای فاکتور ذخیره شده در Stripe مشتق میشوند. نام فایل بر اساس
app.name
مقدار پیکربندی شما است. با این حال، میتوانید برخی از این دادهها را با ارائه یک آرایه به عنوان آرگومان دوم برای
downloadInvoice
متد شخصیسازی کنید. این آرایه به شما امکان می دهد اطلاعاتی مانند جزئیات شرکت و محصول خود را سفارشی کنید:
return $request->user()->downloadInvoice($invoiceId, [ 'vendor' => 'Your Company', 'product' => 'Your Product', 'street' => 'Main Str. 1', 'location' => '2000 Antwerp, Belgium', 'phone' => '+32 499 00 00 00', 'email' => 'info@example.com', 'url' => 'https://example.com', 'vendorVat' => 'BE123456789',]);
این
downloadInvoice
روش همچنین اجازه می دهد تا نام فایل سفارشی را از طریق آرگومان سوم خود انتخاب کنید. این نام فایل به طور خودکار با پسوند
.pdf
:
return $request->user()->downloadInvoice($invoiceId, [], 'my-invoice');
ارائه کننده فاکتور سفارشی
صندوقدار همچنین امکان استفاده از رندر فاکتور سفارشی را فراهم می کند. بهطور پیشفرض، Cashier از
DompdfInvoiceRenderer
پیادهسازی استفاده میکند که از کتابخانه PHP
dompdf
برای تولید فاکتورهای Cashier استفاده میکند. با این حال، می توانید از هر رندری که می خواهید با پیاده سازی
Laravel\Cashier\Contracts\InvoiceRenderer
اینترفیس استفاده کنید. برای مثال، ممکن است بخواهید یک PDF فاکتور را با استفاده از یک تماس API به یک سرویس رندر PDF شخص ثالث ارائه دهید:
use Illuminate\Support\Facades\Http;use Laravel\Cashier\Contracts\InvoiceRenderer;use Laravel\Cashier\Invoice; class ApiInvoiceRenderer implements InvoiceRenderer{ /** * Render the given invoice and return the raw PDF bytes. */ public function render(Invoice $invoice, array $data = [], array $options = []): string { $html = $invoice->view($data)->render(); return Http::get('https://example.com/html-to-pdf', ['html' => $html])->get()->body(); }}
هنگامی که قرارداد ارائه کننده فاکتور را اجرا کردید، باید
cashier.invoices.renderer
مقدار پیکربندی را در فایل پیکربندی برنامه خود به روز کنید
config/cashier.php
. این مقدار پیکربندی باید روی نام کلاس اجرای رندر سفارشی شما تنظیم شود.
وارسی
Cashier Stripe همچنین از Stripe Checkout پشتیبانی می کند . Stripe Checkout با ارائه یک صفحه پرداخت از پیش ساخته شده و میزبانی شده، درد اجرای صفحات سفارشی برای پذیرش پرداخت را کاهش می دهد.
اسناد زیر حاوی اطلاعاتی در مورد نحوه شروع استفاده از Stripe Checkout با صندوقدار است. برای کسب اطلاعات بیشتر درباره Stripe Checkout، باید اسناد خود Stripe را در Checkout نیز مرور کنید .
بررسی های محصول
میتوانید برای یک محصول موجود که در داشبورد Stripe شما ایجاد شده است، با استفاده از
checkout
روش روی یک مدل صورتحساب، تسویه حساب کنید. این
checkout
روش یک جلسه جدید Stripe Checkout را آغاز می کند. بهطور پیشفرض، باید شناسه Stripe Price را ارسال کنید:
use Illuminate\Http\Request; Route::get('/product-checkout', function (Request $request) { return $request->user()->checkout('price_tshirt');});
در صورت نیاز، می توانید مقدار محصول را نیز مشخص کنید:
use Illuminate\Http\Request; Route::get('/product-checkout', function (Request $request) { return $request->user()->checkout(['price_tshirt' => 15]);});
هنگامی که یک مشتری از این مسیر بازدید می کند، به صفحه پرداخت Stripe هدایت می شود. بهطور پیشفرض، زمانی که کاربر خریدی را با موفقیت انجام میدهد یا لغو میکند، به مکان مسیر شما هدایت میشود
home
، اما میتوانید URLهای پاسخ به تماس سفارشی را با استفاده از گزینههای
success_url
و مشخص کنید
cancel_url
:
use Illuminate\Http\Request; Route::get('/product-checkout', function (Request $request) { return $request->user()->checkout(['price_tshirt' => 1], [ 'success_url' => route('your-success-route'), 'cancel_url' => route('your-cancel-route'), ]);});
هنگام تعریف
success_url
گزینه پرداخت خود، ممکن است به Stripe دستور دهید تا هنگام فراخوانی URL شما، شناسه جلسه پرداخت را به عنوان پارامتر رشته پرس و جو اضافه کند. برای انجام این کار، رشته لفظی را
{CHECKOUT_SESSION_ID}
به رشته پرس و جو خود اضافه کنید
success_url
. Stripe این مکاننما را با شناسه جلسه پرداخت واقعی جایگزین میکند:
use Illuminate\Http\Request;use Stripe\Checkout\Session;use Stripe\Customer; Route::get('/product-checkout', function (Request $request) { return $request->user()->checkout(['price_tshirt' => 1], [ 'success_url' => route('checkout-success').'?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => route('checkout-cancel'), ]);}); Route::get('/checkout-success', function (Request $request) { $checkoutSession = $request->user()->stripe()->checkout->sessions->retrieve($request->get('session_id')); return view('checkout.success', ['checkoutSession' => $checkoutSession]);})->name('checkout-success');
کدهای تبلیغاتی
بهطور پیشفرض، Stripe Checkout کدهای تبلیغاتی قابل بازخرید کاربر را
مجاز نمیداند
. خوشبختانه، یک راه آسان برای فعال کردن این موارد برای صفحه پرداخت شما وجود دارد. برای انجام این کار، می توانید از
allowPromotionCodes
روش استفاده کنید:
use Illuminate\Http\Request; Route::get('/product-checkout', function (Request $request) { return $request->user() ->allowPromotionCodes() ->checkout('price_tshirt');});
تسویه حساب تک شارژ
همچنین میتوانید برای یک محصول موقتی که در داشبورد Stripe شما ایجاد نشده است، یک شارژ ساده انجام دهید. برای انجام این کار، میتوانید از این
checkoutCharge
روش در یک مدل قابل پرداخت استفاده کنید و مبلغ قابل شارژ، نام محصول و مقدار اختیاری را برای آن ارسال کنید. هنگامی که مشتری از این مسیر بازدید می کند، به صفحه پرداخت Stripe هدایت می شود:
use Illuminate\Http\Request; Route::get('/charge-checkout', function (Request $request) { return $request->user()->checkoutCharge(1200, 'T-Shirt', 5);});
هنگام استفاده از
checkoutCharge
روش، Stripe همیشه یک محصول و قیمت جدید در داشبورد Stripe شما ایجاد می کند. بنابراین، توصیه می کنیم که محصولات را از جلو در داشبورد Stripe خود ایجاد کنید وcheckout
به جای آن از روش استفاده کنید.
پرداخت های اشتراک
استفاده از Stripe Checkout برای اشتراکها از شما میخواهد که
customer.subscription.created
webhook را در داشبورد Stripe خود فعال کنید. این وب هوک رکورد اشتراک را در پایگاه داده شما ایجاد می کند و همه موارد اشتراک مربوطه را ذخیره می کند.
همچنین میتوانید از Stripe Checkout برای شروع اشتراکها استفاده کنید. پس از تعریف اشتراک خود با روش های سازنده اشتراک صندوقدار، می توانید
checkout
روش را فراخوانی کنید. هنگامی که مشتری از این مسیر بازدید می کند، به صفحه پرداخت Stripe هدایت می شود:
use Illuminate\Http\Request; Route::get('/subscription-checkout', function (Request $request) { return $request->user() ->newSubscription('default', 'price_monthly') ->checkout();});
درست مانند تسویهحسابهای محصول، میتوانید URL موفقیت و لغو را سفارشی کنید:
use Illuminate\Http\Request; Route::get('/subscription-checkout', function (Request $request) { return $request->user() ->newSubscription('default', 'price_monthly') ->checkout([ 'success_url' => route('your-success-route'), 'cancel_url' => route('your-cancel-route'), ]);});
البته، میتوانید کدهای تبلیغاتی را برای پرداختهای اشتراک نیز فعال کنید:
use Illuminate\Http\Request; Route::get('/subscription-checkout', function (Request $request) { return $request->user() ->newSubscription('default', 'price_monthly') ->allowPromotionCodes() ->checkout();});
متأسفانه Stripe Checkout از همه گزینههای صورتحساب اشتراک هنگام شروع اشتراک پشتیبانی نمیکند. استفاده از
anchorBillingCycleOn
روش در سازنده اشتراک، تنظیم رفتار تناسب یا تنظیم رفتار پرداخت هیچ تاثیری در جلسات Stripe Checkout نخواهد داشت. لطفاً برای بررسی پارامترهای موجود، به مستندات Stripe Checkout Session API مراجعه کنید.
Stripe Checkout و دوره های آزمایشی
البته، میتوانید یک دوره آزمایشی را هنگام ساختن یک اشتراک تعریف کنید که با استفاده از Stripe Checkout تکمیل میشود:
$checkout = Auth::user()->newSubscription('default', 'price_monthly') ->trialDays(3) ->checkout();
با این حال، دوره آزمایشی باید حداقل 48 ساعت باشد، که حداقل مدت زمان آزمایشی پشتیبانی شده توسط Stripe Checkout است.
اشتراک ها و وب هوک ها
به یاد داشته باشید، Stripe و Cashier وضعیت اشتراک را از طریق webhooks به روز می کنند، بنابراین این احتمال وجود دارد که وقتی مشتری پس از وارد کردن اطلاعات پرداخت خود به برنامه بازگردد، اشتراک هنوز فعال نباشد. برای رسیدگی به این سناریو، ممکن است بخواهید پیامی را نمایش دهید که به کاربر اطلاع میدهد پرداخت یا اشتراک او در حال تعلیق است.
جمع آوری شناسه های مالیاتی
Checkout همچنین از جمع آوری شناسه مالیاتی مشتری پشتیبانی می کند. برای فعال کردن این مورد در جلسه پرداخت،
collectTaxIds
هنگام ایجاد جلسه، روش را فراخوانی کنید:
$checkout = $user->collectTaxIds()->checkout('price_tshirt');
هنگامی که این روش فراخوانی می شود، یک چک باکس جدید در دسترس مشتری قرار می گیرد که به او امکان می دهد مشخص کند که آیا به عنوان یک شرکت خرید می کند یا خیر. در این صورت، آنها این فرصت را خواهند داشت که شماره شناسه مالیاتی خود را ارائه کنند.
اگر قبلاً جمع آوری مالیات خودکار را در ارائه دهنده خدمات برنامه خود پیکربندی کرده اید ، این ویژگی به طور خودکار فعال می شود و نیازی به فراخوانی روش نیست
collectTaxIds
.
تسویه حساب مهمان
با استفاده از این
Checkout::guest
روش، میتوانید جلسات پرداخت را برای مهمانان برنامه خود که «حساب» ندارند، راهاندازی کنید:
use Illuminate\Http\Request;use Laravel\Cashier\Checkout; Route::get('/product-checkout', function (Request $request) { return Checkout::guest()->create('price_tshirt', [ 'success_url' => route('your-success-route'), 'cancel_url' => route('your-cancel-route'), ]);});
به طور مشابه هنگام ایجاد جلسات تسویه حساب برای کاربران فعلی، می توانید از روش های اضافی موجود در
Laravel\Cashier\CheckoutBuilder
نمونه برای سفارشی کردن جلسه پرداخت مهمان استفاده کنید:
use Illuminate\Http\Request;use Laravel\Cashier\Checkout; Route::get('/product-checkout', function (Request $request) { return Checkout::guest() ->withPromotionCode('promo-code') ->create('price_tshirt', [ 'success_url' => route('your-success-route'), 'cancel_url' => route('your-cancel-route'), ]);});
پس از اتمام تسویه حساب مهمان، Stripe میتواند
checkout.session.completed
رویداد webhook را ارسال کند، بنابراین مطمئن شوید که
وبهوک Stripe خود را طوری پیکربندی کردهاید
که واقعاً این رویداد را به برنامه شما ارسال کند. هنگامی که وب هوک در داشبورد Stripe فعال شد، می توانید
وب هوک را با Cashier مدیریت کنید
. شی موجود در محموله وب هوک،
checkout
شیئی
خواهد بود که می توانید برای انجام سفارش مشتری خود، آن را بررسی کنید.
رسیدگی به پرداخت های ناموفق
گاهی اوقات، پرداخت برای اشتراک یا هزینه های تکی ممکن است با شکست مواجه شود. وقتی این اتفاق میافتد، Cashier استثنایی میاندازد
Laravel\Cashier\Exceptions\IncompletePayment
که به شما اطلاع میدهد که این اتفاق افتاده است. پس از گرفتن این استثنا، شما دو گزینه در مورد نحوه ادامه دارید.
ابتدا، می توانید مشتری خود را به صفحه تأیید پرداخت اختصاصی که همراه صندوقدار است هدایت کنید. این صفحه قبلاً دارای یک مسیر با نام مرتبط است که از طریق ارائهدهنده خدمات Cashier ثبت شده است. بنابراین، می توانید
IncompletePayment
استثنا را بگیرید و کاربر را به صفحه تأیید پرداخت هدایت کنید:
use Laravel\Cashier\Exceptions\IncompletePayment; try { $subscription = $user->newSubscription('default', 'price_monthly') ->create($paymentMethod);} catch (IncompletePayment $exception) { return redirect()->route( 'cashier.payment', [$exception->payment->id, 'redirect' => route('home')] );}
در صفحه تأیید پرداخت، از مشتری خواسته میشود که اطلاعات کارت اعتباری خود را دوباره وارد کند و هرگونه اقدام اضافی مورد نیاز Stripe، مانند تأیید «3D Secure» را انجام دهد. پس از تایید پرداخت، کاربر به URL ارائه شده توسط
redirect
پارامتر مشخص شده در بالا هدایت می شود. پس از تغییر مسیر، متغیرهای رشته پرس و جو
message
(رشته) و
success
(عدد صحیح) به URL اضافه می شوند. صفحه پرداخت در حال حاضر از انواع روش پرداخت زیر پشتیبانی می کند:
- کارت های اعتباری
- Alipay
- Bancontact
- بدهی مستقیم BECS
- EPS
- جیروپای
- ایده آل
- SEPA Direct Debit
از طرف دیگر، میتوانید به Stripe اجازه دهید تا تأیید پرداخت را برای شما انجام دهد. در این حالت، به جای هدایت مجدد به صفحه تأیید پرداخت، میتوانید
ایمیلهای صورتحساب خودکار Stripe را
در داشبورد Stripe خود تنظیم کنید. با این حال، اگر
IncompletePayment
استثنایی مشخص شود، همچنان باید به کاربر اطلاع دهید که یک ایمیل با دستورالعملهای تأیید پرداخت بیشتر دریافت خواهد کرد.
استثناهای پرداخت ممکن است برای روشهای زیر اعمال شود:
charge
,
invoiceFor
و
invoice
در مدلهایی که از این
Billable
ویژگی استفاده میکنند. هنگام تعامل با اشتراکها،
create
روش روی
SubscriptionBuilder
, و روشهای
incrementAndInvoice
و
swapAndInvoice
در مدلهای
Subscription
و
SubscriptionItem
ممکن است استثنائات پرداخت ناقصی ایجاد کند.
تعیین اینکه آیا اشتراک موجود دارای پرداخت ناقص است یا خیر، ممکن است با استفاده از
hasIncompletePayment
روش موجود در مدل قابل پرداخت یا یک نمونه اشتراک انجام شود:
if ($user->hasIncompletePayment('default')) { // ...} if ($user->subscription('default')->hasIncompletePayment()) { // ...}
شما می توانید وضعیت خاص یک پرداخت ناقص را با بررسی
payment
دارایی در مورد استثنا بدست آورید:
use Laravel\Cashier\Exceptions\IncompletePayment; try { $user->charge(1000, 'pm_card_threeDSecure2Required');} catch (IncompletePayment $exception) { // Get the payment intent status... $exception->payment->status; // Check specific conditions... if ($exception->payment->requiresPaymentMethod()) { // ... } elseif ($exception->payment->requiresConfirmation()) { // ... }}
تایید پرداخت ها
برخی از روشهای پرداخت برای تأیید پرداختها به دادههای اضافی نیاز دارند. به عنوان مثال، روشهای پرداخت SEPA به دادههای «اجباری» اضافی در طول فرآیند پرداخت نیاز دارند. شما می توانید این داده ها را با استفاده از روش زیر در اختیار صندوقدار قرار دهید
withPaymentConfirmationOptions
:
$subscription->withPaymentConfirmationOptions([ 'mandate_data' => '...',])->swap('price_xxx');
برای بررسی همه گزینههای پذیرفتهشده هنگام تأیید پرداختها، میتوانید به اسناد Stripe API مراجعه کنید.
احراز هویت قوی مشتری
اگر کسب و کار شما یا یکی از مشتریان شما در اروپا مستقر است، باید از مقررات قوی تایید هویت مشتری (SCA) اتحادیه اروپا پیروی کنید. این مقررات در سپتامبر 2019 توسط اتحادیه اروپا برای جلوگیری از تقلب در پرداخت وضع شد. خوشبختانه، Stripe و Cashier برای ساخت برنامه های سازگار با SCA آماده شده اند.
قبل از شروع، راهنمای Stripe در مورد PSD2 و SCA و همچنین مستندات آنها در مورد APIهای جدید SCA را مرور کنید .
پرداخت هایی که نیاز به تایید اضافی دارند
مقررات SCA معمولاً برای تأیید و پردازش پرداخت نیاز به تأیید اضافی دارند. وقتی این اتفاق میافتد، Cashier استثنایی ایجاد میکند
Laravel\Cashier\Exceptions\IncompletePayment
که به شما اطلاع میدهد که تأیید اضافی لازم است. اطلاعات بیشتر در مورد نحوه رسیدگی به این استثنائات را می توان در اسناد
رسیدگی به پرداخت های ناموفق
یافت .
صفحههای تأیید پرداخت ارائهشده توسط Stripe یا Cashier ممکن است متناسب با جریان پرداخت یک بانک یا صادرکننده کارت خاص باشد و میتواند شامل تأیید کارت اضافی، هزینهای اندک موقت، احراز هویت جداگانه دستگاه یا سایر اشکال تأیید باشد.
وضعیت ناقص و سررسید گذشته
هنگامی که پرداخت نیاز به تأیید اضافی دارد، اشتراک در وضعیت
incomplete
یا
past_due
وضعیتی باقی میماند که در ستون پایگاه داده آن نشان داده شده است
stripe_status
. صندوقدار به محض تکمیل تایید پرداخت و درخواست شما توسط Stripe از طریق webhook از تکمیل آن به طور خودکار اشتراک مشتری را فعال می کند.
برای اطلاعات بیشتر در مورد
incomplete
و
past_due
وضعیت ها، لطفاً به
اسناد اضافی ما در مورد این ایالت ها
مراجعه کنید .
اطلاعیه های پرداخت خارج از جلسه
از آنجایی که مقررات SCA مشتریان را ملزم می کند که گهگاه جزئیات پرداخت خود را حتی در زمانی که اشتراک آنها فعال است تأیید کنند، صندوقدار می تواند در صورت نیاز به تأیید پرداخت خارج از جلسه، اعلانی را برای مشتری ارسال کند. به عنوان مثال، این ممکن است زمانی رخ دهد که یک اشتراک در حال تمدید است. اعلان پرداخت صندوقدار را می توان با تنظیم
CASHIER_PAYMENT_NOTIFICATION
متغیر محیطی روی یک کلاس اطلاع رسانی فعال کرد. به طور پیش فرض، این اعلان غیرفعال است. البته، Cashier شامل یک کلاس اعلان است که می توانید برای این منظور از آن استفاده کنید، اما در صورت تمایل می توانید کلاس اعلان خود را ارائه دهید:
CASHIER_PAYMENT_NOTIFICATION=Laravel\Cashier\Notifications\ConfirmPayment
برای اطمینان از اینکه اعلانهای تأیید پرداخت خارج از جلسه تحویل داده میشوند، بررسی کنید که وبکهوکهای Stripe
برای برنامه شما
پیکربندی شدهاند
invoice.payment_action_required
و وبهوک در داشبورد Stripe شما فعال است. علاوه بر این،
Billable
مدل شما باید از ویژگی لاراول نیز استفاده کند
Illuminate\Notifications\Notifiable
.
حتی زمانی که مشتریان به صورت دستی پرداختی را انجام می دهند که نیاز به تأیید اضافی دارد، اعلان ها ارسال می شود. متاسفانه هیچ راهی برای Stripe وجود ندارد که بداند پرداخت به صورت دستی یا "خارج از جلسه" انجام شده است. اما، اگر مشتری پس از تایید پرداخت خود از صفحه پرداخت بازدید کند، به سادگی پیام "پرداخت موفقیت آمیز" را مشاهده می کند. مشتری مجاز نخواهد بود به طور تصادفی یک پرداخت را دو بار تایید کند و متحمل هزینه دوم تصادفی شود.
Stripe SDK
بسیاری از اشیاء Cashier در اطراف اشیاء Stripe SDK قرار دارند. اگر میخواهید مستقیماً با اشیاء Stripe تعامل داشته باشید، میتوانید به راحتی آنها را با استفاده از
asStripe
روش زیر بازیابی کنید:
$stripeSubscription = $subscription->asStripeSubscription(); $stripeSubscription->application_fee_percent = 5; $stripeSubscription->save();
همچنین می توانید از این
updateStripeSubscription
روش برای به روز رسانی مستقیم اشتراک Stripe استفاده کنید:
$subscription->updateStripeSubscription(['application_fee_percent' => 5]);
اگر می خواهید مستقیماً از کلاینت استفاده کنید،
می توانید
stripe
متد را در کلاس فراخوانی کنید
. به عنوان مثال، می توانید از این روش برای دسترسی به
نمونه و بازیابی لیست قیمت ها از حساب Stripe خود استفاده کنید:
Cashier
Stripe\StripeClient
StripeClient
use Laravel\Cashier\Cashier; $prices = Cashier::stripe()->prices->all();
آزمایش کردن
هنگام آزمایش برنامهای که از Cashier استفاده میکند، ممکن است درخواستهای HTTP واقعی به Stripe API را تقلید کنید. با این حال، این مستلزم آن است که تا حدی رفتار خود Cashier را مجدداً اجرا کنید. بنابراین، توصیه میکنیم به تستهای شما اجازه دهید به Stripe API واقعی برسند. اگرچه این سرعت کندتر است، اما اطمینان بیشتری به شما می دهد که برنامه شما همانطور که انتظار می رود کار می کند و هر آزمایش کند ممکن است در گروه آزمایش Pest / PHPUnit خود قرار گیرد.
هنگام آزمایش، به یاد داشته باشید که خود Cashier در حال حاضر یک مجموعه آزمایشی عالی دارد، بنابراین باید فقط روی آزمایش اشتراک و جریان پرداخت برنامه خود تمرکز کنید و نه هر رفتار زیربنایی صندوقدار.
برای شروع، نسخه
آزمایشی
راز Stripe خود را به
phpunit.xml
فایل خود اضافه کنید:
<env name="STRIPE_SECRET" value="sk_test_<your-key>"/>
اکنون، هر زمان که هنگام آزمایش با Cashier تعامل داشته باشید، درخواستهای API واقعی را به محیط تست Stripe شما ارسال میکند. برای راحتی، باید حساب آزمایشی Stripe خود را با اشتراک ها / قیمت هایی که ممکن است در طول آزمایش استفاده کنید، از قبل پر کنید.
به منظور آزمایش انواع سناریوهای صورتحساب، مانند رد کردن و خرابی کارت اعتباری، میتوانید از طیف وسیعی از شمارهها و نشانههای کارت تست ارائه شده توسط Stripe استفاده کنید.