Skip to content

Commit

Permalink
Merge pull request #91 from bosonprotocol/add-handlers-post-message
Browse files Browse the repository at this point in the history
create communication channel betwwen redemption widget and hosting web page
  • Loading branch information
levalleux-ludo authored Nov 20, 2023
2 parents 1801efa + 35f0eea commit af1c68c
Show file tree
Hide file tree
Showing 17 changed files with 718 additions and 45 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions docs/redemption-widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ When using the Redeem Button, as shown above, the parameters must be passed as H
| exchangeState | data-exchange-state | no | "Committed" | State of the exchanges when shown in the Select Exchange step. Relevant when widgetAction is SELECT_EXCHANGE. | ```"Redeemed"```
| showRedemptionOverview | data-show-redemption-overview | no | true | set to 'false' to skip the Redemption Overview (first step in the [user flow](./redemption-widget/default-redemption-flow.md)) | ```false```
| deliveryInfo | data-delivery-info | no | none | specify the delivery details that shall prefill the Redeem form, or be recapped on Confirm Redeem step. | ```'{"name":"TITI","streetNameAndNumber":"1 grand place","city":"LILLE","state":"NORD","zip":"59000","country":"FR","email":"toto@mail.com","phone":"+33123456789"}'```
| sendDeliveryInfoThroughXMTP | data-send-delivery-info-XMTP | yes | none | whether the widget should send the delivery information to the seller via XMTP | `true`
| targetOrigin | data-target-origin | no | none | If set, the widget will send frontend messages (`boson-delivery-info`, `boson-redemption-submitted` and `boson-redemption-confirmed`) to this origin when appropriate | `"https://myshop.com"`
| shouldWaitForResponse | data-wait-for-response | no | none | whether the widget should wait for a response (`boson-delivery-info-response`) to the deliveryInfo message (`boson-delivery-info`). If false, the widget does not wait and progress further with the redemption flow | `false`
| postDeliveryInfoUrl | data-post-delivery-info-url | no | none | this is the URL to which the widget will post the ***DeliveryInfo*** HTTP request with the delivery Details (see [Redemption with 3rd party eCommerce backend](./redemption-widget/backend-redemption-flow.md)) | ```"https://myshop.com/deliveryInfo"```
| postDeliveryInfoHeaders | data-post-delivery-info-headers | no | none | optionally specifies some request headers that must be added to the ***DeliveryInfo*** HTTP request | ```'{"authorization":"Bearer eyJhbGciOiJIUzL1Ni2sInR5cCI6IkpXVCJ7","another-header":"*****"}'```
| postRedemptionSubmittedUrl | data-post-redemption-submitted-url | no | none | this is the URL to which the widget will post the ***RedemptionSubmitted*** HTTP request with the delivery Details | ```"https://myshop.com/redemptionSubmitted"```
Expand All @@ -127,6 +130,7 @@ Hereafter are detailed examples of the redemption flows supported by the widget.
- [Default redemption flow](./redemption-widget/default-redemption-flow.md)
- [Marketplace redemption flow](./redemption-widget/marketplace-redemption-flow.md)
- [Redemption with 3rd party eCommerce backend](./redemption-widget/backend-redemption-flow.md)
- [Redemption with frontend messaging](./redemption-widget/frontend-redemption-flow.md)

The redemption widget can also support other usecases:
- [Default cancellation flow](./redemption-widget/default-cancellation-flow.md)
Expand Down
7 changes: 5 additions & 2 deletions docs/redemption-widget/backend-redemption-flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@

This flow supposes a 3r-party eCommerce system is used to manage the redemption.

Compared to the [default flow](./default-redemption-flow.md), the main difference is that the delivery information filled by the user is sent via an HTTP POST request to a backend URL passed as a parameter (***postDeliveryInfoUrl***), instead of being sent to the Seller via XMTP.
Compared to the [default flow](./default-redemption-flow.md), the main difference is that the delivery information filled by the user is sent via an HTTP POST request to a backend URL passed as a parameter (***postDeliveryInfoUrl***).

*Note: sending the delivery information to XMTP can still be activated, depending on the value given to the `sendDeliveryInfoThroughXMTP` widget parameter.*

When replying to the postDeliveryInfo request, it's possible for the backend to decide if the widget should continue to the next step or not. This can be useful:
- in case the delivery details can't be validated
- in case the delivery details are not valid, in which case the user can provide other delivery details, or choose to cancel the voucher
- in case the flow needs to be interrupted, for instance, to perform Shipping Cost checkout before the on-chain transaction is submitted

In addition, the on-chain Redeem transaction submission and confirmation can be relayed to the backend using respective parameters ***postRedemptionSubmittedUrl*** and ***postRedemptionConfirmedUrl***.
Expand All @@ -22,6 +24,7 @@ If required, every backend request can contain specific headers (for instance us
| ------ | -------- | ------- |
| configId | yes | the Boson Protocol environment the widget is linked to (see [Boson Environments](../boson-environments.md)) |
| sellerIds | no | specifies the list of sellerIds to filter the exchanges shown to the user ([step #3 below](#Select-Exchange))
| sendDeliveryInfoThroughXMTP | yes | whether the widget should send the delivery information to the seller via XMTP
| postDeliveryInfoUrl | yes - in this present case | this is the URL to which the widget will post the ***DeliveryInfo*** HTTP request with the delivery Details ([step #6.2 below](#postDeliveryInfo))
| postDeliveryInfoHeaders | no | specifies some request headers that must be added to the ***DeliveryInfo*** HTTP request
| postRedemptionSubmittedUrl | no | this is the URL to which the widget will post the ***RedemptionSubmitted*** HTTP request with the delivery Details ([step #6.4 below](#postRedemptionSubmitted))
Expand Down
171 changes: 171 additions & 0 deletions docs/redemption-widget/frontend-redemption-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
[![banner](../assets/banner.png)](https://bosonprotocol.io)

< [Redemption Widget](../redemption-widget.md)

## Redemption Flow with frontend

This flow allows the widget embedded in a web page as an iFrame, to send the redemption information and the transaction progress to the hosting web page.

Compared to the [Redemption flow with backend](./backend-redemption-flow.md), the main difference is that the delivery information filled by the user is sent to the hosting web page using cross-origin communication featured by the web browser (see [reference](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)).

Replying to the `boson-delivery-info` message with a `boson-delivery-info-response` one, is possible for the web page to decide if the widget should continue to the next step or not. This can be useful:
- in case the delivery details are not valid, in which case the user can provide other delivery details, or choose to cancel the voucher
- in case the flow needs to be interrupted, for instance, to perform Shipping Cost checkout before the on-chain transaction is submitted.

In addition, the on-chain Redeem transaction submission and confirmation can be relayed to the frontend using appropriate messages (`boson-redemption-submitted` and `boson-redemption-confirmed`).

### Widget Parameters

| parameter | required | purpose |
| ------ | -------- | ------- |
| configId | yes | the Boson Protocol environment the widget is linked to (see [Boson Environments](../boson-environments.md)) |
| sellerIds | no | specifies the list of sellerIds to filter the exchanges shown to the user ([step #3 below](#Select-Exchange))
| sendDeliveryInfoThroughXMTP | yes | whether the widget should send the delivery information to the seller via XMTP
| targetOrigin | yes - in this present case | If set, the widget will send frontend messages (`boson-delivery-info`, `boson-redemption-submitted` and `boson-redemption-confirmed`) to this origin when appropriate
| shouldWaitForResponse | no | whether the widget should wait for a response (`boson-delivery-info-response`) to the deliveryInfo message (`boson-delivery-info`). If false, the widget does not wait and progress further with the redemption flow

### Main Flow (continuous)

When the Seller website activates the Redemption Widget with the adequate options, the user is guided through the following steps.

1. Wallet connection (if needed)

![Wallet connection](./../assets/redemption-widget/1-wallet-connection.png)
In case the user wallet is already connected, this step is skipped

<div id="showRedemptionOverview"></div>
2. Redemption Overview

![Redemption Overview](./../assets/redemption-widget/2-redemption-overview.png)

<div id="Select-Exchange"></div>
3. Select Exchange

![Select Exchange](./../assets/redemption-widget/3-select-exchange-filtered.png)

Committed exchanges are shown to the user. These are the rNFT owned by the wallet and that the user can redeem. In this example, the ***sellerIds*** parameter is used to show only the exchanges of a unique seller.

The user selects an rNFT and clicks it to show the "Exchange Card". Optionally, the Redeem button can be directly clicked, which leads the user directly to the Redeem Form

4. Exchange Card

![Exchange Card](./../assets/redemption-widget/4-exchange-card-2.png)
This view shows details about the exchange, and presents a Redeem button (in case the rNFT is redeemable) that the user can click to jump to the Redeem Form

5. Redeem Form

![Redeem Form](./../assets/redemption-widget/5-redeem-form.png)
The user fills in the delivery details to get their physical item delivered

6. Redeem Confirmation

![Redeem Confirmation](./../assets/redemption-widget/6-redeem-confirmation-frontend.jpg)

6.1. User Signature

First, the user is asked to sign the delivery details with their wallet to allow the backend to verify the request is coming from the real buyer.

<div id="postDeliveryInfo"></div>
6.2 Post `boson-delivery-info` message

Once the message is signed by the wallet, a frontend `boson-delivery-info` message is sent to the `targetOrigin`, containing the delivery information, details about the redeemed exchange, and the user signature.

The receiving frontend might verify, from the signature, that the signer is the buyer wallet, then store the delivery information for this exchange.

If OK and if `shouldWaitForResponse`, it must reply posting a `boson-delivery-info-response` message with the following content: ```{accepted: yes, resume: yes}```.
- ```accepted: yes``` means the delivery information is accepted so the redemption can be confirmed
- ```resume: yes``` means the widget can go through the next step to get the redemption confirmed

6.3 Sign/Send Redemption Transaction

Now the user is asked to click on **Confirm Redemption** to send the Redeem transaction on-chain (to be signed/confirmed by the user with their wallet)

<div id="postRedemptionSubmitted"></div>
6.4 Post `boson-redemption-submitted` message

Once the Redeem transaction is signed by the wallet and sent on-chain, a frontend `boson-redemption-submitted` message is sent to the `targetOrigin`, containing the details about the redeemed exchange and the expected transaction hash *(Note: the hash of the real transaction may be different than the expected one, for instance in case the wallet resubmits with higher fees, to speed it up)*.

No response to this message is expected by the widget.

7. Congratulations
![Congratulations](./../assets/redemption-widget/7-congratulations-3.jpg)
Once the Redeem transaction is confirmed on-chain, a congratulation message is shown to the user.

<div id="postRedemptionConfirmed"></div>
Once the Redeem transaction is confirmed on-chain, a frontend `boson-redemption-confirmed` message is sent to the `targetOrigin`, containing the details about the redeemed exchange, the effective transaction hash and the blockNumber where the transaction has been validated.

No response to this message is expected by the widget.

The user can:
- close the widget
- go back to select another rNFT.

#### Complete diagram

![Redemption Widget - Redemption Widget Flow with callbacks (continuous)](../assets/redemption-widget/Redemption%20Widget%20-%20Frontend%20redemption%20flow.jpg)

### Interrupted Flow

It is possible, for the hosting web page, to interrupt the redemption flow after the redemption information is set by the user and before the redeem transaction is sent on-chain.

This is useful to allow full redemption to include an additional step or verification between these 2 steps.

Interruption is triggered by the `boson-delivery-info-response` response the `targetOrigin` sends back to the widget when replying to the `boson-delivery-info` message ([step #6.2 above](#postDeliveryInfo)).


6. Redeem Confirmation

![Redeem Confirmation](./../assets/redemption-widget/6-redeem-confirmation-frontend-interrupted.jpg)

6.1. User Signature

Identical to the continuous flow above.

6.2 Post `boson-delivery-info` message (interrupted)

As for the continuous flow, a frontend `boson-delivery-info` message is sent to the `targetOrigin`, containing the delivery information, details about the redeemed exchange, and the user signature. When `shouldWaitForResponse` is true, the widget waits for a response message (`boson-delivery-info-response`) which is used to interrupt the flow, as follow.
- ```accepted: yes``` means the delivery information is accepted so the redemption can be confirmed
- ```resume: NO``` means the widget shall interrupt and not go on with the following step

The next step is, for the frontend, to close/hide the widget, while dealing with the delivery information.

When done, the widget can be called again, with adequate parameters, to end the redemption flow.

### End of Redemption confirmation, following an interrupted flow

To start the widget directly on the Redemption Confirmation flow, the following parameters shall be set:

| option | required | purpose |
| ------ | -------- | ------- |
| configId | yes | the Boson Protocol environment the widget is linked to (see [Boson Environments](../boson-environments.md)) |
| exchangeId | yes - in this present case | the ID of the exchange being redeemed.
| widgetAction | yes - in this present case | **"CONFIRM_REDEEM"**: the action the widget is going to jump on
| showRedemptionOverview | yes - in this present case | **false**: to skip the Redemption Overview ([step #2 above](#showRedemptionOverview))
| deliveryInfo | yes - in this present case | the delivery details that have been validated by the eCommerce backend for this redemption, shown to the user before they confirm the redemption.
| targetOrigin | yes - in this present case | If set, the widget will send frontend messages (`boson-delivery-info`, `boson-redemption-submitted` and `boson-redemption-confirmed`) to this origin when appropriate
| shouldWaitForResponse | no | whether the widget should wait for a response (`boson-delivery-info-response`) to the deliveryInfo message (`boson-delivery-info`). If false, the widget does not wait and progress further with the redemption flow

6. Redeem Confirmation (follow-up)

![Redeem Confirmation](./../assets/redemption-widget/6-redeem-confirmation-frontend-resume.jpg)

6.3 Sign/Send Redemption Transaction

Similarly to the continuous flow, the user is asked to click on **Confirm Redemption** to send the Redeem transaction on-chain (to be signed/confirmed by the user with their wallet)

*Note that the user can decide to go back to the previous step to Edit the delivery information, that will replay the step 5 and 6 of the redemption flow (possibly interrupted, depending on the frontend response)*

6.4 Post `boson-redemption-submitted` message

Identical to the continuous flow.

7. Congratulations

![Congratulations](./../assets/redemption-widget/7-congratulations-3.jpg)
Identical to the continuous flow.

#### Complete diagram

![Redemption Widget - Redemption Widget Flow with callbacks (interrupted)](../assets/redemption-widget/Redemption%20Widget%20-%20Redemption%20flow%20with%20frontend%20messages%20(interrupted).jpg)


Loading

0 comments on commit af1c68c

Please sign in to comment.