@pichxyaponn/tw-angpao
Version:
ระบบรับเงินจาก Truewallet (ซองอั่งเปา) ด้วย ElysiaJS
177 lines (148 loc) • 5.14 kB
Markdown
# tw-angpao
ระบบรับเงินจาก Truewallet (ซองอั่งเปา) ด้วย [ElysiaJS](https://elysiajs.com/)
## ติดตั้ง:
```bash
bun add @pichxyaponn/tw-angpao
# หรือ
npm install @pichxyaponn/tw-angpao
```
## ตัวอย่างการใช้งาน:
#### example/index.ts
```typescript
import { Elysia, t } from "elysia";
import { TWAngpao } from "@pichxyaponn/tw-angpao";
// Reusable validation models — a single source of truth for both
// runtime validation and TypeScript types.
const models = new Elysia().model({
"redeem.body": t.Object({
phoneNumber: t.String({
minLength: 1,
description: "Thai mobile number (e.g. 0812345678 or +66812345678)"
}),
voucherCode: t.String({
minLength: 1,
description: "TrueMoney voucher hash or full gift link"
})
}),
"redeem.error": t.Object({
status: t.Object({
code: t.String(),
message: t.String(),
error: t.Optional(t.Any())
}),
data: t.Optional(t.Any())
})
});
const app = new Elysia()
.use(models)
.use(TWAngpao("TWA"))
.post(
"/redeem",
async ({ body, TWA, status }) => {
const response = await TWA.redeem(body.phoneNumber, body.voucherCode);
if (response.status.code !== "SUCCESS") {
const code = response.status.code;
// Server-side failures -> 5xx, invalid input / voucher problems -> 4xx
const httpStatus =
code.startsWith("HTTP_ERROR_") ||
code.startsWith("NETWORK_ERROR") ||
code === "INVALID_JSON_RESPONSE"
? 500
: 400;
return status(httpStatus, response);
}
// Success (200) — already shaped as { status: { code, message, data } }
return response;
},
{
body: "redeem.body",
response: {
400: "redeem.error",
500: "redeem.error"
}
}
)
.listen(3000);
```
#### POST
```
host:port/redeem
```
#### Body
```json
{
"phoneNumber": "0881234567",
"voucherCode": "c0d3v0ch3r1_c0d3v0ch3r2_c0d3v0ch3r3"
}
```
#### Response
```json
{
"status": {
"code": "SUCCESS",
"message": "Voucher redeemed successfully!",
"data": {
"voucher": {
"voucher_id": "...",
"amount_baht": "10.00",
"redeemed_amount_baht": "10.00",
"member": 1,
"status": "active",
"link": "...",
"detail": "Your pocket money",
"expire_date": 1728661892014,
"type": "R",
"redeemed": 1,
"available": 0
},
"owner_profile": {
"full_name": "... ***"
},
"redeemer_profile": {
"mobile_number": "..."
},
"my_ticket": {
"mobile": "...",
"update_date": 1728402860358,
"amount_baht": "10.00",
"full_name": "...",
"profile_pic": null
},
"tickets": [
{
"mobile": "...-xxx-...",
"update_date": 1728402860358,
"amount_baht": "10.00",
"full_name": "... ***",
"profile_pic": "..."
}
]
}
}
}
```
#### Status codes จาก TrueMoney (ส่งต่อจาก API ปลายทาง)
| code | message |
| ---------------------- | ---------------------------------- |
| VOUCHER_OUT_OF_STOCK | Voucher ticket is out of stock. |
| TARGET_USER_REDEEMED | Redeemed |
| VOUCHER_NOT_FOUND | Voucher doesn't exist. |
| CANNOT_GET_OWN_VOUCHER | Cannot claim your own voucher. |
| VOUCHER_EXPIRED | The gift voucher link has expired. |
| SUCCESS | Voucher redeemed successfully! |
#### Status codes จากตัว library เอง
| code | สาเหตุ |
| --------------------- | ----------------------------------------------- |
| INVALID_PHONE_NUMBER | เบอร์โทรไม่ใช่รูปแบบเบอร์มือถือไทยที่ถูกต้อง |
| INVALID_VOUCHER_CODE | voucher code/link ว่างหรือแกะ code ไม่ได้ |
| HTTP_ERROR_UNKNOWN | API ปลายทางตอบกลับไม่สำเร็จ (response ไม่ ok) |
| INVALID_JSON_RESPONSE | API ตอบกลับมาไม่ใช่ JSON ที่ถูกต้อง |
| NETWORK_ERROR | error ที่ไม่คาดคิด/เชื่อมต่อปลายทางไม่ได้ |
## Config
### name
ตั้งชื่อให้ Decorate method ได้:
เช่น TWA จะ Decorate Context ด้วย Context.TWA
## Support
มีคำแนะนำหรืออยากช่วยพัฒนา ให้ส่ง Pull Request ได้เลย
### Issues
มีปัญหาหรือฟีเจอร์ที่อยากให้เพิ่ม แจ้งได้ที่ [หน้า Issues](https://github.com/pichxyaponn/tw-angpao/issues)