Payment Method Documentation¶
Overview¶
The Payment Method model (payment.method) defines the different methods by which payments can be made or received. It supports various payment types including cash, bank transfer, cheque, credit card, and integrations with payment gateways like PayPal, Paysbuy, and SCB Gateway.
Model Information¶
Model Name: payment.method
Display Name: Payment Method
Key Fields: None (no unique constraint defined)
Features¶
- ❌ Audit logging enabled (
_audit_log) - ❌ Multi-company support (
company_id) - ❌ Full-text content search (
_content_search) - ✅ Multiple payment type support
- ✅ Payment gateway integration (PayPal, Paysbuy, SCB)
- ✅ Account linking for automatic posting
- ✅ Sequence ordering
Key Fields Reference¶
Core Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
Char | ✅ | Payment method name (searchable) |
code |
Char | ❌ | Method code (searchable) |
sequence |
Integer | ❌ | Display order |
type |
Selection | ❌ | Payment method type |
account_id |
Many2One | ❌ | Default GL account for this method |
instructions |
Text | ❌ | Payment instructions for customers |
service_charge |
Decimal | ❌ | Service charge amount |
require_report |
Boolean | ❌ | Whether report is required |
Payment Types¶
| Type | Code | Description |
|---|---|---|
| Cash | cash |
Cash payment |
| Bank Transfer | bank |
Bank transfer/wire |
| Cheque | cheque |
Cheque payment |
| Credit Card | credit_card |
Credit card payment |
| PayPal | paypal |
PayPal gateway |
| SCB Gateway | scb_gateway |
SCB payment gateway |
| Paysbuy | paysbuy |
Paysbuy gateway |
PayPal Integration Fields¶
| Field | Type | Description |
|---|---|---|
paypal_url |
Selection | Server URL (test/production) |
paypal_user |
Char | PayPal API username |
paypal_password |
Char | PayPal API password |
paypal_signature |
Char | PayPal API signature |
Paysbuy Integration Fields¶
| Field | Type | Description |
|---|---|---|
paysbuy_id |
Char | Paysbuy merchant ID |
paysbuy_username |
Char | Paysbuy username |
paysbuy_securecode |
Char | Paysbuy secure code |
paysbuy_resp_back_url |
Char | Response callback URL |
paysbuy_url |
Selection | Server URL (test/production) |
SCB Gateway Integration Fields¶
| Field | Type | Description |
|---|---|---|
scb_mid |
Char | SCB Merchant ID |
scb_terminal |
Char | SCB Terminal ID |
scb_url |
Selection | Server URL (test/production) |
Relationship Fields¶
| Field | Type | Description |
|---|---|---|
comments |
One2Many | Related comments/messages |
Default Ordering¶
Records are ordered by sequence, then by name:
API Methods¶
1. Create Payment Method¶
Method: create(vals, context)
Creates a new payment method.
Parameters:
vals = {
"name": "Bank Transfer", # Required: Method name
"code": "BANK", # Optional: Code
"type": "bank", # Optional: Payment type
"account_id": bank_account_id, # Optional: GL account
"sequence": 10, # Optional: Display order
"instructions": "Transfer to...", # Optional: Instructions
}
Returns: int - New record ID
Example:
# Create a bank transfer method
method_id = get_model("payment.method").create({
"name": "Bank Transfer - USD Account",
"code": "BANK_USD",
"type": "bank",
"account_id": usd_bank_account_id,
"sequence": 10,
"instructions": """
Please transfer to:
Bank: ABC Bank
Account: 1234567890
Swift: ABCDSGSG
""",
})
2. Start Payment¶
Method: start_payment(ids, context)
Initiates a payment process (placeholder for gateway integration).
Example:
3. Payment Received¶
Method: payment_received(context)
Callback method for payment gateway notifications.
Context Parameters:
context = {
"transaction_no": "TXN123456", # Transaction reference
"amount": 100.00, # Payment amount
"currency_id": currency_id, # Currency
"type": "paypal", # Payment type
}
Behavior: 1. Finds invoice by transaction number 2. Validates currency and payment method match 3. Creates and posts payment record 4. Logs payment receipt in audit log
Returns: Navigation to payment view
Example:
# Called by payment gateway callback
result = get_model("payment.method").payment_received(context={
"transaction_no": "PAY-2024-001",
"amount": 250.00,
"currency_id": usd_currency_id,
"type": "paypal",
})
4. Payment Pending¶
Method: payment_pending(context)
Handles pending payment notifications from gateway.
Context Parameters:
Returns: Navigation to invoice view
5. Payment Error¶
Method: payment_error(context)
Handles payment error notifications from gateway.
Context Parameters:
Returns: Navigation to invoice view
Related Models¶
| Model | Relationship | Description |
|---|---|---|
account.account |
Many2One (account_id) | Default GL account for posting |
account.payment |
Reference | Payments using this method |
account.invoice |
Reference | Invoices with this payment method |
message |
One2Many (comments) | Related comments |
Common Use Cases¶
Use Case 1: Set Up Standard Payment Methods¶
# Create standard payment methods
methods = [
{
"name": "Cash",
"code": "CASH",
"type": "cash",
"account_id": cash_account_id,
"sequence": 1,
},
{
"name": "Bank Transfer",
"code": "BANK",
"type": "bank",
"account_id": bank_account_id,
"sequence": 2,
"instructions": "Transfer to: Bank ABC, Acc: 123456789",
},
{
"name": "Cheque",
"code": "CHQ",
"type": "cheque",
"account_id": bank_account_id,
"sequence": 3,
},
{
"name": "Credit Card",
"code": "CC",
"type": "credit_card",
"account_id": cc_clearing_account_id,
"sequence": 4,
"service_charge": 3.0, # 3% service charge
},
]
for method in methods:
existing = get_model("payment.method").search([["code", "=", method["code"]]])
if not existing:
get_model("payment.method").create(method)
Use Case 2: Configure PayPal Integration¶
# Set up PayPal payment method
paypal_id = get_model("payment.method").create({
"name": "PayPal",
"code": "PAYPAL",
"type": "paypal",
"account_id": paypal_account_id,
"sequence": 5,
"paypal_url": "production", # or "test" for sandbox
"paypal_user": "api_username",
"paypal_password": "api_password",
"paypal_signature": "api_signature",
"instructions": "Pay securely with PayPal",
})
Use Case 3: Configure SCB Gateway¶
# Set up SCB payment gateway
scb_id = get_model("payment.method").create({
"name": "SCB Payment Gateway",
"code": "SCB",
"type": "scb_gateway",
"account_id": scb_account_id,
"sequence": 6,
"scb_mid": "MERCHANT_ID",
"scb_terminal": "TERMINAL_ID",
"scb_url": "production", # or "test"
})
Use Case 4: Get Payment Methods for Customer Portal¶
# Get active online payment methods
online_types = ["paypal", "credit_card", "scb_gateway", "paysbuy"]
methods = get_model("payment.method").search_browse([
["type", "in", online_types]
], order="sequence")
available_methods = []
for method in methods:
available_methods.append({
"id": method.id,
"name": method.name,
"type": method.type,
"instructions": method.instructions,
})
Use Case 5: Process Gateway Payment Callback¶
# Example: Handle PayPal IPN callback
def handle_paypal_ipn(request):
# Extract data from PayPal IPN
transaction_no = request.get("custom") # Invoice transaction number
amount = float(request.get("mc_gross"))
currency = request.get("mc_currency")
# Find currency
currency_ids = get_model("currency").search([["code", "=", currency]])
if not currency_ids:
raise Exception(f"Unknown currency: {currency}")
# Process payment
result = get_model("payment.method").payment_received(context={
"transaction_no": transaction_no,
"amount": amount,
"currency_id": currency_ids[0],
"type": "paypal",
})
return result
Best Practices¶
1. Always Link to GL Account¶
# Good: Account linked for automatic posting
method = get_model("payment.method").create({
"name": "Bank Transfer",
"type": "bank",
"account_id": bank_account_id, # Ensures proper GL posting
})
# Bad: No account (manual account selection needed)
method = get_model("payment.method").create({
"name": "Bank Transfer",
"type": "bank",
# Missing account_id
})
2. Use Test Environment First¶
# Good: Start with test environment
method = get_model("payment.method").create({
"name": "PayPal (Test)",
"type": "paypal",
"paypal_url": "test", # Use sandbox first
...
})
# Later: Switch to production after testing
method.write({"paypal_url": "production"})
3. Provide Clear Instructions¶
# Good: Clear payment instructions
method = get_model("payment.method").create({
"name": "Bank Transfer",
"instructions": """
Bank: Singapore Banking Corporation
Account Name: ABC Company Pte Ltd
Account Number: 123-456789-001
Swift Code: SBOCSGSG
Please include your invoice number as reference.
""",
})
4. Use Meaningful Codes¶
# Good: Clear, consistent codes
methods = [
{"name": "Cash - SGD", "code": "CASH_SGD"},
{"name": "Cash - USD", "code": "CASH_USD"},
{"name": "Bank - DBS", "code": "BANK_DBS"},
{"name": "Bank - OCBC", "code": "BANK_OCBC"},
]
# Bad: Generic codes
methods = [
{"name": "Method 1", "code": "M1"},
{"name": "Method 2", "code": "M2"},
]
Troubleshooting¶
"Invoice not found for transaction_no"¶
Cause: Invoice doesn't have matching transaction number Solution: Ensure invoice.transaction_no is set before initiating payment
"Received invoice payment in wrong currency"¶
Cause: Payment currency doesn't match invoice currency Solution: Verify currency settings on invoice and payment gateway
"Received invoice payment with wrong method"¶
Cause: Payment type doesn't match invoice's payment method type Solution: Ensure invoice.pay_method_id matches the payment gateway
"Missing account for payment method"¶
Cause: Payment method doesn't have account_id set Solution: Configure account_id on the payment method
"Missing invoice payment method"¶
Cause: Invoice doesn't have pay_method_id set Solution: Set payment method on invoice before online payment
Testing Examples¶
Unit Test: Create Payment Method¶
def test_payment_method_creation():
# Create method
method_id = get_model("payment.method").create({
"name": "Test Bank Transfer",
"code": "TEST_BANK",
"type": "bank",
"account_id": test_bank_account_id,
"sequence": 99,
})
# Verify
method = get_model("payment.method").browse([method_id])[0]
assert method.name == "Test Bank Transfer"
assert method.code == "TEST_BANK"
assert method.type == "bank"
assert method.account_id.id == test_bank_account_id
# Cleanup
get_model("payment.method").delete([method_id])
Security Considerations¶
Permission Model¶
- Read access for users who process payments
- Write access restricted to accounting/admin
- Gateway credentials should be protected
Sensitive Data¶
- PayPal credentials (user, password, signature)
- Paysbuy credentials (username, securecode)
- SCB credentials (mid, terminal)
Warning: Store gateway credentials securely and restrict access.
Audit Logging¶
The payment_received method uses audit logging:
Configuration Requirements¶
For PayPal Integration¶
- Create PayPal business account
- Obtain API credentials (username, password, signature)
- Configure IPN callback URL
- Test with sandbox before production
For SCB Gateway¶
- Register with SCB as merchant
- Obtain Merchant ID and Terminal ID
- Configure callback URLs
- Test with test environment
For Paysbuy¶
- Register Paysbuy merchant account
- Obtain Paysbuy ID and secure code
- Configure response callback URL
Version History¶
Last Updated: December 2024 Model Version: payment_method.py Framework: Netforce
Additional Resources¶
- Payment Documentation:
account.payment - Invoice Documentation:
account.invoice - Account Documentation:
account.account
This documentation is generated for developer onboarding and reference purposes.