> For the complete documentation index, see [llms.txt](https://docs.flycode.com/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.flycode.com/docs/integrations/stripe-integration-guide-for-flycode.md).

# Stripe integration guide: connect FlyCode to Stripe Billing

Connect FlyCode to Stripe Billing step by step: prerequisites, installing the verified Stripe app, retry and email settings to change, API calls, go-live checklist.

{% hint style="info" %}
**TL;DR:** Install the verified FlyCode app from the Stripe App Marketplace, set Stripe's own retry and recovery email settings so they do not compete with FlyCode, and activate the app. No code, no webhook endpoints to build. FlyCode then retries failed subscription invoices through the Stripe API with per-merchant machine-learning timing, and every action appears in your Stripe dashboard. Setup takes under an hour; the model tunes itself over the first 6 to 8 weeks.
{% endhint %}

## Who this is for

Subscription businesses billing through Stripe Billing (subscriptions and invoices) that want to recover more failed payments than Stripe Smart Retries alone. If you bill through Shopify, Recharge, Skio, Braintree or PayPal, see [Supported payment and subscription platforms](https://docs.flycode.com/docs/integrations/supported-payment-and-subscription-platforms).

## How FlyCode differs from Stripe's built-in recovery

{% embed url="<https://youtu.be/Ok0Emw2Veb0?si=hbKWbaOXUBMUig3b>" %}

Stripe Smart Retries apply one retry strategy trained across all Stripe merchants and cap attempts at 8 per invoice. FlyCode trains a model on your own transactions and issuer responses, chooses the retry moment per invoice, coordinates emails with retries instead of emailing at every attempt, and can charge a backup card on file. Merchants typically recover about 20 percent more failed payments, a 5 to 9 percent lift in ARR. Details: [Stripe Smart Retries complete guide](https://docs.flycode.com/docs/stripe-smart-retries-complete-guide).

## Prerequisites

* A Stripe account using Stripe Billing for subscriptions, with permission to install apps (Administrator or Developer role).
* Access to Stripe's Revenue Recovery settings (Settings, Billing, Revenue recovery).
* A FlyCode account. If you do not have one yet, [get started here](https://www.flycode.com/get-started); installation from the marketplace also starts the sign-up flow.
* Optional: if you want FlyCode to send recovery emails from your domain, the ability to add SPF and DKIM DNS records for a sending subdomain.

## Setup

{% stepper %}
{% step %}

### Install the FlyCode app

Open the [FlyCode app on the Stripe App Marketplace](https://marketplace.stripe.com/apps/flycode-payments) and click Install. Review and confirm the permissions Stripe shows: FlyCode reads customers, subscriptions, invoices, payment intents and charges, and writes invoice metadata, invoice payments and subscription status. Nothing else. On installation FlyCode loads every invoice currently in an error state so recovery starts on your existing past-due book, not only on new failures.
{% endstep %}

{% step %}

### Configure Stripe's retry settings

Go to [Revenue recovery, Retries](https://dashboard.stripe.com/revenue-recovery/retries) and make these changes in this order.

1. **Subscription and invoice status after failed recovery:** set to "leave as past-due". This lets FlyCode manage post-recovery statuses without Stripe cancelling subscriptions on its own schedule.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXf8LiLHfxcXh5CWORAuRm844fCWfvod6i08jJHOvts16HP3JSLhqog6qa45jboJ_luR9995sSycnhPcwbT2YCgtKY8jwoeES9v35bn4nV_3Ff6NQi4t8q7S9tuL3v3A5zU9aDoq?key=fnT4URI1uQRIKM025_99dnW4" alt="" width="375"><figcaption><p>Revenue recovery, Retries tab: status after failed recovery</p></figcaption></figure>

2. **Card retries:** choose "Custom" and set 3 retries with a 7-day interval, for a maximum recovery period of 7 days. This keeps Stripe's own retries to a minimum so FlyCode's engine controls retry timing.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfSC3ZSTInagXI5kX4mdAYhvWe0JuYkqRrya4y1sDdN-Btpd1kS7zHdGHw24NssRkC5jL24TrQC25dYYsojckDl83rVo_KXYBWIL3kQ0PsBMkuBF4T6UEWUgmXH_3DI8DOxwMsSXA?key=fnT4URI1uQRIKM025_99dnW4" alt="" width="375"><figcaption><p>Revenue recovery, Retries tab: custom card retries</p></figcaption></figure>

3. **ACH retries:** if you accept ACH, leave the ACH retry toggle on. FlyCode's card recovery does not replace Stripe's bank debit retries.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXcC6Kplr231bnvbiqH21475nZbnhKxCMhhpV4AU2cn1a0-1WMjCz-D3xhroUjUS8HsyCyast7XwAHlXCwK9ac8cdIhBiFAOKCNRu5STVaoKuRsOqLd3lmTia8c1Plg9cQxr0Wr7?key=fnT4URI1uQRIKM025_99dnW4" alt="" width="375"><figcaption><p>Revenue recovery, Retries tab: ACH</p></figcaption></figure>
{% endstep %}

{% step %}

### Configure Stripe's email settings

Go to [Revenue recovery, Emails](https://dashboard.stripe.com/revenue-recovery/emails).

1. **Failed payment emails:** if you are using FlyCode's recovery notifications (recommended), turn off Stripe's default payment recovery emails so customers do not receive two sets of messages.
2. **Failed ACH debit emails:** if you accept ACH, keep these on.
3. **Card reminder emails:** keep Stripe's card reminder emails enabled.

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXdfnN9iSNdpY2m2X9AJuDFoMG9cIrD0kl490zCliPm7Eeyo8BbwogjT3Qsm7gUkT6yO5BqDcbvx-BwII6xRJEu5R_ja8ObfmQGv0_6y72VKwOIeLNzaLZkukokAGfGbT5nW47pr4Q?key=fnT4URI1uQRIKM025_99dnW4" alt="" width="563"><figcaption><p>Revenue recovery, Emails tab: failed payments</p></figcaption></figure>

<figure><img src="https://lh7-rt.googleusercontent.com/docsz/AD_4nXfekYhFi3VT4xem6fxom2CKN_DxzqvCLs2FKoifzGIB3KTn5U1nPeMvpwb96sQqzWrucCKfm0XKeYTsN8n8SP2XCpKVnNXSsWrP00DXdCaU8yNndzLuMpeBscSULro6QAJdQMMuGw?key=fnT4URI1uQRIKM025_99dnW4" alt="" width="563"><figcaption><p>Revenue recovery, Emails tab: card reminders</p></figcaption></figure>
{% endstep %}

{% step %}

### Set FlyCode preferences and activate

In FlyCode, confirm two preferences: the retry mode (leave the default model-driven schedule unless you have a reason not to) and whether FlyCode sends recovery emails on your behalf. If it does, add the SPF and DKIM records FlyCode gives you so messages authenticate from your domain. Then activate the app. FlyCode begins working on open failed invoices immediately.
{% endstep %}
{% endstepper %}

## How the integration works

The FlyCode app connects your Stripe account to FlyCode's recovery engine. It listens to Stripe webhook events for real-time updates about subscriptions and payments, passes the relevant data to the engine, and executes the engine's decisions through the Stripe API. Everything is executed transparently and reflected in your Stripe dashboard.

<figure><img src="https://857825088-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FedoXR9BFShbgporwvi7n%2Fuploads%2FDsdjL8f9JtDrw6zLI267%2Fimage1.jpg?alt=media&#x26;token=dd0145a5-f69c-463c-98eb-7d4b0529fa45" alt="" width="542"><figcaption><p>FlyCode architecture</p></figcaption></figure>

### What FlyCode reads: webhook events

The app subscribes only to the Stripe events needed for recovery and subscription management: invoice events (created, finalized, payment failed, paid, updated), payment intent and charge events (payment failed, succeeded), and customer and subscription events (created, updated, deleted). These give the engine the decline code, card and issuer details and account history it needs to time each retry. The app uses its own app-scoped event subscription and does not touch webhook endpoints created by your team or by other apps.

### What FlyCode writes: Stripe API calls

These are the only write (POST) calls the FlyCode app makes. Each is logged in the Stripe developer portal and visible on the relevant object in the dashboard.

| Action                                                         | Stripe API call                                                                                                                                                 | When                                                                                      | What you see in Stripe                                                                                          |
| -------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| Mark an invoice as in recovery                                 | [Update Invoice](https://docs.stripe.com/api/invoices/update): adds metadata `flycode_recovery: true`                                                           | When a failed subscription invoice enters recovery                                        | Metadata field on the invoice page; Update Invoice entry in the invoice event log                               |
| Retry a failed invoice                                         | [Pay Invoice](https://docs.stripe.com/api/invoices/pay)                                                                                                         | When the engine decides the retry moment                                                  | Entry in the invoice's Recent Activity; new charge under the original payment intent (no extra payment objects) |
| Cancel an unrecoverable subscription (optional, on by default) | [Cancel Subscription](https://docs.stripe.com/api/subscriptions/cancel), with `cancellation_details`                                                            | After the maximum number of retries without success                                       | Subscription shown as canceled with the cancellation event                                                      |
| Close the unrecovered invoice (optional, on by default)        | [Void Invoice](https://docs.stripe.com/api/invoices/void) or [Mark Uncollectible](https://docs.stripe.com/api/invoices/mark_uncollectible), per your preference | Same moment as cancellation; also applied to later open invoices on the same subscription | Invoice status void or uncollectible with the event logged                                                      |

Before every write, the app re-reads the current state of the Stripe object. If an invoice was already paid, voided or cancelled by another system, FlyCode takes no action. This makes the integration idempotent and prevents duplicate charges or status conflicts.

{% hint style="info" %}
**Safeguard:** a subscription is never cancelled if any invoice created after the unrecoverable one has been paid. A subscription that became healthy by other means stays active.
{% endhint %}

{% hint style="info" %}
**Recommended:** the cancellation and invoice clean-up steps are optional but on by default. Keeping them on stops further attempts on dead invoices and keeps subscription and invoice statuses accurate for your customers and your reporting.
{% endhint %}

<figure><img src="https://857825088-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FedoXR9BFShbgporwvi7n%2Fuploads%2F69gUGUrHMFaGXueBmCPd%2Fimage3.jpg?alt=media&#x26;token=63dcf447-dfee-4d05-9ce2-b79f564e2fd4" alt="" width="524"><figcaption><p>Invoice event log showing the FlyCode metadata update</p></figcaption></figure>

<figure><img src="https://857825088-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FedoXR9BFShbgporwvi7n%2Fuploads%2FIw88HdPBqMOhHGVIsPcI%2Fimage4.jpg?alt=media&#x26;token=f1d55931-473a-4614-aeef-4cee8e1a8c20" alt="" width="531"><figcaption><p>Invoice page after a successful FlyCode retry</p></figcaption></figure>

<figure><img src="https://857825088-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FedoXR9BFShbgporwvi7n%2Fuploads%2FI3Or6eUzg7hleYnVtLNe%2Fimage06.jpg?alt=media&#x26;token=42d63a19-8ffe-40ca-bd21-76ffb65b62e5" alt="" width="541"><figcaption><p>Payments view: the retry is a new charge under the original payment intent</p></figcaption></figure>

<figure><img src="https://857825088-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FedoXR9BFShbgporwvi7n%2Fuploads%2FMSgXsfY1E5EayitNSiNG%2Fimage08.jpg?alt=media&#x26;token=82503ad3-16b6-43e0-816f-b3eb0e8f315e" alt="" width="563"><figcaption><p>Subscription page after cancellation by FlyCode</p></figcaption></figure>

### Recovery emails

For the best results and a consistent brand experience, disable Stripe's default recovery emails and use FlyCode's notifications. They are triggered by the engine in sync with the retry schedule (no email after a soft decline while a retry still has a good chance), sent from your own domain in your brand language, and timed to the customer's local hours. See [Failed Payment Outreach](https://help.flycode.com/failed-payment-outreach).

## Go-live checklist

* [ ] FlyCode app installed and permissions confirmed
* [ ] Stripe retries: status after failed recovery set to "leave as past-due"
* [ ] Stripe retries: card retries set to Custom, 3 retries, 7-day interval
* [ ] Stripe retries: ACH retries left on (if applicable)
* [ ] Stripe emails: default failed payment emails turned off (if FlyCode sends notifications)
* [ ] Stripe emails: failed ACH debit emails on (if applicable), card reminder emails on
* [ ] FlyCode: retry mode and notification preference set; SPF and DKIM records added if FlyCode sends email
* [ ] FlyCode app activated

## What to expect after going live

**Open invoices in recovery.** In Stripe, open Invoices and apply [this filter](https://dashboard.stripe.com/invoices?status=open\&total\[gt]=0\&type=subscription) (status open, subscription invoices, total above zero). Click "Edit columns" and add "FlyCode Recovery (metadata)" to see the recovery flag on each row.

<figure><img src="https://857825088-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FedoXR9BFShbgporwvi7n%2Fuploads%2FTNup2iuvGqgEOMSaOlyo%2Fimage20.jpg?alt=media&#x26;token=9e45d171-d35b-4cbd-bc27-a14a6327edfd" alt=""><figcaption><p>Filtered invoice list with the FlyCode Recovery column</p></figcaption></figure>

**Recovery rate.** Keep using [Stripe's Revenue Recovery dashboard](https://dashboard.stripe.com/revenue-recovery). Invoices recovered by FlyCode appear there as recovered; Stripe's display does not change. FlyCode's own dashboard adds recovery by decline code, recovery speed, attempts per recovered invoice and revenue recovered against your pre-FlyCode baseline.

<figure><img src="https://857825088-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FedoXR9BFShbgporwvi7n%2Fuploads%2F3cvr8xWL3R1fp95JdQOf%2Fimage10.jpg?alt=media&#x26;token=a21131ef-ab99-415d-a577-dc74f452445e" alt=""><figcaption><p>Stripe Revenue Recovery dashboard</p></figcaption></figure>

**Timeline.** The engine typically needs 6 to 8 weeks to optimize its model for your customer base; recovery improves through that window. FlyCode's Go Back in Time feature also revisits invoices that failed up to about 60 days before activation, so recovery rates for earlier months can rise after go-live.

**Stripe's "In recovery" figure.** In the Revenue Recovery breakdown, Stripe defines "In recovery" by the custom maximum retry duration you set (7 days), not by FlyCode's actual recovery window, so that orange segment understates the invoices FlyCode is still working on. Use the invoice filter above or FlyCode's dashboard for the accurate figure.

<figure><img src="https://857825088-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FedoXR9BFShbgporwvi7n%2Fuploads%2FxP3hz0GoPVhbZKTIcXVl%2Fimage18.jpg?alt=media&#x26;token=ee2396c7-d06e-4d56-9273-f902be6070ef" alt="" width="563"><figcaption><p>Revenue Recovery dashboard tooltip for "In recovery"</p></figcaption></figure>

## Troubleshooting

**Customers received two emails about the same failed payment.** Stripe's default recovery emails are still on. Turn them off under Revenue recovery, Emails (Step 3), or set FlyCode to retries-only if you want Stripe or another tool to own messaging.

**Stripe is still retrying on its own schedule.** Card retries are not set to Custom, 3 retries at 7-day intervals (Step 2). Two retry engines on one card can exceed card network attempt limits and lower authorization rates.

**A subscription was cancelled after FlyCode's retries ran out, and we did not expect that.** The cancellation and invoice clean-up steps are on by default. Turn them off in FlyCode if you prefer to keep unrecovered subscriptions past-due, and note that the safeguard already prevents cancellation when a later invoice has been paid.

**An invoice does not show the `flycode_recovery` metadata.** Only failed subscription invoices enter recovery; one-off invoices and invoices that failed before the app's backfill window are not tagged. Check the invoice is a subscription invoice in open status with a payment failure, and that the app is activated.

**Recovery rate in Stripe looks unchanged in the first weeks.** The model is in its 6 to 8 week optimization period, and Stripe's dashboard attributes recovered invoices without distinguishing FlyCode's. Compare against your baseline in FlyCode's dashboard, which is what outcome-based billing uses.

**The "In recovery" amount in Stripe looks too low.** Expected; see the note above on how Stripe defines it.

Still stuck? Email support or [book time with the team](https://www.flycode.com/get-started).

## FAQ

**Does FlyCode need engineering time?** No. Installation is a Stripe app; the only manual steps are the Stripe settings above. Most merchants are live in under an hour.

**Will FlyCode interfere with my existing webhooks or apps?** No. It uses its own app-scoped event subscription, never modifies your webhook endpoints, Radar rules or other apps, and re-checks object state before every write.

**Does FlyCode touch funds?** No. Retries are Pay Invoice calls through your Stripe account; recovered revenue settles to your Stripe balance as normal.

**Can I keep Stripe Smart Retries on?** You keep Stripe's retry feature technically on but minimized to the custom schedule in Step 2 so FlyCode controls timing. Running both fully in parallel wastes attempts.

**What happens to invoices that were already failing before I installed?** They are backfilled on installation and enter recovery; the Go Back in Time feature covers roughly the prior 60 days.

**How is FlyCode priced on Stripe?** Outcome-based: a share of revenue recovered above your baseline, nothing on what Stripe would have recovered anyway. See [How is FlyCode priced for Stripe users?](https://help.flycode.com/flycode-and-stripe/going-further-with-flycode)

## Related

* [FlyCode & Stripe](https://help.flycode.com/flycode-and-stripe) in the Help Center
* [How to Manage Failed Payments in Stripe](https://docs.flycode.com/docs/integrations/how-to-manage-failed-payments-in-stripe)
* [Subscription payment decline codes guide for Stripe](https://docs.flycode.com/docs/subscription-payment-decline-codes-guide-for-stripe)
* [Stripe decline codes reference](https://www.flycode.com/stripe/decline-codes)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.flycode.com/docs/integrations/stripe-integration-guide-for-flycode.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
