Skip to main content
Question

How to test purchases with Paddle


Forum|alt.badge.img
  • New Member
  • 4 replies

Hi, 
I’d like to use Paddle and RevenueCat to offer subscriptions for my SaaS startup :)

As far as I understand, the essential bit of information that connects Paddle webhooks to the right RevenueCat customer is sending the user_id in the metadata. So the flow is:

  • get user_id from authentication provider
  • user wants to access a paid service? Check if user_id has the right entitlements via the RevenueCat web sdk
  • user wants to make a purchase? Start the Paddle checkout flow, attach user_id in the right field of the metadata

How do I test this? I’m thinking the correct way is probably to connect a Paddle Sandbox account to RevenueCat and then run various simulations against a little sandbox website (which has authentication and a handful of mock routes). But I haven’t found documentation on this scenario.

Does RevenueCat realize that products are purchased via a sandbox account? I’d like to test this thoroughly, but not have to pay for sandbox purchases.

What’s the correct way to test Paddle+RevenueCat?

 

This post has been closed for comments

7 replies

Forum|alt.badge.img
  • Author
  • New Member
  • 4 replies
  • July 23, 2025

I’ve done some preliminary testing:

  • Set up a new RevenueCat project, called “My Company (Testing)”
  • Set up a Paddle Sandbox with products that mimic what I want to sell, created an API key
  • Added this API key to the “MyComp (Testing)” project, connected Paddle, imported products, defined entitlements, connected them
  • Went to the Paddle Sandbox and ran a simulation

The simulation failed. After a lot of digging I noticed that the webhook secret that RevenueCat had stored was different from the one that Paddle created. Very confusing, the UI showed me some green text about how Paddle was correctly configured. It seems like RevenueCat set some webhook secret that is not the one communicated by Paddle. I then tried to overwrite this webhook secret. That was difficult, because the RevenueCat UI really didn’t want to save the changes. Multiple times it reset itself to the old (wrong) webhook secret. But ultimately I got the correct webhook secret to stick.

Then I ran the simulation again, and I get this:

 

Paddle is a bit verbose in terms of webhooks. A single “checkout” simulation runs through a long list of webhooks like “transaction.created”, “customer.created”, “customer.created”, … “transaction.paid”, …, “subscription.activated”, 

All of them succeed, except one: “transaction.completed”

Back in the RevenueCat dashboard, I don’t see any new customers or subscription revenue.

Is this an artifact of using the sandbox mode? If yes, can I somehow connect the Paddle sandbox to RevenueCat? If not, what do I need to do to correctly connect Paddle and RevenueCat? I went through the tutorial carefully, and indeed most of the webhooks seem to be processed with a success HTTP code.

 


Forum|alt.badge.img
  • Author
  • New Member
  • 4 replies
  • July 24, 2025

I’d like to add another small follow-up :)

Just to sanity check, I do think I’ve connected Paddle and RevenueCat correctly. The RevenueCat dashboard tells me:

 

Well and when I run a simulation on Paddle, most of the webhooks (except for that transaction.completed one) are processed with a success status code.

 

I decided to try how this would look if I don’t use a simulation, but make a test purchase myself. So I added a hosted checkout to my Paddle project (via the Paddle website), went there and made a purchase (with a test credit card as instructed by Paddle). Paddle tells me this is successful. In fact, in the Paddle sandbox I now see a new customer, created exactly when I made the test purchase and with the email I used.

But over on the RevenueCat side, no information seems to arrive. I don’t see any customers, purchases, etc.


chris_perriam
RevenueCat Staff
Forum|alt.badge.img+6
  • RevenueCat Staff
  • 104 replies
  • July 30, 2025

Hi ​@lhk , excellent work detailing what you’ve tried so far. Are you still experiencing issues seeing your paddle transactions and customers in RevenueCat?

If so, could you please confirm that you’ve enabled the Sandbox data toggle on https://app.revenuecat.com/overview ?

 


Forum|alt.badge.img
  • Author
  • New Member
  • 4 replies
  • July 31, 2025

Hi ​@chris_perriam , thanks for getting back to me on this :)

Yes, the sandbox data toggle is set. I’ve continued to play around with this. Sandbox checkouts with Paddle are successful but I couldn’t really see what is happening with that data on the RevenueCat side. So what I did next was to set up a small Firebase project, install the RevenueCat Firebase extension and then create a small mock website: Authentication with Firebase, then a Dashboard that shows the current claims and a button that prompts a Paddle Checkout to open (initialized with paddle js). I’m also listening to the entitlements collection in Firestore and am reloading the Dashboard if I notice a change.

To my surprise this worked like a charm right away. Purchases from Paddle are synchronized via RevenueCat to Firebase in a matter of seconds. 

However, the new customers didn’t show up on RevenueCat, neither as “Active Subscription” nor “Sandbox” (just to be super clear, yes I have that sandbox toggle set to true, it’s a different setting than just looking at sandbox customers:
 

 

Now, in the screenshot you can see that there are transactions :) In fact, they do show up on RevenueCat but with about a day of delay!

So ultimately what works: Paddle purchases are synchronized very quickly to Firebase, the purchases are correctly recognized as sandbox purchases by RevenueCat. The data synchronization to the RevenueCat dashboard is confusingly slow.

The Paddle simulations still don’t work. In exactly this project, if I run a simulation all the webhooks except “transaction.completed” are successful. I have made sure that the webhook that RevenueCat configured in Paddle is selected for both Platform and Simulation events. I’ve edited the simulation payload to contain the app_user_id in custom metadata. I’ve sanity checked the shared secret etc. I don’t see what I’m missing - and all the other webhooks seem to be processed correctly, so the connection is there.

 


chris_perriam
RevenueCat Staff
Forum|alt.badge.img+6
  • RevenueCat Staff
  • 104 replies
  • August 1, 2025

Hi ​@lhk, thanks for the additional info! I’ve been reviewing the sandbox events in your account and I’ve been unable to find any which were processed later than their purchase time. Each one appears to have an event_timestamp_ms value very close to the purchased_at_ms value.

It would be great if you could provide a sample event ID or App User ID which experienced a delayed event. We’d then be able to take a closer look at how it was processed. Feel free to reach out via a support ticket if you’d rather not share any information publicly.


Forum|alt.badge.img
  • Author
  • New Member
  • 4 replies
  • August 4, 2025

Hi ​@chris_perriam 
thank you for being so responsive and helpful. I’m currently testing/prototyping my way through the various Paddle/RevenueCat interactions. Right now I have a few too many loose ends and would rather double down and try to make it all work. Once I think I’ve arrived at the final setup, I’ll test it and reach out if something doesn’t seem to work properly.

That being said, there is something that I already would like to raise with you (&the RevenueCat team):
I’d like to offer different tiers of a subscription, let’s say basic and premium. A customer must have only one subscription at a time, they should be allowed to upgrade (with some form of proration) and downgrade (at the end of the current billing period). That should be the most standard scenario I think :)
The Paddle JS SDK makes the first purchase very simple, I can just open a checkout for the subscription the user wants to buy. It does not seem possible to use those Paddle JS checkout flows for the up- and downgrade scenario. In fact, I have to be very careful never to open a checkout again, since there are no guardrails against selling the same subscription to a user twice ! 
Hm, ok, that’s not on you. So how do I up-/downgrade a subscription? It works via the Paddle API. I have to first preview a change and then apply a patch. For that it’s important to know:

  • the subscription ID
  • the customer ID

Your Firebase Extension allows me to sync RevenueCat data to Firestore. This data contains (I’m only listing a subset of keys):
 

1{
2 "subscriptions":{
3 "<paddle_product_id>":{
4 "store": "paddle",
5 "store_transaction_id": "<transaction_id>"
6 }
7 }
8}

I then need to look up the customer ID and the subscription ID from the transaction ID via the Paddle API. It would be convenient to have those in Firestore as well, I’m sure they’re sent along with the webhooks, no?


chris_perriam
RevenueCat Staff
Forum|alt.badge.img+6
  • RevenueCat Staff
  • 104 replies
  • August 8, 2025

@lhk that’s the correct understanding of the Paddle subscription change action (docs here).

As you mention, RevenueCat provides the Transaction ID and the Subscription ID can be derived from it.

The Subscription ID isn’t present in our internal Paddle events and subsequently isn't present in webhook events.

Let me know if there’s anything else I can clarify, happy to help!


Cookie policy

We use cookies to enhance and personalize your experience. If you accept you agree to our full cookie policy. Learn more about our cookies.

 
Cookie settings