AI app payments not working after the customer pays.

A customer pays and the account stays locked, or a subscription renews, fails or is cancelled and the app does not notice. In the apps we see, these faults usually sit between the payment provider and your app, where you can find them without reading code. This page covers test and live mode, webhooks, where the unlock should happen and the paths a demo skips.

What a broken payment flow looks like

The checkout page is the part of payments you tested, and it usually works. Money moving is the start of a longer chain. The provider has to tell your app the charge went through. Your app has to trust that message, find the right account, record the purchase and change what the customer can do. A break at any link looks the same from outside: the customer paid and got nothing.

Before changing anything, make one purchase and follow it. Keep three views open: the payment provider's dashboard, your app's database or admin screen, and the app itself signed in as the buyer. After the purchase, look for the payment in the first, a record of it in the second and the unlocked feature in the third. The first view where the purchase is missing tells you which row of the table applies.

Where the purchase got lost

What you see
Test purchases worked, and real cards are refused or no real payments appear
Usual cause
The live site still uses test keys, or live mode was never fully set up
Where to look
Which mode the provider dashboard is showing, and which keys the live site holds
What you see
The provider shows the payment and your app has no record of it
Usual cause
The provider's notification never reached your app, or your app rejected it
Where to look
The provider's list of notifications sent, with the address and the reply for each
What you see
Your app has a record of the payment and the account is still locked
Usual cause
The purchase was stored without being tied to the right user, or the screen reads a different field
Where to look
The purchase record: which account it names and what status it holds
What you see
The account unlocks, and it also unlocks without paying
Usual cause
The browser grants access when the checkout returns, with no confirmation from the provider
Where to look
Open the success page address directly in a signed-in account that has not paid
What you see
A cancelled, refunded or unpaid subscriber keeps access, or a paying one loses it
Usual cause
Only the first purchase was ever handled
Where to look
Run each later event in test mode and compare the account before and after

Test mode and live mode are two separate setups

Payment providers commonly give you two modes. Test mode accepts made-up card numbers and moves no money. Live mode charges real cards. Each mode has its own keys, its own products and prices, its own customers and its own notification settings. Work done in one is not carried over to the other, so an app built entirely in test mode arrives at launch with live mode empty.

Go through live mode item by item. Confirm that the provider has finished verifying your business and will accept real charges. Check that your products and prices exist in live mode and that the app refers to the live versions of them. Check that the live site holds live keys, and that the preview holds test keys so your own experiments never charge anyone. Then register the notification address again in live mode. In the apps we see, that last step is the one most often left out.

Finish with one real purchase at your lowest price, on your own card, and refund it afterwards. A pass in test mode tells you the code can work. A real purchase tells you the live setup is complete.

The payment succeeded and your app never heard

When a charge succeeds, the provider sends a message to an address on your app saying what happened. That message is usually called a webhook. Your app is supposed to receive it, confirm that it really came from the provider, and then record the purchase. The customer's browser plays no part in this, so the message still arrives when the customer closes the tab the moment they pay.

Providers keep a list of every webhook they tried to send, with the address it went to and the reply it got. Open that list after your test purchase. An empty list means no address is registered in that mode. An address that belongs to a preview means it was never updated at launch. A reply that reports an error means the message arrived and your app refused or mishandled it, commonly because the secret used to verify the sender is missing from the live settings or belongs to the other mode.

Two more things are worth checking while you have the list open. Providers often send a webhook again when they get no clear reply, so your app should cope with seeing the same message twice without granting two purchases. The list also shows which kinds of event your app has asked to receive. If the first payment is the only kind on it, renewals and cancellations are going unheard.

Paid, charged and still locked out

Where the unlock happens: the browser or the server

After checkout the provider sends the customer back to a page on your app, often called a success page. A common shortcut is to unlock the account when that page loads. It works in a demo, and it fails in two directions. A customer whose connection drops before the page loads has paid and stays locked. And anyone who learns the success page's address can open it and be unlocked without paying.

You can test both yourself. Sign in with an account that has never paid, then type the success page's address into the browser. If paid features appear, the unlock is happening in the browser. For the other direction, pay in test mode and close the tab before you are sent back, then sign in again and see whether the purchase registered.

The safe arrangement is that only your server changes what an account is entitled to, and it does so after the provider has confirmed the payment through a verified webhook. The success page then reads the account's status and shows it. Keys follow the same rule. The secret key for your payment account belongs in server settings. It should never appear in code the browser downloads, and never in a message to someone helping you. Give a helper access by inviting them through the provider's own team settings.

Renewals, failed cards, cancellations, refunds and plan changes

A first purchase is one event. A subscription produces many more over its life, and each should change something in your app. A renewal extends access. A card that fails at renewal should start a warning or a grace period. A cancellation should end access on the date the customer has paid up to. A refund or a disputed charge should show on the account. An upgrade or downgrade should change the plan the app displays and the limits it applies.

In the apps we see, the first purchase is handled and several of the others are missing, because nobody asked for them and a demo never reaches the second month. Providers commonly let you trigger these events in test mode without waiting for time to pass. Run each one against a test account. Before and after each, write down what the account's record says and what the user can do. Any event that changes nothing in your app is a gap.

Settle the business rule before you ask for the code. How long does someone keep access after a failed card? Does cancelling take effect at once or at the end of the paid period? What happens to a customer's data when they downgrade? These are your decisions, and an AI tool given no answer will choose one without telling you.

What to set up yourself and when to get help

Keys in the wrong mode, missing live products and an unregistered webhook address are setup tasks you can do from the provider's dashboard and your hosting settings. Make the change, repeat the one-purchase test with all three views open, and refund the charge.

Get help when the app unlocks from the browser, when webhooks arrive and fail, when later subscription events are unhandled, or when customers have already paid and you cannot say who is owed what. Mistakes here cost your customers money or give your product away, and they are hard to see from the screens. Describe the fault and share dashboard access by invitation. Do not paste secret keys, webhook secrets or card details into a contact form or a chat, with us or with anyone. Our Diagnostic is a fixed-price written plan of what blocks launch and what to repair first, credited to the build if you go ahead with us. Your repo and accounts stay yours, the payment account included.

Before you take a real payment

Have each of these confirmed in writing. They are what you would want to know before a stranger's card goes through your checkout.

  1. Which mode each environment uses: live keys on the live site, test keys on the preview.
  2. The products and prices that exist in live mode, and that the app points at them.
  3. The webhook address registered in live mode, and the reply it gave to the last message.
  4. That opening the success page without paying unlocks nothing.
  5. What the app does on renewal, failed card, cancellation, refund and plan change.
  6. One real purchase traced from the provider to the purchase record to the unlocked account, then refunded.
How we can help

We can trace where your payments break.

Book a free consultation and describe one purchase that went wrong. We will tell you whether it sounds like a setup step you can finish yourself. If we do the work, we move the unlock to the server, handle the subscription events your product needs, and test each one in your own accounts before real customers reach it.

Book a free consultation

On the project call, we’ll discuss the problem, your existing tools and what TDAT should take off your hands. Then we can define the scope and next steps.

Or call (919) 289-1231

Questions before we start

Why did the payment go through but the account did not unlock?

Commonly because your app never received or accepted the provider's notification that the charge succeeded. Check the provider's list of webhooks sent in live mode. A missing address, a preview address and an error reply each point to a different fix described on this page.

It worked with test cards. Why does it fail with real ones?

Test mode and live mode are separate. Keys, products, prices and webhook settings created in test mode do not exist in live mode until you set them up there. Go through the live setup item by item and finish with one small real purchase.

What is a webhook, in plain terms?

It is a message the payment provider sends to your app when something happens, such as a payment, a renewal or a cancellation. Your app needs an address to receive it and a secret to confirm who sent it. Without that message, your app knows only what the customer's browser tells it.

Is it safe to unlock the account on the success page?

No. The customer's browser can be closed too early, or pointed at that page without paying. Access should be granted by your server after the provider confirms the payment. The success page can then display whatever status the server has recorded.

What do you need from me to look at a payment problem?

A description of one failed purchase with its date and time, an invitation to view the payment provider's dashboard, and access to the code and the database. Please do not send keys or card details in a message. We settle the scope of access with you before we look.