Ada satu endpoint yang mengembalikan seluruh riwayat refund App Store milik seorang pelanggan, dan inilah yang diberikannya
Endpoint Get Refund History dari Apple mengembalikan riwayat refund App Store lengkap milik seorang pelanggan sebagai transaksi bertanda tangan. Inilah setiap field, cara token revision melakukan paginasi, mengapa datanya per pelanggan dan bukan per aplikasi, dan berapa biaya sebuah refund yang Anda lewatkan.

Poin utama
- Get Refund History adalah endpoint App Store Server API yang mengembalikan pembelian dalam aplikasi milik seorang pelanggan yang telah di-refund untuk aplikasi Anda sebagai daftar transaksi bertanda tangan, sehingga Anda dapat merekonsiliasi refund dan mencabut akses meski sebuah notifikasi tidak pernah sampai kepada Anda.
- Anda memanggil GET /inApps/v2/refund/lookup/{transactionId} dengan id transaksi apa pun milik pelanggan itu, dan Apple mengembalikan refund mereka di seluruh jenis pembelian dalam aplikasi Anda, bukan hanya yang Anda tanyakan.
- Respons memiliki tiga field: signedTransactions, hingga 20 transaksi JWS per halaman yang diurutkan dengan refund terlama lebih dulu, ditambah sebuah token revision dan sebuah boolean hasMore untuk paginasi.
- Simpan token revision terakhir. Kirimkan kembali lain kali dan Apple hanya mengembalikan refund yang lebih baru dari titik itu, yang mengubah dump riwayat lengkap menjadi daftar pendek berisi baris baru pada setiap kali dijalankan.
- Setiap transaksi yang telah didekode membawa revocationDate dan revocationReason. Nilai revocationReason 1 berarti pelanggan melakukan refund karena masalah nyata atau yang dirasakan pada aplikasi Anda, dan 0 berarti alasan lain seperti pembelian yang tidak disengaja.
- Endpoint ini bersifat per pelanggan, bukan per aplikasi. Tidak ada satu pun panggilan yang mendaftar setiap refund di seluruh aplikasi Anda, jadi Anda merekonsiliasi per akun dari sebuah id transaksi, atau membaca feed notifikasi REFUND Anda untuk tampilan seluruh aplikasi.
- Alasan untuk memasangnya adalah uang. Sebuah refund yang tidak pernah Anda tangkap membuat akun tetap aktif, dan Anda terus membayar komputasi, panggilan model API, penyimpanan, dan pembayaran untuk pelanggan yang sudah dituntaskan oleh App Store.
Apple menyimpan catatan yang dapat dikueri atas setiap refund yang telah diberikannya pada akun seorang pelanggan untuk aplikasi Anda, dan satu panggilan mengembalikannya. Endpoint-nya adalah Get Refund History, bagian dari App Store Server API, dan ia memberi Anda riwayat refund App Store lengkap milik pelanggan itu sebagai daftar transaksi bertanda tangan. Anda mengirim sebuah id transaksi, Anda menerima kembali apa yang di-refund Apple, dan Anda merekonsiliasinya terhadap apa yang masih Anda aktifkan.
Inilah alasan mengapa Anda perlu repot. Sebuah refund yang tidak pernah Anda lihat adalah refund yang terus Anda bayar. Uangnya sudah hilang, tetapi akun tetap aktif, dan setiap jam ia begitu Anda terus mengeluarkan biaya untuk komputasi, panggilan model API, penyimpanan, dan pembayaran apa pun yang terkait dengan pelanggan itu. Notifikasi refund Anda dimaksudkan untuk menangkap ini saat ia terjadi. Get Refund History adalah pengaman untuk saat mereka gagal, setelah gangguan, sebuah deploy yang menjatuhkan webhook, atau sebuah kasus dukungan tempat Anda butuh gambaran utuh dalam satu panggilan.
Apa yang dikembalikan endpoint riwayat refund App Store
Anda memanggil GET /inApps/v2/refund/lookup/{transactionId} terhadap App Store Server API, ditandatangani dengan JWT yang sama seperti setiap panggilan lain kepadanya. Id transaksi dalam path bisa berupa transaksi apa pun milik pelanggan. Apple membacanya sebagai identitas, bukan filter, dan mengembalikan pembelian pelanggan itu yang telah di-refund di seluruh aplikasi Anda: consumable, non-consumable, langganan yang diperpanjang otomatis maupun yang tidak diperpanjang, semuanya. Versi V1 lama dari endpoint ini mengembalikan hingga 50 refund dalam satu respons dan sudah tidak digunakan lagi. Versi saat ini melakukan paginasi, sehingga Anda menangani pelanggan dengan riwayat panjang tanpa payload raksasa.
Respons terdiri dari tiga field
| Field | Apa yang dikandungnya |
|---|---|
| signedTransactions | Hingga 20 transaksi yang di-refund untuk pelanggan ini, masing-masing sebuah JWS bertanda tangan yang Anda verifikasi dan dekode. Diurutkan dengan refund terlama lebih dulu, berdasarkan revocationDate. Array kosong berarti pelanggan tidak punya refund di aplikasi Anda |
| revision | Sebuah token paginasi. Kirimkan kembali untuk mendapatkan halaman berikutnya, dan simpan yang terakhir untuk mengambil hanya refund baru lain kali |
| hasMore | Bernilai true saat Apple menyimpan lebih banyak transaksi yang di-refund daripada yang dikembalikan halaman ini, jadi Anda memanggil lagi dengan revision |
Apa yang diberitahukan satu transaksi yang di-refund
Setiap entri di signedTransactions adalah sebuah JWS. Verifikasi terhadap rantai sertifikat Apple, dekode, dan Anda punya payload transaksi biasa dengan field refund yang terisi. Inilah yang penting di sini.
| Field | Apa yang diberitahukannya |
|---|---|
| transactionId | Id transaksi yang di-refund, kunci gabung Anda kembali ke pembelian yang Anda catat |
| originalTransactionId | Id pembelian pertama dalam rantai, cara Anda mengikat perpanjangan sebuah langganan bersama |
| productId | Produk yang di-refund, sehingga Anda mencabut entitlement yang tepat dan tidak lebih |
| revocationDate | Waktu UNIX, dalam milidetik, saat Apple me-refund transaksi |
| revocationReason | Mengapa Apple me-refund. 1 berarti masalah nyata atau yang dirasakan pada aplikasi Anda, 0 berarti alasan lain seperti pembelian yang tidak disengaja |
| price, currency | Jumlahnya, dalam milliunits, dan kode mata uang ISO 4217-nya, sehingga Anda dapat menjumlahkan uang yang dikembalikan |
| appAccountToken | UUID yang Anda lampirkan saat pembelian, cara paling bersih untuk memetakan sebuah refund kembali ke pengguna Anda sendiri |
Token revision adalah cara Anda berhenti membaca ulang seluruh daftar
Cara naif menggunakan endpoint ini adalah mencari seorang pelanggan dan menelusuri setiap halaman setiap kali. Itu berhasil, dan pada pelanggan dengan lima puluh refund itu adalah lima puluh baris yang sudah Anda ketahui ditambah satu yang baru. Token revision ada untuk menghapus pemborosan itu. Setiap respons membawa sebuah revision. Saat hasMore bernilai true, Anda mengirimkannya kembali untuk mendapatkan halaman berikutnya. Saat Anda mencapai akhir, Anda menyimpan revision terakhir yang Anda lihat.
Apa yang tidak akan dilakukan endpoint ini
Ada satu ekspektasi yang harus Anda buang sebelum membangun di atasnya. Get Refund History bersifat per pelanggan, bukan per aplikasi. Anda tidak bisa memintanya setiap refund yang diterima aplikasi Anda minggu lalu. Ia menjawab satu pertanyaan, refund mana yang dimiliki akun ini, dan Anda harus datang dengan sebuah id transaksi untuk akun itu untuk menanyakannya. Developer terus-menerus menabrak dinding ini dan pergi mencari endpoint refund seluruh aplikasi yang tidak ada.
Tampilan seluruh aplikasi berada di tempat lain. Feed App Store Server Notifications Anda mengirim sebuah notifikasi REFUND saat Apple memberikan masing-masing, dan Get Notification History memungkinkan Anda memutar ulang feed itu yang difilter ke jenis refund pada suatu rentang tanggal. Jadi pembagiannya bersih. Notifikasi dan riwayatnya memberi Anda aliran seluruh aplikasi. Get Refund History memberi Anda daftar otoritatif satu akun, sesuai permintaan, yang persis Anda inginkan di meja dukungan atau setelah gangguan.

Berapa biaya sebuah refund yang terlewat dalam uang
Endpoint adalah pipa. Tagihannya adalah alasan Anda memasang pipa. Setiap refund dalam daftar itu adalah uang yang sudah dikembalikan, dan satu-satunya variabel yang tersisa dalam kendali Anda adalah berapa lama Anda terus mengeluarkan biaya untuk akun yang tidak lagi membayar.
Anda terus membayar untuk melayani akun yang di-refund
Harga pembelian hilang seketika Apple memberikan refund. Yang terus berjalan adalah biaya pengiriman. Untuk aplikasi yang melakukan pekerjaan nyata per pengguna, itu adalah komputasi, panggilan model API, penyimpanan, dan pembayaran kreator atau mitra apa pun yang terkait dengan penggunaan mereka. Pelanggan yang di-refund yang aksesnya tidak pernah Anda putus adalah langganan yang Anda danai dari kantong sendiri. Merekonsiliasi terhadap Get Refund History dan mencabut berdasarkan apa yang Anda temukan adalah cara Anda mematikan meteran itu saat sebuah notifikasi terlewat.
Alasan refund 1 adalah laporan cacat yang menyamar
revocationReason menelan biaya dua kali jika Anda mengabaikannya. Biaya pertama adalah refund itu sendiri. Yang kedua adalah setiap refund mendatang dari penyebab yang sama. Ketika sebuah produk terus kembali dengan revocationReason 1, sebuah masalah nyata atau yang dirasakan pada aplikasi Anda, Apple sedang menyerahkan kepada Anda sampel berlabel tentang apa yang membuat pelanggan meminta uang mereka kembali. Buat trennya per produk dan Anda dapat memperbaiki kebocoran alih-alih membayarnya satu refund pada satu waktu.
Menangkapnya terlambat tetap lebih baik daripada tidak menangkapnya
Sebuah chargeback bersifat final dengan bank dan, di toko yang lain, kini membawa biaya yang ditanggung developer. Sebuah refund App Store bukan itu. Ia sudah selesai, tetapi entitlement adalah milik Anda untuk dicabut saat Anda mengetahuinya. Jadi bahkan sebuah refund yang Anda temukan terlambat beberapa hari melalui endpoint ini pantas ditemukan. Anda tidak bisa menarik kembali uangnya, tetapi Anda bisa menghentikan pengeluaran yang masih berjalan di belakangnya.
Bagaimana ini cocok dengan notifikasi, dan dengan Google
Anggap potongan-potongan itu sebagai satu sistem. Notifikasi REFUND adalah sinyal langsung, didorong ke server Anda saat Apple memutuskan. Get Refund History adalah sumber kebenaran berbasis tarik untuk satu pelanggan, panggilan yang Anda buat saat push gagal atau saat seorang manusia butuh akun lengkap di depannya. Di sisi Google Play bentuknya adalah ide yang sama dengan nama berbeda: sebuah VoidedPurchaseNotification didorong secara real time, dan Voided Purchases API adalah daftar yang Anda tarik. Kedua toko memberi Anda sebuah aliran dan sebuah buku besar. Kesalahannya adalah hanya mempercayai aliran, karena aliran bisa terputus.
Memasangnya dengan cara RefundHalt
Loop-nya kecil begitu setiap potongan sudah pada tempatnya. Ambil sebuah notifikasi REFUND sebagai pemicu. Rekonsiliasi terhadap Get Refund History agar webhook yang terjatuh tidak pernah membiarkan akun yang di-refund tetap aktif. Dekode setiap transaksi, kunci pada appAccountToken atau transactionId kembali ke pengguna Anda, baca revocationReason agar refund cacat ditandai dan bukan sekadar diarsipkan, dan cabut entitlement yang persis, bukan seluruh akun. Lakukan paginasi dengan token revision agar Anda membaca refund baru, bukan yang lama.
Inilah bagian yang dijalankan RefundHalt untuk Anda. Ia mendengarkan notifikasi refund, mundur ke Get Refund History saat butuh daftar otoritatif, memverifikasi setiap transaksi bertanda tangan, mencabut pembelian yang tepat, dan menyimpan revision agar setiap lintasan hanya membaca apa yang berubah. Anda mendapat akses yang diputus dalam hitungan detik dan catatan bersih tentang siapa yang di-refund, untuk apa, dan mengapa, tanpa Anda sendiri harus menyiapkan polling dan verifikasi JWS.
Pertanyaan yang sering diajukan
- Bagaimana saya melihat setiap refund di seluruh aplikasi saya, bukan hanya satu pelanggan?
- Anda tidak bisa dengan Get Refund History, karena ia bersifat per pelanggan dan butuh sebuah id transaksi untuk akun yang Anda tanyakan. Untuk tampilan seluruh aplikasi, gunakan feed App Store Server Notifications Anda, yang mengirim sebuah notifikasi REFUND untuk setiap refund saat Apple memberikannya, dan Get Notification History untuk memutar ulang feed itu yang difilter ke jenis refund pada suatu rentang tanggal.
- Berapa banyak refund yang dikembalikan endpoint Get Refund History?
- Versi saat ini mengembalikan hingga 20 transaksi yang di-refund per halaman, diurutkan dengan refund terlama lebih dulu, dan melakukan paginasi sisanya dengan sebuah token revision saat hasMore bernilai true. Endpoint V1 yang sudah tidak digunakan mengembalikan hingga 50 dalam satu respons. Tidak ada batas atas pada totalnya, jadi pelanggan dengan riwayat panjang cukup terbentang di lebih banyak halaman.
- Untuk apa token revision itu?
- Itu adalah cara Anda melakukan paginasi dan cara Anda menghindari membaca ulang seluruh riwayat seorang pelanggan setiap kali. Setiap respons menyertakan sebuah revision. Anda mengirimkannya kembali untuk mengambil halaman berikutnya, dan Anda menyimpan yang terakhir agar pencarian berikutnya hanya mengembalikan refund yang lebih baru dari titik itu. Itu menjaga rekonsiliasi terjadwal tetap berupa daftar pendek berisi baris baru.
- Apa arti revocationReason dalam sebuah transaksi yang di-refund?
- Itu adalah alasan Apple me-refund transaksi. Nilai 1 berarti pelanggan melakukan refund karena masalah nyata atau yang dirasakan di dalam aplikasi Anda, dan 0 berarti alasan lain, seperti pembelian yang tidak disengaja. revocationDate memberitahu Anda kapan refund terjadi, dalam milidetik UNIX. Membaca revocationReason memungkinkan Anda memisahkan cacat produk dari refund penyesalan yang bersifat sekali saja.
- Apakah saya masih butuh ini jika saya sudah menangani notifikasi REFUND?
- Ya, sebagai pengaman. Notifikasi adalah sinyal langsung, tetapi sebuah push bisa gagal tiba selama gangguan, deploy yang buruk, atau perubahan webhook, dan sebuah refund yang terlewat membiarkan akun yang di-refund tetap aktif dan menghabiskan uang Anda. Get Refund History adalah sumber kebenaran berbasis tarik yang Anda gunakan untuk merekonsiliasi agar tidak ada yang tetap aktif padahal Apple sudah me-refund-nya.
Sumber dan bacaan lanjutan
- Apple Developer: Get Refund History (App Store Server API)
- Apple Developer: RefundHistoryResponse
- Apple Developer: JWSTransactionDecodedPayload (revocationDate, revocationReason)
- Apple Developer: Get Refund History V1 (deprecated)
- Apple Developer: App Store Server Notifications V2 notificationType (REFUND)
- Apple Developer: Support customers and handle refunds (WWDC21)
RefundHalt
Autopilot refund untuk App Store dan Google Play
Baca selanjutnya
Aplikasi Anda bisa menampilkan lembar permintaan refund di dalam aplikasi, dan inilah yang Apple lakukan setelah pelanggan menekan kirim
Permintaan refund di dalam aplikasi dari Apple memungkinkan pelanggan meminta refund tanpa keluar dari aplikasi Anda, pada lembar yang dibuat dan ditinjau Apple. Inilah yang dikembalikan beginRefundRequest, jam CONSUMPTION_REQUEST dan 48 jam yang dimulainya di server Anda, dan apakah tombol ini layak dirilis.
Ketika pembelian Google Play direfund atau di-chargeback, Voided Purchases API adalah cara Anda mengetahuinya
Google Play membatalkan sebuah pembelian secara diam-diam ketika pembelian itu direfund atau di-chargeback. Voided Purchases API adalah daftar pesanan tersebut, sehingga Anda bisa mencabut akses. Berikut setiap field, jendela 30 hari, opsi revoke yang menyembunyikan pesanan, dan berapa biayanya.