diff --git a/content/docs/ledger/getting-started/core-concepts.mdx b/content/docs/ledger/getting-started/core-concepts.mdx index 12dcbbef..14f61315 100644 --- a/content/docs/ledger/getting-started/core-concepts.mdx +++ b/content/docs/ledger/getting-started/core-concepts.mdx @@ -66,7 +66,7 @@ A **Wallet** is a digital balance tracked in Ledger. Wallets are polymorphic — Wallet operations: - **Credit** — manual credit, no gateway charge -- **Top-Up** — gateway-charged top-up via Stripe or QPay +- **Top-Up** — gateway-charged top-up via GNU Taler, Stripe, or QPay - **Transfer** — move funds between two wallets — produces two transactions (`transfer_out` and `transfer_in`) and one journal entry between the two wallet liability accounts - **Payout** — debit the wallet (e.g., driver earnings payout) - **Freeze / Unfreeze** — toggle status. The `is_frozen` attribute is a **computed accessor** derived from `status === 'frozen'` @@ -130,10 +130,11 @@ See [Transactions](/docs/ledger/payments/transactions). ## Payment Gateways -**Gateways** are payment processors with encrypted credentials. Ledger ships with three drivers: +**Gateways** are payment processors with encrypted credentials. Ledger ships with four drivers: | Driver | Capabilities | | :--- | :--- | +| `taler` | purchase, refund, wallet payment URI, refund URI, webhooks, diagnostics, settlement checks, sandbox | | `stripe` | purchase, refund, tokenization, setup_intent, checkout_session, webhooks, sandbox, recurring | | `qpay` | purchase, refund, webhooks, sandbox | | `cash` | purchase, refund | @@ -163,6 +164,6 @@ Storefront Checkout completes (order.type === 'storefront') Wallet flows: ``` -Customer top-up via Stripe → GatewayTransaction logged → Wallet Transaction (deposit, credit) → Journal entry (DEBIT Cash → CREDIT Wallet Liability) +Customer top-up via GNU Taler, Stripe, or QPay → GatewayTransaction logged → Wallet Transaction (deposit, credit) → Journal entry (DEBIT Cash → CREDIT Wallet Liability) Driver earning payout → Wallet Transaction (payout, debit) → Journal entry (DEBIT Wallet Liability → CREDIT Cash) ``` diff --git a/content/docs/ledger/getting-started/quickstart.mdx b/content/docs/ledger/getting-started/quickstart.mdx index 994a4d13..90215683 100644 --- a/content/docs/ledger/getting-started/quickstart.mdx +++ b/content/docs/ledger/getting-started/quickstart.mdx @@ -51,10 +51,10 @@ See [Settings](/docs/ledger/settings/overview) for the full reference. Navigate to **Ledger → Payments → Gateways**. - Click **New Gateway** and select **Stripe** (or **Cash** for offline / manual receipts). + Click **New Gateway** and select **GNU Taler**, **Stripe**, **Cash**, or **QPay**. Use Cash for offline or manual receipts. - Fill in the credentials shown by the form — for Stripe: **Publishable Key**, **Secret Key**, and **Webhook Signing Secret**. + Fill in the credentials shown by the form. GNU Taler requires a Merchant Backend URL, instance ID, API token, and supported currency; Stripe requires a publishable key, secret key, and webhook signing secret. Set **Environment** to `sandbox` while testing. @@ -129,6 +129,7 @@ When the customer pays: ## Next Steps - [Chart of Accounts](/docs/ledger/accounting/chart-of-accounts) — review the seeded accounts and add custom ones +- [Payment Gateways](/docs/ledger/payments/gateways/overview) — configure GNU Taler, Stripe, Cash, or QPay - [Wallets](/docs/ledger/payments/wallets) — manage driver, customer, company, and user wallets - [Reports](/docs/ledger/reports/overview) — generate balance sheets, income statements, AR aging, and the wallet summary - [Settings](/docs/ledger/settings/overview) — configure invoice prefixes, payment terms, default gateways, and fiscal year diff --git a/content/docs/ledger/index.mdx b/content/docs/ledger/index.mdx index e450535f..1adb91a3 100644 --- a/content/docs/ledger/index.mdx +++ b/content/docs/ledger/index.mdx @@ -18,7 +18,7 @@ description: Ledger is the accounting and invoicing extension for Fleetbase — | **Invoicing** | Create, send, and collect payment on invoices | | **Invoice Templates** | Customize the look of your invoices with company branding | | **Digital Wallets** | Track balances for drivers, customers, your company, and individual users | -| **Payment Gateways** | Stripe, QPay, and Cash — purchases, refunds, and webhook idempotency | +| **Payment Gateways** | GNU Taler, Stripe, Cash, and QPay - purchases, refunds, wallet payment flows, and webhook idempotency | | **Transactions** | Immutable audit trail for every wallet movement | | **Financial Reports** | Balance sheet, income statement, cash flow, trial balance, AR aging, wallet summary | | **Fleet-Ops Integration** | Auto-create draft invoices when a `PurchaseRate` is added to an order | @@ -32,7 +32,7 @@ description: Ledger is the accounting and invoicing extension for Fleetbase — - **Invoice** — a formal request for payment with line items, tax, and due date. Numbered `INV-` plus a 6-digit random integer (e.g. `INV-004821`). Lifecycle: draft → sent → viewed → partial / paid / overdue / cancelled / refunded / void - **Wallet** — a digital balance tied to a driver, customer, company, or user. Supports `credit`, `topup`, `transfer`, `payout`, `freeze`, `unfreeze`, and `recalculate` operations - **Transaction** — an immutable record of money moving relative to a wallet -- **Gateway** — a payment processor (Stripe, QPay, or Cash) with encrypted credentials, sandbox/live environment, and webhook idempotency via `GatewayTransaction` +- **Gateway** — a payment processor (GNU Taler, Stripe, Cash, or QPay) with encrypted credentials, sandbox/live environment, and webhook idempotency via `GatewayTransaction` ## Getting Started diff --git a/content/docs/ledger/payments/gateways.mdx b/content/docs/ledger/payments/gateways.mdx deleted file mode 100644 index e85f50e3..00000000 --- a/content/docs/ledger/payments/gateways.mdx +++ /dev/null @@ -1,123 +0,0 @@ ---- -title: Payment Gateways -description: Configure Stripe, QPay, and Cash payment gateways — credentials, capabilities, sandbox mode, webhooks, and the gateway transaction audit log. ---- - -# Payment Gateways - -**Payment Gateways** are the external services that process real money. Ledger ships with three drivers — Stripe, QPay, and Cash — and exposes a `PaymentGatewayManager::extend()` API for registering custom drivers from a service provider. - -Navigate to **Ledger → Payments → Gateways**. - -![Payment gateway details — driver, environment, credentials, and webhook URL](/images/screenshots/ledger/ledger-payment-gateway-details.webp) - -## Supported Gateways - -| Gateway | Driver | Use Case | -| :--- | :--- | :--- | -| **Stripe** | `stripe` | Card payments and digital wallets globally | -| **QPay** | `qpay` | Invoice-based payments for Mongolian banks | -| **Cash** | `cash` | Manual/offline payments and refunds | - -## Gateway Capabilities - -Each driver advertises the operations it supports. Check capabilities before invoking an operation. - -| Capability | Stripe | QPay | Cash | -| :--- | :---: | :---: | :---: | -| `purchase` | ✓ | ✓ | ✓ | -| `refund` | ✓ | ✓ | ✓ | -| `tokenization` | ✓ | — | — | -| `setup_intent` | ✓ | — | — | -| `checkout_session` | ✓ | — | — | -| `webhooks` | ✓ | ✓ | — | -| `sandbox` | ✓ | ✓ | — | -| `recurring` | ✓ | — | — | - -## Adding a Gateway - - - - Navigate to **Ledger → Payments → Gateways**. - - - Click **New Gateway**. - - - Enter a **Name** and select the **Driver** (stripe, qpay, or cash). - - - Fill in the fields shown by the driver's config schema (see below). - - - Set **Environment** to `sandbox` while testing, `live` for production. The boolean `is_sandbox` is kept in sync automatically. - - - Click **Save**. - - - -The form also exposes optional **Return URL** and **Webhook URL** fields. The system-generated webhook URL is displayed beneath the user-entered field for reference. - -## Stripe Configuration - -| Field | Description | -| :--- | :--- | -| **Publishable Key** | `pk_test_...` or `pk_live_...` | -| **Secret Key** | `sk_test_...` or `sk_live_...` | -| **Webhook Signing Secret** | `whsec_...` — from Stripe Dashboard → Webhooks | -| **Show Postal Code** | Whether the card field requires a postal code | -| **iDEAL Payment** | Enable iDEAL (Netherlands) | -| **FPX Payment** | Enable FPX (Malaysia) | - -Register the Ledger webhook URL (shown beneath the user-entered field on the gateway form) in the Stripe Dashboard so Stripe can notify Fleetbase of `charge.succeeded`, `charge.failed`, and `charge.refunded` events. - -## QPay Configuration - -| Field | Description | -| :--- | :--- | -| **Username** | QPay merchant username | -| **Password** | QPay merchant password | -| **Invoice Code** (`invoice_code`) | QPay invoice type code | - -## Cash Configuration - -The Cash driver supports `purchase` and `refund` and is useful for recording manual / offline payments and refunds without an external processor. - -| Field | Description | -| :--- | :--- | -| **Label** | Optional label shown to operators | -| **Instructions** | Optional payment instructions surfaced to customers | - -## Security - -Gateway credentials are: - -- Stored encrypted at rest using Laravel's `encrypted:array` cast against your `APP_KEY` -- Never exposed in API responses -- Decrypted only in memory when a payment operation is executed - -## Gateway Transaction Audit Log - -Every interaction with a gateway (charge, refund, webhook) is logged as a `GatewayTransaction`. The log is the **idempotency key store** — duplicate webhooks are deduplicated using `GatewayTransaction::isProcessed()`, a check on `(gateway_reference_id, event_type)`. - -View the log for any gateway: - -1. Open the gateway in Ledger -2. Click the **Transactions** tab - -The log includes status, amount, gateway reference ID, raw response, and processing timestamp — useful for debugging payment issues. - -## Extending with Custom Drivers - -Register a custom driver from a service provider: - -```php -use Fleetbase\Ledger\PaymentGatewayManager; - -PaymentGatewayManager::extend('mygateway', function () { - return new MyCustomDriver(); -}); -``` - -Your driver class implements the standard payment gateway contract (`charge`, `refund`, `getCapabilities`, `getConfigSchema`, etc.) and will appear in the gateway picker once registered. diff --git a/content/docs/ledger/payments/gateways/cash.mdx b/content/docs/ledger/payments/gateways/cash.mdx new file mode 100644 index 00000000..170f20af --- /dev/null +++ b/content/docs/ledger/payments/gateways/cash.mdx @@ -0,0 +1,21 @@ +--- +title: Cash +description: Configure the Cash gateway for manual and offline payment collection in Ledger. +--- + +# Cash + +The Cash gateway records manual or offline payment collection without contacting an external processor. Use it when an operator collects cash, bank transfer confirmation, cheque payment, or another offline receipt and needs Ledger to record the invoice payment. + +## Configuration + +| Field | Description | +| :--- | :--- | +| **Label** | Optional label shown to operators | +| **Instructions** | Optional payment instructions surfaced to customers or staff | + +## Behavior + +Cash supports purchases and refunds from Ledger's perspective, but it does not provide hosted checkout, webhooks, tokenization, or settlement verification. Operators are responsible for confirming that the money was collected before recording the payment. + +The resulting Ledger transaction and journal entry are still created, so reports and invoice balances remain consistent with other gateways. diff --git a/content/docs/ledger/payments/gateways/gnu-taler.mdx b/content/docs/ledger/payments/gateways/gnu-taler.mdx new file mode 100644 index 00000000..6ed2b085 --- /dev/null +++ b/content/docs/ledger/payments/gateways/gnu-taler.mdx @@ -0,0 +1,156 @@ +--- +title: GNU Taler +description: Configure the GNU Taler payment gateway for wallet payments, tenant-safe webhooks, refunds, diagnostics, and settlement checks. +--- + +# GNU Taler + +GNU Taler is a wallet-based digital cash gateway for Ledger. Customers pay an invoice from a Taler wallet, the Taler Merchant Backend sends Ledger a tenant-scoped webhook, and Ledger updates the invoice, gateway transaction log, refund state, and settlement metadata. + +Use GNU Taler when you need privacy-preserving wallet payments, a deployed Taler Merchant Backend, and auditable payment/refund records inside Ledger. + +## Requirements + +| Requirement | Description | +| :--- | :--- | +| **Merchant Backend URL** | Base URL for the Taler Merchant Backend, without private credentials in the URL | +| **Instance ID** | Taler merchant instance used by this Ledger gateway | +| **API Token** | Merchant Backend token with permission to create orders, read order status, issue refunds, and create/update webhooks | +| **Currency** | Currency accepted by the Taler exchange and configured for Ledger invoices | +| **HTTPS Webhook URL** | Public Ledger webhook URL reachable by the Taler Merchant Backend | + +Keep sandbox and production credentials outside the repository. Use environment variables, secret storage, or the encrypted Ledger gateway configuration. + +## Fleetbase Hosted Sandbox + +Fleetbase provides hosted GNU Taler sandbox services for Ledger testing: + +| Service | URL | Used For | +| :--- | :--- | :--- | +| **Merchant Backend** | `https://merchant.taler.fleetbase.io` | Ledger gateway API calls, order creation, refunds, webhooks, and settlement checks | +| **Exchange** | `https://exchange.taler.fleetbase.io` | Wallet exchange visibility and sandbox exchange diagnostics | +| **Bank** | `https://bank.taler.fleetbase.io` | Sandbox wallet funding and bank-side test operations | + +Ledger talks directly to the Merchant Backend. The exchange and bank endpoints support wallet funding, wallet trust/exchange visibility, sandbox testing, and operator diagnostics. + +When a GNU Taler gateway is in `sandbox` mode and the Merchant Backend URL is left blank, Ledger defaults to `https://merchant.taler.fleetbase.io`. Live gateways do not use this fallback and should always be configured with your production Merchant Backend URL. + +## Configure The Gateway + + + + Navigate to **Ledger -> Payments -> Gateways**. + + + Click **New Gateway** and select the `taler` driver. + + + Enter the Merchant Backend URL, instance ID, API token, and the currencies this gateway should accept. For Fleetbase hosted sandbox testing, you can leave the Merchant Backend URL blank or use `https://merchant.taler.fleetbase.io`. + + + Set the environment to `sandbox` for test wallets or `live` for production wallets. + + + Save the gateway, then open the gateway details screen. + + + Run **Test Credentials**, **Create Test Order**, and **Register Webhook** before enabling the gateway for invoices. + + + +## Admin Diagnostics + +The Taler gateway details screen includes operational checks for: + +| Diagnostic | Meaning | +| :--- | :--- | +| **Credential status** | Ledger can reach the Merchant Backend with the configured token | +| **Webhook registration** | Ledger registered or updated the Merchant Backend webhook callback | +| **Last webhook received** | Most recent Taler webhook accepted by Ledger | +| **Last payment event** | Most recent Taler payment event recorded in `GatewayTransaction` | +| **Last refund event** | Most recent Taler refund event, including wallet refund URI data | +| **Last settlement check** | Most recent reconciliation check against Taler order status or wire metadata | + +Non-Taler gateways may not expose every diagnostic action. Unsupported actions return an unsupported response instead of changing gateway state. + +## Webhook Payload + +Provisioned GNU Taler webhooks must post enough data for exact tenant-safe routing: + +```json +{ + "order_id": "order_123", + "company_uuid": "company_uuid", + "gateway_id": "gateway_public_id", + "event_type": "pay" +} +``` + +`gateway_uuid` can be used instead of `gateway_id` when the UUID is the identifier available to the provisioning flow. For provisioned webhooks, `order_id`, `company_uuid`, and one gateway identifier are required. + +Ledger rejects ambiguous multi-company Taler callbacks rather than selecting the first active gateway. Failed resolution is recorded as a failed gateway transaction so operators can diagnose unknown gateway, wrong company, or missing routing metadata. + +Duplicate Taler notifications are idempotent. Ledger keeps the gateway transaction key and includes gateway/company scope in duplicate handling and logs. + +## Payment Flow + +1. Ledger creates a Taler order for the invoice amount and stores the order reference. +2. The public invoice page shows the Taler payment URI or QR code. +3. The customer pays with a Taler wallet. +4. The Merchant Backend posts the tenant-scoped webhook to Ledger. +5. Ledger verifies the order state, records the gateway transaction, and marks the invoice paid or partially paid according to the normalized amount. +6. A Ledger transaction and journal entry are created for the invoice payment. + +If the webhook reports an unpaid or unknown order, Ledger records the event and leaves the invoice unpaid. + +## Refunds + +Taler refunds have two separate stages: + +| Stage | Ledger Behavior | +| :--- | :--- | +| Backend refund requested or approved | Ledger records the refund gateway transaction and normalized refund amount | +| Wallet refund URI returned | The internal refund response includes `taler_refund_uri` and `refund_url` for customer wallet processing | +| Wallet accepted | Ledger updates refund status when the accepted state is observable | +| Failed or expired | Ledger records the failed or expired outcome and keeps the invoice/payment history auditable | + +Partial refunds reduce the paid balance without forcing the invoice to fully refunded. Full refunds move the invoice to a refunded state once cumulative refunded amount reaches the paid amount. Refund reversals are linked to Ledger transactions and journal entries. + +## Settlement And Reconciliation + +Settlement verification checks paid Taler orders against the Merchant Backend order status. Ledger records the last settlement status, check timestamp, deposit totals, wire transfer identifiers, and raw Taler settlement fields when the backend exposes them. + +Some sandbox or backend responses may not include a stable wire transfer identifier. In that case Ledger marks the record as settlement checked rather than wire reconciled and stores the best available Taler fields for audit. + +## Sandbox E2E Validation + +Live sandbox validation is opt-in and should not run in normal CI. Configure the sandbox from environment variables or an encrypted gateway record: + +```bash +TALER_E2E_ENABLED=true +TALER_E2E_BACKEND_URL=https://merchant.taler.fleetbase.io +TALER_E2E_INSTANCE_ID=default +TALER_E2E_API_TOKEN=... +TALER_E2E_COMPANY_UUID=... +``` + +The acceptance flow is: + +1. Create or select a Taler gateway. +2. Create an invoice. +3. Start payment and pay with a sandbox wallet. +4. Receive the webhook and confirm the invoice moves to paid. +5. Issue a partial or full refund. +6. Confirm the refund URI is returned and the Ledger reversal is created. +7. Verify settlement or reconciliation metadata after the settlement check runs. + +Never commit real sandbox URLs, API tokens, wallet secrets, or private Merchant Backend credentials. + +## Production Runbook + +- Use HTTPS for the Ledger webhook URL. +- Scope the Merchant Backend token to only the permissions needed by Ledger. +- Register webhooks from the Ledger gateway details screen so `company_uuid` and gateway identifiers are included. +- Confirm diagnostics before enabling the gateway for public invoices. +- Keep gateway records company-scoped and avoid sharing one Merchant Backend instance across companies without tenant-safe webhook metadata. +- Monitor `GatewayTransaction` rows for failed webhooks, duplicate delivery, refund state, and settlement status. diff --git a/content/docs/ledger/payments/gateways/meta.json b/content/docs/ledger/payments/gateways/meta.json new file mode 100644 index 00000000..b66b6d90 --- /dev/null +++ b/content/docs/ledger/payments/gateways/meta.json @@ -0,0 +1,10 @@ +{ + "title": "Payment Gateways", + "pages": [ + "overview", + "gnu-taler", + "stripe", + "cash", + "qpay" + ] +} diff --git a/content/docs/ledger/payments/gateways/overview.mdx b/content/docs/ledger/payments/gateways/overview.mdx new file mode 100644 index 00000000..8dcd5fde --- /dev/null +++ b/content/docs/ledger/payments/gateways/overview.mdx @@ -0,0 +1,98 @@ +--- +title: Payment Gateways +description: Configure GNU Taler, Stripe, Cash, and QPay payment gateways in Ledger. +--- + +# Payment Gateways + +**Payment Gateways** connect Ledger to the services that collect, confirm, refund, and audit payments. Ledger includes drivers for **GNU Taler**, **Stripe**, **Cash**, and **QPay**, and exposes `PaymentGatewayManager::extend()` for registering custom drivers. + +Navigate to **Ledger -> Payments -> Gateways**. + +![Payment gateway details - driver, environment, credentials, and webhook URL](/images/screenshots/ledger/ledger-payment-gateway-details.webp) + +## Supported Gateways + +| Gateway | Driver | Use Case | +| :--- | :--- | :--- | +| [GNU Taler](/docs/ledger/payments/gateways/gnu-taler) | `taler` | Wallet-based digital cash payments, refunds, tenant-safe webhooks, and settlement checks | +| [Stripe](/docs/ledger/payments/gateways/stripe) | `stripe` | Card payments, digital wallets, hosted checkout, subscriptions, and global acquiring | +| [Cash](/docs/ledger/payments/gateways/cash) | `cash` | Manual or offline payment collection without an external processor | +| [QPay](/docs/ledger/payments/gateways/qpay) | `qpay` | Invoice-based payments for Mongolian banks | + +## Gateway Capabilities + +Each driver advertises the operations it supports. Check capabilities before invoking an operation. + +| Capability | GNU Taler | Stripe | Cash | QPay | +| :--- | :---: | :---: | :---: | :---: | +| `purchase` | Yes | Yes | Yes | Yes | +| `refund` | Yes | Yes | Yes | Yes | +| Hosted or wallet payment flow | Yes | Yes | No | Yes | +| Webhook confirmation | Yes | Yes | No | Yes | +| Refund URI or customer refund handoff | Yes | No | No | No | +| Settlement verification | Yes | Partial | No | Partial | +| `tokenization` | No | Yes | No | No | +| `setup_intent` | No | Yes | No | No | +| `checkout_session` | No | Yes | No | No | +| `sandbox` | Yes | Yes | No | Yes | +| `recurring` | No | Yes | No | No | + +## Adding a Gateway + + + + Navigate to **Ledger -> Payments -> Gateways**. + + + Click **New Gateway**. + + + Enter a **Name** and select the driver: `taler`, `stripe`, `cash`, or `qpay`. + + + Fill in the fields shown by the driver's configuration schema. + + + Set **Environment** to `sandbox` while testing and `live` for production. The boolean `is_sandbox` is kept in sync automatically. + + + Click **Save**. + + + +The form also exposes optional **Return URL** and **Webhook URL** fields. For webhook-capable drivers, Ledger displays the generated webhook URL that should be registered with the external gateway. + +## Security + +Gateway credentials are: + +- Stored encrypted at rest using Laravel's `encrypted:array` cast against your `APP_KEY` +- Never exposed in API responses +- Decrypted only in memory when a payment operation is executed +- Scoped to the company that owns the gateway record + +## Gateway Transaction Audit Log + +Every gateway interaction is logged as a `GatewayTransaction`: purchase attempts, payment confirmations, refunds, webhooks, and reconciliation checks. The log is also the idempotency store for webhook processing. + +View the log for any gateway: + +1. Open the gateway in Ledger. +2. Click the **Transactions** tab. + +The log includes status, amount, gateway reference ID, raw provider response, normalized event metadata, and processing timestamps. For GNU Taler it also carries tenant routing fields, refund URI metadata, and settlement or reconciliation details when available. + +## Extending with Custom Drivers + +Register a custom driver from a service provider: + +```php +use Fleetbase\Ledger\PaymentGatewayManager; + +PaymentGatewayManager::extend('mygateway', function () { + return new MyCustomDriver(); +}); +``` + +Your driver class implements the standard payment gateway contract (`charge`, `refund`, `getCapabilities`, `getConfigSchema`, etc.) and appears in the gateway picker once registered. diff --git a/content/docs/ledger/payments/gateways/qpay.mdx b/content/docs/ledger/payments/gateways/qpay.mdx new file mode 100644 index 00000000..09084168 --- /dev/null +++ b/content/docs/ledger/payments/gateways/qpay.mdx @@ -0,0 +1,24 @@ +--- +title: QPay +description: Configure QPay for Mongolian bank invoice payments in Ledger. +--- + +# QPay + +QPay is Ledger's invoice-based gateway for Mongolian bank payments. Use it when customers pay through supported Mongolian bank applications and Ledger needs to track the invoice payment through the gateway transaction log. + +## Configuration + +| Field | Description | +| :--- | :--- | +| **Username** | QPay merchant username | +| **Password** | QPay merchant password | +| **Invoice Code** (`invoice_code`) | QPay invoice type code | + +## Payment Flow + +Ledger creates a QPay invoice, surfaces the payment details to the customer, and records gateway transactions for the payment lifecycle. When QPay confirmation is available, Ledger uses the driver response and webhook handling to update the invoice payment state. + +## Testing + +Configure QPay sandbox credentials separately from production credentials. Keep the gateway in `sandbox` until invoice creation, payment confirmation, and refund handling have been verified with the merchant account. diff --git a/content/docs/ledger/payments/gateways/stripe.mdx b/content/docs/ledger/payments/gateways/stripe.mdx new file mode 100644 index 00000000..f2142a54 --- /dev/null +++ b/content/docs/ledger/payments/gateways/stripe.mdx @@ -0,0 +1,29 @@ +--- +title: Stripe +description: Configure Stripe for card payments, digital wallets, webhooks, refunds, and hosted checkout in Ledger. +--- + +# Stripe + +Stripe is Ledger's card and digital-wallet gateway for global payment collection. Use it for hosted checkout, saved payment methods, card refunds, setup intents, and recurring payment workflows. + +## Configuration + +| Field | Description | +| :--- | :--- | +| **Publishable Key** | `pk_test_...` or `pk_live_...` | +| **Secret Key** | `sk_test_...` or `sk_live_...` | +| **Webhook Signing Secret** | `whsec_...` from Stripe Dashboard -> Webhooks | +| **Show Postal Code** | Whether the card field requires a postal code | +| **iDEAL Payment** | Enable iDEAL for supported markets | +| **FPX Payment** | Enable FPX for supported markets | + +## Webhooks + +Register the Ledger webhook URL shown on the gateway form in the Stripe Dashboard. Stripe uses the webhook signing secret to let Ledger verify events before recording them. + +Ledger uses Stripe webhooks to confirm payment and refund events such as successful charges, failed charges, and refunded charges. Duplicate events are deduplicated through the gateway transaction log. + +## Testing + +Use `sandbox` while testing with Stripe test keys and switch to `live` only after webhooks have been verified. Keep test and live credentials in separate gateway records or environments so production traffic never uses sandbox keys. diff --git a/content/docs/ledger/payments/overview.mdx b/content/docs/ledger/payments/overview.mdx index dcb796ac..cc496cb5 100644 --- a/content/docs/ledger/payments/overview.mdx +++ b/content/docs/ledger/payments/overview.mdx @@ -13,7 +13,7 @@ Navigate to **Ledger → Payments** to access gateways, wallets, and transaction ### Payment Gateways -External payment processors — **Stripe**, **QPay**, and **Cash** — integrated with encrypted credentials and `sandbox`/`live` environments. All three drivers support both `purchase` and `refund` capabilities. Stripe additionally supports tokenization, setup intents, checkout sessions, webhooks, and recurring payments. Each gateway interaction is logged as a `GatewayTransaction` for idempotency and audit. See [Payment Gateways](/docs/ledger/payments/gateways). +External payment processors - **GNU Taler**, **Stripe**, **Cash**, and **QPay** - integrated with encrypted credentials and `sandbox`/`live` environments. All four drivers support `purchase` and `refund` capabilities. GNU Taler adds wallet payment URIs, tenant-safe webhooks, refund URIs, and settlement checks; Stripe adds tokenization, setup intents, checkout sessions, webhooks, and recurring payments. Each gateway interaction is logged as a `GatewayTransaction` for idempotency and audit. See [Payment Gateways](/docs/ledger/payments/gateways/overview). ### Wallets @@ -26,7 +26,7 @@ The complete, immutable ledger of every wallet movement. Transactions are never ## A Typical Payment Lifecycle ``` -Customer pays via Stripe (e.g. invoice payment or wallet top-up) +Customer pays via GNU Taler, Stripe, Cash, or QPay → GatewayTransaction logged (idempotency check) → PaymentSucceeded event fires → Ledger Transaction created (credit direction) @@ -38,7 +38,7 @@ The exact journal entries differ per source — see the per-flow examples on [Wa ## Webhook Security -All payment gateways send webhooks to confirm transactions. Each driver verifies its webhook signature before processing (Stripe via `Webhook::constructEvent`, QPay via its own driver). Duplicate webhooks are deduplicated using `GatewayTransaction::isProcessed()` — a check on `(gateway_reference_id, event_type)` — so each event is processed exactly once. +Webhook-capable gateways send callbacks to confirm transactions. Each driver verifies provider payloads before processing: Stripe validates signed events, QPay uses its driver verification, and GNU Taler requires exact tenant-safe routing with `order_id`, `company_uuid`, and a gateway identifier. Duplicate webhooks are deduplicated using `GatewayTransaction::isProcessed()` - a check on `(gateway_reference_id, event_type)` - so each event is processed exactly once. ## Multi-Currency diff --git a/content/docs/ledger/payments/wallets.mdx b/content/docs/ledger/payments/wallets.mdx index aa4e9cef..e29f173e 100644 --- a/content/docs/ledger/payments/wallets.mdx +++ b/content/docs/ledger/payments/wallets.mdx @@ -75,7 +75,7 @@ Each operation below is a button on the wallet detail panel. | Action | Effect | | :--- | :--- | | **Credit** | Manual credit (no gateway) | -| **Top-Up** | Gateway-charged top-up via Stripe or QPay | +| **Top-Up** | Gateway-charged top-up via GNU Taler, Stripe, or QPay | | **Transfer** | Move funds to another wallet | | **Payout** (sometimes labelled "Withdraw") | Debit the wallet (e.g., driver payout) | | **Freeze** | Set the wallet status to `frozen` | @@ -93,7 +93,7 @@ Journal entry: `DEBIT Cash → CREDIT Wallet Liability`. Transaction type: `depo ### Top-Up (deposit via gateway) -Charges a payment method via the chosen gateway (Stripe or QPay) and credits the wallet on success. +Charges a payment method via the chosen gateway (GNU Taler, Stripe, or QPay) and credits the wallet on success. Journal entry: `DEBIT Cash → CREDIT Wallet Liability`. Transaction type: `deposit`. diff --git a/content/docs/ledger/recipes/payment-gateway-driver.mdx b/content/docs/ledger/recipes/payment-gateway-driver.mdx index e24b3647..5b846d46 100644 --- a/content/docs/ledger/recipes/payment-gateway-driver.mdx +++ b/content/docs/ledger/recipes/payment-gateway-driver.mdx @@ -551,5 +551,5 @@ Before shipping a driver, confirm each of these in sandbox mode: ## Next Steps -- Read the existing drivers — `Fleetbase\Ledger\Gateways\StripeDriver`, `QPayDriver`, and `CashDriver` are the canonical references +- Read the existing drivers - `Fleetbase\Ledger\Gateways\TalerDriver`, `StripeDriver`, `QPayDriver`, and `CashDriver` are the canonical references - Use `Fleetbase\Ledger\PaymentGatewayManager` if you need to invoke gateways programmatically from outside Ledger