# TWIP API *(Version 0.10)*
## Authenticate
Add header:
`Authorization: Bearer 94a3f91f-0751-48ef-b9fb-6265a02fbfa7|T9tnNB5t1vclAYhcqbIswjHfdwU26JKCPyjYkHNY`
## Create User Manually
``` php
$user = App\Models\User::factory()->create()
$wallet = Blockchain::with('tron')->createWallet();
$key = config('app.user_wallet_key') . $user->email;
$iv = hex2bin(hash('sha256', $key));
$user->wallets()->create([
'network' => 'TRON',
'address' => $wallet['address'],
'private_key' => LazyCrypt::withIv($iv)->encrypt($wallet['hex_private_key']),
]);
$user->assets()->createMany([
['asset' => 'TWIP'],
['asset' => 'TWIG'],
);
```
## Create Company Manually
``` php
$company = App\Models\Company::create([
'name' => 'XXX有限公司',
'address' => '台北市西湖區瑞光路1號',
'contact_phone' => '+8860198765432',
'contact_email' => 'hello@example.com',
]);
$wallet = Blockchain::with('tron')->createWallet();
$key = $company->contact_email . config('app.company_wallet_key');
$iv = hex2bin(hash('sha256', $key));
$wallet = $company->wallets()->create([
'network' => 'TRON',
'address' => $wallet['address'],
'private_key' => LazyCrypt::withIv($iv)->encrypt($wallet['hex_private_key']),
]);
```
## Create Store Manually
``` php
$store = App\Models\Store::create([
'name' => '店名',
'address' => '台北市大安區基隆路100號',
'discount_type' => 'fixed',
'discount_value' => 0,
'contact_phone' => '+886900123456',
'contact_email' => 'test@example.com',
]);
$wallet = Blockchain::with('tron')->createWallet();
$exploded = explode('@', $store->contact_email);
$key = $exploded[0] . config('app.store_wallet_key') . $exploded[1];
$iv = hex2bin(hash('sha256', $key));
$wallet = $store->wallets()->create([
'network' => 'TRON',
'address' => $wallet['address'],
'private_key' => LazyCrypt::withIv($iv)->encrypt($wallet['hex_private_key']),
]);
$store->assets()->create([
'asset' => 'TWIP',
'wallet_id' => $wallet->id,
]);
```
## Error Codes
### User
|code|description|
|--|--|
|user_invalid_status_or_verified|狀態異常,該用戶不存在或該用戶已通過驗證|
|user_request_otp_too_often|取得驗證碼次數過於頻繁|
|user_invalid_otp|輸入錯誤的驗證碼|
|user_otp_expired|驗證碼逾期|
|user_email_was_taken|該信箱已被使用|
|user_unauthorized_bank_account|銀行帳號未驗證通過|
|user_bank_account_was_verified|銀行帳號已驗證過|
|user_bank_account_was_taken|銀行帳號已被使用|
|user_invalid_fund_password|交易密碼錯誤|
|user_failed|未預期的失敗|
### Order
|code|description|
|--|--|
|order_invalid_fund_password|輸入錯誤的資金密碼|
|order_insufficient_voucher_of_system|系統可售出的禮券數量不足|
|order_insufficient_voucher_of_user|用戶可使用的禮券數量不足|
|order_invalid_otp|輸入錯誤的驗證碼|
|order_otp_session_expired|驗證碼逾期|
|order_failed|未預期的失敗|
### Account
|code|description|
|--|--|
|account_invalid_wallet|無法取得錢包|
### Withdrawal
|code|description|
|--|--|
|withdrawal_insufficient_balance|提領的餘額不足|
|withdrawal_invalid_status|狀態異常|
|withdrawal_invalid_fund_password|輸入錯誤的資金密碼|
|withdrawal_request_otp_too_often|取得驗證碼次數過於頻繁|
|withdrawal_invalid_otp|輸入錯誤的驗證碼|
|withdrawal_otp_expired|驗證碼逾期|
|withdrawal_broadcast_txhash_failed|廣播雜湊簽章至區塊鏈網路失敗|
### Store
|code|description|
|--|--|
|store_insufficient_balance_of_user|用戶可消費的餘額不足|
|store_invalid_order_status|訂單狀態異常|
|store_request_otp_too_often|取得驗證碼次數過於頻繁|
|store_checkout_broadcast_txhash_failed|取得驗證碼次數過於頻繁|
|store_invalid_otp|輸入錯誤的驗證碼|
|store_otp_expired|驗證碼逾期|
### Card
|code|description|
|--|--|
|card_registered_by_myself|卡片已被本人註冊|
|card_registered_by_someone|卡片已被其他人註冊|
|card_request_otp_too_often|取得驗證碼次數過於頻繁|
|card_invalid_status_or_verified|卡片不存在或已通過驗證|
|card_invalid_otp|驗證碼異常|
|card_otp_expired|驗證碼逾期|
|card_reach_maximum_limited|已達卡片最大註冊上限,限至為 10 張|
### Password
|code|description|
|--|--|
|password_invalid_user|用戶不存在|
|password_reset_throttled|短時間重設的次數過多次|
|password_invalid_token|異常的重設 token|
|password_failed|未預期的失敗|
### Redeem
|redeem_insufficient_balance|提領的餘額不足|
|redeem_request_otp_too_often|取得驗證碼次數過於頻繁|
|redeem_invalid_otp|輸入錯誤的驗證碼|
|redeem_invalid_fund_password|交易密碼錯誤|
|redeem_otp_expired|驗證碼逾期|
|redeem_invalid_status|狀態異常|
## State Machine
### User
``` plantuml
@startuml
hide empty description
[*] --> mail_pending
mail_pending --> mail_verified
mail_verified --> sms_pending
sms_pending --> sms_verified
sms_verified --> password_setup
password_setup --> wallet_generated
wallet_generated --> bank_pending
bank_pending --> bank_verified
bank_verified --> [*]
@enduml
```

### Buying Order
``` plantuml
@startuml
hide empty description
[*] --> created
created --> otp_pending
otp_pending --> otp_verified
otp_verified --> unpaid
unpaid --> paid
paid --> token
paid --> untoken
untoken --> token
token --> [*]
otp_pending --> expired
otp_verified --> expired
unpaid --> expired
@enduml
```

### Swapping Order
``` plantuml
@startuml
hide empty description
[*] --> created
created --> otp_pending
otp_pending --> otp_verified
otp_verified --> token
otp_verified --> failed
token --> complete
otp_pending --> expired
failed --> [*]
complete --> [*]
@enduml
```

### Shopping Order
``` plantuml
@startuml
hide empty description
[*] --> created
created --> otp_pending
otp_pending --> otp_verified
otp_verified --> confirming
confirming --> paid
confirming --> failed
otp_pending --> expired
paid --> [*]
failed --> [*]
@enduml
```

### Withdrawal
``` plantuml
@startuml
hide empty description
[*] --> created
created --> otp_pending
otp_pending --> otp_verified
otp_verified --> confirming
confirming --> confirmed
confirming --> failed
otp_pending --> expired
confirmed --> [*]
failed --> [*]
@enduml
```

## Project Initiation
1. Create companies and wallets.
``` php
function createWallet($company)
{
$wallet = Blockchain::with('tron')->createWallet();
$key = $company->contact_email . config('app.company_wallet_key');
$iv = hex2bin(hash('sha256', $key));
$company->wallets()->create([
'network' => 'TRON',
'address' => $wallet['address'],
'private_key' => LazyCrypt::withIv($iv)->encrypt($wallet['hex_private_key']),
]);
Blockchain::with('tron')->activateAccount($wallet['address']);
}
foreach (['tungkai', 'huanyu'] as $name) {
$company = App\Models\Company::create([
'name' => $name,
'address' => '台北市西湖區瑞光路1號',
'contact_phone' => '+8860198765432',
'contact_email' => 'hello@example.com',
]);
createWallet($company);
}
```
2. Create bank accounts for company
``` php
$companies = Company::get();
$companies[0]->availableAccounts()->create([
'bank_name' => '彰化銀行',
'branch_name' => '復興分行',
'account_name' => '香港商全金集成有限公司台灣分公司',
'bank_account' => '009-5251234567890',
]);
$companies[1]->availableAccounts()->create([
'bank_name' => '永豐銀行',
'branch_name' => '台北分行',
'account_name' => '香港商全金集成有限公司台灣分公司',
'bank_account' => '807-2241234567890',
]);
```
## API Doc
### Register
註冊流程:設定手機號碼 -> 驗證手機號碼 -> 設定信箱 -> 驗證信箱 -> 設定密碼
#### 1. 設定手機號碼
**Method:** POST
**Routing:** /api/v1/register/register_phone
**Authenticated:** FALSE
**Request Params:**
|name|required|description|
|--|--|--|
|country_code|N|手機國碼,採用 ISO 3166 ALPHA-2 格式。EX: TW, JP|
|phone|Y|手機號碼,可填入一般(0960123456)或者 e164 格式(+866960123456)|
|user_source|Y|用戶來源,僅接受參數:tungkai, huanyu|
**Response:**
```
{
"success": true
}
```
#### 2. 驗證手機號碼
**Method:** POST
**Routing:** /api/v1/register/verify_phone
**Authenticated:** FALSE
**Request Params:**
|name|required|description|
|--|--|--|
|country_code|N|手機國碼,採用 ISO 3166 ALPHA-2 格式。EX: TW, JP|
|phone|Y|手機號碼,可填入一般(0960123456)或者 e164 格式(+866960123456)|
|user_source|Y|用戶來源,僅接受參數:tungkai, huanyu|
|otp|Y|驗證碼|
**Response:**
```
{
"success": true
}
```
#### 3. 設定信箱
**Method:** POST
**Routing:** /api/v1/register/set_email
**Authenticated:** FALSE
**Request Params:**
|name|required|description|
|--|--|--|
|country_code|N|手機國碼,採用 ISO 3166 ALPHA-2 格式。EX: TW, JP|
|phone|Y|手機號碼,可填入一般(0960123456)或者 e164 格式(+866960123456)|
|user_source|Y|用戶來源,僅接受參數:tungkai, huanyu|
|email|Y|電子信箱|
**Response:**
```
{
"success": true
}
```
#### 4. 驗證信箱
**Method:** POST
**Routing:** /api/v1/register/verify_email
**Authenticated:** FALSE
**Request Params:**
|name|required|description|
|--|--|--|
|country_code|N|手機國碼,採用 ISO 3166 ALPHA-2 格式。EX: TW, JP|
|phone|Y|手機號碼,可填入一般(0960123456)或者 e164 格式(+866960123456)|
|user_source|Y|用戶來源,僅接受參數:tungkai, huanyu|
|email|Y|電子信箱|
|otp|Y|驗證碼|
**Response:**
```
{
"success": true
}
```
#### 5. 設定密碼
**Method:** POST
**Routing:** /api/v1/register/set_password
**Authenticated:** FALSE
**Request Params:**
|name|required|description|
|--|--|--|
|country_code|N|手機國碼,採用 ISO 3166 ALPHA-2 格式。EX: TW, JP|
|phone|Y|手機號碼,可填入一般(0960123456)或者 e164 格式(+866960123456)|
|user_source|Y|用戶來源,僅接受參數:tungkai, huanyu|
|email|Y|電子信箱|
|password|Y|用戶密碼|
|password_confirmation|Y|確認輸入的密碼|
**Response:**
```
{
"success": true
}
```
### Authenticate
#### 1. 登入
**Method:** POST
**Routing:** /api/v1/login
**Authenticated:** FALSE
**Request Params:**
|name|required|description|
|--|--|--|
|email|Y|用戶信箱|
|password|Y|用戶密碼|
|user_source|Y|用戶來源|
**Response:**
```
{
"data": {
"token": "94bd274d-bcee-4fa7-a96d-ad669a94cce7|M8NzEZ4QSKLljquLLmsKt9tg8kA7oUgytiInND1l",
"name": "Test King",
"email": "test@example.com",
"phone": "+886960123456",
"created_at": "2021-10-28T06:08:11.000000Z"
}
}
```
#### 2. 登出
**Method:** POST
**Routing:** /api/v1/logout
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"success": true
}
```
### Reset Password
#### 1. 忘記密碼
**Method:** POST
**Routing:** /api/v1/forgot-password
**Authenticated:** FALSE
**Request Params:**
|name|required|description|
|--|--|--|
|email|Y|用戶信箱|
|user_source|Y|用戶來源|
**Response:**
```
{
"success": true
}
```
#### 2. 以忘記密碼的 token 重設密碼
**Method:** POST
**Routing:** /api/v1/reset-password
**Authenticated:** FALSE
**Request Params:**
|name|required|description|
|--|--|--|
|token|Y|重設 token|
|email|Y|用戶信箱|
|password|Y|用戶密碼|
|password_confirmation|Y|確認用戶密碼|
|user_source|Y|用戶來源|
**Response: 成功**
```
{
"success": true
}
```
**Response: 用戶不存在**
```
{
"error": {
"message": "Failed: We can't find a user with that email address.",
"code": "password_invalid_user",
"type": "invalid_request_error"
}
}
```
**Response: 用戶存在,但其 token 無法對應到目標用戶**
```
{
"error": {
"message": "Failed: This password reset token is invalid.",
"code": "password_invalid_token",
"type": "invalid_request_error"
}
}
```
### Assets
#### 1. 取得個人數位資產
**Method:** GET
**Routing:** /api/v1/me/assets
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": [
{
"asset": "TWIP",
"free": 100,
"locked": 0
},
{
"asset": "TWIG",
"free": 200,
"locked": 0
}
]
}
```
**Example:**
```
curl --location --request GET 'https://stage-twip-api.goldalles.com/api/v1/me/assets' \
--header 'Accept: application/json' \
--header 'Authorization: Bearer 94a3f91f-0751-48ef-b9fb-6265a02fbfa7|T9tnNB5t1vclAYhcqbIswjHfdwU26JKCPyjYkHNY'
```
### Order
#### 1. 建立購買 TWIP 訂單
**Method:** POST
**Routing:** /api/v1/orders/buy
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|fund_password|Y|資金密碼,目前填入用戶密碼作替代|
|quantity|Y|轉換數量,範圍虛介在 10 ~ 10000000|
|payment_type|Y|付款方式,僅接受參數:atm, remittance|
|payout_account|Y|轉入指定帳號,僅接受帳號:006-1759717135270|
|remittance_name|N|匯款人。當 payment_type 為 remittance 時,該欄位必填|
**Response:**
```
{
"data": {
"id": "94a3f288-89ca-41a3-821e-1d19f81d7acf",
"quantity": 10,
"unit_price": 1,
"total_amount": 10,
"payout_account": "001-123456789",
"payment_type": "atm",
"status": "created"
}
}
```
#### 2. 驗證購買 TWIP 訂單
**Method:** POST
**Routing:** /api/v1/orders/{order}/verify
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|otp|Y|簡訊驗證碼|
**Response:**
```
{
"data": {
"id": "94a3f289-1eb4-4f19-93cf-c6f498703cf6",
"quantity": "141484927.8620000000",
"unit_price": "1000.0000",
"total_amount": "141484927862",
"payout_account": "003-123456789",
"payment_type": "atm",
"status": "unpaid"
}
}
```
#### 3. 取得購買訂單記錄列表
**Method:** GET
**Routing:** /api/v1/orders
**Authenticated:** TRUE
**Request Params:**
**Response: 已付款紀錄**
```
{
"data": [
{
"id": "94a3f30c-af11-40b4-be43-81ad1f835d93",
"quantity": "11525645.7030000000",
"unit_price": "1000.0000",
"total_amount": "11525645703",
"payout_account": "003-123456789",
"payment_type": "atm",
"status": "paid",
"created_at": "2021-11-15T03:49:17.000000Z"
}
]
}
```
**Response: 虛擬帳號未付款紀錄**
```
{
"data": [
{
"id": "94a3f30c-af11-40b4-be43-81ad1f835d93",
"quantity": "11525645.7030000000",
"unit_price": "1000.0000",
"total_amount": "11525645703",
"payout_account": "003-123456789",
"payment_type": "atm",
"status": "unpaid",
"created_at": "2021-11-15T03:49:17.000000Z",
"payer_account": "004-987654321"
}
]
}
```
**Response: 臨櫃匯款未付款紀錄**
```
{
"data": [
{
"id": "94a3f30c-af11-40b4-be43-81ad1f835d93",
"quantity": "11525645.7030000000",
"unit_price": "1000.0000",
"total_amount": "11525645703",
"payout_account": "003-123456789",
"payment_type": "remittance",
"status": "unpaid",
"created_at": "2021-11-15T03:49:17.000000Z",
"payer_account": "004-987654321",
"payout_bank": {
"bank_name": "彰化分行",
"branch_name": "復興分行",
"account_name": "香港商全金集成台灣分公司"
}
}
]
}
```
#### 4. 取得單筆購買訂單記錄
**Method:** GET
**Routing:** /api/v1/orders/{order}
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": {
"id": "94a3f30d-2fff-438f-aed0-b21e6577d05f",
"quantity": "3404005.4300000000",
"unit_price": "1000.0000",
"total_amount": "3404005430",
"payout_account": "003-123456789",
"payment_type": "atm",
"status": "unpaid",
"2021-11-15T03:49:17.000000Z"
}
}
```
### Store
#### 1. 取得商家列表
**Method:** GET
**Routing:** /api/v1/stores
**Authenticated:** FALSE
**Request Params:**
|name|required|description|
|--|--|--|
|name|N|關鍵字查詢:商家名稱|
**Response:**
```
{
"data": [
{
"id": "94a3f4ae-2a64-4098-a7f3-c4c7aae5e12c",
"name": "Mitchell-Stiedemann",
"address": "878 Kuhn Lodge Suite 341\nKameronside, MS 07566-2372",
"discount_type": "fixed",
"discount_value": "0.00"
},
{
"id": "94a3f4ae-1f6d-447f-8d63-ea5f18286959",
"name": "Klein-Veum",
"address": "82254 Emmerich Manor Apt. 027\nHellerside, DC 08464",
"discount_type": "fixed",
"discount_value": "0.00"
}
],
"links": {
"first": "http://localhost/api/v1/stores?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "http://localhost/api/v1/stores",
"per_page": 15,
"to": 2
}
}
```
#### 2. 取得單筆商家資訊
**Method:** GET
**Routing:** /api/v1/stores/{store}
**Authenticated:** FALSE
**Request Params:**
**Response:**
```
{
"data": {
"id": "94a3f4ae-bf67-47fc-af2c-2172e3232a72",
"name": "Collins LLC",
"address": "845 Adaline Isle\nElisaborough, SC 24981",
"discount_type": "fixed",
"discount_value": "0.00"
}
}
```
#### 3. 與特定商家結帳
**Method:** POST
**Routing:** /api/v1/stores/{store}/checkout
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|amount|Y|結帳金額,最小為 0|
**Response:**
```
{
"data": {
"id": "94a3f4af-745a-4554-8562-d88003c6c278",
"store": {
"id": "94a3f4af-6d52-4871-b04c-8892de5a537a",
"name": "Buckridge, Bayer and Goldner",
"address": "976 Schoen Ways\nGerholdburgh, CA 20791"
},
"amount": 100,
"status": "created",
"created_at": "2021-10-15T17:30:57.000000Z"
}
}
```
#### 4. 重送結帳時的驗證訊息
**Method:** POST
**Routing:** /api/v1/stores/{store}/{order}/resend
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"success" true
}
```
#### 5. 驗證結帳需求
**Method:** POST
**Routing:** /api/v1/stores/{store}/{order}/verify
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|otp|Y|驗證碼|
**Response:**
```
{
"data": {
"id": "94a3f4af-745a-4554-8562-d88003c6c278",
"store": {
"id": "94a3f4af-6d52-4871-b04c-8892de5a537a",
"name": "Buckridge, Bayer and Goldner",
"address": "976 Schoen Ways\nGerholdburgh, CA 20791"
},
"amount": 100,
"status": "paid",
"created_at": "2021-10-15T17:30:57.000000Z"
}
}
```
#### 6. 取得消費紀錄列表
**Method:** GET
**Routing:** /api/v1/payments
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": [
{
"id": "956e3bce-c585-4210-beb2-0e6e3e8eea65",
"store": {
"id": "956e3bce-c34a-4eba-9e60-cf6aefb605e2",
"name": "Krajcik-Mayer",
"address": "804 Wilderman Haven Suite 244\nCaylaside, WY 24993-7038"
},
"amount": 91610,
"status": "created",
"created_at": "2022-01-24T06:47:03.000000Z"
}
],
"links": {
"first": "http://localhost/api/v1/payments?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "http://localhost/api/v1/payments",
"per_page": 15,
"to": 1
}
}
```
#### 7. 取得單筆消費紀錄
**Method:** GET
**Routing:** /api/v1/payments/{order}
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": {
"id": "956e3bcf-d6a6-412f-857c-cc1437ded1ca",
"store": {
"id": "956e3bcf-d4c3-4bf9-ad32-0a28b461db58",
"name": "Herzog, Hoppe and Metz",
"address": "8742 Conroy Landing\nEast Ignacio, AR 64991"
},
"amount": 28528,
"status": "created",
"created_at": "2022-01-24T06:47:04.000000Z"
}
}
```
### Payout Account
#### 1. 取得付款帳號
**Method:** GET
**Routing:** /api/v1/payout_accounts
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|company|Y|公司別,僅接受參數:tungkai, huanyu|
**Response:**
```
{
"data": [
{
"bank_name": "彰化銀行",
"branch_name": "復興分行",
"account_name": "全金集成有限公司",
"bank_account": "003-1234567890"
}
]
}
```
### Profile
#### 1. 取得個人資訊
**Method:** GET
**Routing:** /api/v1/profile
**Authenticated:** TRUE
**Request Params:**
**Response: 未驗證銀行帳號**
```
{
"data": {
"email": "rempel.nash@example.org",
"phone": "+14704479621",
"bank_info": null,
"status": "wallet_generated",
"is_activated": false,
"created_at": "2021-11-01T17:46:15.000000Z"
}
}
```
**Response: 銀行帳號通過驗證**
```
{
"data": {
"email": "dietrich.isai@example.net",
"phone": "+16030817118",
"bank_info": {
"name": "Test King",
"bank_code": "123",
"card_no": "******67890"
},
"status": "bank_verified",
"created_at": "2021-11-01T17:46:16.000000Z"
}
}
```
#### 2. 設定銀行帳號
**Method:** POST
**Routing:** /api/v1/profile/set_bank_account
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|name|Y|用戶戶名|
|bank_code|Y|用戶銀行代碼|
|branch_code|Y|用戶分行代碼|
|card_no|Y|用戶銀行帳號,不包含銀行代碼|
|fund_password|Y|資金密碼,目前填入用戶密碼作替代|
**Response:**
```
{
"success": true
}
```
#### 3. 驗證銀行帳號
**Method:** POST
**Routing:** /api/v1/profile/verify_bank_account
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|otp|Y|驗證碼|
**Response:**
```
{
"success": true
}
```
### Withdrawal
#### 1. 取得提領列表
**Method:** GET
**Routing:** /api/v1/withdrawals
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": [
{
"id": "94c8e45b-0c6d-4343-8dd1-f665877bae32",
"recipient_address": "TxyqrLNmgJF5Hy36ni475spt3Fznhonvow",
"currency": "twip",
"amount": "1595.3140000000",
"fee": "0.0000",
"fee_currency": "twip",
"status": "confirming",
"is_external": 0,
"transaction_hash": null,
"transaction_url": null,
"created_at": "2021-11-03T02:10:55.000000Z",
"confirmed_at": null
},
{
"id": "94c8e45b-0d01-4c55-8faa-f7f5a158e273",
"recipient_address": "TZuG4gAimbN6iEGBfBs6mdmkK2EimMEBrm",
"currency": "twip",
"amount": "5553.6620000000",
"fee": "0.0000",
"fee_currency": "twip",
"status": "confirmed",
"is_external": 0,
"transaction_hash": "0x12345",
"transaction_url": "example.com/0x12345",
"created_at": "2021-11-03T02:10:55.000000Z",
"confirmed_at": null
}
],
"links": {
"first": "http://localhost/api/v1/withdrawals?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "http://localhost/api/v1/withdrawals",
"per_page": 15,
"to": 2
}
}
```
#### 2. 取得單筆提領紀錄
**Method:** GET
**Routing:** /api/v1/withdrawals/{withdrawal}
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": {
"id": "94c8e45b-78ae-464b-a5d2-21b68941bb22",
"recipient_address": "TbffxkNKrCqhb3fHbCtD5vPwZuvddcoJvE",
"currency": "twip",
"amount": "832810.0740000000",
"fee": "0.0000",
"fee_currency": "twip",
"status": "created",
"is_external": 0,
"transaction_hash": null,
"transaction_url": null,
"created_at": "2021-11-03T02:10:55.000000Z",
"confirmed_at": null
}
}
```
#### 3. 新增提領請求
**Method:** POST
**Routing:** /api/v1/withdrawals
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|recipient_address|Y|TRON 地址|
|fund_password|Y|資金密碼,目前填入用戶密碼作替代|
|currency|Y|提領幣種,目前支援 twip 參數|
|amount|Y|提領金額,最低數值為 10|
**Response:**
```
{
"data": {
"id": "94c8e45c-23d6-4133-bae2-e1a17b9c5e75",
"recipient_address": "TJLCeMRJQSkeZKU6NXnUoNr1kpgeum3Wch",
"currency": "twip",
"amount": 10000,
"fee": 0,
"fee_currency": "twip",
"status": "created",
"is_external": false,
"transaction_hash": null,
"transaction_url": null,
"created_at": "2021-11-03T02:10:56.000000Z",
"confirmed_at": null
}
}
```
#### 4. 重送提領驗證簡訊
**Method:** POST
**Routing:** /api/v1/withdrawals/resend
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"success": true
}
```
#### 5. 驗證提領訂單
**Method:** POST
**Routing:** /api/v1/withdrawals/verify
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|otp|Y|驗證碼|
**Response:提領失敗**
```
{
"error": {
"message": "提領失敗,請聯絡管理員",
"code": "withdrawal_broadcast_txhash_failed",
"type": "invalid_request_error"
}
}
```
**Response:提領成功**
```
{
"data": {
"id": "94c8eaf2-a0e9-479c-ad6f-ef283cf7c14e",
"recipient_address": "TqAfDp2sy8H9iLsHtehxuzNCLEM9CzeAKj",
"currency": "twip",
"amount": "100.0000000000",
"fee": "0.0000",
"fee_currency": "twip",
"status": "confirming",
"is_external": 0,
"transaction_hash": null,
"transaction_url": null,
"created_at": "2021-11-03T02:29:21.000000Z",
"confirmed_at": null
}
}
```
### Deposit
#### 1. 取得入幣地址
**Method:** GET
**Routing:** /api/v1/deposits/wallet/{currency}
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|currency|Y|幣種。可填入 twip,但目前不管填入什麼值,都只會回傳 TRON 鏈的地址|
**Response:**
```
{
"data": [
{
"network": "TRON",
"address": "TxyqrLNmgJF5Hy36ni475spt3Fznhonvow",
}
]
}
```
#### 2. 取得入幣交易紀錄列表
**Method:** GET
**Routing:** /api/v1/deposits
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": [
{
"id": "94dba895-b559-4bb0-8a0f-00f1ce9456a0",
"network": "TRON",
"currency": "twip",
"amount": "105197.0170000000",
"fee": "0.0000",
"transaction_hash": "0x12345",
"transaction_url": "https://shasta.tronscan.org/0x12345",
"status": "confirming",
"received_at": "2021-11-12 10:04:31"
}
],
"links": {
"first": "http://localhost/api/v1/deposits?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "http://localhost/api/v1/deposits",
"per_page": 15,
"to": 1
}
}
```
#### 3. 取得單筆交易紀錄明細
**Method:** GET
**Routing:** /api/v1/deposits/{deposit}
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": {
"id": "94dba896-2ae8-4218-a33e-f86d6f51a310",
"network": "TRON",
"currency": "twip",
"amount": "0.0200000000",
"fee": "0.0000",
"transaction_hash": "0x12345",
"transaction_url": "https://shasta.tronscan.org/0x12345",
"status": "confirmed",
"received_at": "2021-11-12 10:04:31"
}
}
```
### Card
#### 1. 取得綁定卡片清單
**Method:** GET
**Routing:** /api/v1/cards
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": [
{
"id": "95d0f936-3f53-488a-be68-134ab864a3aa",
"card_no": "0feeafda805bc632f600",
"created_at": "2022-03-14T08:47:48.000000Z"
}
],
"links": {
"first": "http://localhost/api/v1/cards?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "http://localhost/api/v1/cards",
"per_page": 15,
"to": 1
}
}
```
#### 2. 綁定卡片
**Method:** POST
**Routing:** /api/v1/cards
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|card_no|Y|卡片編號,長度為 20|
**Response:卡片已被自己綁定**
```
{
"error": {
"message": "卡片已存在於列表清單中,不可重複註冊。",
"code": "card_registered_by_myself",
"type": "invalid_request_error"
}
}
```
**Response:成功**
```
{
"success": true
}
```
#### 3. 重發卡片註冊驗證訊息
**Method:** POST
**Routing:** /api/v1/cards/resend
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|card_no|Y|卡片編號,長度為 20|
**Response:卡片狀態異常**
```
{
"error": {
"message": "狀態異常,該卡片不存在或卡片已通過驗證",
"code": "card_invalid_status_or_verified",
"type": "invalid_request_error"
}
}
```
**Response:成功**
```
{
"success": true
}
```
#### 4. 驗證註冊卡片
**Method:** POST
**Routing:** /api/v1/cards/verify
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|card_no|Y|卡片編號,長度為 20|
|otp|Y|驗證碼|
**Response:成功**
```
{
"success": true
}
```
#### 5. 刪除已綁定卡片
**Method:** DELETE
**Routing:** /api/v1/cards/{card}
**Authenticated:** TRUE
**Request Params:**
**Response:卡片非屬於本人**
```
{
"error": {
"message": "No such resource.",
"code": "resource_missing",
"type": "invalid_request_error"
}
}
```
**Response:成功**
```
{
"success": true
}
```
### Redemption
#### 1. 取得贖回列表
**Method:** GET
**Routing:** /api/v1/redemptions
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": [
{
"id": "95f1b108-382b-43c3-b2b1-cb67e52882ce",
"recipient_address": "013-1234567890",
"currency": "twd",
"amount": "53",
"fee": "0.0000",
"fee_currency": "twd",
"status": "confirming",
"created_at": "2022-03-30T15:08:17.000000Z",
"confirmed_at": null
}
],
"links": {
"first": "http://localhost/api/v1/redemptions?page=1",
"last": null,
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"path": "http://localhost/api/v1/redemptions",
"per_page": 15,
"to": 1
}
}
```
#### 2. 取得單筆贖回紀錄
**Method:** GET
**Routing:** /api/v1/redemptions/{redemption}
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": {
"id": "95f1b108-858e-4dd4-99d3-06f5a87e81d1",
"recipient_address": "013-1234567890",
"currency": "twd",
"amount": "34417",
"fee": "0",
"fee_currency": "twd",
"status": "created",
"created_at": "2022-03-30T15:08:17.000000Z",
"confirmed_at": null
}
}
```
#### 3. 新增贖回請求
**Method:** POST
**Routing:** /api/v1/redemptions
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|fund_password|Y|資金密碼,目前填入用戶密碼作替代|
|currency|Y|贖回幣種,目前支援 twip 參數|
|amount|Y|贖回金額,最低數值為 10|
**Response:**
```
{
"data": {
"id": "95ef24f9-49ae-4787-8cd3-8b1cb7c2757c",
"recipient_address": "-",
"currency": "twd",
"amount": 100,
"fee": 0,
"fee_currency": "twd",
"status": "created",
"created_at": "2022-03-29T08:45:00.000000Z",
"confirmed_at": null
}
}
```
#### 4. 重送贖回驗證簡訊
**Method:** POST
**Routing:** /api/v1/redemptions/resend
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"success": true
}
```
#### 5. 驗證贖回訂單
**Method:** POST
**Routing:** /api/v1/redemptions/verify
**Authenticated:** TRUE
**Request Params:**
|name|required|description|
|--|--|--|
|otp|Y|驗證碼|
**Response:驗證成功**
```
{
"data": {
"id": "95f1afa2-3d9f-4090-8254-bcc5f1d72879",
"recipient_address": "013-1234567890",
"currency": "twd",
"amount": "100",
"fee": "0",
"fee_currency": "twd",
"status": "confirming",
"created_at": "2022-03-30T15:04:23.000000Z",
"confirmed_at": null
}
}
```
### Bank
#### 1. 取得銀行列表
**Method:** GET
**Routing:** /api/v1/banks
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": [
{
"code": "006",
"name": "第一商業銀行"
},
{
"code": "007",
"name": "合作金庫商業銀行"
}
]
}
```
#### 2. 取得銀行列表所對應之分行列表
**Method:** GET
**Routing:** /api/v1/banks/{bank_code}/branches
**Authenticated:** TRUE
**Request Params:**
**Response:**
```
{
"data": [
{
"code": "0010",
"name": "郵政劃撥儲金"
},
{
"code": "0021",
"name": "郵政存簿儲金"
}
]
}
```
### Policy Version
#### 1. 取得相關條款之版本
**Method:** GET
**Routing:** /api/v1/policy_versions
**Authenticated:** FALSE
**Request Params:**
**Response:**
```
{
"data": [
{
"terms_type": "all",
"version": "1.23"
}
]
}
```