Deteksi refund StoreKit 2 bermuara pada satu property di transaction, dan itu adalah revocationDate
Ketika Apple memberi refund kepada salah satu pelanggan Anda, refund itu sudah ada di dalam app Anda pada revocationDate transaction, sebelum tugas server Anda berjalan. Berikut tempat deteksi refund StoreKit 2 muncul di perangkat, apa yang diberitahukan revocationDate dan revocationReason kepada Anda, dan mengapa klien untuk kecepatan dan server untuk kebenaran.

Poin utama
- Di StoreKit 2 sebuah purchase yang di-refund membawa revocationDate non-nil pada Transaction-nya, sehingga app Anda dapat mendeteksi refund sendiri, tanpa memanggil server Anda.
- revocationDate diatur saat App Store me-refund sebuah transaction atau saat pelanggan kehilangannya melalui Family Sharing, jadi tanggal non-nil tidak selalu berarti refund.
- revocationReason memberi tahu Anda alasannya: developerIssue berarti pelanggan menyebut ada masalah di app Anda, dan other mencakup setiap alasan refund lainnya yang tersisa.
- Transaction.currentEntitlements sudah mengecualikan purchase yang di-refund dan dicabut, jadi gerbang sisi klien paling bersih untuk akses cukup apakah sebuah product masih muncul di sana.
- Transaction.updates hanya mengantarkan refund yang terjadi saat app Anda tertutup jika Anda mulai mendengarkan saat peluncuran, jadi Task yang hilang berarti refund yang terlewat.
- Deteksi sisi klien hanya berjalan saat app terbuka, itulah mengapa REFUND dari App Store Server Notifications V2 tetap menjadi sinyal otoritatif yang menghentikan Anda membayar untuk melayani pengguna yang di-refund.
- Sebuah refund dapat dibalik, dan ketika itu terjadi, field revocation dihapus dari transaction dan Anda diharapkan memulihkan akses yang Anda putus.
Sebagian besar app mengetahui refund Apple dari server mereka, melalui App Store Server Notification, dan tidak pernah menyadari bahwa refund yang sama sudah ada di dalam app. Ia ada pada transaction, dalam sebuah property bernama revocationDate, dan membacanya memungkinkan app Anda memutus akses pelanggan yang di-refund saat berikutnya mereka membukanya, alih-alih menunggu tugas backend. Deteksi refund StoreKit 2 adalah sinyal sisi klien yang dilewati sebagian besar tim. Berikut persis di mana sebuah refund muncul di perangkat, apa yang diberitahukannya, apa yang tidak, dan mengapa ia seharusnya berada di samping notifikasi server Anda, bukan menggantikannya.
Di mana sebuah refund muncul di dalam StoreKit 2
StoreKit 2 menyerahkan transaction kepada Anda sebagai nilai bertanda tangan, dan sebuah refund tidak menghapus transaction. Ia menandainya. Dua property pada Transaction membawa tanda itu, dan keduanya tetap nil selama seluruh masa hidup sebuah purchase yang sehat. Ketika salah satunya menjadi non-nil, App Store telah mengambil kembali purchase tersebut.
revocationDate adalah field yang berbalik
revocationDate adalah Date opsional. Deskripsi Apple sendiri tepat: itu adalah tanggal App Store me-refund transaction atau mencabutnya dari Family Sharing. Untuk sebuah purchase yang masih baik, nilainya nil. Pada saat sebuah refund diproses, ia menyimpan cap waktu refund tersebut. Satu pemeriksaan itu, apakah revocationDate non-nil, itulah seluruh deteksi refund sisi klien. Segala hal lain adalah nuansa yang ditumpuk di atasnya.
revocationReason memberi tahu Anda mengapa Apple menariknya
revocationReason berada di samping tanggal dan menjelaskan penyebabnya. StoreKit memberinya dua nilai yang penting untuk refund. developerIssue berarti pelanggan memberi tahu Apple bahwa refund itu karena masalah nyata atau yang dirasakan di app Anda. other mencakup setiap alasan yang tersisa. Nilai ketiga, upgradedToBundle, sama sekali bukan refund; ia menandai sebuah transaction yang dicabut App Store karena pelanggan berpindah ke subscription bundle. Baca alasannya sebelum Anda bertindak, karena developerIssue adalah yang layak dihitung: sekumpulan darinya adalah produk Anda sendiri yang memberi tahu di mana ia rusak.
| Property | Type | Apa arti nilai non-nil |
|---|---|---|
revocationDate | Date? | App Store me-refund transaction ini, atau mencabutnya melalui Family Sharing, pada tanggal ini |
revocationReason adalah developerIssue | reason | Pelanggan menyebut masalah nyata atau yang dirasakan di app Anda |
revocationReason adalah other | reason | Refund terjadi karena alasan lain yang tidak dirinci Apple |
revocationReason adalah upgradedToBundle | reason | Bukan refund; transaction dicabut karena pelanggan beralih ke subscription bundle |
currentEntitlements sudah menjatuhkan sebuah purchase yang di-refund
Anda tidak selalu harus membaca field revocation sendiri. Transaction.currentEntitlements adalah urutan purchase yang masih menjadi hak pelanggan saat ini, dan Apple membangunnya untuk mengesampingkan yang tidak seharusnya Anda hormati. Sebuah product yang telah di-refund atau dicabut App Store tidak muncul di dalamnya. Begitu pula subscription yang kedaluwarsa, atau consumable, yang lenyap saat selesai digunakan.
Itu menjadikan currentEntitlements gerbang paling bersih untuk akses. Tanyakan apa yang dimiliki pelanggan, berikan persis itu, dan sebuah refund menghapus entitlement untuk Anda tanpa satu pun pemeriksaan revocationDate. Field revocation untuk saat Anda menginginkan detailnya, tanggal dan alasannya, untuk mencatat peristiwa atau menanggapinya. Daftar entitlement untuk pertanyaan sederhana apakah lampu tetap menyala.
Deteksi refund StoreKit 2 dalam praktik, dari peluncuran dan saat app berjalan
Ada dua momen app Anda dapat menangkap refund di perangkat, dan keduanya butuh kode berbeda. Satu saat app terbuka dan sebuah refund terjadi langsung atau di perangkat lain. Yang lain saat peluncuran, mengejar semua yang berubah saat Anda tertutup. Lewatkan yang kedua dan deteksi refund StoreKit 2 Anda punya lubang tepat di tempat sebagian besar refund jatuh, karena pelanggan jarang membuka app Anda saat meminta refund.
Mulai mendengarkan saat peluncuran atau Anda melewatkan refund yang terjadi saat tertutup
Transaction.updates adalah urutan async yang memancarkan sebuah transaction setiap kali sistem membuat atau memperbaruinya di luar app Anda atau di perangkat lain, termasuk sebuah refund. Instruksi Apple tegas: mulai sebuah Task yang mengiterasinya begitu app Anda diluncurkan, atau Anda mungkin melewatkan transaction yang hanya diantarkannya sekali saat startup. Sebuah refund yang mendarat semalaman tiba melalui updates saat berikutnya app dibuka, tetapi hanya jika sebuah listener sudah berjalan untuk menerimanya. Tanpa listener, tanpa event, dan refund tetap tak terlihat sampai sesuatu yang lain merekonsiliasinya.
Sebuah purchase di perangkat yang sama tidak datang melalui updates
Satu jebakan menjerat orang yang menguji refund secara manual. Sebuah purchase normal yang dibuat di perangkat yang sama tidak tiba melalui updates; StoreKit mengembalikannya langsung dari hasil panggilan purchase. updates untuk perubahan di luar jalur: refund, persetujuan Ask to Buy, penukaran offer-code, dan purchase yang dibuat di tempat lain. Jadi bangun penanganan refund Anda di sekitar updates dan currentEntitlements, bukan di sekitar alur purchase, karena refund tidak akan pernah kembali melalui jalur yang dilalui penjualan.

Apa yang tidak dapat dilakukan deteksi sisi klien untuk Anda
Membaca refund di perangkat cepat dan gratis, tetapi ada batasnya, dan berpura-pura tidak ada adalah cara pendapatan bocor. Perangkat hanya tahu apa yang diberitahukan StoreKit, dan StoreKit hanya berbicara saat app Anda berjalan. Pelanggan yang mendapat refund dan tidak pernah membuka app Anda lagi adalah pelanggan yang tidak pernah dilihat pemeriksaan sisi klien Anda.
Sebuah revocationDate tidak selalu berarti refund
Field yang sama berbalik untuk Family Sharing. Ketika seorang pelanggan kehilangan akses ke purchase bersama, karena penyelenggara menghapusnya atau berbagi berakhir, transaction itu juga mendapatkan revocationDate. Jadi tanggal non-nil berarti pelanggan tidak lagi memiliki purchase ini, yang persis apa yang Anda butuhkan untuk kontrol akses, tetapi tidak selalu berarti uang keluar kembali. Jika Anda menghitung refund untuk pendapatan, pisahkan pencabutan Family Sharing dari yang sungguhan sebelum Anda memercayai angkanya.
Sebuah refund dapat dibalik
Sebuah refund tidak selalu final. Apple dapat membalikkannya, dan ketika itu terjadi, field revocation dihapus dari transaction dan purchase valid kembali. Jika Anda memutus akses saat refund, Anda diharapkan memulihkannya saat pembalikan. Di perangkat itu muncul sebagai event updates lain dengan transaction yang bersih; di server Anda itu adalah notifikasi REFUND_REVERSED yang berbeda. Tangani hanya refund dan Anda akan menelantarkan pelanggan yang membayar tanpa akses dan dengan struk yang berfungsi.
Berapa sebenarnya biaya pencabutan yang terlambat
Sebuah refund jarang hanya harga jual yang meninggalkan rekening Anda. Pada saat ia terselesaikan Anda biasanya sudah menghabiskan uang nyata untuk melayani purchase itu, dan pengeluaran itu tidak kembali. Gambar yang dihasilkan menghabiskan menit GPU. Jawaban chat menghabiskan panggilan model API yang ditagihkan kepada Anda per token. Unggahan menghabiskan penyimpanan yang masih Anda bayar untuk menyimpannya. Jika purchase mendanai pembayaran kepada seorang kreator, uang itu sudah keluar. Tak satu pun dari itu terbalik dengan refund.
Deteksi sisi klien mempersempit jendela pada satu bagian yang masih dapat Anda kendalikan, yaitu pengeluaran masa depan. Semakin cepat Anda tahu sebuah purchase di-refund, semakin cepat Anda berhenti melayaninya. Tetapi perangkat hanya memberi tahu Anda saat app terbuka, jadi pengguna yang di-refund yang tidak pernah kembali menyimpan akses sisi server apa pun yang Anda berikan, diam-diam membebani Anda setiap kali tugas latar belakang atau perangkat tersinkron bertindak atas nama mereka. Klien membuat pencabutan cepat. Ia tidak membuatnya terjamin.
Gunakan klien untuk kecepatan dan server untuk kebenaran
Desain yang bersih menggunakan kedua sinyal untuk apa yang masing-masing kuasai. Di perangkat, Transaction.updates dan currentEntitlements memberi Anda reaksi lokal yang instan saat pelanggan yang di-refund membuka app, baik untuk UI dan untuk menyelesaikan perubahan entitlement tanpa perjalanan bolak-balik. Di server, App Store Server Notifications V2 mengirim pesan REFUND yang tiba entah app pernah dibuka lagi atau tidak, yang merupakan satu-satunya sinyal yang secara andal menghentikan backend Anda dari membelanjakan pada akun yang di-refund.
| Signal | Di mana ia berada | Berjalan saat | Percayai ia untuk |
|---|---|---|---|
revocationDate pada sebuah transaction | Device, StoreKit 2 | App Anda membaca transaction | Memberi tahu bahwa purchase tertentu di-refund atau dicabut |
Transaction.updates | Device, StoreKit 2 | Refund mendarat saat app berjalan, atau saat peluncuran jika Anda mendengarkan | Bereaksi instan untuk pelanggan yang hadir |
currentEntitlements | Device, StoreKit 2 | Anda memeriksa apa yang dimiliki pelanggan sekarang | Gerbangi akses tanpa melacak refund sendiri |
REFUND notification | Server Anda, App Store Server Notifications V2 | Apple memproses refund, app terbuka atau tidak | Menghentikan pengeluaran sisi server pada pelanggan yang tidak pernah kembali |
Pasang sinyal perangkat untuk pelanggan yang memegang ponsel, dan notifikasi server untuk yang tidak. Refund muncul di kedua tempat dengan sengaja. Membaca hanya salah satunya adalah cara akun yang di-refund terus membebani Anda setelah penjualan sudah lenyap.
Pertanyaan yang sering diajukan
- Bagaimana cara saya mendeteksi refund di StoreKit 2?
- Periksa revocationDate transaction. Nilainya nil untuk purchase yang valid dan menyimpan tanggal begitu App Store me-refund transaction, jadi revocationDate non-nil adalah sinyal bahwa sebuah purchase di-refund atau dicabut.
- Apa perbedaan antara revocationDate dan revocationReason?
- revocationDate adalah kapan App Store mengambil kembali purchase, dan revocationReason adalah mengapa. Alasannya developerIssue saat pelanggan menyebut masalah di app Anda dan other untuk hal lainnya.
- Apakah purchase yang di-refund masih muncul di currentEntitlements?
- Tidak. Transaction.currentEntitlements mengecualikan purchase yang telah di-refund atau dicabut App Store, jadi product yang di-refund jatuh dari entitlement pelanggan dengan sendirinya, yang menjadikannya gerbang aman untuk akses.
- Akankah StoreKit memberi tahu app saya tentang refund yang terjadi saat app tertutup?
- Hanya jika Anda mendengarkan sejak peluncuran. Transaction.updates mengantarkan perubahan itu sekali saat startup, jadi Anda harus memulai Task yang mengiterasinya saat app Anda diluncurkan atau refund terlewat sampai sesuatu yang lain merekonsiliasinya.
- Apakah deteksi refund sisi klien cukup dengan sendirinya?
- Tidak. Perangkat hanya mengetahui refund saat app Anda berjalan, jadi pelanggan yang tidak pernah membuka kembali app tak terlihat olehnya. REFUND dari App Store Server Notifications V2 adalah sinyal yang menjangkau Anda terlepas dari itu.
- Apakah revocationDate selalu berarti pelanggan di-refund?
- Tidak. revocationDate juga diatur saat pelanggan kehilangan purchase melalui Family Sharing, jadi tanggal non-nil berarti mereka tidak lagi memiliki purchase tetapi tidak selalu berarti uang dikembalikan.
Sumber dan bacaan lanjutan
- Apple Developer: Transaction.revocationDate (StoreKit)
- Apple Developer: Transaction.RevocationReason (StoreKit)
- Apple Developer: Transaction.currentEntitlements (StoreKit)
- Apple Developer: Transaction.updates (StoreKit)
- Apple Developer: App Store Server Notifications V2 notificationType (REFUND, REFUND_REVERSED)
- Apple Developer Tech Talk: Support customers with StoreKit 2 and App Store Server API
RefundHalt
Autopilot refund untuk App Store dan Google Play
Baca selanjutnya
Setiap jendela refund App Store dan Google Play adalah hitung mundur, dan inilah berapa jam yang diberikan masing-masing
Setiap refund di App Store dan Google Play memulai sebuah jam, dan sebagian besar berjalan tanpa kamu. Jendela refund terpendek Apple adalah 12 jam, jendela chargeback Google adalah 24 jam, dan mulai 3 Agustus 2026 jendela chargeback yang terlewat adalah tagihan, bukan sekadar penjualan yang hilang. Inilah setiap tenggat yang menyentuh akunmu.
Notifikasi pembelian yang dibatalkan memungkinkan server Google Play Anda mencabut akses begitu refund masuk
Google Play dapat mengirimkan notifikasi pembelian yang dibatalkan ke server Anda begitu sebuah pembelian di-refund, di-chargeback, atau dibatalkan. Notifikasi ini membawa purchaseToken, orderId, productType, dan refundType, dan artinya satu hal, cabut akses. Berikut cara membacanya dan menghubungkannya.