Skip to content

Subscription - Захиалга

Subscription боломжийг ашиглан та сар эсвэл жилээр давтагдан төлөгддөг үйлчилгээгээ (SaaS багц, гишүүнчлэл, контентын эрх гэх мэт) Byl дээр бүрэн зохицуулах боломжтой.

Монголын төлбөрийн системүүдэд автомат суутгал (auto-charge) байдаггүй тул Byl-ийн subscription нь request-to-pay зарчмаар ажиллана: мөчлөг бүрийн төгсгөлд хэрэглэгч рүү сануулга илгээгдэж, хэрэглэгч өөрөө төлбөрөө төлж эрхээ сунгана. Сануулга, дуусах хугацааны хяналт, статусын шилжилт, webhook мэдэгдэл зэргийг Byl автоматаар зохицуулна.

Хэрэглэгч захиалгаа billing portal дээр өөрөө удирдана — login шаардлагагүй, түр хугацааны session линкээр ордог энэ хуудсаар сунгах, багц солих, цуцлах, төлбөрийн түүхээ харах боломжтой.

Хэрхэн ажилладаг вэ

  1. Удирдлагын панелаас бүтээгдэхүүндээ давтагдах (recurring) үнэ үүсгэнэ (сар эсвэл жилийн мөчлөгтэй).
  2. Хэрэглэгч тань худалдан авахад та recurring үнэтэй checkout үүсгэнэ.
  3. Checkout төлөгдмөгц subscription автоматаар үүсч, subscription.created webhook илгээгдэнэ.
  4. Мөчлөг дуусахын өмнө Byl хэрэглэгч рүү имэйл сануулга (portal линктэй) илгээж, танд subscription.renewal_due webhook явуулна.
  5. Хэрэглэгч portal дээрээ төлбөл мөчлөг сунгагдана (subscription.renewed); төлөхгүй бол хугацаа дуусмагц цуцлагдана (subscription.canceled).

Статусууд

СтатусТайлбар
trialingТуршилтын хугацаа. Туршилт дуусахад төлбөл active болно.
activeИдэвхтэй. Мөчлөг дуустал эрх нээлттэй.
past_dueХугацаа хэтэрсэн (зөвхөн grace period тохируулсан бүтээгдэхүүн дээр).
canceledЦуцлагдсан. Хэрэглэгчийн эрхийг хаах ёстой төлөв.

Хэрэглэгчийн эрхийг subscription.canceled event ирэх хүртэл нээлттэй байлгахыг зөвлөж байна — trialing, active, past_due статусууд бүгд эрхтэйд тооцогдоно.

Сануулгын хуваарь

Мөчлөгөөс хамаарч дараах хуваариар хэрэглэгч рүү имэйл сануулга илгээгдэж, танд subscription.renewal_due webhook явуулна:

  • Сарын багц — дуусахаас 7 хоног, 1 хоногийн өмнө
  • Жилийн багц — дуусахаас 30 хоног, 7 хоног, 1 хоногийн өмнө

Цуцлалт хүссэн хэрэглэгч рүү сануулга илгээгдэхгүй.

Портал

Хэрэглэгч захиалгаа billing portal дээр өөрөө удирдана: сунгах, багц солих, цуцлах/буцаах, дахин захиалах, төлбөрийн түүхээ харах. Захиалга үүсэх, сануулга очих, цуцлагдах бүрд Byl хэрэглэгч рүү portal линктэй, таны брэндтэй имэйл автоматаар илгээдэг тул ихэнх тохиолдолд танаас нэмэлт ажиллагаа шаардлагагүй.

Өөрийн аппликэйшн дотроос ("Миний захиалга" цэс гэх мэт) хандалт өгөхийг хүсвэл POST /billing-portal/sessions-ээр түр хугацааны session линк үүсгэж чиглүүлнэ — дэлгэрэнгүйг Billing portal хуудаснаас уншина уу.

Захиалга эхлүүлэх

Subscription нь recurring үнэтэй checkout төлөгдөхөд автоматаар үүснэ. Ердийн checkout-оос хоёр нэмэлт шаардлагатай:

  • customer_id заавал — захиалга тодорхой харилцагчид бүртгэгдэнэ
  • Ганц item — recurring үнэтэй checkout-д өөр item нэмж болохгүй

customer_idCustomer үүсгэх endpoint-оор авна — client_reference_id дамжуулбал upsert байдлаар ажилладаг тул checkout бүрийн өмнө дуудсан ч давхардал үүсэхгүй.

Жишээ хүсэлт

shell
BYL_PROJECT_ID="таны төслийн ID"
BYL_TOKEN="таны API token"
$ curl -X POST https://byl.mn/api/v1/projects/$BYL_PROJECT_ID/checkouts \
    -H "Authorization: Bearer $BYL_TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json' \
    -d '{
          "customer_id": 12,
          "success_url": "https://example.mn/subscribe/success",
          "items": [
              {
                  "price": "starter_monthly",
                  "quantity": 1
              }
          ]
      }'

Checkout төлөгдмөгц subscription үүсч subscription.created webhook илгээгдэнэ. Хэрэглэгч рүү portal линктэй имэйл очно.

Тэмдэглэл: Нэг харилцагч нэг бүтээгдэхүүн дээр зөвхөн нэг идэвхтэй subscription-тэй байна. Идэвхтэй subscription-тэй харилцагчийн ижил бүтээгдэхүүний ижил үнэтэй checkout нь шинэ subscription үүсгэхгүй, одоогийнхыг нь сунгана. Харин өөр үнэтэй checkout үүсгэх бол subscription_id-г заавал дамжуулна — эс бөгөөс хүсэлт алдаа буцаана (үлдсэн хоногийн кредит алдагдахаас сэргийлнэ).

Багцын хязгаар: Идэвхтэй subscription-ий нийт тоо таны Byl багцаас хамаарна — Starter багцад 10, Growth багцад хязгааргүй. Хязгаарт хүрсэн үед шинэ subscription эхлүүлэх хүсэлт алдаа буцаана; одоо байгаа subscription-ий сунгалт, багц солилтод хязгаар үйлчлэхгүй. Test горимд хязгаар шалгагдахгүй.

Сунгалт

Хэрэглэгч portal дээрээ "Сунгах" даран төлдөг тул ихэнх тохиолдолд танаас нэмэлт ажиллагаа шаардлагагүй. Хэрэв өөрийн системээс сунгалтын checkout үүсгэхийг хүсвэл subscription_id параметрийг дамжуулна:

shell
$ curl -X POST https://byl.mn/api/v1/projects/$BYL_PROJECT_ID/checkouts \
    -H "Authorization: Bearer $BYL_TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json' \
    -d '{
          "customer_id": 12,
          "subscription_id": 4,
          "items": [
              {
                  "price": "starter_monthly",
                  "quantity": 3
              }
          ]
      }'
  • Сунгалт одоогийн дуусах хугацаан дээр нэмэгдэнэ — үлдсэн хоног алдагдахгүй.
  • quantity нь хэдэн мөчлөгөөр сунгахыг заана (жишээн дээр 3 сар).

Багц солих

subscription_id-тай checkout-д өөр recurring үнэ өгвөл багц солилт болно — subscription шинэ багц руу шилжиж, шинэ мөчлөг төлсөн өдрөөс эхэлнэ. Өөр бүтээгдэхүүний үнэ рүү ч (жишээ нь Starter → Growth) солих боломжтой.

Одоогийн мөчлөгийн үлдсэн хоногийн үнэ кредит болж шинэ checkout-ийн дүнгээс автоматаар хасагдана. Кредит нь шинэ багцын үнээс их эсвэл тэнцүү бол (жишээ нь жилийн багцаас сарын багц руу буух) мөчлөг дундуур солих боломжгүй — мөчлөг дуусахад л солино.

Кредит нь checkout үүсэх мөчид тооцогддог тул багц солих checkout 24 цагийн дотор төлөгдөх ёстой — хугацаа хэтэрвэл шинэ checkout үүсгэнэ.

Portal дээр "Багц солих" хэсэгт төслийн бусад recurring үнэнүүд автоматаар харагддаг тул энэ урсгалыг та өөрөө хийх шаардлагагүй.

Туршилт (Trial)

Туршилтын захиалга төлбөргүй эхэлдэг тул checkout-оор биш, API-аар шууд үүсгэнэ:

  • HTTP Method: POST
  • URL: https://byl.mn/api/v1/projects/1/subscriptions
ПараметерТөрөлЗаавал эсэхТайлбар
customer_idNumbertrueХарилцагчийн ID.
price_idNumbertrueRecurring үнийн ID.
trial_daysNumbertrueТуршилтын хоног (1–365).
shell
$ curl -X POST https://byl.mn/api/v1/projects/$BYL_PROJECT_ID/subscriptions \
    -H "Authorization: Bearer $BYL_TOKEN" \
    -H 'Accept: application/json' \
    -H 'Content-Type: application/json' \
    -d '{
          "customer_id": 12,
          "price_id": 3,
          "trial_days": 14
      }'

Туршилт дуусахын өмнө хэрэглэгч рүү ердийн сануулга очих ба portal дээрээ төлснөөр active болно, төлөхгүй бол цуцлагдана.

Тэмдэглэл: Нэг харилцагч нэг бүтээгдэхүүн дээр нэг л удаа туршилт авч болно. Өмнө нь туршилт авсан бол хүсэлт алдаа буцаана.

Цуцлалт

Цуцлалт нь Stripe-ийн адил мөчлөгийн төгсгөлд хэрэгждэг:

  • Цуцлах үед статус active хэвээр үлдэж, subscription.updated webhook илгээгдэнэ (canceled_at талбар бөглөгдсөн байна).
  • Хэрэглэгчийн эрх мөчлөг дуустал хүчинтэй, харин сануулга дахиж илгээгдэхгүй.
  • Мөчлөг дуусмагц статус canceled болж subscription.canceled webhook илгээгдэнэ — энэ үед л эрхийг хаана.
  • Мөчлөг дуусахаас өмнө цуцлалтыг буцаах (resume) боломжтой.

Хэрэглэгч portal дээрээсээ өөрөө цуцлах ба та мөн API-аар цуцалж болно:

shell
# Цуцлах
$ curl -X POST https://byl.mn/api/v1/projects/$BYL_PROJECT_ID/subscriptions/4/cancel \
    -H "Authorization: Bearer $BYL_TOKEN" \
    -H 'Accept: application/json'

# Цуцлалт буцаах
$ curl -X POST https://byl.mn/api/v1/projects/$BYL_PROJECT_ID/subscriptions/4/resume \
    -H "Authorization: Bearer $BYL_TOKEN" \
    -H 'Accept: application/json'

Аль хэдийн бүрэн цуцлагдсан subscription дээр эдгээр хүсэлт 409 Conflict буцаана.

Subscription объект

ПараметерТөрөлТайлбар
idNumberSubscription ID.
statusStringТөлөв: trialing, active, past_due, canceled
customer_idNumberХарилцагчийн ID.
product_idNumberБүтээгдэхүүний ID.
price_idNumberҮнийн ID (багц солиход өөрчлөгдөнө).
current_period_startDateОдоогийн мөчлөгийн эхлэл.
current_period_endDateОдоогийн мөчлөгийн төгсгөл (эрхийн дуусах хугацаа).
trial_ends_atDateТуршилтын дуусах хугацаа (туршилтгүй бол null).
canceled_atDateЦуцлалт хүссэн огноо (цуцлаагүй бол null).
is_testBooleanTest горимд үүссэн эсэх.

Захиалгын жагсаалт

  • HTTP Method: GET
  • URL: https://byl.mn/api/v1/projects/1/subscriptions

Filter хийх боломжтой параметрүүд: customer_id, price_id, status.

shell
$ curl -X GET "https://byl.mn/api/v1/projects/$BYL_PROJECT_ID/subscriptions?customer_id=12&status=active" \
    -H "Authorization: Bearer $BYL_TOKEN" \
    -H 'Accept: application/json'

Захиалга лавлах

  • HTTP Method: GET
  • URL: https://byl.mn/api/v1/projects/1/subscriptions/4

Жишээ гаралт

json
{
  "data": {
    "id": 4,
    "status": "active",
    "project_id": 1,
    "customer_id": 12,
    "product_id": 7,
    "price_id": 3,
    "current_period_start": "2026-07-23T04:10:00.000000Z",
    "current_period_end": "2026-08-23T15:59:59.000000Z",
    "trial_ends_at": null,
    "canceled_at": null,
    "is_test": false,
    "customer": {
      "id": 12,
      "name": "Бат-Эрдэнэ",
      "email": "[email protected]",
      "phone": "99999999",
      "client_reference_id": "user_842"
    },
    "price": {
      "id": 3,
      "type": "recurring",
      "unit_amount": 30000,
      "recurring_interval": "month",
      "recurring_interval_count": 1,
      "lookup_key": "starter_monthly",
      "product": {
        "id": 7,
        "name": "Starter багц",
        "client_reference_id": null
      }
    },
    "created_at": "2026-06-23T04:10:00.000000Z",
    "updated_at": "2026-07-23T04:10:00.000000Z"
  }
}

Харилцагчийн идэвхтэй захиалгууд

"Энэ хэрэглэгч subscribed юу?" гэсэн шалгалтын хамгийн хялбар зам — харилцагч лавлахад идэвхтэй захиалгууд нь хамт ирнэ:

  • HTTP Method: GET
  • URL: https://byl.mn/api/v1/projects/1/customers/12 эсвэл https://byl.mn/api/v1/projects/1/customers/by-client-reference-id/user_842

data.subscriptions массивт зөвхөн эрхтэй (trialing, active, past_due) захиалгууд багтана.

Webhook event-үүд

EventХэзээ илгээгдэх вэ
subscription.createdШинэ subscription үүссэн (checkout төлөгдсөн эсвэл trial эхэлсэн).
subscription.renewedМөчлөг амжилттай сунгагдсан.
subscription.updatedБагц солигдсон, цуцлалт хүссэн эсвэл цуцлалт буцсан.
subscription.renewal_dueСунгалтын сануулга илгээгдсэн.
subscription.past_dueХугацаа хэтэрсэн (зөвхөн grace period тохируулсан бүтээгдэхүүн дээр).
subscription.canceledSubscription бүрэн цуцлагдсан — хэрэглэгчийн эрхийг энэ үед хаана.

Event бүрийн data.object-т subscription объект (customer, product, price мэдээллийн хамт) очно. Webhook тохиргоо болон гарын үсгийн шалгалтын талаар Webhook хуудаснаас уншина уу.