0

I'm trying to add a payment to xero using the pyxero python library for python3. I'm able to add invoices and contacts, but payments always returns a validation exception. Here is the data I'm submitting:

payments.put([{'Amount': '20.00', 
               'Date': datetime.date(2016, 5, 25), 
               'AccountCode': 'abc123', 
               'Reference': '8831_5213', 
               'InvoiceID': '09ff0465-d1b0-4fb3-9e2e-3db4e83bb240'}])

And the xero response:

xero.exceptions.XeroBadRequest: ValidationException: A validation exception occurred
MattDMo
  • 100,794
  • 21
  • 241
  • 231
Dylan
  • 3
  • 1
  • 1

1 Answers1

1

Please note: this solution became a hack inside pyxero to get the result I needed. This may not be the best solution for you.

The XML that pyxero generates for "payments.put" does not match the "PUT Payments" XML structure found in the xero documentation.

I first changed the structure of your dictionary so that the XML generated in basemanager.py was similar to the documentation's.

data = {
    'Invoice': {'InvoiceID': "09ff0465-d1b0-4fb3-9e2e-3db4e83bb240"},
    'Account': {"AccountID": "58F8AD72-1F2E-AFA2-416C-8F660DDD661B"},
    'Date': datetime.datetime.now(),
    'Amount': 30.00,
}
xero.payments.put(data)

The error still persisted though, so I was forced to start changing code inside pyxero's basemanager.py.

In basemanager.py on line 133, change the formatting of the date:

val = sub_data.strftime('%Y-%m-%dT%H:%M:%S')

to:

val = sub_data.strftime('%Y-%m-%d')

pyxero is originally returning the Time. This is supposed to only be a Date value - The docs stipulate the formatting.

Then, again in basemanager.py, on line 257, change the following:

body = {'xml': self._prepare_data_for_save(data)}

to:

if self.name == "Payments":
    body = {'xml': "<Payments>%s</Payments>" % self._prepare_data_for_save(data)}
else:
    body = {'xml': self._prepare_data_for_save(data)}

Please note that in order for you to be able to create a payment in the first place, the Invoice's "Status" must be set to "AUTHORISED". Also, make sure the Payment's "Amount" is no greater than Invoice's "AmountDue" value.