صندوقدار لاراول
- معرفی
- ارتقاء صندوقدار
- نصب و راه اندازی
- پیکربندی
- مشتریان
- روش های پرداخت
- اشتراک ها
- آزمایشات اشتراک
- رسیدگی به قلاب های راه راه
- شارژ تک
- فاکتورها
- رسیدگی به پرداخت های ناموفق
- احراز هویت قوی مشتری (SCA)
- Stripe SDK
- آزمایش کردن
معرفی
Laravel Cashier یک رابط رسا و روان برای خدمات صورتحساب اشتراک Stripe فراهم می کند. تقریباً تمام کدهای صورتحساب اشتراک دیگ بخار را که از نوشتن آن میترسید مدیریت میکند. علاوه بر مدیریت اشتراک اولیه، Cashier میتواند کوپنها، تعویض اشتراک، "مقدار" اشتراک، دورههای مهلت لغو، و حتی فایلهای PDF فاکتور تولید کند.
ارتقاء صندوقدار
هنگام ارتقاء به نسخه جدید Cashier، مهم است که راهنمای ارتقا را به دقت مرور کنید .
برای جلوگیری از شکستن تغییرات، Cashier از یک نسخه API ثابت Stripe استفاده می کند. Cashier 12 از نسخه Stripe API استفاده می کند
2020-03-02
. نسخه Stripe API در نسخههای کوچک بهروزرسانی میشود تا از ویژگیها و بهبودهای جدید Stripe استفاده کند.
نصب و راه اندازی
ابتدا به بسته Cashier برای Stripe with Composer نیاز دارید:
composer require laravel/cashier
برای اطمینان از اینکه Cashier به درستی همه رویدادهای Stripe را مدیریت می کند، به یاد داشته باشید که کنترل وب هوک Cashier را تنظیم کنید .
مهاجرت های پایگاه داده
ارائه دهنده خدمات Cashier دایرکتوری مهاجرت پایگاه داده خود را ثبت می کند،
بنابراین به یاد داشته باشید که پس از نصب بسته، پایگاه داده خود را انتقال دهید.
مهاجرت صندوقدار چندین ستون را به
users
جدول شما اضافه می کند و همچنین یک
subscriptions
جدول جدید برای نگهداری تمام اشتراک های مشتری شما ایجاد می کند:
php artisan migrate
اگر نیاز به بازنویسی انتقالهایی دارید که با بسته Cashier ارسال میشوند،
میتوانید آنها را با استفاده از
vendor:publish
دستور Artisan منتشر کنید:
php artisan vendor:publish --tag="cashier-migrations"
اگر می خواهید از اجرای کامل مهاجرت صندوقدار جلوگیری کنید، می توانید از
برنامه
ignoreMigrations
ارائه شده توسط صندوقدار استفاده کنید.
register
به طور معمول، این روش باید در متد شما
فراخوانی شود
AppServiceProvider
:
use Laravel\Cashier\Cashier; Cashier::ignoreMigrations();
Stripe توصیه می کند که هر ستونی که برای ذخیره شناسه های Stripe استفاده می شود باید به حروف بزرگ و کوچک حساس باشد. بنابراین، باید اطمینان حاصل کنید که ترکیب ستون برای
stripe_id
ستون، به عنوان مثال، در MySQL تنظیم شده استutf8_bin
. اطلاعات بیشتر را می توان در مستندات Stripe یافت .
پیکربندی
مدل قابل پرداخت
قبل از استفاده از Cashier، این
Billable
ویژگی را به تعریف مدل خود اضافه کنید.
این ویژگی روشهای مختلفی را ارائه میکند تا به شما امکان میدهد کارهای
رایج صورتحساب را انجام دهید، مانند ایجاد اشتراک، اعمال کوپن، و بهروزرسانی اطلاعات روش پرداخت:
use Laravel\Cashier\Billable; class User extends Authenticatable{ use Billable;}
Cashier فرض می کند که مدل Billable شما کلاسی است
App\User
که با لاراول ارسال می شود.
اگر می خواهید این را تغییر دهید، می توانید مدل دیگری را در
.env
فایل خود مشخص کنید:
CASHIER_MODEL=App\User
اگر از مدلی غیر از
App\User
مدل ارائه شده لاراول استفاده میکنید، باید مهاجرتهای ارائه شده را منتشر کرده و تغییر دهید تا با نام جدول مدل جایگزین شما مطابقت داشته باشد.
کلیدهای API
در مرحله بعد، باید کلیدهای Stripe خود را در
.env
فایل خود پیکربندی کنید.
می توانید کلیدهای Stripe API خود را از کنترل پنل Stripe بازیابی کنید.
STRIPE_KEY=your-stripe-keySTRIPE_SECRET=your-stripe-secret
پیکربندی ارز
واحد پول نقد پیش فرض دلار آمریکا (USD) است.
با تنظیم متغیر محیطی می توانید ارز پیش فرض را تغییر دهید
CASHIER_CURRENCY
:
CASHIER_CURRENCY=eur
علاوه بر پیکربندی واحد پول Cashier، میتوانید محلی را نیز تعیین کنید که
هنگام قالببندی مقادیر پول برای نمایش در فاکتورها استفاده شود.
در داخل، Cashier از
کلاس
PHP
NumberFormatter
برای تنظیم محلی ارز استفاده می کند:
CASHIER_CURRENCY_LOCALE=nl_BE
به منظور استفاده از زبانهای محلی به غیر از
en
، مطمئن شوید کهext-intl
پسوند PHP روی سرور شما نصب و پیکربندی شده است.
ورود به سیستم
Cashier به شما امکان می دهد کانال ورود به سیستم را مشخص کنید تا هنگام ثبت
تمام استثناهای مربوط به Stripe استفاده شود.
شما می توانید کانال ورود به سیستم را با استفاده از
CASHIER_LOGGER
متغیر محیطی مشخص کنید:
CASHIER_LOGGER=stack
مشتریان
بازیابی مشتریان
با استفاده از این روش میتوانید یک مشتری را با شناسه Stripe او بازیابی
کنید
Cashier::findBillable
.
این یک نمونه از مدل Billable را برمی گرداند:
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 ایجاد
می کند:
$stripeCustomer = $user->createOrGetStripeCustomer();
به روز رسانی مشتریان
گاهی اوقات، ممکن است بخواهید مشتری Stripe را مستقیماً با اطلاعات اضافی به
روز کنید.
شما می توانید این کار را با استفاده از
updateStripeCustomer
روش زیر انجام دهید:
$stripeCustomer = $user->updateStripeCustomer($options);
پورتال صورتحساب
Stripe
یک راه آسان برای راهاندازی یک پورتال صورتحساب
ارائه میدهد تا مشتری شما بتواند اشتراک، روشهای پرداخت خود را مدیریت
کند و سابقه صورتحساب خود را مشاهده کند.
redirectToBillingPortal
میتوانید با استفاده از روش کنترلکننده یا مسیر،
کاربران خود را به درگاه صورتحساب هدایت کنید :
use Illuminate\Http\Request; public function billingPortal(Request $request){ return $request->user()->redirectToBillingPortal();}
به طور پیش فرض، زمانی که کاربر مدیریت اشتراک خود را به پایان رساند، می
تواند به
home
مسیر برنامه شما بازگردد.
شما می توانید یک URL سفارشی ارائه کنید که کاربر باید با ارسال URL به
عنوان آرگومان برای
redirectToBillingPortal
متد، به آن بازگردد:
use Illuminate\Http\Request; public function billingPortal(Request $request){ return $request->user()->redirectToBillingPortal( route('billing') );}
اگر میخواهید فقط URL را به درگاه صورتحساب ایجاد کنید، میتوانید از
billingPortalUrl
روش زیر استفاده کنید:
$url = $user->billingPortalUrl(route('billing'));
روش های پرداخت
ذخیره سازی روش های پرداخت
برای ایجاد اشتراک یا انجام هزینههای «یکباره» با Stripe، باید یک روش پرداخت را ذخیره کرده و شناسه آن را از Stripe بازیابی کنید. رویکرد مورد استفاده برای انجام این کار بسته به اینکه آیا قصد دارید از روش پرداخت برای اشتراک یا هزینه تکی استفاده کنید متفاوت است، بنابراین در زیر هر دو را بررسی خواهیم کرد.
روش های پرداخت برای اشتراک
هنگام ذخیره کارت های اعتباری برای مشتری برای استفاده در آینده، Stripe
Setup Intents API باید برای جمع آوری ایمن جزئیات روش پرداخت مشتری استفاده شود.
یک "نیت راه اندازی" به Stripe نشان می دهد که قصد دارد از روش پرداخت مشتری
هزینه کند.
Billable
ویژگی
Cashier شامل
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
موجود در نمونه مدل Billable مجموعه ای از
Laravel\Cashier\PaymentMethod
نمونه ها را برمی گرداند:
$paymentMethods = $user->paymentMethods();
برای بازیابی روش پرداخت پیش فرض،
defaultPaymentMethod
ممکن است از روش زیر استفاده شود:
$paymentMethod = $user->defaultPaymentMethod();
همچنین میتوانید روش پرداخت خاصی را که متعلق به مدل Billable است با
استفاده از
findPaymentMethod
روش زیر بازیابی کنید:
$paymentMethod = $user->findPaymentMethod($paymentMethodId);
تعیین اینکه آیا کاربر یک روش پرداخت دارد
برای تعیین اینکه آیا یک مدل قابل صورتحساب یک روش پرداخت پیشفرض به حسابش
متصل است، از
hasDefaultPaymentMethod
روش زیر استفاده کنید:
if ($user->hasDefaultPaymentMethod()) { //}
برای تعیین اینکه آیا یک مدل قابل صورتحساب حداقل یک روش پرداخت به حساب
خود دارد یا خیر، از
hasPaymentMethod
روش زیر استفاده کنید:
if ($user->hasPaymentMethod()) { //}
به روز رسانی روش پرداخت پیش فرض
این
updateDefaultPaymentMethod
روش ممکن است برای بهروزرسانی اطلاعات روش پرداخت پیشفرض مشتری استفاده
شود.
این روش یک شناسه روش پرداخت Stripe را میپذیرد و روش پرداخت جدید را به
عنوان روش پرداخت صورتحساب پیشفرض اختصاص میدهد:
$user->updateDefaultPaymentMethod($paymentMethod);
برای همگامسازی اطلاعات روش پرداخت پیشفرض خود با اطلاعات روش پرداخت
پیشفرض مشتری در Stripe، میتوانید از این
updateDefaultPaymentMethodFromStripe
روش استفاده کنید:
$user->updateDefaultPaymentMethodFromStripe();
روش پرداخت پیشفرض برای مشتری فقط برای صدور صورتحساب و ایجاد اشتراکهای جدید قابل استفاده است. به دلیل محدودیت های Stripe، ممکن است برای شارژ تک استفاده نشود.
اضافه کردن روش های پرداخت
برای افزودن روش پرداخت جدید، میتوانید
addPaymentMethod
با ارسال شناسه روش پرداخت، با روش کاربر قابل پرداخت تماس بگیرید:
$user->addPaymentMethod($paymentMethod);
برای یادگیری نحوه بازیابی شناسههای روش پرداخت، لطفاً اسناد ذخیرهسازی روش پرداخت را مرور کنید .
حذف روش های پرداخت
برای حذف یک روش پرداخت، میتوانید
delete
روشی را که
Laravel\Cashier\PaymentMethod
میخواهید حذف کنید تماس بگیرید:
$paymentMethod->delete();
این
deletePaymentMethods
روش همه اطلاعات روش پرداخت را برای مدل قابل صورتحساب حذف میکند:
$user->deletePaymentMethods();
اگر کاربر اشتراک فعالی دارد، باید از حذف روش پرداخت پیشفرض خود جلوگیری کنید.
اشتراک ها
ایجاد اشتراک
برای ایجاد اشتراک، ابتدا نمونه ای از مدل قابل پرداخت خود را بازیابی کنید
که معمولاً نمونه ای از
App\User
.
هنگامی که نمونه مدل را بازیابی کردید، می توانید از
newSubscription
روش برای ایجاد اشتراک مدل استفاده کنید:
$user = User::find(1); $user->newSubscription('default', 'price_premium')->create($paymentMethod);
اولین آرگومان ارسال شده به
newSubscription
متد باید نام اشتراک باشد.
اگر برنامه شما فقط یک اشتراک ارائه می دهد، می توانید با این
default
یا تماس بگیرید
primary
.
آرگومان دوم، طرح خاصی است که کاربر در حال اشتراک در آن است.
این مقدار باید با شناسه قیمت طرح در Stripe مطابقت داشته باشد.
روشی
create
که
شناسه روش پرداخت Stripe
یا
PaymentMethod
شی Stripe را می پذیرد، اشتراک را آغاز می کند و همچنین پایگاه داده شما را
با شناسه مشتری و سایر اطلاعات صورتحساب مرتبط به روز می کند.
ارسال شناسه روش پرداخت به طور مستقیم به
create()
روش اشتراک نیز به طور خودکار آن را به روش های پرداخت ذخیره شده کاربر اضافه می کند.
مقادیر
اگر میخواهید هنگام ایجاد اشتراک، مقدار خاصی را برای طرح تعیین کنید،
میتوانید از
quantity
روش زیر استفاده کنید:
$user->newSubscription('default', 'price_monthly') ->quantity(5) ->create($paymentMethod);
توضیحات بیشتر
اگر میخواهید جزئیات اضافی مشتری یا اشتراک را مشخص کنید، میتوانید این
کار را با ارسال آنها به عنوان آرگومانهای دوم و سوم به روش انجام دهید
create
:
$user->newSubscription('default', 'price_monthly')->create($paymentMethod, [ 'email' => $email,], [ 'metadata' => ['note' => 'Some extra information.'],]);
برای کسب اطلاعات بیشتر در مورد فیلدهای اضافی پشتیبانی شده توسط Stripe، مستندات Stripe در مورد ایجاد مشتری و ایجاد اشتراک را بررسی کنید .
کوپن
اگر می خواهید هنگام ایجاد اشتراک کوپن اعمال کنید، می توانید از
withCoupon
روش زیر استفاده کنید:
$user->newSubscription('default', 'price_monthly') ->withCoupon('code') ->create($paymentMethod);
اضافه کردن اشتراک ها
اگر میخواهید اشتراکی را به مشتری اضافه کنید که قبلاً یک روش پرداخت
پیشفرض دارد، میتوانید
add
هنگام استفاده از
newSubscription
روش از این روش استفاده کنید:
$user = User::find(1); $user->newSubscription('default', 'price_premium')->add();
بررسی وضعیت اشتراک
هنگامی که یک کاربر در برنامه شما مشترک شد، می توانید به راحتی وضعیت
اشتراک او را با استفاده از روش های مختلف مناسب بررسی کنید.
ابتدا،
اگر کاربر اشتراک فعال داشته باشد،
subscribed
روش برمی گردد ، حتی اگر اشتراک در حال حاضر در دوره آزمایشی خود باشد:
true
if ($user->subscribed('default')) { //}
این
subscribed
روش همچنین یک کاندیدای عالی برای
میانافزار مسیر
است که به شما امکان میدهد دسترسی به مسیرها و کنترلکنندهها را بر اساس
وضعیت اشتراک کاربر فیلتر کنید:
public function handle($request, Closure $next){ 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()) { //}
این
subscribedToPlan
روش ممکن است برای تعیین اینکه آیا کاربر در یک طرح معین بر اساس شناسه قیمت
Stripe داده شده مشترک است یا خیر استفاده شود.
در این مثال، تعیین خواهیم کرد که آیا اشتراک کاربر
default
به طور فعال در
monthly
طرح مشترک است یا خیر:
if ($user->subscribedToPlan('price_monthly', 'default')) { //}
با ارسال یک آرایه به متد، می توانید تعیین کنید که آیا
اشتراک
subscribedToPlan
کاربر به طور فعال در طرح
یا
طرح مشترک است:
default
monthly
yearly
if ($user->subscribedToPlan(['price_monthly', 'price_yearly'], 'default')) { //}
این
recurring
روش ممکن است برای تعیین اینکه آیا کاربر در حال حاضر مشترک است و دیگر در
دوره آزمایشی خود نیست استفاده می شود:
if ($user->subscription('default')->recurring()) { //}
وضعیت اشتراک لغو شده
برای تعیین اینکه آیا کاربر زمانی مشترک فعال بوده است، اما اشتراک خود را
لغو کرده است، می توانید از
cancelled
روش زیر استفاده کنید:
if ($user->subscription('default')->cancelled()) { //}
همچنین میتوانید تعیین کنید که آیا یک کاربر اشتراک خود را لغو کرده است یا
خیر، اما هنوز در «دوره مهلت» خود است تا زمانی که اشتراک به طور کامل منقضی شود.
به عنوان مثال، اگر کاربری اشتراکی را در تاریخ 5 مارس لغو کند که در ابتدا
قرار بود در 10 مارس منقضی شود، کاربر تا 10 مارس در "مهلت مهلت" خود است.
توجه داشته باشید که
subscribed
روش همچنان
true
در این مدت باز می گردد:
if ($user->subscription('default')->onGracePeriod()) { //}
برای تعیین اینکه آیا کاربر اشتراک خود را لغو کرده است و دیگر در "دوره
مهلت" خود نیست، می توانید از
ended
روش زیر استفاده کنید:
if ($user->subscription('default')->ended()) { //}
محدوده های اشتراک
اکثر حالت های اشتراک نیز به عنوان محدوده پرس و جو در دسترس هستند، به طوری که می توانید به راحتی پایگاه داده خود را برای اشتراک هایی که در یک وضعیت خاص هستند پرس و جو کنید:
// Get all active subscriptions...$subscriptions = Subscription::query()->active()->get(); // Get all of the cancelled subscriptions for a user...$subscriptions = $user->subscriptions()->cancelled()->get();
لیست کاملی از دامنه های موجود در زیر موجود است:
Subscription::query()->active();Subscription::query()->cancelled();Subscription::query()->ended();Subscription::query()->incomplete();Subscription::query()->notCancelled();Subscription::query()->notOnGracePeriod();Subscription::query()->notOnTrial();Subscription::query()->onGracePeriod();Subscription::query()->onTrial();Subscription::query()->pastDue();Subscription::query()->recurring();
وضعیت ناقص و سررسید گذشته
اگر یک اشتراک پس از ایجاد به یک اقدام پرداخت ثانویه نیاز داشته باشد،
اشتراک به عنوان علامت گذاری می شود
incomplete
.
وضعیت اشتراک در
stripe_status
ستون جدول پایگاه داده صندوقدار ذخیره می شود
subscriptions
.
به طور مشابه، اگر هنگام تعویض طرحها، اقدام پرداخت ثانویه لازم باشد،
اشتراک بهعنوان علامتگذاری میشود
past_due
.
هنگامی که اشتراک شما در هر یک از این حالت ها باشد، تا زمانی که مشتری
پرداخت خود را تایید نکند، فعال نخواهد بود.
بررسی اینکه آیا یک اشتراک پرداخت ناقصی دارد میتواند با استفاده از
hasIncompletePayment
روش موجود در مدل Billable یا یک نمونه اشتراک انجام شود:
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
، می توانید از
keepPastDueSubscriptionsActive
روش ارائه شده توسط Cashier استفاده کنید.
register
به طور معمول، این روش باید در متد شما
فراخوانی شود
AppServiceProvider
:
use Laravel\Cashier\Cashier; /** * Register any application services. * * @return void */public function register(){ Cashier::keepPastDueSubscriptionsActive();}
هنگامی که یک اشتراک در
incomplete
وضعیتی است، تا زمانی که پرداخت تأیید نشده است، نمی توان آن را تغییر داد. بنابراین، متدهایswap
وupdateQuantity
زمانی که اشتراک در یک وضعیت باشد، استثنا ایجاد میکندincomplete
.
تغییر برنامه ها
پس از اینکه کاربر در برنامه شما مشترک شد، ممکن است گهگاه بخواهد به یک طرح
اشتراک جدید تغییر کند.
برای تعویض کاربر با یک اشتراک جدید، شناسه قیمت طرح را به
swap
روش ارسال کنید:
$user = App\User::find(1); $user->subscription('default')->swap('provider-price-id');
اگر کاربر در حالت آزمایشی باشد، دوره آزمایشی حفظ خواهد شد. همچنین، اگر "کمیتی" برای اشتراک وجود داشته باشد، آن مقدار نیز حفظ خواهد شد.
اگر میخواهید برنامهها را عوض کنید و هر دوره آزمایشی را که کاربر در حال
حاضر در آن است لغو کنید، میتوانید از
skipTrial
روش زیر استفاده کنید:
$user->subscription('default') ->skipTrial() ->swap('provider-price-id');
اگر میخواهید به جای اینکه برای چرخه صورتحساب بعدی کاربر منتظر بمانید،
برنامهها را مبادله کنید و فوراً فاکتور بگیرید، میتوانید از
swapAndInvoice
روش زیر استفاده کنید:
$user = App\User::find(1); $user->subscription('default')->swapAndInvoice('provider-price-id');
تناسب
بهطور پیشفرض، Stripe هنگام جابجایی بین طرحها، هزینهها را نسبت میدهد.
این
noProrate
روش ممکن است برای بهروزرسانی اشتراکها بدون نسبت هزینهها استفاده شود:
$user->subscription('default')->noProrate()->swap('provider-price-id');
برای اطلاعات بیشتر در مورد میزان اشتراک، به مستندات Stripe مراجعه کنید .
اجرای
noProrate
متد قبل ازswapAndInvoice
متد هیچ تاثیری بر proration ندارد. همیشه فاکتور صادر می شود.
مقدار اشتراک
گاهی اوقات اشتراک ها تحت تأثیر "کمیت" قرار می گیرند.
به عنوان مثال، برنامه شما ممکن است 10 دلار در ماه
برای هر کاربر
در یک حساب دریافت کند.
برای افزایش یا کاهش آسان تعداد اشتراک خود، از روش های
incrementQuantity
و استفاده کنید
decrementQuantity
:
$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 to the subscription's current quantity...$user->subscription('default')->decrementQuantity(5);
از طرف دیگر، میتوانید مقدار خاصی را با استفاده از
updateQuantity
روش زیر تنظیم کنید:
$user->subscription('default')->updateQuantity(10);
این
noProrate
روش ممکن است برای به روز رسانی مقدار اشتراک بدون نسبت هزینه ها استفاده
شود:
$user->subscription('default')->noProrate()->updateQuantity(10);
برای اطلاعات بیشتر در مورد مقدار اشتراک، به مستندات Stripe مراجعه کنید .
لطفاً توجه داشته باشید که هنگام کار با اشتراک های چندطرفه، یک پارامتر "طرح" اضافی برای روش های کمیت بالا مورد نیاز است.
اشتراک های چند پلان
اشتراک های Multiplan به شما امکان می دهد چندین طرح صورتحساب را به یک اشتراک اختصاص دهید. به عنوان مثال، تصور کنید که در حال ساختن یک برنامه کاربردی "helpdesk" برای خدمات مشتری هستید که اشتراک پایه آن 10 دلار در ماه است، اما یک برنامه افزودنی چت زنده را با 15 دلار اضافی در ماه ارائه می دهد:
$user = User::find(1); $user->newSubscription('default', [ 'price_monthly', 'chat-plan',])->create($paymentMethod);
اکنون مشتری دو طرح در
default
اشتراک خود خواهد داشت.
هزینه هر دو طرح در فواصل صورتحساب مربوطه دریافت می شود.
همچنین می توانید از
quantity
روش برای نشان دادن مقدار خاص برای هر طرح استفاده کنید:
$user = User::find(1); $user->newSubscription('default', ['price_monthly', 'chat-plan']) ->quantity(5, 'chat-plan') ->create($paymentMethod);
یا، می توانید طرح اضافی و مقدار آن را به صورت پویا با استفاده از
plan
روش اضافه کنید:
$user = User::find(1); $user->newSubscription('default', 'price_monthly') ->plan('chat-plan', 5) ->create($paymentMethod);
از طرف دیگر، میتوانید در فرصتی دیگر طرح جدیدی را به اشتراک موجود اضافه کنید:
$user = User::find(1); $user->subscription('default')->addPlan('chat-plan');
مثال بالا طرح جدید را اضافه می کند و مشتری در چرخه صورتحساب بعدی خود برای
آن صورتحساب دریافت می کند.
اگر می خواهید بلافاصله صورتحساب مشتری را دریافت کنید، می توانید از
addPlanAndInvoice
روش زیر استفاده کنید:
$user->subscription('default')->addPlanAndInvoice('chat-plan');
اگر میخواهید طرحی با کمیت خاص اضافه کنید، میتوانید مقدار را به عنوان
پارامتر دوم
addPlan
یا
addPlanAndInvoice
متدها ارسال کنید:
$user = User::find(1); $user->subscription('default')->addPlan('chat-plan', 5);
با استفاده از روش زیر می توانید طرح ها را از اشتراک ها حذف کنید
removePlan
:
$user->subscription('default')->removePlan('chat-plan');
نمی توانید آخرین طرح را در یک اشتراک حذف کنید. در عوض، شما باید به سادگی اشتراک را لغو کنید.
مبادله
همچنین میتوانید طرحهای پیوست شده به اشتراک چندطرفه را تغییر دهید.
basic-plan
به عنوان مثال، تصور کنید که در یک اشتراک با یک
chat-plan
افزونه
هستید و می خواهید به
pro-plan
برنامه ارتقا دهید:
$user = User::find(1); $user->subscription('default')->swap(['pro-plan', 'chat-plan']);
هنگام اجرای کد بالا، آیتم اشتراک زیرین با کد
basic-plan
حذف می شود و موردی که دارای آن است
chat-plan
حفظ می شود.
علاوه بر این، یک آیتم اشتراک جدید برای جدید
pro-plan
ایجاد می شود.
همچنین می توانید گزینه های مورد اشتراک را مشخص کنید. برای مثال، ممکن است لازم باشد مقادیر طرح اشتراک را مشخص کنید:
$user = User::find(1); $user->subscription('default')->swap([ 'pro-plan' => ['quantity' => 5], 'chat-plan']);
اگر میخواهید یک طرح واحد را با یک اشتراک عوض کنید، میتوانید این کار را
با استفاده از
swap
روش موجود در خود مورد اشتراک انجام دهید.
برای مثال اگر بخواهید تمام ابرداده های موجود در مورد اشتراک را حفظ کنید،
این رویکرد مفید است.
$user = User::find(1); $user->subscription('default') ->findItemOrFail('basic-plan') ->swap('pro-plan');
تناسب
بهطور پیشفرض، Stripe هنگام افزودن یا حذف طرحها از اشتراک، هزینهها را
نسبت میدهد.
اگر میخواهید یک تنظیم برنامه را بدون تناسب انجام دهید، باید این
noProrate
روش را به عملیات طرح خود زنجیره بزنید:
$user->subscription('default')->noProrate()->removePlan('chat-plan');
مقادیر
اگر میخواهید مقادیر را در طرحهای اشتراک فردی بهروزرسانی کنید، میتوانید این کار را با استفاده از روشهای کمیت موجود و ارسال نام طرح به عنوان آرگومان اضافی برای روش انجام دهید:
$user = User::find(1); $user->subscription('default')->incrementQuantity(5, 'chat-plan'); $user->subscription('default')->decrementQuantity(3, 'chat-plan'); $user->subscription('default')->updateQuantity(10, 'chat-plan');
وقتی چندین پلن را روی یک اشتراک تنظیم کنید، ویژگیها
stripe_plan
وquantity
ویژگیهایSubscription
مدل خواهد بودnull
. برای دسترسی به طرح های فردی، باید ازitems
رابطه موجود درSubscription
مدل استفاده کنید.
موارد اشتراک
هنگامی که یک اشتراک دارای چندین طرح است، چندین "اقلام" اشتراک در جدول
پایگاه داده شما ذخیره می شود
subscription_items
.
می توانید از طریق
items
رابطه موجود در اشتراک به این موارد دسترسی داشته باشید:
$user = User::find(1); $subscriptionItem = $user->subscription('default')->items->first(); // Retrieve the Stripe plan and quantity for a specific item...$stripePlan = $subscriptionItem->stripe_plan;$quantity = $subscriptionItem->quantity;
همچنین می توانید یک طرح خاص را با استفاده از
findItemOrFail
روش زیر بازیابی کنید:
$user = User::find(1); $subscriptionItem = $user->subscription('default')->findItemOrFail('chat-plan');
مالیات اشتراک
برای تعیین نرخهای مالیاتی که کاربر برای اشتراک میپردازد،
taxRates
روش را در مدل قابل پرداخت خود پیادهسازی کنید و آرایهای را با شناسههای
نرخ مالیات برگردانید.
می توانید این نرخ های مالیاتی را در
داشبورد Stripe خود
تعریف کنید :
public function taxRates(){ return ['tax-rate-id'];}
این
taxRates
روش به شما امکان می دهد نرخ مالیات را بر اساس مدل به مدل اعمال کنید، که
ممکن است برای یک پایگاه کاربری که چندین کشور و نرخ مالیات را در بر می گیرد مفید باشد.
اگر با اشتراکهای چندطرفه کار میکنید، میتوانید با پیادهسازی روشی
planTaxRates
در مدل قابل پرداخت خود، نرخهای مالیات متفاوتی را برای هر طرح تعریف کنید:
public function planTaxRates(){ return [ 'plan-id' => ['tax-rate-id'], ];}
این
taxRates
روش فقط برای هزینه های اشتراک اعمال می شود. اگر از Cashier برای ایجاد هزینههای «یکباره» استفاده میکنید، باید نرخ مالیات را در آن زمان به صورت دستی مشخص کنید.
همگام سازی نرخ های مالیاتی
هنگام تغییر شناسههای نرخ مالیاتی رمزگذاریشده بازگرداندهشده با
taxRates
روش، تنظیمات مالیاتی روی هر اشتراک موجود برای کاربر یکسان باقی میماند.
اگر میخواهید ارزش مالیات اشتراکهای موجود را با
taxTaxRates
مقادیر برگشتی بهروزرسانی کنید، باید
syncTaxRates
روش موجود در نمونه اشتراک کاربر را فراخوانی کنید:
$user->subscription('default')->syncTaxRates();
این همچنین نرخ مالیات آیتم های اشتراک را همگام می کند، بنابراین مطمئن
شوید که
planTaxRates
روش را نیز به درستی تغییر داده اید.
معافیت مالیاتی
Cashier همچنین روش هایی را برای تعیین معافیت مالیاتی مشتری با فراخوانی
Stripe API ارائه می دهد.
روش های
isNotTaxExempt
,
isTaxExempt
و
reverseChargeApplies
در مدل قابل صورتحساب موجود است:
$user = User::find(1); $user->isTaxExempt();$user->isNotTaxExempt();$user->reverseChargeApplies();
این روش ها بر روی هر شی نیز موجود است
Laravel\Cashier\Invoice
.
با این حال، هنگام فراخوانی این متدها بر روی یک
Invoice
شی، متدها وضعیت معافیت را در زمان ایجاد فاکتور تعیین می کنند.
تاریخ لنگر اشتراک
به طور پیشفرض، لنگر چرخه صورتحساب، تاریخی است که اشتراک ایجاد شده است،
یا اگر دوره آزمایشی استفاده میشود، تاریخی است که دوره آزمایشی به پایان میرسد.
اگر میخواهید تاریخ لنگر صورتحساب را تغییر دهید، میتوانید از
anchorBillingCycleOn
روش زیر استفاده کنید:
use App\User;use Carbon\Carbon; $user = User::find(1); $anchor = Carbon::parse('first day of next month'); $user->newSubscription('default', 'price_premium') ->anchorBillingCycleOn($anchor->startOfDay()) ->create($paymentMethod);
برای اطلاعات بیشتر در مورد مدیریت چرخههای صورتحساب اشتراک، به مستندات چرخه صورتحساب Stripe مراجعه کنید
لغو اشتراک ها
برای لغو اشتراک، با
cancel
روش موجود در اشتراک کاربر تماس بگیرید:
$user->subscription('default')->cancel();
هنگامی که یک اشتراک لغو می شود، صندوقدار به طور خودکار
ends_at
ستون را در پایگاه داده شما تنظیم می کند.
از این ستون برای دانستن زمان
subscribed
شروع بازگشت متد استفاده می شود
false
.
به عنوان مثال، اگر مشتری در تاریخ 1 مارس اشتراک خود را لغو کند، اما قرار
نبود اشتراک تا 5 مارس پایان یابد، این روش
تا 5 مارس
subscribed
ادامه خواهد داشت .
true
onGracePeriod
با استفاده از این روش
میتوانید تعیین کنید که آیا کاربر اشتراک خود را لغو کرده است اما هنوز در
«دوره مهلت» خود است :
if ($user->subscription('default')->onGracePeriod()) { //}
اگر می خواهید اشتراک را فوراً لغو کنید، با
cancelNow
روش موجود در اشتراک کاربر تماس بگیرید:
$user->subscription('default')->cancelNow();
از سرگیری اشتراک ها
اگر کاربری اشتراک خود را لغو کرده است و میخواهید آن را از سر بگیرید، از
این
resume
روش استفاده کنید.
کاربر
برای ازسرگیری اشتراک
باید همچنان در دوره مهلت خود باشد:
$user->subscription('default')->resume();
اگر کاربر اشتراکی را لغو کند و سپس آن اشتراک را قبل از انقضای کامل اشتراک از سر بگیرد، بلافاصله صورتحساب دریافت نخواهد شد. در عوض، اشتراک آنها مجدداً فعال می شود و در چرخه صورتحساب اصلی صورتحساب دریافت می شود.
آزمایشات اشتراک
با روش پرداخت از قبل
اگر میخواهید در حین جمعآوری اطلاعات روش پرداخت، دورههای آزمایشی را به
مشتریان خود ارائه دهید،
trialDays
هنگام ایجاد اشتراکهای خود باید از این روش استفاده کنید:
$user = User::find(1); $user->newSubscription('default', 'price_monthly') ->trialDays(10) ->create($paymentMethod);
این روش تاریخ پایان دوره آزمایشی را در سابقه اشتراک در پایگاه داده تنظیم
می کند، و همچنین به 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()) { //}
تعریف روزهای آزمایشی در Stripe / صندوقدار
میتوانید تعیین کنید که برنامه شما چند روز آزمایشی را در داشبورد Stripe
دریافت میکند یا همیشه آنها را با استفاده از Cashier به صراحت سپری کنید.
اگر تصمیم دارید روزهای آزمایشی طرح خود را در Stripe تعریف کنید، باید توجه
داشته باشید که اشتراکهای جدید، از جمله اشتراکهای جدید برای مشتری که در گذشته اشتراک داشتهاند، همیشه یک
دوره آزمایشی دریافت میکنند، مگر اینکه صریحاً با روش تماس بگیرید
trialDays(0)
.
بدون روش پرداخت از قبل
اگر میخواهید دورههای آزمایشی را بدون جمعآوری اطلاعات روش پرداخت کاربر
از قبل ارائه دهید، میتوانید ستون
trial_ends_at
روی سابقه کاربر را روی تاریخ پایان آزمایشی مورد نظر خود تنظیم کنید.
این معمولاً در هنگام ثبت نام کاربر انجام می شود:
$user = User::create([ // Populate other user properties... 'trial_ends_at' => now()->addDays(10),]);
حتماً یک تغییردهنده تاریخ برای
trial_ends_at
تعریف مدل خود اضافه کنید.
صندوقدار به این نوع آزمایش به عنوان یک "آزمایش عمومی" اشاره می کند، زیرا
به هیچ اشتراک موجود متصل نیست.
اگر تاریخ فعلی از مقدار زیر گذشته نباشد،
متد
onTrial
موجود در
User
نمونه برمیگردد
.
true
trial_ends_at
if ($user->onTrial()) { // User is within their trial period...}
onGenericTrial
همچنین اگر میخواهید به طور خاص بدانید که کاربر در دوره آزمایشی «عمومی»
خود است و هنوز اشتراک واقعی ایجاد نکرده است،
میتوانید از این روش استفاده کنید :
if ($user->onGenericTrial()) { // User is within their "generic" trial period...}
هنگامی که آماده ایجاد یک اشتراک واقعی برای کاربر هستید، می توانید
newSubscription
طبق معمول از روش زیر استفاده کنید:
$user = User::find(1); $user->newSubscription('default', 'price_monthly')->create($paymentMethod);
تمدید آزمایشات
این
extendTrial
روش به شما امکان می دهد دوره آزمایشی یک اشتراک را پس از ایجاد آن تمدید
کنید:
// 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 پیکربندی می شود. این کنترلر تمام درخواست های وب هوک دریافتی را رسیدگی می کند.
بهطور پیشفرض، این کنترلکننده بهطور خودکار لغو اشتراکهایی را که هزینههای ناموفق زیادی دارند (همانطور که تنظیمات Stripe شما تعریف کردهاند)، بهروزرسانیهای مشتری، حذفهای مشتری، بهروزرسانیهای اشتراک و تغییرات روش پرداخت را کنترل میکند. با این حال، همانطور که به زودی متوجه خواهیم شد، می توانید این کنترلر را برای مدیریت هر رویداد وب هوکی که دوست دارید گسترش دهید.
برای اطمینان از اینکه برنامه شما می تواند وب هوک های Stripe را مدیریت
کند، حتماً URL وب هوک را در کنترل پنل Stripe پیکربندی کنید.
به طور پیش فرض، کنترلر وب هوک Cashier به
/stripe/webhook
مسیر URL گوش می دهد.
لیست کامل تمام وبکهک هایی که باید در کنترل پنل Stripe پیکربندی کنید
عبارتند از:
-
customer.subscription.updated
-
customer.subscription.deleted
-
customer.updated
-
customer.deleted
-
invoice.payment_action_required
مطمئن شوید که از درخواستهای دریافتی با میانافزار تأیید امضای وبهوک شامل Cashier محافظت میکنید .
Webhooks & CSRF Protection
از آنجایی که وب هوک های Stripe باید
حفاظت CSRF
لاراول را دور بزنند ، حتماً URI را به عنوان یک استثنا در
VerifyCsrfToken
میان افزار خود فهرست کنید یا مسیر خارج از
web
گروه میان افزار را فهرست کنید:
protected $except = [ 'stripe/*',];
تعریف مدیریت رویداد Webhook
Cashier به طور خودکار لغو اشتراک را در صورت هزینه های ناموفق رسیدگی می
کند، اما اگر رویدادهای webhook دیگری دارید که می خواهید مدیریت کنید، کنترلر Webhook را گسترش دهید.
نام روشهای شما باید مطابق با قرارداد مورد انتظار Cashier باشد، بهویژه،
باید پیشوند روشها
handle
و نام «مورد شتر» وبقلابی باشد که میخواهید مدیریت کنید.
به عنوان مثال، اگر می خواهید
invoice.payment_succeeded
وب هوک را مدیریت کنید، باید یک
handleInvoicePaymentSucceeded
روش به کنترلر اضافه کنید:
<?php namespace App\Http\Controllers; use Laravel\Cashier\Http\Controllers\WebhookController as CashierController; class WebhookController extends CashierController{ /** * Handle invoice payment succeeded. * * @param array $payload * @return \Symfony\Component\HttpFoundation\Response */ public function handleInvoicePaymentSucceeded($payload) { // Handle The Event }}
در مرحله بعد، مسیری را برای کنترل صندوقدار خود در
routes/web.php
فایل خود تعریف کنید.
با این کار مسیر پیشفرض ارسال شده بازنویسی میشود:
Route::post( 'stripe/webhook', '\App\Http\Controllers\WebhookController@handleWebhook');
Cashier یک
Laravel\Cashier\Events\WebhookReceived
رویداد را هنگامی که یک وب هوک دریافت میکند، و یک
Laravel\Cashier\Events\WebhookHandled
رویداد زمانی که یک وب هوک توسط Cashier مدیریت میشود، منتشر میکند.
هر دو رویداد حاوی بار کامل وب هوک Stripe هستند.
اشتراک های ناموفق
اگر اعتبار کارت اعتباری مشتری منقضی شود چه می شود؟ نگران نباشید - کنترلر Cashier's Webhook اشتراک مشتری را برای شما لغو می کند. پرداختهای ناموفق بهطور خودکار توسط کنترلکننده ضبط و رسیدگی میشود. هنگامی که Stripe تشخیص دهد که اشتراک ناموفق بوده است، کنترل کننده اشتراک مشتری را لغو می کند (معمولاً پس از سه بار تلاش برای پرداخت ناموفق).
تأیید امضاهای Webhook
برای ایمن سازی وب هوک های خود، می توانید از امضاهای وب هوک Stripe استفاده کنید . برای راحتی، Cashier به طور خودکار یک میان افزار را شامل می شود که اعتبار درخواست وب هوک Stripe دریافتی را تأیید می کند.
برای فعال کردن تأیید وب هوک، مطمئن شوید که
STRIPE_WEBHOOK_SECRET
متغیر محیط در
.env
فایل شما تنظیم شده است.
وب هوک
secret
ممکن است از داشبورد حساب Stripe شما بازیابی شود.
شارژ تک
شارژ ساده
این
charge
روش مبلغی را میپذیرد که میخواهید با کمترین مخرج ارز استفاده شده توسط برنامه شما شارژ کنید .
اگر میخواهید برای روش پرداخت مشتری مشترک، هزینه «یکباره» اعمال کنید،
میتوانید از این
charge
روش در نمونه مدل قابل صورتحساب استفاده کنید.
شما باید
یک شناسه روش پرداخت را
به عنوان آرگومان دوم ارائه دهید:
// Stripe Accepts Charges In Cents...$stripeCharge = $user->charge(100, $paymentMethod);
این
charge
روش یک آرایه را به عنوان آرگومان سوم خود می پذیرد و به شما این امکان را
می دهد که هر گزینه ای را که می خواهید به ایجاد شارژ Stripe زیربنایی منتقل کنید.
با توجه به گزینه های موجود در هنگام ایجاد هزینه، با اسناد Stripe مشورت
کنید:
$user->charge(100, $paymentMethod, [ 'custom_option' => $value,]);
همچنین میتوانید از این
charge
روش بدون مشتری یا کاربر اصلی استفاده کنید:
use App\User; $stripeCharge = (new User)->charge(100, $paymentMethod);
این
charge
روش در صورت عدم موفقیت شارژ، یک استثنا ایجاد می کند.
در صورت موفقیت آمیز بودن شارژ، نمونه ای
Laravel\Cashier\Payment
از متد برگردانده می شود:
try { $payment = $user->charge(100, $paymentMethod);} catch (Exception $e) { //}
شارژ با فاکتور
گاهی اوقات ممکن است نیاز داشته باشید که یک بار شارژ کنید، اما یک فاکتور
برای شارژ تهیه کنید تا بتوانید یک رسید PDF به مشتری خود ارائه دهید.
این
invoiceFor
روش به شما امکان می دهد این کار را انجام دهید.
به عنوان مثال، بیایید 5.00 دلار برای یک «هزینه یک بار مصرف» به مشتری
فاکتور کنیم:
// Stripe Accepts Charges In Cents...$user->invoiceFor('One Time Fee', 500);
فاکتور بلافاصله بر اساس روش پرداخت پیش فرض کاربر کسر می شود.
متد
invoiceFor
همچنین یک آرایه را به عنوان آرگومان سوم خود می پذیرد.
این آرایه شامل گزینه های صورتحساب برای مورد فاکتور است.
آرگومان چهارم پذیرفته شده توسط متد نیز یک آرایه است.
این آرگومان نهایی گزینههای صورتحساب را برای خود فاکتور میپذیرد:
$user->invoiceFor('Stickers', 500, [ 'quantity' => 50,], [ 'default_tax_rates' => ['tax-rate-id'],]);
این
invoiceFor
روش یک فاکتور Stripe ایجاد میکند که تلاشهای صورتحساب ناموفق را دوباره امتحان میکند. اگر نمیخواهید فاکتورها هزینههای ناموفق را دوباره امتحان کنند، باید آنها را با استفاده از Stripe API پس از اولین شارژ ناموفق ببندید.
هزینه های بازپرداخت
اگر نیاز به بازپرداخت هزینه Stripe دارید، میتوانید از این
refund
روش استفاده کنید.
این روش شناسه هدف پرداخت Stripe را به عنوان اولین آرگومان خود می پذیرد:
$payment = $user->charge(100, $paymentMethod); $user->refund($payment->id);
فاکتورها
بازیابی فاکتورها
می توانید به راحتی آرایه ای از فاکتورهای یک مدل قابل پرداخت را با استفاده
از
invoices
روش زیر بازیابی کنید:
$invoices = $user->invoices(); // Include pending invoices in the results...$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>
تولید پی دی اف فاکتور
از داخل یک مسیر یا کنترلر، از
downloadInvoice
روشی برای ایجاد دانلود PDF فاکتور استفاده کنید.
این روش به طور خودکار پاسخ HTTP مناسب را برای ارسال دانلود به مرورگر
ایجاد می کند:
use Illuminate\Http\Request; Route::get('user/invoice/{invoice}', function (Request $request, $invoiceId) { return $request->user()->downloadInvoice($invoiceId, [ 'vendor' => 'Your Company', 'product' => 'Your Product', ]);});
این
downloadInvoice
روش همچنین اجازه می دهد تا نام فایل سفارشی اختیاری را به عنوان پارامتر
سوم انتخاب کنید.
.pdf
این نام فایل به طور خودکار برای شما
پسوند می شود :
return $request->user()->downloadInvoice($invoiceId, [ 'vendor' => 'Your Company', 'product' => 'Your Product',], 'my-invoice');
رسیدگی به پرداخت های ناموفق
گاهی اوقات، پرداخت برای اشتراک یا هزینه های تکی ممکن است با شکست مواجه
شود.
وقتی این اتفاق میافتد، Cashier استثنایی میاندازد
IncompletePayment
که به شما اطلاع میدهد که این اتفاق افتاده است.
پس از گرفتن این استثنا، شما دو گزینه در مورد نحوه ادامه دارید.
ابتدا، می توانید مشتری خود را به صفحه تأیید پرداخت اختصاصی که همراه
صندوقدار است هدایت کنید.
این صفحه در حال حاضر دارای یک مسیر مرتبط است که از طریق ارائه دهنده خدمات
Cashier ثبت شده است.
بنابراین، می توانید
IncompletePayment
استثنا را بگیرید و به صفحه تأیید پرداخت هدایت شوید:
use Laravel\Cashier\Exceptions\IncompletePayment; try { $subscription = $user->newSubscription('default', $planId) ->create($paymentMethod);} catch (IncompletePayment $exception) { return redirect()->route( 'cashier.payment', [$exception->payment->id, 'redirect' => route('home')] );}
در صفحه تأیید پرداخت، از مشتری خواسته میشود تا اطلاعات کارت اعتباری خود
را دوباره وارد کند و هرگونه اقدام اضافی مورد نیاز Stripe، مانند تأیید «3D Secure» را انجام دهد.
پس از تایید پرداخت، کاربر به URL ارائه شده توسط
redirect
پارامتر مشخص شده در بالا هدایت می شود.
پس از تغییر مسیر، متغیرهای رشته پرس و جو
message
(رشته) و
success
(عدد صحیح) به URL اضافه می شوند.
از طرف دیگر، میتوانید به Stripe اجازه دهید تا تأیید پرداخت را برای شما
انجام دهد.
در این حالت، به جای هدایت مجدد به صفحه تأیید پرداخت، میتوانید
ایمیلهای صورتحساب خودکار Stripe را
در داشبورد Stripe خود تنظیم کنید.
با این حال، اگر
IncompletePayment
استثنایی مشخص شود، همچنان باید به کاربر اطلاع دهید که یک ایمیل با
دستورالعملهای تأیید پرداخت بیشتر دریافت خواهد کرد.
استثناهای پرداخت ممکن است برای روش های زیر اعمال شود:
charge
,
invoiceFor
و
invoice
بر روی
Billable
کاربر.
هنگام مدیریت اشتراکها،
create
متدهای موجود در و
و
SubscriptionBuilder
متدهای
روی
مدل ممکن است استثناهایی ایجاد کنند.
incrementAndInvoice
swapAndInvoice
Subscription
در حال حاضر دو نوع استثناء پرداخت وجود دارد که گسترش می یابد
IncompletePayment
.
در صورت نیاز میتوانید این موارد را به طور جداگانه دریافت کنید تا بتوانید
تجربه کاربری را سفارشی کنید:
-
PaymentActionRequired
: این نشان می دهد که Stripe برای تأیید و پردازش پرداخت نیاز به تأیید بیشتری دارد. -
PaymentFailure
: این نشان می دهد که یک پرداخت به دلایل مختلف دیگر مانند کمبود وجوه موجود شکست خورده است.
احراز هویت قوی مشتری
اگر کسب و کار شما در اروپا مستقر است، باید از قوانین تأیید هویت قوی مشتری (SCA) پیروی کنید. این مقررات در سپتامبر 2019 توسط اتحادیه اروپا برای جلوگیری از تقلب در پرداخت وضع شد. خوشبختانه، Stripe و Cashier برای ساخت برنامه های سازگار با SCA آماده شده اند.
قبل از شروع، راهنمای Stripe در مورد PSD2 و SCA و همچنین مستندات آنها در مورد APIهای جدید SCA را مرور کنید .
پرداخت هایی که نیاز به تایید اضافی دارند
مقررات SCA معمولاً برای تأیید و پردازش پرداخت نیاز به تأیید اضافی دارند.
وقتی این اتفاق میافتد، Cashier استثنایی ایجاد میکند
PaymentActionRequired
که به شما اطلاع میدهد که این تأیید اضافی لازم است.
اطلاعات بیشتر در مورد نحوه رسیدگی به این استثناها را
در اینجا
پیدا کنید .
وضعیت ناقص و سررسید گذشته
هنگامی که پرداخت نیاز به تأیید اضافی دارد، اشتراک در وضعیت
incomplete
یا
past_due
وضعیتی باقی میماند که در ستون پایگاه داده آن نشان داده شده است
stripe_status
.
صندوق دار به محض تکمیل تایید پرداخت، اشتراک مشتری را از طریق وب هوک به
طور خودکار فعال می کند.
برای اطلاعات بیشتر در مورد
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]);
آزمایش کردن
هنگام آزمایش برنامهای که از Cashier استفاده میکند، ممکن است درخواستهای HTTP واقعی به Stripe API را تقلید کنید. با این حال، این مستلزم آن است که تا حدی رفتار خود Cashier را مجدداً اجرا کنید. بنابراین، توصیه میکنیم به تستهای شما اجازه دهید به Stripe API واقعی برسند. اگرچه این سرعت کندتر است، اما اطمینان بیشتری به شما می دهد که برنامه شما همانطور که انتظار می رود کار می کند و هر آزمایش کند ممکن است در گروه آزمایش PHPUnit خودش قرار گیرد.
هنگام آزمایش، به یاد داشته باشید که خود صندوق دار قبلاً مجموعه آزمایشی عالی دارد، بنابراین باید فقط روی آزمایش جریان اشتراک و پرداخت برنامه خود تمرکز کنید و نه هر رفتار زیربنایی صندوقدار.
برای شروع، نسخه
آزمایشی
راز Stripe خود را به
phpunit.xml
فایل خود اضافه کنید:
<env name="STRIPE_SECRET" value="sk_test_<your-key>"/>
اکنون، هر زمان که هنگام آزمایش با Cashier تعامل داشته باشید، درخواستهای API واقعی را به محیط تست Stripe شما ارسال میکند. برای راحتی، باید حساب آزمایشی Stripe خود را از قبل با اشتراک ها / طرح هایی پر کنید که می توانید در طول آزمایش از آنها استفاده کنید.
به منظور آزمایش انواع سناریوهای صورتحساب، مانند رد کردن و خرابی کارت اعتباری، میتوانید از طیف وسیعی از شمارهها و نشانههای کارت تست ارائه شده توسط Stripe استفاده کنید.