Quickstart¶
The following examples takes you through the flow from payers signing up for AvtaleGiro to receiving payments.
See the objects API reference for details on the API and data fields used in the examples below.
Parsing AvtaleGiro agreements¶
To parse an OCR file, you must first read the contents of the OCR file. It should be decoded using the ISO-8859-1 encoding:
with open('my-ocr-file.txt', 'r', encoding='iso-8859-1') as fh:
data = fh.read()
For the purpose of the following example we use the following input data:
>>> data = """
... NY000010000080801091949000102000000000000000000000000000000000000000000000000000
... NY212420000000000000000299991042764000000000000000000000000000000000000000000000
... NY21947000000011 000112000507155J00000000000000000000000000000000000000
... NY21947000000021 001006300507304N00000000000000000000000000000000000000
... NY21947000000031 001020200507462J00000000000000000000000000000000000000
... NY21947000000041 001026300507518J00000000000000000000000000000000000000
... NY21947000000051 001044400507783J00000000000000000000000000000000000000
... NY21947000000061 001045000507792N00000000000000000000000000000000000000
... NY21947000000071 001057800507922N00000000000000000000000000000000000000
... NY21947000000081 001060300509570J00000000000000000000000000000000000000
... NY21947000000091 001087600508176J00000000000000000000000000000000000000
... NY21947000000101 001105600508416J00000000000000000000000000000000000000
... NY21947000000111 001123000508621J00000000000000000000000000000000000000
... NY21947000000121 001124000508637J00000000000000000000000000000000000000
... NY21947000000131 001138900509107N00000000000000000000000000000000000000
... NY21947000000141 001143700509281J00000000000000000000000000000000000000
... NY21947000000151 001146800509317J00000000000000000000000000000000000000
... NY21947000000161 001186100509492N00000000000000000000000000000000000000
... NY212488000000160000001800000000000000000000000000000000000000000000000000000000
... NY000089000000160000002000000000000000000190417000000000000000000000000000000000
... """.strip()
netsgiro.parse()
parses the input and returns a
netsgiro.Transmission
object:
>>> import netsgiro
>>> transmission = netsgiro.parse(data)
>>> transmission
Transmission(number='1091949', data_transmitter='00008080', data_recipient='00010200', date=datetime.date(2017, 4, 19))
>>> transmission.number
'1091949'
Each transmission can contain any number of assignments:
>>> len(transmission.assignments)
1
>>> assignment = transmission.assignments[0]
>>> assignment
Assignment(service_code=<ServiceCode.AVTALEGIRO: 21>, type=<AssignmentType.AVTALEGIRO_AGREEMENTS: 24>, number='0000002', account='99991042764', agreement_id=None, date=None)
>>> assignment.number
'0000002'
Each assignment can contain any number of transactions, in this case AvtaleGiro agreement updates:
>>> pprint(assignment.transactions)
[Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=1, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='000112000507155', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=2, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001006300507304', notify=False),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=3, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001020200507462', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=4, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001026300507518', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=5, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001044400507783', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=6, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001045000507792', notify=False),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=7, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001057800507922', notify=False),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=8, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001060300509570', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=9, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001087600508176', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=10, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001105600508416', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=11, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001123000508621', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=12, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001124000508637', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=13, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001138900509107', notify=False),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=14, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001143700509281', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=15, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001146800509317', notify=True),
Agreement(service_code=<ServiceCode.AVTALEGIRO: 21>, number=16, registration_type=<AvtaleGiroRegistrationType.NEW_OR_UPDATED_AGREEMENT: 1>, kid='001186100509492', notify=False)]
As you can see, all updates here are for new or updated agreements. If a payer
deletes their AvtaleGiro agreement the registration_type
field will be
DELETED_AGREEMENT
.
Building payment requests¶
Once you have established AvtaleGiro agreements with some payers, you can start creating payment requests based on your invoices.
You start by creating a Transmission
with Nets as the
recipient:
>>> from datetime import date
>>> from decimal import Decimal
>>> import netsgiro
>>> transmission = netsgiro.Transmission(
... number='1703231',
... data_transmitter='01234567',
... data_recipient=netsgiro.NETS_ID)
Then, add an AvtaleGiro transaction assignment to the transmission using
add_assignment()
:
>>> assignment = transmission.add_assignment(
... service_code=netsgiro.ServiceCode.AVTALEGIRO,
... assignment_type=netsgiro.AssignmentType.TRANSACTIONS,
... number='0323001',
... account='99998877777')
For each invoice, add a payment requests to the assignment using
add_payment_request()
:
>>> payment_request = assignment.add_payment_request(
... kid='000133700501645',
... due_date=date(2017, 4, 6),
... amount=Decimal('5244.63'),
... reference='ACME invoice #50164',
... payer_name='Wonderland',
... bank_notification=None)
Finally, you can write out the OCR data using
to_ocr()
:
>>> data = transmission.to_ocr()
>>> print(data)
NY000010012345671703231000080800000000000000000000000000000000000000000000000000
NY210020000000000032300199998877777000000000000000000000000000000000000000000000
NY2102300000001060417 00000000000524463 000133700501645000000
NY2102310000001Wonderland ACME invoice #50164 00000
NY210088000000010000000400000000000524463060417060417000000000000000000000000000
NY000089000000010000000600000000000524463060417000000000000000000000000000000000
Before delivering the transmission to Nets, remember to encode it using the ISO-8859-1 encoding to correctly preserve Norwegian letters.
To encode a bytestring with the correct encoding:
encoded_data = data.encode('iso-8859-1')
To save the result a file with the correct encoding:
with open('my-ocr-file.txt', 'wt', encoding='iso-8859-1') as fh:
fh.write(data)
Building payment cancellations¶
To cancel one or more AvtaleGiro payment requests, the process is very similar
to creating payment requests. You start with a Transmission
:
>>> from datetime import date
>>> from decimal import Decimal
>>> import netsgiro
>>> transmission = netsgiro.Transmission(
... number='1703232',
... data_transmitter='01234567',
... data_recipient=netsgiro.NETS_ID)
Add a AvtaleGiro cancellation assignment to the transmission using
add_assignment()
:
>>> assignment = transmission.add_assignment(
... service_code=netsgiro.ServiceCode.AVTALEGIRO,
... assignment_type=netsgiro.AssignmentType.AVTALEGIRO_CANCELLATIONS,
... number='0323002',
... account='99998877777')
Add one or more payment cancellations to the assignment using
add_payment_cancellation()
:
>>> transaction = assignment.add_payment_cancellation(
... kid='000133700501645',
... due_date=date(2017, 4, 6),
... amount=Decimal('5244.63'),
... reference='ACME invoice #50164',
... payer_name='Wonderland',
... bank_notification=None)
The arguments passed to add_payment_cancellation()
must be identical to the arguments passed to
add_payment_request()
when creating the payment
request you are now cancelling.
Finally, you can write out the OCR data using
to_ocr()
and write the result to a file.
>>> data = transmission.to_ocr()
>>> print(data)
NY000010012345671703232000080800000000000000000000000000000000000000000000000000
NY213620000000000032300299998877777000000000000000000000000000000000000000000000
NY2193300000001060417 00000000000524463 000133700501645000000
NY2193310000001Wonderland ACME invoice #50164 00000
NY213688000000010000000400000000000524463060417060417000000000000000000000000000
NY000089000000010000000600000000000524463060417000000000000000000000000000000000
Parsing OCR Giro transactions¶
When receiving payments to your bank account, you’ll receive OCR Giro files with lists of all the transactions.
For the purpose of the following example we use the following input data:
>>> data = """
... NY000010000080800170031000102000000000000000000000000000000000000000000000000000
... NY090020001008566000000299991042764000000000000000000000000000000000000000000000
... NY09213000000012001921320101464000000000000102000 0000531000000
... NY092131000000196368271940990385620000000160192999905123410000000000000000000000
... NY0921320000001Foo bar baz 0000000000000000000000000
... NY09103000000022001921320101464000000000000102000 0036633000000
... NY091031000000297975960160975960161883206160192999910055240000000000000000000000
... NY09103000000032001921320101464000000000000056000 0048763000000
... NY091031000000397975816750975816751883206170192999910427640000000000000000000000
... NY09103000000042001921320101464000000000000102000 0063851000000
... NY091031000000497975857600975857601883206170192999910055240000000000000000000000
... NY09103000000052001921320101464000000000000102000 0120243000000
... NY091031000000597975915790975915791883206170192999905678980000000000000000000000
... NY09103000000062001921320101464000000000000056000 0165867000000
... NY091031000000697975851090975851091883206160192999910427640000000000000000000000
... NY09103000000072001921320101464000000000000102000 0178357000000
... NY091031000000797975848550975848551883206160192999910055240000000000000000000000
... NY09113000000082001921320101570000000000000150000 02212291038306000000
... NY091131000000896000000006001553800000000200192999995455280000000000000000000000
... NY09123000000092001921320101570000000000000120000 02311291038304000000
... NY091231000000900000000000010201690000000000000999910154060000000000000000000000
... NY09133000000102001921320101570000000000000055000 02310291038308000000
... NY091331000001000000000002206638000000000000000999910175300000000000000000000000
... NY09113000000112001921320231570000000000000194300 000149012000000
... NY091131000001196000000006001552110000000200192999905080340000000000000000000000
... NY09123000000122001921320231570000000000000100000 01211291038306000000
... NY091231000001200000000000010201690000000000000999905080340000000000000000000000
... NY09133000000132001921320231570000000000000050000 02111291038305000000
... NY091331000001300000000000320663700000000000000999905230840000000000000000000000
... NY09133000000142001921320335572000000000002050000 02321291038303000000
... NY091331000001400000000000250663700000000000000999905100550000000000000000000000
... NY09133000000152001921320941570000000000000550000 02331291038302000000
... NY091331000001500000000007974896260000000000000999910111250000000000000000000000
... NY09133000000162001921320941570000000000001050000 02341291038301000000
... NY091331000001600000000000281163700000000000000999995455280000000000000000000000
... NY09103000000172001921320941570000000000000064400 02358291038305000000
... NY091031000001700000000002806638000000000000000999995455280000000000000000000000
... NY09103000000182001921320904514000000000000056400 02311291029238000000
... NY091031000001896367780030913067140000000170192999910154060000000000000000000000
... NY09103000000192001921320904514000000000000028800 02311291034832000000
... NY091031000001996367778210976949990000000160192999910080340000000000000000000000
... NY09103000000202001921320904514000000000000054000 02311291133188000000
... NY091031000002096367781170913088610000000170192999910111250000000000000000000000
... NY090088000000200000004300000000005144900200192200192200192000000000000000000000
... NY000089000000200000004500000000005144900200192000000000000000000000000000000000
... """.strip()
netsgiro.parse()
parses the input and returns a
netsgiro.Transmission
object:
>>> import netsgiro
>>> transmission = netsgiro.parse(data)
>>> transmission
Transmission(number='0170031', data_transmitter='00008080', data_recipient='00010200', date=datetime.date(1992, 1, 20))
>>> transmission.number
'0170031'
Each transmission can contain any number of assignments:
>>> len(transmission.assignments)
1
>>> assignment = transmission.assignments[0]
>>> assignment
Assignment(service_code=<ServiceCode.OCR_GIRO: 9>, type=<AssignmentType.TRANSACTIONS: 0>, number='0000002', account='99991042764', agreement_id='001008566', date=datetime.date(1992, 1, 20))
>>> assignment.number
'0000002'
>>> assignment.get_earliest_transaction_date()
datetime.date(1992, 1, 20)
>>> assignment.get_latest_transaction_date()
datetime.date(1992, 1, 20)
>>> assignment.get_total_amount()
Decimal('51449')
Each assignment can contain any number of transactions, in this case OCR Giro payment transactions:
>>> pprint(assignment.transactions)
[Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.PURCHASE_WITH_TEXT: 21>, number=1, date=datetime.date(1992, 1, 20), amount=Decimal('1020'), kid='0000531', reference='099038562', text='Foo bar baz', centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01464', sign='0', form_number='9636827194', bank_date=datetime.date(1992, 1, 16), debit_account='99990512341', _filler='0000000'),
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_GIRO_DEBITED_ACCOUNT: 10>, number=2, date=datetime.date(1992, 1, 20), amount=Decimal('1020'), kid='0036633', reference='097596016', text=None, centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01464', sign='0', form_number='9797596016', bank_date=datetime.date(1992, 1, 16), debit_account='99991005524', _filler='1883206'),
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_GIRO_DEBITED_ACCOUNT: 10>, number=3, date=datetime.date(1992, 1, 20), amount=Decimal('560'), kid='0048763', reference='097581675', text=None, centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01464', sign='0', form_number='9797581675', bank_date=datetime.date(1992, 1, 17), debit_account='99991042764', _filler='1883206'),
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_GIRO_DEBITED_ACCOUNT: 10>, number=4, date=datetime.date(1992, 1, 20), amount=Decimal('1020'), kid='0063851', reference='097585760', text=None, centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01464', sign='0', form_number='9797585760', bank_date=datetime.date(1992, 1, 17), debit_account='99991005524', _filler='1883206'),
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_GIRO_DEBITED_ACCOUNT: 10>, number=5, date=datetime.date(1992, 1, 20), amount=Decimal('1020'), kid='0120243', reference='097591579', text=None, centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01464', sign='0', form_number='9797591579', bank_date=datetime.date(1992, 1, 17), debit_account='99990567898', _filler='1883206'),
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_GIRO_DEBITED_ACCOUNT: 10>, number=6, date=datetime.date(1992, 1, 20), amount=Decimal('560'), kid='0165867', reference='097585109', text=None, centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01464', sign='0', form_number='9797585109', bank_date=datetime.date(1992, 1, 16), debit_account='99991042764', _filler='1883206'),
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_GIRO_DEBITED_ACCOUNT: 10>, number=7, date=datetime.date(1992, 1, 20), amount=Decimal('1020'), kid='0178357', reference='097584855', text=None, centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01464', sign='0', form_number='9797584855', bank_date=datetime.date(1992, 1, 16), debit_account='99991005524', _filler='1883206'),
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_STANDING_ORDERS: 11>, number=8, date=datetime.date(1992, 1, 20), amount=Decimal('1500'), kid='02212291038306', reference='600155380', text=None, centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01570', sign='0', form_number='9600000000', bank_date=datetime.date(1992, 1, 20), debit_account='99999545528', _filler='0000000'),
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_DIRECT_REMITTANCE: 12>, number=9, date=datetime.date(1992, 1, 20), amount=Decimal('1200'), kid='02311291038304', reference='001020169', text=None, centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01570', sign='0', form_number='0000000000', bank_date=None, debit_account='99991015406', _filler='0000000'),
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_BUSINESS_TERMINAL_GIRO: 13>, number=10, date=datetime.date(1992, 1, 20), amount=Decimal('550'), kid='02310291038308', reference='220663800', text=None, centre_id='13', day_code=20, partial_settlement_number=1, partial_settlement_serial_number='01570', sign='0', form_number='0000000000', bank_date=None, debit_account='99991017530', _filler='0000000'),
...
Transaction(service_code=<ServiceCode.OCR_GIRO: 9>, type=<TransactionType.FROM_GIRO_DEBITED_ACCOUNT: 10>, number=20, date=datetime.date(1992, 1, 20), amount=Decimal('540'), kid='02311291133188', reference='091308861', text=None, centre_id='13', day_code=20, partial_settlement_number=9, partial_settlement_serial_number='04514', sign='0', form_number='9636778117', bank_date=datetime.date(1992, 1, 17), debit_account='99991011125', _filler='0000000')]