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

# Stripe

## Overview

The Stripe integration connects Younium to a merchant’s Stripe account through **Stripe Connect**. It supports collecting and storing customer payment credentials, charging posted invoices automatically or on demand, accepting one-off invoice payments via Stripe Checkout, and recording payments and payouts in Younium’s payment and accounting flows.

The integration operates at **legal entity** scope. Each legal entity maintains its own Stripe connection, payment method mapping, per-currency payout mappings, and per-account **online payment details**. Customers with orders configured for Stripe as the payment method can receive credential requests, complete setup in Stripe-hosted Checkout (setup mode), and have due invoices collected when credentials are on file.

***

## Authentication

An administrator connects Younium to Stripe from the Stripe integration settings of a legal entity. Younium sends them to Stripe, where they sign in to the merchant's Stripe account and approve the connection; Stripe returns them to Younium and the integration is live. There are no API keys to copy and no credentials for the customer to look after.

The connection is made per legal entity. Each legal entity connects to one Stripe account and keeps its own payment method, payout and payment-collection settings, so a group can run several Stripe accounts side by side without them affecting one another. The integration settings show which Stripe account a legal entity is connected to and whether the connection is active. Until a legal entity is connected, nothing in the Stripe integration runs for it: no payment details are requested, no invoices are collected, and no payouts are recorded.

Once approved, the connection stays in place until it is disconnected in Younium or the approval is withdrawn in Stripe. Nothing expires that an administrator has to renew, and Stripe only ever acts on the account the legal entity is connected to — updates arriving for any other account are ignored.

***

## Sandbox vs. Production

Stripe has no separate sandbox for the customer to point Younium at: the connection takes its mode from the Stripe account it was approved against. Connecting to a Stripe test account gives a test connection, and connecting to a live account gives a live one.

The two never mix. Younium acts on updates from Stripe only when they match the mode of the Younium environment, so payments made in a test account cannot appear as real payments in a production tenant, and a live payment is never recorded against a test environment.

***

## Activation

Approving the connection in Stripe is what activates the integration. From that point Younium can create the customer records it needs in the connected Stripe account, ask customers for payment details, collect posted invoices, and record payments and payouts.

Activation establishes the connection and nothing else. It does not decide which payment methods customers may use, which Younium payment method collected payments are posted to, or how payouts map to payment methods per currency. Those are configured in the integration settings afterwards, and automatic collection does not charge anything until a Younium payment method is configured for Stripe.

***

## Deactivation

Disconnecting is done from the same integration settings. Younium withdraws its access to the Stripe account and then clears what it held for that legal entity: the connection itself, every stored payment credential, and the link between each Younium account and its Stripe customer.

Nothing is removed inside Stripe — the merchant's customers, payment methods and payment history stay in their Stripe account. What is lost is what Younium stored about them. Reconnecting later starts from an empty state: every customer has to provide their payment details again before invoices can be collected automatically.

***

## Save and Setup

Saved settings take effect immediately for the legal entity, and the connected Stripe account continues to be recognised for the updates Stripe sends back. There is no separate setup step: saving settings does not create custom fields in Younium or change what the integration listens for.

### Settings (integration configuration)

| Setting                                                                                                                                                                 | Description                                                                        | Default                  |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------ |
| `PaymentMethodId`                                                                                                                                                       | Younium payment method used for Stripe collections (must include bank fee account) | Unset until configured   |
| `OptionToPayInvoicesDirectlyThroughStripe`                                                                                                                              | Enables hosted Checkout payment flow for invoices                                  | Per tenant               |
| `EnableCard` / `EnableSepaDebit` / `EnableBacsDebit` / `EnableACHDebit`                                                                                                 | Payment method types allowed in **setup** Checkout                                 | Per flags                |
| `LocaleForPaymentCollection`                                                                                                                                            | Stripe Checkout locale for credential collection                                   | Optional                 |
| `DefaultPaymentCollectionLanguage`                                                                                                                                      | UI language for payment-details pages (`English`, `German`)                        | `English`                |
| `CancelURLForDirectPayment`                                                                                                                                             | Checkout cancel URL for direct invoice payment                                     | Optional                 |
| `LocaleForDirectPayment`                                                                                                                                                | Checkout locale for direct invoice payment                                         | Optional                 |
| `EnableCardForDirectPayment` / `EnableSepaDebitForDirectPayment` / `EnableBacsDebitForDirectPayment` / `EnableACHDebitForDirectPayment` / `EnableIdealForDirectPayment` | Types for direct invoice Checkout                                                  | Per flags                |
| `DisableEmailReceipts`                                                                                                                                                  | Suppresses Stripe receipt email on PaymentIntents                                  | `false`                  |
| `AllowInvoiceCreationWithoutDetails`                                                                                                                                    | Allows invoice flows without stored credentials (product behaviour)                | Per tenant               |
| `UseStripeSdk`                                                                                                                                                          | Sets `use_stripe_sdk` on off-session PaymentIntents                                | Per tenant               |
| `GeneratePaymentDetailsUrlOnPostInvoice`                                                                                                                                | Regenerates payment-details link when invoice posts                                | Per tenant               |
| `EnableSavePaymentMethodCheckbox`                                                                                                                                       | Enables optional save on direct payment Checkout                                   | Per tenant               |
| `PaymentRequestEmailSubject`                                                                                                                                            | Credential request email subject; supports `{legalentityname}`, `{accountname}`    | Default subject if empty |

### Payout method mapping

Per currency, `StripePayoutMethod` links a Younium payment method to `StripeSettings` for payout journal posting.

| Younium field                        | Stripe / behaviour                                           |
| ------------------------------------ | ------------------------------------------------------------ |
| `StripePayoutMethod.CurrencyCode`    | Payout `currency` (case-insensitive match)                   |
| `StripePayoutMethod.PaymentMethodId` | Younium payment method debited on payout (bank account side) |
| `StripeSettings.PaymentMethodId`     | Younium payment method credited (Stripe clearing side)       |

***

## Custom fields created by the integration

Stripe does not create Younium custom fields. Credential and payment state live on `OnlinePaymentDetails` and related logs.

***

## Eligibility and scope

### Automatic invoice payment job (`Stripe invoice payment`)

Runs on a schedule (minimum interval 30 minutes). Selects invoices where:

* `PaymentMethodForInvoice == Stripe`
* `Status == Posted`
* `DueDate <= UtcNow`
* `OnlinePaymentStatus` is not `Processing` or `Succeeded`
* No prior `OnlinePaymentLog` with `FailedPayment == false`
* `TotalAmount.Amount >= 0` (negative totals are skipped with an error)

Requires account `OnlinePaymentDetails` with `StripeCustomerId`, `StripePaymentMethodId`, and `StripeCredentialStatus == CredentialCollected` (validated at charge time).

### Credential request jobs

| Job                              | Display name                   | Selection                                                                                                   |
| -------------------------------- | ------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| `StripeInitialPaymentRequestJob` | Stripe initial payment request | Accounts with an active order `OrderPaymentMethod == Stripe`, `StripeCredentialStatus == MissingCredential` |
| `StripeResendPaymentRequestJob`  | Stripe resend payment request  | Same, but `StripeCredentialStatus == CredentialRequested`                                                   |

Both send the payment-details email and set status to `CredentialRequested` (unless pending bank verification or already collected).

### Direct invoice Checkout

Checkout is offered only when the invoice is not settled, the token is active, integration is active, and online payment is not already `Processing`. Settled partial payments reduce the Checkout line amount by fully posted settlement totals.

### Off-session charge (`Payment`)

Skipped when invoice already succeeded or is processing in Stripe; dry-run posting is rolled back before creating the PaymentIntent. Negative invoice totals are rejected.

### Payout webhook

Processed only on `payout.paid` when no successful `OnlinePaymentLog` already exists for the same `PayoutId`, and a `StripePayoutMethod` exists for the payout currency.

### Charge status webhook

Ignored for payment methods of type `card` or `ideal` (those use PaymentIntent flow). Other types update `OnlinePaymentStatus` from charge events.

***

## Field mapping

### Stripe Connect customer (setup — new customer)

When no `StripeCustomerId` exists, Younium creates a Stripe Customer on the connected account:

| Younium field                                        | Stripe `Customer` field                                                      |
| ---------------------------------------------------- | ---------------------------------------------------------------------------- |
| `Account.InvoiceEmailAddress`                        | `email`                                                                      |
| `Account.Name`                                       | `name`                                                                       |
| `Account.DefaultInvoiceAddress.Street`               | `address.line1`                                                              |
| `Account.DefaultInvoiceAddress.Street2`              | `address.line2`                                                              |
| `Account.DefaultInvoiceAddress.City`                 | `address.city`                                                               |
| `Account.DefaultInvoiceAddress.State`                | `address.state`                                                              |
| `Account.DefaultInvoiceAddress.Zip`                  | `address.postal_code`                                                        |
| `Account.DefaultInvoiceAddress.Country.TwoAlphaCode` | `address.country`                                                            |
| `Account.AccountNumber`                              | `metadata["Account number"]`                                                 |
| `Account.AccountType`                                | `metadata["Account type"]`                                                   |
| `Account.Currency.Code`                              | `metadata["Currency Code"]`                                                  |
| Tenant / legal entity / account ids                  | `metadata["tenantId"]`, `metadata["legalEntityId"]`, `metadata["accountId"]` |

### Setup Checkout session

| Younium field                                                                         | Stripe Checkout `Session` field                          |
| ------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| `GetPaymentMethods(settings)` → `card`, `sepa_debit`, `bacs_debit`, `us_bank_account` | `payment_method_types`                                   |
| `OnlinePaymentDetails.StripeCustomerId` or new customer id                            | `customer`                                               |
| API base + success/cancel paths                                                       | `success_url`, `cancel_url`                              |
| `settings.LocaleForPaymentCollection`                                                 | `locale`                                                 |
| Mode                                                                                  | `setup`                                                  |
| Token id                                                                              | `metadata["token"]`, `SetupIntentData.metadata["token"]` |
| Session id                                                                            | Stored on `OnlinePaymentDetails.SetupIntentId`           |

### Direct invoice payment Checkout session

| Younium field                                                 | Stripe Checkout field                                                      |
| ------------------------------------------------------------- | -------------------------------------------------------------------------- |
| `Invoice.TotalAmount.CurrencyCode` (minus posted settlements) | `currency`, line `unit_amount` (minor units except non-decimal currencies) |
| `Invoice.Account.InvoiceEmailAddress`                         | `PaymentIntentData.receipt_email` (unless `DisableEmailReceipts`)          |
| `Invoice.InvoiceNumber`                                       | `PaymentIntentData.description`, line item name                            |
| `Invoice.Id`, tenant, legal entity, account                   | `PaymentIntentData.metadata` and/or session `metadata` when save enabled   |
| `settings.CancelURLForDirectPayment`                          | `cancel_url`                                                               |
| `settings.LocaleForDirectPayment`                             | `locale`                                                                   |
| Success URL with token + `{CHECKOUT_SESSION_ID}`              | `success_url`                                                              |

Amount conversion: most currencies multiply by 100; **non-decimal** currencies (`BIF`, `CLP`, `DJF`, `GNF`, `JPY`, `KMF`, `KRW`, `MGA`, `PYG`, `RWF`, `UGX`, `VND`, `VUV`, `XAF`, `XOF`, `XPF`) use whole units.

### Off-session PaymentIntent (automatic / manual collection)

| Younium field                                             | Stripe `PaymentIntent` field      |
| --------------------------------------------------------- | --------------------------------- |
| Invoice total minus posted settlements (converted amount) | `amount`                          |
| `Invoice.TotalAmount.CurrencyCode`                        | `currency`                        |
| `Account.OnlinePaymentDetails.StripeCustomerId`           | `customer`                        |
| `Account.OnlinePaymentDetails.StripePaymentMethodId`      | `payment_method`                  |
| Payment method type from Stripe API                       | `payment_method_types`            |
| `Invoice.Id`, tenant, legal entity, account               | `metadata`                        |
| `Invoice.InvoiceNumber`                                   | `description`                     |
| `Account.InvoiceEmailAddress`                             | `receipt_email` (unless disabled) |
| `true`                                                    | `confirm`, `off_session`          |
| `automatic`                                               | `capture_method`                  |
| `{invoiceId}-{paymentMethodId}`                           | Idempotency key                   |
| `settings.UseStripeSdk`                                   | `use_stripe_sdk` when enabled     |

### Payment posted from `payment_intent.succeeded` webhook

| Younium field                                                  | Stripe / derived                                 |
| -------------------------------------------------------------- | ------------------------------------------------ |
| `Invoice.InvoiceNumber`                                        | `Payment.PaymentReference`                       |
| Configured payment method description                          | `Payment.PaymentDescription`                     |
| `PaymentIntent.amount_received` (normalised)                   | `Payment.Amount.Amount`                          |
| Charge balance transaction fee (with exchange-rate adjustment) | `Payment.BankFeeAmount`                          |
| `PaymentIntent.Id`                                             | `Payment.OnlinePaymentIntentId`                  |
| Charge id                                                      | `Payment.OnlinePaymentChargeId`                  |
| Invoice id                                                     | `PaymentSettlement.InvoiceId`, settlement amount |

### Payout journal (`payout.paid`)

| Younium field                | Stripe `Payout` field                                  |
| ---------------------------- | ------------------------------------------------------ |
| `payout.amount` (normalised) | Debit/credit amount                                    |
| `payout.currency`            | Currency; matched to `StripePayoutMethod.CurrencyCode` |
| `payout.id`                  | `OnlinePaymentLog.PayoutId`                            |

Journal description: `Payout from Stripe`; postings debit payout financial account and credit Stripe payment method financial account.

### Online payment details write-back

| Stripe event / outcome                                              | Younium `OnlinePaymentDetails`                                                                                                                                                                                        |
| ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Setup success                                                       | `StripeCustomerId`, `StripePaymentMethodId`, `StripeCredentialStatus` → `CredentialCollected` or `PendingBankAccountVerification` (US bank microdeposits)                                                             |
| `payment_method.attached` (not explicit save-from-payment)          | Updates ids; `StripeCredentialStatus` → `CredentialCollected`                                                                                                                                                         |
| `payment_method.detached`                                           | Clears `StripePaymentMethodId`; status → `MissingCredential`                                                                                                                                                          |
| `customer.deleted`                                                  | Record removed; account link cleared                                                                                                                                                                                  |
| Checkout save (payment mode)                                        | Customer metadata + optional credential collection when `AllowRedisplay == always`                                                                                                                                    |
| Payment method set directly on the account (not via Setup Checkout) | Checked against Stripe first: the payment method must exist and belong to the given `StripeCustomerId`, or the update is rejected. `StripeCredentialStatus` only becomes `CredentialCollected` once this check passes |

> **Note on manual credential submission:** Setting the payment method directly on the account, rather than completing Setup Checkout, does not skip verification — Younium still checks with Stripe that the payment method exists and belongs to the given customer before treating the credential as collected.

### Credential status values

| Value                            | Meaning                                            |
| -------------------------------- | -------------------------------------------------- |
| `MissingCredential`              | No usable payment method                           |
| `CredentialRequested`            | Email sent; awaiting customer                      |
| `CredentialCollected`            | Customer and payment method stored                 |
| `PendingBankAccountVerification` | US bank account awaiting microdeposit verification |

***

## Payment flows

### 1. Credential collection (setup Checkout)

A **token authentication** record is created per account (`EntityId = account id`, `IsActive = true`). The customer opens `api/Stripe/PaymentDetails?code={token}`, which can redirect to setup Checkout (`create-checkout-session`). On `checkout.session.completed` (setup mode), Younium loads the SetupIntent and calls `SaveCustomerAndPaymentMethod`, deactivates the token, and stores customer/payment method ids.

SetupIntent webhooks handle microdeposit verification (`requires_action`, `setup_failed`, `canceled`) and may reset credentials or regenerate payment-details URLs.

Whenever these flows change an account's stored payment details or credential status, Younium publishes the account-changed event, so subscribed webhooks see the update.

The V2 API can also request this same link directly for an account, without a credential-request email going out — for a consumer building its own payment-details collection flow. It follows the same reuse rule as the emailed link: the account's stored link is returned unchanged while credentials have not yet been collected, and a new one is generated and stored otherwise. The request fails if the account does not exist or the legal entity has no active Stripe connection.

### 2. Direct invoice payment (payment Checkout)

Token links invoice id. `InvoicePayment` creates a payment-mode Checkout session. Success redirect calls `ProcessSuccessfulPayment`, which sets `OnlinePaymentStatus` from PaymentIntent status and writes `OnlinePaymentLog`. Settlement posting for card/ideal typically follows `payment_intent.succeeded` webhook (`ProcessPayment`).

### 3. Automatic collection (job + PaymentIntent)

The payment job calls `Payment`, which validates settings, ensures no duplicate success, creates an off-session PaymentIntent, and sets `OnlinePaymentStatus` from Stripe status. Successful intents are settled via the payment webhook (journal + payment batch).

### 4. Payout accounting

`payout.paid` creates a payout journal; `payout.failed` logs failure on `OnlinePaymentLog` with `IsPayout = true`.

***

## Events and jobs

| Trigger           | Id / name                                                    | Behaviour                                       |
| ----------------- | ------------------------------------------------------------ | ----------------------------------------------- |
| Scheduled job     | Stripe invoice payment                                       | Off-session charge for eligible posted invoices |
| Scheduled job     | Stripe initial / resend payment request                      | Email payment-details link                      |
| Application event | None subscribed by Stripe integration                        | —                                               |
| Webhook           | `payment_intent.succeeded` / `payment_intent.payment_failed` | Post payment or log failure                     |
| Webhook           | `checkout.session.completed`                                 | Setup or optional save-on-pay                   |
| Webhook           | `payment_method.*`                                           | Update stored payment method                    |
| Webhook           | `payout.paid` / `payout.failed`                              | Payout journal or failure log                   |
| Webhook           | `charge.*` (non-card/non-ideal)                              | Update `OnlinePaymentStatus`                    |
| Webhook           | `customer.deleted`                                           | Remove online payment details                   |
| Webhook           | `setup_intent.*`                                             | Bank verification lifecycle                     |


---

# 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.younium.com/payments-integrations/stripe.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.
