Closed wsdOgawa closed 2 years ago
It looks like the last issue that has yet to be addressed in this one. If I can put a pending close
tag on this issue, then I'll go back to all of the other issues and make sure that everything has been addressed before moving into documentation.
For the purposes of this issue, first want to test did authentication, which means sending an empty presentation to build modules needed for working with presentations. Then we can update the contacts module to use this approach. And then we can update the invoice and invoice updates to use presentations. Which means that once we've done this, this should be the first issue that we can definitively cross off as complete.
The next quest is how do we approach this. The first step is to identify the end points, what we need to send and what we expect to get back. The two that we expect to implement are both on the receiver side. On the sender's side we need to implement a module that will init this flow and take either null or a single verifiable credential to send to the remote server.
For /presentations/available
, on the sender's side there's not much that we need to do. We can pretty much copy the example as-is, and then send it to the receiver. On the receiver's side of things we want two issues that need to address. First is the domain, this value looks like it's not really needed or used at all. Since it's the domain of the url which the sender is sending to anyways. So we can be lazy and put in the placeholder of "my-domain" to ignore this value because as far as I can can it's not doing anything.
The challenge is a slightly different story. We need to generate it, store it, and then either have it be consumed if it's used, or have it automatically be deleted after a certain number of seconds. The easy approach would be to do this in code, but I think it would be safer to do it with redis.
Edit: I'm getting trolled by redis, where the client always returns true even if the key doesn't exist in the store. So I'm going to do a simpler version of setting a global variable and checking against it.
The first pass of this was addressed with https://github.com/WebServiceDevelopment/PrivateInvoice/pull/14. The next steps will be move invoices and status messages over to the presentation end points as well.
Status messages were moved to presentations in https://github.com/WebServiceDevelopment/PrivateInvoice/pull/19. Remaining issues will be addressed in https://github.com/WebServiceDevelopment/PrivateInvoice/issues/15.
Abstract
Once we have the same Invoice distributed across two nodes, we will need to manage the state between them.
The flow for an Invoice is after send, the invoice can either be confirmed, or returned. If the invoice is returned, the seller will be required to amend and resend the invoice as a new invoice, or nullify it. In both cases the existing Invoice will be effectively nullified, and the buyer's node will be informed of the timing the Invoice has been nullified either in the case of recreate, or trashed.
If the invoice is confirmed by the buyer, the invoice will be put in the state of
Confirmed
for the buyer, andAwait Payment
for the seller.The seller will then have the option to return the Invoice back to the
unconfirmed
state, or make a payment on the invoice. A payment must be made with Ethereum, and will be reported back to the seller with the transaction hash to update the state toPaid
for both parties.After an Invoice has been marked as
Paid
, either party can move the Invoice toArchived
independently of the other party which will indicate the seller or buyer has marked the Invoice as resolved, and only needs a read only copy for records.For now we will describe this process as an exchange of presentations to update the status of a specific Invoice between Nodes. Potentially this could be better implement Baseline Protocol. More investigation into the source code, or documentation would be required to implement this correctly.
Data Structure
The closest status update schema we have is PGA Status Message.
With the case of invoices, we should try to adapt to the schemas are defined there. In the case of our invoice update message, it's niche enough that it would not cause conflict and we could provide our own enums and attribute names. We will map to an existing message type, and ivestigate the baseline protocol before opening a Pull Request on this front.
Disputing an Invoice
When a buyer has received an invoice, the two options they have are to
Confirm
it orDispute
it. Disputing the invoice effectively acts as a return to sender, for the seller to either amend or nullify the invoice.Confirming an Invoice
The other option is to confirm an invoice, where the buyer has confirmed the validity of the invoice and shows intent to make payment on the invoice.
Unconfirm Invoice
If an invoice has been confirmed, the buyer can choose to unconfirm the invoice in cases where an issue with the invoice was discovered before payment.
Withdraw an Invoice
If a seller has recognized a mistake with their invoice, they can withdraw it on the condition that it has not yet been confirmed.
Make Payment on an Invoice
The process for making a payment on an invoice is described in its own issue: https://github.com/WebServiceDevelopment/PrivateInvoice/issues/7
Archive an Invoice
Archiving an invoice happens independently of the other party. After an invoice has been paid, each party can leave it in their
Paid
tray until they have no need to actively reference the invoice, and move into theArchive
folder on their respective node.