Skip to content

EP Finance Sources

EP Finance Sources is the plumbing between the plugins that take money, or owe it, and the book that records it. Nothing here is typed in twice.

This page documents EP Finance Sources 0.2.0.

Published by ElmsPark Studio.

SourceWhat postsDirection
EP EcommerceOrders when fulfilled, and refunds as an exact reversalIncome
EP Ecommerce SubscriptionsRenewalsIncome
EP BookingBooking payments and refundsIncome
EP EventsTicket salesIncome
EP InstructorsApproved and paid pay-linesCost
Stripe (optional)Processing fees, synced in bulkCost

EP Instructors already works out what each instructor is owed for every class taught. Until now that figure only left the plugin as a CSV somebody had to retype into the accounts. It now posts itself.

Each approved pay-line is recorded as a cost against the class it was earned on, not the day it happened to be approved. A class taught in August stays an August cost even if the pay-line is approved in September, so a profit and loss report, or a VAT period built on it, covers what actually happened in that period.

A pay-line marked paid tells us the studio considers it settled. It does not tell us which bank account paid it, on what date, or whether a single payment covered five classes.

So the plugin records the cost, and leaves the amount owed standing. That amount clears when the real payment arrives on your bank statement and is imported through EP Finance Importer.

This is deliberate. Your bank statement stays the one place that says money left the business, which is also what stops the same wage being counted twice: once when it was approved, and again when it was paid.

You are told, and nothing is altered. The sweep reports the pay-line, the figure currently in the book, and the figure now, and leaves the book alone. Changing a wage after it was approved is a bookkeeping decision, not something a background job should quietly make for you.

Every posting carries an identifier derived from the thing it came from. Re-running a sweep, or running a backfill over a period you have already done, changes nothing. This is what makes the buttons safe to press whenever you are unsure.

Pay-lines still waiting for approval are never posted.

SettingWhat it does
Source togglesTurn any bridge off if you never want it posting to the book
Account mapping overridesPoint any of the accounts it uses at one of your own, if you already keep a real chart of accounts
Stripe feedOff by default. A Stripe key (a restricted key with read access to Balance transactions is enough, stored encrypted), the date the first sync reads from, and a bank account for payouts. “Preview: Stripe feed” shows what would be posted without posting; “Sync: Stripe feed” posts

The plugin creates the accounts and categories it needs the first time you press Set up default accounts and categories. Everything is saved with PageMotor’s own Save button.

Orders post the moment they are fulfilled. The other sources are swept, nightly where EP Cron is available, and on demand from the buttons on the settings screen. There is a button per source and one for all of them.

  • Settings language menu. The language menu in this plugin’s settings now lists only the languages it is actually translated into, plus English, so you can no longer pick a language that changes nothing.
  • Sales now carry their VAT. With EP Finance 0.8.0 set as VAT registered, every Stripe payment, shop order, subscription payment, booking, event ticket and course sale is put in your books at its price without VAT, with the VAT on its own line, at the rate you choose for site sales in EP Finance. Refunds take their VAT back off. Sales dated before your VAT registration date are not changed.
  • A part refund of a sale that carries VAT takes back the right share of the VAT.
  • Course sales from EP Courses are now booked automatically. Each paid enrolment is recorded under a new “Course income” category, on the day it was paid. Before, course money reached your books only if the Stripe feed was switched on, and then as a general Stripe payment.
  • A course refunded in full is taken back out on the day of the refund. If Stripe then fails or cancels that refund, the sale is put back. If the refund is made again later, it is taken out again.
  • A customer who paid twice for the same course has both payments booked until you refund one.
  • Courses sold in currencies such as the Japanese yen are booked at the right amount, using your exchange rate for that currency.
  • New “Sweep: Courses” button, and a “Pause this bridge” box for EP Courses in the settings. Like the other bridges, it runs nightly.
  • If you already use the Stripe feed: course payments the feed has already booked are left as they are, so nothing is counted twice. From the first time the course bridge runs, new course payments are booked as course income, and the feed books only their Stripe fees.
  • Partial refunds of a course are not booked automatically, because EP Courses only records full refunds. Enter a partial refund by hand.
  • A second Stripe payment of a subscription on the same day is now booked. If a customer changed plan on the day they subscribed or renewed, Stripe took two payments that day: the plan’s payment and the charge for the change. Only the first reached your books. Each payment is now booked for its own amount.
  • Refunding that second payment takes only that payment out of your books. Before, it could reverse the other payment of that day instead, taking the wrong amount out.
  • PayPal subscriptions still book one payment per day, as before.
  • With the Stripe feed on, an event ticket paid through Stripe Checkout is no longer counted twice. If the feed read the payment before EP Events had finished recording it (for example when Stripe’s message to your site arrived late), the feed booked it as a general Stripe payment and the event ticket sync booked it again. The feed now recognises EP Events payments from the details EP Ecommerce Stripe attaches to them, so each ticket is booked once, as an event ticket.
  • The same applies to a ticket refunded before EP Events received the payment: neither the payment nor its refund is booked twice.
  • Tickets counted twice before this version are not changed. If you had the Stripe feed on while selling event tickets through Stripe Checkout, compare the “Stripe payment” entries in your books with your event tickets for the same days and amounts.
  • A booking refund that fails in Stripe comes back into your books. With EP Booking 2.4.45, when Stripe fails or cancels a refund of a booking, that refund is taken back out of your books with a “Refund failed” entry, dated the day EP Booking recorded the failure. Only the refund that failed is taken back: any other refund of the same booking stays.
  • If the booking is refunded again later, the new refund is booked as normal.
  • A booking refunded in full after a partial refund of unknown amount is now left to you. Partial refunds recorded by EP Booking before 2.4.41 carry no amount, so you were asked to enter them by hand. When such a booking was later refunded in full, the whole payment came out of your books, on top of the part you had entered. The booking is now listed for you to enter the rest by hand instead.
  • A failed Stripe refund of a subscription payment now always comes back into your books. Some older subscription refunds were booked as the whole payment in one go, before each Stripe refund was kept separately. If Stripe later failed or cancelled that refund, your books still showed the payment as refunded, although the money never left. The sync now undoes that refund with one “Refund failed” entry. If part of the payment really was refunded, that part is then booked on its own.
  • If you refund that payment again later and the money does leave, the new refund is booked as normal.
  • Nothing you will notice. If a sale, refund or payment amount from another plugin were ever too large for your books, the sync now reports “amount_out_of_range” instead of “bad_amount” (or “unknown_group” for a refund). EP Booking, EP Ecommerce and EP Ecommerce Subscriptions store amounts that cannot reach that size.
  • Booking refunds are dated the day they happened. With EP Booking 2.4.41 or later, a refund is now dated when EP Booking recorded it, not the day your books picked it up. A date inside your closed period is booked today, with a note, as for other refunds.
  • A booking refunded in part now comes out of your books by the amount refunded. Until now it stayed in full as income and was listed for you to enter by hand. Each partial refund is now booked for the new amount, on its own date. If the rest is refunded later, only the rest is booked.
  • Partial refunds from before this version are not booked for you. You were asked to enter those by hand, so they stay on that list, and only refunds made after you update are booked. A partial refund with no amount recorded (EP Booking before 2.4.41) also stays on the list.
  • A PayPal subscription payment refunded in part now comes out of your books by the amount refunded. Until now it stayed in full as income and was listed for you to enter by hand. Each refund is now booked for its own amount, on the day PayPal made it.
  • PayPal refunds are dated the day they happened. A refund PayPal notifies your site about is now dated the day PayPal made it. It used to be dated the day your site first noticed it, which could be a day or more later.
  • If PayPal says a payment was fully refunded but your site only received some of the refund notices, the rest is listed for you to enter by hand, with a note saying why.
  • This needs EP Ecommerce Subscriptions 0.2.25 and EP Ecommerce PayPal 0.1.19, and the PAYMENT.SALE.REFUNDED event added to your PayPal webhook. Without them it works as before.
  • An event ticket whose Stripe refund fails now goes back into your books. When a ticket sold through EP Events’ own Stripe checkout is refunded in full and Stripe then fails the refund (for example because the customer’s card has been closed) or you cancel it, EP Events 1.0.66 confirms the booking again. The refund is now undone in your books with one matching entry under Event ticket income, dated the day the booking came back; if that day is in a period you have already closed, it is recorded today with a note saying so.
  • If the same ticket is refunded again, it is taken out of your books again. However often a ticket is refunded and its refund fails, your books show the sale once while the booking stands and not at all while it is refunded.
  • With the Stripe feed on, these refunds and failed refunds are left to the event records, as the sale and the refund already were, so nothing is counted twice.
  • Update this plugin first, then EP Events 1.0.66, then EP Ecommerce Stripe 0.1.28.
  • A shop refund that fails or is cancelled now puts the sale back in your books. When a refunded EP Ecommerce order’s refund later fails at the payment provider (for example because the customer’s card has been closed) or is cancelled, the money stays with you and EP Ecommerce marks the order completed again. The refund is now undone in your books with one matching entry under Sales (website), dated the day the failure was seen; if that day is in a period you have already closed, it is recorded today with a note saying so.
  • If you then refund the same order again, it is taken out of your books again. However often an order is refunded and its refund fails, your books show the sale once when the order is completed and not at all when it is refunded.
  • A subscription’s first payment is never reversed or put back twice, whichever of the shop and the subscription records the refund.
  • With the Stripe feed on, a failed refund of a shop order is left to the shop records, as the refund itself was; a failed refund the feed recorded stays with the feed.
  • This needs EP Ecommerce 0.1.44 and EP Ecommerce Stripe 0.1.26 or later. Update all three together, or this plugin first.
  • A Stripe subscription refund that fails or is cancelled now puts the money back in your books. Stripe can fail a refund after you make it (for example when the customer’s card has been closed) or cancel one that was still pending, and the money then stays with you. Until now the refund stayed in your books. Now, once EP Ecommerce Subscriptions sees the refund fail, the refund is undone with one matching entry under Subscriptions, dated the day the failure was first seen; if that day is in a period you have already closed, it is recorded today with a note saying so.
  • If you then refund the same payment again, the new refund is taken out as normal, and never more than the customer paid.
  • A refund that failed before it ever reached your books is not recorded at all, and the run results list it.
  • With the Stripe feed on, a failed refund the feed recorded is now undone by the feed (before, Stripe’s “refund failure” entry was listed as a type it could not record). A failed refund of a subscription payment that EP Finance Sources recorded under Subscriptions is undone there instead, never twice.
  • This needs EP Ecommerce Subscriptions 0.2.23 or later. Update both together.
  • A Stripe subscription payment you refund now comes back out of your books. Until now a refunded Stripe subscription payment stayed recorded as income, unless you had switched on the Stripe feed, which recorded the refund under Stripe sales rather than Subscriptions. Each Stripe refund is now taken out under Subscriptions, dated the day you made it; if that day is in a period you have already closed, it is recorded today with a note saying so.
  • Partial refunds are handled exactly. A Stripe refund of part of a payment takes out just that amount. If you refund the rest later, that is taken out too, and never more than the customer paid.
  • A first payment refunded both in EP Ecommerce and at Stripe is taken out once, not twice.
  • If the Stripe feed already recorded one of these refunds, it is not recorded again, and the run results list it.
  • A partial refund of a payment in another currency is listed for you to enter by hand, with the refund and its amount. A full refund in another currency is taken out at the value it was recorded at.
  • This needs EP Ecommerce Subscriptions 0.2.22 or later; with an older version the Stripe feed keeps recording these refunds as before. Update both together.
  • A PayPal subscription payment you refund now comes back out of your books. Until now a refunded PayPal subscription payment stayed recorded as income. A full refund is now reversed, dated the day the refund was first seen; if that day is in a period you have already closed, it is recorded today with a note saying so.
  • Partial refunds are listed for you to enter. A partly refunded PayPal subscription payment is not reversed automatically (that would take out the part the customer kept). It is listed with the subscription, the payment date, the amount paid and, where PayPal says, the amount refunded, so you can enter the refund by hand.
  • A first payment refunded both in EP Ecommerce and at PayPal is taken out once, not twice.
  • A refund whose payment is not in your books yet (for example because it waits for an exchange rate) is listed and taken out on a later run, once the payment is in.
  • This needs EP Ecommerce Subscriptions 0.2.21 or later; with an older version it works as before.
  • PayPal subscription renewals now reach your books. Until now only the first payment of a PayPal subscription was recorded; every renewal after it was missing. Each PayPal renewal is now recorded on the day it was paid, for the amount PayPal took.
  • Past PayPal renewals are recovered too. Renewals paid before this update are read back from PayPal and recorded. This happens a few subscriptions at a time, so on a site with many PayPal subscribers the first runs may take several nights before all of the history is in your books.
  • A Stripe renewal is no longer lost when two arrive between runs. If a subscription renewed more than once between two nightly runs (for example while the nightly run was off), only the latest period was recorded. Every paid period is now recorded.
  • Renewals are recorded at the amount actually paid, not at the price of the original order, so a price change or a discount shows correctly.
  • A free period of a Stripe subscription (for example a trial month) is no longer recorded at the full price.
  • Nothing already in your books is recorded a second time. This needs EP Ecommerce Subscriptions 0.2.20 or later; with an older version it works as before.
  • Refunds are now dated on the day they happened. A refund of a shop order or an event ticket was dated the day the nightly run found it, which could be days or weeks later and put it in the wrong month. It is now dated when the order or registration was marked as refunded. EP Booking does not record when a refund was made, so a booking refund is still dated the day the run finds it.
  • A refund that falls in a period you have closed is still recorded. Your closed figures are not changed: the refund is recorded today instead, its description says the date it really happened, and the run results list it under “refunds dated today” so you can see it.
  • The Run and Sweep buttons now tell you when something went wrong. They used to say “run complete” even when a source failed or some items could not be posted. They now say what went wrong, and the details appear below either way.
  • Preview: Stripe feed no longer replaces your last run’s results. The preview is shown on its own, marked as a preview, and the results of your last real run stay as they were.
  • Renaming an account no longer creates a new one. If you renamed one of the accounts this plugin set up, for example “Stripe balance (pending)”, a new account with the old name appeared on the next page load. The plugin now remembers its accounts and categories by their identity, not their name.
  • New accounts use your book’s currency. Accounts this plugin creates were always set to pounds sterling; they now take the currency your books are kept in. Existing accounts are not changed.
  • The account set-up check now runs once after each update, when you use the buttons on this screen, and on the nightly run, rather than on every page load.
  • Sales that could not be posted are now reported as failures, with the reason. Until now the EP Ecommerce, Booking, Events and Subscriptions results counted a sale refused by your books (for example one dated inside a period you have closed) as “already posted”, so nothing looked wrong. The last-run results now show it under “failed”, with the order, booking, registration or subscription and the reason.
  • One Stripe transaction the books refuse no longer stops the Stripe feed. Before, a single refused transaction (for example one dated inside a closed period) meant the feed started again from the same place every night, for good. The feed now moves on, keeps that transaction on a waiting list, tries it again on every run, and posts it as soon as it can.
  • Stripe transactions waiting for an exchange rate are no longer forgotten. A transaction in another currency with no rate used to be listed once and then lost when the feed moved on. It now stays on the waiting list and is posted on the first run after you add a rate. The run results list everything still waiting, and why.
  • Event tickets marked as attended or as a no-show are now posted. A ticket sold through EP Events’ own checkout was only posted while it was still “confirmed”. If it was checked in, or marked as a no-show, before the nightly run, it was never recorded. Cancelled, refunded, pending, waitlist and store-credit registrations are still not posted, and free tickets are not listed as failures.
  • More subscription payments are recorded. The final paid period of a subscription that was cancelled or expired before the nightly run is now posted, and so is the first payment of a PayPal subscription, which was not being recorded at all. Nothing already posted is posted again. A renewal that came and went between two runs still cannot be recovered, because EP Ecommerce Subscriptions keeps only the current period.
  • The Stripe processing-fee sync reads every charge and posts one entry per day. It used to read only the first 100 charges, and a second run on the same day could drop fees. It now reads them all and posts each finished day once. Days an earlier version already posted are not posted again.
  • The fee sync does not run while the Stripe feed is switched on, because the feed records Stripe’s fees itself. The run results say so.
  • The Stripe feed now records the Stripe fee on payments your EP plugins record. The feed leaves a shop order, booking, event ticket or subscription renewal to its own plugin, and until now nothing recorded the fee Stripe took on it while the feed was on. The feed now posts that fee on its own, once per payment, dated like the payment. A fee in another currency waits for an exchange rate, and one dated in a closed period waits on the same list as other held items. Days an earlier version’s fee sync already covered are not posted again.
  • The Stripe fee sync works again. It reads your Stripe secret key from EP Ecommerce Stripe to fetch the fees Stripe charged you. Since EP Ecommerce Stripe began storing that key encrypted, the sync found an empty key and quietly did nothing, so no Stripe fees reached your books. It now reads the key correctly.
  • Nothing else changes.
  • Sales in other currencies are no longer booked at the wrong value. A sale charged in a currency other than your book’s was recorded as if it were in your book’s currency. On a pound book, a $100 order became £100 and a ¥5,000 event ticket became £5,000. Each sale is now recorded in the currency the customer was charged in and converted at an exchange rate you give.
  • New “Exchange rates” setting. Under “Sales in other currencies” in the settings, enter one currency per line, for example USD 0.79, meaning 1 US dollar is 0.79 in your book’s currency.
  • A sale with no rate waits instead of being booked wrongly. It is listed as needing a rate in the last-run results, and the next run posts it once you add one.
  • Each sale keeps the rate it was posted at. A refund reverses it at that same rate, so the two cancel out exactly.
  • The Stripe feed uses the same rates. Stripe transactions in another currency used to be skipped.
  • Sales in your book’s own currency are recorded exactly as before.
  • Sales already booked at the wrong value are not changed. If your shop, bookings or events charge in a currency other than your book’s, check earlier sales from those plugins in the Transactions screen.
  • Stripe payouts now follow EP Finance’s new “Main bank account” setting. When “Bank account (Stripe payouts land here)” is left on “Use the default”, payouts are recorded on the main bank account set in EP Finance. If none is set, they go to “Bank account (Stripe payouts)” as before. An account chosen here still wins.
  • The Stripe feed no longer books EP Booking, EP Events and subscription payments a second time. Those payments are already posted by their own bridges. Until now the feed only recognised EP Ecommerce orders, so with the feed switched on every booking, own-checkout event ticket and subscription renewal appeared twice. The feed now leaves those payments, and their refunds, to their own bridges, and lists them in the run results as “booked by” that plugin.
  • Refunds of subscription renewals are still posted by the feed, because no other bridge records them.
  • The Stripe feed no longer skips older transactions on a busy account. When there are more transactions to read than one run can handle, the feed now remembers exactly where it stopped and carries on from there next time, until everything has been read. Before, anything beyond the newest 2,000 in a run was never read, and nothing said so.
  • Each run can now read up to 10,000 transactions, and saves its progress after every 100, so a run cut short by the server loses almost nothing.
  • Transactions an earlier version already skipped are not recovered automatically. Before 0.3.4 the feed could only be switched on over the API, so few sites will have any.
  • The switches on the Finance Sources settings page now appear and work. Until now the “Sources” section showed a heading with nothing under it. The bridges could not be switched off, and the Stripe feed could not be switched on.
  • Each bridge now has a “Pause this bridge” box. EP Ecommerce, Subscriptions, Booking, Events and Instructor pay all keep posting to your books unless you tick their box. Untick it to start again. Pausing stops new postings only. Nothing already in your books is removed.
  • The Stripe processing-fee sync and the Stripe feed each have a “Switch on” box. Both stay off until you tick it.
  • Nothing changes when you upgrade. Every bridge that was posting keeps posting, and both Stripe options stay off, until you change a box and save.
  • A paused bridge now really stops. The nightly run and the “Run all” button skip it and show it as “paused” in the results. Before, the EP Ecommerce backfill ran every night whatever its setting said.
  • Event tickets bought through the shop are no longer booked twice. A ticket sold through EP Ecommerce was posted once as a shop order and again as an event ticket, so ticket income was doubled. The shop order is now the only posting for those tickets. Tickets sold through EP Events’ own checkout are posted as before.
  • The first payment of a subscription is no longer booked twice. It was posted once as a shop order and again as the subscription’s first month. It is now posted once, as the subscription’s first month. A refund of that first payment reverses that posting.
  • A partial refund no longer wipes out the whole sale. When only part of an event ticket was refunded, the whole sale used to be reversed. The sale now stays booked, and the registration is listed in the last-run results under “partial refunds to enter by hand” so you can record the refunded part yourself.
  • Doubled postings already in your books are not removed. This release stops new doubles. Earlier ones, for example an epecom-order-… and an epevent-… posting for the same ticket, need to be deleted by hand from the Transactions screen.
  • The download no longer includes an internal notes file. Earlier versions carried a CLAUDE.md file of developer notes in the plugin folder. Neither the plugin nor PageMotor ever read it, so nothing about how the plugin works changes. If an earlier version left ep-finance-sources/CLAUDE.md on your site, it is harmless and safe to delete.
  • Fixes a doubled cache-busting tag on its admin script. On PageMotor 0.11 and later the page asked for the file with two version tags on the end of its address (?v=…?v=…), because the core had started adding its own tag and the plugin was still adding one too. The file loaded correctly, so nothing was visibly broken; the address was just malformed and every cache saw a longer key than it needed. The plugin now leaves the tag to the core on 0.11 and later, and still adds its own on older cores, where nothing else would.
  • No change to what that script does.

Released 17 September 2026.

  • Money that never went through an EP plugin now reaches the book. A Stripe invoice paid by a client, a payment link, a charge made from the Stripe Dashboard, and every payout to your bank used to be invisible to EP Finance, because every source here started from an EP plugin’s own record. The new Stripe feed reads your Stripe balance and posts each movement as its own entry: payments, refunds, payouts and Stripe’s own fees.
  • Payment fees are split per payment, not swept in bulk. Each Stripe payment posts the gross to sales, the fee to payment processing and the net to the Stripe balance, from Stripe’s own figures for that payment.
  • Payouts move money from the Stripe balance to a bank account the plugin creates for you (“Bank account (Stripe payouts)”), or one you already keep, so the Stripe balance in the book tracks the one in your Dashboard.
  • A preview button shows what would be posted before anything is. “Preview: Stripe feed” reads the balance and lists every transaction with what the feed would do with it; “Sync: Stripe feed” posts. The nightly sweep includes the feed once it is switched on.
  • Nothing is counted twice. A payment that EP Ecommerce already booked is recognised by its Stripe reference and skipped. Re-running a sync, or overlapping the last one, changes nothing.
  • Nothing is guessed. A transaction in a currency the book does not keep is skipped and listed for you unless a rate provider can supply that day’s rate. Disputes, adjustments and transfers are counted and reported by type for a human to post.
  • The Stripe key is yours to give, and stored encrypted. A restricted key with read access to Balance transactions is enough; the feed never writes to Stripe. Off until you switch it on.

Released 9 September 2026.

  • Instructor pay now reaches the book on its own. EP Instructors already worked out what each instructor is owed for every class taught, but that figure only ever left the plugin as a CSV somebody had to retype into the accounts. Approved and paid pay-lines are now posted for you, as a cost against the class they were earned on.
  • Each posting is dated to the class, not to the day it was processed. A class taught in August stays an August cost even if the pay-line is approved in September, so a profit and loss report, or a VAT period built on it, covers what actually happened in that period.
  • Money owed and money paid are kept apart, on purpose. A pay-line marked paid tells us the studio considers it settled. It does not tell us which bank account paid it, on what date, or whether one payment covered five classes. So the cost is recorded and the amount owed is left standing, to be cleared against the real bank line when it comes in through EP Finance Importer. Your bank statement stays the single source of truth for money leaving, which is also what stops the same wage being counted twice.
  • Nothing is ever posted twice. Re-running a sweep, or running a backfill over a period already done, changes nothing. Pay-lines still awaiting approval are never posted.
  • If an approved amount later changes, you are told rather than quietly corrected. The sweep reports the pay-line, the figure in the book, and the figure now, and leaves the book alone.
  • New setting to turn the bridge off, two new account mapping overrides if you already keep your own chart of accounts, and a “Sweep: Instructor pay” button alongside the existing ones.
  • Nothing changes for the existing EP Ecommerce, Subscriptions, Booking or Events bridges.