Skip to main content

Overview

Stripe handles all payment processing. The integration uses Stripe Connect for marketplace-style payments: students pay the platform, the platform pays tutors. File: app/Models/Services/Payments/StripeService.php SDK: stripe/stripe-php v7.2

Configuration

STRIPE_SECRET              — Stripe secret API key
STRIPE_SIGNING_SECRET      — Webhook signing secret (payment events)
STRIPE_SUBSCRIPTION_SIGNING_SECRET — Webhook signing secret (subscription events)
STRIPE_VERSION             — Stripe API version
BUSINESS_PROFILE_MCC_CODE  — Merchant category code
Config file: config/services.php under stripe key.

Account types

Two types of Stripe accounts are used:
TypePrefixOwnerPurpose
Customercus_*Student/ParentHolds payment methods, makes charges
Connectacct_*TutorReceives payouts
Both stored in payment_accounts table, linked to payment_gateways.

Key operations

Customer management

StripeService::createCustomer($user)
Creates a Stripe Customer, stores the ID in PaymentAccount. Called during registration or first payment.

Card management

StripeService::createCard($user, $data)
// Validates card, creates PaymentMethod, attaches to customer, sets as default

StripeService::validateCard($data)
// Validates card without saving — used for pre-validation
Cards stored in the cards table with card_id, brand, last_4, exp_month, exp_year, is_default. Soft-deleted when removed.

Charging & payment flow

The full charge → capture → receipt → payout flow is documented in Booking & Payments. Key StripeService methods:
MethodPurpose
createCharge()Creates PaymentIntent with manual capture, handles 3D Secure
capture()Captures a pre-authorized payment
createReceipt()Creates PaymentReceipt with commission breakdown
createPayout()Transfers funds to tutor’s Connect account
refund()Full or partial refund

Subscriptions

Tutors pay a subscription fee to use the platform.
StripeService::createSubscription($user, $product)
StripeService::createSubscriptionWithTrial($user, $product, $trialEndDate)
Subscription products are defined in the subscription_products table with product_id, price_id, and trial_period.

Billing portal

StripeService::getCancelSubscriptionCustomerPortalURL($paymentAccount)
StripeService::getUpdatePaymentMethodSubscriptionCustomerPortalURL($paymentAccount)
Generates Stripe Customer Portal URLs for self-service subscription management.

Subscription statuses

Tracked in the subscriptions table:
StatusMeaning
trialingIn trial period
activeActive and paying
canceledCancelled
incompletePayment failed, awaiting retry
incomplete_expiredPayment failed, subscription ended

Webhooks

Payment webhooks

Endpoint: POST /api/v1/payments/webhooks/accounts Validates webhook signature using STRIPE_SIGNING_SECRET.

Subscription webhooks

Endpoint: POST /api/subscriptions/webhooks
StripeService::handleSubscriptionWebhook($request)
Validates signature using STRIPE_SUBSCRIPTION_SIGNING_SECRET. Updates subscription status in the database based on Stripe events.
Both webhook endpoints are public (no auth middleware). Security relies entirely on Stripe’s webhook signature verification.

Payment status flow

See Booking & Payments — Step 3 for the full payment flow with booking state transitions.
PaymentIntent created (manual capture)
├── requires_action → Client handles 3D Secure → succeeds/fails
├── requires_capture → Booking state: REQUIRES_CAPTURE (5)
│   └── capture() → Booking state: PAYED (1)
│       └── createPayout() → Transfer to tutor Connect account
├── succeeded → Booking state: PAYED (1)
└── canceled/failed → Payment failed