Odoo Integration
Sync Odoo invoices and receipts with Payments Central, and optionally use the redirect payment flow for Odoo's online payment portal.
Two integration modes
Choose the mode that fits your setup:
Mode A — Payment provider: use Payments Central as an Odoo payment acquirer for online invoice payments (redirect flow).
Mode B — API sync: pull confirmed Payments Central transactions into Odoo via the REST API for bookkeeping.
Mode A — Payment provider: use Payments Central as an Odoo payment acquirer for online invoice payments (redirect flow).
Mode B — API sync: pull confirmed Payments Central transactions into Odoo via the REST API for bookkeeping.
Requirements
- Odoo 16 or 17 (Community or Enterprise)
- Python 3.10+
- A Payments Central account with an API key
- Odoo hosted on HTTPS (required for webhooks)
Mode A — Payment provider (redirect flow)
Install the Odoo module
- Download the
payment_payments_centralmodule from core.payments-central.com/plugins/odoo - Copy it to your Odoo
addonsdirectory - In Odoo go to Apps → Update Apps List
- Search for Payments Central and click Install
Configure the payment provider
- Go to Invoicing / Accounting → Configuration → Payment Providers
- Find Payments Central and click Activate
- In Credentials, paste your API key
- Set State to Test (uses sandbox) or Enabled (production)
- Save
Configure webhooks
- Copy your Odoo webhook URL:
https://yourodoo.com/payment/payments_central/webhook - In Payments Central dashboard go to Settings → Webhooks → Add endpoint
- Paste the URL and subscribe to
transaction.captured,transaction.failed - Copy the webhook secret into the Odoo provider settings
Test the payment flow
- Create a customer invoice in Odoo with state Posted
- Open the invoice and click Send & Print → Send by Email — the email contains a payment link
- Or use the Pay Now button on the customer portal
- The customer is redirected to Payments Central checkout
- After payment, Odoo automatically marks the invoice as Paid via the webhook
Mode B — API sync (bookkeeping)
Use this mode to pull transactions from Payments Central into Odoo as journal entries or payments — useful for reconciling your books when you use Payments Central for external checkouts.
Fetch recent transactions
import os, requests
from datetime import datetime, timedelta
api_key = os.environ['PC_API_KEY']
base_url = 'https://api.payments-central.com'
# Fetch captured transactions from the last 24 hours
resp = requests.get(
f'{base_url}/api/v1/transactions',
headers={'Authorization': f'Bearer {api_key}'},
params={
'status': 'captured',
'page': 1,
'limit': 100,
},
)
resp.raise_for_status()
transactions = resp.json()['data']
for txn in transactions:
print(f"{txn['id']} {txn['amount']/100:.2f} {txn['currency']} ref={txn['merchant_ref']}")
Sync transactions to Odoo via XML-RPC
import xmlrpc.client
odoo_url = 'https://yourodoo.com'
db = 'your_db'
username = 'admin'
password = os.environ['ODOO_API_KEY']
common = xmlrpc.client.ServerProxy(f'{odoo_url}/xmlrpc/2/common')
uid = common.authenticate(db, username, password, {})
models = xmlrpc.client.ServerProxy(f'{odoo_url}/xmlrpc/2/object')
for txn in transactions:
# Register payment on matching invoice
invoice_ids = models.execute_kw(
db, uid, password,
'account.move', 'search',
[[['ref', '=', txn['merchant_ref']], ['state', '=', 'posted']]],
)
if invoice_ids:
# Record payment
models.execute_kw(
db, uid, password,
'account.payment', 'create',
[{
'payment_type': 'inbound',
'partner_type': 'customer',
'amount': txn['amount'] / 100,
'currency_id': models.execute_kw(
db, uid, password, 'res.currency', 'search',
[[['name', '=', txn['currency']]]]
)[0],
'memo': f"Payments Central {txn['id']}",
'journal_id': 1, # your payment journal ID
}],
)
print(f"Synced {txn['id']} → invoice {invoice_ids[0]}")
Ledger data
Payments Central maintains a double-entry ledger of all transactions. You can pull trial balance data to cross-reference with Odoo:
resp = requests.get(
f'{base_url}/v1/ledger/trial-balance',
headers={'Authorization': f'Bearer {api_key}'},
params={'as_of_date': '2026-05-12'},
)
trial_balance = resp.json()
print(f"Balanced: {trial_balance['is_balanced']}")
for account in trial_balance['accounts']:
print(f" {account['code']} {account['name']}: {account['balance']/100:.2f}")
Scheduled sync
For automated reconciliation, schedule the sync script as an Odoo scheduled action:
- Go to Settings → Technical → Scheduled Actions
- Create a new action with Python code calling your sync logic
- Set it to run daily (or on whatever frequency your business needs)
Use idempotency keys for re-runs
When creating Odoo payments from Payments Central transactions, store the transaction ID
(
txn_ prefix) in the payment's memo field and check for duplicates
before creating to ensure your sync is idempotent.
Troubleshooting
| Issue | Solution |
|---|---|
| Invoices not marked as paid after payment | Verify webhook is configured and the signing secret matches |
401 Unauthorized from API |
Check the API key is correct and not expired |
| Currency mismatch errors in Odoo | Ensure Odoo has the currency enabled: Accounting → Configuration → Currencies |
| Payment provider not visible in Odoo portal | Check the provider is set to Enabled (not Test) in production |