PaymentLoad
Record payments made against invoices. Upserts on external_source +
external_payment_id. A payment has a list of lines, each
applying part of the total amount to a specific invoice.
Import
from lib.objects.payment import PaymentLoad
Standard BaseLoad methods
get_all(), search(), new(), save_all(). See baseload.md.
PaymentLoad does NOT support delete_where() — delete by setting
status='CANCELED' and re-saving instead.
Payment fields
| Field | Required | Notes |
|---|---|---|
id | (assigned) | BIGINT |
external_payment_id | yes | Your stable id from the source system |
external_source | e.g. 'SAP', 'NETSUITE' — combined with external_payment_id as the upsert key. Strongly recommended even though the API doesn't enforce it; without it, two systems pushing the same id collide. | |
status | INITIATED, PROCESSING, SENT, SETTLED, RETURNED, FAILED, CANCELED, PAID | |
method | yes | ACH, WIRE, SEPA, SWIFT, RTP, CHECK, CARD, VIRTUAL_CARD, PAYPAL, OTHER |
total_amount | yes | float |
currency | yes | 3-letter ISO |
| Lifecycle timestamps | ||
scheduled_at / submitted_at / sent_at | ||
expected_settlement_at / settled_at / returned_at | ||
| References | ||
payment_reference | Free-form | |
bank_reference | ||
ach_trace_number | for ACH | |
sepa_end_to_end_id | for SEPA | |
rtp_trace_id | for RTP | |
| Check-specific | ||
check_number | ||
check_mailed_at / check_cleared_at | ||
check_stop_payment | bool | |
| Beneficiary (recipient) | ||
beneficiary_name | ||
beneficiary_bank_name / beneficiary_bank_country (2-char) | ||
beneficiary_swift_bic | up to 11 chars | |
beneficiary_iban / beneficiary_account / beneficiary_routing | ||
| Payer (sender) | ||
payer_bank_name / payer_bank_country | ||
payer_account / payer_routing | ||
| Remittance | ||
remittance_memo | ||
remittance_advice_url | ||
replace_lines | bool, default true. When saving with a lines array, true wipes existing lines and replaces; false appends. |
PaymentLine fields (the application to an invoice)
| Field | Required |
|---|---|
invoice_token_id | yes — UUID of the target invoice |
applied_amount | yes — float |
applied_currency | |
fx_rate_line / fx_at_line | |
discount_amount / discount_currency | |
fee_amount_line / fee_currency_line | |
remittance_label / remittance_value | |
notes |
Example: ACH payment applied to two invoices
from lib.objects.payment import PaymentLoad
def run(context):
load = PaymentLoad(context)
p = load.new()
p.external_payment_id = 'PAY-2026-001'
p.external_source = 'SAP'
p.method = 'ACH'
p.total_amount = 1500.00
p.currency = 'USD'
p.status = 'SENT'
p.sent_at = '2026-04-25T14:00:00Z'
p.beneficiary_name = 'Acme Corporation'
p.ach_trace_number = 'T20260425001'
line1 = p.new_line()
line1.invoice_token_id = 'aaaaaaaa-0001-...'
line1.applied_amount = 1000.00
line2 = p.new_line()
line2.invoice_token_id = 'aaaaaaaa-0002-...'
line2.applied_amount = 500.00
load.save_all()
return {'created': 1}
Lookup
# By external id
p = load.get_by_external_id('SAP', 'PAY-2026-001')
if p:
print(p.status, p.total_amount, p.currency)
# All payments touching an invoice
for p in load.get_by_invoice('aaaaaaaa-0001-...'):
for ln in p.lines:
print(ln.applied_amount)
Update an existing payment
Save again with the same external_source + external_payment_id —
fields you set get updated, fields you leave unset are preserved.
p = load.get_by_external_id('SAP', 'PAY-2026-001')
p.status = 'SETTLED'
p.settled_at = '2026-04-26T10:00:00Z'
p.save()
By default, re-saving with a new lines array replaces the
applications. Pass p.replace_lines = False to append instead.