บทความทั้งหมด
Deep diveใช้เวลาอ่าน 7 นาที

แอปของคุณสามารถแสดงชีตคำขอคืนเงินภายในแอปได้ และนี่คือสิ่งที่ Apple ทำหลังจากลูกค้าแตะส่ง

คำขอคืนเงินภายในแอปของ Apple ให้ลูกค้าขอคืนเงินได้โดยไม่ต้องออกจากแอปของคุณ บนชีตที่ Apple สร้างและตรวจสอบเอง นี่คือสิ่งที่ beginRefundRequest ส่งคืน นาฬิกา CONSUMPTION_REQUEST และ 48 ชั่วโมงที่มันเริ่มจับเวลาบนเซิร์ฟเวอร์ของคุณ และปุ่มนี้คุ้มค่าที่จะปล่อยใช้งานหรือไม่

มือถือสมาร์ตโฟนที่กำลังแสดงหน้าจอการตั้งค่าบัญชี ข้าง ๆ มีใบเสร็จกระดาษและเหรียญหนึ่งเหรียญ แสดงถึงคำขอคืนเงินภายในแอปที่ลูกค้าเริ่มได้โดยไม่ต้องออกจากแอป

ประเด็นสำคัญ

  • beginRefundRequest ของ Apple เป็นเมธอด StoreKit 2 ที่แสดงชีตคืนเงินของ Apple เองภายในแอปของคุณ ลูกค้าจะเห็นรายละเอียดการซื้อและรายการรหัสเหตุผล เลือกหนึ่งข้อ แล้วคำขอจะถูกส่งไปยัง Apple คุณไม่ได้สร้างฟอร์มและไม่ได้ตัดสินผลลัพธ์
  • การเรียกนี้ส่งคืนสถานะ success หรือ userCancelled หรือโยน duplicateRequest หรือ failed สถานะ success หมายความว่า App Store ได้รับคำขอแล้ว ไม่ใช่ว่าอนุมัติแล้ว อย่าแสดงการคืนเงินที่ยืนยันแล้วใน UI ของคุณเมื่อได้ success เด็ดขาด
  • หลังจากลูกค้าส่ง Apple ใช้เวลาไม่เกิน 48 ชั่วโมงในการอนุมัติหรือปฏิเสธ สำหรับการซื้อแบบสิ้นเปลือง มันจะส่ง CONSUMPTION_REQUEST ไปยังเซิร์ฟเวอร์ของคุณก่อน และคุณมีเวลาตามปกติ 12 ชั่วโมงในการตอบด้วยข้อมูลการใช้งานหากลูกค้ายินยอม
  • ผลลัพธ์มาถึงเซิร์ฟเวอร์ของคุณในรูปแบบ App Store Server Notification ซึ่งเป็นฟีดเดียวกับที่คุณรับอยู่แล้ว การอนุมัติคือการแจ้งเตือน REFUND การปฏิเสธคือ REFUND_DECLINED คำขอภายในแอปจะเข้าฟีดนั้นเหมือนกับการคืนเงินที่เริ่มบนหน้า reportaproblem ของ Apple ทุกประการ
  • ปุ่มนี้ใช้ได้ตั้งแต่ iOS 15 และ iPadOS 15, Mac Catalyst 15 และ visionOS 1 ดังนั้นแอปใดก็ตามที่รองรับเวอร์ชันเหล่านั้นสามารถแสดงมันได้ตั้งแต่วันนี้
  • เหตุผลทางการเงินคือการคืนเงินที่คุณโต้แย้งได้ดีกว่าการเรียกคืนเงินผ่านบัตรที่คุณโต้แย้งไม่ได้ การเก็บลูกค้าไว้ในกระบวนการของ Apple จะกระตุ้น CONSUMPTION_REQUEST ที่คุณตอบได้ แทนที่จะเป็นการเรียกคืนเงินผ่านธนาคารซึ่งเป็นที่สิ้นสุดและมีค่าธรรมเนียม
  • คำแนะนำเรื่องตำแหน่งวางของ Apple คือให้เรียกมันจากการตั้งค่าบัญชีหรือเมนูช่วยเหลือ ไม่ใช่หน้าจอการซื้อ เพื่อให้ลูกค้าที่ไม่พอใจหามันเจอโดยไม่ต้องโฆษณาการคืนเงินให้คนอื่น ๆ ทั้งหมด

Apple ให้ลูกค้าขอคืนเงินได้โดยไม่ต้องออกจากแอปของคุณเลย การเรียก StoreKit เพียงครั้งเดียวคือ beginRefundRequest จะแสดงชีตคืนเงินของ Apple เองภายในหน้าจอของคุณ ลูกค้าเลือกเหตุผล แล้วคำขอจะถูกส่งไปให้ Apple ตรวจสอบ คุณไม่ได้สร้างฟอร์ม คุณไม่ได้แตะต้องเงิน และคุณไม่ได้ตัดสินผลลัพธ์ สิ่งที่คุณได้คือวิธีวางเส้นทางคืนเงินไว้ตรงจุดที่ลูกค้าที่กำลังหงุดหงิดอยู่แล้ว แทนที่จะสูญเสียเขาไปให้ธนาคารของเขา นี่คือคำขอคืนเงินภายในแอป และคุณควรเข้าใจมันก่อนตัดสินใจว่าจะปล่อยปุ่มนี้หรือไม่

นี่คือส่วนที่สำคัญต่อรายได้ของคุณ ปุ่มนี้ไม่ได้คืนเงินอะไรด้วยตัวมันเอง มันเปิดคำขอขึ้นมา Apple ใช้เวลาไม่เกิน 48 ชั่วโมงในการอนุมัติหรือปฏิเสธ และสำหรับการซื้อแบบสิ้นเปลือง มันจะยิง CONSUMPTION_REQUEST ไปยังเซิร์ฟเวอร์ของคุณก่อน ดังนั้นชีตนี้จึงไม่ใช่การแจกฟรี มันคือกรวยที่นำเข้าสู่การตรวจสอบคืนเงินแบบเดียวกับที่คุณมีอิทธิพลต่อได้อยู่แล้ว และมันสามารถดึงข้อพิพาทกลับมาจากเครือข่ายบัตรก่อนที่มันจะกลายเป็นการเรียกคืนเงินที่คุณโต้แย้งไม่ได้

ชีตคำขอคืนเงินภายในแอปคืออะไรกันแน่

beginRefundRequest เป็นเมธอด StoreKit 2 ที่แสดงชีตคำขอคืนเงินสำหรับ transaction หนึ่งใน window scene ลายเซ็นของมันสั้น: func beginRefundRequest(in scene: UIWindowScene) async throws -> Transaction.RefundRequestStatus เมื่อคุณเรียกมัน ระบบจะแสดงชีตพร้อมรายละเอียดการซื้อของลูกค้าและรายการรหัสเหตุผลให้เลือก Apple เป็นผู้สร้างและควบคุม UI นั้น คุณส่ง scene และ transaction ให้ ไม่มีอะไรอื่น

คำแนะนำของ Apple เรื่องที่จะวางมันไว้ตรงไหนนั้นชัดเจน ให้เรียกฟังก์ชันนี้จากการตั้งค่าบัญชีหรือเมนูช่วยเหลือ เพื่อให้ลูกค้าที่ต้องการคืนเงินหามันเจอในที่ที่เขาจะไปหาการสนับสนุน มันมาพร้อมกับ iOS 15 และ iPadOS 15, Mac Catalyst 15 และ visionOS 1 ดังนั้นแอปใดก็ตามที่รองรับเวอร์ชันเหล่านั้นสามารถแสดงมันได้ตั้งแต่วันนี้

สองวิธีในการเปิดชีต

มีจุดเข้าสองจุด คุณสามารถเรียก beginRefundRequest(in:) บน transaction เฉพาะที่คุณถืออยู่แล้ว ซึ่งจำกัดชีตไว้ที่การซื้อนั้นเพียงรายการเดียว คุณยังสามารถเปิดชีตด้วยตัวระบุผลิตภัณฑ์เมื่อคุณต้องการให้ลูกค้าคืนเงินการซื้อของผลิตภัณฑ์หนึ่ง ไม่ว่าทางใด ชีต รายการเหตุผล และการตัดสินใจล้วนเป็นของ Apple งานของคุณจบลงที่การแสดงมันและอ่านผลลัพธ์

การเรียกส่งคืนอะไร และอะไรที่อาจผิดพลาดได้

เมธอดนี้เป็น async throws ดังนั้นมันจะส่งคืนสถานะหรือโยนข้อผิดพลาด ทั้งสองอย่างเป็นรายการสั้น ๆ และทั้งสองอย่างควรค่าแก่การจัดการ เพื่อให้ UI ของคุณบอกอะไรที่เป็นความจริงหลังจากชีตปิดลง

ผลลัพธ์ประเภทความหมาย
successRefundRequestStatusApp Store ได้รับคำขอคืนเงินแล้ว ส่งแล้ว ไม่ใช่อนุมัติแล้ว
userCancelledRefundRequestStatusลูกค้าปิดชีตโดยไม่ส่ง ไม่มีอะไรถูกส่งไป
duplicateRequestRefundRequestErrorApp Store มีคำขอคืนเงินสำหรับการซื้อนี้อยู่แล้ว
failedRefundRequestErrorการส่งเองล้มเหลว ให้ลูกค้าลองใหม่

เกิดอะไรขึ้นบนเซิร์ฟเวอร์ของคุณหลังจากลูกค้าแตะส่ง

การที่ชีตปิดลงคือจุดเริ่มต้นของกระบวนการ ไม่ใช่จุดจบ Apple ตรวจสอบคำขอและใช้เวลาไม่เกิน 48 ชั่วโมงในการอนุมัติหรือปฏิเสธ สำหรับการซื้อภายในแอปแบบสิ้นเปลือง ก่อนที่มันจะตัดสินใจ App Store จะส่งการแจ้งเตือน CONSUMPTION_REQUEST ไปยังเซิร์ฟเวอร์ของคุณเพื่อขอข้อมูลการใช้งาน หากลูกค้ายินยอมให้แบ่งปันข้อมูลนั้น คุณตอบผ่าน endpoint Send Consumption Information หากเขาไม่ยินยอม คำสั่งของ Apple เองคือไม่ต้องตอบการแจ้งเตือนนั้นเลย

เมื่อ Apple ตัดสินแล้ว ผลลัพธ์จะมาถึงเซิร์ฟเวอร์ของคุณในรูปแบบ App Store Server Notification นั่นคือฟีดเดียวกับที่คุณรับอยู่แล้ว และคำขอภายในแอปจะเข้าสู่มันเหมือนกับการคืนเงินที่ลูกค้าเริ่มบนหน้า reportaproblem ของ Apple ทุกประการ ไม่มีอะไรเกี่ยวกับการจัดการเปลี่ยนไปเพียงเพราะคำขอเริ่มต้นภายในแอปของคุณ

ขั้นตอนอะไรถูกกระตุ้นสิ่งที่คุณทำนาฬิกา
ลูกค้าส่งชีตbeginRefundRequest ส่งคืน successบันทึกไว้ แสดงว่ากำลังรอ ไม่ใช่คืนเงินแล้วทันที
เฉพาะแบบสิ้นเปลือง Apple ถามก่อนการแจ้งเตือน CONSUMPTION_REQUESTส่งข้อมูลการใช้งานหากลูกค้ายินยอม มิฉะนั้นให้เงียบไว้12 ชั่วโมงในการตอบ
Apple อนุมัติการแจ้งเตือน REFUNDเพิกถอนสิทธิ์สำหรับ transaction นั้นไม่เกิน 48 ชั่วโมงในการตัดสิน
Apple ปฏิเสธการแจ้งเตือน REFUND_DECLINEDคงยอดขายไว้ ไม่ต้องเปลี่ยนอะไรไม่เกิน 48 ชั่วโมงในการตัดสิน
นาฬิกาทรายข้างสมาร์ตโฟนและใบเสร็จกระดาษ แสดงถึงการรอไม่เกิน 48 ชั่วโมงหลังจากลูกค้าส่งคำขอคืนเงินภายในแอปไปยัง Apple

ปุ่มนี้ทำให้คุณเสียอะไร และมันช่วยประหยัดอะไรได้บ้าง

การคืนเงินที่คุณโต้แย้งได้ดีกว่าการเรียกคืนเงินที่คุณโต้แย้งไม่ได้

ลูกค้าที่หาเส้นทางคืนเงินภายในแอปของคุณไม่เจอจะไม่ยอมแพ้ เขาจะไปหาธนาคารของเขา การเรียกคืนเงินผ่านบัตรเป็นที่สิ้นสุดกับธนาคาร มันมีค่าธรรมเนียมข้อพิพาท และมันดึงการตัดสินออกไปจากมือของทั้งคุณและ Apple คำขอคืนเงินภายในแอปเก็บลูกค้าคนเดียวกันนั้นไว้ในระบบของ Apple ที่ซึ่งการซื้อแบบสิ้นเปลืองกระตุ้น CONSUMPTION_REQUEST ที่คุณตอบได้และการตัดสินที่คุณมีอิทธิพลต่อได้ การแลกการเรียกคืนเงินที่โต้แย้งไม่ได้กับการตรวจสอบของ Apple ที่โต้แย้งได้คือเหตุผลทางการเงินทั้งหมดของปุ่มนี้

คุณกำลังลดแรงเสียดทานในการคืนเงิน

น้ำหนักถ่วงที่ซื่อสัตย์คือเส้นทางคืนเงินที่มองเห็นได้และแตะครั้งเดียวสร้างคำขอคืนเงินมากกว่าอีเมลสนับสนุนที่ถูกซ่อนไว้ บางคำขอในนั้นคงไม่มีวันเกิดขึ้น นั่นเป็นต้นทุนจริง และนั่นคือเหตุผลที่ Apple บอกให้คุณวางจุดเข้าไว้ในการตั้งค่าบัญชีหรือเมนูช่วยเหลือแทนที่จะเป็นบนหน้าจอการซื้อ คุณต้องการให้ลูกค้าที่ไม่พอใจอยู่แล้วหามันเจอ ไม่ใช่ลูกค้าที่เพียงแค่อยากรู้อยากเห็น

ต้นทุนที่เดินอยู่ตลอดเวลาคือการให้บริการบัญชีที่คืนเงินไปแล้ว

ไม่ว่าการตัดสินจะไปทางไหน มิเตอร์ของการส่งมอบยังคงเดินต่อไปจนกว่าคุณจะลงมือทำตามผลลัพธ์ ทุก ๆ ชั่วโมงที่สิทธิ์ที่คืนเงินไปแล้วยังเปิดใช้งานอยู่ คุณยังคงจ่ายต้นทุนจริงที่อยู่เบื้องหลังมัน: การประมวลผล การเรียก model API พื้นที่จัดเก็บ และการจ่ายเงินให้ครีเอเตอร์หรือพาร์ตเนอร์ใด ๆ ที่ผูกกับการใช้งานของลูกค้าคนนั้น คำขอภายในแอปไม่เปลี่ยนสิ่งนั้น การเพิกถอนอย่างทันท่วงทีเมื่อได้การแจ้งเตือน REFUND ต่างหากที่เปลี่ยน ปุ่มนี้ถูกก็ต่อเมื่อคุณจัดการการแจ้งเตือนที่มันสร้างขึ้นในที่สุดได้ดีเท่านั้น

คุณควรปล่อยคำขอคืนเงินภายในแอปหรือไม่

วางไว้ที่ที่การสนับสนุนอยู่ ไม่ใช่ที่ที่การขายอยู่

ทำตามคำแนะนำเรื่องตำแหน่งวางของ Apple การตั้งค่าบัญชีและเมนูช่วยเหลือคือบ้านที่ถูกต้อง ลิงก์คืนเงินข้าง ๆ paywall ฝึกให้ผู้คนคาดหวังว่าจะได้เงินคืน และมันเชื้อเชิญการคืนเงินเพราะความอยากรู้ที่คุณไม่เคยจำเป็นต้องเสนอ

ทดสอบกระบวนการทั้งหมดใน sandbox ก่อนที่คุณจะไว้ใจมัน

คุณสามารถจำลองเส้นทางทั้งหมดใน sandbox และในการทดสอบ StoreKit ของ Xcode โดยย้ายคำขอจากกำลังรอไปเป็นอนุมัติหรือปฏิเสธ การอนุมัติจะส่งการแจ้งเตือน REFUND ไปยังเซิร์ฟเวอร์ของคุณ และการปฏิเสธจะส่ง REFUND_DECLINED ดังนั้นคุณสามารถพิสูจน์ได้ว่าตัวจัดการของคุณตอบสนองอย่างถูกต้องก่อนที่ลูกค้าจริงจะแตะส่งเสียอีก

จัดการทุกผลลัพธ์ และอย่ากล่าวอ้างเกินจริงเด็ดขาด

แสดงกำลังรอเมื่อ success เสนอให้ลองใหม่เมื่อ failed บอกว่าไม่มีอะไรเปลี่ยนเมื่อ userCancelled และปฏิบัติต่อ duplicateRequest เป็นบันทึกเงียบ ๆ ว่าคำขอก่อนหน้าของลูกค้ายังคงมีผลอยู่ ความผิดพลาดเดียวที่สร้างความเสียหายคือการบอกลูกค้าว่าการคืนเงินของเขาเสร็จสิ้นแล้วทั้งที่สิ่งที่คุณถืออยู่มีเพียงคำขอที่ส่งไปเท่านั้น

RefundHalt จัดการเรื่องที่ตามมาอย่างไร

ชีตภายในแอปเป็นของ Apple สิ่งที่ตามมาหลังจากนั้นเป็นของคุณ และนั่นคือส่วนที่ RefundHalt ดูแล เมื่อลูกค้าส่งคำขอคืนเงินจากภายในแอปของคุณ RefundHalt จะดักจับ CONSUMPTION_REQUEST สำหรับการซื้อแบบสิ้นเปลืองและตอบมันภายในหน้าต่าง 12 ชั่วโมงด้วยหลักฐานการใช้งานที่ช่วยให้ Apple ตัดสิน เมื่อ Apple ตัดสิน มันจะเพิกถอนเมื่อได้ REFUND และคงการเข้าถึงไว้ไม่แตะต้องเมื่อได้ REFUND_DECLINED โดยแต่ละอย่างผูกกับ transaction ที่ถูกต้อง คุณจะสามารถเสนอเส้นทางคืนเงินภายในแอปที่เป็นมิตรกว่าได้โดยไม่ต้องปล่อยการตรวจสอบ หลักฐาน หรือการเพิกถอนไว้กับการวิ่งวุ่นแบบทำมือ

คำถามที่พบบ่อย

beginRefundRequest ทำอะไร?
มันแสดงชีตคำขอคืนเงินของ Apple ภายในแอปของคุณสำหรับ transaction เฉพาะรายการหนึ่ง ลูกค้าจะเห็นรายละเอียดการซื้อและรายการรหัสเหตุผล เลือกหนึ่งข้อ แล้วคำขอจะถูกส่งไปยัง Apple เมธอดนี้ส่งคืนสถานะ success หรือ userCancelled หรือโยน duplicateRequest หรือ failed มันไม่ได้คืนเงินการซื้อด้วยตัวมันเอง เพราะ Apple ตรวจสอบคำขอและใช้เวลาไม่เกิน 48 ชั่วโมงในการตัดสิน
คำขอคืนเงินภายในแอปคืนเงินทันทีเลยหรือไม่?
ไม่ ผลลัพธ์ success หมายความว่า App Store ได้รับคำขอแล้ว ไม่ใช่ว่าอนุมัติแล้ว Apple ใช้เวลาไม่เกิน 48 ชั่วโมงในการอนุมัติหรือปฏิเสธ และสำหรับสินค้าสิ้นเปลือง มันจะขอข้อมูลการใช้งานจากเซิร์ฟเวอร์ของคุณก่อนผ่านการแจ้งเตือน CONSUMPTION_REQUEST แสดงสถานะกำลังรอให้ลูกค้าเห็นเมื่อได้ success อย่าแสดงการคืนเงินที่ยืนยันแล้วเด็ดขาด
iOS เวอร์ชันไหนรองรับคำขอคืนเงินภายในแอป?
iOS 15 และ iPadOS 15, Mac Catalyst 15 และ visionOS 1 เมธอด StoreKit 2 beginRefundRequest(in:) ใช้ได้ตั้งแต่เวอร์ชันเหล่านั้น ดังนั้นแอปใดก็ตามที่รองรับ iOS 15 ขึ้นไปสามารถแสดงชีตคืนเงินของ Apple จากภายในแอปได้
ฉันควรวางปุ่มคืนเงินภายในแอปไว้ที่ไหน?
คำแนะนำของ Apple คือให้เรียกมันจากการตั้งค่าบัญชีหรือเมนูช่วยเหลือ ไม่ใช่จากหน้าจอการซื้อหรือ paywall นั่นวางเส้นทางคืนเงินไว้ในที่ที่ลูกค้าที่ไม่พอใจมองหาการสนับสนุน โดยไม่ต้องโฆษณาการคืนเงินให้ลูกค้าที่ไม่ได้ตั้งใจจะขอ
คำขอคืนเงินภายในแอปดีกว่าการที่ลูกค้าติดต่อธนาคารของเขาหรือไม่?
โดยทั่วไปแล้วใช่ สำหรับรายได้ของคุณ การเรียกคืนเงินผ่านธนาคารเป็นที่สิ้นสุดและมีค่าธรรมเนียม และมันตัดทั้ง Apple และคุณออกจากการตัดสิน คำขอคืนเงินภายในแอปเก็บลูกค้าไว้ในกระบวนการของ Apple ที่ซึ่งการซื้อแบบสิ้นเปลืองกระตุ้น CONSUMPTION_REQUEST ที่คุณตอบได้และการตรวจสอบที่คุณมีอิทธิพลต่อได้ การคืนเงินที่โต้แย้งได้ดีกว่าการเรียกคืนเงินที่โต้แย้งไม่ได้

แหล่งข้อมูลและเนื้อหาเพิ่มเติม

RefundHalt

ระบบอัตโนมัติสำหรับการคืนเงินบน App Store และ Google Play

อ่านต่อ

Deep diveใช้เวลาอ่าน 8 นาที

เมื่อการซื้อบน Google Play ถูกคืนเงินหรือถูก chargeback, Voided Purchases API คือวิธีที่ทำให้คุณรู้

Google Play จะเพิกถอนการซื้อแบบเงียบ ๆ เมื่อมันถูกคืนเงินหรือถูก chargeback. Voided Purchases API คือรายการของออร์เดอร์เหล่านั้น เพื่อให้คุณเพิกถอนสิทธิ์การเข้าถึงได้. นี่คือทุกฟิลด์ หน้าต่าง 30 วัน ตัวเลือก revoke ที่ซ่อนออร์เดอร์ และค่าใช้จ่ายของมัน

Playbookใช้เวลาอ่าน 7 นาที

การแจ้งเตือนการคืนเงินของ App Store สามรายการจะมาถึงหลังจาก Apple ตัดสิน และ REFUND_REVERSED จะคืนยอดขายกลับมาให้

Apple ส่งข้อความเกี่ยวกับการคืนเงินสี่รายการผ่าน App Store Server Notifications V2 และแอปส่วนใหญ่จัดการเพียงสองรายการ REFUND บอกให้คุณเพิกถอนสิทธิ์ REFUND_DECLINED หมายถึงเก็บยอดขายไว้ และ REFUND_REVERSED คืนยอดขายกลับมาและขอให้คุณคืนสิ่งที่คุณได้นำออกไป นี่คือสิ่งที่แต่ละรายการต้องการ

คำขอคืนเงินครั้งต่อไปกำลังมา

ตั้งค่า RefundHalt ได้ในเวลาพอ ๆ กับการอ่านอีเมลฝ่ายช่วยเหลืออีกฉบับเกี่ยวกับการคืนเงินที่คุณไม่มีโอกาสโต้แย้ง