P PoriFyx - Create AI-powered chat docs

Platform admin

Bank transfers & manual payments

Bank transfer is a fourth way for customers to pay, next to Stripe, PayPal and Razorpay. It also covers cash, cheques or any other offline payment. The customer reports the payment from the billing page; you check that the money arrived and approve it. A plan only starts after your approval, and only for the period that was paid.

Turn it on

Go to Settings โ†’ System โ†’ Billing (as a super admin) and open the Bank transfer card:

FieldWhat it does
Offer bank transfer to customers Shows the option on every customer's billing page. Off by default.
Payment instructions Where the money goes: bank, account holder, IBAN or account number, SWIFT / BIC, anything else the customer needs. Shown next to the exact amount. Required to switch the option on โ€” without instructions it stays hidden.
Reference prefix (optional) Letters, digits and dashes, up to 12. Each workspace gets a suggested payment reference such as PB-1A2B3C4D (prefix + a code that is fixed per workspace), so you can match transfers on your bank statement.

The values are stored in app_settings (manual_payments_enabled, manual_payments_instructions, manual_payments_reference_prefix) and applied like the other gateway settings. If you serve the app with Octane, reload the workers after saving (php artisan octane:reload).

Amounts are always quoted in the platform currency (CASHIER_CURRENCY, the currency plan prices are entered in). A monthly plan can be paid per month at its price, and per year when the plan has a yearly price. A plan billed yearly is paid per year. Free, custom and lifetime plans are not offered by bank transfer.

What the customer does

On /app/billing the customer chooses a plan and Bank transfer, then sees the amount, your instructions and the suggested reference. After transferring, they submit the reference (they can change it, and add a note). The workspace stays on its current plan, and the billing page shows Payment pending approval with the reference. See Billing & plans for the customer side.

  • One payment per workspace can wait for approval at a time.
  • Refused while the workspace still has a live Stripe, PayPal or Razorpay subscription, so nobody pays twice. The customer cancels that subscription first.
  • The amount is stored with the payment when it is submitted, so a later price change never changes what you are asked to match.

Approve or reject

New payments appear under Pending payments in the admin sidebar (/admin/manual-payments), and the admin bell shows how many are waiting. Each row shows the workspace, plan, period, amount, reference, the customer's note and, for pending payments, the date the plan would run until if you approve now.

Approve only once the money is in your account. Approval is the only thing that activates a plan for a bank transfer, and only platform super admins can do it.

Approve does what a paid PayPal or Razorpay subscription does:

  • sets the workspace's plan and payment_gateway = manual;
  • writes the workspace's plan_subscriptions row (gateway = manual, status = active, the period end) โ€” so an expired trial is unlocked right away;
  • adds the payment to the customer's order history on the billing page;
  • emails the workspace owner a confirmation with the end date.

The period runs one month or one year from the approval. When the workspace is still inside a bank-transfer period, the new period starts where the current one ends, so paying early never loses days (a renewal approved on 5 February for a period ending 15 February runs 15 February โ€“ 15 March). A payment for another plan switches the plan at approval.

Reject asks for a reason. The workspace keeps its plan, the owner receives the reason by email, and the billing page shows it until the customer submits a new payment.

Renewal reminders and the end of a period

A bank transfer does not renew by itself. The scheduled command billing:process-manual-payments (hourly, see routes/console.php) handles both ends:

  • Reminder โ€” 7 days before a period ends, the owner gets one email asking for a new payment. It is sent once per paid period, and skipped while a renewal already waits for approval.
  • End of period โ€” when the period has ended and no newer payment was approved, the workspace falls back exactly like an ended PayPal or Razorpay subscription: the plan_subscriptions row becomes canceled, the workspace moves to the plan with slug free and the gateway is cleared. Agents, sources and conversations are kept.

The scheduler must run (php artisan schedule:run every minute from cron, see Deployment). You can also run the command by hand; it is safe to repeat. Use --days=N to change the reminder window.

Keep a plan with the slug free. Without one, an ended period โ€” like an ended PayPal or Razorpay subscription โ€” records the end but leaves the workspace on its paid plan.

Data

Each reported payment is a row in manual_payments: workspace, plan, period (month / year), amount_cents, currency, reference, note, status (pending / approved / rejected), who submitted and who decided, decided_at, rejection_reason, the paid period (period_starts_at, period_ends_at) and expiry_reminder_sent_at. Rows are scoped to their workspace like every tenant table; customers only ever see their own workspace's payments.