PROPOSAL
Separate the “invoice” from the “how to pay”. Payment Pointers are great for directing someone to a service that can give them an ILP Address and secret so they are able to open a STREAM connection.
Overloading this with business logic like invoices might not be a good idea in the long term.
So when a client resolves a payment pointer, the response headers should contain:
ILP-Address: <some ILP address>
ILP-Secret: <some base64 encoded secret>
The body of the response could be anything (or nothing).
Option 1
Your server (e.g. https://anypay.global) can simply host invoices using good ol’ REST.
e.g. You could have a pointer like this: $anypay.global/invoices/1234
The actual invoice that is returned when you GET https://anypay.global/invoices/1234
can be whatever you like. You could find a standard eInvoice format (there are many https://en.wikipedia.org/wiki/Electronic_invoicing#e-Invoicing_standards) or invent your own, as long as your customers know how to interpret it so they know how much to pay you.
I don’t think the ILP community is a good place to design an invoice standard.
How you choose to correlate the STREAM connection details that to the invoice is up to you. A common approach which saves you from needing to store the correlation somewhere is to simply put the invoice id in the ILP address and derive the secret using the address or invoice id.
When your STREAM server receives an incoming connection it can correlate it with the invoice based on the address on the incoming packets. (You don’t even HAVE to do this in real time, you could just accept as much money as the sender is prepared to send and then reconcile your payments with your invoices later like most businesses do.)
Option 2
Only provide the STREAM connection details in the Payment Pointer response.
After the client has established the STREAM connection they use the data channel on that connection to get the details of outstanding invoices, request to pay one or more of these or even submit an invoice to the server for payment (pull payments).
If we define a simple REST API for creating payment requests (more general than just invoices) and payments then this could be executed over the STREAM data connection.
Examples of possible API endpoints might be:
/payment
- create a new payment and then “pay” it using the money channel on the same stream
/paymentRequest
- create a request for payment with the counter-party who, after accepting the request, pays it via the money channel on the same stream