Project

General

Profile

Marketplace » History » Revision 34

Revision 33 (Ryan Supawarapong, 02/23/2026 02:11 AM) → Revision 34/36 (Ryan Supawarapong, 02/23/2026 08:20 AM)

# Marketplace 

 There are the following API: 
 1. [Lists](#Lists) 
 2. [Posted](#Posted) 
 3. [Interested](#Interested) 
 4. [Get Interested](#Get-Interested) 

 ## Diagram 
 <img src="market_place.png"><br> 
 ``` 
 title Market Place 

 actor "customer" as c 
 actor "owner" as o 
 actor "admin" as a 
 participant "frontend" as fe 
 participant "admin" as adm 
 participant "backend" as be 
 database "database" as db 
 participant "notification" as n 

 o->fe: post sell asset 
 fe->be: verify asset and quantities 
 be<->db: query database 
 be->fe: true/false 
 fe->c: true: dispaly new post 
 c->fe: click "interest" button 
 fe->be: update status and count down 15 minutes 
 be<->db: update database 
 be->fe: true/false 
 fe->c: show status "locked" 
 be->n: update payment notification 
 n->c: email bank account info and payment noti within 15 minutes 
 c->n: click confirm payment 
 c->fe: totp to confirm payment 
 fe->be: update payment 
 fe->fe: update status to "pending payment confirm" 
 be<->db: update database 
 be->n: update payment confirmation 
 n->o: email payment acknowledge confirmation and pay service fees 
 o->n: click confirm service fees 
 o->fe: totp to confirm service fees 
 fe->be: update service fees transaction 
 fe->fe: update status to "pending service fees confirm" 
 be<->db: update database 
 be->n: send service fees notification 
 n->a: get noti for new service fees 
 adm<->be: get new service fees 
 a->adm: verify service fees 
 adm<->be: show service fees 
 a->adm: approved service fees 
 adm->be: update service fees status 
 be<->db: update database 
 be->n: send notification 
 n->o: get noti service fees approved 
 fe->fe: update status to "complete" 
 ``` 

 ## API route 

 ## Lists 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/customer/marketplace/lists` | 
 | Request Type | `GET` | 
 | Content-Type | `application/json` | 
 | Authorization | `bearer ...` | 

 ### Request Body 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | - | - | - | no body | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"success"` | yes | 
 | data | object | `{"transactions":[...]}` | yes | 
 | data.transactions | array<object> | `[{"id":1,"transactionId":"TXN_123",...}]` | yes | 
 | data.transactions[].id | number | `1` | no (`omitempty`) | 
 | data.transactions[].sellerCode | string | `"90000005"` | no | 
 | data.transactions[].sellerName | string | `"First Last"` | no | 
 | data.transactions[].assetCode | string | `"ASSET001"` | no | 
 | data.transactions[].assetName | string | `"Asset 001"` | no | 
 | data.transactions[].assetShortName | string | `"A001"` | no | 
 | data.transactions[].quantity | number | `10` | no | 
 | data.transactions[].price | number | `10.01` | no | 
 | data.transactions[].totalAmount | number | `100.10` | no | 
 | data.transactions[].currency | string | `"THB"` | no | 
 | data.transactions[].status | number | `1` | no | 

 ### Error Response 

 #### Internal Server Error (500) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"error"` | yes | 
 | message | string | `"database error"` | yes | 

 --- 

 ## Posted 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/customer/marketplace/posted` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 
 | Authorization | `bearer ...` | 

 

 ### Request Body 

 > `customerCode` and `customerName` are injected from auth token by handler, not required from client body. 

 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | assetCode | string | `"ASSET001"` | yes | 
 | assetName | string | `"Asset 001"` | yes | 
 | assetShortName | string | `"A001"` | yes | 
 | customerName | string | `"firstname Lastname"` | yes | 
 | quantity | number | `5` | yes (`> 0`) | 
 | price | number | `10` | yes (`> 0`) | 
 | totalAmount | number | `50` | yes (`> 0`) | 

 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"success"` | yes | 

 ### Error Response 

 #### Bad Request (400) - bind error 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"failed"` | yes | 
 | data | object | `{"error":"...bind error..."}` | yes | 
 | data.error | string | `"code=400, message=..."` | yes | 

 #### Unauthorized (401) - token missing/invalid 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"failed"` | yes | 
 | data | object | `{"error":"invalid token claims"}` | yes | 
 | data.error | string | `"invalid token claims"` | yes | 

 #### Bad Request (400) - validation error 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"failed"` | yes | 
 | data | object | `{"errors":{"assetCode":"required"}}` | yes | 
 | data.errors | object | `{"field":"message"}` | yes | 

 #### Internal Server Error (500) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"error"` | yes | 
 | message | string | `"internal error"` | yes | 

 --- 

 ## Interested 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/customer/marketplace/interested` | 
 | Request Type | `POST` | 
 | Content-Type | `application/json` | 
 | Authorization | `bearer ...` | 

 ### Request Body 


 | Key | Type | Example | Required | 
 |---|---|---|---| 
 | assetCode | string | `"ASSET001"` | yes | 
 | assetName | string | `"Asset 001"` | yes | 
 | assetShortName | string | `"A001"` | yes | 
 | quantity | number | `5` | yes (`> 0`) | 
 | price | number | `10` | yes (`> 0`) | 
 | totalAmount | number | `50` | yes (`> 0`) | 
 | transactionId | string | `"TXN_123"` | yes | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"success"` | yes | 
 | data | object | `{"emailID":"emailID"}` | yes | 
 | data.emailID | string | `"emailID"` | yes | 

 ### Error Response 

 #### Bad Request (400) - bind error 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"failed"` | yes | 
 | data | object | `{"error":"...bind error..."}` | yes | 
 | data.error | string | `"code=400, message=..."` | yes | 

 #### Unauthorized (401) - token missing/invalid 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"failed"` | yes | 
 | data | object | `{"error":"invalid token claims"}` | yes | 
 | data.error | string | `"invalid token claims"` | yes | 

 #### Bad Request (400) - validation error 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"failed"` | yes | 
 | data | object | `{"errors":{"transactionId":"required"}}` | yes | 
 | data.errors | object | `{"field":"message"}` | yes | 

 #### Internal Server Error (500) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"error"` | yes | 
 | message | string | `"internal error"` | yes | 

 --- 

 ## Get Interested 

 | Type | Value | 
 |---|---| 
 | API Path | `/api/v1/customer/marketplace/interested/lists` | 
 | Request Type | `GET` | 
 | Content-Type | `application/json` | 
 | Authorization | `bearer ...` | 

 ### Success Response (200) 

 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"success"` | yes | 
 | data | object | `{"interestedList":[...]}` | yes | 
 | data.interestedList | array<object> | `[{"id":"TXN_123",...}]` | yes | 
 | data.interestedList[].id | number | `1` | no (`omitempty`) | 
 | data.interestedList[].sellerCode | string | `"90000005"` | no | 
 | data.interestedList[].sellerName | string | `"First Last"` | no | 
 | data.interestedList[].buyerCode | string | `"90000004"` | no | 
 | data.interestedList[].buyerName | string | `"First Last2"` | no | 
 | data.interestedList[].assetCode | string | `"ASSET001"` | no | 
 | data.interestedList[].assetName | string | `"Asset 001"` | no | 
 | data.interestedList[].assetShortName | string | `"A001"` | no | 
 | data.interestedList[].quantity | number | `10` | no | 
 | data.interestedList[].price | number | `10.01` | no | 
 | data.interestedList[].totalAmount | number | `100.10` | no | 
 | data.interestedList[].currency | string | `"THB"` | no | 
 | data.interestedList[].status | number | `1` | no | 

 ### Error Response 

 #### Unauthorized (401) - token missing/invalid 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"failed"` | yes | 
 | data | object | `{"error":"invalid token claims"}` | yes | 
 | data.error | string | `"invalid token claims"` | yes | 

 #### Internal Server Error (500) 
 | JSON Path | Type | Example | Required | 
 |---|---|---|---| 
 | status | string | `"error"` | yes | 
 | message | string | `"internal error"` | yes |