PayPal to Postgres integration for a queryable transaction replica
The PayPal to Postgres integration from Adapters syncs transactions, gross and fee amounts, refunds, and payer details from the PayPal Transaction Search API into your own Postgres tables on an incremental schedule, so finance and product reporting query settlement data with plain SQL instead of paging PayPal live. Field mapping is no-code, so try it against sample records in the live demo.
No credit card required.
Field mapping auto-plugged · tap a port to rewire
Plug a source port into
Transform on this cable
JSON in
JSON out
5 sample records ready
Last updated September 2026
What running PayPal to Postgres by hand costs you
- PayPal reports cannot join to your orders, subscriptions, or accounting tables, so gross-to-net and chargeback questions get answered by hand from CSV downloads.
- The Transaction Search API only returns a bounded date window per call and paginates by page, so a naive pull silently drops transactions outside the window.
- Gross, fee, and net sit in separate amount objects, and a one-time export makes reconciliation to the payout total guesswork.
The field mapping, out of the box
These cables are pre-wired when you pick the pair. Rewire any of them, or add your own, in the same visual data mapping tool you use for every adapter.
Input / PAYPAL
Output / POSTGRES
Transforms included
Incremental loads step the Transaction Search API in overlapping date windows so nothing between windows is skipped; gross, fee, and net land as separate NUMERIC(19,4) columns with a currency code so gross-to-net ties out to the payout, payer email flattens to a joinable column, the ISO 8601 timestamps parse to TIMESTAMPTZ in UTC, and writes upsert with ON CONFLICT on the PayPal transaction id so a re-pulled window never double-counts revenue.
PayPal to Postgres in depth
Two PayPal facts decide this route, and neither is a rate limit. The Transaction Search API caps a single query at 31 days and 10,000 records, and PayPal does not publish a rate limiting policy at all. Read from PayPal developer documentation on 29 August 2026.
PayPal publishes no rate limit numbers, deliberately
Every other payment platform documents a throughput ceiling. PayPal does not. Its rate limiting page states plainly that PayPal does not publish a rate limiting policy and may temporarily rate limit traffic that appears abusive. So any article quoting you a PayPal requests-per-second figure invented it. The two defenses PayPal does document are concrete: use webhooks or IPN rather than polling, and cache the OAuth token instead of minting one per request.
The 31 day window is the real ceiling
A single Transaction Search call accepts a maximum date range of 31 days. Any backfill longer than a month has to be chunked into windows by the caller, and the windows should overlap slightly so a transaction landing exactly on a boundary is not skipped. This is the constraint that shapes the whole extract, and it is why a naive from-the-beginning-of-time pull returns an error rather than history.
10,000 records per range, and you cannot page past it
Within an accepted date range the API returns at most 10,000 records, paged at up to 500 per page with a default of 100. PayPal's documented remedy when an account exceeds it is to shorten the date range, because there is no page you can request that reaches record 10,001. A busy merchant hitting this on a 31 day window gets a partial month with no error, so window size must be driven by transaction volume rather than by the calendar.
Executed transactions take up to three hours to appear
PayPal states that it takes a maximum of three hours for an executed transaction to appear in the list transactions call. A nightly job whose window ends at the moment it runs will therefore miss the last three hours of activity, every single night, and the gap compounds. End each window at least three hours in the past, or re-read the trailing window on the next run and upsert.
History stops at three years
The call lists transactions for the previous three years only. If the reason for building this replica is multi-year finance reporting, the Postgres table becomes the system of record for anything older, because PayPal will not serve it again. That makes the first backfill more important than it looks: get it complete before the oldest month you care about rolls out of the window.
Amounts are decimal strings, not minor units
PayPal reports money as a string with exactly two digits after the decimal point plus a separate currency_code. This is the opposite of Stripe, which uses integer minor units. A pipeline that shares a divide-by-100 helper across both processors will book PayPal revenue at one hundredth of its value. Land gross, fee and net as separate NUMERIC(19,4) columns and never the PostgreSQL MONEY type, whose display depends on the server lc_monetary setting.
Enabling the scope takes up to nine hours to propagate
Transaction Search is a permission you switch on for a REST app. PayPal warns that if the app was already used for other calls, it can take up to nine hours before a newly issued access token carries the new permission, and until then the API returns permission denied. Teams routinely conclude the integration is broken and rebuild it during that window. The scope is https://uri.paypal.com/services/reporting/search/read.
Prove one payout before scheduling it
Take a single real payout and reconcile gross, fees and refunds against the rows landed in Postgres. Store timestamps as TIMESTAMPTZ so the incremental watermark does not drift at a clock change, and upsert on the transaction id so an overlapping window never double counts. Wider context on Postgres ETL tools and data migration tools.
How it goes live
Three steps, minutes end to end, covered by flat data integration pricing from $49 a month.
STEP 01
Pick the pair
Connect PayPal and Postgres with scoped credentials. About a minute each.
STEP 02
Confirm the mapping
The cables above are pre-wired. Adjust any field, preview the transform on sample records, done.
STEP 03
Schedule the sync
Hourly down to every minute, with retries, alerting, and a full log on every run.
Prefer to understand the moving parts first? Our long-form guide to replicating PayPal transactions to Postgres covers the field-by-field detail, the failure cases, and what changes at volume.
PayPal to Postgres sync: common questions
How do I sync PayPal transactions to Postgres?
Connect the PayPal account, pull transactions and settlement data through the reporting API, map gross, fee and net onto separate Postgres columns, and schedule it. Adapters walks the date windows the API requires and upserts on the transaction id, so a backfill and a nightly run land in the same table without duplicates.
What Postgres type should PayPal amounts use?
NUMERIC(19,4) for gross, fee and net, each in its own column, with the currency code stored separately. Never the PostgreSQL MONEY type, which is locale dependent. Keeping the three amounts apart rather than netting them at load time means a later question about fee rates is a query rather than a re-load.
Why does PayPal in Postgres disagree with the PayPal dashboard?
Because the dashboard figure and the loaded figure are usually different amounts. PayPal exposes gross, fee, net and, for converted transactions, both original and settled amounts. Loading one of them and comparing against another produces a difference that looks like data loss and is actually a definition mismatch. Load them all and define the metric in SQL.
How do I reconcile PayPal payouts against transactions in Postgres?
Join on the payout batch or settlement identifier rather than by date. A payout covers a window that does not line up with a calendar day, and refunds and disputes land inside it, so a date join always leaves a residual. With the batch id as the key, the difference between a payout and its transactions is explainable line by line.
How does the PayPal to Postgres sync work?
The PayPal to Postgres integration from Adapters syncs transactions, gross and fee amounts, refunds, and payer details from the PayPal Transaction Search API into your own Postgres tables on an incremental schedule, so finance and product reporting query settlement data with plain SQL instead of paging PayPal live. Field mapping is no-code, so try it against sample records in the live demo.
Is there a prebuilt PayPal connector for Postgres?
Yes. This PayPal to Postgres connector ships prebuilt: the field mapping is wired the moment you pick the pair, transforms are included, and you can try it against sample records in the live demo. No code or engineering sprint required.
How much does the PayPal Postgres integration cost?
Pricing is flat and monthly: Starter at $49, Growth at $149, Scale at $399. Every plan includes this pair, visual field mapping, and per-record logs. There are no per-task or per-row fees, so the bill stays the same as volume grows.
How often can Adapters sync PayPal to Postgres?
Hourly on Starter, every 5 minutes on Growth, and down to every minute on Scale. Failed records retry automatically with backoff, and alerting plus a full per-record log come standard on every run.
Do I need to write code to connect PayPal and Postgres?
No. Fields are auto-mapped the moment you pick the pair, and you can rewire any mapping visually before the first sync. Incremental loads step the Transaction Search API in overlapping date windows so nothing between windows is skipped; gross, fee, and net land as separate NUMERIC(19,4) columns with a currency code so gross-to-net ties out to the payout, payer email flattens to a joinable column, the ISO 8601 timestamps parse to TIMESTAMPTZ in UTC, and writes upsert with ON CONFLICT on the PayPal transaction id so a re-pulled window never double-counts revenue.
More pairs from the API connector library
Browse the full api connector library, or request a pair you do not see.
PayPal and Postgres, finally in agreement
Map the pair once and let it sync on schedule. Flat price from $49 a month, no per-task fees.
No credit card required.