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

# Adyen - SEPA

> Configure SEPA via Adyen as a payment method in Gr4vy.

export const connector = {
  id: "adyen-sepa",
  displayName: "SEPA",
  provider: "Adyen",
  method: "sepa",
  mode: "redirect",
  category: "bank",
  features: "create_transaction deep_linking direct_capture direct_integration_create partial_refunds payment_method_tokenization redirect_requires_popup refunds requires_webhook_setup settlement_reporting settlement_reporting_from_webhook verify_credentials",
  supportedCountries: "AT BE BG CY CZ DE DK EE ES FI FR GB GR HR HU IE IT LT LU LV MT NL PL PT RO SE SI SK",
  supportedCurrencies: "EUR"
};

export const ConnectorRegions = ({data, kind, name: nameOverride}) => {
  const [query, setQuery] = useState("");
  const [open, setOpen] = useState(false);
  const isCountries = kind === "countries";
  const raw = data && (isCountries ? data.supportedCountries : data.supportedCurrencies);
  const codes = typeof raw === "string" ? raw.split(/\s+/).filter(Boolean) : Array.isArray(raw) ? raw : [];
  const DISPLAY_NAME_OVERRIDES = {
    authorizenet: "Authorize.net",
    cardpointe: "CardPointe",
    cybersource: "Cybersource",
    dlocal: "dLocal",
    shift4i4go: "Shift4 i4go",
    tokenex: "TokenEx"
  };
  const rawName = data && data.displayName || "";
  const name = nameOverride || DISPLAY_NAME_OVERRIDES[rawName.toLowerCase()] || rawName || "This connector";
  const verb = isCountries ? "supports transactions from buyers in" : "supports processing payments in";
  const noun = isCountries ? "countries" : "currencies";
  if (codes.length === 0) return null;
  const unrestricted = codes.length >= (isCountries ? 200 : 150);
  const disclaimer = <p style={{
    opacity: 0.7,
    fontSize: "0.8125rem",
    marginTop: "0.75rem"
  }}>
      This list is for guidance only. It doesn't guarantee availability or
      create any rights, and the provider must also enable each of these {noun}{" "}
      for your account.
    </p>;
  let displayNames = null;
  try {
    displayNames = new Intl.DisplayNames(["en"], {
      type: isCountries ? "region" : "currency"
    });
  } catch (e) {
    displayNames = null;
  }
  const resolve = code => {
    if (!displayNames) return null;
    try {
      const resolved = displayNames.of(code);
      return resolved && resolved !== code ? resolved : null;
    } catch (e) {
      return null;
    }
  };
  const MAJOR_CURRENCIES = ["USD", "EUR", "GBP", "CAD", "AUD", "JPY", "CHF", "CNY", "SGD", "HKD", "NZD", "SEK", "NOK", "DKK", "MXN", "BRL", "INR"];
  const items = codes.map(code => ({
    code,
    label: resolve(code)
  }));
  if (isCountries) {
    items.sort((a, b) => (a.label || a.code).localeCompare(b.label || b.code));
  } else {
    const rank = code => {
      const i = MAJOR_CURRENCIES.indexOf(code);
      return i === -1 ? MAJOR_CURRENCIES.length : i;
    };
    items.sort((a, b) => rank(a.code) - rank(b.code) || a.code.localeCompare(b.code));
  }
  if (codes.length <= 3) {
    const parts = items.map(it => isCountries || !it.label ? it.label || it.code : `${it.label} (${it.code})`);
    const joined = parts.length === 1 ? parts[0] : parts.length === 2 ? `${parts[0]} and ${parts[1]}` : `${parts.slice(0, -1).join(", ")}, and ${parts[parts.length - 1]}`;
    return <div>
        <p>
          {name} {verb} {joined}.
        </p>
        {disclaimer}
      </div>;
  }
  const chipStyle = {
    display: "inline-flex",
    alignItems: "baseline",
    gap: "0.4rem",
    padding: "0.15rem 0.55rem",
    borderRadius: "0.375rem",
    border: "1px solid rgba(128, 128, 128, 0.25)",
    fontSize: "0.875rem",
    lineHeight: 1.5
  };
  const codeStyle = {
    fontFamily: "var(--font-mono, ui-monospace, monospace)",
    fontWeight: 600,
    fontSize: "0.8125rem"
  };
  const controlStyle = {
    color: "inherit",
    background: "transparent",
    border: "1px solid rgba(128, 128, 128, 0.3)",
    borderRadius: "0.5rem",
    fontSize: "0.875rem"
  };
  const renderChip = it => <span key={it.code} style={chipStyle} title={isCountries ? it.code : it.label || it.code}>
      {isCountries ? it.label || it.code : <span style={codeStyle}>{it.code}</span>}
      {!isCountries && it.label ? <span style={{
    opacity: 0.7
  }}>{it.label}</span> : null}
    </span>;
  const PREVIEW = 5;
  const collapsible = items.length > PREVIEW;
  const q = query.trim().toLowerCase();
  const filtered = q ? items.filter(it => it.code.toLowerCase().includes(q) || it.label && it.label.toLowerCase().includes(q)) : items;
  const expanded = open || q !== "";
  const visible = !collapsible ? items : expanded ? filtered : items.slice(0, PREVIEW);
  const toggle = () => {
    const next = !open;
    setOpen(next);
    if (!next) setQuery("");
  };
  return <div>
      {unrestricted ? <p>
          Gr4vy doesn't limit {name} to specific {noun}. Check with the provider
          which {noun} it supports for your account.
        </p> : <p>
          {name} {verb} the following {codes.length} {noun}:
        </p>}

      {collapsible ? <input type="text" value={query} onChange={e => setQuery(e.target.value)} placeholder={`Filter ${noun}…`} aria-label={`Filter ${noun}`} style={{
    ...controlStyle,
    display: "block",
    width: "100%",
    maxWidth: "22rem",
    padding: "0.4rem 0.7rem",
    margin: "0 0 0.75rem"
  }} /> : null}

      <div style={{
    display: "flex",
    flexWrap: "wrap",
    gap: "0.4rem"
  }}>
        {visible.map(renderChip)}
      </div>

      {q && filtered.length === 0 ? <p style={{
    opacity: 0.7,
    marginTop: "0.6rem"
  }}>
          No {noun} match “{query.trim()}”.
        </p> : null}
      {q && filtered.length > 0 ? <p style={{
    opacity: 0.6,
    fontSize: "0.8125rem",
    marginTop: "0.6rem"
  }}>
          Showing {filtered.length} of {items.length}.
        </p> : null}

      {collapsible && !q ? <button type="button" aria-expanded={open} onClick={toggle} style={{
    ...controlStyle,
    display: "inline-flex",
    alignItems: "center",
    gap: "0.4rem",
    padding: "0.35rem 0.75rem",
    marginTop: "0.75rem",
    cursor: "pointer"
  }}>
          <span aria-hidden="true" style={{
    display: "inline-block",
    transform: open ? "rotate(90deg)" : "none",
    transition: "transform 0.15s ease"
  }}>
            ›
          </span>
          {open ? "Show fewer" : `and ${items.length - PREVIEW} more`}
        </button> : null}

      {disclaimer}
    </div>;
};

export const ConnectorCapabilities = ({data}) => {
  const CAPABILITIES = [{
    keys: ["three_d_secure_pass_through"],
    label: "3-D Secure",
    description: "Gr4vy runs the 3DS authentication and sends the results to the provider on the authorization.",
    cardOnly: true
  }, {
    keys: ["three_d_secure_hosted"],
    label: "3-D Secure (provider-hosted)",
    description: "The provider runs the 3DS authentication itself, redirecting the buyer to its own page.",
    cardOnly: true
  }, {
    keys: ["partial_authorization"],
    label: "Partial authorization",
    description: "Support partial approval responses."
  }, {
    keys: ["zero_auth"],
    label: "Zero auth",
    description: "Verify a payment method without charging it."
  }, {
    keys: ["void"],
    label: "Void",
    description: "Cancel an authorized transaction before capture."
  }, {
    keys: ["incremental_authorization"],
    label: "Incremental authorization",
    description: "Increase the amount of an existing authorization before capture."
  }, {
    keys: ["direct_capture"],
    label: "Direct capture",
    description: "Capture a payment immediately at authorization.",
    hideWhenUnsupported: true
  }, {
    keys: ["delayed_capture"],
    label: "Delayed capture",
    description: "Authorize a payment and capture it at a later time."
  }, {
    keys: ["partial_capture"],
    label: "Partial capture",
    description: "Capture a portion of the authorized amount."
  }, {
    keys: ["over_capture"],
    label: "Over capture",
    description: "Capture more than the originally authorized amount."
  }, {
    keys: ["multi_capture"],
    label: "Multiple captures",
    description: "Capture one authorization in several partial captures."
  }, {
    keys: ["tracking_details"],
    label: "Shipment tracking",
    description: "Forward shipment tracking details to the provider on capture."
  }, {
    keys: ["refunds"],
    label: "Refunds",
    description: "Refund a captured payment."
  }, {
    keys: ["partial_refunds"],
    label: "Partial refunds",
    description: "Refund a portion of the captured amount."
  }, {
    keys: ["settlement_reporting"],
    label: "Settlement reporting",
    description: "Automatic settlement and reconciliation reporting."
  }, {
    keys: ["create_session"],
    label: "Create session",
    description: "Create a connector session for client-side flows."
  }, {
    keys: ["network_tokens_default", "network_tokens_toggle"],
    label: "Network tokens",
    description: "Network-level tokenization for improved approval rates.",
    cardOnly: true
  }, {
    keys: ["open_loop", "open_loop_toggle"],
    label: "Open loop",
    description: "Charge stored cards with card data from the Gr4vy vault, so merchant-initiated payments aren't tied to the connection that stored the card.",
    optionalKey: "open_loop_toggle",
    optionalNote: "Off by default. The provider must allow it before you turn it on for the connection.",
    cardOnly: true
  }, {
    keys: ["issuer_based_installments"],
    label: "Issuer installments",
    description: "Ask the issuer to split a single payment into installments with installment_count.",
    cardOnly: true,
    hideWhenUnsupported: true
  }, {
    keys: ["digital_wallets"],
    label: "Digital wallets",
    description: "Apple Pay, Google Pay, and other wallet integrations."
  }, {
    keys: ["payment_method_tokenization", "payment_method_tokenization_toggle"],
    label: "Payment method tokenization",
    description: "Store payment methods outside of transactions."
  }, {
    keys: ["transaction_sync"],
    label: "Transaction sync",
    description: "Synchronize transaction state from the connector."
  }, {
    keys: ["create_token"],
    label: "Tokenization",
    description: "Create a token from card details collected via Secure Fields.",
    hideWhenUnsupported: true
  }, {
    keys: ["delete_token"],
    label: "Delete token",
    description: "Delete a stored token.",
    hideWhenUnsupported: true
  }, {
    keys: ["verify_credentials"],
    label: "Verify credentials",
    description: "Validate the configured credentials against the connector.",
    hideWhenUnsupported: true
  }];
  const raw = data && data.features;
  const enabled = typeof raw === "string" ? new Set(raw.split(/\s+/).filter(Boolean)) : Array.isArray(raw) ? new Set(raw) : new Set(Object.keys(raw || ({})).filter(key => raw[key]));
  const isOn = entry => entry.keys.some(key => enabled.has(key));
  const isNonCard = data && data.method && data.method !== "card";
  const renderGroup = (title, entries, supported) => {
    if (entries.length === 0) return null;
    const mark = supported ? "✓" : "✕";
    const markColor = supported ? "#16a34a" : "#9ca3af";
    return <div style={{
      marginTop: "1rem"
    }}>
        <div style={{
      fontSize: "0.75rem",
      fontWeight: 600,
      letterSpacing: "0.05em",
      textTransform: "uppercase",
      opacity: 0.6,
      marginBottom: "0.25rem"
    }}>
          {title}
        </div>
        {}
        <div role="list">
          {entries.map(entry => <div role="listitem" key={entry.label} style={{
      display: "flex",
      gap: "0.5rem",
      alignItems: "baseline",
      padding: "0.3rem 0",
      opacity: supported ? 1 : 0.7
    }}>
              <span aria-hidden="true" style={{
      color: markColor,
      fontWeight: 700,
      flexShrink: 0
    }}>
                {mark}
              </span>
              <span>
                <strong>{entry.label}</strong>
                {entry.description ? <span style={{
      opacity: 0.85
    }}> — {entry.description}</span> : null}
                {supported && entry.optionalKey && entry.keys.every(key => key === entry.optionalKey || !enabled.has(key)) ? <span style={{
      opacity: 0.85
    }}> {entry.optionalNote}</span> : null}
              </span>
            </div>)}
        </div>
      </div>;
  };
  const visible = isNonCard ? CAPABILITIES.filter(entry => !entry.cardOnly) : CAPABILITIES;
  const supported = visible.filter(isOn);
  const unsupported = visible.filter(entry => !isOn(entry) && !entry.hideWhenUnsupported);
  return <div>
      {renderGroup("Supported", supported, true)}
      {renderGroup("Not supported", unsupported, false)}
      <p style={{
    opacity: 0.7,
    fontSize: "0.8125rem"
  }}>
        This list is for guidance only. It doesn't guarantee availability or
        create any rights, and the provider may need to enable some features for
        your account.
      </p>
    </div>;
};

export const ConnectorHeader = ({data, name: nameProp, method: methodName, logo, category: categoryProp, catalog, providers}) => {
  const [logoStage, setLogoStage] = useState(0);
  const [chipLogoFailed, setChipLogoFailed] = useState(false);
  const [anchors, setAnchors] = useState({});
  useEffect(() => {
    const found = {};
    for (const id of ["capabilities", "supported-countries", "supported-currencies", "supported-payment-methods"]) {
      found[id] = Boolean(document.getElementById(id));
    }
    setAnchors(found);
  }, []);
  const hasData = Boolean(data && data.id);
  if (!hasData && !(nameProp && logo)) return null;
  const CATEGORY_LABELS = {
    card: "Cards",
    bank: "Banking",
    bnpl: "BNPL",
    cash: "Cash vouchers",
    crypto: "Crypto",
    wallet: "Wallets",
    tokenization: "Tokenization"
  };
  const DISPLAY_NAME_OVERRIDES = {
    authorizenet: "Authorize.net",
    cardpointe: "CardPointe",
    cybersource: "Cybersource",
    dlocal: "dLocal",
    shift4i4go: "Shift4 i4go",
    tokenex: "TokenEx",
    "worldine travelhub": "Worldline TravelHub"
  };
  const HIGHLIGHTS = [{
    keys: ["three_d_secure_pass_through", "three_d_secure_hosted"],
    label: "3-D Secure",
    cardOnly: true
  }, {
    keys: ["network_tokens_default", "network_tokens_toggle"],
    label: "Network tokens",
    cardOnly: true
  }, {
    keys: ["digital_wallets"],
    label: "Digital wallets"
  }, {
    keys: ["delayed_capture"],
    label: "Delayed capture"
  }, {
    keys: ["partial_capture"],
    label: "Partial capture"
  }, {
    keys: ["refunds"],
    label: "Refunds"
  }, {
    keys: ["partial_refunds"],
    label: "Partial refunds"
  }, {
    keys: ["zero_auth"],
    label: "Zero auth"
  }, {
    keys: ["settlement_reporting"],
    label: "Settlement reporting"
  }];
  const d = hasData ? data : {};
  const method = d.method || "";
  const provider = !hasData ? "" : method && d.id.endsWith(`-${method}`) ? d.id.slice(0, -(method.length + 1)) : d.id.split("-")[0];
  const fix = value => DISPLAY_NAME_OVERRIDES[(value || "").toLowerCase()] || value || "";
  const name = fix(d.provider) || nameProp || fix(d.displayName) || provider;
  const displayName = fix(d.displayName);
  const productName = !hasData ? "" : method === "card" ? d.provider ? displayName : "" : methodName || (d.provider && displayName !== name ? displayName : "");
  const methodLed = Boolean(productName);
  const cardProduct = methodLed && method === "card";
  const category = categoryProp || (method === "card" && !cardProduct ? "" : CATEGORY_LABELS[d.category] || "");
  const flowLabel = d.category !== "bank" ? "" : d.mode === "bank" ? "Stored in Gr4vy" : d.mode === "redirect" ? "Redirect" : "";
  const providerLogo = hasData ? `/assets/connectors/providers/${provider}.svg` : logo;
  const methodLogo = `/assets/connectors/methods/${method}.svg`;
  const title = methodLed ? productName : name;
  const chipLabel = !hasData ? "" : methodLed ? `via ${name}` : methodName;
  const chipLogo = cardProduct ? "" : methodLed ? providerLogo : methodLogo;
  const logos = methodLed && !cardProduct ? [methodLogo, providerLogo] : [providerLogo];
  const primaryLogo = logos[logoStage] || null;
  const enabled = new Set((d.features || "").split(/\s+/).filter(Boolean));
  const highlights = HIGHLIGHTS.filter(h => !(h.cardOnly && method !== "card") && h.keys.some(k => enabled.has(k)));
  const codes = value => (value || "").split(/\s+/).filter(Boolean);
  const providerSet = new Set(codes(providers));
  const members = !hasData && catalog && providerSet.size > 0 ? catalog.filter(e => providerSet.has(e.provider)) : [];
  const union = key => new Set(members.flatMap(e => codes(e[key]))).size;
  const methodsCount = members.length;
  const countries = hasData ? codes(d.supportedCountries).length : union("countries");
  const currencies = hasData ? codes(d.supportedCurrencies).length : union("currencies");
  const border = "1px solid rgba(128, 128, 128, 0.2)";
  const labelStyle = {
    fontSize: "0.6875rem",
    fontWeight: 600,
    letterSpacing: "0.05em",
    textTransform: "uppercase",
    opacity: 0.6
  };
  const chipStyle = {
    display: "inline-flex",
    alignItems: "center",
    gap: "0.3rem",
    padding: "0.1rem 0.5rem",
    borderRadius: "999px",
    border,
    fontSize: "0.8125rem",
    whiteSpace: "nowrap"
  };
  const renderStat = (label, value, anchor) => <a href={anchors[anchor] ? `#${anchor}` : undefined} style={{
    display: "flex",
    flexDirection: "column",
    gap: "0.1rem",
    textDecoration: "none",
    borderBottom: "none",
    color: "inherit",
    minWidth: "6rem"
  }}>
      <span style={labelStyle}>{label}</span>
      <span style={{
    fontSize: "1.25rem",
    fontWeight: 600
  }}>{value}</span>
    </a>;
  return <div className="not-prose" style={{
    border,
    borderRadius: "0.75rem",
    padding: "1.25rem",
    margin: "1rem 0 1.5rem",
    display: "flex",
    flexDirection: "column",
    gap: "1rem"
  }}>
      <div style={{
    display: "flex",
    alignItems: "center",
    gap: "1rem"
  }}>
        {primaryLogo ? <img src={primaryLogo} alt={`${title} logo`} width="56" height="56" onError={() => setLogoStage(logoStage + 1)} style={{
    width: "3.5rem",
    height: "3.5rem",
    borderRadius: "0.5rem",
    margin: 0,
    flexShrink: 0
  }} /> : <span aria-hidden="true" style={{
    width: "3.5rem",
    height: "3.5rem",
    borderRadius: "0.5rem",
    border,
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    fontSize: "1.5rem",
    fontWeight: 600,
    flexShrink: 0
  }}>
            {title.charAt(0).toUpperCase()}
          </span>}
        <div style={{
    display: "flex",
    flexDirection: "column",
    gap: "0.35rem",
    minWidth: 0
  }}>
          <span style={{
    fontSize: "1.25rem",
    fontWeight: 600,
    lineHeight: 1.2
  }}>{title}</span>
          <span style={{
    display: "flex",
    flexWrap: "wrap",
    gap: "0.4rem",
    alignItems: "center"
  }}>
            {chipLabel ? <span style={chipStyle}>
                {chipLogoFailed || !chipLogo ? null : <img src={chipLogo} alt="" width="16" height="16" onError={() => setChipLogoFailed(true)} style={{
    width: "1rem",
    height: "1rem",
    borderRadius: "0.2rem",
    margin: 0
  }} />}
                {chipLabel}
              </span> : null}
            {category ? <span style={{
    ...chipStyle,
    opacity: 0.75
  }}>{category}</span> : null}
            {flowLabel ? <span style={{
    ...chipStyle,
    opacity: 0.75
  }}>{flowLabel}</span> : null}
          </span>
        </div>
      </div>

      {methodsCount > 0 || countries > 0 || currencies > 0 || highlights.length > 0 ? <div style={{
    display: "flex",
    flexWrap: "wrap",
    gap: "1rem 2rem",
    paddingTop: "1rem",
    borderTop: border
  }}>
        {methodsCount > 0 ? renderStat("Payment methods", methodsCount, "supported-payment-methods") : null}
        {}
        {countries > 0 ? renderStat("Countries", countries >= 200 ? "No limit" : countries, "supported-countries") : null}
        {currencies > 0 ? renderStat("Currencies", currencies >= 150 ? "No limit" : currencies, "supported-currencies") : null}
        {highlights.length > 0 ? <div style={{
    display: "flex",
    flexDirection: "column",
    gap: "0.35rem",
    flex: "1 1 16rem"
  }}>
            <span style={labelStyle}>Highlights</span>
            <span style={{
    display: "flex",
    flexWrap: "wrap",
    gap: "0.35rem"
  }}>
              {highlights.map(h => <span key={h.label} style={chipStyle}>
                  <span aria-hidden="true" style={{
    color: "#16a34a",
    fontWeight: 700
  }}>✓</span>
                  {h.label}
                </span>)}
              {anchors.capabilities ? <a href="#capabilities" style={{
    ...chipStyle,
    borderStyle: "dashed",
    textDecoration: "none",
    color: "inherit"
  }}>
                  All capabilities →
                </a> : null}
            </span>
          </div> : null}
      </div> : null}
    </div>;
};

<ConnectorHeader data={connector} name="Adyen" method="SEPA" />

Adyen is a global payment technology company founded in 2006 in Amsterdam, Netherlands. The company provides a single platform for accepting payments across online, mobile, and in-store channels for major enterprises worldwide including Uber, Spotify, and Microsoft.

SEPA (Single Euro Payments Area) is a payment integration initiative that makes bank transfers within the European Union as easy as domestic transfers. SEPA Direct Debit allows merchants to collect payments directly from buyers' bank accounts across participating European countries, providing a cost-effective alternative to card payments.

<Note>
  **Four Adyen connectors debit a buyer's bank account.** Pick the one that matches who collects the account:

  * [ACH Direct Debit](/connections/payments/adyen-ach) (redirect): the buyer enters their account and routing numbers on Adyen's page, and Adyen keeps them.
  * [SEPA](/connections/payments/adyen-sepa) (redirect): the buyer enters their IBAN on Adyen's page, and Adyen keeps it.
  * [Pay by Bank (redirect)](/connections/payments/adyen-paybybank): Adyen sends the buyer to Plaid to choose their bank. US only.
  * [Bank account (ACH, SEPA, BACS)](/connections/payments/adyen-bank) (stored in Gr4vy): you send the bank account details or a Plaid-linked account, and Gr4vy stores the account. Use this connector to charge bank accounts that you [import](/guides/features/token-import/overview) into Gr4vy.
</Note>

## Setup

Please follow the [common Adyen instructions](./adyen) to get set up with SEPA.

Next, make sure to enable SEPA as a payment method on your configured account.

## Capabilities

<ConnectorCapabilities data={connector} />

## Supported countries

<ConnectorRegions data={connector} kind="countries" />

## Supported currencies

<ConnectorRegions data={connector} kind="currencies" />

## Integration

For SEPA, the default integration for Adyen is through a redirect to a hosted payments page.

### Redirect integration

Start by creating a new transaction with the following required fields.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
      transactionCreate: new TransactionCreate()
      {
          Amount = 1299,
          Currency = "EUR",
          Country = "DE",
          Intent = "capture",
          PaymentMethod =
              TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
                  new RedirectPaymentMethodCreate()
                  {
                      Method = "sepa",
                      Country = "DE",
                      Currency = "EUR",
                      RedirectUrl = "https://example.com/callback",
                  }
              ),
      }
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  currency := "EUR"
  country := "DE"
  method := components.RedirectPaymentMethodCreateMethodSepa
  redirectUrl := "https://example.com/callback"

  redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
      Method: method,
      Country: country,
      Currency: currency,
      RedirectURL: redirectUrl,
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
      Amount:        amount,
      Currency:      currency,
      Country:       &country,
      Intent:       gr4vy.Pointer(components.TransactionIntentCapture),
      PaymentMethod: &paymentMethod,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
      .transactionCreate(TransactionCreate.builder()
          .amount(1299L)
          .currency("EUR")
          .country("DE")
          .intent(TransactionIntent.CAPTURE)
          .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
              .method(RedirectPaymentMethodCreateMethod.SEPA)
              .country("DE")
              .currency("EUR")
              .redirectUrl("https://example.com/callback")
              .build()))
          .build())
      .call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
      amount: 1299,
      currency: 'EUR',
      country: 'DE',
      intent: 'capture',
      paymentMethod: new RedirectPaymentMethodCreate(
          method: 'sepa',
          country: 'DE',
          currency: 'EUR',
          redirectUrl: 'https://example.com/callback'
      )
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
      amount=1299,
      currency="EUR",
      country="DE",
      intent="capture",
      payment_method={
          "method": "sepa",
          "country": "DE",
          "currency": "EUR",
          "redirect_url": "https://example.com/callback",
      }
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
      amount: 1299,
      currency: "EUR",
      country: "DE",
      intent: "capture",
      paymentMethod: {
          method: "sepa",
          country: "DE",
          currency: "EUR",
          redirectUrl: "https://example.com/callback"
      }
  })
  ```
</CodeGroup>

After the transaction is created, the API response includes `payment_method.approval_url` and the `buyer_approval_pending` status.

```json theme={"system"}
{
  "type": "transaction",
  "id": "ea1efdd0-20f9-44d9-9b0b-0a3d71e9b625",
  "payment_method": {
    "type": "payment-method",
    "approval_url": "https://cdn.sandbox.spider.gr4vy.app/connectors/adyen/apm.html?token=..."
  },
  "method": "sepa"
}
```

Redirect the buyer to the `approval_url` so they can complete authentication and approve the payment. After approval the buyer is redirected to the `redirect_url` you provided when creating the transaction. Do not rely solely on the redirect - either poll the transaction or (recommended) rely on webhooks to detect the final status (for example `capture_succeeded` or failure states).

### Direct integration

Adyen provides [web](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=Web\&integration=Components\&version=6.23.0), [Android](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=Android\&integration=Components\&version=5.15.0) and [iOS](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=iOS\&integration=Components\&version=5.21.1) SDKs for a direct integration. For these flows you should indicate the platform by setting an appropriate `integration_client` when creating the transaction, and then build a client-side integration that uses the [`POST /transactions/:transaction_id/session`](/reference/transactions/get-transaction-session) API to initialize the Adyen SDK.

To start, create a new transaction with the appropriate `integration_client`.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
    transactionCreate: new TransactionCreate()
    {
      Amount = 1299,
      Currency = "EUR",
      Country = "DE",
      Intent = "capture",
      IntegrationClient = "ios",
      PaymentMethod =
        TransactionCreatePaymentMethod.CreateRedirectPaymentMethodCreate(
          new RedirectPaymentMethodCreate()
          {
            Method = "sepa",
            Country = "DE",
            Currency = "EUR",
            RedirectUrl = "https://example.com/callback",
          }
        ),
    }
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  currency := "EUR"
  country := "DE"
  integrationClient := "ios"
  method := components.RedirectPaymentMethodCreateMethodSepa
  redirectUrl := "https://example.com/callback"

  redirectPaymentMethodCreate := components.RedirectPaymentMethodCreate{
    Method: method,
    Country: country,
    Currency: currency,
    RedirectURL: redirectUrl,
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodRedirectPaymentMethodCreate(redirectPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
    Amount:            amount,
    Currency:          currency,
    Country:           &country,
    Intent:           gr4vy.Pointer(components.TransactionIntentCapture),
    IntegrationClient: &integrationClient,
    PaymentMethod:     &paymentMethod,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
    .transactionCreate(TransactionCreate.builder()
      .amount(1299L)
      .currency("EUR")
      .country("DE")
      .intent(TransactionIntent.CAPTURE)
      .integrationClient("ios")
      .paymentMethod(TransactionCreatePaymentMethod.of(RedirectPaymentMethodCreate.builder()
        .method(RedirectPaymentMethodCreateMethod.SEPA)
        .country("DE")
        .currency("EUR")
        .redirectUrl("https://example.com/callback")
        .build()))
      .build())
    .call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
    amount: 1299,
    currency: 'EUR',
    country: 'DE',
    intent: 'capture',
    integrationClient: 'ios',
    paymentMethod: new RedirectPaymentMethodCreate(
      method: 'sepa',
      country: 'DE',
      currency: 'EUR',
      redirectUrl: 'myapp://callback'
    )
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
    amount=1299,
    currency="EUR",
    country="DE",
    intent="capture",
    integration_client="ios",
    payment_method={
      "method": "sepa",
      "country": "DE",
      "currency": "EUR",
      "redirect_url": "https://example.com/callback",
    }
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
    amount: 1299,
    currency: "EUR",
    country: "DE",
    intent: "capture",
    integrationClient: "ios",
    paymentMethod: {
      method: "sepa",
      country: "DE",
      currency: "EUR",
      redirectUrl: "https://example.com/callback"
    }
  })
  ```
</CodeGroup>

For mobile, set `integration_client` to `ios` or `android` and use your app deep link for `redirect_url` (for example, `yourapp://`).

After the transaction is created, the API response includes a `session_token` which can be used to get the [session data](/reference/transactions/get-transaction-session) for that transaction.

```sh theme={"system"}
POST /transactions/:transaction_id/session?token=:session_token
```

<CodeGroup>
  ```json Web theme={"system"}
  {
    "session_data": {
      "sessionId": "CS04C0B8AC9849A7D8E25B20D",
      "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
      "environment": "live",
      "clientKey": "client-key",
      "returnUrl": "https://example.com/callback",
      "paymentMethod": "sepa",
      "storePaymentMethod": true
    },
    "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
    "integration_client": "web"
  }
  ```

  ```json iOS theme={"system"}
  {
    "session_data": {
      "sessionId": "CS04C0B8AC9849A7D8E25B20D",
      "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
      "environment": "live",
      "clientKey": "client-key",
      "returnUrl": "yourapp://",
      "paymentMethod": "sepa",
      "storePaymentMethod": true
    },
    "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
    "integration_client": "ios"
  }
  ```

  ```json Android theme={"system"}
  {
    "session_data": {
      "sessionId": "CS04C0B8AC9849A7D8E25B20D",
      "sessionData": "Ab02b4c0!BQABAgBLgbLpvkt1r3",
      "environment": "live",
      "clientKey": "client-key",
      "returnUrl": "yourapp://",
      "paymentMethod": "sepa",
      "storePaymentMethod": true
    },
    "default_completion_url": "https://api.sandbox.spider.gr4vy.app/transactions/approve/some-token",
    "integration_client": "android"
  }
  ```
</CodeGroup>

This session data provides the `sessionId` and `sessionData` required to load the Adyen SDK.

<CodeGroup>
  ```js Web theme={"system"}
  const adyenEnvironment = sessionData.environment;
  const clientKey = sessionData.clientKey;
  const sessionId = sessionData.sessionId;
  const adyenSessionData = sessionData.sessionData;
  const returnUrl = sessionData.returnUrl;
  const paymentMethod = sessionData.paymentMethod;
  const storePaymentMethod = sessionData.storePaymentMethod;
  const configuration = {
      environment: adyenEnvironment,
      clientKey,
      analytics: {
        enabled: false,
      },
      session: {
        id: sessionId,
        sessionData: adyenSessionData,
      },
  }
  AdyenCheckout(configuration).then(function (checkout) {
    let component = checkout
      .create(paymentMethod)
      .mount('#component');
    });
  ```

  ```swift iOS  theme={"system"}
  var adyenEnvironment = sessionData.environment;
  var clientKey = sessionData.clientKey;
  var sessionId = sessionData.sessionId;
  var adyenSessionData = sessionData.sessionData;
  var returnUrl = sessionData.returnUrl;
  var paymentMethod = sessionData.paymentMethod;
  var storePaymentMethod = sessionData.storePaymentMethod;

  override func viewDidLoad() {
    super.viewDidLoad()

    let configuration = AdyenSession.Configuration(sessionIdentifier: sessionId,
      initialSessionData: adyenSessionData)

    AdyenSession.initialize(with: configuration, delegate: self, presentationDelegate: self) { [weak self] result in
      switch result {
        case let .success(session):
            //Store the session object.
            self?.session = session
        case let .failure(error):
            //Handle the error.
      }
    }
  }   
  ```

  ```kotlin Android theme={"system"}
  val adyenEnvironment = sessionData.environment;
  val clientKey = sessionData.clientKey;
  val sessionId = sessionData.sessionId;
  val adyenSessionData = sessionData.sessionData;
  val returnUrl = sessionData.returnUrl;
  val paymentMethod = sessionData.paymentMethod;
  val storePaymentMethod = sessionData.storePaymentMethod;

  // Create the session object
  val checkoutSession = CheckoutSession(
      session = Session(id = sessionId, sessionData = adyenSessionData),
      environment = Environment.TEST,
      clientKey = clientKey
  )

  when (result) {
      is CheckoutSessionResult.Success -> handleCheckoutSession(result.checkoutSession)
      is CheckoutSessionResult.Error -> handleError(result.exception)
  }
  ```
</CodeGroup>

#### Complete the transaction

<Badge color="green">Recommended</Badge>

On mobile integrations, after the buyer completes the payment flow, the Adyen SDK provides the developer with an `onFinished` call, which includes a `statusCode`.

The system automatically syncs the status through webhooks, but to complete the transaction it is also recommended sending a `GET` request to the `default_completion_url` provided in the session response with the `sessionId` and the `sessionResult` as query parameters to finalize the transaction. This also moves the transaction to a completed status without waiting for the webhook to be sent.

The call returns a `204 No Content` response. After receiving this response, you can also optionally fetch the transaction to confirm final status.

<CodeGroup>
  ```swift iOS  theme={"system"}
  func didComplete(with result: AdyenSessionResult,
              component: Component,
              session: AdyenSession)
  {
      var urlComponents = URLComponents(string: defaultCompletionUrl)!
      urlComponents.queryItems = [
          URLQueryItem(name: "sessionId", value: session.session.id),
          URLQueryItem(name: "sessionResult", value: result.sessionResult)
      ]
      
      var request = URLRequest(url: urlComponents.url!)
      request.httpMethod = "GET"
      let task = URLSession.shared.dataTask(with: request) { data, response, error in
          // Handle 204 response, you can now poll the transaction
      }
      task.resume()
  }
  ```

  ```kotlin Android theme={"system"}
  override fun onFinished(result: SessionPaymentResult) {
      val sessionResult = result.sessionResult
      val uri = Uri.parse(defaultCompletionUrl)
          .buildUpon()
          .appendQueryParameter("sessionId", result.sessionId)
          .appendQueryParameter("sessionResult", sessionResult)
          .build()
      val url = URL(uri.toString())
      val urlConnection = url.openConnection() as HttpURLConnection
      urlConnection.requestMethod = "GET"
      val responseCode = urlConnection.responseCode
      if (responseCode == HttpURLConnection.HTTP_NO_CONTENT) {
          // Handle 204 response, you can now poll the transaction
      }
  }
  ```
</CodeGroup>

Please refer to the Adyen documentation for the [web](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=Web\&integration=Components\&version=6.23.0), [Android](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=Android\&integration=Components\&version=5.15.0) and [iOS](https://docs.adyen.com/online-payments/build-your-integration/sessions-flow?platform=iOS\&integration=Components\&version=5.21.1) for further guidance.

### Recurring payments

SEPA via Adyen supports recurring payments. To process a recurring payment, please be aware of the following limitations when storing a SEPA payment method for future use.

* To store a SEPA payment for future use, set `store: true` on the transaction request.
* When stored, a SEPA payment method is initially in a `processing` state until a webhook is received from Adyen. You need to set up the Adyen `RECURRING_CONTRACT` webhooks for this update to be received.
* A stored SEPA payment method in a `processing` state can not be used in Embed until it is ready and marked as `succeeded`

Once a SEPA payment method is successfully stored, you can use it to create a subsequent payment.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
      transactionCreate: new TransactionCreate()
      {
          Amount = 1800,
          Currency = "EUR",
          Country = "DE",
          Intent = "capture",
          PaymentMethod = TransactionCreatePaymentMethod.CreateTokenPaymentMethodCreate(
              new TokenPaymentMethodCreate()
              {
                  Id = "f758d736-9a81-4bd0-85a9-2d3ee361b863"
              }
          ),
          IsSubsequentPayment = true,
          MerchantInitiated = true,
          PaymentSource = "recurring"
      }
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1800)
  currency := "EUR"
  country := "DE"
  paymentSource := components.TransactionPaymentSourceRecurring

  tokenPaymentMethodCreate := components.TokenPaymentMethodCreate{
      ID: "f758d736-9a81-4bd0-85a9-2d3ee361b863",
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodTokenPaymentMethodCreate(tokenPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
      Amount:              amount,
      Currency:            currency,
      Country:             &country,
      Intent:              gr4vy.Pointer(components.TransactionIntentCapture),
      PaymentMethod:       &paymentMethod,
      IsSubsequentPayment: gr4vy.Bool(true),
      MerchantInitiated:   gr4vy.Bool(true),
      PaymentSource:       &paymentSource,
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
      .transactionCreate(TransactionCreate.builder()
          .amount(1800L)
          .currency("EUR")
          .country("DE")
          .intent(TransactionIntent.CAPTURE)
          .paymentMethod(TransactionCreatePaymentMethod.of(TokenPaymentMethodCreate.builder()
              .id("f758d736-9a81-4bd0-85a9-2d3ee361b863")
              .build()))
          .isSubsequentPayment(true)
          .merchantInitiated(true)
          .paymentSource(TransactionPaymentSource.RECURRING)
          .build())
      .call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
      amount: 1800,
      currency: 'EUR',
      country: 'DE',
      intent: 'capture',
      paymentMethod: new TokenPaymentMethodCreate(
          id: 'f758d736-9a81-4bd0-85a9-2d3ee361b863'
      ),
      isSubsequentPayment: true,
      merchantInitiated: true,
      paymentSource: 'recurring'
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
      amount=1800,
      currency="EUR",
      country="DE",
      intent="capture",
      payment_method=models.TokenPaymentMethodCreate(
          id="f758d736-9a81-4bd0-85a9-2d3ee361b863"
      ),
      is_subsequent_payment=True,
      merchant_initiated=True,
      payment_source="recurring"
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
      amount: 1800,
      currency: "EUR",
      country: "DE",
      intent: "capture",
      paymentMethod: {
          method: "id",
          id: "f758d736-9a81-4bd0-85a9-2d3ee361b863"
      },
      isSubsequentPayment: true,
      merchantInitiated: true,
      paymentSource: "recurring"
  })
  ```
</CodeGroup>

When processing a recurring payment please note the following.

* SEPA supports the `payment_source` of `recurring` and `instalment`, which maps to `Subscription` on the Adyen API. In all other scenarios it sets the recurring processing mode as `UnscheduledCardOnFile`.
* Until the first transaction is settled, a stored SEPA payment uses a different mandate for the subsequent request. In a production environment, this might lead to a subsequent payment failing if the original mandate has not been fully settled yet.

### Auto-rescue

Adyen's [auto-rescue](https://docs.adyen.com/online-payments/auto-rescue/sepa/) feature is supported
by this connector. This feature automatically retries customer-not-present direct debit
transactions when they receive a chargeback.

To enable this feature, pass in the following connection options for Adyen when making a subsequent payment request.

<CodeGroup>
  ```csharp C# theme={"system"}
  var transaction = await client.Transactions.CreateAsync(
      transactionCreate: new TransactionCreate()
      {
          Amount = 1299,
          Country = "DE",
          Currency = "EUR",
          Intent = "capture",
          PaymentMethod = TransactionCreatePaymentMethod.CreateTokenPaymentMethodCreate(
              new TokenPaymentMethodCreate()
              {
                  Id = "7f6fb9ca-eb1c-42c6-9b65-8f1c699b84bd"
              }
          ),
          ConnectionOptions = new Dictionary<string, object>
          {
              ["adyen-sepa"] = new Dictionary<string, object>
              {
                  ["autoRescue"] = true,
                  ["maxDaysToRescue"] = 5
              }
          },
          PaymentSource = "card_on_file",
          IsSubsequentPayment = true,
          MerchantInitiated = true
      }
  );
  ```

  ```go Go theme={"system"}
  amount := int64(1299)
  country := "DE"
  currency := "EUR"
  paymentSource := components.TransactionPaymentSourceCardOnFile

  tokenPaymentMethodCreate := components.TokenPaymentMethodCreate{
      ID: "7f6fb9ca-eb1c-42c6-9b65-8f1c699b84bd",
  }
  paymentMethod := components.CreateTransactionCreatePaymentMethodTokenPaymentMethodCreate(tokenPaymentMethodCreate)

  transactionCreate := components.TransactionCreate{
      Amount:        amount,
      Country:       &country,
      Currency:      currency,
      Intent:        gr4vy.Pointer(components.TransactionIntentCapture),
      PaymentMethod: &paymentMethod,
      ConnectionOptions: map[string]interface{}{
          "adyen-sepa": map[string]interface{}{
              "autoRescue":      true,
              "maxDaysToRescue": 5,
          },
      },
      PaymentSource:       &paymentSource,
      IsSubsequentPayment: gr4vy.Bool(true),
      MerchantInitiated:   gr4vy.Bool(true),
  }

  transaction, err := client.Transactions.Create(ctx, transactionCreate, nil, nil, nil)
  ```

  ```java Java theme={"system"}
  CreateTransactionResponse transactionResponse = gr4vyClient.transactions().create()
      .transactionCreate(TransactionCreate.builder()
          .amount(1299L)
          .country("DE")
          .currency("EUR")
          .intent(TransactionIntent.CAPTURE)
          .paymentMethod(TransactionCreatePaymentMethod.of(TokenPaymentMethodCreate.builder()
              .id("7f6fb9ca-eb1c-42c6-9b65-8f1c699b84bd")
              .build()))
          .connectionOptions(Map.of(
              "adyen-sepa", Map.of(
                  "autoRescue", true,
                  "maxDaysToRescue", 5
              )
          ))
          .paymentSource(TransactionPaymentSource.CARD_ON_FILE)
          .isSubsequentPayment(true)
          .merchantInitiated(true)
          .build())
      .call();

  Transaction transaction = transactionResponse.transaction().orElse(null);
  ```

  ```php PHP theme={"system"}
  $transactionCreate = new TransactionCreate(
      amount: 1299,
      country: 'DE',
      currency: 'EUR',
      intent: 'capture',
      paymentMethod: new TokenPaymentMethodCreate(
          id: '7f6fb9ca-eb1c-42c6-9b65-8f1c699b84bd'
      ),
      connectionOptions: [
          'adyen-sepa' => [
              'autoRescue' => true,
              'maxDaysToRescue' => 5
          ]
      ],
      paymentSource: 'card_on_file',
      isSubsequentPayment: true,
      merchantInitiated: true
  );
  $response = self::$sdk->transactions->create($transactionCreate);
  $transaction = $response->transaction;
  ```

  ```python Python theme={"system"}
  transaction: models.Transaction = client.transactions.create(
      amount=1299,
      country="DE",
      currency="EUR",
      intent="capture",
      payment_method=models.TokenPaymentMethodCreate(
          id="7f6fb9ca-eb1c-42c6-9b65-8f1c699b84bd"
      ),
      connection_options={
          "adyen-sepa": {
              "autoRescue": True,
              "maxDaysToRescue": 5
          }
      },
      payment_source="card_on_file",
      is_subsequent_payment=True,
      merchant_initiated=True
  )
  ```

  ```ts TypeScript theme={"system"}
  const transaction = await gr4vy.transactions.create({
      amount: 1299,
      country: "DE",
      currency: "EUR",
      intent: "capture",
      paymentMethod: {
          method: "id",
          id: "7f6fb9ca-eb1c-42c6-9b65-8f1c699b84bd"
      },
      connectionOptions: {
          "adyen-sepa": {
              autoRescue: true,
              maxDaysToRescue: 5
          }
      },
      paymentSource: "card_on_file",
      isSubsequentPayment: true,
      merchantInitiated: true
  })
  ```
</CodeGroup>

<Note>
  Please note that this feature only works for customer-not-present transactions where `is_subsequent_payment` is set to `true`.
</Note>

The following fields need to be set.

* `autoRescue` - A boolean value that enables the feature. This defaults to `false`.
* `maxDaysToRescue` - The rescue window, in days. You can specify between 1 and 42 days. Adyen recommends using a rescue window of one calendar month (30 days).
* `autoRescueScenario` - This is one of the [test scenarios](https://docs.adyen.com/online-payments/auto-rescue/sepa/#test-auto-rescue) as defined by Adyen. This only works in sandbox.
* `ownerName` - Set this to the type of chargeback that you want to simulate. Use a concatenation of chargeback and the reason code. For example, `chargeback:MS03` or `chargeback:AM04`. This only works in sandbox.

Auto-rescued SEPA transactions are always `capture_succeeded` in the system as the payment
is always processed successfully initially. Instead, the auto-rescue fights the chargeback by re-attempting the payment.
The system does not report on these attempts, but may report the chargeback in settlement reports.

## Testing

In a test environment, you can simulate a SEPA payment.
Adyen has [extensive instructions](https://docs.adyen.com/payment-methods/sepa-direct-debit/web-component/#test-and-go-live) on how
to help with this.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.