Shukah vs Locate
Tổng quan
Không có tài liệu API Shukah nào ở bất cứ đâu. Trang này là nơi duy nhất phía Shukah được ghi lại: mobile app gửi gì tới từng route Shukah, nhận lại gì, và route Locate thay thế nó khác ra sao. Mọi link "So sánh với Shukah" trên một trang endpoint đều trỏ tới một mục ở đây.
Cách dùng:
- Bắt đầu với hai bảng bên dưới. Bấm vào một route Shukah để nhảy tới mục của nó.
- Đọc Các khác biệt chung một lần. Base URL, token, body lỗi, id, ngày tháng và header thay đổi giống nhau trên mọi route, nên các mục bên dưới không lặp lại chúng.
- Một mục có URL dev đầy đủ, request mà app gửi, một lệnh
curl(bỏ qua cho các route xóa tài khoản hoặc thu tiền), response Shukah đã capture, các lỗi đã thấy, và, với một route đã thay thế, một link tới trang Locate và một bảng theo từng field. - Các capture Shukah được lấy trên dev vào 2026-10-01 với client test dev 356259. Vào 2026-10-02 một parity audit đã gửi cùng một input tới Shukah và tới Locate cho mọi route có thể gọi an toàn, với các header của app 2.31.5; một mục nói rõ khi một giá trị đến từ lần chạy đó. Các field cá nhân trong mọi sample đều được thay bằng giá trị minh họa. Một giá trị mà không nguồn nào cho thấy được đánh dấu "Chưa được tài liệu hóa". Khi kỳ vọng của chính app là nguồn Shukah duy nhất, mục đó sẽ nói rõ.
$SHUKAH_BASE_URLlàhttps://dev-api.shukah.comvà$SHUKAH_TOKENlà một token opaque của Shukah. Các trang Locate dùng$AUTH_BASE_URL,$ORDER_BASE_URLvà$TOKEN.- Hai mục Shukah, update profile và update setting, là cùng một route Shukah. Chúng là hai dòng vì Locate tách chúng thành hai route.
Auth
| API Shukah | API Locate | Service | Trạng thái |
|---|---|---|---|
GET /maeda/api/reset-otp | GET /api/v1/clients/reset-otp | auth-service | ✅ Đã thay thế |
GET /maeda/api/verify-otp | GET /api/v1/clients/verify-otp | auth-service | ✅ Đã thay thế |
GET /maeda/api/verify-token | GET /api/v1/clients/verify-token | auth-service | ✅ Đã thay thế |
GET /maeda/client | GET /api/v1/clients | auth-service | ✅ Đã thay thế |
GET /maeda/address-book | GET /api/v1/clients/address-book | auth-service | ✅ Đã thay thế |
GET /maeda/address-book/:id | GET /api/v1/clients/address-book/:id | auth-service | ✅ Đã thay thế |
POST /maeda/address-book | POST /api/v1/clients/address-book | auth-service | ✅ Đã thay thế |
PUT /maeda/address-book/:id | PUT /api/v1/clients/address-book/:id | auth-service | ✅ Đã thay thế |
DELETE /maeda/address-book/:id | DELETE /api/v1/clients/address-book/:id | auth-service | ✅ Đã thay thế |
PUT /maeda/client/:client_id | PUT /api/v1/clients/:client_id | auth-service | ✅ Đã thay thế |
PUT /maeda/client/:client_id | PUT /api/v1/clients/setting | auth-service | ✅ Đã thay thế |
POST /maeda/client/add-device-id | POST /api/v1/clients/add-device-id | auth-service | ✅ Đã thay thế |
GET /maeda/client/status | — | — | ❌ Chưa thay thế |
GET /maeda/client/delete | — | — | ❌ Chưa thay thế |
Điểm
| API Shukah | API Locate | Service | Trạng thái |
|---|---|---|---|
GET /maeda/client/points | GET /api/v2/client/points | order-v2 → point-service | ✅ Đã thay thế |
GET /maeda/point-rate | GET /api/v2/client/system_configs/point_rates | order-v2 | ✅ Đã thay thế 🚩 enableMerchantService |
GET /maeda/giftcard-code/use | POST /api/v2/client/gift-card-code | order-v2 | ✅ Đã thay thế 🚩 enableMerchantService |
GET /maeda/client/point-history | GET /api/v2/client/point-history | order-v2 → point-service | ✅ Đã thay thế |
GET /maeda/point-offer | GET /api/v2/client/point-offers | order-v2 → point-service | ✅ Đã thay thế |
GET /maeda/point-occasion | GET /api/v2/client/point-occasions | order-v2 → point-service | ✅ Đã thay thế |
POST /maeda/point-order | POST /api/v2/client/point-orders | order-v2 → point-service | ✅ Đã thay thế 🚩 POINT_ORDER_POINT_ENABLED |
POST /maeda/point-order/get-description | POST /api/v2/client/point-orders/description | order-v2 → point-service | ✅ Đã thay thế |
POST /maeda/order/checkout-payment-standalone | POST /api/v2/client/point-orders/:correlation_id/pay/card | order-v2 → point-service | ✅ Đã thay thế 🚩 POINT_ORDER_CARD_ENABLED |
POST /maeda/order/checkout-payment-flow | POST /api/v2/client/point-orders/:correlation_id/pay/session | order-v2 → point-service | ✅ Đã thay thế 🚩 POINT_ORDER_CARD_ENABLED |
GET /maeda/points-faq | GET /api/v2/client/points-faq | order-v2 → point-service | ✅ Đã thay thế |
GET /maeda/point-order | — | — | ❌ Chưa thay thế |
POST /maeda/order/checkout-payment | — | — | ❌ Chưa thay thế |
POST /maeda/order/checkout-payment-stcpay | — | — | ❌ Chưa thay thế |
POST /maeda/order/payfort-token | — | — | ❌ Chưa thay thế |
POST /maeda/order/payfort-stc-pay-checkout | — | — | ❌ Chưa thay thế |
Khi tài liệu và code mâu thuẫn
Các nhận định của các phiên bản trước của trang này mà các capture 2026-10-02 hoặc code mâu thuẫn. Mỗi mục giờ nói rõ điều đã tìm thấy.
- 2026-10-02: Token nói một JWT Locate chạy trên các route điểm của order-v2. Trên dev giờ
nó nhận
401; chỉ token Shukah chạy ở đó. - 2026-10-02: Id và ba mục thanh toán nói app gửi
point_order_iddưới dạng integer. App 2.31.5 gửi một chuỗi ("1252","1253"). - 2026-10-02: Định dạng số và mục balance ghi số dư Shukah là
"128712.41", bằng khoảng một phần tư của Locate. Giờ nó là"514853.64", cao hơn Locate 447.96 điểm. - 2026-10-02: reset-otp, update profile, update setting, add-device-id và danh sách quà đã gửi chưa có capture Shukah. Giờ chúng đã có.
- 2026-10-02: verify-otp ghi body mã sai với
typekiểu Yii. Body Shukah hiện nay cótypecủa Symfony. - 2026-10-02: mục verify-otp không có capture Shukah của lời gọi thành công. Giờ đã có:
200 {access_token, data}, cùng hồ sơ 13 key với giá trị bằng nhau như Locate, và các session trước vẫn hợp lệ. - 2026-10-02: danh sách địa chỉ ghi 13 và 28 địa chỉ, không có mặc định trên
Shukah và tất cả đều mặc định trên Locate, và thứ tự Shukah chưa rõ. Giờ là 15 và 30, Shukah
0ở cả 15, Locatetrueở 28 trong 30, và Shukah sắp theoposition. - 2026-10-02: danh sách địa chỉ không cho thấy khác biệt
image_urls. Locate đã mất URL ảnh của 4 địa chỉ Shukah có ảnh. - 2026-10-02: mục address get không cho thấy khác biệt
is_defaulthayimage_urls. Cùng một địa chỉ là0trên Shukah và1trên Locate, và có URL ảnh trên Shukah còn[]trên Locate. - 2026-10-02: mục point history nói các số tiền earn mới nhất của Shukah
(0.5, 0.5, 2.5) ở một thang đo khác với của Locate. Các dòng mới nhất của Shukah giờ là 2, 2, 2, 2,
10: không còn chênh thang đo. Dòng mới nhất của Shukah là 2026-10-01 17:00:01, không phải 10:40:44, và 8 trong 9 dòng
earn của Locate trong 10 dòng đầu có
descriptionrỗng, không phải bốn trong năm. - 2026-10-02: các mục point-order create và
danh sách quà đã gửi kỳ vọng
occasion_id. Shukah gửipoint_occasion_id. - 2026-10-02: mục point-order create không có capture Shukah và không
biết create có trả lời với dòng order hay không. Giờ nó có một capture:
201với cùng mười hai key như các dòng order. - 2026-10-02: mục PayFort token không nêu lời gọi Locate nào. order-v2 có một relay tới cùng route Shukah.
- 2026-10-02:
GET /maeda/client/statustừng được liệt kê là được khai báo nhưng không bao giờ được gọi. Traffic production cho thấy 768 lời gọi trong 3 ngày, nên giờ nó có một mục.
Các khác biệt chung
Base URL
| Shukah | Locate | |
|---|---|---|
| API Auth (login, profile, address book) | Dev https://dev-api.shukah.com/maeda/, production https://api.shukah.com/maeda/ (BASE_URL của app). | Auth service, được gọi trực tiếp. Dev https://dev.authentication.locate.sa, prefix /api/v1. Host production: Chưa được tài liệu hóa. |
| API điểm | Cùng base URL của Shukah. | order-v2. Dev https://dev.v2.api.order.locate.sa, prefix /api/v2/client. Production https://v2.api.order.locate.sa/api/v2 (BASE_URL_V2 production của app). order-v2 chuyển phần lớn route điểm sang point service, mà không được expose cho app. |
Điều gì thay đổi với app:
- Hai prefix là mới, một cái biến mất. Mọi route Shukah nằm dưới
/maeda. Host auth của Locate không phục vụ nó:GET /maeda/api/verify-tokentrên host auth trả404(capture trên dev, 2026-10-01). Các route auth chuyển sang/api/v1/clients/…, các route điểm sang/api/v2/client/…. - Segment
api/không ổn định trên Shukah. Các route login có nó (/maeda/api/reset-otp); address book thì không (/maeda/address-book). Một lời gọi/maeda/api/address-booktrên Shukah dev trả404(capture 2026-10-01). - Path điểm thành số nhiều.
point-offerthànhpoint-offers,point-occasionthànhpoint-occasionsvàpoint-orderthànhpoint-orders. - App không có base URL của auth service. Không file môi trường nào của app nêu host auth. Nó có
một base URL order-v2 (
BASE_URL_V2), mà nó đã dùng cho một vài lời gọi ở chế độ Merchant. - Dựng URL. App nối base URL,
/và endpoint, rồi một query sắp theo key. Dấu gạch chéo ở đầu endpoint không có khác biệt.
Token
Shukah cấp một token opaque. Locate cấp một JWT (HS256, payload {client_id, phone}) mà
không bao giờ hết hạn. Cả hai đều đi trong Authorization: Bearer <token>.
Hiện nay không có token đơn nào chạy được trên cả hai service. Route Locate nào nhận token nào (dev, được capture vào 2026-10-02 với cả hai token trên mọi route có thể gọi an toàn):
| Route Locate | Token |
|---|---|
| Auth: reset-otp, verify-otp, exchange-token, add-device-id | Không cần. |
| Auth: verify-token, client lookup, năm route address-book, update profile, update setting | Chỉ JWT Locate. Token Shukah nhận 401 {"status":401,"message":"Unauthorization"} (đã capture). |
Auth: user detail (GET /api/v1/users) | Cần header x-auth-from (422 nếu thiếu). Với x-auth-from: SHUKAH và auth_source của dev là shukah, token được Shukah dev kiểm tra: một token Shukah qua được và một JWT Locate bị từ chối. Với auth_source đặt là locate, mọi JWT Locate nhận 401 (một defect). |
| Các route điểm của order-v2 (balance, history, FAQ, offers, occasions, point orders) | Chỉ token Shukah. Một JWT Locate nhận 401 {"success":false,"error":{"code":"UNAUTHORIZED","message":"Invalid or expired token"}} trên các route balance, history, FAQ, offers và occasions (đã capture). Các route point-order dùng cùng cách kiểm tra. Vào 2026-10-01 một JWT Locate vẫn nhận 200 trên route balance. |
| Tỷ lệ tích điểm của order-v2 | Không cần: public. 200 khi không có token, với một token Shukah và với một JWT Locate (đã capture). |
| Gift-card code của order-v2 | Cùng cách kiểm tra như các route điểm, nên chỉ token Shukah (đọc code; chưa gọi với token, vì nó cộng điểm). |
Vì sao (từ code trên origin/develop): guard client của auth service chạy jwt.verify, nên một token
Shukah opaque không qua được. Point service và order-v2 hỏi auth service người gọi là ai
với x-auth-from: SHUKAH: guard của order-v2 hard-code nó, và point service gửi nó theo mặc định
(setting AUTH_VERIFY_APPLICATION của nó). Setting auth_source của dev là shukah (đọc từ client
settings công khai vào 2026-10-02), nên auth service chuyển token sang Shukah dev, nơi từ chối
JWT Locate (suy luận từ 401: verify-token của Shukah dev không được gọi với chính JWT).
Vào 2026-10-01 Shukah vẫn chấp nhận nó. Đặt auth_source là locate sẽ không giúp được một mình:
ở nhánh đó mọi JWT Locate nhận 401, vì một defect được mô tả trên
User detail. Vậy hiện nay app cần cả hai token: JWT cho
auth service, token Shukah cho order-v2.
Bản thân Shukah trả lời bốn route không cần token: point-offer, point-occasion, point-rate và
points-faq. Locate cần token cho offers, occasions và FAQ.
Exchange-token chuyển đổi một token theo cả hai hướng
(target_platform là locate hoặc shukah). App không bao giờ gọi nó. Vì vậy một user đang đăng nhập
bằng token Shukah mà gọi verify-token của Locate sẽ nhận 401, và app xóa token đã lưu khi gặp
401 đó (chỉ verify-token và delete-account làm vậy), khiến user bị đăng xuất. Các route
ở lại Shukah (xóa tài khoản, danh sách quà đã gửi, các thanh toán PayFort và Frames) vẫn cần một
token mà Shukah chấp nhận: Locate đẩy mỗi JWT nó cấp sang Shukah theo kiểu best-effort (sau một server setting), hoặc app
có thể exchange lấy token Shukah với target_platform: "shukah". Vào 2026-10-02 Shukah dev không còn
chấp nhận JWT Locate (xem ở trên), nên không thể dựa vào push đó ở đó.
Body lỗi
Năm shape lỗi gặp nhau trong lần migrate này. Một body thật của mỗi loại:
| Gửi bởi | Body thật | Capture ở đâu |
|---|---|---|
| Shukah (Laravel, probe hôm nay) | {"name":"Unauthorized","message":"Your request was made with invalid credentials.","code":0,"status":401,"type":"Illuminate\\Auth\\AuthenticationException"} | GET /maeda/api/verify-token không có token, dev, 2026-10-01. Cùng các key name, code, status và type mang một 404 ({"name":"Not Found","message":"Object not found: 162119",…,"type":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException"}, address get sau khi delete, 2026-10-01). |
| Shukah (Yii, capture cũ hơn) | {"name":"Bad Request","message":"Last Name cannot be blank.","code":0,"status":400,"type":"yii\\web\\BadRequestHttpException"} | Từ một lời gọi tới reset-otp của Shukah, trong capture tháng 7 năm 2026 lưu ở draft doc của auth service (api-auth-draft.md, 2026-07-07). Shukah có còn gửi nó hay không: Chưa được tài liệu hóa. 400 của reset-otp và client-lookup của chính auth service cũng dùng shape Yii này. |
| Auth service | {"status":401,"message":"Unauthorization"} | GET /api/v1/clients/verify-token, không token, dev, 2026-10-01. 500 là {"status":500,"message":"Internal server error"} trên production. Trên dev nó mang text lỗi gốc và một field stack. |
| Point service (qua order-v2) | {"success":false,"error":{"code":"UNAUTHORIZED","message":"Missing or invalid authorization header"}} | GET /api/v2/client/points, không token, dev, 2026-10-01. Một key details được thêm cho lỗi validation. order-v2 dựng body 502 và 504 cùng shape. |
| Chính order-v2 (Nest) | {"message":"Unauthorized","statusCode":401} | POST /api/v2/client/gift-card-code, không token, dev, 2026-10-01. |
Cách app hiển thị chúng: một status từ 400 trở lên thành một lỗi có message là
body.message, hoặc toàn bộ body dạng chuỗi JSON khi không có message ở cấp cao nhất. Vì vậy:
- Body của Shukah, auth-service và Nest hiển thị
messagecủa chúng. Các keyname,type,codevàstatusCodekhông bao giờ được đọc. - Envelope của point-service không có
messageở cấp cao nhất, nên app sẽ hiển thị chuỗi JSON thô{"success":false,"error":{…}}cho user trừ khi nó tự đọcerror.message. - Một body không phải JSON (một trang HTML
404) thành{message: <text>}. - App mặc định mở một global error cho
403,500,502,503,504và505. Các flag point-order trả403, nên đó là một lỗi nghiêm trọng trừ khi danh sách status được đổi. - Tín hiệu đăng ký vẫn chạy nếu text giữ nguyên: app mở màn hình đăng ký
khi reset-otp trả
400và message chứaLast Name.
Id
| Thứ | Shukah | Locate |
|---|---|---|
| Client | client_id integer (356259). | Cùng integer đó cho client đã migrate. Client đăng ký trong Locate nhận id từ 1,000,000,001. |
| Địa chỉ | id integer (162115). | Chuỗi hex 24 ký tự (6abbeed8a492ed4862500b74). Một giá trị chỉ gồm chữ số trong path vẫn được thử trước như id Shukah cũ. |
| Point offer, point occasion | id integer, 1 đến 5 và 1 đến 7. | Chuỗi hex 24 ký tự. Một integer Shukah gửi tới Locate là 400. |
| Point order | point_order_id, một số trong danh sách order của Shukah. Các body payment của app 2.31.5 gửi nó dưới dạng chuỗi, "1252" (capture trên dev, 2026-10-02). | UUID correlation_id, trong path của các route get và pay. Một point_order_id trong body bị bỏ qua. order_no (từ 100000) là số dễ đọc. |
| Dòng point-history | id integer trên các dòng expense, shukah_id trên các dòng earn. | id hex 24 ký tự trên các dòng expense. shukah_id là null cho các dòng Locate tự ghi. |
App khai báo mọi id có kiểu number. Lời gọi delete-address của nó biến id thành số bằng toán tử unary
plus, nên một id 24-hex thành NaN. Id của offer và occasion đến Locate dưới dạng text và chạy được.
Phân trang
| Lời gọi | Shukah | Locate |
|---|---|---|
| Point history | Không có: toàn bộ lịch sử trong một mảng (8,134 dòng cho client 356259 vào 2026-10-01, 2.3 s; 8,136 vào 2026-10-02). | Query page và limit. Mặc định 20, tối đa 100. Không có total và không có marker next-page. App không gửi cái nào. |
Danh sách quà đã gửi (GET point-order) | Query page và per-page. Tổng trong các response header x-pagination-total-count và x-pagination-page-count. | Không có route. |
| Danh sách địa chỉ, offers, occasions, FAQ, rates | Không có. | Không có. |
Ngày tháng và múi giờ
Cả hai phía đều dùng giờ đồng hồ Riyadh (Asia/Riyadh, UTC+3, không có giờ mùa hè) cho các dòng ledger, và không có dấu múi giờ.
| Giá trị | Shukah | Locate |
|---|---|---|
date_created của point-history | YYYY-MM-DD HH:mm:ss, giờ Riyadh. | Cùng định dạng và múi giờ. |
pointsExpirationDate | YYYY-MM-DD. | YYYY-MM-DD, một ngày theo Riyadh. |
birth_date | YYYY-MM-DD. | YYYY-MM-DD: ngày UTC của giá trị đã ghi. |
date_created của kết quả gift-card | Chưa được tài liệu hóa. | yyyy-mm-dd hh:mm:ss, giờ Ả Rập (UTC+3). |
created_at, updated_at của địa chỉ | Không trả về. | ISO 8601 theo UTC (2026-09-29T17:01:10.000Z), chỉ trên câu trả lời list và create. |
Định dạng số
| Giá trị | Shukah | Locate |
|---|---|---|
Số dư điểm points | Chuỗi với hai chữ số thập phân: "514853.64" (2026-10-02). | Chuỗi với tối đa bốn chữ số thập phân, bỏ số 0 ở cuối: "514405.6788". "0" khi không có tài khoản. App chuyển bằng Number(points) || 0. |
total_points của history | Một số trên các dòng earn, một chuỗi với hai chữ số thập phân trên các dòng expense ("684.00", do team point service đo vào 2026-07-17). | Một số trên các dòng earn và một chuỗi với chính xác hai chữ số thập phân trên các dòng expense ("360.00"). |
amount của offer, money_amount của order | amount là chuỗi với hai chữ số thập phân: "40.00". | amount giống nhau; money_amount của order là chuỗi với hai chữ số thập phân. |
point_amount, purchased_point_amount của offer | Integer. | Số. purchased_point_amount có thể là null khi offer không có giá bằng điểm. |
lat, lng của địa chỉ | Số JSON trên mọi route. | Số trên list và create, chuỗi trên get và update. |
is_default của địa chỉ | 0 hoặc 1 trong type của app. 0 trên mọi địa chỉ và mọi route trong các capture 2026-10-02. | Boolean trên list và create, 0 hoặc 1 trên get và update (được xác nhận bởi code và các capture 2026-10-02). |
sex, receive_offers, push_enabled | Integer (sex 0, 1, 2 hoặc 9). | Integer. sex 9 được lưu là không rõ và đọc lại là 0. |
Request header
Request. App gửi những thứ này trên mọi lời gọi Shukah (và trên các lời gọi order-v2):
| Header hoặc query | Giá trị | Locate |
|---|---|---|
Authorization | Bearer <stored token> khi đã đăng nhập. | Cần trên các route có guard. Xem Token. |
Accept, Content-Type | application/json. | Content-Type: application/json cần cho các route POST của order-v2 mà đọc body. |
x-from-application | LOCATE_CLIENT_V2. | Auth service bỏ qua. order-v2 không chuyển nó sang point service. |
from-application, x-from-version | Chế độ app và phiên bản app. | Giống vậy: bỏ qua hoặc không chuyển tiếp. |
language (query) | en-GB, hoặc ar-SA cho bất kỳ ngôn ngữ nào khác. | Auth service bỏ qua, trừ reset-otp, nơi lưu phần trước dấu -. Các route điểm bỏ qua nó, và nhãn occasion chỉ là tiếng Ả Rập khi language chính xác là ar. |
key (query) | maeda, chỉ gửi trên reset-otp và phone lookup. | Bị bỏ qua. |
x-auth-from | SHUKAH, chỉ được gửi bởi helper shukahApi của app, không phải client chính. | Point service tự đặt giá trị của nó khi gọi auth service. App không cần gửi nó. |
Các capture 2026-10-01 chỉ gửi Accept, cộng x-from-application và Content-Type trên các
lời gọi ghi, kèm token, và nhận 200. Các capture 2026-10-02 gửi các header của app 2.31.5
(x-from-application, from-application, x-from-version: 2.31.5, x-user-id, Accept) và
?language=en-GB ở cả hai phía. x-device-id không được app gửi.
Response: các header app-version. App đọc new_version, old_version, has_new_version và
is_required_update từ response của bất kỳ lời gọi nào có URL chứa api/verify-token hoặc
client/points, và hiển thị popup cập nhật từ chúng. Shukah có gửi chúng hay không: Chưa được tài liệu hóa
(các capture chỉ lưu request header). Không Locate service nào gửi chúng. URL verify-token của Locate
(/api/v1/clients/verify-token) không chứa api/verify-token, nên app sẽ không tìm
ở đó. URL điểm của Locate có chứa client/points, nhưng không có gì set các header. Nếu Shukah
hiện nay gửi chúng, popup cập nhật sẽ lặng lẽ ngừng sau khi chuyển. Xem
Verify token.
Response: các header phân trang. Danh sách quà đã gửi đọc x-pagination-total-count và
x-pagination-page-count. Xem Phân trang.
API Auth
GET /maeda/api/reset-otp
Thay thế bằng Locate: GET /api/v1/clients/reset-otp
URL dev đầy đủ: https://dev-api.shukah.com/maeda/api/reset-otp
Một route làm cả đăng nhập và đăng ký. Không có Authorization: user đang đăng xuất.
Request (từ app). Đăng nhập gửi contact_phone (chỉ chữ số, bỏ +), key=maeda và
language. Đăng ký thêm first_name, last_name, email_address và, tùy chọn, sex (0, 1,
2 hoặc 9), birth_date (yyyy-mm-dd) và receive_offers (gửi là 1 chỉ khi user đồng ý,
không bao giờ là 0).
# Sends a real SMS to the phone. Use a test-mode number.
curl -s -G "$SHUKAH_BASE_URL/maeda/api/reset-otp" --data-urlencode "contact_phone=$PHONE" --data-urlencode "key=maeda" --data-urlencode "language=en-GB"
Response Shukah đã capture. 200, 895 ms, cho một phone đã biết (capture trên dev, 2026-10-02; nó đã gửi
một SMS). Locate trả lời cùng body. Type app parse là {status: any}. Draft doc của auth
service (api-auth-draft.md, 2026-07-07), từ một lời gọi tới dev Shukah, cho thấy cùng
{"status": true} cho một lần đăng ký.
{
"status": true
}
Lỗi đã thấy.
- Thiếu phone,
400, bằng tiếng Ả Rập và vớitypecủa Laravel (capture trên dev, 2026-10-01, vớikey=maedavà không cólanguage):{"name":"Bad Request","message":"حقل contact phone مطلوب.","code":0,"status":400,"type":"Illuminate\\Validation\\ValidationException"} - Phone không tồn tại và không có field đăng ký,
400, trong capture tháng 7 năm 2026 lưu ở draft doc của auth service (api-auth-draft.md, 2026-07-07):{"name":"Bad Request","message":"Last Name cannot be blank.","code":0,"status":400,"type":"yii\\web\\BadRequestHttpException"}. Tín hiệu để app mở đăng ký. Hôm nay Shukah có còn gửi text này hay không: Chưa được tài liệu hóa.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
contact_phone (query) | Chỉ chữ số, + bị app bỏ. | Bỏ khoảng trắng, khớp có hoặc không có + ở đầu. Không kiểm tra định dạng. | Trống cho 400 ở cả hai. |
key (query) | maeda. | Bị bỏ qua. | App có thể tiếp tục gửi nó. |
first_name, last_name, email_address (query) | Các field đăng ký. | Cần khi không client active nào có phone. Kiểm tra theo thứ tự last name, first name, email. | Một lời gọi trần cho phone không tồn tại nhận Last Name cannot be blank. trên Locate. Text hiện tại của Shukah: Chưa được tài liệu hóa. |
sex (query) | 0, 1, 2 hoặc 9. | 1 nam, 2 nữ. Mọi giá trị khác được lưu là không rõ. | |
birth_date (query) | yyyy-mm-dd. | Được đọc như một ngày, lưu dạng YYYY-MM-DD. Giá trị xấu được lặng lẽ lưu rỗng. | |
receive_offers (query) | Chỉ gửi 1. | Không được đọc. Client mới bắt đầu với giá trị tắt. | |
language (query) | en-GB hoặc ar-SA. | Lưu phần trước dấu -, chữ thường. Thiếu thì thành ar. | Không đổi ngôn ngữ SMS (tiếng Ả Rập). |
status (response) | true. | true. Cũng true khi một mã còn chờ và không có SMS mới được gửi. | Đừng đọc true là "đã gửi SMS". |
| Lỗi thiếu phone | Message tiếng Ả Rập, type Laravel. | {"name":"Bad Request","message":"Phone number cannot be blank.","code":0,"status":400,"type":"yii\\web\\BadRequestHttpException"} (capture trên dev, 2026-10-01). | Các key giống nhau, text và type khác nhau. |
GET /maeda/api/verify-otp
Thay thế bằng Locate: GET /api/v1/clients/verify-otp
URL dev đầy đủ: https://dev-api.shukah.com/maeda/api/verify-otp
Request (từ app). Query contact_phone, code (4 chữ số), fcm_token (bỏ qua khi app
không lấy được), platform (Android, iOS hoặc Huawei) và language. Không có key. Không có
Authorization.
# Uses up the code and returns a new token. Use a test-mode number.
curl -s -G "$SHUKAH_BASE_URL/maeda/api/verify-otp" --data-urlencode "contact_phone=$PHONE" --data-urlencode "code=$CODE" --data-urlencode "platform=iOS"
Response Shukah đã capture. 200 trên dev, 2026-10-02 (mã đúng 2022, platform=iOS, không có
token). Giá trị access_token đã bị che, nên loại token không được ghi lại ở đây. Profile data là
cùng 13 field với giá trị bằng nhau như trên Locate.
{
"access_token": "<redacted>",
"data": {
"client_id": 356259,
"odoo_id": "1342170",
"contact_phone": "+966500000000",
"status": "active",
"email_address": "user@example.com",
"first_name": "Test",
"last_name": "User",
"sex": 1,
"birth_date": "1990-01-01",
"receive_offers": 0,
"push_enabled": 0,
"is_food_truck_user": 1,
"is_cod_disabled": 0
}
}
Hai token phát hành trước đó vẫn dùng được sau lời gọi này (Shukah GET /maeda/client/points 200):
một lần đăng nhập mới không kết thúc các session trước đó. Shukah xử lý fcm_token và platform thế
nào vẫn chưa thấy trong response.
Lỗi đã thấy. Mã sai, 400 (capture trên dev, 2026-10-02):
{"name":"Bad Request","message":"Sorry, but your verification code is incorrect","code":0,"status":400,"type":"Symfony\\Component\\HttpKernel\\Exception\\HttpException"}.
Capture tháng 7 năm 2026 lưu ở draft doc của auth service (api-auth-draft.md, 2026-07-07) có cùng
message với type kiểu Yii yii\\web\\BadRequestHttpException.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
contact_phone (query) | Chữ số. | Bỏ khoảng trắng, khớp có hoặc không có +. | |
code (query) | 4 chữ số. | So sánh dạng text, nên số 0 ở đầu có ý nghĩa. | |
fcm_token (query) | Gửi khi app có. Shukah làm gì với nó: Chưa được tài liệu hóa. | Bị bỏ. | Nếu Shukah có dùng nó, nó sẽ mất. App cũng lưu FCM token của nó riêng, sang order-v2 (client/fcm/save-token). |
platform (query) | Android, iOS hoặc Huawei. Shukah làm gì với nó: Chưa được tài liệu hóa. | Bị bỏ. | |
language (query) | Có gửi. | Bị bỏ qua. | |
access_token (response) | Một token opaque của Shukah. | Một JWT Locate, không bao giờ hết hạn. | Mọi lời gọi /api/v1/clients/* sau đó đều cần JWT. |
data (response) | Cùng hồ sơ 13 field như Locate, giá trị bằng nhau (capture trên dev, 2026-10-02). | Hồ sơ 13 field, như ở verify-token. | Không có: shape và giá trị khớp nhau trong cặp gọi 2026-10-02. |
| Lỗi mã sai | Body Laravel ở trên (type của Symfony). | {"status":400,"message":"Sorry, but your verification code is incorrect"} (capture trên dev, 2026-10-01 và 2026-10-02). | name, code và type không còn. Một message duy nhất bao phủ mã sai, hết hạn, đã dùng và phone không tồn tại. |
GET /maeda/api/verify-token
Thay thế bằng Locate: GET /api/v1/clients/verify-token
URL dev đầy đủ: https://dev-api.shukah.com/maeda/api/verify-token
Request. Authorization: Bearer <stored token>, language. App cũng đặt Accept,
Content-Type và x-from-application: LOCATE_CLIENT_V2 tường minh trên lời gọi này. Nó chạy mỗi lần
app khởi động và lại khi Home mở.
curl -s "$SHUKAH_BASE_URL/maeda/api/verify-token" -H "Authorization: Bearer $SHUKAH_TOKEN"
Response Shukah đã capture. 200, 731 ms.
{
"client_id": 356259,
"odoo_id": "1342170",
"contact_phone": "+966500000000",
"status": "active",
"email_address": "user@example.com",
"first_name": "Test",
"last_name": "User",
"sex": 1,
"birth_date": "1990-01-01",
"receive_offers": 0,
"push_enabled": 0,
"is_food_truck_user": 1,
"is_cod_disabled": 0
}
Capture trên dev, 2026-10-01 (client 356259); các field cá nhân đã được thay thế. Vào 2026-10-02 body Shukah
và body Locate (với một JWT Locate) lại bằng nhau, từng key một. Type hồ sơ của app
bỏ qua odoo_id, is_food_truck_user và is_cod_disabled.
Lỗi đã thấy. Không có token, 401 (capture trên dev, 2026-10-01): body Laravel được hiển thị ở
Body lỗi. Với mọi 401 app xóa token đã lưu.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
client_id, odoo_id, contact_phone, status, email_address, first_name, last_name, sex, birth_date, receive_offers, push_enabled, is_food_truck_user, is_cod_disabled (response) | 13 key ở trên. | Cùng 13 key, kiểu và giá trị cho client 356259 (capture trên dev, 2026-10-01). | Body là drop-in. |
Authorization (header) | Một token opaque của Shukah. | Chỉ JWT Locate. | Token Shukah nhận 401. Xem Token. |
language, x-from-application và các header khác | Có gửi. | Được chấp nhận và bỏ qua. | |
Body 401 | Body Laravel ở trên. | {"status":401,"message":"Unauthorization"} (capture trên dev, 2026-10-01). | Mọi chỗ so khớp theo text, name hay type đều phải đổi. |
| Các response header app-version | Shukah có gửi chúng hay không: Chưa được tài liệu hóa. | Không gửi. URL Locate không chứa api/verify-token. | Xem Request header. |
GET /maeda/client
Thay thế bằng Locate: GET /api/v1/clients
URL dev đầy đủ: https://dev-api.shukah.com/maeda/client?contact_phone=<digits>&key=maeda&language=en-GB
Dùng để tìm người nhận quà theo phone. Request. Bearer token. Query contact_phone (chữ số, app
bỏ +), key=maeda, language.
curl -s -G "$SHUKAH_BASE_URL/maeda/client" -H "Authorization: Bearer $SHUKAH_TOKEN" --data-urlencode "contact_phone=$PHONE" --data-urlencode "key=maeda"
Response Shukah đã capture. 200, 867 ms. Một mảng với một object.
[
{
"client_id": 356259,
"contact_phone": "+966500000000",
"first_name": "Test",
"last_name": "User"
}
]
Capture trên dev, 2026-10-01 (client 356259); các field cá nhân đã được thay thế. Capture đã thay
last_name, nên Shukah có che nó hay không không thấy được: Chưa được tài liệu hóa.
Lỗi đã thấy. Không có token, 401, body Laravel (capture trên dev, 2026-10-01). App chỉ lấy
dòng đầu tiên và coi mảng rỗng là "User not found".
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
client_id (response) | Integer. | Integer. | |
contact_phone (response) | Phone. | Phone như đã lưu, không bị che. | |
first_name (response) | Tên. | Đã trim; trống thành null. Không bị che. | |
last_name (response) | Chưa được tài liệu hóa (không thấy được việc che trong capture). | Bị che: giữ ký tự đầu và cuối, phần giữa thành * (User thành U**r); một hoặc hai ký tự giữ nguyên. | App copy nó từ dòng đầu tiên. Hãy kiểm tra flow tặng quà. |
| Phone không tồn tại | Chưa được tài liệu hóa. | 200 với [], cũng cho client không active. | App đã coi [] là "User not found". |
Authorization (header) | Một token Shukah. | Chỉ JWT Locate. | Xem Token. |
key, language (query) | Có gửi. | Bị bỏ qua. | |
Body 401 | Body Laravel. | {"status":401,"message":"Unauthorization"}. |
GET /maeda/address-book
Thay thế bằng Locate: GET /api/v1/clients/address-book
URL dev đầy đủ: https://dev-api.shukah.com/maeda/address-book (không có segment api/).
Request. Bearer token. Không có tham số nào ngoài language.
curl -s "$SHUKAH_BASE_URL/maeda/address-book" -H "Authorization: Bearer $SHUKAH_TOKEN"
Response Shukah đã capture. 200, 770 ms. Một mảng phẳng gồm 13 địa chỉ cho client 356259; địa chỉ đầu tiên:
{
"id": 162115,
"location_name": "Saihat",
"is_default": 0,
"formatted_address": "King Fahd Rd, Al Olaya, Riyadh 12211",
"area_name": "A12345",
"street": "King Fahd Rd",
"city": "Saihat",
"area": "Eastern Province",
"state": "Al-Qatif",
"zipcode": "32461",
"country": "Saudi Arabia",
"country_code": "SA",
"lat": 24.7136,
"lng": 46.6753,
"image_urls": ["https://example.com/address-photo.jpg"],
"position": 0
}
Capture trên dev, 2026-10-01 (client 356259); các field cá nhân và tọa độ đã được thay thế. Không
địa chỉ nào trong 10 địa chỉ đầu là mặc định. Vào 2026-10-02 list có 15 địa chỉ, tất cả is_default là 0,
sắp theo position từ 0 đến 14 trong khi các id không theo thứ tự (162115, 161996, 162101, …).
Lỗi đã thấy. Không có cho route này. Path /maeda/api/address-book trả 404
{"name":"Not Found","message":"The route maeda/api/address-book could not be found.",…} (capture
2026-10-01): app không gọi nó.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
id | Integer (162115). | Chuỗi 24 ký tự. | App khai báo kiểu của nó là number. |
is_default | 0 hoặc 1. | Boolean. | Một phép thử truthiness chạy được với cả hai. Một phép so sánh strict với 1 thì không. |
location_name, formatted_address, area_name, street, city, area, state, zipcode, country, country_code | Chuỗi. | Chuỗi, null khi thiếu (list shape). | |
lat, lng | Số JSON. | Số JSON trên list. | |
image_urls | Một mảng hoặc null. Bốn trong 15 địa chỉ có URL ảnh (2026-10-02). | Luôn là mảng. [] trên các bản copy Locate của bốn địa chỉ đó (2026-10-02). | Ảnh bị mất khi copy sang Locate. Nguyên nhân: Chưa được tài liệu hóa. |
position | Integer. | Không trả về. | App không đọc nó. |
source, created_at, updated_at | Không trả về. | source (mt_client_inline, mt_address_book hoặc locate) và hai ngày ISO UTC. | App không đọc chúng. |
| Thứ tự | Theo position, từ 0 đến 14 (capture trên dev, 2026-10-02). | created_at mới nhất trước. | Danh sách có thể hiển thị theo thứ tự khác. |
| Số lượng cho client 356259 | 15 địa chỉ (2026-10-02; 13 vào 2026-10-01). | 30 địa chỉ, cùng client, cùng ngày (28 vào 2026-10-01). | Các lần xóa làm trên Shukah không bao giờ tới Locate, và một địa chỉ xuất hiện ba lần. |
| Địa chỉ mặc định | is_default là 0 ở cả 15 (2026-10-02). | true ở 28 trong 30 (2026-10-02). | App lấy mặc định đầu tiên nó thấy. |
Authorization | Một token Shukah. | Chỉ JWT Locate. |
GET /maeda/address-book/:id
Thay thế bằng Locate: GET /api/v1/clients/address-book/:id
URL dev đầy đủ: https://dev-api.shukah.com/maeda/address-book/<id>
Request. Bearer token. Path id, một integer từ list.
curl -s "$SHUKAH_BASE_URL/maeda/address-book/$ADDRESS_ID" -H "Authorization: Bearer $SHUKAH_TOKEN"
Response Shukah đã capture. 200, 286 ms: cùng 16 key như mục list ở trên, phẳng.
{
"id": 162115,
"location_name": "Saihat",
"is_default": 0,
"formatted_address": "King Fahd Rd, Al Olaya, Riyadh 12211",
"area_name": "A12345",
"street": "King Fahd Rd",
"city": "Saihat",
"area": "Eastern Province",
"state": "Al-Qatif",
"zipcode": "32461",
"country": "Saudi Arabia",
"country_code": "SA",
"lat": 24.7136,
"lng": 46.6753,
"image_urls": ["https://example.com/address-photo.jpg"],
"position": 0
}
Capture trên dev, 2026-10-01 (client 356259); text địa chỉ và tọa độ đã được thay thế.
Lỗi đã thấy. Sau một lần delete, 404 (capture trên dev, 2026-10-01):
{"name":"Not Found","message":"Object not found: 162119","code":0,"status":404,"type":"Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException"}.
Địa chỉ của client khác (id 1), 403 (capture trên dev, 2026-10-02):
{"name":"Forbidden","message":"You can only view address that belong to you.","code":0,"status":403,"type":"Symfony\\Component\\HttpKernel\\Exception\\AccessDeniedHttpException"}.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
id | Integer. | Chuỗi 24 ký tự. Id số của Shukah vẫn chạy trong path với các địa chỉ đến từ Shukah. | App so sánh id chọn lần cuối đã lưu dưới dạng chuỗi, nên một integer Shukah đã lưu không còn khớp. |
is_default | 0 hoặc 1. | 0 hoặc 1. | Cùng type, nhưng không phải lúc nào cũng cùng giá trị: địa chỉ 162115 là 0 trên Shukah và 1 trên Locate (2026-10-02). |
lat, lng | Số JSON. | Chuỗi ("24.7136"). | App chuyển bằng Number(). |
| Các field text | Chuỗi. | Chuỗi, "" khi thiếu, không bao giờ là null. | |
image_urls | Một mảng hoặc null. | Luôn là mảng. | Địa chỉ 162115 có một URL ảnh trên Shukah và [] trên Locate (2026-10-02). |
position | Integer. | Không trả về. | |
| Địa chỉ của người khác | 403 với body Laravel ở trên. | 404 Address not found, như với một id không tồn tại (đọc code; một id của người khác chưa được thử live trên Locate). | Status và text app hiển thị sẽ đổi. |
Body 404 | Body Laravel ở trên. | {"status":404,"message":"Address not found"} (capture trên dev, 2026-10-01). Trên dev nó cũng mang một field stack với stack trace của server. | Text app hiển thị sẽ đổi. |
POST /maeda/address-book
Thay thế bằng Locate: POST /api/v1/clients/address-book
URL dev đầy đủ: https://dev-api.shukah.com/maeda/address-book
Request (từ app). JSON với lat và lng dạng chuỗi, is_default (0 hoặc 1),
area_name, location_name và image_urls (một mảng hoặc null). Trước lời gọi app xóa
mọi địa chỉ hiện có cùng location_name, nên một lần lưu là một delete rồi mới đến create này.
# Creates an address on dev. Delete it afterwards.
curl -s -X POST "$SHUKAH_BASE_URL/maeda/address-book" -H "Authorization: Bearer $SHUKAH_TOKEN" -H "Content-Type: application/json" -d '{"lat":"24.7136","lng":"46.6753","is_default":0,"area_name":"Olaya","location_name":"Docs test","image_urls":[]}'
Response Shukah đã capture. 200, 678 ms. Địa chỉ mới, phẳng. Shukah đã điền street, city,
area, state, zipcode, country và formatted address từ tọa độ.
{
"id": 162119,
"location_name": "Docs capture (Shukah)",
"is_default": 0,
"formatted_address": "King Fahd Rd, Al Olaya, Riyadh 12211",
"area_name": "Olaya",
"street": "King Fahd Rd",
"city": "Riyadh",
"area": "Riyadh Province",
"state": "Riyadh Principality",
"zipcode": "12251",
"country": "Saudi Arabia",
"country_code": "SA",
"lat": 24.7136,
"lng": 46.6753,
"image_urls": [],
"position": 13
}
Capture trên dev, 2026-10-01 (client 356259, request body như ở curl nhưng với tên
Docs capture (Shukah)); đã xóa sau đó.
Lỗi đã thấy. Chưa capture lỗi nào.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
lat, lng (body) | Chuỗi từ app. | Số hoặc numeric string; mọi thứ khác được lưu là null. | |
is_default (body) | 0 hoặc 1. | 1, "1" hoặc true nghĩa là mặc định; mọi thứ khác thì không. | Trên Locate một mặc định cũng xóa flag trên các địa chỉ khác. |
area_name, location_name (body) | Có gửi. | Lưu đã trim. | |
image_urls (body) | Mảng hoặc null. | Mảng; chuỗi được trim, chuỗi trống bị bỏ. | |
street, city, area, state, zipcode, country, country_code, formatted_address | Shukah điền từ tọa độ (đã capture lại vào 2026-10-02). Bằng cách nào: Chưa được tài liệu hóa. | Chỉ lưu nếu được gửi, nếu không là null: cả tám giá trị đều trả về null cho body của app (capture trên dev, 2026-10-02). | Một địa chỉ tạo bằng body hiện tại của app không có street hay city trên Locate. |
| Shape response | Chính địa chỉ, phẳng, với id integer và position. | {"status":200,"address":{…}} với id 24 ký tự, source: "locate" và các ngày ISO. | App đọc id, lat, lng ở cấp cao nhất, nên với wrapper chúng bị thiếu. Hãy đọc address. |
| Được lưu ở đâu | Shukah. | Locate, rồi một bản copy best-effort sang Shukah. | Trên dev bản copy không tới được Shukah vào 2026-10-01 hay vào 2026-10-02: bản copy được post tới /maeda/api/address-book, mà Shukah dev trả lời bằng 404. |
PUT /maeda/address-book/:id
Thay thế bằng Locate: PUT /api/v1/clients/address-book/:id
URL dev đầy đủ: https://dev-api.shukah.com/maeda/address-book/<id>
Request (từ app). Path id. JSON với bất kỳ key nào trong street, city, location_name, state,
zipcode, country_code, country, area, formatted_address, is_default (0 hoặc 1) và
image_urls. Màn hình Edit address của app gửi location_name, area, is_default và
image_urls. Không có lat, lng hay area_name khi update.
# Edits an address on dev. Use one you created.
curl -s -X PUT "$SHUKAH_BASE_URL/maeda/address-book/$ADDRESS_ID" -H "Authorization: Bearer $SHUKAH_TOKEN" -H "Content-Type: application/json" -d '{"location_name":"Docs test (edited)"}'
Response Shukah đã capture. 200, 245 ms. Địa chỉ đầy đủ, phẳng, với field đã đổi.
{
"id": 162119,
"location_name": "Docs capture (Shukah, edited)",
"is_default": 0,
"formatted_address": "King Fahd Rd, Al Olaya, Riyadh 12211",
"area_name": "Olaya",
"street": "King Fahd Rd",
"city": "Riyadh",
"area": "Riyadh Province",
"state": "Riyadh Principality",
"zipcode": "12251",
"country": "Saudi Arabia",
"country_code": "SA",
"lat": 24.7136,
"lng": 46.6753,
"image_urls": [],
"position": 13
}
Capture trên dev, 2026-10-01 (client 356259, body {"location_name":"Docs capture (Shukah, edited)"}); đã xóa sau đó.
Lỗi đã thấy. Chưa capture lỗi nào. Một id không tồn tại trả 404 Laravel được hiển thị ở
get.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
id (path) | Integer. | Một id 24 ký tự, hoặc chữ số cho một id Shukah. | |
| Các key của body | Các key ở trên; update một phần. | Cùng các key, một phần. Một key gửi là null, "" hoặc khoảng trắng sẽ xóa field (image_urls thành []). | |
is_default | 0 hoặc 1. | Chỉ khi key có trong body. Đặt nó sẽ di chuyển mặc định. Quy tắc mặc định của Shukah: Chưa được tài liệu hóa. | |
| Response | Địa chỉ phẳng, id integer, lat và lng dạng số, position. | Địa chỉ phẳng, id 24 ký tự, lat và lng dạng chuỗi, không có position. | Các key app đọc đều có đủ. |
| Copy sang Shukah | Không áp dụng. | Một bản copy best-effort. Khi không có Shukah id nó tạo một địa chỉ mới ở đó, có thể gây trùng lặp. | Trên dev việc sửa một địa chỉ do Locate tạo không tới được Shukah vào 2026-10-02. Một lần sửa làm trên Shukah cũng không tới được Locate. |
DELETE /maeda/address-book/:id
Thay thế bằng Locate: DELETE /api/v1/clients/address-book/:id
URL dev đầy đủ: https://dev-api.shukah.com/maeda/address-book/<id>
Request. Path id, không có body. App trước tiên biến id thành số bằng toán tử unary plus.
# Deletes an address on dev, permanently. Use one you created.
curl -s -X DELETE "$SHUKAH_BASE_URL/maeda/address-book/$ADDRESS_ID" -H "Authorization: Bearer $SHUKAH_TOKEN"
Response Shukah đã capture. 204 với body rỗng, 286 ms (capture trên dev, 2026-10-01). App
không đọc body.
Lỗi đã thấy. Lần đọc thứ hai của id đã xóa trả 404 Laravel
Object not found: 162119 (capture trên dev, 2026-10-01).
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
id (path) | Integer. | Một id 24 ký tự, hoặc chữ số cho một id Shukah. | Unary plus của app biến một id 24-hex thành NaN, nên lời gọi thành .../address-book/NaN và nhận 404. |
| Thành công | 204, body rỗng. | 200 {"status":200}. | Không có: app không đọc body. |
Body 404 | Body Laravel. | {"status":404,"message":"Address not found"}. Lần delete thứ hai cũng nhận nó. | |
| Copy sang Shukah | Không áp dụng. | Delete không bao giờ được copy sang Shukah. | Một địa chỉ được sửa qua Locate rồi xóa có thể vẫn còn trên Shukah. |
PUT /maeda/client/:client_id
Thay thế bằng Locate: PUT /api/v1/clients/:client_id
URL dev đầy đủ: https://dev-api.shukah.com/maeda/client/<client_id>
Một route Shukah này phục vụ hai entry registry. Việc sửa hồ sơ và công tắc push-notification
đều gọi PUT /maeda/client/<client_id>. Chúng chỉ được phân biệt bằng body: sửa hồ sơ
mang các key hồ sơ, công tắc push mang {client_id, push_enabled}. Locate tách chúng: entry
này ánh xạ tới PUT /api/v1/clients/:client_id, và update setting ánh xạ tới
PUT /api/v1/clients/setting. App không có lời gọi setting Shukah riêng.
Request (từ app). Path client_id (số, lặp lại trong body). JSON client_id
cộng bất kỳ key nào trong contact_phone, email_address, first_name, last_name, sex (0, 1, 2 hoặc 9),
birth_date (YYYY-MM-DD, hoặc null) và receive_offers (0 hoặc 1).
# Writes the profile on dev. Send the client's current value back.
curl -s -X PUT "$SHUKAH_BASE_URL/maeda/client/$CLIENT_ID" -H "Authorization: Bearer $SHUKAH_TOKEN" -H "Content-Type: application/json" -d "{\"client_id\":$CLIENT_ID,\"receive_offers\":$CURRENT_RECEIVE_OFFERS}"
Response Shukah đã capture. 200, 239 ms (capture trên dev, 2026-10-02, với body
{"client_id":356259,"receive_offers":0}, giá trị hiện tại được ghi lại): hồ sơ 13 field,
với cùng key, type và giá trị như sample verify-token. Locate
trả lời cùng body. App parse nó thành UserServer.
Lỗi đã thấy. Một birth_date sai ("not-a-date"), 422 (capture trên dev, 2026-10-02):
[{"field":"birth_date","message":"The birth date field must match the format Y-m-d."}]. Đó là một
mảng lỗi theo field, không phải object lỗi Laravel. Locate trả lời 400
{"status":400,"message":"birth_date is invalid","stack":"…"} cho cùng body. Các quy tắc validation khác của
Shukah: Chưa được tài liệu hóa.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
client_id (path và body) | Id số, ở cả hai. Shukah có kiểm tra nó với token hay không: Chưa được tài liệu hóa. | Phải bằng client của token trong path, và trong body nếu có gửi, nếu không 400 client_id does not match the authenticated client. | |
contact_phone | Có chấp nhận phone bị đổi hay không: Chưa được tài liệu hóa. | Phải bằng đúng phone đã lưu, kể cả + ở đầu, nếu không 400 contact_phone cannot be changed. Không bao giờ được ghi. | Đừng định dạng lại phone. |
first_name, last_name | Chuỗi. | null hoặc tối đa 100 ký tự sau khi trim, nếu không 400. | |
email_address | Chuỗi. | Mọi chuỗi hoặc null, không kiểm tra định dạng. | |
birth_date | YYYY-MM-DD hoặc null. | Bất cứ thứ gì new Date() đọc được, lưu dưới dạng ngày UTC. null xóa nó. "" hoặc giá trị xấu là 400 birth_date is invalid. | |
sex | 0, 1, 2 hoặc 9. | 1 nam, 2 nữ. Mọi giá trị khác được lưu là không rõ và đọc lại là 0. | Một 9 của Shukah đọc là không rõ sau khi chuyển. |
receive_offers | 0 hoặc 1. | 1, "1" hoặc true nghĩa là bật, mọi thứ khác là tắt. | |
push_enabled | Được chấp nhận trên route này: công tắc push dùng nó. | Bị bỏ qua. Lời gọi trả 200 với hồ sơ không đổi. | Chuyển công tắc sang update setting, nếu không nó lặng lẽ không làm gì. |
| Response | Hồ sơ 13 field (capture trên dev, 2026-10-02). | Cùng hồ sơ 13 field (capture trên dev, 2026-10-01 và 2026-10-02). | |
| Lỗi | 422 với một mảng {field, message} (đã capture cho birth_date, 2026-10-02). | 400 {"status":400,"message":"…"}, chỉ kiểm tra lỗi đầu tiên. Trên dev body cũng có field stack. | App hiển thị message, nên nó mất tên field, và status đổi từ 422 sang 400. |
Authorization | Một token Shukah. | Chỉ JWT Locate. | |
| Copy sang Shukah | Không áp dụng. | Không được copy. | Mọi thứ vẫn đọc hồ sơ từ Shukah sẽ giữ giá trị cũ. |
PUT /maeda/client/:client_id
Thay thế bằng Locate: PUT /api/v1/clients/setting
URL dev đầy đủ: https://dev-api.shukah.com/maeda/client/<client_id>
Cùng route Shukah với update profile. Nó là công tắc push khi
body chỉ là {client_id, push_enabled}.
Request (từ app). JSON {"client_id": <id>, "push_enabled": 0 or 1}.
# Writes the push setting on dev. Send the current value back.
curl -s -X PUT "$SHUKAH_BASE_URL/maeda/client/$CLIENT_ID" -H "Authorization: Bearer $SHUKAH_TOKEN" -H "Content-Type: application/json" -d "{\"client_id\":$CLIENT_ID,\"push_enabled\":$CURRENT_PUSH_ENABLED}"
Response Shukah đã capture. 200, 252 ms (capture trên dev, 2026-10-02, với body
{"client_id":356259,"push_enabled":0}, giá trị hiện tại được ghi lại): hồ sơ 13 field với
push_enabled là 0, như ở sample verify-token. Route setting của Locate
trả lời cùng body. App đọc push_enabled từ đó. Vì giá trị được ghi là giá trị
hiện tại, capture không chứng minh rằng Shukah áp dụng push_enabled trên route này.
Lỗi đã thấy. Chưa capture lỗi nào: Chưa được tài liệu hóa.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
| Route | PUT /maeda/client/<client_id>, route hồ sơ. | PUT /api/v1/clients/setting, không có id trong path. | Trỏ công tắc push sang route mới. |
client_id (body) | Có gửi. Shukah có kiểm tra nó hay không: Chưa được tài liệu hóa. | Bắt buộc. Phải bằng client của token, nếu không 400 client_id does not match the authenticated client. | App đã gửi nó. |
push_enabled (body) | 0 hoặc 1. | Bắt buộc. 1, "1" hoặc true bật nó, mọi thứ khác tắt. Key bị thiếu là 400 push_enabled is required. | |
| Các key khác | Các key hồ sơ được chấp nhận trên cùng route. | Không được chấp nhận: chỉ client_id và push_enabled. | |
| Response | Hồ sơ 13 field (capture trên dev, 2026-10-02). | Hồ sơ 13 field với push_enabled mới (capture trên dev, 2026-10-01 và 2026-10-02). | |
Authorization | Một token Shukah. | Chỉ JWT Locate. | |
| Copy sang Shukah | Không áp dụng. | Không được copy. Shukah giữ giá trị cũ. |
POST /maeda/client/add-device-id
Thay thế bằng Locate: POST /api/v1/clients/add-device-id
URL dev đầy đủ: https://dev-api.shukah.com/maeda/client/add-device-id
Request (từ app). JSON {"device_id": "<device unique id>"}. App gửi nó một lần cho mỗi
bản cài, chỉ khi đã đăng nhập, và ghi lại rằng nó đã được gửi sau một 200.
curl -s -X POST "$SHUKAH_BASE_URL/maeda/client/add-device-id" -H "Authorization: Bearer $SHUKAH_TOKEN" -H "Content-Type: application/json" -d '{"device_id":"00000000-0000-4000-8000-000000000000"}'
Response Shukah đã capture. 200, 236 ms (capture trên dev, 2026-10-02, với device id giả
của lệnh curl ở trên). App bỏ qua câu trả lời.
{
"id": 1074,
"client_id": 356259,
"device_id": "00000000-0000-4000-8000-000000000000"
}
Shukah đã lưu một dòng thiết bị mới (1074) cho người gọi. Không API nào xóa nó, nên dòng giả vẫn
còn trên dev.
Lỗi đã thấy. Chưa capture lỗi nào.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
device_id (body) | Device id. Shukah lưu một dòng thiết bị mới cho người gọi ở mỗi lời gọi (2026-10-02). | Được echo lại. Không validate, không lưu. | |
id (response) | Id của dòng thiết bị mới (1074). | Luôn là 920, cho mọi caller. | Một giá trị giả cố định. |
client_id (response) | Id của người gọi (356259). | Luôn là 356315, không phải id của người gọi. | Một giá trị giả cố định. |
device_id (response) | Được echo. | Được echo; một id mẫu cố định khi body không có. | |
Authorization | App gửi token của nó. Shukah có yêu cầu nó hay không: Chưa được tài liệu hóa. | Không cần, không kiểm tra. | |
| Tác dụng | Một dòng thiết bị được lưu cho người gọi (2026-10-02). | Không có: không có gì được lưu. | App đánh dấu thiết bị là đã gửi và không bao giờ thử lại, dù không có gì được lưu. |
GET /maeda/client/status
Chưa có thay thế từ Locate — bất cứ thứ gì gọi route này vẫn gọi Shukah.
URL dev đầy đủ: https://dev-api.shukah.com/maeda/client/status
Shape của request. Chưa được tài liệu hóa. Snapshot app ngày 2026-02-26 khai báo endpoint này, nhưng không có code nào trong đó gọi endpoint, nên request mà nó sẽ gửi không rõ.
curl -s "$SHUKAH_BASE_URL/maeda/client/status" -H "Authorization: Bearer $SHUKAH_TOKEN"
Response Shukah đã capture. 404, 320 ms (capture trên dev, 2026-10-02): Shukah dev không có
route như vậy.
{
"name": "Not Found",
"message": "The route maeda/client/status could not be found.",
"code": 0,
"status": 404,
"type": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException"
}
Lỗi đã thấy. 404 ở trên.
Những gì đã biết:
- Bảng traffic production ngày 2026-10-02 cho thấy 768 lời gọi tới route này trong 3 ngày, nên có thứ gì đó gọi nó trên production. Client nào gửi chúng: Chưa được tài liệu hóa. App 2.31.5 mới hơn snapshot, nên hãy hỏi team mobile màn hình nào gọi nó.
- Shukah dev trả
404: route bị thiếu trong bản port Laravel trên dev. Production có còn phục vụ nó hay không: Chưa được tài liệu hóa. Nếu app 2.31.5 gọi nó, lời gọi đó hiện fail trên dev. - Không tìm thấy route Locate nào cho nó. Không code nào đã đọc cho audit (snapshot app, auth service,
order-v2 và ba backend Locate khác) gọi nó; route
statusriêng của order-v2 là một kiểm tra disaster-recovery và không liên quan. Route làm gì: Chưa được tài liệu hóa.
GET /maeda/client/delete
Chưa có thay thế từ Locate — app vẫn gọi Shukah.
URL dev đầy đủ: https://dev-api.shukah.com/maeda/client/delete
Cảnh báo: route này xóa tài khoản, và nó là một
GET. Nó chưa bao giờ được gọi khi viết trang này, với bất kỳ token nào. Cố ý không có lệnh chạy được ở đây. Đừng chạy nó với một tài khoản thật, và đừng để một link preview, một crawler hay một health check gọi nó.
Shape của request. GET, không có query nào ngoài language, không có body. Authorization: Bearer <stored token>
là input duy nhất. Lý do mà user chọn trên màn hình xóa không được gửi.
Response Shukah đã capture. Không có: chưa bao giờ được gọi. App không kỳ vọng body. Khi thành công app đăng xuất
user ở local. Một 401 khiến app xóa token đã lưu.
Lỗi đã thấy. Không có.
Những gì đã biết:
- Không route nào trong auth service, point service hay order-v2 xóa một tài khoản. App vẫn gọi route Shukah này, route cần một token mà Shukah chấp nhận (xem Token).
- Shukah làm gì với bản ghi (soft delete, đổi status) và điều đó đến Locate như thế nào: Chưa được tài liệu hóa. Không code Locate nào set một client là đã xóa.
API điểm
GET /maeda/client/points
Thay thế bằng Locate: GET /api/v2/client/points
URL dev đầy đủ: https://dev-api.shukah.com/maeda/client/points
Request. Bearer token, language. Không có tham số nào khác. Một caller thứ hai của app (package food-court)
thêm x-auth-from: SHUKAH.
curl -s "$SHUKAH_BASE_URL/maeda/client/points" -H "Authorization: Bearer $SHUKAH_TOKEN"
Response Shukah đã capture. 200, 251 ms.
{
"id": "356259",
"user_id": "356259",
"points": "514853.64",
"pointsExpirationDate": "2026-11-30"
}
Capture trên dev, 2026-10-02 (client 356259). Vào 2026-10-01 cùng lời gọi trả "128712.41",
nên dữ liệu Shukah dev đã thay đổi trong khoảng đó.
Lỗi đã thấy. Không có token, 401, body Laravel (capture trên dev, 2026-10-01).
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
id | Client id dạng text. | Client id dạng text. | |
user_id | Giống id. | Giống id. | |
points | Chuỗi với hai chữ số thập phân: "514853.64" (2026-10-02). | Chuỗi với tối đa bốn chữ số thập phân: "514405.6788" (cùng client, cùng ngày, với một token Shukah). | App dùng Number(points) || 0. Locate thấp hơn 447.96 điểm, khoảng 0.09%. Dòng ledger mới nhất của Locate cũ hơn của Shukah hai ngày, khớp với khoảng chênh (suy luận). |
pointsExpirationDate | "2026-11-30". | "2026-11-28". | Sớm hơn hai ngày; null trừ khi quy tắc hết hạn áp dụng. |
Authorization | Một token Shukah. | Chỉ token Shukah trên dev hiện nay: một JWT Locate nhận 401 Invalid or expired token (capture trên dev, 2026-10-02). Vào 2026-10-01 cả hai đều chạy. | App phải giữ một token Shukah cho route này. Xem Token. |
| Body lỗi | Body Laravel. | Envelope của point-service. | |
| Các header app-version | Shukah có gửi chúng trên URL này hay không: Chưa được tài liệu hóa. | Không gửi. URL Locate cũng chứa client/points, nên app sẽ tìm. | Xem Request header. |
GET /maeda/point-rate
Thay thế bằng Locate: GET /api/v2/client/system_configs/point_rates
URL dev đầy đủ: https://dev-api.shukah.com/maeda/point-rate
Public trên Shukah: 200 khi không có token. App chỉ gọi route Locate thay thế ở chế độ Merchant
(enableMerchantService: true trong client settings).
Request. Không có tham số nào ngoài language.
curl -s "$SHUKAH_BASE_URL/maeda/point-rate"
Response Shukah đã capture. 200, 235 ms.
[
{"amount_from": 0, "amount_to": 139, "point_earn": 2},
{"amount_from": 140, "amount_to": 153, "point_earn": 12},
{"amount_from": 154, "amount_to": 250, "point_earn": 16},
{"amount_from": 251, "amount_to": 450, "point_earn": 20},
{"amount_from": 451, "amount_to": null, "point_earn": 30}
]
Capture trên dev, 2026-10-01.
Lỗi đã thấy. Không có.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
amount_from | Integer, bắt đầu từ 0. | Bắt đầu từ 70. | App thêm một dòng bên dưới dòng đầu, nên một tổng dưới 70 hiển thị 0 điểm trên Locate. |
amount_to | Integer, null ở dòng cuối. Các khoảng không chồng lên nhau (139, rồi 140). | Integer, null ở dòng cuối. Các khoảng dùng chung giá trị cuối (140 kết thúc một dòng và bắt đầu dòng kế tiếp). | Một tổng chính xác 140 hoặc 251 có thể khớp hai dòng. |
point_earn | 2, 12, 16, 20, 30. | 2, 4, 10, 16. | Các bậc khác nhau trên dev. |
| Số dòng | Năm. | Bốn: 70-140, 140-251, 251-451, 451 trở lên (capture trên dev, 2026-10-01). | Bảng nào là đúng: Chưa được tài liệu hóa. |
| Câu trả lời rỗng | Chưa được tài liệu hóa. | [] khi tùy chọn chưa được đặt. | App đọc dòng đầu mà không kiểm tra. |
Authorization | Không cần. | Không cần. | |
| Quy tắc credit | Không áp dụng. | order-v2 vẫn tính số điểm một order tích được từ bảng của Shukah. | Thẻ có thể khác với số điểm thực sự được credit. |
GET /maeda/giftcard-code/use
Thay thế bằng Locate: POST /api/v2/client/gift-card-code
URL dev đầy đủ: https://dev-api.shukah.com/maeda/giftcard-code/use?code=<code>
Request. Bearer token. Query code. App chỉ gọi route Locate thay thế ở chế độ Merchant
(enableMerchantService: true).
Cảnh báo: một
GETmà cộng điểm khi code hợp lệ. Nó chưa bao giờ được gọi khi viết trang này.
# Credits points if the code is valid. Use a code you may spend.
curl -s -G "$SHUKAH_BASE_URL/maeda/giftcard-code/use" -H "Authorization: Bearer $SHUKAH_TOKEN" --data-urlencode "code=$GIFT_CODE"
Response Shukah đã capture. Không có: nó cộng điểm. App kỳ vọng sáu key: total_points,
date_created, description, message, points_type, trans_type. Giá trị thật của Shukah: Chưa được
tài liệu hóa.
Lỗi đã thấy. Chưa capture lỗi nào.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
Method và code | GET với ?code=. | POST với {"code":"<code>"} trong body. | Đổi method, URL và nơi đặt code. |
total_points, date_created, description, message, points_type, trans_type (response) | Sáu key mà app parse. Giá trị thật: Chưa được tài liệu hóa. | Cùng sáu key. date_created là yyyy-mm-dd hh:mm:ss theo giờ Ả Rập. | App parse cùng các key ở cả hai chế độ. |
| Kho code | Các code của chính Shukah. | Các code trong merchant database của order-v2. Các code do Shukah phát hành có ở đó không: Chưa được tài liệu hóa. | Một code chạy được trên Shukah có thể bị từ chối. |
Authorization | Một token Shukah. | Cùng cách kiểm tra token như các route điểm (qua /api/v1/users); chưa capture với token. | |
| Khoản credit đáp xuống đâu | Không áp dụng. | Shukah hoặc point service, theo một server flag (mặc định tắt: Shukah trước). Giá trị trên dev: Chưa được tài liệu hóa. | Với flag tắt, số dư Locate chỉ thay đổi sau khi sync. |
| Body lỗi | Chưa được tài liệu hóa. | Nest: {"message":"Unauthorized","statusCode":401} cho token bị thiếu. |
GET /maeda/client/point-history
Thay thế bằng Locate: GET /api/v2/client/point-history
URL dev đầy đủ: https://dev-api.shukah.com/maeda/client/point-history
Request. Bearer token. Không có page hay limit.
curl -s "$SHUKAH_BASE_URL/maeda/client/point-history" -H "Authorization: Bearer $SHUKAH_TOKEN"
Response Shukah đã capture. 200, 2,254 ms: một mảng JSON gồm 8,134 dòng (8,136 vào 2026-10-02). Dòng earn đầu tiên:
{
"shukah_id": 1351762,
"total_points": 0.5,
"date_created": "2026-10-01 10:40:44",
"description": "Points gained by buy item Order ID L07678739",
"message": "",
"points_type": "earn",
"trans_type": "adjustment"
}
Capture trên dev, 2026-10-01 (client 356259), dòng đầu tiên trong 8,134 dòng (capture giữ 10 dòng đầu, tất cả
đều là dòng earn). Các dòng expense không có trong các dòng đã lưu; 14 key của chúng (id, client_id,
merchant_id, order_id, total_points dạng chuỗi như "684.00", status, date_created,
ip_address, total_points_amt, trans_type, points_type, remarks, external_id,
description) lấy từ báo cáo parity của point service,
locate-point-service: docs/reports/2026-07-17-client-api-parity.md (đo vào 2026-07-17).
Lỗi đã thấy. Không có token, 401, body Laravel (capture trên dev, 2026-10-01).
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
| Phân trang | Không có: toàn bộ lịch sử. | page và limit, mặc định 20, tối đa 100. | App không gửi cái nào, nên nó sẽ hiển thị 20 dòng mới nhất. |
shukah_id (earn) | Integer. | Integer, hoặc null cho các dòng Locate đã ghi. | |
total_points (earn) | Một số. | Một số. | Không có chênh thang đo vào 2026-10-02: 2, 2, 2, 2, 10 trên các dòng mới nhất của Shukah (0.5, 0.5, 2.5 vào 2026-10-01). |
date_created | YYYY-MM-DD HH:mm:ss, Riyadh. | Giống vậy. | Dòng mới nhất 2026-10-01 17:00:01 trên Shukah, 2026-09-29 12:45:07 trên Locate (2026-10-02): Locate bị trễ. |
description | Text, ví dụ Points gained by buy item Order ID L07678739. | "" trên 8 trong 9 dòng earn trong 10 dòng đầu, manual credit trên một dòng (2026-10-02). | App sẽ hiển thị một dòng trống. |
message | "". | "". | |
points_type | earn hoặc expenses. | Giống vậy. | |
trans_type | adjustment trên các dòng earn đã capture. | adjustment trên earn, order trên dòng expense đã capture. | |
id của expense | Một integer. | Một chuỗi 24 ký tự. | Type lịch sử của app không có id. |
total_points của expense | Một chuỗi với hai chữ số thập phân. | Một chuỗi với chính xác hai chữ số thập phân ("360.00"). | |
Expense client_id, merchant_id, order_id, status, ip_address, total_points_amt, remarks, external_id | Có trên các dòng expense của Shukah (báo cáo parity tháng 7 năm 2026); chưa capture giá trị. | Có: status luôn là "active", ip_address luôn là "", external_id luôn là null. | |
| Dòng hết hạn | Một dòng earn âm. | Một dòng expense với số tiền dương cho các lần hết hạn từ 2026-09-16; các dòng cũ hơn là dòng earn âm. | |
| Body lỗi | Body Laravel. | Envelope của point-service. |
GET /maeda/point-offer
Thay thế bằng Locate: GET /api/v2/client/point-offers
URL dev đầy đủ: https://dev-api.shukah.com/maeda/point-offer
Public trên Shukah: 200 khi không có token.
Request. Không có tham số nào cho list. App cũng gọi nó với ?id=<id> rồi tự chọn offer
ra khỏi danh sách trả về.
curl -s "$SHUKAH_BASE_URL/maeda/point-offer"
Response Shukah đã capture. 200, 235 ms: năm offer.
[
{"id": 1, "point_amount": 100, "purchased_point_amount": 110, "amount": "40.00"},
{"id": 2, "point_amount": 200, "purchased_point_amount": 240, "amount": "60.00"},
{"id": 3, "point_amount": 300, "purchased_point_amount": 360, "amount": "90.00"},
{"id": 4, "point_amount": 400, "purchased_point_amount": 480, "amount": "120.00"},
{"id": 5, "point_amount": 500, "purchased_point_amount": 600, "amount": "150.00"}
]
Capture trên dev, 2026-10-01.
Lỗi đã thấy. Không có.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
id | Integer, 1 đến 5. | Chuỗi 24 ký tự, ví dụ 6a46104f3dd7b3dd6a261d90. | Đừng bao giờ trộn hai loại: Locate từ chối integer của Shukah. |
point_amount | Integer. | Giá trị bằng nhau vào 2026-10-01. | |
purchased_point_amount | Integer. | Giá trị bằng nhau, nhưng có thể là null khi offer không có giá bằng điểm. | App khai báo kiểu của nó là number. |
amount | Chuỗi với hai chữ số thập phân. | Giá trị bằng nhau vào 2026-10-01. | |
?id= (query) | Trả về toàn bộ danh sách. | Được chấp nhận và bỏ qua: lại toàn bộ danh sách. | Cách tự chọn phía client của app chạy được với các id mới. |
Authorization | Không cần. | Bắt buộc: 401 khi không có token (capture trên dev, 2026-10-01). | Một màn hình hiển thị offer trước khi đăng nhập sẽ lỗi. |
| Thứ tự | Chưa được tài liệu hóa. | Theo sequence do admin đặt, rồi Shukah id. | |
| Body lỗi | Chưa được tài liệu hóa (public). | Envelope của point-service. |
GET /maeda/point-occasion
Thay thế bằng Locate: GET /api/v2/client/point-occasions
URL dev đầy đủ: https://dev-api.shukah.com/maeda/point-occasion
Public trên Shukah: 200 khi không có token.
Request. Không có tham số nào cho list; app cũng gọi nó với ?id=<id> và tự lọc
danh sách.
curl -s "$SHUKAH_BASE_URL/maeda/point-occasion"
Response Shukah đã capture. 200, 249 ms: bảy occasion.
[
{"id": 1, "occasion": "Birthday", "occasion_en": "Birthday", "is_custom": 0},
{"id": 2, "occasion": "Born", "occasion_en": "Born", "is_custom": 0},
{"id": 3, "occasion": "Gift", "occasion_en": "Gift", "is_custom": 0},
{"id": 4, "occasion": "Wedding", "occasion_en": "Wedding", "is_custom": 0},
{"id": 5, "occasion": "Graduation", "occasion_en": "Graduation", "is_custom": 0},
{"id": 6, "occasion": "Thank", "occasion_en": "Thank", "is_custom": 1},
{"id": 7, "occasion": "Other", "occasion_en": "Other", "is_custom": 1}
]
Capture trên dev, 2026-10-01.
Lỗi đã thấy. Không có.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
id | Integer, 1 đến 7. | Chuỗi 24 ký tự. | Đừng bao giờ trộn hai loại. |
occasion | Text tiếng Anh. | Tiếng Anh, hoặc tiếng Ả Rập khi language chính xác là ar. | App gửi ar-SA, nên không bao giờ nhận được nhãn tiếng Ả Rập. |
occasion_en | Text tiếng Anh. | Giá trị bằng nhau vào 2026-10-01. | Type của app đọc occasionEn, nên tên tiếng Anh của nó hiện là undefined ở cả hai phía. |
is_custom | 0 hoặc 1. | Giá trị bằng nhau vào 2026-10-01. | |
?id= (query) | Trả về toàn bộ danh sách. | Bị bỏ qua: lại toàn bộ danh sách. | |
Authorization | Không cần. | Bắt buộc: 401 khi không có token. | |
| Body lỗi | Chưa được tài liệu hóa (public). | Envelope của point-service. |
POST /maeda/point-order
Thay thế bằng Locate: POST /api/v2/client/point-orders
URL dev đầy đủ: https://dev-api.shukah.com/maeda/point-order
Request (từ app). JSON point_offer_id (string), to_client_id (string), payment_type
(point, hoặc với thanh toán online là giá trị payment từ common settings: payfort,
hyperpay hoặc checkout), và tùy chọn point_occasion_id và occasion (text tự do). Không có
idempotency key: một POST được thử lại tạo order thứ hai.
Cảnh báo: tạo một order.
payment_typepointlàm điểm di chuyển ngay (người gửi trả một markup: 110 cho 100). Chỉ thửcheckout, vốn ở lại trạng thái chưa thanh toán. Mỗi loại được gọi một lần trên dev ngày 2026-10-02, được người dùng chấp thuận (order 1256 và 1257).
# Creates an unpaid order on dev.
curl -s -X POST "$SHUKAH_BASE_URL/maeda/point-order" -H "Authorization: Bearer $SHUKAH_TOKEN" -H "Content-Type: application/json" -d "{\"point_offer_id\":\"$OFFER_ID\",\"to_client_id\":\"$TO_CLIENT_ID\",\"payment_type\":\"checkout\"}"
Response Shukah đã capture. 201, 320 ms: một order checkout tới chính id của client.
{
"point_order_id": 1256,
"payment_point_order_id": "p-1256",
"client_id": 356259,
"to_client_id": 356259,
"point_amount": 100,
"purchased_point_amount": 110,
"amount": "40.00",
"status": "initial_order",
"payment_type": "checkout",
"point_occasion_id": null,
"occasion": "",
"description": ""
}
Capture trên dev, 2026-10-02 (client 356259). Order point (1257, tới một client dev khác) có
cùng mười hai key, với status là successful. Nó làm số dư Shukah giảm 110 và để nguyên số dư
Locate.
Create trả lời với cùng các key như các dòng order của danh sách quà đã gửi.
App cũng kỳ vọng chúng, trừ việc nó khai báo occasion_id: Shukah gửi point_occasion_id (một số
hoặc null), nên occasionId của app luôn là undefined.
Lỗi đã thấy. Chưa capture lỗi nào.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
point_offer_id (body) | Integer dạng text. | Chuỗi 24 ký tự từ danh sách Locate. | Một integer Shukah là 400. |
to_client_id (body) | Chuỗi của id. | Một số nguyên dương; một numeric string được chấp nhận. | |
payment_type (body) | point, payfort, hyperpay hoặc checkout. | Chỉ point hoặc checkout. | payfort và hyperpay là 400. Nếu settings ghi payfort hoặc hyperpay, create lỗi. |
point_occasion_id (body) | Integer dạng text. | Chuỗi 24 ký tự, hoặc không có. | |
occasion (body) | Text tự do. | Đã trim, 1 đến 255 ký tự. | |
| HTTP status | 201. | 200 (capture trên dev, 2026-10-02). | Không có khi app chấp nhận mọi 2xx. |
point_order_id (response) | Integer. | Không trả về. Order id là UUID correlation_id. | Các route pay và get nhận nó trong path. |
client_id, to_client_id, amount, occasion, point_occasion_id, description, payment_point_order_id (response) | App có đọc, và kỳ vọng occasion_id trong khi các dòng order của Shukah có point_occasion_id. | Không trả về. | Object order phải được dựng lại từ các key mới. |
correlation_id, order_no, payment_status, money_amount, order_type (response) | Không trả về. | Mới: UUID, số từ 100000, trạng thái gateway hoặc null, chuỗi hai chữ số thập phân, gift hoặc transfer. | |
status, point_amount, purchased_point_amount, payment_type (response) | Các từ status của app: initial_order, payment_failed, successful, paid. | Cùng các từ đó (một order Locate chỉ đạt tới ba từ đầu). | |
| Flag | Không có. | point cần POINT_ORDER_POINT_ENABLED; tắt trả 403. Bật trên dev (probe 2026-10-01); production chưa xác nhận. | |
| Tự tặng | Được phép. | Được phép với checkout, 400 với point. | |
Số dư sau một order point | Chỉ số dư Shukah giảm (110 cho order 1257). | Chỉ số dư Locate giảm (110 cho order 100012). | Các ledger không được đồng bộ khi tiêu điểm (dev, 2026-10-02, trong vài giây của lần chạy; việc nó có tới sau đó hay không thì chưa được kiểm tra). Hãy đọc số dư và lịch sử ở chính bên tạo order. |
| Body lỗi | Chưa được tài liệu hóa. | Envelope của point-service. |
POST /maeda/point-order/get-description
Thay thế bằng Locate: POST /api/v2/client/point-orders/description
URL dev đầy đủ: https://dev-api.shukah.com/maeda/point-order/get-description
Request (từ app). JSON point_offer_id (string), tùy chọn point_occasion_id (string)
và occasion (text tự do). App gọi nó hai lần cho mỗi order. Nó không ghi gì.
curl -s -X POST "$SHUKAH_BASE_URL/maeda/point-order/get-description" -H "Authorization: Bearer $SHUKAH_TOKEN" -H "Content-Type: application/json" -d '{"occasion":"","point_offer_id":"1","point_occasion_id":"1"}'
Response Shukah đã capture. 200, 857 ms. Một description rỗng.
{
"description": ""
}
Capture trên dev, 2026-10-01 (client 356259), với body trong curl ở trên, và lại vào
2026-10-02 với cùng câu trả lời. Mọi body đã thử vào 2026-10-01 đều trả cùng kết quả: id dạng text, id dạng số, và với text tự do. Tài liệu của point service nói
Shukah đã trả câu đầy đủ vào 2026-09-21
(locate-point-service: docs/integrations/2026-07-16-client-facing-point-apis.md, thay đổi lần cuối
2026-09-22). Vì sao giờ nó rỗng: Chưa được tài liệu hóa.
Lỗi đã thấy. Chưa capture lỗi nào.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
point_offer_id (body) | Integer dạng text. | Chuỗi 24 ký tự. | Một integer Shukah là 400. |
point_occasion_id (body) | Integer dạng text. | Chuỗi 24 ký tự, hoặc không có. | |
occasion (body) | Text tự do. | Text tự do; khi nó không rỗng nó thắng occasion id. | |
description (response) | "" trên dev hôm nay. Câu đầy đủ theo tài liệu ngày 2026-09-21. | You have received a gift Birthday of 100 points from Test User (*****0000) (capture trên dev, 2026-10-01). | Với Shukah ô lời nhắn hiện nay sẽ rỗng. |
| Câu văn | Cùng cách diễn đạt; một khoảng trắng đôi khi không có occasion. | Cùng cách diễn đạt và cùng khoảng trắng đôi. | Đừng trim nó. |
Authorization | Một token Shukah. | Một token Shukah (200 trên dev, 2026-10-02). Một JWT Locate chưa được thử ở đây; cùng bước kiểm tra đó cho nó 401 trên các route point khác. | Xem Token. |
| Body lỗi | Chưa được tài liệu hóa. | Envelope của point-service. |
POST /maeda/order/checkout-payment-standalone
Thay thế bằng Locate: POST /api/v2/client/point-orders/:correlation_id/pay/card
URL dev đầy đủ: https://dev-api.shukah.com/maeda/order/checkout-payment-standalone
Cùng route Shukah này cũng thanh toán order nhà hàng. Mục này nói về việc dùng nó cho point order.
Cảnh báo: tính tiền một thẻ đã lưu tại payment gateway. Không có lệnh chạy được ở đây, và nó chưa bao giờ được gọi khi viết trang này.
Shape của request. JSON {"id": "<saved card id>", "cvv": "<cvv>", "point_order_id": "<order id>"}.
id là card.tokenName của app. point_order_id là một chuỗi: các body payment của app 2.31.5
được capture trên dev vào 2026-10-02 gửi nó là "1252" và "1253".
Response Shukah đã capture. Không có: nó tạo một khoản thanh toán. App kỳ vọng id, status,
reference, 3ds (downgraded, enrolled) và _links (self, actions, redirect.href).
Lỗi đã thấy. Shukah dev trả lời các route thanh toán point-order bằng 422 (được báo cáo vào
2026-10-02, từ app 2.31.5 trên dev):
{"name":"Unprocessable Content","message":"Checkout payment is not configured properly.","code":0,"status":422,"type":"Symfony\\Component\\HttpKernel\\Exception\\HttpException"}.
Shukah dev hiện không nhận được một khoản thanh toán point. Lỗi thanh toán đến từ payment service dưới dạng
4xx riêng của nó.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
id (body) | Id thẻ đã lưu. | Giống vậy. | |
cvv (body) | Mã bảo mật. | Một string hoặc số, 1 đến 8 ký tự. Được forward, không lưu. | |
point_order_id (body) | Một chuỗi như "1252", trong body (app 2.31.5, 2026-10-02). | Được chấp nhận và bỏ qua. Order là UUID correlation_id trong path. | App chỉ giữ pointOrderId; nó phải giữ id mới từ create. |
payment_type (body) | Không gửi trên route này. | Được chấp nhận và bỏ qua. | |
| Response | App kỳ vọng 3ds.downgraded và _links.redirect. | Body của payment service không đổi; sample của nó có 3ds.is_redirect. Một khoản thanh toán bị từ chối có thể không có _links.redirect. | Hãy kiểm tra bước bắt đầu 3-D Secure với một response thật. |
| Flag | Không có. | POINT_ORDER_CARD_ENABLED; tắt trả 403 trước mọi lần đọc. Bật trên dev (probe 2026-10-01); production chưa xác nhận. | |
| Body lỗi | Của chính payment service. | Được chuyển tiếp không đổi cho lỗi thanh toán; nếu không là envelope của point-service. |
POST /maeda/order/checkout-payment-flow
Thay thế bằng Locate: POST /api/v2/client/point-orders/:correlation_id/pay/session
URL dev đầy đủ: https://dev-api.shukah.com/maeda/order/checkout-payment-flow
Cũng được dùng cho order nhà hàng. Mục này nói về point order.
Cảnh báo: mở một payment session tại payment gateway. Không có lệnh chạy được ở đây. Các tài liệu chưa bao giờ gọi nó; app 2.31.5 đã gọi nó trên dev vào 2026-10-02, và Shukah dev trả
422(chưa được cấu hình).
Shape của request. JSON {"point_order_id": "<order id>", "payment_type": "<wallet>", "rememberMe": true or false}.
App 2.31.5 đã gửi {"point_order_id":"1253","payment_type":"applePay","rememberMe":false} (capture
trên dev, 2026-10-02). point_order_id là một chuỗi. Snapshot app cũng cho phép stcpay và card
làm payment_type, nhưng app 2.31.5 gửi STC Pay tới route riêng của nó,
checkout-payment-stcpay.
Response Shukah đã capture. Không có. App kỳ vọng id, payment_session_secret,
payment_session_token và _links.self.href.
Lỗi đã thấy. Lời gọi của app 2.31.5 ở trên, 422 (capture trên dev, 2026-10-02):
{"name":"Unprocessable Content","message":"Checkout payment is not configured properly.","code":0,"status":422,"type":"Symfony\\Component\\HttpKernel\\Exception\\HttpException"}.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
point_order_id (body) | Một chuỗi như "1253" (app 2.31.5, 2026-10-02). | Được chấp nhận và bỏ qua. Order là UUID correlation_id trong path. | |
payment_type (body) | applePay trong capture 2.31.5. Snapshot cũng cho phép stcpay và card. | Được chấp nhận và bỏ qua. Checkout session cung cấp các wallet. | Wallet không còn được chọn ở server. |
rememberMe (body) | Boolean. | true, false, "true" hoặc "false"; mặc định false. Mọi giá trị khác là 400. | |
| Response | App kỳ vọng id, payment_session_secret, payment_session_token, _links.self. | Session của payment service, không đổi, với cùng các key. | |
| Flag | Không có. | POINT_ORDER_CARD_ENABLED, như ở trên. | |
| Body lỗi | Chưa được tài liệu hóa. | Envelope của point-service. |
GET /maeda/points-faq
Thay thế bằng Locate: GET /api/v2/client/points-faq
URL dev đầy đủ: https://dev-api.shukah.com/maeda/points-faq
Public trên Shukah: 200 khi không có token.
Request. Không có tham số.
curl -s "$SHUKAH_BASE_URL/maeda/points-faq"
Response Shukah đã capture. 200, 233 ms: năm mục. Mục đầu tiên (text tiếng Ả Rập được rút ngắn ở đây):
{
"title_ar": "…",
"text_ar": "…",
"title_en": "How many points are worth in the Locate App?",
"text_en": "each point equal to 0.25 SR\r\nthat means, each 4 points equal to one SR"
}
Capture trên dev, 2026-10-01. Mảng năm mục bằng của Locate, kể cả thứ tự key.
Lỗi đã thấy. Không có.
| Field | Shukah | Locate | Ghi chú |
|---|---|---|---|
title_ar, text_ar, title_en, text_en | Chuỗi. | Bằng nhau vào 2026-10-01. | Drop-in. |
Authorization | Không cần. | Bắt buộc: 401 khi không có token (capture trên dev, 2026-10-01). | Một màn hình hiển thị FAQ trước khi đăng nhập sẽ lỗi. |
| Body lỗi | Chưa được tài liệu hóa (public). | Envelope của point-service. | |
Content-Type | application/json | application/json; charset=utf-8 |
GET /maeda/point-order
Chưa có thay thế từ Locate — app vẫn gọi Shukah.
URL dev đầy đủ: https://dev-api.shukah.com/maeda/point-order?page=<n>&per-page=<n>
Đây là tab "Sent gifts": danh sách duy nhất các món quà mà một user đã gửi.
Request. Bearer token. Query page và per-page.
curl -s -G "$SHUKAH_BASE_URL/maeda/point-order" -H "Authorization: Bearer $SHUKAH_TOKEN" --data-urlencode "page=1" --data-urlencode "per-page=20"
Response Shukah đã capture. 200, 251 ms, một mảng trần gồm 20 order cho page=1&per-page=20
(capture trên dev, 2026-10-02). Cái đầu tiên:
{
"point_order_id": 1255,
"payment_point_order_id": "p-1255",
"client_id": 356259,
"to_client_id": 356259,
"point_amount": 200,
"purchased_point_amount": 240,
"amount": "60.00",
"status": "initial_order",
"payment_type": "checkout",
"point_occasion_id": 3,
"occasion": "Gift",
"description": ""
}
App kỳ vọng một mảng order với point_order_id, client_id, to_client_id,
point_amount, purchased_point_amount, amount, status, payment_type, occasion,
occasion_id, description và payment_point_order_id. Shukah gửi point_occasion_id, không phải
occasion_id, nên occasion id của app là undefined. App cũng đọc các response header
x-pagination-total-count và x-pagination-page-count; capture không lưu response
header.
Lỗi đã thấy. Không có.
Những gì đã biết:
- Không route Locate nào liệt kê các point order của một client. Point service và order-v2 chỉ có create,
get theo
correlation_id, description và hai route pay. Không kế hoạch nào nêu một route list. - Gift checkout mở tab này sau khi thanh toán, nên một order tạo qua Locate không hiển thị ở đó.
- Locate có một route get-theo-
correlation_id, nhưng nó mới và không phải là thay thế cho list này. App cũng cóGET /maeda/point-order/<id>trong code, nhưng không màn hình nào gọi nó.
POST /maeda/order/checkout-payment
Chưa có thay thế từ Locate — app vẫn gọi Shukah.
URL dev đầy đủ: https://dev-api.shukah.com/maeda/order/checkout-payment
Cảnh báo: tạo một khoản thanh toán tại payment gateway. Không có lệnh chạy được ở đây.
Shape của request. JSON {"payment_token": "<Checkout.com Frames token>", "point_order_id": <order id>}.
App dùng nó cho quà tặng điểm khi nó lấy một card token từ Checkout.com Frames.
Response Shukah đã capture. Không có. App kỳ vọng cùng các key như route standalone (id,
status, reference, 3ds, _links).
Lỗi đã thấy. Không có.
Những gì đã biết: Locate cung cấp hai cách để thanh toán một point order, một thẻ đã lưu và một session. Một Frames token không có đối tác. App nên dùng lời gọi Locate nào thay thế: Chưa được tài liệu hóa.
POST /maeda/order/checkout-payment-stcpay
Chưa có thay thế từ Locate — app vẫn gọi Shukah.
URL dev đầy đủ: https://dev-api.shukah.com/maeda/order/checkout-payment-stcpay
Cảnh báo: bắt đầu một khoản thanh toán STC Pay. Không có lệnh chạy được ở đây.
Shape của request. JSON {"point_order_id": "<order id>", "environment": "sandbox" or "production"}.
App 2.31.5 đã gửi {"point_order_id":"1252","environment":"sandbox"} (capture trên dev, 2026-10-02):
point_order_id là một chuỗi.
Response Shukah đã capture. Không có. App kỳ vọng một chuỗi (phần bắt đầu STC Pay).
Lỗi đã thấy. Lời gọi của app 2.31.5 ở trên, 422 (capture trên dev, 2026-10-02):
{"name":"Unprocessable Content","message":"Checkout payment is not configured properly.","code":0,"status":422,"type":"Symfony\\Component\\HttpKernel\\Exception\\HttpException"}.
Những gì đã biết: Locate coi STC Pay là một wallet bên trong route pay-session và không dùng một endpoint STC Pay riêng cho point order.
POST /maeda/order/payfort-token
Chưa có thay thế từ Locate — app vẫn gọi Shukah.
URL dev đầy đủ: https://dev-api.shukah.com/maeda/order/payfort-token
Cảnh báo: bắt đầu một khoản thanh toán PayFort. Không có lệnh chạy được ở đây.
Shape của request. JSON với point_order_id, device_id, digital_wallet, type: "GiftOrder" và
tùy chọn promo_code. Dùng cho đường thẻ PayFort và đường Apple Pay của một món quà điểm.
Response Shukah đã capture. Không có. App kỳ vọng một response payment-token; các key của nó: Chưa được tài liệu hóa.
Lỗi đã thấy. Không có.
Những gì đã biết: PayFort nằm ngoài phạm vi của point order Locate ("deferred by design"). Khi giá trị
payment của common settings không phải checkout, app gửi các khoản thanh toán thẻ, Apple Pay và STC
Pay của quà điểm tới PayFort, và những khoản đó không thể dùng Locate. order-v2 có một
route POST /api/v2/client/payments/sdk-token mà, với type: "GiftOrder", chỉ chuyển tiếp lời gọi tới
route Shukah này cùng các header của người gọi. Nó không phải là bản thay thế: nó vẫn cần Shukah và một
token mà Shukah chấp nhận.
POST /maeda/order/payfort-stc-pay-checkout
Chưa có thay thế từ Locate — app vẫn gọi Shukah.
URL dev đầy đủ: https://dev-api.shukah.com/maeda/order/payfort-stc-pay-checkout
Cảnh báo: bắt đầu một khoản thanh toán PayFort STC Pay. Không có lệnh chạy được ở đây.
Shape của request. JSON với type GiftOrder. Các key khác: Chưa được tài liệu hóa.
Response Shukah đã capture. Không có. App kỳ vọng một URL thanh toán STC Pay; các key của nó: Chưa được tài liệu hóa.
Lỗi đã thấy. Không có.
Những gì đã biết: PayFort nằm ngoài phạm vi của point order Locate ("deferred by design"), nên đường STC Pay này vẫn gọi Shukah.