Maksekeskus payment provider
Accept Estonian bank links and card payments via Maksekeskus / MakeCommerce inside Odoo's native payment framework.
disabled
— follow the setup steps below to enable it.
What this addon does
- Adds Maksekeskus as a redirect-flow payment provider in
Settings → Payment Providers. - Sends customers to Maksekeskus's hosted checkout (bank link or card) and receives them back signed.
- Verifies the
MACsignature on every callback before changing any transaction state. - Re-fetches the authoritative payment status from Maksekeskus's API as defense in depth — the customer's browser cannot lie about whether they paid.
Refunds, tokenisation and manual capture are out of scope for v1. The framework's feature flags are left off; add them only when needed.
How the payment flow works
- Customer clicks Pay on an invoice, order, or payment link.
- Odoo creates a
payment.transactionand callsPOST /v1/transactionson the Maksekeskus API. - Maksekeskus returns a hosted-checkout URL; the customer's browser is auto-submitted to it.
- The customer pays at the bank or with a card.
- Maksekeskus sends two messages: a browser return (
/payment/maksekeskus/return) and a server-to-server notification (/payment/maksekeskus/webhook). Both carryjson + mac. - Odoo verifies the MAC, re-fetches the transaction status from Maksekeskus, and updates the
payment.transactionstate (done,cancel,pending, …).
Setup — five steps
1. Get a Maksekeskus account
Sign up at merchant.maksekeskus.ee for production credentials, or use the shared sandbox credentials for development.
2. Copy three keys
From the merchant portal, copy:
Shop ID(UUID)Secret Key— signs MAC + HTTP Basic passwordPublishable Key— currently reserved for future use
3. Open the provider form
Go to Settings → Payment Providers → Maksekeskus .
Requires the Administration / Settings group.
4. Enter the credentials
Paste the three keys into the Maksekeskus credentials group. The Shop ID and Secret Key are required to enable the provider; the field group becomes visible only when the provider's code is maksekeskus.
5. Switch state and verify
Choose one:
- Test mode — uses
https://api.test.maksekeskus.ee. Safe to drive a few sandbox payments end-to-end. Use the shared test cards (e.g. Visa4505131234000011). - Enabled — uses
https://api.maksekeskus.ee. Real money. Only flip after a successful test-mode round-trip.
Before going live: set web.base.url (in ir.config_parameter) to the public HTTPS URL of this Odoo instance, otherwise the return and notification URLs sent to Maksekeskus will point at the wrong host.
Use case examples
A. Pay a single invoice
Open a confirmed customer invoice, click Send & Print with the portal link, or share the invoice's customer-portal URL. The portal's Pay button creates a transaction via the framework, redirects the customer to Maksekeskus, and lands them on /payment/confirmation when done.
B. Generate a one-off payment link
On any record that supports payment links (sale order, invoice, etc.), use Action → Generate Payment Link. The wizard produces a URL like /payment/pay?amount=…¤cy_id=…&partner_id=…&access_token=…. Share it with the customer; they click and pay.
C. Website checkout
With website_sale installed, Maksekeskus appears alongside other configured providers in the cart's Pay step. The customer picks Maksekeskus, gets redirected, pays, and lands on the order's confirmation page.
D. Subscription renewals (with OCA contract)
OCA's contract module generates invoices on a schedule; each invoice can be paid via Maksekeskus through the customer portal. Combine with Odoo's email reminder cron for an automated billing loop.
E. Refund a customer (full or partial)
Open the original payment.transaction in state done, click Refund, enter an amount (defaults to full). A refund-child transaction is created with a negative amount and a SETTLED state once the gateway confirms. Sandbox returns SETTLED synchronously; production typically settles on the next banking day. Status PART_REFUNDED on the parent transaction is informational — the framework tracks aggregate refunds via the child transactions.
F. Card-on-file recurring billing
Customers can save their card during a first payment: the Maksekeskus card iframe shows a Recurring consent checkbox; ticking it stores a token after the payment completes. Subsequent merchant-initiated charges use the saved token via a server-to-server POST /v1/transactions/{id}/payments — no customer redirect, no 3DS step. Combine with OCA contract for fully automated subscription billing.
Shipping+ (carrier integration)
If the merchant also uses Maksekeskus Shipping+, the addon ships a delivery.carrier integration covering rate quotes, label generation, and tracking links across Omniva, DPD, Venipak, Unisend and SmartPosti.
- Ask Maksekeskus support to activate Shipping+ on your shop (paid service: €1.99 / shipment with Maksekeskus rates, or €5/month + €0.05/shipment with merchant carrier contracts).
- In Odoo, open Inventory → Configuration → Shipping Methods and create a new method with Provider = Maksekeskus Shipping+.
- Link the new method to the same Maksekeskus payment provider record — it reuses the Shop ID + Secret Key and the test/live state.
- At checkout the cart fetches a rate via
POST /rates; at delivery confirmation the addon callsPOST /shipmentsto generate a label and tracking number, then shows the tracking link in the picking's chatter.
The shipping API lives at shipping[.test].makecommerce.net — a different host from the payment API. The shared sandbox shop does NOT have Shipping+ activated; first real-bytes validation happens after the merchant requests activation.
Test mode — shared sandbox credentials
Maksekeskus publishes shared test credentials at
makecommerce.net/test-environment.
Safe to paste into state=test on the provider form — they only work against api.test.maksekeskus.ee.
| Field | Value |
|---|---|
| Shop ID | f7741ab2-7445-45f9-9af4-0d0408ef1e4c |
| Secret Key | pfOsGD9o…IWAOcBeqt (full value on the makecommerce.net page) |
| Test Visa card | 4505131234000011 · 06/28 · CVC 123 |
| Test MasterCard | 5191631234000016 · 06/28 · CVC 123 |
| Decline test | Use either card with amount 99.99 EUR |
Troubleshooting
test vs enabled) does not match the environment those keys belong to. Sandbox keys only work against api.test.maksekeskus.ee; live keys only against api.maksekeskus.ee.
?trx=… query parameter. The addon's redirect template echoes query params as hidden inputs to avoid this. If you've customised the template, ensure those hidden inputs are preserved.
/payment/status cannot find the transaction in the session. Happens when a transaction was created via API / ORM scripting rather than the framework's payment form. Real customer journeys (Pay button on invoice / order / website checkout) set the session key correctly and land on /payment/confirmation with the right message.
2xx within 30 seconds. Confirm: (a) web.base.url points to a public HTTPS URL Maksekeskus can reach, (b) reverse proxy / firewall allows POST to /payment/maksekeskus/webhook with no CSRF check, (c) Odoo logs show the inbound POST. The browser return path covers most state transitions even when the webhook is slow.
Security model — in one paragraph
Every callback (return and webhook) is signed by Maksekeskus with
UPPERCASE(HEX(SHA-512(json + secret))). The addon verifies that MAC on the byte-for-byte raw JSON before any state mutation, with a constant-time comparison. If verification passes, the addon then re-fetches the authoritative transaction status from Maksekeskus's API over HTTPS+Basic auth — the customer's browser never decides the final state. Amount and currency are re-validated against the stored Odoo transaction; mismatches drive the transaction to error. csrf=False is required on the public callback routes (external caller cannot send an Odoo CSRF token) and is justified exclusively by these checks.