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.

Requirements

Mode A — Payment provider (redirect flow)

Install the Odoo module

  1. Download the payment_payments_central module from core.payments-central.com/plugins/odoo
  2. Copy it to your Odoo addons directory
  3. In Odoo go to Apps → Update Apps List
  4. Search for Payments Central and click Install

Configure the payment provider

  1. Go to Invoicing / Accounting → Configuration → Payment Providers
  2. Find Payments Central and click Activate
  3. In Credentials, paste your API key
  4. Set State to Test (uses sandbox) or Enabled (production)
  5. Save

Configure webhooks

  1. Copy your Odoo webhook URL: https://yourodoo.com/payment/payments_central/webhook
  2. In Payments Central dashboard go to Settings → Webhooks → Add endpoint
  3. Paste the URL and subscribe to transaction.captured, transaction.failed
  4. Copy the webhook secret into the Odoo provider settings

Test the payment flow

  1. Create a customer invoice in Odoo with state Posted
  2. Open the invoice and click Send & Print → Send by Email — the email contains a payment link
  3. Or use the Pay Now button on the customer portal
  4. The customer is redirected to Payments Central checkout
  5. 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:

  1. Go to Settings → Technical → Scheduled Actions
  2. Create a new action with Python code calling your sync logic
  3. 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

IssueSolution
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