> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fusioncore.us/llms.txt
> Use this file to discover all available pages before exploring further.

# Stripe Troubleshooting

> Diagnose and fix common Stripe setup and payment problems in fusionCore

Use this page when Stripe payments are not working in your fusionCore org. Work through the checks in order. Most problems trace back to configuration on the **Payment Provider Account** record or the Stripe **webhook**, not to a code bug.

A few terms used below:

* **Payment Provider Account (PPA)** — the fusionCore record (`FCORE_PAY__Payment_Provider_Account__c`) that stores the connection to one Stripe account. This is where keys, the external id, and the signing secret live.
* **Webhook** — a URL Stripe calls to push events (payment succeeded, refunded, customer created) back into your org. Stripe sends these to `/services/apexrest/FCORE_PSTRIPE/Stripe`.
* **Validation** — running the **Validate** action on a PPA to confirm the keys, signing secret, and webhook all work end to end.

## The Payment Modal Does Not Load

If the Stripe card-entry window never appears when a member tries to pay, check the following.

<Steps>
  <Step title="Check the External Id">
    Confirm the Payment Provider Account has the correct `FCORE_PAY__External_Id__c`. For a connected account this is the Stripe connected-account id.
  </Step>

  <Step title="Check the Payment Type component">
    Confirm each `FCORE_PAY__Payment_Type__c` record has the correct value in its **Payment Component** field.
  </Step>

  <Step title="Check the Stripe keys">
    Confirm the Stripe public key and secret key are set correctly in the **Payment Provider Secret** custom metadata records.
  </Step>

  <Step title="Check user permissions">
    Confirm the current user is assigned the right Stripe permission set. Staff who process payments need `FC_Stripe_Access`; portal users need `FC_Stripe_Portal`.
  </Step>

  <Step title="Check that the account is validated">
    Confirm the Payment Provider Account has been validated and its `FCORE_PAY__Validation_Status__c` reads `Succeeded`.

    If validation fails with an error about the secret or public key in a **production** org, set `FCORE_PAY__Force_Test_Mode__c` (**Force Test Mode**) to true. In test mode the org serves the sandbox keys and accepts test webhooks even in production.
  </Step>

  <Step title="Check the connected account">
    Confirm the webhook is set up on the correct **connected account** in Stripe, not on the platform fusionCore/fusionSpan account. If the webhook lives on the platform account, the card and ACH modal hangs on loading.
  </Step>
</Steps>

## The Modal Loads but the Payment Hangs

If the member can enter card details, but clicking **Process Payment** hangs and no Payment Provider Event is created, the problem is almost always the webhook or the integration user.

<Steps>
  <Step title="Check the integration user permissions">
    Confirm the Stripe integration user is assigned the `FC_Stripe_Integration_User` permission set. Stripe calls the org back as this user; without access the callback is silently dropped.
  </Step>

  <Step title="Check the Request Signature Secret">
    Confirm `FCORE_PAY__Request_Signature_Secret__c` on the Payment Provider Account exactly matches the signing secret shown for the webhook in Stripe. A mismatched secret makes the org reject the webhook.
  </Step>

  <Step title="Recreate the payment customer">
    Try deleting the Payment Provider Customer record and letting it be recreated on the next payment attempt.
  </Step>

  <Step title="Check the webhook URL">
    In Stripe, confirm the webhook endpoint URL matches your org's URL and ends with `/services/apexrest/FCORE_PSTRIPE/Stripe`.

    The Stripe webhook view also lists every call Stripe has made. Find your payment (the `payment_intent`) in that list and open it to see why Stripe marked it failed.

    A `500` response means either an error on the fusionCore side or a webhook signature that was not set correctly, so access was denied (see the Request Signature Secret step above).
  </Step>

  <Step title="Check the subscribed events">
    If you see `200` responses in the Stripe API logs but payments still do not complete, confirm the webhook subscribes to the correct event types. See the full list in [Connected Account Webhook Set Up](/end-user-guides/stripe/connected-account-webhook-set-up).
  </Step>
</Steps>

## Limitations and Common Pitfalls

These behaviors come from how the Stripe addon works in code. Knowing them up front saves time during setup.

* **Validation is asynchronous.** Clicking **Validate** does not set `Succeeded` on its own. It creates a Stripe test customer and then waits for the inbound `customer.created` or `customer.updated` webhook to flip `FCORE_PAY__Validation_Status__c` to `Succeeded`. If the webhook is misconfigured, validation never completes even when your keys are correct. The customer event is also ignored unless it arrives within about 10 seconds of clicking **Validate**, so re-run validation if it has been longer.

* **Editing key fields resets validation.** Changing `FCORE_PAY__External_Id__c`, `FCORE_PAY__Request_Signature_Secret__c`, or `Stripe_MDT_Prefix__c` on the Payment Provider Account clears `FCORE_PAY__Validation_Status__c` automatically. You must re-run **Validate** after any such edit.

* **External Id must be unique.** Two Payment Provider Account records cannot share the same `FCORE_PAY__External_Id__c`; the org throws "Multiple Payment Provider Accounts were found with the same External Id." A missing or unknown External Id throws "Payment Provider Secret Not Found."

* **Failed webhooks are easy to miss.** When the org rejects an inbound webhook — missing or malformed `Stripe-Signature` header, a signature that does not match any active PPA's signing secret, or a request older than 300 seconds — it returns HTTP `204`, not an error. Stripe sees a success and will not retry. Check the Stripe API logs and the webhook delivery list rather than waiting for a retry.

* **Events for other orgs or the wrong mode are dropped silently.** A webhook whose metadata org id does not match this org is rejected with `204`. A production-versus-sandbox mismatch on Stripe's `livemode` flag causes the event to return early and do nothing. Confirm you are sending from the right Stripe account and mode.

* **Subscribe only to the handled event types.** Sending an unsupported event type causes an error response and noise in the Stripe API log. Use exactly the events listed in [Connected Account Webhook Set Up](/end-user-guides/stripe/connected-account-webhook-set-up).

* **Alipay and WeChat Pay require Stripe Direct.** These payment methods are blocked on a standard connected-account setup. Saving a Payment Type for them errors with "This payment method is not available with current Stripe setup." They require the `EnableDirectStripeInstance` feature parameter turned on. See [Stripe Direct Accounts](/end-user-guides/stripe/stripe-direct-accounts/index).

* **Pending payments auto-cancel after a timeout.** Payments left in `requires_action` are cancelled after a method-specific window: Card after 60 minutes, ACH after 7 days, Alipay and WeChat Pay after 5 minutes. If a member takes too long to complete 3-D Secure or microdeposit verification, the payment is cancelled.

* **Large wallet charge batches can partially fail.** Charging saved payment methods runs inline and stops at the Salesforce callout limit (or about 110 seconds), marking remaining events **Failed** with "Callout limit exceeded." Split very large batches.

* **Do not flip a live account into test mode, or switch connection models on a live account.** Both change how money is routed and which keys are used. Keep a separate test Payment Provider Account instead. See [Stripe testing — production and sandbox](/end-user-guides/stripe/stripe-testing-production-sandbox).

If every check above passes and payments still fail, the issue may be in the code. Capture the relevant `Stripe_API_Log__c` records and the Stripe webhook delivery details, then contact the fusionCore team.
