Title: DahuConcept Deferred SEPA for WooCommerce
Author: Hugo Vial-Jaime
Published: <strong>November 14, 2026</strong>
Last modified: November 14, 2026

---

Search plugins

![](https://ps.w.org/dahuconcept-deferred-sepa/assets/banner-772x250.png?rev=3802409)

![](https://ps.w.org/dahuconcept-deferred-sepa/assets/icon.svg?rev=3802409)

# DahuConcept Deferred SEPA for WooCommerce

 By [Hugo Vial-Jaime](https://profiles.wordpress.org/dahuconcept/)

[Download](https://downloads.wordpress.org/plugin/dahuconcept-deferred-sepa.1.2.5.zip)

 * [Details](https://wordpress.org/plugins/dahuconcept-deferred-sepa/#description)
 * [Reviews](https://wordpress.org/plugins/dahuconcept-deferred-sepa/#reviews)
 *  [Installation](https://wordpress.org/plugins/dahuconcept-deferred-sepa/#installation)
 * [Development](https://wordpress.org/plugins/dahuconcept-deferred-sepa/#developers)

 [Support](https://wordpress.org/support/plugin/dahuconcept-deferred-sepa/)

## Description

Some customers are not charged when they order. A trade account on 30-day terms,

a wholesale buyer, a subscription-style arrangement: the mandate is signed, the 
order ships, and the money is taken later.

Stripe charges a SEPA Direct Debit as soon as the order is placed. This plugin
 
adds a checkout option that does not. It reuses the mandate the customer has already
saved, records it on the order, puts the order on hold, and schedules the real charge
for a configurable number of days after the order is marked Completed. Eight days
by default, overridable per customer.

**Who may pay late is decided by the shop, not by the customer.** An
 administrator
names one of the customer’s saved IBANs as the active mandate on their user profile.
The customer must also have that same IBAN set as their own default. Both halves
have to agree, which is what stops a customer quietly switching to an IBAN nobody
approved.

#### What it does

 * **Deferred charging.** Nothing is taken at checkout. The charge is scheduled
   
   automatically when the order is completed, using Action Scheduler.
 * **Move the date.** The due date is shown on the order screen and can be moved
   
   until the moment it fires, with every move recorded.
 * **Charge now.** A button to send the charge immediately, behind a capability
   
   check, a nonce and a confirmation.
 * **Charged once, whatever happens.** A persistent idempotency key per order
    means
   a replayed scheduled action, a network timeout or a retry can never produce a
   second debit.
 * **Its own Stripe webhook.** SEPA is asynchronous: a charge leaves as
    “processing”
   and succeeds or fails days later. A dedicated endpoint with its own signing secret
   listens for the outcome and for disputes, independently of the official Stripe
   plugin’s webhook.
 * **Per-customer terms.** A delay set on a customer’s profile overrides the
    global
   one, for a trade account on different terms.
 * **A charges screen.** WooCommerce  SEPA charges, with an Upcoming tab for
    expected
   cash and a History tab of every charge sent, filterable by date and outcome, 
   sortable, and exportable to CSV.
 * **Optionally hides Stripe’s immediate SEPA option** at checkout, while
    leaving
   it available under My account  Payment methods, where the customer signs the 
   mandate in the first place.
 * **Nothing fails in silence.** A refused charge is emailed to the shop, once,
   
   with the reason and never with a raw carrier response. A charge whose date has
   passed and which never ran is taken out of “upcoming”, listed at the top of the
   screen with what is in the way, and reported by a daily check: a deferred charge
   is the one payment path with no customer in front of a screen to find out it 
   did not work. Nothing is ever retried automatically, because a charge that may
   already have been sent would be taken twice.
 * **Diagnostics.** The gateway is deliberately hard to qualify for, so it can
    
   show an administrator each condition it checks and the answer, rather than leaving“
   why is it not showing?” to be guessed.
 * **HPOS and legacy order storage.** Both, with no custom tables: everything is
   
   order meta.

#### What it needs

WooCommerce, and SEPA Direct Debit working at Stripe — in practice the official

WooCommerce Stripe Payment Gateway, which is what lets a customer sign and save 
a mandate. This plugin does not replace it and does not take card payments.

The Stripe secret key can be this plugin’s own setting (a restricted key that
 may
only write PaymentIntents is enough) or borrowed from the official plugin’s configuration.

#### Before you switch it on

A SEPA mandate carries obligations to the payer that are yours, not this
 plugin’s.
Depending on the mandate you use, you may owe the customer advance notice of the
date and amount of each debit. Deferring a charge changes that date. Check what 
your mandate and your bank require before charging customers on a delay, and tell
your customers what to expect.

This plugin is not affiliated with or endorsed by Stripe.

### External services

This plugin sends requests to **Stripe** (https://api.stripe.com), using the
 Stripe
API key you configure. Stripe is the payment processor that holds the customer’s
SEPA mandate and moves the money; without it the plugin has nothing to charge.

What is sent, and when:

 * **When a deferred charge comes due** — the order total and currency, the
    Stripe
   customer and payment-method identifiers already saved on the order, a description
   containing the order number and your site name, and metadata containing the order
   id, the order number and your site URL. This is the request that creates and 
   confirms the payment.
 * **When resolving which Stripe customer owns a saved mandate** — the
    payment-
   method identifier alone, read back to confirm its owner. The answer is cached
   so this is not repeated.

Nothing is sent for an order that is not being charged, and no request is made
 
unless a Stripe secret key is configured.

The plugin also _receives_ requests from Stripe, at its own webhook endpoint,
 telling
it whether a charge succeeded, failed or was disputed. Those requests are rejected
unless they carry a valid signature for your webhook signing secret.

Stripe’s terms: https://stripe.com/legal/ssa
 Stripe’s privacy policy: https://stripe.
com/privacy

This plugin is not affiliated with, endorsed by or sponsored by Stripe.

## Screenshots

[⌊The gateway settings.⌉⌊The gateway settings.⌉[

The gateway settings.

[⌊Naming a customer's active mandate on their user profile.⌉⌊Naming a customer's
active mandate on their user profile.⌉[

Naming a customer’s active mandate on their user profile.

[⌊The charge date on the order screen, with the button to send it now.⌉⌊The charge
date on the order screen, with the button to send it now.⌉[

The charge date on the order screen, with the button to send it now.

[⌊WooCommerce → SEPA charges: expected cash, and the history.⌉⌊WooCommerce → SEPA
charges: expected cash, and the history.⌉[

WooCommerce  SEPA charges: expected cash, and the history.

## Installation

 1. Install and activate WooCommerce, and the official WooCommerce Stripe Payment Gateway
    with SEPA Direct Debit enabled. Keep Stripe in test mode while you set this up.
 2. Install and activate this plugin.
 3. Go to WooCommerce  Settings  Payments  Deferred SEPA Direct Debit and enable it.
    Set the default delay.
 4. Create a webhook endpoint in your Stripe dashboard pointing at https://yoursite.
    example/wp-json/ubac-sepa/v1/webhook, listening for `payment_intent.succeeded`,`
    payment_intent.payment_failed` and charge.dispute.created. Copy its signing secret
    into `wp-config.php`:
 5. define( ‘UBAC_SEPA_WEBHOOK_SECRET’, ‘whsec_…’ );
 6. Have a test customer save an IBAN under My account  Payment methods, then approve
    it on their user profile under Deferred SEPA Direct Debit.

Test mode and live mode are separate endpoints with different secrets. When you 
go live, create a live endpoint and update the constant, or every notification is
rejected and orders stay unresolved.

## FAQ

### Why does the gateway not appear at checkout?

It appears only when all of these hold: it is enabled; the customer is signed
 in;
their role is not excluded; an administrator has named one of their IBANs as the
active mandate; the customer has that same IBAN as their own default; and a Stripe
secret key is configured. Turn on Diagnostics in the gateway settings and the plugin
will tell you which one is failing.

### Can a customer be charged twice?

No. Each order gets one idempotency key, generated once and reused, so Stripe
 treats
every retry of the same charge as the same request.

### What happens if a charge fails?

The webhook marks the order failed and records the reason Stripe gave, as an
 order
note. The charge is not retried automatically: a failed direct debit usually needs
a human to look at it.

### Does it work without the official Stripe plugin?

The charging does, given a secret key and a customer who already has a mandate
 
saved at Stripe. But that plugin is how a customer signs and saves a mandate in 
the first place, so in practice you want both.

### Does it handle currencies other than the euro?

No. Stripe accepts SEPA Direct Debit in euro only. An order in another currency

is refused with an order note rather than charged in the wrong unit.

### Is my order history deleted if I uninstall it?

No. The settings are removed and any queued charge is cancelled. Everything
 written
on an order — when each charge was due, when it was sent, what Stripe answered —
is a payment record and is kept. No setting changes that: an uninstall never removes
it, not least because an uninstall is very often a step in reinstalling. If you 
have to erase it — a data-erasure request, say — that is an operation on your own
orders, through WooCommerce’s personal data tools or your database, and not something
this plugin does on the way out.

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“DahuConcept Deferred SEPA for WooCommerce” is open source software. The following
people have contributed to this plugin.

Contributors

 *   [ Hugo Vial-Jaime ](https://profiles.wordpress.org/dahuconcept/)

[Translate “DahuConcept Deferred SEPA for WooCommerce” into your language.](https://translate.wordpress.org/projects/wp-plugins/dahuconcept-deferred-sepa)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/dahuconcept-deferred-sepa/),
check out the [SVN repository](https://plugins.svn.wordpress.org/dahuconcept-deferred-sepa/),
or subscribe to the [development log](https://plugins.trac.wordpress.org/log/dahuconcept-deferred-sepa/)
by [RSS](https://plugins.trac.wordpress.org/log/dahuconcept-deferred-sepa/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 1.2.5

 * Changed: the requested payment method read on the order screen is now sanitised
   with `sanitize_text_field()` rather than `wc_clean()`. The line was already sanitising,
   but WPCS does not recognise WooCommerce’s helper and reported it as unsanitised
   input — on a payment path, using the tool the tooling recognises is better than
   annotating the warning away. It also fails more safely: a forged array now yields
   an empty string, which matches no known gateway, where the previous helper returned
   the array.
 * Changed: the two user-meta deletions at uninstall now carry the `SlowDBQuery`
   sniff in their annotation, with the reason. Deleting by meta key alone is the
   point there — it removes every user’s copy in one pass, once — and indexing for
   it would cost on every request for the life of the shop.

#### 1.2.4

 * Changed: the compiled French catalogue now travels in the package. It was left
   out on the grounds that the directory serves language packs, which is true only
   for a copy installed from the directory and only once translations have been 
   imported: a copy installed by hand showed English with a catalogue that was fully
   translated.
 * Changed: the French readme moves under docs/, so the directory’s checker no longer
   reports an unexpected markdown file at the plugin root.

#### 1.2.3

 * Changed: WordPress 6.2 is now the floor. Three extensions of the family need 
   it for prepare()’s %i identifier placeholder, and the family states one floor
   rather than two because the welcome screen and the shared admin stylesheet are
   copied byte for byte across it.

#### 1.2.2

 * Fixed: a webhook event could confirm a charge on an order this plugin had never
   charged. The signature proves an event comes from Stripe, not that it concerns
   this order, and the metadata it carries is set by whoever created the payment.
   A confirmation now requires the payment intent this plugin recorded when it sent
   the charge, and the two must match.
 * An event that has nothing to confirm is refused, and the refusal is written on
   the order rather than dropped in silence, so a charge whose Stripe answer was
   lost in transit can still be picked up by hand.
 * Fixed: an event whose payment id arrived in Stripe’s expanded form wrote the 
   literal text “Array” as the order’s payment reference. The id is now read one
   way and used everywhere, instead of being read once for the check and once again
   for the record.
 * An event the plugin does not act on no longer writes anything on the order, and
   a refusal is written once per order and per event type rather than on every delivery.
 * Fixed: an event is applied once however often Stripe redelivers it. Replays left
   the amounts alone but repeated the order notes, and a redelivered failure on 
   a settled charge sent one reversal alert per delivery.

#### 1.2.1

 * An empty Upcoming tab now says what will appear there instead of showing a bare
   line of text, and an empty History tab no longer blames filters that were never
   set.

#### 1.2.0

 * The activation screen now opens on the plugin’s own mark rather than its initials,
   and the banner carries the same drawing as a watermark.

#### 1.1.1

 * A per-customer charge delay of zero days — “charge as soon as it ships” — is
   
   now saved. It was silently discarded, and that customer fell back to the shop’s
   global delay with nothing on screen to say so.
 * Uninstalling now also removes the overdue-sweep marker, any charge claim left
   
   behind by a worker killed mid-charge, and the daily sweep’s own cron event, which
   used to keep waking the site up for a hook nothing answered.

#### 1.1.0

 * A charge Stripe accepted and then refused before settlement no longer leaves
   
   the order stuck. Nothing left the customer’s account, so the order is reopened
   and can be scheduled again — previously the “already charged” guard refused a
   charge, a reschedule and the “settled another way” mark alike, leaving no way
   out at all.
 * A failure or a dispute reported on a charge that was already collected is
    emailed
   to the shop. It was written on the order and told to nobody.
 * Such an order is deliberately left untouched: undoing a settlement on an
    event
   that may be a duplicate is the one move that could cost money.

#### 1.0.0

 * First release.

## Meta

 *  Version **1.2.5**
 *  Last updated **18 hours ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.2 or higher **
 *  Tested up to **7.1.4**
 *  PHP version ** 7.4 or higher **
 * Tags
 * [deferred payment](https://wordpress.org/plugins/tags/deferred-payment/)[Direct Debit](https://wordpress.org/plugins/tags/direct-debit/)
   [mandate](https://wordpress.org/plugins/tags/mandate/)[payment terms](https://wordpress.org/plugins/tags/payment-terms/)
   [sepa](https://wordpress.org/plugins/tags/sepa/)
 *  [Advanced View](https://wordpress.org/plugins/dahuconcept-deferred-sepa/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/dahuconcept-deferred-sepa/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/dahuconcept-deferred-sepa/reviews/)

## Contributors

 *   [ Hugo Vial-Jaime ](https://profiles.wordpress.org/dahuconcept/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/dahuconcept-deferred-sepa/)