Owner review 4, lane F: sign-up data from providers, linked accounts, identity checks because money will move, and Korean caption wording (2026-10-12)
Status: Draft · Date: 2026-10-12 · Lane F of owner review 4, points 10 and 13. Inputs: flat-v2-auth.jsx, flat-v2-ia-and-flows-2026-10-09.md (flow 1), owner-review-3-rulings-2026-10-11.md (sign-up route), the shipped onboarding (packages/features/onboarding/src/onboarding-wizard-screen.tsx), the auth port (packages/app/src/ports/services/auth.service.port.ts), canon/payments.md, the voice guide and terminology guide, lane B of review 3 (§5.4 caption rewrites), and web sources read on 2026-10-12. Audience: the owner. Written in English; Korean only for in-app strings. Law is summarised from secondary sources and marked needs counsel where it decides a product obligation.
Owner, review 4. "10. Sign-up - better. We need to know how much information we will bring in from third party providers so that we can streamline the signup experience. And many of these providers can be connected; the same person can hook it up to multiple providers. So we need to configure that eventually. And I agree with your signup method. But please make sure that since we would eventually involve monetary transaction through toss payments (like an escrow system), we would have to follow the local regulations and practices to sign people in non-anonymously." · "13. As for caption rewrites, make sure you reference local practices and language usages."
0. Evidence tags, method and limits
| Tag | Meaning |
|---|---|
| P | Provider or vendor developer documentation, read 2026-10-12 |
| L | Law, as summarised by a law firm, vendor or ministry page (not the statute text) |
| C | Our code or our docs, with path:line |
| S | A secondary source (blog, news, community post) or my background knowledge |
Limits, stated plainly.
- Naver's developer pages (
developers.naver.com) could not be fetched from this environment. The Naver rows in §1 come from the Auth.js provider reference and community SDK threads (S), not from Naver. Check them against Naver's profile-API page and the 검수 guide before anything is built. - The Apple page returned only a summary; the Apple rows use Apple's well-known documented behaviour (name once, relay email, stable
sub) and are tagged S. - I could not retrieve statute text for 전자상거래법, 전자금융거래법, 특정금융정보법 or 정보통신망법. §4 rests on law-firm and PG vendor pages (L). Nothing in §4 is legal advice.
- KRDS's UX writing guide and 국립국어원's UI-word rules were not retrievable as pages; §6 says which claims rest on what.
- Peer practice (§4.3) is thin: only 크몽, 당근알바 and Toss Payments' own 지급대행 flow gave first-party text. Everything else is marked unverified.
1. What each provider gives
1.1 Field table
| Provider | Field | Exact scope or key | Needs a business app, review or partnership | User can decline? | Reliability |
|---|---|---|---|---|---|
| Kakao Login | Nickname | profile_nickname (닉네임) | None; provided by default (P1) | Yes (optional consent allowed) | Always present for a Kakao Account login; not unique, not the real name |
| Kakao Login | Profile image | profile_image (프로필 사진) | None; default (P1) | Yes | Present by default; we do not need it (faces rule, canon) |
| Kakao Login | account_email (카카오계정(이메일)) | Biz app or test app (P1, P2) | Yes | Includes a verified flag and a validity flag; Supabase's Kakao page lets you run without it ("Allow users without an email") (P3) | |
| Kakao Login | Name | name (이름) | Biz app + permission to set consent levels, test app before review (P1) | Yes | The Kakao Account name; self-entered at Kakao, not verified by a 본인확인기관 |
| Kakao Login | Phone number | phone_number (카카오계정(전화번호)) | Same; "provision after collecting through Kakao Account" is not settable (P1) | Yes | The KakaoTalk number; one forum thread reports the field is missing from the self-service request form (S) |
| Kakao Login | Birth year / birthday | birthyear, birthday | Same (P1) | Yes | Self-declared at Kakao |
| Kakao Login | Gender / age range | gender, age_range (연령대, by Korean age) | Same (P1) | Yes | Self-declared |
| Kakao Login | CI | account_ci (CI(연계정보)) | Biz app + permission; a forum answer says the required-consent level is given only if our own general sign-up form requires CI, otherwise optional only (S, forum, 2 threads) | Yes | Kakao states it "is not an identity verification agency", so the CI "cannot replace" 본인인증 (P1). It is a matching key, not proof of who they are. |
| Kakao Sync (간편가입) | Service terms | Kakao shows our terms inside its consent screen | Same biz-app review; consent items are reviewed against what our own sign-up form collects (S, forum) | Per item | Would move our 약관 step into Kakao's screen. Needs counsel for PIPA purposes (who collects the consent). |
| Kakao CI mark / "Kakao CI" | Brand asset | n/a | Partner-only per the brief; I did not find a page to cite | n/a | We use the standard yellow button from the brand guide; unverified |
| Naver Login (secondary source, see §0) | Id | response.id | None | No (always sent) | Stable per app; its format changed once (S, SDK issue #52) |
| Naver Login | Nickname, profile image | nickname, profile_image | Chosen as 제공 정보 in the console; app review (검수) before non-registered users can log in (ruling of 2026-10-11; not re-verified here) | Can be left unfilled by the user | May be null |
| Naver Login | Name, email, mobile | name, email, mobile | Same; sensitive items get questioned at 검수 (S) | Yes, by the user at the consent screen (S) | May be null; age, email, name are typed optional in Auth.js (S) |
| Naver Login | Gender, birthday, birth year, age band | gender ("F", "M", "U"), birthday, birthyear, age | Same | Yes | A 2022 SDK issue reports age, gender, birthday and the image coming back null where they had been present days earlier (S) |
| Sign in with Apple | Name | name scope; fullName on the credential | Apple Developer account and a Services ID/key; no review (S) | Yes, and they can edit it | Sent only on the first authorization. If we do not store it then, it is gone (S) |
| Sign in with Apple | email scope | Same | Yes: "Hide My Email" gives ...@privaterelay.appleid.com, which forwards only if we register our sending domain with Apple (S) | Real or relay; never use it as the identity key | |
| Sign in with Apple | Stable id | sub in the identity token | Same | No | Stable per team; the right key (S) |
| Google Sign-In | Id, email, name, photo, locale | sub; email, email_verified; name, given_name, family_name, picture, locale (P4) | An OAuth client; the basic openid email profile scopes need no verification review (S) | Basic scopes are not individually declinable | sub is "never reused" and the stable key; name, picture, locale "might be provided" (P4). No birth year, gender or phone at the basic scopes. |
Sources: P1 Kakao Login consent items and its Korean version; P2 Kakao prerequisites (items need a biz app and a business-information review, "about 3 to 5 business days"; changing Required to Optional "applies immediately without an additional review"); P3 Supabase: Login with Kakao; P4 Google OpenID Connect; Kakao forum threads on CI consent and consent-item review; Naver: Auth.js Naver reference and naveridlogin-sdk-android issue 52.
1.2 What this means
- Only Kakao offers a rich profile, and only behind a biz app. Name, phone, birth year, gender and CI all need the 비즈 앱 conversion and a review (3 to 5 business days, reviewed against what our own sign-up form collects). Naver is similar behind its 검수. Apple gives a name once and maybe a fake email. Google gives no birth year at all.
- So a provider cannot replace the birth-year step. Two of the four providers (Apple, Google) never supply it, and the others supply a self-declared one. The redesign needs the year for the under-14 gate before consent (PIPA §22-2), and a screen that exists for two providers exists for all.
- None of the provider data is verified identity. Kakao says so in terms about its own CI. The directive of 2026-06-02 (verified identity; nationality from the IdP) is met only by 본인인증, so provider name and birth fields would be overwritten by it later anyway.
- Every extra Kakao field costs review time and a rejection risk ("items you do not collect in your own sign-up form can be rejected"). Asking for fewer fields starts the Kakao project sooner.
2. What sign-up asks today and what a provider could fill
2.1 Sources
- Shipped onboarding (C): value-props → welcome → 출생연도 (under-14 gate on the next step) → 동의 (five rows, three required, no master row) → 이름 (2 to 20) → 플레이 스타일 (stored, read by nothing) → 완료. It writes
displayNameandbirthYear(onboarding-wizard-screen.tsx:221-237) and consents. Account creation itself is email and password for provisioned users only (flow 1 "Today", IA doc §3).OAuthProvideris'kakao' | 'google' | 'apple'(packages/app/src/domain/entities/auth.entity.ts:7); the port is onesignInWithOAuth(provider)(auth.service.port.ts:21); there is nolinkIdentity,unlinkIdentityor identity list on the port. There is no Naver value. - The redesign (C):
flat-v2-auth.jsxdraws four steps, 1/4 출생 연도 → 2/4 약관 동의 → 3/4 이름 → 4/4 첫 시작; the year runs before consent "so the under-14 rule runs first (PIPA §22-2)" (flat-v2-auth.jsx:1634). The entry buttons are iOS Kakao, Naver, Apple and Android Kakao, Naver, Google (flat-v2-auth.jsx:149-150). The name step reads "클럽 멤버에게 보이는 이름이에요" (:772), so it is a display name, not a legal name. - Memory notes (C): verified identity is the directive (KR 본인인증; nationality from the IdP); unified OAuth through Supabase with PKCE and no native SDKs; the profile row is created by the
auto_create_profiletrigger. - Supabase and Naver, changed since the ruling. The ruling said "Naver has no built-in Supabase provider: a one-day spike first". Supabase now has custom OAuth/OIDC providers: Auth Providers › New Provider › Manual configuration, an identifier starting
custom:, client id and secret, and the authorization, token and userinfo URLs; sign-in issignInWithOAuthwith thecustom:identifier. The free plan allows 3 custom providers, Pro unlimited. That makes Naver a configuration, not a build. The spike shrinks to two checks: that Naver's userinfo shape maps cleanly, and how the custom provider behaves under identity linking (§3).
2.2 Field table
| Sign-up field | Kakao | Naver | Apple | Can the step be skipped or prefilled? | |
|---|---|---|---|---|---|
Account key (auth.users) | provider id, always | id | sub | sub | Automatic; no screen |
| Display name (이름, 2 to 20) | profile_nickname (no review) | nickname (may be null) | name, first login only, may be hidden | name ("might be provided") | Prefill; the screen becomes a one-tap confirm when present, a field when empty (Apple second login, Naver null) |
| Birth year (출생연도) | birthyear (biz app + review) | birthyear (review) | none | none | Cannot be skipped for Apple and Google, so it stays one field for everyone; do not request the provider scope |
| Consents (약관 동의) | Kakao Sync could show ours | none | none | none | Cannot be skipped: our own, after the year. A master row (전체 동의) is the shortcut |
account_email (biz app), optional | email | real or relay | email + email_verified | Not asked in the wizard. Used only for linking and recovery (§3). Treat as optional | |
| Real name, birth date, gender, phone, CI, nationality | optional, unverified | optional, unverified | none | none | Not at sign-up. They arrive from 본인인증 before the first money action (§4), and overwrite any provider value |
| First start (어떻게 시작할까요?) | none | none | none | none | Optional ("나중에 할게요" exists); skipped when the sign-up began from an invite, a share link or a next param |
2.3 Shortest flow (recommendation)
Ask each provider for the minimum: the stable id and the nickname. Request no biz-app field at launch.
- Provider button (1 tap, plus the provider's own page).
- 출생연도 (1 field, number pad; the under-14 Notice sits on the same screen as today).
- 약관 동의 (전체 동의 plus the required rows; 1 tap to tick all, 1 to continue).
- 이름, prefilled from the provider nickname when there is one (1 tap to confirm; a field when empty).
- 첫 시작, skipped when an invite or share link started the flow.
That is the redesign's four steps, with step 4 collapsing to one confirm for Kakao and Naver users and for Google users. It keeps the ruled order, needs no Kakao review beyond the default scopes, needs no Naver review beyond basic items, and does not depend on Apple or Google supplying anything. It is also the only design that behaves the same on all four providers.
What this gives up, honestly: a Kakao user could skip the year and name screens entirely if we took birthyear and name. I do not recommend it for three reasons: (a) it needs the biz-app review before launch, (b) it covers one provider of four, so the screen must exist anyway, and (c) the values are self-declared and will be replaced by 본인인증, so we would be collecting data to discard it. If the owner wants the saving later, it is a config change (request the scope, prefill step 2), not a redesign.
Decided by evidence: the year stays; Apple and Google cannot fill it; provider data is not verified identity. Owner's taste: whether Kakao users should be spared one screen at the price of the biz-app dependency (Question F1).
3. One person, several logins
3.1 What Supabase does
Source: Supabase identity linking.
- Automatic linking. A new OAuth sign-in links to an existing user with the same email. Emails must be unique for this to work. Linking to an unverified email is avoided, and when a new identity links, Supabase "will remove any other unconfirmed identities linked to an existing user" (pre-account-takeover protection). SAML SSO users are excluded.
- Manual linking (beta). A signed-in user calls
supabase.auth.linkIdentity({ provider }), is redirected to the provider and back, and the identity is added, even when its email differs. It must be enabled first (dashboard setting; self-hostGOTRUE_SECURITY_MANUAL_LINKING_ENABLED). Native apps can link with an ID token (linkIdentityWithIdToken, which supports Google, Apple, Facebook, Kakao, Keycloak). - Unlinking.
getUserIdentities()lists them;unlinkIdentity()needs a signed-in user with at least two identities. That is the last-method rule, enforced by the server. - Email and password on an OAuth account needs
updateUser({ password }). Signing up by email with an address already used for OAuth returns an obfuscated response and sends no mail (anti-enumeration).
3.2 The edge cases
| Case | What happens | What we do |
|---|---|---|
| Same verified email on two providers (for example Kakao and Google) | Supabase links them automatically | Accept; it is the common case. Show both in 설정 › 계정 |
Email missing or unverified (Kakao without account_email or unverified, Naver null) | No automatic link; the second login makes a second account | Accept at sign-up; reconcile at 본인인증 (below) |
| Apple private relay | The relay address matches nothing else, so it never auto-links | Same as above; never use the relay as a key or for recovery |
| Signs up twice through different providers before verifying | Two accounts, two profiles, possibly two club memberships | Detect at 본인인증: the CI is the same on both (§3.3) |
| Merging two accounts | Supabase has no merge; linkIdentity attaches an identity to one user, and the other user remains | A server-side merge of our own tables (needs counsel for consents and payment history). Prefer blocking the second 본인인증 and routing to "이미 가입한 계정이 있어요" |
| Custom provider (Naver) | Not confirmed whether the custom: provider takes part in automatic email linking | Part of the one-day spike; if not, Naver links only by the manual route or by CI |
3.3 Linking by the CI
CI (연계정보) is a one-way value that a 본인확인기관 derives from the resident number; the 정보통신망법 chapter on 연계정보 (§23-5 and §23-6 in the current table of contents, L) governs its generation and safeguards, and KISA treats it as personal information if it can be combined with other data. In practice:
- Store the CI from our 본인인증 vendor, hashed or encrypted, with a unique constraint on it. The second account that completes 본인인증 collides on that constraint.
- On collision, do not merge silently. Tell the person which login created the first account ("이미 카카오로 가입했어요"), and offer to sign in with it. A merge of data is a manual support action.
- Kakao's own
account_ciis the same idea but is not a 본인확인기관 result; use only the vendor's CI for the constraint. - Whether CI may be stored at all, for how long, and under which consent: needs counsel.
3.4 What 설정 › 계정 shows
(New screen; the shipped Settings has an 계정 section but no provider list.)
- A Group of Cells, one per provider: icon, provider name, the identifier the provider gave (a nickname or masked email, never the relay), and the date linked. Trailing action: 해제 for a linked provider, 연결 for an unlinked one (the provider's own page opens; returning completes
linkIdentity). - Last-method rule: with one identity the 해제 control is absent and a caption says why ("로그인 수단이 하나뿐이면 해제할 수 없어요"); the server rule above is the backstop. An email-only account that never set a password counts one identity.
- 해제 asks for confirmation in a Dialog (a consequential mutation, house rule). Wording: "카카오 연결을 해제할까요?" with 해제 and 닫기 (Toss avoids 취소 for two-button choices, §6).
- Under the list: the verified state ("본인인증 완료" with the date, or a ghost CTA 본인인증하기) because that is what makes the accounts one person.
4. Signing people in non-anonymously because money will move
Read this section as research, not advice. Everything marked needs counsel is a decision a Korean lawyer or the PG must confirm before launch.
4.1 The money model decides the law
Today's code has two rails (canon/payments.md): a manual rail where a member transfers to the 총무's own account and the host or canManageDues confirms, and a PortOne rail where the member pays by card and the server verifies. The owner now says "through Toss Payments (like an escrow system)". The legal weight depends on who holds the money:
| Model | Who touches the money | Regulatory shape |
|---|---|---|
| A. Manual (today): member to 총무's own account | Members and 총무; TwoMore never does | Outside 전자금융거래법 for TwoMore. No identity duty on us beyond our own trust needs |
| B. PG collects, PG pays the club account (지급대행 / 정산 by the PG) | The PG | TwoMore sends instructions only. The PG carries the 전자금융 duties and runs seller KYC (§4.2). Our duty is to feed it verified payee data |
| C. TwoMore receives the money and forwards it to clubs | TwoMore | Reads as 전자지급결제대행 (settlement agency) and needs registration; the registration bar is high (§4.2). Avoid. |
Recommendation: model B. Never model C. "Escrow-like" should mean the PG's own 지급대행 and settlement hold, not TwoMore holding funds.
4.2 Rules, in order
| Topic | What it says | Who it falls on | Effect on us |
|---|---|---|---|
| 전자금융거래법 §2 no. 19 (settlement agency) and §28 (registration) | Intermediating or running the settlement of the price of goods or services by electronic means is 전자지급결제대행 and needs FSC registration. The PortOne legal note puts it as: platforms that "정산을 대행하거나 매개" must register as a PG. Exemption (§28 (3) 2): "자금이동에 직접 관여하지 않고 전자지급거래의 정보만을 단순히 전달하는 경우". Penalty (§49 (5) 5): up to 3 years or a fine up to 20 million KRW. Registration: capital 1 billion KRW (300 million for the small-scale categories), debt ratio within 200%, 5 IT staff with 2+ years, facilities. The PortOne note says 157 firms were registered in June 2024 (L: PortOne) | The platform that moves or settles the money | Do model B. A club fee is the price of a service, so model C is the case the law targets |
| 전자금융거래법 amendment, passed 2025-11-27 | Narrows the definition to payments between third parties by electronic means; adds a carve-out when settlement is "부수적으로" part of business under the e-commerce act and others; requires PGs to hold settlement funds by deposit, trust or guarantee (Arts. 25-4, 25-5; 60% in year one, 80% in year two); enforcement one year after promulgation (L: BKL, a bill summary, not final text) | PGs | Strengthens the case for the PG holding the funds. Needs counsel on whether the carve-out could ever cover us. |
| 전자상거래법 구매안전서비스 (에스크로) | A prepaying online seller must let the consumer use an escrow or a consumer-damage insurance until the goods arrive, with exceptions (credit-card payments, goods delivered online). I could not retrieve §8 and §24 text; the summary is from consumer-protection pages (L: thecheck, KoreaScience) | The 통신판매업자 | A club fee is not a retail sale of goods, so escrow may not be mandatory; needs counsel on whether a paid 번개 is a "통신판매" and who the seller is |
| 통신판매중개자 duties | A platform that only intermediates between sellers and buyers has lighter duties than a seller (it must tell consumers it is not a party to the sale, and so on). I could not retrieve the article text | The platform | Needs counsel. Likely relevant if paid 번개 are open to non-members |
| 특정금융정보법 (AML) CDD / KYC | Financial companies and e-finance operators must identify customers, verify them, and apply enhanced checks to high-risk ones (§5-2). PG industry summaries treat the PG as the obliged party and report that FIU readings reach down to the final payee (2nd and 3rd-tier counterparts) (L: Alchera, vendor blog, treat as indicative) | The PG, not us | Toss Payments does it for model B: see the seller KYC row below. We must be able to supply a verified payee |
| Toss Payments 지급대행 seller KYC | A seller registers and completes 본인인증; sellers who receive 10 million KRW or more in a rolling 7 days are selected for KYC; if KYC is not approved the payout "fails under AML rules"; review takes up to 2 business days; the page does not distinguish personal from business sellers (L, P: Toss Payments) | The seller, which is the club or its 총무 | A 총무 who collects fees by this route will meet identity verification regardless of what we do. Design for it |
| 정보통신망법 §23-2 and 연계정보 | Online services may not collect resident registration numbers except where a law allows or the service is a designated 본인확인기관 (§23-2 and §23-3). The current table lists §23-5 (연계정보 generation) and §23-6 (CI safeguards) (L: elaw table of contents). The section has since been retitled; confirm the current text. | Every service | We never collect a 주민등록번호. A 본인확인기관 (PASS, NICE, KCB) proves identity and returns CI, name, birth date, gender, phone and a domestic/foreign flag |
| Payout account holder name | The settlement account's holder name must match the verified person. Methods: 실명조회 (account number + birth date returns the holder name) is fast; 1원 인증 (send 1 won with a random 4 to 6 digit code in the depositor field; the user types it back) proves they control the account. Both run on 금융결제원 open-banking-based APIs (S: Alchera) | The party paying out (the PG for model B) | Toss Payments' 지급대행 checks the account; we should show the result, not rebuild the check |
| Minors | PIPA: processing a child's (under 14) personal data needs the legal guardian's consent (L: MOJ page quoting the Act); our app refuses under-14 and has no guardian flow (flat-v2-auth.jsx:507-509). Payments by 14 to 18: Civil Act §5 lets a legal guardian cancel acts done without consent (background knowledge, not retrieved) | Us; the PG | Under-14 stays blocked. For 14 to 18 paying fees: needs counsel. A conservative default is 본인인증 plus no card payment under 19 |
4.3 What Korean apps verify, and when
| App | At sign-up | Before paying | Before being paid | Confidence |
|---|---|---|---|---|
| 당근 / 당근페이 | Phone number (SMS) and a neighbourhood check; no 본인인증 | 당근페이 sign-up used phone 본인인증, terms and a 6-digit payment PIN at launch in 2021; top-up limit reported at 500,000 KRW (S, VentureSquare) | Not found | Launch-era, not current |
| 당근알바 | Not required | n/a | Employer and seeker verification in tiers: account, ID, ID plus face match; 금융인증서 added 2025-12-23, shown as badges (P: Byline) | High, for 당근알바 only |
| 번개장터 / 번개페이 | Not found | Not found | A 2018 article says settlement goes to the account after confirmation; no first-party text on identity found | Unverified |
| 크몽 | Account only | Not found | Sellers (전문가) register before they may list: individuals give identity data, business sellers give business documents; the privacy policy lists real name, phone, birth date and CI collected from experts; a settlement-account change re-triggers verification, up to 5 business days (P: 크몽 지원센터) | High |
| 숨고 | Not found | Not found | Not found | Unverified |
| 토스 / 카카오페이 / 배민페이 | 토스: 본인인증 is the account (S, background). 카카오페이: one person one account, refused when the phone is not in the person's name (S, yellowit). 배민: not found | 배민페이: register a card or account in the app; a PIN reset uses name, resident-number prefix and carrier (S) | n/a | Mixed |
| Toss Payments 지급대행 | n/a | n/a | 본인인증 on registration; KYC with documents at 10 million KRW in 7 days (P, §4.2) | High |
The pattern the evidence supports: open marketplaces and social apps let people in with a phone or a social login, and ask for full identity when money flows out to the person (sellers, experts, payouts) or when a financial product is opened (페이, wallets). Identity checks on the paying side are mostly the PG's card or account step, not 본인인증. I found no first-party evidence of 본인인증 required at sign-up for a non-financial community app; the gaps (번개장터, 숨고) are my search failing, not evidence of absence.
4.4 Recommended verification ladder
| Rung | When | What | Why |
|---|---|---|---|
| 0 | Sign-up | Provider login (Kakao, Naver, Apple, Google), birth year, consents, display name. Not anonymous: a provider account is tied to a phone and an email, and the year gate applies. No 본인인증 | Keeps sign-up at a few taps (Naver's own guidance, cited in the ruling, warns that phone verification at sign-up loses people); a provider login is a real account, not a guest |
| 1 | First trust action that is not money: joining a club, hosting, entering a score | 본인인증 once (PASS / NICE / KCB): real name, birth date, gender, phone, CI, domestic or foreign flag. Birth year and nationality are overwritten from it | The directive of 2026-06-02; the same value fixes duplicate accounts (§3.3) |
| 2 | Before paying (a member pays a session fee or dues through the PG) | Rung 1 plus the PG's card or account step. No extra KYC from us. Under 19: needs counsel | The paying side is the PG's customer; asking more adds friction on the busiest screen |
| 3 | Before receiving money (a 총무 or host who will be paid through 지급대행) | Rung 1 plus the PG's seller registration and payout account holder-name check (실명조회, or 1원 인증 when the PG requires it); KYC documents when the PG selects them (10 million KRW in 7 days). For a club account (non-personal), a business or association document; needs counsel | Mirrors 크몽, 당근알바 and Toss Payments' own rule: identity is demanded where money leaves |
The question the owner asked, answered plainly. "Sign people in non-anonymously" does not need 본인인증 at sign-up. It means: a provider login (a real account with a phone or email behind it) plus the birth-year gate at sign-up, and a full 본인인증 before the first trust action; a payout-account name check before any money is received. The law puts the strict duty (registration, AML, KYC) on whoever holds or settles funds. In model B that is the PG, and the PG's own flow already demands 본인인증 from the payee. Putting 본인인증 on every sign-up would not make a payer any safer in law, would cost sign-ups, and would not remove the PG's own check at the payout rung. The one thing that would change this answer is model C: if TwoMore ever holds funds, every user is in scope and everything moves to needs counsel first.
4.5 Questions this raises for the owner
- F2. Money model: confirm model B (PG holds and pays out; TwoMore never holds funds), and that the manual rail stays for clubs that want it.
- F3. Rung 1 trigger: 본인인증 "before the first trust action" is already ruled. Confirm "joining a club" is in that set, or lighten it to hosting, paying and receiving only.
- F4. Under-19 members paying fees: allow with a guardian-cancellation risk, or require a 본인인증 age check and block card payments (a lawyer should confirm).
5. Point 10: what changes
- Auth port and domain.
OAuthProvidergains'naver'(ascustom:naver); the port gainsgetIdentities(),linkIdentity(provider)andunlinkIdentity(provider), with the adapter over Supabase (auth.supabase.ts). Enable manual linking in Supabase. - Profile. A
verified_identityrecord keyed by the user, with the CI (unique, hashed or encrypted), verified name, birth date, gender, phone and nationality,verified_atand the vendor.profiles.birth_yearandnationality_codeare overwritten from it (00228 already says nationality is derived). - Onboarding. Birth year step stays first; name step prefilled from the provider nickname; no provider birth-year scope. Master consent row (already in the redesign).
- Settings. An 계정 screen with the provider Group (§3.4).
6. Point 13: caption wording in Korean
6.1 The norms, with their sources
| Norm | Source |
|---|---|
| 해요체 for everything user-facing; formal 합니다체 only in legal and some settings pages | Our voice-and-tone-guide.md §2; Toss's Voice Tone Maker rule "해요 style: reduce excessive formal and written-style endings" (Byline) |
| Remove Sino-Korean words where an everyday word exists, unless the Sino-Korean word is clearer; "5000원 송금이 완료되었습니다" became "5000원을 보냈어요" | Same Byline article |
| Prefer the active voice | Same article |
| Punctuation follows the component: titles drop the period, plain explanatory text keeps it | Same article. This is the one place where review 3's rule 2 (a one-sentence caption has no final period) departs from Toss's tool. See Question F5. |
| Weed cutting: delete words that change nothing ("앞으로"); do not repeat the title in the body; say only what must be checked now | Toss's 8 writing principles |
| Easy to speak: avoid Sino-Korean, written-language and long-breath sentences; one message per sentence; read it aloud | Same, principle 5 ("Easy to read가 아니라 speak") |
| Suggest, do not force or frighten | Same, principle 6 |
| Universal words: no slang, no trend words | Same, principle 7 |
| Two-button choices: avoid "취소"; use "닫기" or "다음에". Screen transitions: "확인" or "다음". Single-CTA requests end in "~하기" | Toss UX writer interview |
| Spacing: 보조 용언 (such as 주다 in "해 주세요") is spaced by rule, and joined is also allowed; pick one and keep it. 하다 and 지다 stay joined | 한글 맞춤법 제47항 (via 국립국어원 article and summary); I did not retrieve the rule text itself |
| KRDS (digital government design system): principles of simplicity and ease; a separate private "디지털 정부 서비스 표준 UX 라이팅 가이드라인" exists | Design Compass, DI Today. I could not retrieve KRDS's own wording rules, so I cite nothing from them. |
| 당근's and 카카오뱅크's own writing guidance | Not found. Our voice guide records their speech level (당근 해요체; 카카오뱅크 해요체, mixing 합니다체 for financial confirmations) from earlier research, not re-checked here. I have no first-party caption text to quote from either, and will not invent any. |
6.2 The 32 rewrites reviewed
Review 3 lists 32 changed strings in 25 table rows (a row may cover several strings, for example #8, #22, #23, #24). I review the rows. "Keep" means review 3's rewrite stands. A star marks a taste decision for the owner.
| # | Original | Review 3 rewrite | My revision | Rule or source |
|---|---|---|---|---|
| 1 | 경기가 끝났어요. 점수를 입력해 주세요 | 경기가 끝났어요 | Keep | Toss: do not repeat the title (principle 3) |
| 2 | 상대 팀 확인을 기다려요 / 상대가 동의했어요 / 호스트가 확정했어요 | (delete) | Keep * | Toss principle 3. Taste: a Tag can be read by a screen reader as a bare word; the owner may want the sentence kept on the record page |
| 3 | 숫자 아래는 이전 30일과의 차이예요 | 아래 숫자는 이전 30일과 비교한 변화예요 | Keep | Plain verb over a noun phrase; one template |
| 4 | 4/47경기 표시, 0/47경기 표시 | 47경기 중 4경기, 47경기 중 0경기 | Keep | Spoken form; matches the terminology guide's counter rules |
| 5 | 검색 결과 제공: 네이버 | 네이버 제공 | Keep | Weed cutting |
| 6 | 방문 1회 / 한도 3회 | 방문 1회 | 한도 3회 | Keep | Our house style (MetaSegments) |
| 7 | 계좌번호를 길게 눌러서 복사하세요 | 계좌번호를 길게 누르면 복사돼요 | 계좌번호를 길게 누르면 복사할 수 있어요 | Active voice (Toss); "복사돼요" is passive. "~할 수 있어요" is Toss's form for an ability |
| 8 | 납부 문의는 총무에게 연락해 주세요 / 납부 관련 문의는 총무에게 직접 연락해주세요. | 납부 문의는 총무에게 연락해 주세요 | Keep | One wording; spaced "해 주세요" by 제47항 (joined is also allowed, so this is a house choice) |
| 9 | 확인되면 누적 30,000원으로 완납 처리돼요 | 확인되면 누적 30,000원으로 완납돼요 | Keep | 완납 is the ledger term (terminology guide); dropping 처리 removes a weed |
| 10 | 각 기록을 인정하면 해당 페널티가 즉시 사라져요 | 기록을 인정하면 그 페널티가 바로 사라져요 | Keep | Easy to speak: 즉시 to 바로, 해당 to 그 |
| 11 | 총 비용을 참석 인원으로 나눠 1,000원 단위로 올림한 금액이 참가비가 돼요 | 총 비용을 참석 인원으로 나누고 1,000원 단위로 올려서 참가비를 정해요 | Keep | Active; verb over 올림한 금액 |
| 12 | 불참한 멤버만 ✕를 눌러 표시해 주세요. 나머지는 완료되면 자동으로 기록돼요 | ...완료하면 자동으로 기록돼요. | Keep * | Two sentences, so periods on both. Taste: see F5 |
| 13 | 접수 내역이 나타날 때까지 이 화면을 열어 두세요. 앱을 다시 시작하면 작성 중인 내용은 남지 않아요 | 접수 내역이 나타날 때까지 이 화면을 닫지 말아 주세요. 앱을 다시 시작하면 작성 중인 내용이 사라져요. | 접수 내역이 나타날 때까지 이 화면에서 기다려 주세요. 앱을 다시 시작하면 작성 중인 내용이 사라져요. | Review 3's version is a negative request ("닫지 말아"); Toss and our guide prefer saying what to do |
| 14 | 확인한 날짜와, 설명이나 공개 링크 중 하나가 필요해요 | 확인한 날짜와 함께 설명이나 공개 링크 중 하나가 필요해요 | Keep | Grammar |
| 15 | 수정을 시작할 때 불러온 장소 정보가 기준이에요 | 수정을 시작한 시점의 장소 정보가 기준이에요 | 수정을 시작할 때의 장소 정보가 기준이에요 | "시점" is Sino-Korean and a written-language noun; "때" is what people say (Toss easy to speak) |
| 16 | 테마는 시각 프리셋이에요. 특정 대회나 단체와 관련이 없어요 | 테마는 화면 색을 바꾸는 설정이에요. 특정 대회나 단체와는 관련이 없어요. | Keep | Plain words; two sentences with periods |
| 17 | 모든 알림은 알림함에 표시돼요. 아래에서 푸시로도 받을 항목을 켜세요 | 모든 알림은 알림함에 표시돼요. 푸시로도 받고 싶은 항목은 아래에서 켜 주세요. | Keep | A suggestion in place of an order (Toss principle 6) |
| 18 | 필수 동의는 회원 탈퇴 시에만 철회돼요 | 필수 동의는 탈퇴할 때만 철회돼요 | Keep | 시 to 때 (spoken) |
| 19 | 카카오로 가입했다면 카카오 로그인을 써 주세요 | 카카오로 가입했다면 카카오 로그인을 이용해 주세요 | 카카오로 가입했다면 카카오로 로그인해 주세요 | Review 3 moved to the Sino-Korean 이용 "for register"; Toss's rule is the other way (everyday word first). The verb form also drops the noun phrase * |
| 20 | 안내 참가비는 시작 전까지 입금하면 돼요 | 참가비는 시작 전까지 입금하면 돼요 | Keep | "안내" is a weed |
| 21 | 공지 이번 주 토요일 코트가 변경됐어요 | 공지 이번 주 토요일 코트가 바뀌었어요 | Keep | 변경 to 바뀌다 (Toss: everyday word) |
| 22 | 클럽 일정에 참석한 기록이 없어요 / 추천한 멤버가 없어요 | 아직 클럽 일정에 참석한 기록이 없어요 / 아직 추천한 멤버가 없어요 | Keep | Matches four siblings; a temporary empty reads as 아직 |
| 23 | 시행일 2026. 9. 1. / 시행일: 2026. 5. 18.버전: KR-1.0.0 | 2026년 5월 18일 시행 | 버전 KR-1.0.0 | Keep | One format; the legal text itself stays verbatim. The dotted date is the Korean legal-document form, so keeping it on the legal page only is a defensible alternative * |
| 24 | 1인당 20,000원, 매월 5일 납부 / 매월 5일 납부 | 1인당 20,000원 | 매월 5일까지 | Keep | One wording per concept |
| 25 | 올림픽공원 테니스장 (a pin caption) | a Section head | Keep | Not a wording change |
Result: 4 revised (#7, #13, #15, #19), 21 kept as written (#23 carries a taste flag). Revisions come from rules review 3 did not apply: active voice (#7), a positive instruction (#13), and everyday words over Sino-Korean ones (#15, #19). #19 reverses a review 3 choice on those grounds.
Taste flags (Question F5 and F6): the final-period rule (rows 12, 16, 17); the deletion of status sentences when a Tag exists (row 2); the dotted date on the legal page (row 23).
6.3 Question F5 in full: the final period
Review 3 fixed "one sentence: no final period; two or more: a period after each". Toss's own tool applies a different rule, by component: titles have no period, plain explanatory text keeps one. Our captions are explanatory text, but they are short support lines, which in practice read like labels. Both rules are defensible; the cost of the review 3 rule is that a caption that gains a second sentence later changes its first sentence's punctuation. Recommendation: keep review 3's rule (a short support line is closer to a label, and the rule is already on the boards and in the verifier), and state in the guide that it is a house choice that departs from Toss's component rule. The owner decides.
6.4 A short Korean wording guide for the terminology guide to link to
- 해요체, 과거는 줄여서 쓴다: 됐어요, 바뀌었어요, 사라져요.
- 한자어보다 일상어: 변경 대신 바뀌었어요, 즉시 대신 바로, 시점 대신 때, 이용 대신 쓰다 또는 동사. 한자어가 더 분명하면 남긴다(완납, 입금).
- 능동형: "복사돼요" 대신 "복사할 수 있어요", "처리돼요" 대신 동사를 쓴다.
- 긍정형으로 할 일을 말한다: "닫지 마세요" 대신 "기다려 주세요".
- 권유는 하되 강요하지 않는다: 사실이나 결과를 말하고("~면 ~돼요"), 사용자가 꼭 해야 할 때만 "~해 주세요".
- 제목에 이미 있는 말은 반복하지 않는다. 있어도 없어도 같은 단어는 뺀다.
- 소리 내어 읽어 본다: 한 문장에 한 가지 말만 담고, 숨이 긴 문장은 나눈다.
- 보조 용언은 띄어 쓴다: "해 주세요", "알려 드려요". 하나로 정하고 한 가지로만 쓴다(붙여 쓰기도 허용되지만 섞지 않는다).
- 마침표: 한 문장은 마침표 없이, 두 문장 이상은 문장마다(마지막 포함). 이는 우리 하우스 스타일이며 토스의 컴포넌트별 규칙과는 다르다.
- 버튼과 선택지: 두 선택지에서 "취소"를 쓰지 않고 "닫기"나 "다음에"를 쓴다.
- 숫자와 구분: "47경기 중 4경기", 둘 이상의 사실은 "|"로 나눈다. 쉼표와 슬래시로 잇지 않는다.
7. Questions for the owner (few, concrete)
- F1. Keep the shortest flow (provider id and nickname only, birth year always asked), or take Kakao's name and birth year behind the biz-app review to spare Kakao users two screens? Recommendation: keep it; revisit after launch.
- F2. Confirm the money model: the PG holds and pays out; TwoMore never holds funds.
- F3. Is "joining a club" part of the first trust action that triggers 본인인증, or only hosting, paying and receiving?
- F4. Under-19 members: may they pay by card, pending counsel?
- F5. Final period on single-sentence captions: keep review 3's no-period rule (recommended) or follow Toss's component rule?
- F6. The dotted date
2026. 5. 18.on the legal pages: keep (the legal-document convention) or use2026년 5월 18일everywhere?
8. Implementation
Wizard and sign-in (kit and boards)
- [ ]
flat-v2-auth.jsx: step 3 (이름) shows the provider nickname prefilled with a one-tap confirm when present; add a frame "empty" for Apple second login and Naver null. Leave the four steps and the ruled order alone. - [ ]
flat-v2-auth.jsx: add the Naver button to the verified-identity wording of the entry spec; no new components. - [ ] A new
flat-v2-settings-accountframe set (or an 계정 section on the existing settings board): provider Group of Cells with 연결 and 해제, the last-method caption, 해제 Dialog, and the 본인인증 status row. Uses existing Cell, Dialog and CaptionRow only. - [ ]
flat-v2-ia-and-flows-2026-10-09.mdflow 1: record that the Kakao/Naver custom-provider spike is shortened by Supabase's custom OAuth providers; add the verification ladder (§4.4) as the sign-up and money rules. - [ ] Library: Cell (trailing ghost action), Dialog (two-button wording 해제 / 닫기).
Code and schema (after owner rulings, not now)
- [ ]
packages/app/src/domain/entities/auth.entity.ts:OAuthProvideradds'naver'(mapped tocustom:naver). - [ ]
auth.service.port.tsandadapters/supabase/auth.supabase.ts:getIdentities,linkIdentity,unlinkIdentity; enable manual linking in the Supabase project. - [ ] Migration:
verified_identities(user id, hashed CI with a unique constraint, verified name, birth date, gender, phone, nationality,verified_at, vendor), with its own RLS and an explicit GRANT;profiles.birth_yearandnationality_coderewritten from it. PII rules apply (no PII in JSONB). - [ ] Confirm with counsel before storing CI: retention, consent, hashing.
Copy
- [ ] Apply the four revisions (#7, #13, #15, #19) to the caption strings that review 3 already queued (
yarn i18n:apply-copy-plan), and update the voice guide link target with §6.4. - [ ]
terminology-guide.mdandvoice-and-tone-guide.md: link §6.4 as the Korean wording guide; state the final-period rule as a house choice (pending F5). - [ ] The house-style gate: add 즉시, 시점, 변경 and 이용해 (as a verb in captions) to the near-duplicate or house-style checks only after the owner rules on F5 and #19.
9. Sources
Providers: Kakao Login consent items (EN) · (KO) · Kakao prerequisites · Supabase: Kakao · Supabase: identity linking · Supabase: custom OAuth/OIDC providers · Google OpenID Connect · Auth.js Naver · Naver Android SDK issue 52 · Kakao forum: CI consent · Kakao forum: consent-item review FAQ.
Law and money: PortOne: partner settlement law note · BKL: 전자금융거래법 amendment · Toss Payments: seller KYC · Toss Payments: amendment note · thecheck: 구매안전서비스 · KoreaScience: Safety Transaction Service · Alchera: PG KYC · Alchera: 1원 인증 · elaw: 정보통신망법 table of contents · MOJ: under-14 consent.
Peers: Byline: 당근알바 금융인증서 · VentureSquare: 당근페이 · 크몽: 출금 계좌 변경 · 크몽: 전문가 이용가이드.
Writing: 토스 8가지 라이팅 원칙 · 토스 UX writer 인터뷰 · Byline: 토스 보이스톤 메이커 · 국립국어원: 띄어쓰기 · Design Compass: KRDS.