Skip to content

Instantly share code, notes, and snippets.

@opejovic
Last active February 12, 2024 10:10
Show Gist options
  • Save opejovic/b9645c60231338ffe260e5b31ccd51da to your computer and use it in GitHub Desktop.
Save opejovic/b9645c60231338ffe260e5b31ccd51da to your computer and use it in GitHub Desktop.

For production:

  • Invoices for the current month will be generated on the 1st of that month, or any day after that if onboarding a new agency/agent.
  • Subscriptions will be valid until the last day of that month, unless suspended

For testing purposes:

  • Billing period is set to 5 minutes
  • Subscriptions expire from when the invoice is generated + 5 minutes
  • Cron jobs will run every minute

  1. Populate .env with subscriptions stripe account.
    STRIPE_KEY=your-stripe-key 
    STRIPE_SECRET=your-stripe-secret
    STRIPE_WEBHOOK_SECRET=your-stripe-webhook-secret
    

https://dashboard.stripe.com/test/apikeys

  1. Run php artisan migrate

  2. Run php artisan tbsubscription-models:generate This will generate TbSubscription model for all the agents in the system, with an active status and expiration date set to null. Generate invoices command will then pick it up, and create an invoice for the given agent(s). When we create a new agent, we have a model event listener, that will create TbSubscription model for the new agent. User has one TbSubscription.

  3. Go to Super Admin -> Billing

    • Here you can set up agency fees, fee overrides, leader pays. If the fees are 0, we will still generate an invoice and mark it paid, but we won’t hit stripes API (nor would it allow us to)
    • Here you can also see agents from the agency, and filter them by the active / inactive status, and by the TB subscription status (which can be active and suspended). If the subscription is suspended, you can unsuspend the user here. Or suspend them for whatever reason. (Explore this more - when they suspend - un-suspend)
  4. Locally run php artisan schedule:work (!Important - Please terminate this process before you check out to a different branch)

    This will run a jobs on the cron. I’ve created a new Kernel.php file with only two jobs there

    1. GenerateInvoicesCommand This command will go through all agencies, depending on the billing option set on agency level, which can be Agency or Agent, it will generate the invoices for the running (current) month.

      • Agency Pay: We generate one invoice for the current period. That invoice will have as many line items as there active users in the moment of the invoice generation. Financially responsible user, bill_to field on the invoice will be agency admin.

      • Agent Pay: Two scenarios

        1. Agent pays for other agents (Super Admin -> Billing -> Agencies -> Leader Pay) One invoice will be generated for the Agent that pays for other agents which will include himself and the agents he pays for as the line items in the invoice, taking into consideration overrides fees (if any), and prorations.

        2. Agent pays only for himself One invoice will be generated for the Agent in question and will include only one line in the invoice, taking into consideration overrides fees (if any), and prorations.

      • If the agency / agent is onboarded after 1st in the month, or we start the billing process, we will have prorated fees. (For example, if the month has 30 days, and we push billing to production on 10th, and we set agency fee to be $30 - the fee per agent would be $20 for the that month)

        If in between of the billing cycles (which should be first of month, and last of month), we onboard/activate new agent(s), we will create additional invoice, with the the corresponding line item(s) (new agent(s)), and a prorated fee.

        Upon invoice generation - we will attempt to charge it automatically ONCE using the card on file. If the payment is successful (and is greater than $0), we will send out Invoice Paid email. If for whatever reason card is declined - we will mark the invoice as DECLINED, and send out Payment Declined email. If there is no card on file - the invoice will remain in the OPEN status.

        • If Agency pay billing option - admins can go in Agency Settings -> Billing -> Invoices, and click on PAY button. If no card is set up, they can go in Agency Settings -> Billing -> Subscription Billing Info, add a card and try again either by checking Pay open invoices when saving a card, or go back to invoices and choose an invoice they can pay.

        • If Agent pay is set up - agents can go to Billing -> Invoices, and click on PAY button. If no card is set up, they can go in Billing -> Subscription Billing Info, add a card and try again either by checking Pay open invoices when saving a card, or go back to invoices and choose an invoice they can pay.

    2. AutosuspendAccountsCommand This command will pick up any unpaid invoices, that are overdue (due_date in past), and suspend any account that is connected with it via invoice line item. In production - Suspension should occur only on the last Monday of the current month.

      When suspended, user will see a banner stating that their account has been suspended. Sidebar will have limited items:

      1. Billing
      2. Agency Settings -> Billing option (if user is agency admin)
      3. Support (they can ask support why is their account suspended if its not clear)
      4. Logout

      If all the unpaid invoice(s) get paid, users account will be unsuspended, and TbSubscription expiry date will be set to the latest generated invoice date (end of month), and new invoice will be generated (if necessary)

Test Cards

A few Stripe test cards that will result in successful payments: https://stripe.com/docs/testing#cards

BRAND NUMBER CVC DATE
Visa 4242424242424242 Any 3 digits Any future date
Visa (debit) 4000056655665556 Any 3 digits Any future date
Mastercard 5555555555554444 Any 3 digits Any future date
Mastercard (2-series) 2223003122003222 Any 3 digits Any future date
Mastercard (debit) 5200828282828210 Any 3 digits Any future date
Mastercard (prepaid) 5105105105105100 Any 3 digits Any future date
American Express 378282246310005 Any 4 digits Any future date

Card that will throw generic decline exception: (Attaching this card to a Customer object succeeds, but attempts to charge the customer fail.)

NUMBER CVC DATE
4000000000000341 Any 3 digits Any future date
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment