Skip to content

How to Connect 2Checkout (Verifone) to Odoo: Global Payment Integration

DeployMonkey Team · March 23, 2026 10 min read

Why Use 2Checkout with Odoo?

2Checkout, now part of Verifone, specializes in global digital commerce. It acts as a merchant of record, handling tax compliance, payment processing, and subscription management in over 200 countries. For SaaS companies and digital product sellers using Odoo, 2Checkout simplifies international sales by handling VAT/GST collection, currency conversion, and local payment methods.

The key advantage over Stripe or PayPal is 2Checkout's merchant-of-record model. They become the legal seller, handling tax remittance in every jurisdiction. You receive net revenue without worrying about tax compliance in 200 countries.

Integration Approaches

MethodComplexityBest For
2Checkout IPN (webhooks)MediumReal-time order/payment sync
2Checkout REST APIMediumFull control, bidirectional sync
Zapier / MakeEasySimple order notification
Custom Odoo ModuleHighDeep integration with subscriptions

Step 1: Get 2Checkout API Access

  1. Log into your 2Checkout Merchant Control Panel
  2. Go to Integrations → Webhooks & API
  3. Generate your Merchant Code and Secret Key
  4. Enable the REST API
  5. Set up IPN (Instant Payment Notification) URL

Step 2: Configure IPN Webhook

2Checkout's IPN system sends notifications for order events. Configure the IPN URL to point to your Odoo endpoint:

# In 2Checkout Control Panel:
# IPN URL: https://your-odoo.com/2checkout/ipn
# Events: ORDER_CREATED, FRAUD_STATUS_CHANGED, 
#         INVOICE_STATUS_CHANGED, REFUND_ISSUED

Step 3: Handle IPN in Odoo

from odoo import http
import json, hashlib

class TwoCheckoutIPN(http.Controller):
    @http.route('/2checkout/ipn', type='http', auth='none',
                csrf=False, methods=['POST'])
    def handle_ipn(self, **kwargs):
        data = http.request.httprequest.form.to_dict()
        
        # Verify IPN signature
        if not self._verify_signature(data):
            return http.request.make_response('Invalid signature', status=401)
        
        notification_type = data.get('ORDERSTATUS')
        
        if notification_type == 'COMPLETE':
            self._create_order(data)
        elif notification_type == 'REFUND':
            self._create_refund(data)
        
        return http.request.make_response(
            'OK|'
        )
    
    def _create_order(self, data):
        partner = self._find_or_create_partner({
            'name': f"{data.get('FIRSTNAME')} {data.get('LASTNAME')}",
            'email': data.get('CUSTOMEREMAIL'),
            'country_code': data.get('COUNTRY'),
        })
        
        order_vals = {
            'partner_id': partner.id,
            'origin': f"2CO #{data.get('REFNO')}",
            'order_line': [],
        }
        
        # Parse product lines
        idx = 0
        while data.get(f'IPN_PID[{idx}]'):
            product = self._find_product(data[f'IPN_PID[{idx}]'])
            order_vals['order_line'].append((0, 0, {
                'product_id': product.id if product else False,
                'name': data.get(f'IPN_PNAME[{idx}]', ''),
                'product_uom_qty': int(data.get(f'IPN_QTY[{idx}]', 1)),
                'price_unit': float(data.get(f'IPN_PRICE[{idx}]', 0)),
            }))
            idx += 1
        
        http.request.env['sale.order'].sudo().create(order_vals)

Step 4: Subscription Sync

2Checkout handles subscription billing natively. Sync subscription events to Odoo:

# 2Checkout subscription events to handle:
# RECURRING_INSTALLMENT_SUCCESS -> Record payment in Odoo
# RECURRING_INSTALLMENT_FAILED -> Flag in Odoo, notify customer
# RECURRING_STOPPED -> Cancel Odoo subscription
# RECURRING_COMPLETE -> Close Odoo subscription

def _handle_subscription_event(self, data):
    event = data.get('RECURRING_TYPE')
    ref = data.get('REFNO')
    
    subscription = http.request.env['sale.order'].sudo().search(
        [('origin', 'like', f'2CO #{ref}')], limit=1
    )
    if not subscription:
        return
    
    if event == 'RECURRING_INSTALLMENT_SUCCESS':
        # Create payment record
        amount = float(data.get('IPN_TOTALGENERAL', 0))
        self._register_payment(subscription, amount)
    elif event == 'RECURRING_STOPPED':
        subscription.action_cancel()

Multi-Currency Handling

2Checkout processes payments in the buyer's local currency and settles to you in your preferred currency. In Odoo, handle this by:

  • Recording the sale in the buyer's currency (from IPN data)
  • Recording the settlement in your base currency
  • Letting Odoo's exchange rate mechanism handle the conversion
  • Reconciling against 2Checkout settlement reports

Tax Compliance

As a merchant of record, 2Checkout handles tax collection and remittance. In Odoo, record the gross sale amount and 2Checkout's tax/fee deductions separately so your books reflect the actual revenue flow.

2Checkout Pricing

ModelRateBest For
2Sell (gateway)3.5% + $0.35Low volume, simple
2Subscribe4.5% + $0.45SaaS, recurring billing
2Monetize (MoR)6.0% + $0.60Global sales, tax compliance

DeployMonkey + 2Checkout

DeployMonkey instances support the IPN webhook endpoints needed for 2Checkout integration. Our AI agent can help configure the payment flow, map products, and set up subscription sync.