الفرق بين المراجعتين لصفحة: «Laravel/billing»
أنشأ الصفحة ب'== مقدمة == يقدم Laravel Cashier واجهة قويّة لاشتراكات خدمات الفواتير Stripe و Braintree، وهي تعالج تقريبًا ك...' |
رؤيا-بنعطية (نقاش | مساهمات) لا ملخص تعديل |
||
(14 مراجعة متوسطة بواسطة مستخدمين اثنين آخرين غير معروضة) | |||
سطر 1: | سطر 1: | ||
<noinclude>{{DISPLAYTITLE:Laravel Cashier}}</noinclude> | |||
== مقدمة == | == مقدمة == | ||
يقدم Laravel Cashier واجهة قويّة لاشتراكات خدمات الفواتير Stripe و Braintree، وهي تعالج تقريبًا كل شيفرات boilerplate الخاصة باشتراك الفواتير التي تخشى من كتابتها، وبالإضافة إلى إدارة الاشتراكات الأساسية، يستطيع Cashier التعامل مع القسائم (coupons)، ومبادلة الاشتراكات وكميّات الاشتراكات وفترات السماح بالإلغاء وحتى إنشاء ملفات PDF للفواتير. | يقدم Laravel Cashier واجهة قويّة لاشتراكات خدمات الفواتير Stripe و Braintree، وهي تعالج تقريبًا كل شيفرات boilerplate الخاصة باشتراك الفواتير التي تخشى من كتابتها، وبالإضافة إلى إدارة الاشتراكات الأساسية، يستطيع Cashier التعامل مع القسائم (coupons)، ومبادلة الاشتراكات وكميّات الاشتراكات وفترات السماح بالإلغاء وحتى إنشاء ملفات PDF للفواتير. | ||
سطر 15: | سطر 16: | ||
==== تهجير قواعد البيانات ==== | ==== تهجير قواعد البيانات ==== | ||
قبل استخدام Cashier، سنحتاج أيضًا إلى إعداد قاعدة البيانات، وذلك عن طريق إضافة عدة أعمدة إلى جدول users وإنشاء جدول subscriptions جديد لاحتواء جميع اشتراكات عملائنا:<syntaxhighlight lang="php"> | قبل استخدام Cashier، سنحتاج أيضًا إلى إعداد قاعدة البيانات، وذلك عن طريق إضافة عدة أعمدة إلى جدول <code>users</code> وإنشاء جدول <code>subscriptions</code> جديد لاحتواء جميع اشتراكات عملائنا:<syntaxhighlight lang="php"> | ||
Schema::table('users', function ($table) { | Schema::table('users', function ($table) { | ||
$table->string('stripe_id')->nullable(); | $table->string('stripe_id')->nullable(); | ||
سطر 36: | سطر 37: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
بمجرّد إنشاء التهجيرات، شغّل أمر <code> | بمجرّد إنشاء التهجيرات، شغّل أمر <code>migrate</code> Artisan. | ||
=== نموذج Billable === | === نموذج Billable === | ||
بعد ذلك، أضف سمة Billable إلى تعريف نموذجك، توفّر هذه السمة طرقًا مختلفة تسمح لك بتنفيذ مهام الفوترة الشائعة، كإنشاء الاشتراكات وتطبيق القسائم وتحديث بيانات بطاقة الائتمان:<syntaxhighlight lang="php3"> | بعد ذلك، أضف سمة <code>Billable</code> إلى تعريف نموذجك، توفّر هذه السمة طرقًا مختلفة تسمح لك بتنفيذ مهام الفوترة الشائعة، كإنشاء الاشتراكات وتطبيق القسائم وتحديث بيانات بطاقة الائتمان:<syntaxhighlight lang="php3"> | ||
use Laravel\Cashier\Billable; | use Laravel\Cashier\Billable; | ||
سطر 49: | سطر 50: | ||
==== مفاتيح الواجهة البرمجيّة API ==== | ==== مفاتيح الواجهة البرمجيّة API ==== | ||
ختامًا، يجب عليك ضبط مفتاح Stripe في ملف الضبط services. | ختامًا، يجب عليك ضبط مفتاح Stripe في ملف الضبط <code>services.php</code>، ويمكنك استرداد مفاتيح Stripe API من لوحة تحكم Stripe:<syntaxhighlight lang="php"> | ||
'stripe' => [ | 'stripe' => [ | ||
'model' => App\User::class, | 'model' => App\User::class, | ||
سطر 61: | سطر 62: | ||
==== تحذيرات Braintree ==== | ==== تحذيرات Braintree ==== | ||
تعمل تطبيقات Stripe و Braintree بنفس الطريقة في عدة عمليات، فكلاهما يوفران فوترة الاشتراك ببطاقات الائتمان لكن يدعم Braintree | تعمل تطبيقات Stripe و Braintree بنفس الطريقة في عدة عمليات، فكلاهما يوفران فوترة الاشتراك ببطاقات الائتمان لكن يدعم Paypal Braintree أيضًا، ومع ذلك، يفتقر Braintree إلى بعض المميزات المدعومة من Stripe، ويجب عليك مراعاة ما يلي عند اتخاذ قرار استخدام Stripe أو Braintree: | ||
* يدعم Braintree | * يدعم Paypal Braintree على عكس Stripe. | ||
* لا يدعم Braintree توابع الزيادة والنقصان على الاشتراكات، وهذه حدود Braintree وليست حدود Cashier. | * لا يدعم Braintree توابع الزيادة والنقصان على الاشتراكات، وهذه حدود Braintree وليست حدود Cashier. | ||
سطر 84: | سطر 85: | ||
==== تهجير قواعد البيانات ==== | ==== تهجير قواعد البيانات ==== | ||
قبل استخدام Cashier، سنحتاج إلى إعداد قاعدة البيانات، وذلك عن طريق إضافة عدة أعمدة إلى جدول users و إنشاء جدول subscriptions جديد لاحتواء جميع اشتراكات عملائنا:<syntaxhighlight lang="php"> | قبل استخدام Cashier، سنحتاج إلى إعداد قاعدة البيانات، وذلك عن طريق إضافة عدة أعمدة إلى جدول <code>users</code> و إنشاء جدول <code>subscriptions</code> جديد لاحتواء جميع اشتراكات عملائنا:<syntaxhighlight lang="php"> | ||
Schema::table('users', function ($table) { | Schema::table('users', function ($table) { | ||
$table->string('braintree_id')->nullable(); | $table->string('braintree_id')->nullable(); | ||
سطر 106: | سطر 107: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
بمجرّد إنشاء التهجيرات، شغّل أمر Artisan | بمجرّد إنشاء التهجيرات، شغّل أمر <code>migrate</code> Artisan. | ||
==== نموذج Billable ==== | ==== نموذج <code>Billable</code> ==== | ||
بعد ذلك، أضف سمة <code>Billable</code> إلى تعريف نموذجك:<syntaxhighlight lang="php"> | بعد ذلك، أضف سمة <code>Billable</code> إلى تعريف نموذجك:<syntaxhighlight lang="php"> | ||
use Laravel\Cashier\Billable; | use Laravel\Cashier\Billable; | ||
سطر 120: | سطر 121: | ||
=== مفاتيح الواجهة البرمجيّة API === | === مفاتيح الواجهة البرمجيّة API === | ||
ختامًا، يجب عليك ضبط الخيارات التاليّة في ملف الضبط services.php:<syntaxhighlight lang="php"> | ختامًا، يجب عليك ضبط الخيارات التاليّة في ملف الضبط <code>services.php</code>:<syntaxhighlight lang="php"> | ||
'braintree' => [ | 'braintree' => [ | ||
'model' => App\User::class, | 'model' => App\User::class, | ||
سطر 130: | سطر 131: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
ثم يجب عليك إضافة استدعاءات حزمة برمجيات التطوير Braintree SDK التالية إلى تابع boot الخاص بموفّر الخدمة AppServiceProvider: | ثم يجب عليك إضافة استدعاءات حزمة برمجيات التطوير Braintree SDK التالية إلى تابع boot الخاص بموفّر الخدمة AppServiceProvider:<syntaxhighlight lang="php"> | ||
\Braintree_Configuration::environment(config('services.braintree.environment')); | \Braintree_Configuration::environment(config('services.braintree.environment')); | ||
\Braintree_Configuration::merchantId(config('services.braintree.merchant_id')); | \Braintree_Configuration::merchantId(config('services.braintree.merchant_id')); | ||
\Braintree_Configuration::publicKey(config('services.braintree.public_key')); | \Braintree_Configuration::publicKey(config('services.braintree.public_key')); | ||
\Braintree_Configuration::privateKey(config('services.braintree.private_key')); | \Braintree_Configuration::privateKey(config('services.braintree.private_key')); | ||
</syntaxhighlight> | |||
==== ضبط العملة ==== | |||
العملة الافتراضية لـ Cashier هي الدولار الأمريكي (USD)، ويمكنك تغيير العملة الافتراضيّة باستدعاء تابع <code>Cashier::useCurrency</code> من داخل تابع <code>boot</code> من أحد موفرّي الخدمة. | |||
يقبل تابع <code>useCurrency</code> سلستين نصيتيّن كمعاملات: العملة ورمز العملة:<syntaxhighlight lang="php"> | |||
use Laravel\Cashier\Cashier; | use Laravel\Cashier\Cashier; | ||
Cashier::useCurrency('eur', '€'); | Cashier::useCurrency('eur', '€'); | ||
</syntaxhighlight> | |||
الاشتراكات | == الاشتراكات == | ||
=== إنشاء الاشتراكات === | |||
لإنشاء اشتراك، استردّ نسخة من نموذج <code>billable</code> والتي ستكون عادةً نسخة من <code>App\User</code>، وبمجرد استرداد نسخة النموذج، يمكنك استخدام تابع <code>newSubscription</code> لإنشاء اشتراك النموذج:<syntaxhighlight lang="php"> | |||
$user = User::find(1); | $user = User::find(1); | ||
$user->newSubscription('main', 'premium')->create($stripeToken); | $user->newSubscription('main', 'premium')->create($stripeToken); | ||
</syntaxhighlight> | |||
يجب أن يكون المعامل الأول الممرّر إلى تابع newSubscription هو اسم الاشتراك، إذا كان تطبيقك يوفّر نوع واحد من الاشتراكات، يمكنك تسميته main أو primary، وأما المعامل الثاني فهو تحديد خطة Stripe أو Braintree التي يشترك فيها المستخدم، ويجب أن تتوافق هذه القيمة مع معرّف Stripe أو Braintree. | يجب أن يكون المعامل الأول الممرّر إلى تابع newSubscription هو اسم الاشتراك، إذا كان تطبيقك يوفّر نوع واحد من الاشتراكات، يمكنك تسميته main أو primary، وأما المعامل الثاني فهو تحديد خطة Stripe أو Braintree التي يشترك فيها المستخدم، ويجب أن تتوافق هذه القيمة مع معرّف Stripe أو Braintree. | ||
سيبدأ | سيبدأ التابع <code>create</code>، والذي يقبل بطاقة ائتمان أو رمز مصدر Stripe، الاشتراك بالإضافة إلى تحديث قاعدة بياناتك بمعرّف العميل ومعلومات الفوترة ذات الصلة. | ||
==== بيانات المستخدم إضافيّة ==== | |||
إذا كنت ترغب في تحديد تفاصيل إضافيّة للعميل، فيمكنك القيام بذلك عن طريق تمريرها كمعامل ثاني إلى التابع <code>create</code>:<syntaxhighlight lang="php"> | |||
$user->newSubscription('main', 'monthly')->create($stripeToken, [ | $user->newSubscription('main', 'monthly')->create($stripeToken, [ | ||
'email' => $email, | |||
]); | ]); | ||
</syntaxhighlight> | |||
لمعرفة المزيد حول الحقول الإضافية المدعومة بواسطة Stripe أو Braintree، راجع توثيق Stripe حول إنشاء العميل أو توثيق Braintree المشابهة. | لمعرفة المزيد حول الحقول الإضافية المدعومة بواسطة Stripe أو Braintree، راجع توثيق Stripe حول إنشاء العميل أو توثيق Braintree المشابهة. | ||
القسائم | === القسائم === | ||
إذا رغبت في تطبيق قسيمة عند إنشاء الاشتراك، فيمكنك استخدام تابع <code>withCoupon</code>:<syntaxhighlight lang="php"> | |||
إذا رغبت في تطبيق قسيمة عند إنشاء الاشتراك، فيمكنك استخدام تابع withCoupon: | |||
$user->newSubscription('main', 'monthly') | $user->newSubscription('main', 'monthly') | ||
->withCoupon('code') | |||
->create($stripeToken); | |||
</syntaxhighlight> | |||
=== التحقق من حالة الاشتراك === | |||
بمجرد اشتراك المستخدم بتطبيقك، يمكنك التحقق بسهولة من حالة الاشتراك باستخدام مجموعة متنوعة من التوابع المناسبة، فالتابع <code>subscribed</code> يرجع <code>true</code> إذا كان للمستخدم اشتراك نشط، وحتى إذا كان الاشتراك حاليًا ضمن الفترة التجريبيّة:<syntaxhighlight lang="php"> | |||
if ($user->subscribed('main')) { | if ($user->subscribed('main')) { | ||
// | |||
} | } | ||
</syntaxhighlight> | |||
إن التابع subscribed هو مرشح رائع لبرمجيّة وسيطة للمسار، فهو يسمح لك بترشيح الوصول إلى المسارات ووحدات التحكم بناءًا على حالة اشتراك المستخدم: | إن التابع <code>subscribed</code> هو مرشح رائع لبرمجيّة وسيطة للمسار، فهو يسمح لك بترشيح الوصول إلى المسارات ووحدات التحكم بناءًا على حالة اشتراك المستخدم:<syntaxhighlight lang="php"> | ||
public function handle($request, Closure $next) | public function handle($request, Closure $next) | ||
{ | { | ||
if ($request->user() && ! $request->user()->subscribed('main')) { | |||
// This user is not a paying customer... | |||
return redirect('billing'); | |||
} | |||
return $next($request); | |||
} | } | ||
</syntaxhighlight> | |||
إذا أردت تحديد ما إذا كان المستخدم ما يزال ضمن الفترة التجريبيّة، فيمكنك استخدام التابع | إذا أردت تحديد ما إذا كان المستخدم ما يزال ضمن الفترة التجريبيّة، فيمكنك استخدام التابع <code>onTrial</code>، ويمكنك استخدام هذا التابع لعرض تحذير للمستخدم بأنه ما يزال في الفترة التجريبيّة الخاصة به:<syntaxhighlight lang="php"> | ||
if ($user->subscription('main')->onTrial()) { | if ($user->subscription('main')->onTrial()) { | ||
// | |||
} | } | ||
</syntaxhighlight> | |||
يمكن استخدام التابع subscribedToPlan لتحديد ما إذا كان المستخدم مشتركًا بخطة معينة بناءً على معرّف الخطة في Stripe / Braintree، وفي هذا المثال، سنحدد ما إذا كان الاشتراك main للمستخدم مفعّل للخطة الشهريّة: | يمكن استخدام التابع <code>subscribedToPlan</code> لتحديد ما إذا كان المستخدم مشتركًا بخطة معينة بناءً على معرّف الخطة في Stripe / Braintree، وفي هذا المثال، سنحدد ما إذا كان الاشتراك main للمستخدم مفعّل للخطة الشهريّة:<syntaxhighlight lang="php"> | ||
if ($user->subscribedToPlan('monthly', 'main')) { | if ($user->subscribedToPlan('monthly', 'main')) { | ||
// | |||
} | } | ||
</syntaxhighlight> | |||
حالة الاشتراك الملغى | ==== حالة الاشتراك الملغى ==== | ||
لتحديد ما إذا كان المستخدم مشتركًا نشيطًا سابقًا ولكنه ألغى اشتراكه، يمكنك استخدام تابع <code>cancelled</code>:<syntaxhighlight lang="php"> | |||
لتحديد ما إذا كان المستخدم مشتركًا نشيطًا سابقًا ولكنه ألغى اشتراكه، يمكنك استخدام تابع cancelled: | |||
if ($user->subscription('main')->cancelled()) { | if ($user->subscription('main')->cancelled()) { | ||
// | |||
} | } | ||
</syntaxhighlight> | |||
يمكنك أيضًا تحديد ما إذا كان المستخدم قد ألغى اشتراكه ولكنه لا يزال في فترة "السماح" حتى انتهاء صلاحيّة اشتراكه بالكامل، فعلى سبيل المثال، إذا الغى المستخدم اشتراكه في الخامس من شهر آذار/مارس والذي من المقرر في الأصل أن تنتهي صلاحيته في 10 من آذار/مارس، فسيكون المستخدم في فترة "السماح" حتى 10 من آذار/مارس، ولاحظ أن | يمكنك أيضًا تحديد ما إذا كان المستخدم قد ألغى اشتراكه ولكنه لا يزال في فترة "السماح" حتى انتهاء صلاحيّة اشتراكه بالكامل، فعلى سبيل المثال، إذا الغى المستخدم اشتراكه في الخامس من شهر آذار/مارس والذي من المقرر في الأصل أن تنتهي صلاحيته في 10 من آذار/مارس، فسيكون المستخدم في فترة "السماح" حتى 10 من آذار/مارس، ولاحظ أن التابع <code>subscribed</code> سيرجع <code>true</code> في هذه الحالة:<syntaxhighlight lang="php"> | ||
if ($user->subscription('main')->onGracePeriod()) { | if ($user->subscription('main')->onGracePeriod()) { | ||
// | |||
} | } | ||
</syntaxhighlight> | |||
تغيير الخطط | === تغيير الخطط === | ||
قد يرغب المستخدم بعد اشتراك في تطبيقك في تغييره إلى خطة اشتراك جديدة، ولاستبدال اشتراك جديد باشتراك المستخدم الحالي، مرّر معرّف الخطة إلى التابع <code>swap</code>:<syntaxhighlight lang="php"> | |||
قد يرغب المستخدم بعد اشتراك في تطبيقك في تغييره إلى خطة اشتراك جديدة، ولاستبدال اشتراك جديد باشتراك المستخدم الحالي، مرّر معرّف الخطة إلى | |||
$user = App\User::find(1); | $user = App\User::find(1); | ||
$user->subscription('main')->swap('provider-plan-id'); | $user->subscription('main')->swap('provider-plan-id'); | ||
</syntaxhighlight> | |||
إذا كان المستخدم قيد الإصدار التجريبي، فسيُحتفظ بالفترة التجريبيّة أيضًا وإذا كان هنالك كميّة للاشتراك، فسيُحتفظ بتلك الكميّة quantity أيضًا. | إذا كان المستخدم قيد الإصدار التجريبي، فسيُحتفظ بالفترة التجريبيّة أيضًا وإذا كان هنالك كميّة للاشتراك، فسيُحتفظ بتلك الكميّة quantity أيضًا. | ||
إذا أردت مبادلة الخطط وإلغاء أي فترة تجريبيّة للمستخدم قيد التشغيل حاليًا، فيمكنك استخدام التابع skipTrial: | إذا أردت مبادلة الخطط وإلغاء أي فترة تجريبيّة للمستخدم قيد التشغيل حاليًا، فيمكنك استخدام التابع <code>skipTrial</code>:<syntaxhighlight lang="php"> | ||
$user->subscription('main') | $user->subscription('main') | ||
->skipTrial() | |||
->swap('provider-plan-id'); | |||
</syntaxhighlight> | |||
=== كميّة الاشتراك === | |||
تنبيه: كميّة الاشتراك مدعومة فقط من نسخة Stripe من Cashier، فلا يملك Braintree خاصيّة تتوافق مع "كميّة" Stripe. | تنبيه: كميّة الاشتراك مدعومة فقط من نسخة Stripe من Cashier، فلا يملك Braintree خاصيّة تتوافق مع "كميّة" Stripe. | ||
تتأثر في بعض الأحيان الاشتراكات بالكميّة، فعلى سبيل المثال، إذا كان يتقاضى تطبيقك 10 دولارات شهريًا للمستخدم على الحساب، فلزيادة أو نقصان كميّة الاشتراك بسهولة، يمكنك استخدام التوابع incrementQuantity وdecrementQuantity: | تتأثر في بعض الأحيان الاشتراكات بالكميّة، فعلى سبيل المثال، إذا كان يتقاضى تطبيقك 10 دولارات شهريًا للمستخدم على الحساب، فلزيادة أو نقصان كميّة الاشتراك بسهولة، يمكنك استخدام التوابع <code>incrementQuantity</code> <code>وdecrementQuantity</code>:<syntaxhighlight lang="php"> | ||
$user = User::find(1); | $user = User::find(1); | ||
سطر 259: | سطر 249: | ||
// Add five to the subscription's current quantity... | // Add five to the subscription's current quantity... | ||
$user->subscription('main')->incrementQuantity(5); | $user->subscription('main')->incrementQuantity(5); | ||
سطر 265: | سطر 254: | ||
// Subtract five to the subscription's current quantity... | // Subtract five to the subscription's current quantity... | ||
$user->subscription('main')->decrementQuantity(5); | $user->subscription('main')->decrementQuantity(5); | ||
</syntaxhighlight> | |||
يمكنك بدلًا من ذلك تعيين كميّة محددة باستخدام التابع updateQuantity: | يمكنك بدلًا من ذلك تعيين كميّة محددة باستخدام التابع <code>updateQuantity</code>:<syntaxhighlight lang="php"> | ||
$user->subscription('main')->updateQuantity(10); | $user->subscription('main')->updateQuantity(10); | ||
</syntaxhighlight> | |||
يمكنك استخدام التابع noProrate لتحديث كميّة الاشتراك دون تقييم الرسوم: | يمكنك استخدام التابع <code>noProrate</code> لتحديث كميّة الاشتراك دون تقييم الرسوم:<syntaxhighlight lang="php"> | ||
$user->subscription('main')->noProrate()->updateQuantity(10); | $user->subscription('main')->noProrate()->updateQuantity(10); | ||
</syntaxhighlight> | |||
للمزيد من المعلومات حول كميّات الاشتراك، راجع توثيق Stripe. | للمزيد من المعلومات حول كميّات الاشتراك، راجع توثيق Stripe. | ||
رسوم الاشتراك | === رسوم الاشتراك === | ||
لتحديد نسبة الرسوم للمستخدم على الاشتراك، طبّق التابع <code>taxPercentage</code> على نموذج <code>billable</code> الخاص بك، وأرجع قيمة رقميّة بين 0 و 100، مع عدم وجود أكثر من منزلتين عشريتين.<syntaxhighlight lang="php"> | |||
لتحديد نسبة الرسوم للمستخدم على الاشتراك، طبّق التابع taxPercentage على نموذج billable الخاص بك، وأرجع قيمة رقميّة بين 0 و 100، مع عدم وجود أكثر من منزلتين عشريتين. | |||
public function taxPercentage() { | public function taxPercentage() { | ||
return 20; | |||
} | } | ||
</syntaxhighlight> | |||
يمكّنك التابع taxPercentage من تطبيق معدّل الرسوم على أساسيات نموذج بنموذج model-by-model، والذي قد يكون مفيدًا لقاعدة المستخدمين التي تغطي الكثير من البلدان ومعدلات الرسوم. | يمكّنك التابع <code>taxPercentage</code> من تطبيق معدّل الرسوم على أساسيات نموذج بنموذج model-by-model، والذي قد يكون مفيدًا لقاعدة المستخدمين التي تغطي الكثير من البلدان ومعدلات الرسوم. | ||
تنبيه: لا يطبّق التابع taxPercentage على رسوم الاشتراك فقط، فإذا استخدمت Cashier لتحصيل رسوم دفعة واحدة، فستحتاج إلى تعديد معدل الرسوم يدويًا في ذلك الوقت. | تنبيه: لا يطبّق التابع <code>taxPercentage</code> على رسوم الاشتراك فقط، فإذا استخدمت Cashier لتحصيل رسوم دفعة واحدة، فستحتاج إلى تعديد معدل الرسوم يدويًا في ذلك الوقت. | ||
=== إلغاء الاشتراكات === | |||
لإلغاء اشتراك، استدع التابع <code>cancel</code> على اشتراك المستخدم:<syntaxhighlight lang="php"> | |||
$user->subscription('main')->cancel(); | $user->subscription('main')->cancel(); | ||
</syntaxhighlight> | |||
عند إلغاء الاشتراك، سيعيّن Cashier بشكل تلقائي عمود ends_at في قاعدة بياناتك، وسيُستخدم هذا العمود لمعرفة متى يجب على التابع subscribed إرجاع القيمة | عند إلغاء الاشتراك، سيعيّن Cashier بشكل تلقائي عمود <code>ends_at</code> في قاعدة بياناتك، وسيُستخدم هذا العمود لمعرفة متى يجب على التابع <code>subscribed</code> إرجاع القيمة <code>false</code>، فعلى سبيل المثال، إذا ألغى عميل اشتراكه في الأول من مارس،ولم يكن من المقرر أن ينتهي الاشتراك حتى الخامس من مارس، فسيبقى التابع <code>subscribed</code> يرجع <code>true</code> حتى تاريخ 5 مارس. | ||
يمكنك تحديد ما إذا كان المستخدم قد ألغى اشتراكه ولكن لا يزال في فترة "السماح" عن طريق استخدام التابع <code>onGracePeriod</code>:<syntaxhighlight lang="php"> | |||
if ($user->subscription('main')->onGracePeriod()) { | if ($user->subscription('main')->onGracePeriod()) { | ||
// | |||
} | } | ||
</syntaxhighlight> | |||
إذا رغبت في إنهاء الاشتراك فورًا، فاستدع التابع cancelNow على اشتراك المستخدم: | إذا رغبت في إنهاء الاشتراك فورًا، فاستدع التابع <code>cancelNow</code> على اشتراك المستخدم:<syntaxhighlight lang="php"> | ||
$user->subscription('main')->cancelNow(); | $user->subscription('main')->cancelNow(); | ||
</syntaxhighlight> | |||
استئناف الاشتراكات | === استئناف الاشتراكات === | ||
إذا ألغى مستخدم اشتراكه ويرغب في استئنافه استخدم التابع <code>resume</code>، ويجب على المستخدم أن يظل في فترة السماح لاستئناف اشتراكه:<syntaxhighlight lang="php"> | |||
إذا ألغى مستخدم اشتراكه ويرغب في استئنافه استخدم التابع | |||
$user->subscription('main')->resume(); | $user->subscription('main')->resume(); | ||
</syntaxhighlight> | |||
إذا ألغى مستخدم اشتراكه ثم استأنفه قبل انتهاء صلاحيّة الاشتراك بالكامل فلن يحاسب على الفور، وبدلًا من ذلك، سيعاد تنشيط اشتراكه وسيحاسب على دورة الفوترة الأصليّة. | إذا ألغى مستخدم اشتراكه ثم استأنفه قبل انتهاء صلاحيّة الاشتراك بالكامل فلن يحاسب على الفور، وبدلًا من ذلك، سيعاد تنشيط اشتراكه وسيحاسب على دورة الفوترة الأصليّة. | ||
تحديث بطاقات الائتمان | === تحديث بطاقات الائتمان === | ||
يمكن استخدام التابع <code>updateCard</code> لتحديث معلومات بطاقة ائتمان العميل، ويقبل هذا التابع رمز Stripe وسيعيّن بطاقة الائتمان الجديدة المصدر الافتراضي للفوترة:<syntaxhighlight lang="php"> | |||
يمكن استخدام التابع updateCard لتحديث معلومات بطاقة ائتمان العميل، ويقبل هذا التابع رمز Stripe وسيعيّن بطاقة الائتمان الجديدة المصدر الافتراضي للفوترة: | $user->updateCard($stripeToken); | ||
</syntaxhighlight> | |||
== الفترات التجريبيّة للاشتراكات == | |||
=== مع واجهة بطاقة الائتمان === | |||
إذا كنت ترغب في توفير فترات تجريبيّة لعملائك مع الاستمرار في جمع معلومات طريقة الدفع، يجب عليك استخدام التابع <code>trialDays</code> عند إنشائك للاشتراك:<syntaxhighlight lang="php"> | |||
$user = User::find(1); | $user = User::find(1); | ||
$user->newSubscription('main', 'monthly') | $user->newSubscription('main', 'monthly') | ||
->trialDays(10) | |||
->create($stripeToken); | |||
</syntaxhighlight> | |||
سيحدد هذا التابع تاريخ انتهاء الفترة التجريبيّة في سجل الاشتراك داخل قاعدة البيانات، بالإضافة إلى إرشاد Stripe أو Braintree إلى عدم البدء في إعداد فواتير للعميل إلى ما بعد هذا التاريخ. | سيحدد هذا التابع تاريخ انتهاء الفترة التجريبيّة في سجل الاشتراك داخل قاعدة البيانات، بالإضافة إلى إرشاد Stripe أو Braintree إلى عدم البدء في إعداد فواتير للعميل إلى ما بعد هذا التاريخ. | ||
تنبيه: إذا لم يلغي العميل اشتراكه قبل انتهاء الفترة التجريبيّة فسُتفرض الرسوم فور انتهاء الفترة التجريبيّة، لذلك يجب عليك التأكد من إبلاغ المستخدمين بتاريخ انتهاء الفترة التجريبيّة. | تنبيه: إذا لم يلغي العميل اشتراكه قبل انتهاء الفترة التجريبيّة فسُتفرض الرسوم فور انتهاء الفترة التجريبيّة، لذلك يجب عليك التأكد من إبلاغ المستخدمين بتاريخ انتهاء الفترة التجريبيّة. | ||
يتيح لك التابع trialUntil توفير نسخة DateTime لتحديد موعد انتهاء الفترة التجريبيّة: | يتيح لك التابع <code>trialUntil</code> توفير نسخة <code>DateTime</code> لتحديد موعد انتهاء الفترة التجريبيّة:<syntaxhighlight lang="php"> | ||
use Carbon\Carbon; | use Carbon\Carbon; | ||
$user->newSubscription('main', 'monthly') | $user->newSubscription('main', 'monthly') | ||
->trialUntil(Carbon::now()->addDays(10)) | |||
->create($stripeToken); | |||
</syntaxhighlight> | |||
يمكنك معرفة ما إذا كان المستخدم في فترته التجريبيّة أو لا إما باستخدام التابع <code>onTrial</code> على نسخة المستخدم أو باستخدام التابع <code>onTrial</code> على نسخة الاشتراك، فالمثالان التاليان متطابقان:<syntaxhighlight lang="php"> | |||
if ($user->onTrial('main')) { | if ($user->onTrial('main')) { | ||
// | |||
} | } | ||
if ($user->subscription('main')->onTrial()) { | if ($user->subscription('main')->onTrial()) { | ||
// | |||
} | } | ||
</syntaxhighlight> | |||
بدون واجهة بطاقة الائتمان | === بدون واجهة بطاقة الائتمان === | ||
إذا كنت ترغب في تقديم فترات تجريبيّة دون جمع معلومات عن طريقة دفع المستخدم، يمكنك تعيين عمود <code>trial_ends_at</code> في سجل المستخدم بناءً على تاريخ انتهاء الإصدار التجريبي المطلوب، ويتم ذلك عادةً أثناء تسجيل المستخدم:<syntaxhighlight lang="php"> | |||
إذا كنت ترغب في تقديم فترات تجريبيّة دون جمع معلومات عن طريقة دفع المستخدم، يمكنك تعيين عمود trial_ends_at في سجل المستخدم بناءً على تاريخ انتهاء الإصدار التجريبي المطلوب، ويتم ذلك عادةً أثناء تسجيل المستخدم: | |||
$user = User::create([ | $user = User::create([ | ||
// ملأ بقية خصائص المستخدم | |||
'trial_ends_at' => now()->addDays(10), | |||
]); | ]); | ||
</syntaxhighlight> | |||
تنبيه: تأكد من إضافة تاريخ لـ trial_ends_at لتعريف النموذج. | تنبيه: تأكد من إضافة تاريخ لـ <code>trial_ends_at</code> لتعريف النموذج. | ||
يشير Cashier إلى نوع الفترة التجريبيّة على أنها "تجربة عامة"، نظرًا لأنه غير مرتبط بأي اشتراك حالي، وسيُرجع التابع <code>onTrial</code> في نسخة <code>User</code> القيمة <code>true</code> إذا لم يتجاوز التاريخ الحالي قيمة <code>trial_ends_at</code>:<syntaxhighlight lang="php"> | |||
if ($user->onTrial()) { | if ($user->onTrial()) { | ||
// المستخدم في الفترة التجريبية | |||
} | } | ||
</syntaxhighlight> | |||
يمكنك أيضًا استخدام التابع onGenericTrial إذا أردت معرفة على وجه التحديد أن المستخدم ضمن فترة النسخة التجريبيّة العامة ولم ينشئ اشتراكًا فعليًّا بعد: | يمكنك أيضًا استخدام التابع <code>onGenericTrial</code> إذا أردت معرفة على وجه التحديد أن المستخدم ضمن فترة النسخة التجريبيّة العامة ولم ينشئ اشتراكًا فعليًّا بعد:<syntaxhighlight lang="php"> | ||
if ($user->onGenericTrial()) { | if ($user->onGenericTrial()) { | ||
// المستخدم في الفترة التجريبية العامة | |||
} | } | ||
</syntaxhighlight> | |||
بمجرّد استعدادك لإنشاء اشتراك فعلي للمستخدم، يمكنك استخدام التابع newSubscription كالمعتاد: | بمجرّد استعدادك لإنشاء اشتراك فعلي للمستخدم، يمكنك استخدام التابع <code>newSubscription</code> كالمعتاد:<syntaxhighlight lang="php"> | ||
$user = User::find(1); | $user = User::find(1); | ||
$user->newSubscription('main', 'monthly')->create($stripeToken); | $user->newSubscription('main', 'monthly')->create($stripeToken); | ||
</syntaxhighlight> | |||
معالجة | == معالجة خطاطيف الويب في Stripe == | ||
يمكن لكل من Stripe وBraintree إعلام تطبيقك بمجموعة من الأحداث عبر خطاطيف الويب (webhooks)، ولمعالجة خطاطيف الويب في Stripe، يجب عليك تعريف المسار الذي يشير إلى وحدة تحكم خطّاف الويب الخاص بـ Cashier، وستُعالج وحدة التحكم هذه جميع طلبات خطّاف الويب الواردة وترسلها إلى تابع وحدة التحكم المناسب:<syntaxhighlight lang="php"> | |||
يمكن لكل من Stripe وBraintree إعلام تطبيقك بمجموعة من الأحداث عبر | |||
Route::post( | Route::post( | ||
'stripe/webhook', | |||
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook' | |||
); | |||
</syntaxhighlight> | |||
تنبيه: بمجرّد تسجيل الطريق الخاص بك، تأكد من تكوين عنوان خطاف ويب webhook URL في إعدادات لوحة تحكم Stripe. | تنبيه: بمجرّد تسجيل الطريق الخاص بك، تأكد من تكوين عنوان خطاف ويب webhook URL في إعدادات لوحة تحكم Stripe. | ||
سطر 400: | سطر 381: | ||
بشكل افتراضي، ستتعامل وحدة التحكم تلقائيًا مع إلغاء الاشتراكات التي تحتوي على عدد كبير من محاولات الحصول على الرسوم الفاشلة (كما هو محدد بواسطة إعدادات Stripe)، ومع ذلك، كما سنكتشف قريبًا، يمكننا توسيع وحدة التحكم للتعامل مع أي حدث خطاف ويب ترغب به. | بشكل افتراضي، ستتعامل وحدة التحكم تلقائيًا مع إلغاء الاشتراكات التي تحتوي على عدد كبير من محاولات الحصول على الرسوم الفاشلة (كما هو محدد بواسطة إعدادات Stripe)، ومع ذلك، كما سنكتشف قريبًا، يمكننا توسيع وحدة التحكم للتعامل مع أي حدث خطاف ويب ترغب به. | ||
=== خطاطيف الويب وحماية CSRF === | |||
نظرًا لأن خطاطيف ويب Stripe تحتاج إلى تجاوز [[Laravel/csrf|حماية CSRF]] الخاصة بإطار Laravel، تأكد من وضع عنوان URI كاستثناء في البرمجيّة الوسيطة <code>VerifyCsrfToken</code> الخاصة بك أو ضع المسار خارج مجموعة البرمجيّة الوسيطة web:<syntaxhighlight lang="php"> | |||
نظرًا لأن | |||
protected $except = [ | protected $except = [ | ||
'stripe/*', | |||
]; | ]; | ||
</syntaxhighlight> | |||
تعريف معالجات أحداث | === تعريف معالجات أحداث خطاطيف الويب === | ||
سيتعامل Cashier بشكل تلقائي بإلغاء الاشتراك عند فشل شحن المبلغ، لكن إذا كان لديك أحداث خطاطيف ويب Stripe ترغب في معالجتها، فوسّع وحدة التحكم خطّاف الويب ويجب أن تكون أسماء التوابع متطابقة مع اتفاقيّة Cashier المتوقعة، والتي تنصّ على أنه يجب أن تبدأ بالكلمة handle وتستخدم حالة سِنَام الجمل (camelCase) لاسم خطّاف الويب الذي ترغب في معالجته. فعلى سبيل المثال، إذا كنت ترغب في معالجة خطاف الويب الخاص بالخطاف <code>invoice.payment_succeeded</code> فيجب عليك إضافة التابع <code>handleInvoicePaymentSucceeded</code> إلى وحدة التحكم:<syntaxhighlight lang="php"> | |||
سيتعامل Cashier بشكل تلقائي بإلغاء الاشتراك عند فشل شحن المبلغ، لكن إذا كان لديك أحداث | |||
<?php | <?php | ||
سطر 419: | سطر 397: | ||
class WebhookController extends CashierController | class WebhookController extends CashierController | ||
{ | { | ||
/** | |||
* التعامل مع خطاطيف الويب. | |||
* | |||
* @param مصفوفة $payload | |||
* @return Response | |||
*/ | |||
public function handleInvoicePaymentSucceeded($payload) | |||
{ | |||
// معالجة الحدث | |||
} | |||
} | } | ||
</syntaxhighlight> | |||
بعد ذلك، حدد المسار إلى وحدة التحكم Cashier داخل ملف routes/web.php: | بعد ذلك، حدد المسار إلى وحدة التحكم Cashier داخل ملف <code>routes/web.php</code>:<syntaxhighlight lang="php"> | ||
Route::post( | Route::post( | ||
'stripe/webhook', | |||
'\App\Http\Controllers\WebhookController@handleWebhook' | |||
); | ); | ||
</syntaxhighlight> | |||
اشتراكات فاشلة | === اشتراكات فاشلة === | ||
ماذا لو انتهت صلاحيّة بطاقة ائتمان العميل؟ لا تقلق! يحتوي Cashier على وحدة تحكم خطاف ويب يمكنها إلغاء اشتراك العميل بسهولة. | ماذا لو انتهت صلاحيّة بطاقة ائتمان العميل؟ لا تقلق! يحتوي Cashier على وحدة تحكم خطاف ويب يمكنها إلغاء اشتراك العميل بسهولة. | ||
وكما ذُكِر أعلاه، كل ما عليك القيام به هو توجيه المسار إلى وحدة التحكم: | وكما ذُكِر أعلاه، كل ما عليك القيام به هو توجيه المسار إلى وحدة التحكم:<syntaxhighlight lang="php"> | ||
Route::post( | Route::post( | ||
'stripe/webhook', | |||
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook' | |||
); | ); | ||
</syntaxhighlight> | |||
وهذا كل شيء، ستُلتقط المدفوعات الفاشلة وتُعالج عن طريق وحدة التحكم، وستلغي وحدة التحكم اشتراك العميل عندما يعلن Stripe فشل الاشتراك (عادةً بعد ثلاث محاولات دفع فاشلة). | وهذا كل شيء، ستُلتقط المدفوعات الفاشلة وتُعالج عن طريق وحدة التحكم، وستلغي وحدة التحكم اشتراك العميل عندما يعلن Stripe فشل الاشتراك (عادةً بعد ثلاث محاولات دفع فاشلة). | ||
معالجة | == معالجة خطاطيف الويب في Braintree == | ||
يمكن لكل من Stripe وBraintree إعلام تطبيقك بمجموعة من الأحداث عبر خطاطيف الويب، ولمعالجة خطاطيف ويب Braintree، يجب عليك تعريف المسار الذي يشير إلى وحدة تحكم خطّاف الويب الخاص بـ Cashier، وستعالج وحدة التحكم هذه جميع طلبات خطّاف الويب الواردة وترسلها إلى تابع وحدة التحكم المناسب:<syntaxhighlight lang="php"> | |||
يمكن لكل من Stripe وBraintree إعلام تطبيقك بمجموعة من الأحداث عبر | |||
Route::post( | Route::post( | ||
'braintree/webhook', | |||
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook' | |||
); | ); | ||
</syntaxhighlight> | |||
تنبيه: بمجرّد تسجيل المسار الخاص بك، تأكد من إنشاء عنوان خطاف ويب webhook URL في إعدادات لوحة تحكم Braintree. | تنبيه: بمجرّد تسجيل المسار الخاص بك، تأكد من إنشاء عنوان خطاف ويب webhook URL في إعدادات لوحة تحكم Braintree. | ||
سطر 478: | سطر 442: | ||
بشكل افتراضي، ستتعامل وحدة التحكم هذه تلقائيًا مع إلغاء الاشتراكات التي تحتوي على عدد كبير من محاولات الحصول على الرسوم الفاشلة (كما هو محدد بواسطة إعدادات Braintree)، ومع ذلك، كما سنكتشف قريبًا، يمكننا توسيع وحدة التحكم للتعامل مع أي حدث خطّاف ويب ترغب به. | بشكل افتراضي، ستتعامل وحدة التحكم هذه تلقائيًا مع إلغاء الاشتراكات التي تحتوي على عدد كبير من محاولات الحصول على الرسوم الفاشلة (كما هو محدد بواسطة إعدادات Braintree)، ومع ذلك، كما سنكتشف قريبًا، يمكننا توسيع وحدة التحكم للتعامل مع أي حدث خطّاف ويب ترغب به. | ||
خطاطيف الويب وحماية CSRF | === خطاطيف الويب وحماية CSRF === | ||
نظرًا لأن خطاطيف ويب Braintree تحتاج إلى تجاوز [[Laravel/csrf|حماية CSRF]] الخاصة بإطار [[Laravel]]، فتأكد من وضع URI كاستثناء في وسيطة <code>VerifyCsrfToken</code> الخاصة بك أو ضع مسار خارج مجموعة وسيطة web:<syntaxhighlight lang="php"> | |||
نظرًا لأن Braintree | |||
protected $except = [ | protected $except = [ | ||
'braintree/*', | |||
]; | ]; | ||
</syntaxhighlight> | |||
تعريف معالجات أحداث | === تعريف معالجات أحداث خطاطيف الويب === | ||
سيتعامل Cashier بشكل تلقائي بإلغاء الاشتراك عند فشل شحن المبلغ، لكن إذا كان لديك أحداث Braintree خطّاف ويب ترغب في معالجتها، فوسّع وحدة التحكم خطّاف الويب ويجب أن تكون أسماء التوابع متطابقة مع اتفاقيّة Cashier المتوقعة، والتي تنصّ على أنه يجب أن تبدأ بالكلمة handle وتستخدم حالة سِنَام الجمل (camelCase) لاسم خطّاف الويب الذي ترغب في معالجته. فعلى سبيل المثال، إذا كنت ترغب في التعامل مع خطّاف الويب <code>dispute_opened</code> فيجب عليك إضافة التابع <code>handleDisputeOpened</code> إلى وحدة التحكم:<syntaxhighlight lang="php"> | |||
سيتعامل Cashier بشكل تلقائي بإلغاء الاشتراك عند فشل شحن المبلغ، لكن إذا كان لديك أحداث Braintree خطّاف ويب ترغب في معالجتها، فوسّع وحدة التحكم خطّاف الويب ويجب أن تكون أسماء التوابع متطابقة مع اتفاقيّة Cashier المتوقعة، والتي تنصّ على أنه يجب أن تبدأ بالكلمة handle وتستخدم حالة سِنَام الجمل (camelCase) لاسم خطّاف الويب الذي ترغب في معالجته. فعلى سبيل المثال، إذا كنت ترغب في التعامل مع خطّاف الويب dispute_opened فيجب عليك إضافة التابع handleDisputeOpened إلى وحدة التحكم: | |||
<?php | <?php | ||
سطر 495: | سطر 456: | ||
use Braintree\WebhookNotification; | use Braintree\WebhookNotification; | ||
use Laravel\Cashier\Http\Controllers\WebhookController as CashierController; | use Laravel\Cashier\Http\Controllers\WebhookController as CashierController; | ||
class WebhookController extends CashierController | class WebhookController extends CashierController | ||
{ | { | ||
/** | |||
* التعامل مع خطّافي Braintree. | |||
* | |||
* @param WebhookNotification $webhook | |||
* @return Response | |||
*/ | |||
public function handleDisputeOpened(WebhookNotification $notification) | |||
{ | |||
// Handle The Event | |||
} | |||
} | } | ||
</syntaxhighlight> | |||
اشتراكات فاشلة | === اشتراكات فاشلة === | ||
ماذا لو انتهت صلاحيّة بطاقة ائتمان العميل؟ لا تقلق! يحتوي Cashier على وحدة التحكم خطّاف الويب الذي يمكنه إلغاء اشتراك العميل بسهول. | ماذا لو انتهت صلاحيّة بطاقة ائتمان العميل؟ لا تقلق! يحتوي Cashier على وحدة التحكم خطّاف الويب الذي يمكنه إلغاء اشتراك العميل بسهول. | ||
وكما ذكر أعلاه، كل ما عليك القيام به هو توجيه المسار إلى وحدة التحكم: | وكما ذكر أعلاه، كل ما عليك القيام به هو توجيه المسار إلى وحدة التحكم:<syntaxhighlight lang="php"> | ||
Route::post( | Route::post( | ||
'braintree/webhook', | |||
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook' | |||
); | ); | ||
</syntaxhighlight> | |||
وهذا كل شيء، ستُلتقط المدفوعات الفاشلة وتُعالج عن طريق وحدة التحكم، وستلغى وحدة التحكم اشتراك العميل عندما يعرّف Braintree بفشل الاشتراك (عادةً بعد ثلاث محاولات دفع فاشلة). لا تنس أنك بحاجة إلى إعداد عنوان خطّاف الويب webhook URI في إعدادات لوحة تحكم Braintree الخاصة بك. | وهذا كل شيء، ستُلتقط المدفوعات الفاشلة وتُعالج عن طريق وحدة التحكم، وستلغى وحدة التحكم اشتراك العميل عندما يعرّف Braintree بفشل الاشتراك (عادةً بعد ثلاث محاولات دفع فاشلة). لا تنس أنك بحاجة إلى إعداد عنوان خطّاف الويب webhook URI في إعدادات لوحة تحكم Braintree الخاصة بك. | ||
رسوم واحدة | == رسوم واحدة == | ||
=== رسم بسيط === | |||
تنبيه: عند استخدام Stripe، سيقبل التابع <code>charge</code> المقدار الذي ترغب في خصمه في أدنى مقام للعملة المستخدمة في طلب اشتراكك، ومع ذلك، عند استخدام Braintree، يجب عليك تمرير المبلغ الكامل بالدولار إلى التابع <code>charge</code>: | |||
إذا كنت ترغب في إجراء دفعة واحدة لبطاقة ائتمان أحد العملاء المشتركين، فيمكنك استخدام التابع <code>charge</code> على نسخة نموذج <code>Billable</code>.<syntaxhighlight lang="php"> | |||
// centsتقبل الدفعات بال Stripe | |||
$user->charge(100); | $user->charge(100); | ||
// | //Dollarsتقبل الدفعات بال Braitree | ||
$user->charge(1); | $user->charge(1); | ||
</syntaxhighlight> | |||
يقبل التابع charge مصفوفة كمعامل ثاني مما يسمح لك بتمرير أي خيارات ترغب في تضمينها لرسوم إنشاء Stripe / Braintree، راجع توثيقات Stripe أو Braintree المتعلقة بالخيارات المتاحة لك عند إنشاء الرسوم: | يقبل التابع <code>charge</code> مصفوفة كمعامل ثاني مما يسمح لك بتمرير أي خيارات ترغب في تضمينها لرسوم إنشاء Stripe / Braintree، راجع توثيقات Stripe أو Braintree المتعلقة بالخيارات المتاحة لك عند إنشاء الرسوم:<syntaxhighlight lang="php"> | ||
$user->charge(100, [ | $user->charge(100, [ | ||
'custom_option' => $value, | |||
]); | ]); | ||
</syntaxhighlight> | |||
سيرمي التابع charge استثناء إذا فشلت عمليّة الشحن، وإذا نجحت، فستعاد إجابة Stripe أو Braintree كاملة من التابع: | سيرمي التابع <code>charge</code> استثناء إذا فشلت عمليّة الشحن، وإذا نجحت، فستعاد إجابة Stripe أو Braintree كاملة من التابع:<syntaxhighlight lang="php"> | ||
try { | try { | ||
$response = $user->charge(100); | |||
} catch (Exception $e) { | } catch (Exception $e) { | ||
// | |||
} | } | ||
</syntaxhighlight> | |||
الشحن مع الفاتورة | === الشحن مع الفاتورة === | ||
قد تحتاج في بعض الأحيان إلى تحصيل رسوم لمرة واحدة ولكن ترغب أيضًا في إنشاء فاتورة لتحصيل الرسوم حتى تتمكن من تقديم إيصال بصيغة PDF إلى عميلك، يسمح لك التابع <code>invoiceFor</code> بذلك. فعلى سبيل المثال، لنفرض على العميل رسوم 5.00$ لمرة واحدة:<syntaxhighlight lang="php"> | |||
قد تحتاج في بعض الأحيان إلى تحصيل رسوم لمرة واحدة ولكن ترغب أيضًا في إنشاء فاتورة لتحصيل الرسوم حتى تتمكن من تقديم إيصال بصيغة PDF إلى عميلك، يسمح لك التابع invoiceFor بذلك. فعلى سبيل المثال، لنفرض على العميل رسوم 5.00$ لمرة واحدة: | // centsتقبل الدفعات بال Stripe | ||
// Stripe | |||
$user->invoiceFor('One Time Fee', 500); | $user->invoiceFor('One Time Fee', 500); | ||
// | // dollarsتقبل الدفعات بال Braitree | ||
$user->invoiceFor('One Time Fee', 5); | $user->invoiceFor('One Time Fee', 5); | ||
</syntaxhighlight> | |||
ستفرض الفاتورة على الفور على بطاقة ائتمان المستخدم، يقبل التابع invoiceFor مصفوفة كمعامل ثالث، مما يسمح لك بتمرير أي خيارات ترغب في تمريرها إلى Stripe أو Braintree عند إنشاء الرسم: | ستفرض الفاتورة على الفور على بطاقة ائتمان المستخدم، يقبل التابع <code>invoiceFor</code> مصفوفة كمعامل ثالث، مما يسمح لك بتمرير أي خيارات ترغب في تمريرها إلى Stripe أو Braintree عند إنشاء الرسم:<syntaxhighlight lang="php"> | ||
$user->invoiceFor('One Time Fee', 500, [ | $user->invoiceFor('One Time Fee', 500, [ | ||
'custom-option' => $value, | |||
]); | ]); | ||
</syntaxhighlight> | |||
إذا كنت تستخدم Braintree كموفّر للفوترة، يجب عليك تضمين خيار description عند استدعاء التابع invoiceFor: | إذا كنت تستخدم Braintree كموفّر للفوترة، يجب عليك تضمين خيار <code>description</code> عند استدعاء التابع <code>invoiceFor</code>:<syntaxhighlight lang="php"> | ||
$user->invoiceFor('One Time Fee', 500, [ | $user->invoiceFor('One Time Fee', 500, [ | ||
'description' => 'your invoice description here', | |||
]); | ]); | ||
</syntaxhighlight> | |||
سينشئ التابع <code>invoiceFor</code> فاتورة Stripe والتي ستعيد محاولات الفوترة الفاشلة، وإذا كنت لا ترغب في إنشاء فاتورة لإعادة المحاولة مع العمليات الفاشلة، ستحتاج إلى إغلاقها باستخدام واجهة Stripe البرمجية بعد أول عمليّة تحصيل رسوم فاشلة. | |||
== الفواتير == | |||
يمكنك استرداد مصفوفة من فواتير نموذج <code>billable</code> بسهولة باستخدام التابع <code>invoices</code>:<syntaxhighlight lang="php"> | |||
$invoices = $user->invoices(); | $invoices = $user->invoices(); | ||
// تضمين الفواتير المعلّقة في النتائج | // تضمين الفواتير المعلّقة في النتائج | ||
$invoices = $user->invoicesIncludingPending(); | $invoices = $user->invoicesIncludingPending(); | ||
</syntaxhighlight> | |||
عند إدراج الفواتير الخاصة بالعميل، يجوز لك استخدام التوابع المساعدة لعرض معلومات الفاتورة ذات الصلة، فعلى سبيل المثال، قد ترغب في سرد كل فاتورة في جدول مما يسمح للمستخدم تنزيل أي منها بسهولة:<syntaxhighlight lang="php"> | |||
<table><tr><td | <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> | |||
</syntaxhighlight> | |||
=== توليد فواتير PDF === | |||
من خلال المسار أو وحدة التحكم، استخدم التابع <code>downloadInvoice</code> لإنشاء PDF قابل للتحميل من الفاتورة، سينشئ هذا التابع استجابة HTTP المناسبة تلقائيًا لإرسال ملف التنزيل إلى المتصفح:<syntaxhighlight lang="php"> | |||
use Illuminate\Http\Request; | use Illuminate\Http\Request; | ||
Route::get('user/invoice/{invoice}', function (Request $request, $invoiceId) { | Route::get('user/invoice/{invoice}', function (Request $request, $invoiceId) { | ||
return $request->user()->downloadInvoice($invoiceId, [ | |||
'vendor' => 'Your Company', | |||
'product' => 'Your Product', | |||
]); | |||
}); | }); | ||
</syntaxhighlight> | |||
== مصادر == | == مصادر == | ||
* [https://laravel.com/docs/5.6/billing صفحة Laravel Cashier في توثيق Laravel الرسمي]. | * [https://laravel.com/docs/5.6/billing صفحة Laravel Cashier في توثيق Laravel الرسمي]. | ||
[[تصنيف:Laravel|{{SUBPAGENAME}}]] | |||
[[تصنيف:Laravel Official Packages|{{SUBPAGENAME}}]] |
المراجعة الحالية بتاريخ 14:11، 23 أكتوبر 2018
مقدمة
يقدم Laravel Cashier واجهة قويّة لاشتراكات خدمات الفواتير Stripe و Braintree، وهي تعالج تقريبًا كل شيفرات boilerplate الخاصة باشتراك الفواتير التي تخشى من كتابتها، وبالإضافة إلى إدارة الاشتراكات الأساسية، يستطيع Cashier التعامل مع القسائم (coupons)، ومبادلة الاشتراكات وكميّات الاشتراكات وفترات السماح بالإلغاء وحتى إنشاء ملفات PDF للفواتير.
تنبيه: إذا كنت تضع رسوم لمرة واحدةً فقط ولا توفّر الاشتراكات، فيجب عليك أن لا تستخدم Cashier، وبدلًا من ذلك، يجب عليك استخدام حزمة برمجيات التطوير (SDK) الخاصة بـ Braintree و Stripe مباشرةً.
الضبط
Stripe
Composer
أولًا، أضف حزمة Cashier الخاصة بخدمة Stripe إلى اعتماديّاتك:
composer require "laravel/cashier":"~7.0"
تهجير قواعد البيانات
قبل استخدام Cashier، سنحتاج أيضًا إلى إعداد قاعدة البيانات، وذلك عن طريق إضافة عدة أعمدة إلى جدول users
وإنشاء جدول subscriptions
جديد لاحتواء جميع اشتراكات عملائنا:
Schema::table('users', function ($table) {
$table->string('stripe_id')->nullable();
$table->string('card_brand')->nullable();
$table->string('card_last_four')->nullable();
$table->timestamp('trial_ends_at')->nullable();
});
Schema::create('subscriptions', function ($table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->string('name');
$table->string('stripe_id');
$table->string('stripe_plan');
$table->integer('quantity');
$table->timestamp('trial_ends_at')->nullable();
$table->timestamp('ends_at')->nullable();
$table->timestamps();
});
بمجرّد إنشاء التهجيرات، شغّل أمر migrate
Artisan.
نموذج Billable
بعد ذلك، أضف سمة Billable
إلى تعريف نموذجك، توفّر هذه السمة طرقًا مختلفة تسمح لك بتنفيذ مهام الفوترة الشائعة، كإنشاء الاشتراكات وتطبيق القسائم وتحديث بيانات بطاقة الائتمان:
use Laravel\Cashier\Billable;
class User extends Authenticatable
{
use Billable;
}
مفاتيح الواجهة البرمجيّة API
ختامًا، يجب عليك ضبط مفتاح Stripe في ملف الضبط services.php
، ويمكنك استرداد مفاتيح Stripe API من لوحة تحكم Stripe:
'stripe' => [
'model' => App\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
Braintree
تحذيرات Braintree
تعمل تطبيقات Stripe و Braintree بنفس الطريقة في عدة عمليات، فكلاهما يوفران فوترة الاشتراك ببطاقات الائتمان لكن يدعم Paypal Braintree أيضًا، ومع ذلك، يفتقر Braintree إلى بعض المميزات المدعومة من Stripe، ويجب عليك مراعاة ما يلي عند اتخاذ قرار استخدام Stripe أو Braintree:
- يدعم Paypal Braintree على عكس Stripe.
- لا يدعم Braintree توابع الزيادة والنقصان على الاشتراكات، وهذه حدود Braintree وليست حدود Cashier.
- لا يدعم Braintree الخصومات القائمة على النسبة المئويّة، وهذه حدود Braintree وليست حدود Cashier.
Composer
أضف أولًا حزمة Cashier الخاصة بخدمة Braintree إلى اعتماديّاتك:
composer require "laravel/cashier-braintree":"~2.0"
مقدم الخدمة
بعد ذلك، سجّل مقدّم الخدمة Laravel\Cashier\CashierServiceProvider
في ملف الضبط config/app.php
:
Laravel\Cashier\CashierServiceProvider::class
قسيمة خطة الائتمان
قبل استخدام Cashier مع Braintree، ستحتاج إلى تعريف قسيمة plan-credit في لوحة تحكم Braintree، وسيُستخدم هذا الخصم لتجزئة الاشتراكات التي تتغيّر من الفوترة السنويّة إلى الشهريّة أو من الشهريّة إلى السنويّة.
يمكن أن يكون مقدار الخصم الذي تريد تكوينه في لوحة تحكم Braintree أي قيمة تريدها، حيث سيعيد Cashier تعريف المبلغ المحدد بالمبلغ المخصص الخاص بنا في كل مرة نطبّق فيها القسيمة، وهذه القسيمة مطلوبة لأن Braintree لا يدعم الاشتراكات التناسبية عبر ترددات الاشتراك.
تهجير قواعد البيانات
قبل استخدام Cashier، سنحتاج إلى إعداد قاعدة البيانات، وذلك عن طريق إضافة عدة أعمدة إلى جدول users
و إنشاء جدول subscriptions
جديد لاحتواء جميع اشتراكات عملائنا:
Schema::table('users', function ($table) {
$table->string('braintree_id')->nullable();
$table->string('paypal_email')->nullable();
$table->string('card_brand')->nullable();
$table->string('card_last_four')->nullable();
$table->timestamp('trial_ends_at')->nullable();
});
Schema::create('subscriptions', function ($table) {
$table->increments('id');
$table->unsignedInteger('user_id');
$table->string('name');
$table->string('braintree_id');
$table->string('braintree_plan');
$table->integer('quantity');
$table->timestamp('trial_ends_at')->nullable();
$table->timestamp('ends_at')->nullable();
$table->timestamps();
});
بمجرّد إنشاء التهجيرات، شغّل أمر migrate
Artisan.
نموذج Billable
بعد ذلك، أضف سمة Billable
إلى تعريف نموذجك:
use Laravel\Cashier\Billable;
class User extends Authenticatable
{
use Billable;
}
مفاتيح الواجهة البرمجيّة API
ختامًا، يجب عليك ضبط الخيارات التاليّة في ملف الضبط services.php
:
'braintree' => [
'model' => App\User::class,
'environment' => env('BRAINTREE_ENV'),
'merchant_id' => env('BRAINTREE_MERCHANT_ID'),
'public_key' => env('BRAINTREE_PUBLIC_KEY'),
'private_key' => env('BRAINTREE_PRIVATE_KEY'),
],
ثم يجب عليك إضافة استدعاءات حزمة برمجيات التطوير Braintree SDK التالية إلى تابع boot الخاص بموفّر الخدمة AppServiceProvider:
\Braintree_Configuration::environment(config('services.braintree.environment'));
\Braintree_Configuration::merchantId(config('services.braintree.merchant_id'));
\Braintree_Configuration::publicKey(config('services.braintree.public_key'));
\Braintree_Configuration::privateKey(config('services.braintree.private_key'));
ضبط العملة
العملة الافتراضية لـ Cashier هي الدولار الأمريكي (USD)، ويمكنك تغيير العملة الافتراضيّة باستدعاء تابع Cashier::useCurrency
من داخل تابع boot
من أحد موفرّي الخدمة.
يقبل تابع useCurrency
سلستين نصيتيّن كمعاملات: العملة ورمز العملة:
use Laravel\Cashier\Cashier;
Cashier::useCurrency('eur', '€');
الاشتراكات
إنشاء الاشتراكات
لإنشاء اشتراك، استردّ نسخة من نموذج billable
والتي ستكون عادةً نسخة من App\User
، وبمجرد استرداد نسخة النموذج، يمكنك استخدام تابع newSubscription
لإنشاء اشتراك النموذج:
$user = User::find(1);
$user->newSubscription('main', 'premium')->create($stripeToken);
يجب أن يكون المعامل الأول الممرّر إلى تابع newSubscription هو اسم الاشتراك، إذا كان تطبيقك يوفّر نوع واحد من الاشتراكات، يمكنك تسميته main أو primary، وأما المعامل الثاني فهو تحديد خطة Stripe أو Braintree التي يشترك فيها المستخدم، ويجب أن تتوافق هذه القيمة مع معرّف Stripe أو Braintree.
سيبدأ التابع create
، والذي يقبل بطاقة ائتمان أو رمز مصدر Stripe، الاشتراك بالإضافة إلى تحديث قاعدة بياناتك بمعرّف العميل ومعلومات الفوترة ذات الصلة.
بيانات المستخدم إضافيّة
إذا كنت ترغب في تحديد تفاصيل إضافيّة للعميل، فيمكنك القيام بذلك عن طريق تمريرها كمعامل ثاني إلى التابع create
:
$user->newSubscription('main', 'monthly')->create($stripeToken, [
'email' => $email,
]);
لمعرفة المزيد حول الحقول الإضافية المدعومة بواسطة Stripe أو Braintree، راجع توثيق Stripe حول إنشاء العميل أو توثيق Braintree المشابهة.
القسائم
إذا رغبت في تطبيق قسيمة عند إنشاء الاشتراك، فيمكنك استخدام تابع withCoupon
:
$user->newSubscription('main', 'monthly')
->withCoupon('code')
->create($stripeToken);
التحقق من حالة الاشتراك
بمجرد اشتراك المستخدم بتطبيقك، يمكنك التحقق بسهولة من حالة الاشتراك باستخدام مجموعة متنوعة من التوابع المناسبة، فالتابع subscribed
يرجع true
إذا كان للمستخدم اشتراك نشط، وحتى إذا كان الاشتراك حاليًا ضمن الفترة التجريبيّة:
if ($user->subscribed('main')) {
//
}
إن التابع subscribed
هو مرشح رائع لبرمجيّة وسيطة للمسار، فهو يسمح لك بترشيح الوصول إلى المسارات ووحدات التحكم بناءًا على حالة اشتراك المستخدم:
public function handle($request, Closure $next)
{
if ($request->user() && ! $request->user()->subscribed('main')) {
// This user is not a paying customer...
return redirect('billing');
}
return $next($request);
}
إذا أردت تحديد ما إذا كان المستخدم ما يزال ضمن الفترة التجريبيّة، فيمكنك استخدام التابع onTrial
، ويمكنك استخدام هذا التابع لعرض تحذير للمستخدم بأنه ما يزال في الفترة التجريبيّة الخاصة به:
if ($user->subscription('main')->onTrial()) {
//
}
يمكن استخدام التابع subscribedToPlan
لتحديد ما إذا كان المستخدم مشتركًا بخطة معينة بناءً على معرّف الخطة في Stripe / Braintree، وفي هذا المثال، سنحدد ما إذا كان الاشتراك main للمستخدم مفعّل للخطة الشهريّة:
if ($user->subscribedToPlan('monthly', 'main')) {
//
}
حالة الاشتراك الملغى
لتحديد ما إذا كان المستخدم مشتركًا نشيطًا سابقًا ولكنه ألغى اشتراكه، يمكنك استخدام تابع cancelled
:
if ($user->subscription('main')->cancelled()) {
//
}
يمكنك أيضًا تحديد ما إذا كان المستخدم قد ألغى اشتراكه ولكنه لا يزال في فترة "السماح" حتى انتهاء صلاحيّة اشتراكه بالكامل، فعلى سبيل المثال، إذا الغى المستخدم اشتراكه في الخامس من شهر آذار/مارس والذي من المقرر في الأصل أن تنتهي صلاحيته في 10 من آذار/مارس، فسيكون المستخدم في فترة "السماح" حتى 10 من آذار/مارس، ولاحظ أن التابع subscribed
سيرجع true
في هذه الحالة:
if ($user->subscription('main')->onGracePeriod()) {
//
}
تغيير الخطط
قد يرغب المستخدم بعد اشتراك في تطبيقك في تغييره إلى خطة اشتراك جديدة، ولاستبدال اشتراك جديد باشتراك المستخدم الحالي، مرّر معرّف الخطة إلى التابع swap
:
$user = App\User::find(1);
$user->subscription('main')->swap('provider-plan-id');
إذا كان المستخدم قيد الإصدار التجريبي، فسيُحتفظ بالفترة التجريبيّة أيضًا وإذا كان هنالك كميّة للاشتراك، فسيُحتفظ بتلك الكميّة quantity أيضًا.
إذا أردت مبادلة الخطط وإلغاء أي فترة تجريبيّة للمستخدم قيد التشغيل حاليًا، فيمكنك استخدام التابع skipTrial
:
$user->subscription('main')
->skipTrial()
->swap('provider-plan-id');
كميّة الاشتراك
تنبيه: كميّة الاشتراك مدعومة فقط من نسخة Stripe من Cashier، فلا يملك Braintree خاصيّة تتوافق مع "كميّة" Stripe.
تتأثر في بعض الأحيان الاشتراكات بالكميّة، فعلى سبيل المثال، إذا كان يتقاضى تطبيقك 10 دولارات شهريًا للمستخدم على الحساب، فلزيادة أو نقصان كميّة الاشتراك بسهولة، يمكنك استخدام التوابع incrementQuantity
وdecrementQuantity
:
$user = User::find(1);
$user->subscription('main')->incrementQuantity();
// Add five to the subscription's current quantity...
$user->subscription('main')->incrementQuantity(5);
$user->subscription('main')->decrementQuantity();
// Subtract five to the subscription's current quantity...
$user->subscription('main')->decrementQuantity(5);
يمكنك بدلًا من ذلك تعيين كميّة محددة باستخدام التابع updateQuantity
:
$user->subscription('main')->updateQuantity(10);
يمكنك استخدام التابع noProrate
لتحديث كميّة الاشتراك دون تقييم الرسوم:
$user->subscription('main')->noProrate()->updateQuantity(10);
للمزيد من المعلومات حول كميّات الاشتراك، راجع توثيق Stripe.
رسوم الاشتراك
لتحديد نسبة الرسوم للمستخدم على الاشتراك، طبّق التابع taxPercentage
على نموذج billable
الخاص بك، وأرجع قيمة رقميّة بين 0 و 100، مع عدم وجود أكثر من منزلتين عشريتين.
public function taxPercentage() {
return 20;
}
يمكّنك التابع taxPercentage
من تطبيق معدّل الرسوم على أساسيات نموذج بنموذج model-by-model، والذي قد يكون مفيدًا لقاعدة المستخدمين التي تغطي الكثير من البلدان ومعدلات الرسوم.
تنبيه: لا يطبّق التابع taxPercentage
على رسوم الاشتراك فقط، فإذا استخدمت Cashier لتحصيل رسوم دفعة واحدة، فستحتاج إلى تعديد معدل الرسوم يدويًا في ذلك الوقت.
إلغاء الاشتراكات
لإلغاء اشتراك، استدع التابع cancel
على اشتراك المستخدم:
$user->subscription('main')->cancel();
عند إلغاء الاشتراك، سيعيّن Cashier بشكل تلقائي عمود ends_at
في قاعدة بياناتك، وسيُستخدم هذا العمود لمعرفة متى يجب على التابع subscribed
إرجاع القيمة false
، فعلى سبيل المثال، إذا ألغى عميل اشتراكه في الأول من مارس،ولم يكن من المقرر أن ينتهي الاشتراك حتى الخامس من مارس، فسيبقى التابع subscribed
يرجع true
حتى تاريخ 5 مارس.
يمكنك تحديد ما إذا كان المستخدم قد ألغى اشتراكه ولكن لا يزال في فترة "السماح" عن طريق استخدام التابع onGracePeriod
:
if ($user->subscription('main')->onGracePeriod()) {
//
}
إذا رغبت في إنهاء الاشتراك فورًا، فاستدع التابع cancelNow
على اشتراك المستخدم:
$user->subscription('main')->cancelNow();
استئناف الاشتراكات
إذا ألغى مستخدم اشتراكه ويرغب في استئنافه استخدم التابع resume
، ويجب على المستخدم أن يظل في فترة السماح لاستئناف اشتراكه:
$user->subscription('main')->resume();
إذا ألغى مستخدم اشتراكه ثم استأنفه قبل انتهاء صلاحيّة الاشتراك بالكامل فلن يحاسب على الفور، وبدلًا من ذلك، سيعاد تنشيط اشتراكه وسيحاسب على دورة الفوترة الأصليّة.
تحديث بطاقات الائتمان
يمكن استخدام التابع updateCard
لتحديث معلومات بطاقة ائتمان العميل، ويقبل هذا التابع رمز Stripe وسيعيّن بطاقة الائتمان الجديدة المصدر الافتراضي للفوترة:
$user->updateCard($stripeToken);
الفترات التجريبيّة للاشتراكات
مع واجهة بطاقة الائتمان
إذا كنت ترغب في توفير فترات تجريبيّة لعملائك مع الاستمرار في جمع معلومات طريقة الدفع، يجب عليك استخدام التابع trialDays
عند إنشائك للاشتراك:
$user = User::find(1);
$user->newSubscription('main', 'monthly')
->trialDays(10)
->create($stripeToken);
سيحدد هذا التابع تاريخ انتهاء الفترة التجريبيّة في سجل الاشتراك داخل قاعدة البيانات، بالإضافة إلى إرشاد Stripe أو Braintree إلى عدم البدء في إعداد فواتير للعميل إلى ما بعد هذا التاريخ.
تنبيه: إذا لم يلغي العميل اشتراكه قبل انتهاء الفترة التجريبيّة فسُتفرض الرسوم فور انتهاء الفترة التجريبيّة، لذلك يجب عليك التأكد من إبلاغ المستخدمين بتاريخ انتهاء الفترة التجريبيّة.
يتيح لك التابع trialUntil
توفير نسخة DateTime
لتحديد موعد انتهاء الفترة التجريبيّة:
use Carbon\Carbon;
$user->newSubscription('main', 'monthly')
->trialUntil(Carbon::now()->addDays(10))
->create($stripeToken);
يمكنك معرفة ما إذا كان المستخدم في فترته التجريبيّة أو لا إما باستخدام التابع onTrial
على نسخة المستخدم أو باستخدام التابع onTrial
على نسخة الاشتراك، فالمثالان التاليان متطابقان:
if ($user->onTrial('main')) {
//
}
if ($user->subscription('main')->onTrial()) {
//
}
بدون واجهة بطاقة الائتمان
إذا كنت ترغب في تقديم فترات تجريبيّة دون جمع معلومات عن طريقة دفع المستخدم، يمكنك تعيين عمود trial_ends_at
في سجل المستخدم بناءً على تاريخ انتهاء الإصدار التجريبي المطلوب، ويتم ذلك عادةً أثناء تسجيل المستخدم:
$user = User::create([
// ملأ بقية خصائص المستخدم
'trial_ends_at' => now()->addDays(10),
]);
تنبيه: تأكد من إضافة تاريخ لـ trial_ends_at
لتعريف النموذج.
يشير Cashier إلى نوع الفترة التجريبيّة على أنها "تجربة عامة"، نظرًا لأنه غير مرتبط بأي اشتراك حالي، وسيُرجع التابع onTrial
في نسخة User
القيمة true
إذا لم يتجاوز التاريخ الحالي قيمة trial_ends_at
:
if ($user->onTrial()) {
// المستخدم في الفترة التجريبية
}
يمكنك أيضًا استخدام التابع onGenericTrial
إذا أردت معرفة على وجه التحديد أن المستخدم ضمن فترة النسخة التجريبيّة العامة ولم ينشئ اشتراكًا فعليًّا بعد:
if ($user->onGenericTrial()) {
// المستخدم في الفترة التجريبية العامة
}
بمجرّد استعدادك لإنشاء اشتراك فعلي للمستخدم، يمكنك استخدام التابع newSubscription
كالمعتاد:
$user = User::find(1);
$user->newSubscription('main', 'monthly')->create($stripeToken);
معالجة خطاطيف الويب في Stripe
يمكن لكل من Stripe وBraintree إعلام تطبيقك بمجموعة من الأحداث عبر خطاطيف الويب (webhooks)، ولمعالجة خطاطيف الويب في Stripe، يجب عليك تعريف المسار الذي يشير إلى وحدة تحكم خطّاف الويب الخاص بـ Cashier، وستُعالج وحدة التحكم هذه جميع طلبات خطّاف الويب الواردة وترسلها إلى تابع وحدة التحكم المناسب:
Route::post(
'stripe/webhook',
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);
تنبيه: بمجرّد تسجيل الطريق الخاص بك، تأكد من تكوين عنوان خطاف ويب webhook URL في إعدادات لوحة تحكم Stripe.
بشكل افتراضي، ستتعامل وحدة التحكم تلقائيًا مع إلغاء الاشتراكات التي تحتوي على عدد كبير من محاولات الحصول على الرسوم الفاشلة (كما هو محدد بواسطة إعدادات Stripe)، ومع ذلك، كما سنكتشف قريبًا، يمكننا توسيع وحدة التحكم للتعامل مع أي حدث خطاف ويب ترغب به.
خطاطيف الويب وحماية CSRF
نظرًا لأن خطاطيف ويب Stripe تحتاج إلى تجاوز حماية CSRF الخاصة بإطار Laravel، تأكد من وضع عنوان URI كاستثناء في البرمجيّة الوسيطة VerifyCsrfToken
الخاصة بك أو ضع المسار خارج مجموعة البرمجيّة الوسيطة web:
protected $except = [
'stripe/*',
];
تعريف معالجات أحداث خطاطيف الويب
سيتعامل Cashier بشكل تلقائي بإلغاء الاشتراك عند فشل شحن المبلغ، لكن إذا كان لديك أحداث خطاطيف ويب Stripe ترغب في معالجتها، فوسّع وحدة التحكم خطّاف الويب ويجب أن تكون أسماء التوابع متطابقة مع اتفاقيّة Cashier المتوقعة، والتي تنصّ على أنه يجب أن تبدأ بالكلمة handle وتستخدم حالة سِنَام الجمل (camelCase) لاسم خطّاف الويب الذي ترغب في معالجته. فعلى سبيل المثال، إذا كنت ترغب في معالجة خطاف الويب الخاص بالخطاف invoice.payment_succeeded
فيجب عليك إضافة التابع handleInvoicePaymentSucceeded
إلى وحدة التحكم:
<?php
namespace App\Http\Controllers;
use Laravel\Cashier\Http\Controllers\WebhookController as CashierController;
class WebhookController extends CashierController
{
/**
* التعامل مع خطاطيف الويب.
*
* @param مصفوفة $payload
* @return Response
*/
public function handleInvoicePaymentSucceeded($payload)
{
// معالجة الحدث
}
}
بعد ذلك، حدد المسار إلى وحدة التحكم Cashier داخل ملف routes/web.php
:
Route::post(
'stripe/webhook',
'\App\Http\Controllers\WebhookController@handleWebhook'
);
اشتراكات فاشلة
ماذا لو انتهت صلاحيّة بطاقة ائتمان العميل؟ لا تقلق! يحتوي Cashier على وحدة تحكم خطاف ويب يمكنها إلغاء اشتراك العميل بسهولة.
وكما ذُكِر أعلاه، كل ما عليك القيام به هو توجيه المسار إلى وحدة التحكم:
Route::post(
'stripe/webhook',
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);
وهذا كل شيء، ستُلتقط المدفوعات الفاشلة وتُعالج عن طريق وحدة التحكم، وستلغي وحدة التحكم اشتراك العميل عندما يعلن Stripe فشل الاشتراك (عادةً بعد ثلاث محاولات دفع فاشلة).
معالجة خطاطيف الويب في Braintree
يمكن لكل من Stripe وBraintree إعلام تطبيقك بمجموعة من الأحداث عبر خطاطيف الويب، ولمعالجة خطاطيف ويب Braintree، يجب عليك تعريف المسار الذي يشير إلى وحدة تحكم خطّاف الويب الخاص بـ Cashier، وستعالج وحدة التحكم هذه جميع طلبات خطّاف الويب الواردة وترسلها إلى تابع وحدة التحكم المناسب:
Route::post(
'braintree/webhook',
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);
تنبيه: بمجرّد تسجيل المسار الخاص بك، تأكد من إنشاء عنوان خطاف ويب webhook URL في إعدادات لوحة تحكم Braintree.
بشكل افتراضي، ستتعامل وحدة التحكم هذه تلقائيًا مع إلغاء الاشتراكات التي تحتوي على عدد كبير من محاولات الحصول على الرسوم الفاشلة (كما هو محدد بواسطة إعدادات Braintree)، ومع ذلك، كما سنكتشف قريبًا، يمكننا توسيع وحدة التحكم للتعامل مع أي حدث خطّاف ويب ترغب به.
خطاطيف الويب وحماية CSRF
نظرًا لأن خطاطيف ويب Braintree تحتاج إلى تجاوز حماية CSRF الخاصة بإطار Laravel، فتأكد من وضع URI كاستثناء في وسيطة VerifyCsrfToken
الخاصة بك أو ضع مسار خارج مجموعة وسيطة web:
protected $except = [
'braintree/*',
];
تعريف معالجات أحداث خطاطيف الويب
سيتعامل Cashier بشكل تلقائي بإلغاء الاشتراك عند فشل شحن المبلغ، لكن إذا كان لديك أحداث Braintree خطّاف ويب ترغب في معالجتها، فوسّع وحدة التحكم خطّاف الويب ويجب أن تكون أسماء التوابع متطابقة مع اتفاقيّة Cashier المتوقعة، والتي تنصّ على أنه يجب أن تبدأ بالكلمة handle وتستخدم حالة سِنَام الجمل (camelCase) لاسم خطّاف الويب الذي ترغب في معالجته. فعلى سبيل المثال، إذا كنت ترغب في التعامل مع خطّاف الويب dispute_opened
فيجب عليك إضافة التابع handleDisputeOpened
إلى وحدة التحكم:
<?php
namespace App\Http\Controllers;
use Braintree\WebhookNotification;
use Laravel\Cashier\Http\Controllers\WebhookController as CashierController;
class WebhookController extends CashierController
{
/**
* التعامل مع خطّافي Braintree.
*
* @param WebhookNotification $webhook
* @return Response
*/
public function handleDisputeOpened(WebhookNotification $notification)
{
// Handle The Event
}
}
اشتراكات فاشلة
ماذا لو انتهت صلاحيّة بطاقة ائتمان العميل؟ لا تقلق! يحتوي Cashier على وحدة التحكم خطّاف الويب الذي يمكنه إلغاء اشتراك العميل بسهول.
وكما ذكر أعلاه، كل ما عليك القيام به هو توجيه المسار إلى وحدة التحكم:
Route::post(
'braintree/webhook',
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);
وهذا كل شيء، ستُلتقط المدفوعات الفاشلة وتُعالج عن طريق وحدة التحكم، وستلغى وحدة التحكم اشتراك العميل عندما يعرّف Braintree بفشل الاشتراك (عادةً بعد ثلاث محاولات دفع فاشلة). لا تنس أنك بحاجة إلى إعداد عنوان خطّاف الويب webhook URI في إعدادات لوحة تحكم Braintree الخاصة بك.
رسوم واحدة
رسم بسيط
تنبيه: عند استخدام Stripe، سيقبل التابع charge
المقدار الذي ترغب في خصمه في أدنى مقام للعملة المستخدمة في طلب اشتراكك، ومع ذلك، عند استخدام Braintree، يجب عليك تمرير المبلغ الكامل بالدولار إلى التابع charge
:
إذا كنت ترغب في إجراء دفعة واحدة لبطاقة ائتمان أحد العملاء المشتركين، فيمكنك استخدام التابع charge
على نسخة نموذج Billable
.
// centsتقبل الدفعات بال Stripe
$user->charge(100);
//Dollarsتقبل الدفعات بال Braitree
$user->charge(1);
يقبل التابع charge
مصفوفة كمعامل ثاني مما يسمح لك بتمرير أي خيارات ترغب في تضمينها لرسوم إنشاء Stripe / Braintree، راجع توثيقات Stripe أو Braintree المتعلقة بالخيارات المتاحة لك عند إنشاء الرسوم:
$user->charge(100, [
'custom_option' => $value,
]);
سيرمي التابع charge
استثناء إذا فشلت عمليّة الشحن، وإذا نجحت، فستعاد إجابة Stripe أو Braintree كاملة من التابع:
try {
$response = $user->charge(100);
} catch (Exception $e) {
//
}
الشحن مع الفاتورة
قد تحتاج في بعض الأحيان إلى تحصيل رسوم لمرة واحدة ولكن ترغب أيضًا في إنشاء فاتورة لتحصيل الرسوم حتى تتمكن من تقديم إيصال بصيغة PDF إلى عميلك، يسمح لك التابع invoiceFor
بذلك. فعلى سبيل المثال، لنفرض على العميل رسوم 5.00$ لمرة واحدة:
// centsتقبل الدفعات بال Stripe
$user->invoiceFor('One Time Fee', 500);
// dollarsتقبل الدفعات بال Braitree
$user->invoiceFor('One Time Fee', 5);
ستفرض الفاتورة على الفور على بطاقة ائتمان المستخدم، يقبل التابع invoiceFor
مصفوفة كمعامل ثالث، مما يسمح لك بتمرير أي خيارات ترغب في تمريرها إلى Stripe أو Braintree عند إنشاء الرسم:
$user->invoiceFor('One Time Fee', 500, [
'custom-option' => $value,
]);
إذا كنت تستخدم Braintree كموفّر للفوترة، يجب عليك تضمين خيار description
عند استدعاء التابع invoiceFor
:
$user->invoiceFor('One Time Fee', 500, [
'description' => 'your invoice description here',
]);
سينشئ التابع invoiceFor
فاتورة Stripe والتي ستعيد محاولات الفوترة الفاشلة، وإذا كنت لا ترغب في إنشاء فاتورة لإعادة المحاولة مع العمليات الفاشلة، ستحتاج إلى إغلاقها باستخدام واجهة Stripe البرمجية بعد أول عمليّة تحصيل رسوم فاشلة.
الفواتير
يمكنك استرداد مصفوفة من فواتير نموذج billable
بسهولة باستخدام التابع invoices
:
$invoices = $user->invoices();
// تضمين الفواتير المعلّقة في النتائج
$invoices = $user->invoicesIncludingPending();
عند إدراج الفواتير الخاصة بالعميل، يجوز لك استخدام التوابع المساعدة لعرض معلومات الفاتورة ذات الصلة، فعلى سبيل المثال، قد ترغب في سرد كل فاتورة في جدول مما يسمح للمستخدم تنزيل أي منها بسهولة:
<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>
توليد فواتير PDF
من خلال المسار أو وحدة التحكم، استخدم التابع 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',
]);
});