One-time purchase charges showing "Active" before merchant is invoiced - how are others handling billing abuse?

Hi all,

We’ve run into a recurring issue with Shopify’s billing system that I’d love some community insight on.

Our app sells credits as one-time purchase charges. In most cases, merchants are invoiced and charged immediately upon purchase, which we assumed was the standard behavior. However, we’ve identified multiple cases where the charge is never actually invoiced, yet Shopify continues to report the one-time purchase as “Active” on our end.

This raises a question: shouldn’t a charge only be marked “Active” once it’s actually been invoiced/collected? Right now it feels like we can’t fully trust that status as a signal of payment, which means we’ve had to build manual monitoring to catch and block merchants who are exploiting this gap. Beyond the operational overhead, it’s a real risk to our business if left unchecked.

On top of that, we’ve seen similar abuse patterns with subscription billing cycles, which compounds the problem.

For those who’ve dealt with this before - how do you balance fraud prevention with merchant UX?

Would appreciate any insight into why Shopify’s billing status behaves this way, and how others have mitigated abuse without adding friction for legitimate merchants.

Thanks in advance!

Hi @Rokas_Va! For one-time charges, ACTIVE is a reliable signal that the merchant was charged. Per the AppPurchaseStatus docs, the merchant is charged immediately after approval and only then does the status move to ACTIVE. If the payment fails, the purchase stays PENDING. So an ACTIVE one-time charge shouldn’t map to an uncollected payment. An ApplicationCharge is invoiced immediately but only appears as an earning in your Partner Dashboard within about 7 days (reference), so a charge that’s ACTIVE but not yet in earnings is expected.

If you are seeing one-time charges that become ACTIVE and were never collected, that’s not documented behavior. The x-request-id header from one of the affected API responses is enough for us to trace it in our logs. Can you share that header for one or two examples?

With subscriptions, the first charge is collected on the billing cycle rather than at approval, so a merchant can approve, pull value, and cancel before collection. The way to handle that is to gate credit or token delivery on a confirmed active state via the APP_SUBSCRIPTIONS_UPDATE webhook rather than on approval alone, and to keep the credit ledger in your own backend.

Happy to take a closer look if you can share an x-request-id from one of the affected calls.

Hi, thanks for the reply. Where can I find those x-request-ids that you need? I have charge Ids handy, would they help?

You can find the x-request-id in the response headers you receive back when you make a call to Shopify via API.

They’re really useful as they allow us to pull logs for the specific request without having to filter for shop, app, timestamp etc so we do recommend logging them!

I’ll send you a DM to request more details!

Thanks for the details, I dug into the charges you shared. It turns out this is expected app billing behaviour rather than the discrepancy I flagged earlier, even though the active status makes it look like you’ve already been paid.

For one-time charges, active means the charge was approved and invoiced, not that Shopify has collected the funds. App charges aren’t billed on their own. They get added to the merchant’s regular Shopify invoice and collected alongside their subscription fees on the merchant’s billing cycle, so there’s a normal gap between a charge going active and the money actually being collected and paid out to you.

That’s what’s happening on the charges you listed. They’ve been invoiced, but the invoices they sit on haven’t been collected yet, and a few have already failed to collect. Since these charges only settle once the merchant pays the Shopify invoice they’re attached to, a merchant whose payment isn’t going through leaves the charges uncollected even though they show as active.

So active on a one-time charge is a reliable “invoiced” signal but not a “paid” one. Treat it as provisional and reconcile against what Shopify actually pays out, since you’re only paid once the merchant settles the invoice the charge sits on (reference). For higher-value credit top-ups it’s worth holding delivery, or building in a clawback, until the charge settles rather than releasing value the moment it flips to active.

Thanks for looking into it, but aren’t there like a threshold on merchants shops that if they get over it they get charged instantly?

In regards to checking if merchant has “paid” for that one time charge, is there a programatic way to check it?

Good question on the threshold - it does exist but it isn’t really in play here. There’s a per-plan billing threshold that makes Shopify issue a bill early once accumulated account activity (recurring app charges, third-party transaction fees, and other outstanding charges) crosses it, with plan-based defaults of Trial $60, Basic/Starter/Lite $200, Grow $480, Advanced $1,280, and Plus $4,000 USD. It only affects when a bill is issued though, not whether it gets paid, and your one-time credit charges don’t sit on that accumulated bill at all. Each one is invoiced on its own the moment it’s created, so it never waits on the threshold or the 30-day cycle. See billing cycles and thresholds.

That’s a correction I want to make to my previous post above - one-time charges aren’t added to the merchant’s regular subscription bill and collected alongside their subscription fees. Each gets its own invoice, and Shopify attempts to collect that invoice automatically. The gap you see is that automatic collection can fail or lag behind, for example a declined or capped payment method or a slow bank debit, so a charge can show ACTIVE and invoiced while its invoice never actually collects. That lines up with what I saw on the charges you shared, invoiced but either failing to collect or still pending.

On checking payment programmatically, there’s no collected or paid state in the Billing API. AppPurchaseStatus only has ACTIVE, PENDING, DECLINED, and EXPIRED, and ACTIVE just means approved and invoiced. The signal for actual collection lives in the Partner API. Query transactions filtered to the APP_ONE_TIME_SALE type and you get AppOneTimeSale records with grossAmount (what the merchant actually paid) and netAmount (what lands in your payout), tied to a payout. A transaction only appears there once the merchant has paid the invoice the charge sits on, so that’s the reconciliation source you want.

I hope this helps, and apologies again for the inaccuracy earlier!