Laravel SDK
Laravel аппликэйшнаас Byl-ийг ашиглах албан ёсны SDK. Нэхэмжлэх, checkout, харилцагч, захиалга, billing portal болон webhook-ийг Laravel-д зохицсон байдлаар хэрэглэнэ.
- Package:
kitelab-dev/byl-laravel - Шаардлага: PHP 8.2+, Laravel 11 / 12 / 13
Суулгах
composer require kitelab-dev/byl-laravel.env файлд дараах гурван утгыг нэмнэ:
BYL_TOKEN=таны-api-token
BYL_PROJECT_ID=1
BYL_WEBHOOK_SECRET=таны-webhook-secretBYL_TOKEN— API токен хуудсанд үүсгэнэ.BYL_PROJECT_ID— төслийн тохиргоо цэснээс харна.BYL_WEBHOOK_SECRET— webhook-ийн дэлгэрэнгүй хуудсанд байх гарын үсгийн түлхүүр.
Тохиргооны файл хэрэгтэй бол:
php artisan vendor:publish --tag=byl-configНэхэмжлэх
use Byl\Laravel\Facades\Byl;
$invoice = Byl::invoices()->create([
'amount' => 25000,
'description' => 'Гишүүнчлэлийн төлбөр',
]);
$invoice->url; // төлбөрийн хуудасны хаяг
$invoice->status; // InvoiceStatus::Open
$invoice->isPaid(); // false
Byl::invoices()->find($invoice->id);
Byl::invoices()->void($invoice->id);
Byl::invoices()->delete($invoice->id);Нэхэмжлэх, checkout, portal session объектыг controller-оос шууд буцаахад тухайн хуудас руу redirect хийнэ:
public function pay(Order $order)
{
return Byl::invoices()->createFor($order->total, "Захиалга #{$order->id}");
}Checkout
$checkout = Byl::checkouts()->builder()
->successUrl(route('purchase.success'))
->cancelUrl(route('cart'))
->addPrice('starter_monthly') // lookup key
->addPriceId(3) // Byl дээрх үнийн ID
->addPriceData(15000, 'Гутал', quantity: 2) // шууд үнэ
->collectPhoneNumber()
->collectDeliveryAddress()
->allowPromotionCodes()
->discount(5400, 'Хямдрал')
->clientReferenceId("order_{$order->id}")
->create();
return redirect()->away($checkout->url);Лавлахад item болон хэрэглэгдсэн хөнгөлөлтийн кодууд хамт ирнэ:
$checkout = Byl::checkouts()->find(13338);
$checkout->status; // CheckoutStatus::Complete
$checkout->amountTotal;
$checkout->items; // Collection<CheckoutItem>
$checkout->couponCodes; // Collection<CouponCode>Харилцагч
client_reference_id-д өөрийн хэрэглэгчийн ID дамжуулбал давхардал үүсэхгүй тул checkout үүсгэхийн өмнө бүр удаа дуудаж болно:
$customer = Byl::customers()->upsert([
'email' => $user->email,
'name' => $user->name,
'client_reference_id' => (string) $user->id,
]);
$customer = Byl::customers()->findByClientReferenceId((string) $user->id);
$customer = Byl::customers()->findByClientReferenceIdOrNull((string) $user->id); // олдоогүй бол null
$customer->isSubscribed(); // эрхтэй захиалга байгаа эсэх
$customer->subscriptionForLookupKey('starter_monthly');Захиалга
Recurring үнэтэй checkout төлөгдөхөд subscription автоматаар үүснэ (customer_id заавал, ганц item):
Byl::checkouts()->builder()
->customer($customer->id)
->addPrice('starter_monthly')
->successUrl(route('subscribe.success'))
->create();
// Сунгалт / багц солилт
Byl::checkouts()->builder()
->customer($customer->id)
->subscription($subscriptionId)
->addPrice('growth_monthly')
->create();$subscription = Byl::subscriptions()->find(4);
$subscription->status; // SubscriptionStatus::Active
$subscription->isEntitled(); // canceled-аас бусад бүх төлөв → true
$subscription->currentPeriodEnd; // эрхийн дуусах хугацаа (Carbon)
$subscription->cancelRequested(); // цуцлалт хүссэн ч мөчлөг дуусаагүй
Byl::subscriptions()->list(['status' => 'active']); // хуудаслалттай
Byl::subscriptions()->list(['price' => 'starter_monthly']); // lookup key-ээр
Byl::subscriptions()->all(['status' => 'active']); // бүх хуудас (lazy)
Byl::subscriptions()->startTrial(customerId: 12, price: 'starter_monthly', trialDays: 14);
Byl::subscriptions()->cancel(4);
Byl::subscriptions()->resume(4);Billable trait
Laravel Cashier шиг модель дээрээ шууд ажиллах хувилбар. Захиалга нь локал byl_subscriptions хүснэгтэд тусаж, webhook ирэх бүрд автоматаар шинэчлэгддэг тул $user->subscribed() шалгалт сүлжээнд гарахгүй.
php artisan vendor:publish --tag=byl-migrations
php artisan migrateBYL_BILLABLE_MODEL="App\Models\User"use Byl\Laravel\Billing\Billable;
class User extends Authenticatable
{
use Billable;
}Эрхийн шалгалт
$user->subscribed(); // trialing / active / past_due
$user->subscribed('starter_monthly'); // тодорхой багц дээр
$user->subscribedToProduct(7);
$user->onTrial();
$user->onGracePeriod(); // цуцлалт хүссэн ч мөчлөг дуусаагүй
$user->bylSubscription()->current_period_end;Route хамгаалах:
Route::get('/dashboard', ...)->middleware('byl.subscribed');
Route::get('/pro', ...)->middleware('byl.subscribed:growth_monthly');Захиалга эхлүүлэх, удирдах
// Recurring checkout — төлөгдмөгц subscription үүснэ
return $user->newSubscription('starter_monthly')
->successUrl(route('subscribe.success'))
->checkout();
$user->newSubscription('starter_monthly')->cycles(3)->checkout(); // 3 мөчлөг нэг дор
$user->newSubscription('starter_monthly')->startTrial(14); // төлбөргүй туршилт
$subscription = $user->bylSubscription();
return $subscription->renewCheckout(3); // сунгах
return $subscription->swapCheckout('growth_monthly'); // багц солих
$subscription->cancel();
$subscription->resume();Харилцагч Byl дээр байхгүй бол эдгээр method нь client_reference_id-аар upsert хийж byl_customer_id-г автоматаар хадгална.
Cashier-аас ялгаатай тал: Монголд автомат суутгал байдаггүй тул
swap(),renew()шиг шууд суутгадаг method байхгүй — оронд нь checkout буцаадаг (swapCheckout(),renewCheckout()) бөгөөд хэрэглэгч төлбөрөө өөрөө төлнө.
| Cashier | Byl SDK |
|---|---|
$user->subscribed('default') | $user->subscribed('starter_monthly') |
$user->subscription() | $user->bylSubscription() |
$user->newSubscription(...)->checkout() | $user->newSubscription('starter_monthly')->checkout() |
->trialDays(14)->create() | $user->newSubscription('starter_monthly')->startTrial(14) |
$subscription->swap($price) | $subscription->swapCheckout($price) |
| — | $subscription->renewCheckout($cycles) |
$user->createAsStripeCustomer() | $user->createOrGetBylCustomer() |
Өгөгдлөө нөхөх
$user->syncBylSubscriptions(); // Byl дээрх захиалгуудыг локал хүснэгтэд татах
$user->asBylCustomer(); // API-аас харилцагчийн мэдээлэлclient_reference_id нь өгөгдмөлөөр primary key. Өөр багана эсвэл өөрийн логик хэрэглэх бол:
// config/byl.php
'billable' => ['client_reference_column' => 'uuid'],
// эсвэл AppServiceProvider::boot дотор
Byl::resolveBillableUsing(fn (string $reference) => Team::where('slug', $reference)->first());Billing portal
Route::get('/billing', function () {
$customer = Byl::customers()->findByClientReferenceId((string) auth()->id());
return Byl::billingPortal()->createSession($customer->id); // portal руу redirect
});Webhook
SDK нь POST /byl/webhook хаягийг автоматаар бүртгэж, Byl-Signature гарын үсгийг шалгаад Laravel event болгож илгээнэ. Byl веб хуудсанд webhook нэмэхдээ энэ хаягийг бүртгэнэ.
use Byl\Laravel\Events\CheckoutCompleted;
use Byl\Laravel\Events\SubscriptionCanceled;
use Illuminate\Support\Facades\Event;
Event::listen(function (CheckoutCompleted $event) {
Order::where('id', $event->checkout->clientReferenceId)->update(['paid_at' => now()]);
});
Event::listen(function (SubscriptionCanceled $event) {
// Хэрэглэгчийн эрхийг ЗӨВХӨН энэ event дээр хаана
User::where('id', $event->subscription->customer?->clientReferenceId)->update(['plan' => null]);
});Event класс бүр Byl-ийн event төрөлтэй харгалзана: InvoicePaid, InvoiceVoided, CheckoutCompleted, CheckoutExpired, SubscriptionCreated, SubscriptionRenewed, SubscriptionUpdated, SubscriptionRenewalDue, SubscriptionPastDue, SubscriptionCanceled. Бүх event-ийг нэг дор барих бол WebhookReceived.
Хаягийг өөрчлөх, эсвэл өөрийн controller хэрэглэх:
// config/byl.php → webhook.route.path = 'integrations/byl/webhook'
// эсвэл өөрийн route дээр гарын үсгийн шалгалтыг залгах
Route::post('/my/byl-webhook', MyWebhookController::class)->middleware('byl-signature');Алдаа
Бүх алдаа Byl\Laravel\Exceptions\BylException interface-тэй:
use Byl\Laravel\Exceptions\BylException;
use Byl\Laravel\Exceptions\ValidationException;
try {
Byl::invoices()->create(['amount' => 5]);
} catch (ValidationException $exception) {
$exception->errorFor('amount'); // "The amount must be at least 10."
} catch (BylException $exception) {
report($exception);
}| Exception | Статус |
|---|---|
AuthenticationException | 401 — токен буруу/хүчингүй |
AuthorizationException | 403 — эрхгүй |
NotFoundException | 404 — олдсонгүй |
ConflictException | 409 — жш: цуцлагдсан захиалгыг дахин цуцлах |
ValidationException | 422 — параметер буруу |
RateLimitException | 429 — retryAfter() |
ServerException | 5xx |
ConnectionException | сүлжээ / timeout |
Холболтын алдаа, 429 болон 5xx хариу дээр SDK автоматаар дахин хүсэлт илгээнэ.
Хэд хэдэн төсөл
Byl::project(7)->invoices()->createFor(1000);
Byl::project(7, 'other-token')->customers()->find(12);Тест бичих
Byl::fake() нь сүлжээнд гарахгүйгээр бодит бүтэцтэй хариу буцааж, хүсэлтийг шалгах боломж өгнө:
$byl = Byl::fake();
$this->post('/orders', ['product' => 'starter'])->assertRedirect();
$byl->assertCheckoutCreated(fn (array $payload) => $payload['items'][0]['price'] === 'starter_monthly');Webhook-ийг гарын үсэгтэйгээр турших:
use Byl\Laravel\Testing\FakeWebhook;
$webhook = FakeWebhook::checkoutCompleted(['id' => 13338]);
$this->postJson(route('byl.webhook'), $webhook->payload(), $webhook->headers())->assertOk();