# OpenAI phone verification provider abstraction — Luban SMS lessons This note captures reusable lessons from adding Luban SMS as a second SMS provider for Codex/OpenAI phone verification. ## Why provider abstraction matters The original runner assumed 5sim semantics: ```text activation id = id phone field = phone poll = /user/check/ cancel = /user/cancel/ finish = /user/finish/ ``` Luban semantics differ: ```text activation id = request_id phone field = number poll = /getSms?request_id=... cancel/release = /setStatus?request_id=...&status=reject finish = no explicit API; local no-op after browser accepts code ``` Future SMS providers should be added behind functions like: ```text sms_buy(country) -> {activation_id, phone, metadata} sms_check(activation_id) -> wait/success/code/expired sms_cancel(activation_id) sms_finish(activation_id) ``` Keep browser/OpenAI page logic independent from provider-specific APIs. ## Verification before spending When adding a new SMS provider, first do non-spending probes only: 1. Balance/profile endpoint. 2. Service/country lookup endpoint. 3. Resolve target OpenAI/ChatGPT service id. 4. Compile/smoke-test helper scripts. Do not buy a number just to prove integration unless BOSS explicitly asks. ## Luban-specific quirks - API docs say all requests are GET under `https://lubansms.com/v2/api` with `apikey` query parameter. - Python `urllib` without a browser-like `User-Agent` returned HTTP 403; adding a Chrome UA returned HTTP 200. - Service lookup uses `/List?country=&service=OpenAI&language=en&page=1`. - OpenAI can appear as `OpenAI`, `OpenAI / ChatGpt`, etc.; dynamic matching is safer than hardcoding a service id. - `/getSms` states: - `{"code":0,"msg":"wait",...}` -> keep polling - `{"code":0,"msg":"success","sms_code":"123456"}` -> submit code - `{"code":400,"msg":"wrong_status"}` -> expired/closed/no longer usable - Release with `/setStatus?...&status=reject`. ## Logging/redaction Never print: ```text apikey full phone number SMS code OAuth callback code/state ``` Safe logs: ```json {"http":200,"ok":true,"balance":"2.000"} {"ok":true,"selected":{"service_id":"...","country_en":"...","service_name":"OpenAI","provider":"...","cost":0.05}} ``` Phone numbers should be redacted to suffix-only at most, e.g. `[REDACTED]1234`.