Feral File (FF) maintains the sale and is in charge of determining the sale price, sale items and royality amounts based on the sale types (**normal** sale or **auction** sale). The contract is only to facilitates payments and tokens distributing according to the sale instrument from FF.
### Sale Lock
To ensure both crypto user and credit card user both have the same opportunity to process the sale, we introduce a sale lock into the system. It is a **3** minutes lock that starts counting down when the purchase process begin. Due to the limit of signature revealing, the purchasing lock will persist until the purchase is fulfill or the time count down to zero. That means each user can only perform a purchasing flow at a time.
To ensure the contract function also align with the server lock, there is a expiry time of each sale instrument data. The expiry will set to the end time of the lock for each sale.
### Pay in Crypto
In crypto payments, the collectors will get sale instrument data from FF server. The data includes target tokens in a particular sale and the price of the sale. Users use the data to construct payment transactions and submit it to the blockchain to pay and get tokens directly.
```mermaid
sequenceDiagram
autonumber
User ->>+ FF : Collect
FF ->> +FF Server: Collect API call
FF Server ->> FF Server: Lock edition
FF Server ->> FF Server: Summarize the sale data
FF Server ->>+ Vault : Sign the sale data
rect rgb(223, 191, 255)
note left of Vault : Vault
note right of Vault : An address set to<br> signer in contract
Vault -->>- FF Server : signature
end
FF Server -->>- FF : transaction data <br> (purchasing instrument) <br> for buyArtworks
FF ->> User: Prompt wallet to sign <br>and broadcast the transaction
User ->>+ Blockchain: Submit buyArtworks TX
Blockchain->>Blockchain: verify the signature from FF
Blockchain->>Blockchain: check the fund and transfer tokens
Blockchain -->>- FF : TX ID
FF ->>+ Blockchain: Watch TX ID
Blockchain -->>- FF : Minted or Timeout
FF -->>- User : Purchase completed / failed
```
### Pay by Credit card
In the credit card payment, the lock mechanism is the same. Instead of submit transaction directly to the blockchain, FF server will submit the sale transaction for users. Users using credit card pay will be an addition estimated fee for the blockchain transaction. The remaining fee will refund to users if they are not totally spent.
If the a credit card payment is confirmed after its sale lock expired, FF server will not send to purchasing transaction and will return all funds back to the user.
```mermaid
sequenceDiagram
autonumber
rect rgb(191, 223, 255)
note right of User : Credit card payment
User ->>+ FF : Collect
FF ->> +FF Server: Collect API call
FF Server ->> FF Server: Lock edition
FF Server ->> FF Server: Cacluate the price in USD
FF Server -->>- FF: Price
FF -->>- User: Sale page
User ->>+ FF: Pick as gas for the sale tx
FF ->> +FF Server: Calculate the total price
FF Server -->>- FF: total price
FF -->>- User: Credit card form
end
User ->> Stripe : User pay with credit card
Stripe ->>+ FF Server: Paid webhook
FF Server ->>+ Vault : Sign the sale data
Vault -->>- FF Server : signature
rect rgb(223, 332, 255)
note right of FF Server : ITX service
FF Server ->>+ ITX : transaction data for buyArtworks
ITX ->>+ Exhibition Contract: Submit buyArtworks TX with 0 ether
ITX ->> ITX: Keep higher gas price until confirmed
rect rgb(223, 132, 255)
note right of Exhibition Contract : Contract
Exhibition Contract ->>+ Vault Contract : pay(sale_price)
Vault Contract -->> Vault Contract : Check msg.sender from EC
Vault Contract -->>- Exhibition Contract : sale_price ether
Exhibition Contract ->> Exhibition Contract: buyArtworks logic
end
ITX -->>- FF Server : ITX TxID
FF Server ->>+ ITX : Watch ITX TxID
ITX -->>- FF Server : TxID
end
FF Server ->>+ Exhibition Contract : Watch TxID
Exhibition Contract -->>- FF Server : Succeed or Failed
FF Server -> Stripe: Charge order <br> (full amount for minted) <br> (gas amount for timeout)
Stripe --> FF Server: Webhook
FF Server -->>- FF: Update the result <br> (minted / timeout)
FF -->> User : Purchase completed / failed
```