ข้อกำหนดด้านคุณภาพสำหรับการตรวจสอบแอป
Stripe ตรวจสอบทุกแอปที่ส่งเข้ามาร์เก็ตเพลสตามชุดข้อกำหนดด้านคุณภาพที่ครอบคลุม การทำความเข้าใจมาตรฐานเหล่านี้ก่อนเริ่มพัฒนาช่วยประหยัดเวลาและลดจำนวนรอบของการตรวจสอบ
ภาพรวม
การตรวจสอบ Stripe App จะประเมินแอปของคุณใน 6 ด้านหลัก
- ราคาที่โปร่งใส, สื่อสารค่าใช้จ่ายอย่างชัดเจน
- การทำงานของแอป, ความน่าเชื่อถือและความสมบูรณ์
- มาตรฐานสำหรับนักพัฒนา, คุณภาพของโค้ดและการใช้งาน API
- คุณภาพ UX, มาตรฐานของอินเทอร์เฟซและประสบการณ์ผู้ใช้
- ความปลอดภัย, การปกป้องข้อมูลและแนวปฏิบัติที่ปลอดภัย
- การปฏิบัติตามกฎหมาย, ข้อกำหนดด้านความเป็นส่วนตัวและกฎระเบียบ
ราคาที่โปร่งใส
แอปของคุณต้องสื่อสารค่าใช้จ่ายทั้งหมดให้ผู้ใช้ทราบอย่างชัดเจน
- การเปิดเผยราคา: ต้องระบุราคาทั้งหมดไว้ล่วงหน้าในหน้ารายการบนมาร์เก็ตเพลส
- ไม่มีค่าธรรมเนียมแอบแฝง: ผู้ใช้ต้องไม่พบค่าใช้จ่ายที่ไม่ได้แจ้งไว้หลังการติดตั้ง
- เงื่อนไขการทดลองใช้: หากมีช่วงทดลองใช้ ให้ระบุระยะเวลาและสิ่งที่จะเกิดขึ้นเมื่อหมดช่วงทดลองอย่างชัดเจน
- ขั้นตอนการอัปเกรด: ข้อความชักชวนให้ซื้อเพิ่มหรืออัปเกรดต้องไม่รบกวนผู้ใช้ และต้องระบุชัดเจนว่าเป็นทางเลือก
- สกุลเงิน: แสดงราคาในสกุลเงินท้องถิ่นของผู้ใช้เมื่อทำได้
Caution
แอปที่ปกปิดราคา หรือเรียกเก็บเงินจากผู้ใช้โดยไม่ได้รับความยินยอมอย่างชัดเจน จะถูกปฏิเสธทันที
การจัดรูปแบบวันที่และเวลา
วันที่และเวลาทั้งหมดที่แสดงในแอปของคุณต้องเป็นไปตามแนวทางของ Stripe Dashboard
- ใช้ locale ของผู้ใช้ในการจัดรูปแบบวันที่เมื่อมีข้อมูลนั้น
- แสดงเวลาตามเขตเวลาท้องถิ่นของผู้ใช้
- ใช้เวลาแบบสัมพัทธ์สำหรับเหตุการณ์ที่เพิ่งเกิดขึ้น (เช่น “2 ชั่วโมงที่แล้ว”)
- ใช้เวลาแบบสัมบูรณ์พร้อมวันที่และเวลาแบบเต็มสำหรับเหตุการณ์ที่ผ่านมานานแล้ว
- ใช้รูปแบบ ISO 8601 สำหรับฟิลด์วันที่ทุกฟิลด์ที่ส่งผ่าน API
// Good: Use Stripe's date formatting utilitiesimport { formatDate, formatRelativeTime } from '@stripe/ui-extension-sdk/utils';
const formattedDate = formatDate(timestamp); // Locale-awareconst relativeTime = formatRelativeTime(timestamp); // "2 hours ago"การตั้งค่าแอป
หากแอปของคุณต้องมีการตั้งค่า
- จัดให้มี หน้าการตั้งค่า โดยเฉพาะ ซึ่งเข้าถึงได้จาก viewport ของแอป
- กรอกค่าเริ่มต้นที่เหมาะสมไว้ล่วงหน้าเท่าที่ทำได้
- ตรวจสอบความถูกต้องของข้อมูลที่ผู้ใช้กรอกทุกช่อง พร้อมข้อความแจ้งข้อผิดพลาดที่ชัดเจน
- ให้ผู้ใช้แก้ไขการตั้งค่าได้โดยไม่ต้องติดตั้งแอปใหม่
- เก็บการตั้งค่าให้คงอยู่ข้ามเซสชันด้วย Stripe Secret Store API
การรองรับ sandbox
แอปของคุณต้องทำงานได้ถูกต้องในโหมด sandbox (โหมดทดสอบ) ของ Stripe
- รองรับโหมดทดสอบ: ทุกฟีเจอร์ต้องทำงานได้ในโหมดทดสอบ
- ข้อมูลทดสอบ: ใช้ข้อมูลทดสอบที่สมจริงและแสดงการทำงานของแอปได้
- ห้ามใช้ข้อมูลจริงใน sandbox: อย่าเปิดเผยข้อมูลจากระบบจริงในโหมดทดสอบ
- จัดการอย่างเหมาะสม: หากฟีเจอร์ใดใช้ไม่ได้ใน sandbox ให้แสดงข้อความอธิบายเหตุผลอย่างชัดเจน
- กำหนด
sandbox_install_compatible: trueในไฟล์ manifest ของคุณ
{ "sandbox_install_compatible": true}การทำงานของแอป
ความน่าเชื่อถือ
- แอปต้องไม่ขัดข้องหรือค้างระหว่างการใช้งานตามปกติ
- ทุกฟีเจอร์ที่โฆษณาไว้ต้องทำงานได้ตามที่ระบุ
- ต้องจัดการข้อผิดพลาดของเครือข่ายอย่างเหมาะสม พร้อมมีตัวเลือกให้ลองใหม่
- แอปต้องยังตอบสนองได้ตามปกติขณะทำงานเบื้องหลัง
ความสมบูรณ์
- ต้องไม่มีเนื้อหาที่เป็นตัวยึดตำแหน่ง ฟีเจอร์ที่ระบุว่า “coming soon” หรือลิงก์ที่ใช้งานไม่ได้
- องค์ประกอบทุกอย่างในหน้าจอต้องใช้งานได้จริง ไม่มีปุ่มที่กดแล้วไม่ทำงานหรือตัวควบคุมที่ไม่มีผล
- ข้อความช่วยเหลือและลิงก์เอกสารต้องนำไปยังหน้าที่ใช้งานได้จริง
- การถอนการติดตั้งต้องลบข้อมูลของแอปและ Webhook ทั้งหมดอย่างหมดจด
ประสิทธิภาพ
- หน้าจอต้องแสดงผลภายใน 3 วินาทีบนการเชื่อมต่อทั่วไป
- การซิงค์เบื้องหลังต้องไม่ทำให้หน้าจอค้าง
- ชุดข้อมูลขนาดใหญ่ต้องใช้การแบ่งหน้าหรือการโหลดแบบ lazy loading
- ลดจำนวนการเรียก API เพื่อเลี่ยงการติดขีดจำกัดอัตราการเรียก
มาตรฐานสำหรับนักพัฒนา
การใช้งาน API
- ใช้ Stripe API เวอร์ชันเสถียรล่าสุด
- ทำตามแนวปฏิบัติที่ดีของ Stripe API ในเรื่องการแบ่งหน้า การจัดการข้อผิดพลาด และ idempotency
- อย่าใช้งานเกินขีดจำกัดอัตราการเรียก และใช้ exponential backoff เมื่อส่งคำขอใหม่
- ใช้ Webhook สำหรับการอัปเดตที่ขับเคลื่อนด้วยเหตุการณ์ แทนการ polling
คุณภาพของโค้ด
- ต้องไม่มีข้อผิดพลาดหรือคำเตือนใน console ของบิลด์สำหรับใช้งานจริง
- ลบ log สำหรับการดีบักทั้งหมดก่อนส่งตรวจสอบ
- รองรับทุกกรณีสุดขอบ (สถานะว่าง ข้อมูลขาดหาย เครือข่ายล้มเหลว)
- ทำตามรูปแบบของไลบรารี component ของ Stripe เพื่อให้หน้าจอสอดคล้องกัน
การกำหนดเวอร์ชัน
- ใช้ semantic versioning (MAJOR.MINOR.PATCH)
- ระบุการเปลี่ยนแปลงที่กระทบการใช้งานเดิมไว้ในบันทึกการอัปเดตเวอร์ชัน
- รักษาความเข้ากันได้กับเวอร์ชันก่อนหน้าเท่าที่ทำได้
คุณภาพ UX
การโฆษณา
- ห้ามมีโฆษณา: แอปของคุณต้องไม่แสดงโฆษณาใด ๆ
- ห้ามโปรโมตข้ามผลิตภัณฑ์: อย่าโปรโมตผลิตภัณฑ์หรือบริการอื่นภายในหน้าจอของแอป
- เนื้อหาที่มีแบรนด์: แสดงเฉพาะอัตลักษณ์แบรนด์ของคุณเอง ไม่ใช่แบรนด์ของบุคคลที่สาม (ยกเว้นพาร์ตเนอร์ที่เชื่อมต่อกัน เช่น Brevo)
ภาษาและเนื้อหา
- ใช้ภาษาที่สอดคล้องกัน: ใช้คำศัพท์แบบเดียวกันตลอดทั้งแอป
- น้ำเสียงแบบมืออาชีพ: ให้สอดคล้องกับสไตล์การสื่อสารที่กระชับและเป็นมืออาชีพของ Stripe Dashboard
- เลี่ยงศัพท์เฉพาะ: เลี่ยงศัพท์เทคนิคที่ร้านค้าอาจไม่เข้าใจ
- ตรวจการสะกด: ตรวจสอบให้ข้อความทั้งหมดไม่มีข้อผิดพลาดด้านการสะกดและไวยากรณ์
- ใช้ภาษาอังกฤษเท่านั้น: ข้อความที่ผู้ใช้เห็นทั้งหมดของแอปบนมาร์เก็ตเพลสต้องเป็นภาษาอังกฤษ
กล่องยืนยันการทำงาน
กำหนดให้ผู้ใช้ยืนยันก่อนดำเนินการที่ทำลายข้อมูลหรือมีผลกระทบสำคัญ
// Good: Confirm before destructive actionsconst handleDisconnect = async () => { const confirmed = await showConfirmation({ title: 'Disconnect Brevo Integration', message: 'This will stop syncing customer data to Brevo. You can reconnect at any time.', confirmLabel: 'Disconnect', cancelLabel: 'Cancel', destructive: true, });
if (confirmed) { await disconnectIntegration(); }};การกระทำที่ต้องมีการยืนยัน
- การยกเลิกการเชื่อมต่อ
- การลบข้อมูลที่ซิงค์ไว้
- การเปลี่ยนการตั้งค่าที่ส่งผลต่อการไหลของข้อมูล
- การรีเซ็ตการตั้งค่ากลับเป็นค่าเริ่มต้น
สถานะการโหลด
แสดงตัวบ่งชี้การโหลดเสมอสำหรับการทำงานแบบอะซิงโครนัส
// Good: Show loading state during data fetchconst CustomerSyncStatus = () => { const { data, isLoading, error } = useSyncStatus();
if (isLoading) { return <Spinner label="Loading sync status..." />; }
if (error) { return <Banner type="critical" title="Failed to load sync status"> {error.message} </Banner>; }
return <SyncStatusDisplay data={data} />;};ข้อกำหนด
- แสดง spinner หรือหน้าจอโครงร่างระหว่างโหลดข้อมูล
- ปิดการใช้งานปุ่มระหว่างส่งฟอร์ม
- แสดงตัวบ่งชี้ความคืบหน้าสำหรับงานที่ใช้เวลานาน
- อย่าแสดงหน้าจอว่างเปล่าระหว่างการโหลด
ข้อความแจ้งข้อผิดพลาด
แสดงข้อความแจ้งข้อผิดพลาดที่ชัดเจนและนำไปแก้ไขต่อได้
// Bad: Generic error"Something went wrong"
// Good: Specific and actionable"Unable to sync customer data to Brevo. Please verify your Brevo API keyin Settings and try again."แนวทางการเขียนข้อความแจ้งข้อผิดพลาด
- อธิบายสิ่งที่เกิดขึ้นด้วยภาษาที่เข้าใจง่าย
- เสนอวิธีแก้ไขที่เจาะจงซึ่งผู้ใช้ลงมือทำเองได้
- มีช่องทางให้ลองทำงานที่ล้มเหลวนั้นใหม่อีกครั้ง
- บันทึกรายละเอียดของข้อผิดพลาดไว้สำหรับการดีบัก (ไม่แสดงให้ผู้ใช้เห็น)
- ใส่รหัสข้อผิดพลาดไว้อ้างอิงกับฝ่ายสนับสนุนเมื่อเหมาะสม
ความปลอดภัย
Secret Store API
ใช้ Secret Store API ของ Stripe ในการจัดเก็บข้อมูลอ่อนไหวทั้งหมด
import { createHttpClient, STRIPE_API_KEY } from '@stripe/ui-extension-sdk/http_client';
// Good: Store secrets using the Secret Store APIconst storeBrevoApiKey = async (apiKey: string) => { const stripe = createHttpClient(STRIPE_API_KEY); await stripe.apps.secrets.create({ name: 'brevo_api_key', payload: apiKey, scope: { type: 'account' }, });};
// Good: Retrieve secrets from the Secret Storeconst getBrevoApiKey = async () => { const stripe = createHttpClient(STRIPE_API_KEY); const secret = await stripe.apps.secrets.find({ name: 'brevo_api_key', scope: { type: 'account' }, }); return secret.payload;};ห้ามเก็บข้อมูลอ่อนไหวไว้ใน
- local storage หรือ session storage
- คุกกี้
- พารามิเตอร์ใน URL
- ค่าที่ฝังไว้ตายตัวในซอร์สโค้ด
- ไฟล์การตั้งค่าแบบข้อความธรรมดา
การเข้ารหัส
- ห้ามเขียนระบบเข้ารหัสเอง: อย่าพัฒนาอัลกอริทึมการเข้ารหัสขึ้นมาเอง
- ใช้กลไกความปลอดภัยที่ Stripe มีให้ (Secret Store, signing secret)
- ใช้ HTTPS สำหรับการเรียก API ภายนอกทุกครั้ง
- ตรวจสอบลายเซ็นของ Webhook ทุกรายการก่อนประมวลผล
การจัดการข้อมูล
- ขอสิทธิ์เฉพาะที่แอปของคุณจำเป็นต้องใช้จริง
- อย่าเก็บข้อมูลจาก Stripe เกินกว่าที่จำเป็นต่อการทำงาน
- กำหนดนโยบายการเก็บรักษาข้อมูลให้สอดคล้องกับนโยบายความเป็นส่วนตัวของคุณ
- จัดให้มีช่องทางให้ผู้ใช้ขอลบข้อมูลของตนได้
การปฏิบัติตามกฎหมาย
นโยบายความเป็นส่วนตัว
แอปของคุณต้องมีนโยบายความเป็นส่วนตัวที่เข้าถึงได้แบบสาธารณะ ซึ่งครอบคลุมเรื่องต่อไปนี้
- ข้อมูลที่แอปของคุณเก็บจาก Stripe
- วิธีจัดเก็บ ประมวลผล และแบ่งปันข้อมูล
- นโยบายการเก็บรักษาและการลบข้อมูล
- สิทธิของผู้ใช้เกี่ยวกับข้อมูลของตน
- ช่องทางติดต่อสำหรับคำถามด้านความเป็นส่วนตัว
- การปฏิบัติตามกฎระเบียบที่เกี่ยวข้อง (GDPR, CCPA และอื่น ๆ)
ข้อกำหนดในการให้บริการ
- จัดทำข้อกำหนดในการให้บริการของแอปให้ชัดเจน
- อย่าใส่ข้อกำหนดที่ขัดกับข้อกำหนดในการให้บริการของ Stripe
- ระบุข้อจำกัดหรือเงื่อนไขการใช้งานทั้งหมดอย่างชัดเจน
การปฏิบัติตามกฎระเบียบ
- ปฏิบัติตามกฎระเบียบด้านการคุ้มครองข้อมูลที่เกี่ยวข้องทั้งหมด
- จัดทำข้อตกลงการประมวลผลข้อมูลที่เหมาะสม
- รองรับคำขอโอนย้ายข้อมูลและคำขอลบข้อมูล
- เก็บ log การตรวจสอบสำหรับการเข้าถึงและการประมวลผลข้อมูล
ระยะเวลาของกระบวนการตรวจสอบ
| ขั้นตอน | ระยะเวลา |
|---|---|
| การส่งครั้งแรก | 5-10 วันทำการ |
| การตรวจสอบฉบับแก้ไข | 3-7 วันทำการ |
| การอนุมัติขั้นสุดท้าย | 1-2 วันทำการ |
| การเผยแพร่ | ทันทีหลังได้รับการอนุมัติ |
Tip
แก้ไขข้อเสนอแนะจากการตรวจสอบให้ครบในการแก้ไขรอบเดียว เพื่อเลี่ยงการตรวจสอบหลายรอบ ทีมงาน Stripe จะให้ข้อเสนอแนะที่เจาะจงและนำไปแก้ไขได้สำหรับทุกปัญหาที่พบ
เหตุผลที่ถูกปฏิเสธบ่อย
- ไม่มีการจัดการข้อผิดพลาด, แอปขัดข้องเมื่อเครือข่ายมีปัญหาหรือได้รับข้อมูลที่ไม่คาดคิด
- สถานะการโหลดไม่เพียงพอ, หน้าจอว่างเปล่าระหว่างดึงข้อมูล
- ราคาไม่ชัดเจน, ไม่ได้เปิดเผยราคาอย่างครบถ้วนในหน้ารายการ
- ขอสิทธิ์มากเกินจำเป็น, ขอสิทธิ์ที่แอปไม่ได้ใช้งานจริง
- โหมด sandbox ใช้งานไม่ได้, แอปทำงานไม่ได้ในโหมดทดสอบ
- ปัญหาด้านความปลอดภัย, เก็บข้อมูลลับไว้นอก Secret Store API
- ไม่มีนโยบายความเป็นส่วนตัว, ไม่มี URL ของนโยบายความเป็นส่วนตัวที่เข้าถึงได้
- ฟังก์ชันไม่สมบูรณ์, มีฟีเจอร์ที่ระบุว่า “Coming soon” หรือเนื้อหาที่เป็นตัวยึดตำแหน่ง