Help centre

How can we help?

Guides, FAQ, and integration walkthroughs. Search or browse by topic.

← All topics

Stripe

Stripe payments

Accept card, Apple Pay and Google Pay on any invoice. Payment status flows back into the CRM automatically via webhooks so you never chase a paid invoice again.

Before you start

  • A Stripe account with your business details already verified. Set up at dashboard.stripe.com/register. Verification takes 1-3 business days.
  • Your bank account already added to Stripe's Payouts settings, or your first payments will sit in "pending" until you add one.
  • Access to your CRM domain's DNS if you want to use a custom checkout domain (optional).
  • 10 minutes for the setup, plus one test payment through the flow before you go live.

Current UI limitation

The Settings > Integrations > Payment > Stripe card in the CRM currently only shows a Configure Stripe button that opens the admin Stripe page - and that admin page does not yet have a first-time key entry form. Until the admin UI ships, you have two options:

  • Ask support (email andrew@validusmedia.com) to paste your sk_live_... key into the settings table under key stripe_secret_key, scoped to your company ID.
  • If you have database access, run: INSERT INTO settings (company_id, `key`, value) VALUES (<your_company_id>, 'stripe_secret_key', 'sk_live_...') ON DUPLICATE KEY UPDATE value = VALUES(value);

The rest of this guide assumes the key is in the database. Everything else (webhook, payment link flow) works today.

Step 1: Get your live secret key

  1. Log in to dashboard.stripe.com.
  2. In the top-right, toggle from Test mode to Live mode (unless you are still testing, in which case leave it in test).
  3. Click Developers in the top-right menu, then API keys.
  4. Under Standard keys, find the Secret key row.
  5. Click Reveal live key. Copy the string starting with sk_live_.

This key is bearer credential

Anyone with this key can charge your customers, refund arbitrary amounts, and transfer money to a bank account they add. Treat it like the master password. Never paste it into Slack, email, or a support ticket outside the CRM. If you ever leak it, immediately click Roll key next to it in the dashboard.

Step 2: Get the key into the CRM

See the warning at the top of this guide. Either forward the key over an encrypted channel to support, or run the SQL insert yourself.

To confirm the key is saved, go to Settings > Integrations > Payment > Stripe and click Configure Stripe. If the connection is working, the admin page shows your Stripe account name in the top banner.

Step 3: Add the webhook endpoint

Without the webhook, the CRM never learns that a payment succeeded. Invoices stay in "Sent" forever and you look silly chasing paid customers.

  1. In the Stripe dashboard, go to Developers > Webhooks.
  2. Click Add endpoint.
  3. Set Endpoint URL to: https://your-crm-domain.com/api/stripe_webhook.php
  4. Under Select events to listen to, tick these six:
    • checkout.session.completed
    • payment_intent.succeeded
    • payment_intent.payment_failed
    • charge.refunded
    • invoice.paid
    • invoice.payment_failed
  5. Click Add endpoint.
  6. On the endpoint detail page, click Reveal next to Signing secret. Copy the string starting with whsec_.

Step 4: Save the webhook signing secret

Same procedure as the secret key: either ask support or run:

INSERT INTO settings (company_id, `key`, value)
VALUES (<your_company_id>, 'stripe_webhook_secret', 'whsec_...')
ON DUPLICATE KEY UPDATE value = VALUES(value);

The signing secret is what stops someone hitting your /api/stripe_webhook.php endpoint with a fake "payment succeeded" event and marking their own invoice as paid.

Step 5: Trigger a test event

  1. Back on the Stripe webhook endpoint detail page, click Send test webhook.
  2. Choose payment_intent.succeeded.
  3. Click Send test webhook.
  4. You should see a green tick and HTTP 200 response. If you see anything else, click through to the delivery detail - it will show the actual error the CRM returned.

Step 6: Create your first payment link

  1. In the CRM go to Invoices (or Quotes).
  2. Open any draft invoice.
  3. Click Send payment link. This calls POST /api/payment_links.php which creates a Stripe Checkout Session and returns the URL.
  4. Choose the delivery channel: email, SMS, or copy to clipboard.
  5. The customer clicks the link, pays via Stripe-hosted checkout, and the webhook fires checkout.session.completed. The invoice status flips to Paid within 5 seconds.

How to test it works

  1. Create a test invoice for 1 GBP (or 1 USD).
  2. Click Send payment link and open the resulting URL in an incognito window.
  3. Pay with a real card (Stripe charges on live keys, so use a small amount).
  4. Refresh the invoice page in the CRM. Status should be Paid within 10 seconds.
  5. Check the contact's activity timeline - a Payment received entry should appear.
  6. Refund the test charge from the Stripe dashboard. The invoice status should update to Refunded via the charge.refunded event.

Common problems

Webhook shows HTTP 400 "invalid signature"
Wrong webhook signing secret. Re-copy from Stripe (careful - each endpoint has its own secret) and re-save.
Webhook shows HTTP 500
PHP error in /api/stripe_webhook.php. Check the CRM error log. Most commonly caused by the invoice ID in metadata not existing (the invoice was deleted between link creation and payment).
Payment link creation returns "No API key provided"
The Stripe secret key is not saved in the database. Redo step 2.
Payment succeeds but invoice stays "Sent"
Webhook not firing. In Stripe dashboard, go to the webhook endpoint and check the Events tab. If it shows failed deliveries, click one and read the error. If it shows no events at all, the endpoint URL is wrong or your CRM is not publicly reachable from AWS us-east-1.
Apple Pay / Google Pay buttons do not show up
Stripe requires domain verification for wallet buttons. Go to Settings > Payments > Payment methods > Apple Pay > Add domain in Stripe and upload the verification file to /.well-known/apple-developer-merchantid-domain-association. This is separate from the CRM setup.
Test key works but live key returns "No such customer"
You pasted the wrong-mode key. Test keys start sk_test_, live keys start sk_live_. Look at the prefix carefully.

What this unlocks in the CRM

Every invoice can now be paid instantly by card. The Invoices module tracks paid vs outstanding in real time. The MRR module reads Stripe subscriptions if you have any. Payment activity appears on the contact timeline. And the receptionist can take deposits mid-call if you also wired that up. Once Stripe is live you can also enable Direct Debit via GoCardless for lower fees on recurring customers - see that guide.

Still stuck?
Email us and we’ll come back within one business day.
info@unavoidablecrm.com