Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Gunakan API pengiriman Microsoft Store untuk aplikasi MSI atau EXE untuk mengkueri dan membuat pengiriman secara terprogram untuk aplikasi MSI atau EXE untuk akun Pusat Mitra organisasi Anda. API ini berguna jika akun Anda mengelola banyak aplikasi, dan Anda ingin mengotomatiskan dan mengoptimalkan proses pengiriman untuk aset ini. API ini menggunakan Azure Active Directory (Azure AD) untuk mengautentikasi panggilan dari aplikasi atau layanan Anda.
Langkah-langkah berikut menjelaskan proses end-to-end menggunakan API pengiriman Microsoft Store:
- Pastikan Anda telah menyelesaikan semua prasyarat.
- Sebelum Anda memanggil metode di MICROSOFT Store submission API, dapatkan token akses Azure AD. Setelah mendapatkan token, Anda memiliki waktu 60 menit untuk menggunakan token ini dalam panggilan ke API pengiriman Microsoft Store sebelum token kedaluwarsa. Setelah token kedaluwarsa, Anda dapat menghasilkan token baru.
- Panggil API pengiriman Microsoft Store untuk aplikasi MSI atau EXE.
Langkah 1: Selesaikan prasyarat untuk menggunakan API pengiriman Microsoft Store
Sebelum Anda mulai menulis kode untuk memanggil API pengiriman Microsoft Store untuk aplikasi MSI atau EXE, pastikan Anda telah menyelesaikan prasyarat berikut.
- Anda (atau organisasi Anda) harus memiliki direktori Azure Active Directory dan harus memiliki izin Administrator perusahaan untuk direktori tersebut. Jika sudah menggunakan Microsoft 365 atau layanan bisnis lainnya dari Microsoft, Anda sudah memiliki direktori Azure Active Directory. Jika tidak, Anda dapat membuat Azure AD baru di Pusat Mitra tanpa biaya tambahan.
- Anda harus mengaitkan aplikasi Azure Active Directory dengan akun Pusat Mitra dan mendapatkan ID penyewa, ID klien, dan kunci. Anda memerlukan nilai-nilai ini untuk mendapatkan token akses Azure Active Directory, yang akan Anda gunakan dalam panggilan ke API pengiriman Microsoft Store.
- Siapkan aplikasi Anda untuk digunakan dengan API pengiriman Microsoft Store:
- Jika aplikasi Anda belum ada di Pusat Mitra, Anda harus membuat aplikasi dengan mengirimkan namanya di Pusat Mitra. Anda tidak dapat menggunakan API pengiriman Microsoft Store untuk membuat aplikasi di Pusat Mitra; Anda harus bekerja di Pusat Mitra untuk membuatnya, lalu setelah itu Anda dapat menggunakan API untuk mengakses aplikasi dan membuat pengiriman secara terprogram untuk itu.
- Sebelum dapat membuat pengiriman untuk aplikasi tertentu menggunakan API ini, Anda harus terlebih dahulu membuat satu pengiriman untuk aplikasi di Pusat Mitra, termasuk menjawab kuesioner peringkat usia. Setelah melakukan ini, Anda akan dapat membuat pengiriman baru secara terprogram untuk aplikasi ini menggunakan API.
- Jika Anda membuat atau memperbarui pengiriman aplikasi dan Anda perlu menyertakan paket baru, siapkan detail paket.
- Jika Anda membuat atau memperbarui pengiriman aplikasi dan Perlu menyertakan cuplikan layar atau gambar untuk daftar Toko, siapkan cuplikan layar dan gambar aplikasi.
Cara mengaitkan aplikasi Azure Active Directory dengan akun Pusat Mitra Anda
Sebelum dapat menggunakan API pengiriman Microsoft Store untuk aplikasi MSI atau EXE, Anda harus mengaitkan aplikasi Microsoft Azure AD dengan akun Pusat Mitra Anda, mengambil ID penyewa dan ID klien untuk aplikasi dan membuat kunci. Aplikasi Azure ACTIVE Directory mewakili aplikasi atau layanan tempat Anda ingin memanggil API pengiriman Microsoft Store. Anda memerlukan ID penyewa, ID klien, dan kunci untuk mendapatkan token akses Azure Active Directory yang Anda berikan ke API.
Catatan
Anda hanya perlu melakukan tugas ini satu kali. Setelah memiliki ID penyewa, ID klien, dan kunci, Anda dapat menggunakannya kembali kapan saja Anda perlu untuk membuat token akses Azure Active Directory baru.
- Di Pusat Mitra, kaitkan akun Pusat Mitra organisasi dengan direktori Azure Active Directory organisasi Anda.
- Selanjutnya, dari halaman Pengguna di bagian Pengaturan akun di Pusat Mitra, tambahkan aplikasi Azure ACTIVE Directory yang mewakili aplikasi atau layanan yang akan Anda gunakan untuk mengakses pengiriman untuk akun Pusat Mitra Anda. Pastikan Anda menetapkan aplikasi ini sebagai peranManajer. Jika aplikasi belum ada di direktori Azure Active Directory, Anda dapat membuat aplikasi Azure Active Directory baru di Pusat Mitra.
- Kembali ke halaman Pengguna, klik nama aplikasi Azure Active Directory Anda untuk masuk ke pengaturan aplikasi, dan salin nilai ID Penyewa dan ID Klien.
- Untuk menambahkan kunci baru atau Rahasia klien, lihat instruksi berikut atau lihat instruksi untuk mendaftarkan aplikasi melalui Portal Microsoft Azure:
Untuk mendaftarkan aplikasi Anda:
Masuk ke portal Azure.
Jika Anda memiliki akses ke beberapa penyewa, gunakan filter Direktori + langganan di menu atas untuk memilih penyewa tempat Anda ingin mendaftarkan aplikasi.
Cari dan pilih Microsoft Azure Active Directory.
Di bawah Kelola, pilih Pendaftaran aplikasi > Pilih aplikasi Anda.
Pilih Sertifikat & rahasia > Rahasia > klien Rahasia klien baru.
Tambahkan deskripsi untuk rahasia klien Anda.
Pilih kedaluwarsa untuk rahasia atau tentukan masa pakai kustom.
Masa pakai rahasia klien dibatasi hingga dua tahun (24 bulan) atau kurang. Anda tidak dapat menentukan masa pakai kustom lebih dari 24 bulan.
Catatan
Microsoft menyarankan agar Anda menetapkan nilai kedaluwarsa kurang dari 12 bulan.
Pilih Tambahkan.
Catat nilai rahasia untuk digunakan dalam kode aplikasi klien Anda. Nilai rahasia ini tidak pernah ditampilkan lagi setelah Anda meninggalkan halaman ini.
Langkah 2: Mendapatkan token akses Azure Active Directory
Sebelum Anda memanggil salah satu metode di API pengiriman Microsoft Store untuk aplikasi MSI atau EXE, Anda harus terlebih dahulu mendapatkan token akses Microsoft Azure AD yang Anda teruskan ke header Otorisasi dari setiap metode di API. Setelah mendapatkan token akses, Anda memiliki waktu 60 menit untuk menggunakan token akses sebelum masa berlakunya habis. Setelah token kedaluwarsa, Anda dapat merefresh token sehingga Anda dapat terus menggunakannya dalam panggilan lebih lanjut ke API.
Untuk mendapatkan token akses, ikuti instruksi di [Service to Service Calls Using Client Credentials]/azure/active-directory/azuread-dev/v1-oauth2-client-creds-grant-flow) untuk mengirim HTTP POST ke https://login.microsoftonline.com/
<titik akhir tenant_id>/oauth2/token. Berikut adalah contoh permintaan.
POST https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token HTTP/1.1
Host: login.microsoftonline.com
Content-Type: application/x-www-form-urlencoded; charset=utf-8
grant_type=client_credentials
&client_id=<your_client_id>
&client_secret=<your_client_secret>
&scope=https://api.store.microsoft.com/.default
tenant_id
Untuk nilai di POST URI dan client_id
parameter dan client_secret
, tentukan ID penyewa, ID klien, dan kunci untuk aplikasi yang Anda ambil dari Pusat Mitra di bagian sebelumnya. Untuk parameter cakupan, Anda harus menentukan https://api.store.microsoft.com/.default
.
Setelah token akses kedaluwarsa, Anda dapat merefreshnya dengan mengikuti instruksi di sini.
Untuk contoh yang menunjukkan cara mendapatkan token akses dengan menggunakan C# atau Node.js, lihat contoh kode untuk API pengiriman Microsoft Store untuk aplikasi MSI atau EXE.
Langkah 3: Menggunakan API pengiriman Microsoft Store
Setelah Anda memiliki token akses Azure ACTIVE Directory, Anda dapat memanggil metode di API pengiriman Microsoft Store untuk aplikasi MSI atau EXE. API mencakup banyak metode yang dikelompokkan ke dalam skenario untuk aplikasi. Untuk membuat atau memperbarui pengiriman, Anda biasanya memanggil beberapa metode dalam urutan tertentu. Untuk informasi tentang setiap skenario dan sintaks setiap metode, lihat bagian berikut:
Catatan
Setelah mendapatkan token akses, Anda memiliki waktu 60 menit untuk memanggil metode di API pengiriman Microsoft Store untuk aplikasi MSI atau EXE sebelum token kedaluwarsa.
URL Dasar
URL dasar untuk MICROSOFT Store Submission API untuk exe atau aplikasi MSI adalah: https://api.store.microsoft.com
Kontrak API
Dapatkan API Metadata Pengiriman Draf Saat Ini
Mengambil metadata di setiap modul (daftar, properti, atau ketersediaan) di bawah pengiriman draf saat ini.
Jalur [Semua Modul]: /submission/v1/product/{productId}/metadata?languages={languages}&includelanguagelist={true/false}
Jalur [Modul Tunggal]: /submission/v1/product/{productId}/metadata/{moduleName}?languages={languages}&includelanguagelist={true/false}
Metode: GET
Parameter Jalur
Pengaturan | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
nama modul | Modul Pusat Mitra – daftar, properti, atau ketersediaan |
Parameter Kueri:
Pengaturan | Deskripsi |
---|---|
bahasa |
Opsional Filter bahasa daftar sebagai string yang dipisahkan koma [batas hingga 200 Bahasa]. Jika tidak ada, 200 metadata bahasa daftar pertama yang tersedia akan diambil. [ misalnya, "en-us, en-gb"]. |
daftarBahasaDimasukkan | Boolean opsional – jika true, mengembalikan daftar bahasa daftar tambahan dan status kelengkapannya. |
Header yang Diperlukan
Kepala Halaman | Nilai |
---|---|
Authorization: Bearer <Token> |
ID aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Header Respons
Kepala Halaman | Nilai |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan Tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
dukungan aksesibilitas | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Ketentuan Lisensi Tambahan | string | |
ketersediaan | Objek | Data modul ketersediaan |
kategori | string | Lihat daftar kategori di bawah ini |
catatan sertifikasi | string | |
kode | string | Kode kesalahan Pesan |
informasi kontak | string | |
hak cipta | string | |
bergantungPadaDriverAtauNT | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
deskripsi | string | |
dikembangkan oleh | string | |
kemampuan penemuan | string | [DAPAT DITEMUKAN, DEEPLINK_ONLY] |
enableInFutureMarkets | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | Daftar pesan kesalahan atau peringatan jika ada |
freeTrial | string | [TIDAK_ADA_UJI_C |
jenisItemPerangkatKeras | string | |
Apakah Kebijakan Privasi Diperlukan | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
direkomendasikan | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
diharuskan | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
apakahFiturSistemDiperlukan | Array objek | |
bahasa | string | Lihat daftar bahasa di bawah ini |
Daftar | Array objek | Mencantumkan data modul untuk setiap bahasa |
pasar | Array string | Lihat daftar pasar di bawah ini |
pesan | string | Deskripsi kesalahan |
perangkat keras minimal | string | |
persyaratan minimum | string | |
penAndInkSupport | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
harga | string | [GRATIS, FREEMIUM, LANGGANAN, BERBAYAR] |
urlKebijakanPrivasi | string | |
deklarasiProduk | Objek | |
fiturProduk | Array string | |
properti | Objek | Data modul properti |
perangkat keras yang direkomendasikan | string | |
persyaratan yang direkomendasikan | string | |
responseData | Objek | Berisi Payload respons aktual untuk Permintaan |
persyaratan | Array objek | |
Istilah Pencarian | Array string | |
Deskripsi Singkat | string | |
subkategori | string | Lihat daftar sub-kategori di bawah ini |
InformasiKontakDukungan | string | |
rincianPersyaratanSistem | Array objek | |
sasaran | string | Entitas tempat Kesalahan berasal |
situs web | string | |
Apa yang Baru | string |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"availability":{
"markets": ["US"],
"discoverability": "DISCOVERABLE",
"enableInFutureMarkets": true,
"pricing": "PAID",
"freeTrial": "NO_FREE_TRIAL"
},
"properties":{
"isPrivacyPolicyRequired": true,
"privacyPolicyUrl": "http://contoso.com",
"website": "http://contoso.com",
"supportContactInfo": "http://contoso.com",
"certificationNotes": "Certification Notes",
"category": "DeveloperTools",
"subcategory": "Database",
"productDeclarations": {
"dependsOnDriversOrNT": false,
"accessibilitySupport": false,
"penAndInkSupport": false
},
"isSystemFeatureRequired": [
{
"isRequired": true,
"isRecommended": false,
"hardwareItemType": "Touch"
},
{
"isRequired": true,
"isRecommended": false,
"hardwareItemType": "Keyboard"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Mouse"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Camera"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "NFC_HCE"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "NFC_Proximity"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Bluetooth_LE"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Telephony"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Microphone"
}
],
"systemRequirementDetails": [
{
"minimumRequirement": "1GB",
"recommendedRequirement": "4GB",
"hardwareItemType": "Memory"
},
{
"minimumRequirement": "",
"recommendedRequirement": "",
"hardwareItemType": "DirectX"
},
{
"minimumRequirement": "",
"recommendedRequirement": "",
"hardwareItemType": "Video_Memory"
},
{
"minimumRequirement": "",
"recommendedRequirement": "",
"hardwareItemType": "Processor"
},
{
"minimumRequirement": "",
"recommendedRequirement": "",
"hardwareItemType": "Graphics"
}
]
},
"listings":[{
"language": "en-us",
"description": "Description",
"whatsNew": "What's New",
"productFeatures": ["Feature 1"],
"shortDescription": "Short Description",
"searchTerms": ["Search Ter 1"],
"additionalLicenseTerms": "License Terms",
"copyright": "Copyright Information",
"developedBy": "Developer Details",
"sortTitle": "Product 101",
"requirements": [
{
"minimumHardware": "Pentium4",
"recommendedHardware": "Corei9"
}
],
"contactInfo": "contactus@contoso.com"
}],
"listingLanguages": [{"language":"en-us", "isComplete": true}]
}
}
Memperbarui API Metadata Pengiriman Draf Saat Ini
Memperbarui metadata di setiap Modul di bawah pengiriman draf. Pemeriksaan API
- Untuk Pengiriman Aktif. Jika Ada, Gagal dengan Pesan Kesalahan.
- Jika semua modul dalam status siap untuk mengizinkan operasi Simpan Draf.
- Setiap bidang dalam pengiriman divalidasi sesuai persyaratan Penyimpanan
- Aturan validasi Detail Persyaratan Sistem:
- Nilai yang Diizinkan dalam hardwareItemType = Memori: 300MB, 750MB, 1GB, 2GB, 4GB, 6GB, 8GB, 12GB, 16GB, 20GB
- Nilai yang Diizinkan dalam hardwareItemType = DirectX: DX9, DX10, DX11, DX12-FEATURELEVEL11, DX12-FEATURELEVEL12
- Nilai yang Diizinkan dalam hardwareItemType = Video_Memory: 1GB, 2GB, 4GB, 6GB
Jalur [Pembaruan Modul Lengkap]: /submission/v1/product/{productId}/metadata
Metode: PUT
Jalur [Module Patch Update]: /submission/v1/product/{productId}/metadata
Metode: PATCH
Perilaku API
Dalam kasus API Pembaruan Modul Lengkap – seluruh Data Modul perlu ada dalam Permintaan untuk pembaruan lengkap setiap bidang. Bidang apa pun yang tidak ada dalam Permintaan, nilai defaultnya digunakan untuk menimpa nilai saat ini untuk Modul tertentu tersebut.
Dalam kasus PATch Module Update API – hanya bidang yang akan diperbarui yang perlu ada dalam Permintaan. Nilai bidang dari Permintaan ini akan menimpa nilai yang ada, menjaga semua bidang lain yang tidak ada dalam Permintaan, sama seperti saat ini untuk Modul tertentu.
Parameter Jalur
Pengaturan | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
Header yang Diperlukan
Kepala Halaman | Nilai |
---|---|
Authorization: Bearer <Token> |
ID aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Parameter Permintaan
Nama | Tipe | Deskripsi |
---|---|---|
ketersediaan | Objek | Objek untuk menyimpan metadata Modul Ketersediaan |
pasar | Array string | Diperlukan Lihat daftar pasar di bawah ini |
kemampuan penemuan | string | Diperlukan [DAPAT DITEMUKAN, DEEPLINK_ONLY] |
enableInFutureMarkets | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Diperlukan |
harga | string | Diperlukan [GRATIS, FREEMIUM, LANGGANAN, BERBAYAR] |
freeTrial | string | Diperlukan jika Harga BERBAYAR atau LANGGANAN [NO_FREE_TRIAL, FREE_TRIAL] |
properti | Objek | Objek untuk menyimpan metadata Modul Properti |
Apakah Kebijakan Privasi Diperlukan | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Diperlukan |
urlKebijakanPrivasi | string | Diperlukan jika isPrivacyPolicyRequired = true Harus berupa URL yang valid |
situs web | string | Harus berupa URL yang valid |
InformasiKontakDukungan | string | Harus berupa URL atau alamat Email yang valid |
catatan sertifikasi | string | Batas Karakter yang Direkomendasikan = 2000 |
kategori | string | Diperlukan Lihat daftar kategori di bawah ini |
subkategori | string | Diperlukan Lihat daftar sub-kategori di bawah ini |
deklarasiProduk | Objek | Diperlukan |
apakahFiturSistemDiperlukan | Array objek | [Sentuh, Keyboard, Mouse, Kamera, NFC_HCE, NFC_Proximity, Bluetooth_LE, Telepon, Mikrofon] |
diharuskan | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Diperlukan |
direkomendasikan | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Diperlukan |
jenisItemPerangkatKeras | string | Diperlukan |
rincianPersyaratanSistem | Array objek | [Prosesor, Grafis, Memori, DirectX, Video_Memory] |
persyaratan minimum | string |
Diperlukan Untuk systemRequirementsText, MaxLength = 200 Nilai yang Diizinkan dalam hardwareItemType = Memori: [300MB, 750MB, 1GB, 2GB, 4GB, 6GB, 8GB, 12GB, 16GB, 20GB] Nilai yang Diizinkan dalam hardwareItemType = DirectX: [DX9, DX10, DX11, DX12-FEATURELEVEL11, DX12-FEATURELEVEL12] Nilai yang Diizinkan dalam hardwareItemType = Video_Memory: [1GB, 2GB, 4GB, 6GB] |
persyaratan yang direkomendasikan | string |
Diperlukan Untuk systemRequirementsText, MaxLength = 200 Nilai yang Diizinkan dalam hardwareItemType = Memori: [300MB, 750MB, 1GB, 2GB, 4GB, 6GB, 8GB, 12GB, 16GB, 20GB] Nilai yang Diizinkan dalam hardwareItemType = DirectX: [DX9, DX10, DX11, DX12-FEATURELEVEL11, DX12-FEATURELEVEL12] Nilai yang Diizinkan dalam hardwareItemType = Video_Memory: [1GB, 2GB, 4GB, 6GB] |
bergantungPadaDriverAtauNT | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Diperlukan |
dukungan aksesibilitas | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Diperlukan |
penAndInkSupport | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Diperlukan |
Daftar | Objek | Objek untuk mencantumkan data modul untuk satu bahasa |
bahasa | string | Diperlukan Lihat daftar bahasa di bawah ini |
deskripsi | string | Batas Karakter yang Diperlukan = 10000 |
Apa yang Baru | string | Batas karakter = 1500 |
fiturProduk | Array String | 200 karakter per fitur; Hingga 20 fitur |
Deskripsi Singkat | string | Batas karakter = 1000 |
Istilah Pencarian | Array String | 30 karakter per istilah pencarian; Hingga 7 istilah pencarian 21 kata unik TOTAL di semua istilah pencarian |
Ketentuan Lisensi Tambahan | string | Batas Karakter yang Diperlukan = 10000 |
hak cipta | string | Batas karakter = 200 |
dikembangkan oleh | string | Batas karakter = 255 |
persyaratan | Array objek | 200 karakter per item; TOTAL hingga 11 item antara minimum dan disarankan] |
minimumHardware | string | Batas karakter = 200 |
perangkat keras yang direkomendasikan | string | Batas karakter = 200 |
informasi kontak | string | Batas karakter = 200 |
daftar yang akan ditambahkan | Array string | Lihat daftar bahasa di bawah ini |
daftarUntukDihapus | Array string | Lihat daftar bahasa di bawah ini |
Pasar
Pasar | Singkatan |
---|---|
Afganistan | AF |
Albania | AL (Angkatan Laut) |
Aljazair | DZ |
Samoa Amerika | Amerika Serikat |
Andorra | IKLAN |
Angola | AO |
Anguilla | Kecerdasan Buatan (AI) |
Antarktika | AQ |
Antigua dan Barbuda | AG |
Argentina | AR (Augmented Reality) |
Armenia | pagi |
Aruba | AW |
Australia | AU |
Austria | PADA |
Azerbaijan | AZ |
Bahama | BS |
Bahrain | Bahrain |
Bangladesh | BD |
Barbados | BB |
Belarus | OLEH |
Belgia | ADA |
Belize | BZ |
Benin | BJ |
Bermuda | BM |
Bhutan | BT |
Republik Bolivarian Venezuela | VE |
Bolivia | BO |
Bonaire | BQ |
Bosnia dan Herzegovina | Bachelor of Arts |
Botswana | BW |
Pulau Bouvet | BV |
Brasil | Brasil |
Wilayah Inggris di Samudra Hindia | IO |
Kepulauan Virgin Britania Raya | VG |
Brunei Darussalam | BN |
Bulgaria | BG |
Burkina Faso | Pacar |
Burundi | Bank Indonesia |
Kamboja | KH |
Kamerun | cm |
Kanada | OS |
Tanjung Verde | Daftar Riwayat Hidup |
Kepulauan Cayman | KY |
Republik Afrika Tengah | CF |
Cad | TD |
Cile | CL |
Tiongkok | Cina |
Pulau Christmas | CX |
Kepulauan Cocos (Keeling) | CC |
Kolombia | Karbon Monoksida |
Komoro | KILOMETER |
Kongo | CG |
Kongo (DRC) | CD |
Kepulauan Cook | CK |
Kosta Rika | CR |
Kroasia | Sumber Daya Manusia |
Curaçao | CW |
Siprus | CY |
Republik Ceko | CZ |
Pantai Gading | Integrasi Berkelanjutan (CI) |
Denmark | DK |
Jibuti | DJ |
Dominika | DM |
Republik Dominika | MELAKUKAN |
Ekuador | Komisi Eropa |
Mesir | Misalnya |
El Salvador | SV |
Guinea Ekuatorial | GQ |
Eritrea | IGD |
Estonia | EE |
Etiopia | ET |
Kepulauan Falkland | FK |
Kepulauan Faroe | FO |
Fiji | FJ |
Finlandia | FI |
Prancis | FR |
Guyana Prancis | Pacar perempuan |
Polinesia Prancis | PF |
Tanah Prancis Selatan dan Antartika | TF |
Gabon | Majelis Umum |
Gambia | Manajer Umum |
Georgia | GE |
Jerman | Jerman |
Ghana | GH |
Gibraltar | Indeks Glikemik |
Yunani | GR |
Grinlandia | GL |
Grenada | GD |
Guadeloupe | dokter umum |
Guam | GU |
Guatemala | GT |
Guernsey | GG |
Guinea | GN |
Guinea-Bissau | GW |
Guyana | GY |
Haiti | HT |
Pulau Heard dan Kepulauan McDonald | HM |
Vatikan | VA |
Honduras | HN |
Hong Kong, Kawasan Administratif Khusus (SAR) | Hong Kong |
Hungaria | HU |
Islandia | Negara Islam |
India | DI |
Indonesia | Nomor Identitas |
Irak | IQ |
Irlandia | IE (Internet Explorer) |
Israel | Israel |
Italia | TI |
Jamaika | JM |
Jepang | JP |
Jersey | JE |
Yordania | JO |
Kazakstan | KZ |
Kenya | KE |
Kiribati | KI |
Korea Selatan | KR |
Kuwait | kW |
Kirgistan | kg |
Laos | LA |
Latvia | Latvia |
Libanon | LB |
Lesotho | LS |
Liberia | LR |
Libya | LY |
Liechtenstein | LI |
Lituania | LT |
Luksemburg | LU |
Makau SAR | MO |
Makedonia Utara | MK |
Madagaskar | MG |
Malawi | megawatt |
Malaysia | Milik saya |
Maladewa | MV |
Mali | ML |
Malta | MT |
Pulau Man | IM |
Kepulauan Marshall | MH |
Martinik | MQ |
Mauritania | Tuan |
Mauritius | MU |
Mayotte | YouTube |
Meksiko | MX |
Mikronesia | FM |
Moldova | MD |
Monako | Pembawa Acara (MC) |
Mongolia | MN |
Montenegr - ME | |
Montserrat | MS |
Maroko | Magister Seni |
Mozambik | MZ |
Myanmar | MM (milimeter) |
Namibia | NA |
Nauru | NR |
Nepal | NP |
Belanda | Belanda |
Kaledonia Baru | NC |
Selandia Baru | NZ |
Nikaragua | NI |
Niger | NE |
Nigeria | NG |
Niue | NU |
Kepulauan Norfolk | NF |
Kepulauan Mariana Utara | Anggota Parlemen |
Norwegia | TIDAK |
Oman | OM |
Pakistan | PK |
Palau | Tahanan perang |
Otoritas Nasional Palestina | P.S. |
Panama | PA |
Papua Nugini | PG |
Paraguay | PY |
Peru | PE |
Filipina | PH |
Kepulauan Pitcairn | PN |
Polandia | PL |
Portugal | PT |
Qatar | Penjaminan Kualitas (QA) |
Reuni | KEMBALI |
Rumania | RO |
Rusia | Rusia |
Rwanda | RW |
Saint Barthélemy | BL |
Saint Helena, Ascension dan Tristan da Cunha | SH |
Saint Kitts dan Nevis | KN |
Saint Lucia | LC |
Saint Martin (Bagian Prancis) | MF |
Saint Pierre dan Miquelon | Perdana Menteri |
Saint Vincent dan Grenadines | VC |
Samoa | WS |
San Marino | SM |
Arab Saudi | SA |
Senegal | SN |
Serbia dan Montenegro | RS |
Seychelles | SC |
Sierra Leone | SL |
Singapura | Singapura |
Sint Maarten (Bagian Belanda) | SX |
Slovakia | SK |
Slovenia | Sistem Internasional (SI) |
Kepulauan Solomon | SB |
Somalia | Jadi |
Afrika Selatan | Afrika Selatan |
Georgia Selatan dan Kepulauan Sandwich Selatan | GS |
Spanyol | ES |
Sri Lanka | LK |
Suriname | SR |
Svalbard dan Jan Mayen | SJ |
Swaziland | SZ |
Swedia | SE |
Swiss | CH |
São Tomé dan Príncipe | ST |
Taiwan | Taiwan |
Tajikistan | TJ |
Tanzania | TZ |
Thailand | TH |
Timor-Leste | TL |
Tog - TG | |
Tokelau | Taman Kanak-kanak |
Tonga | KE |
Trinidad dan Tobag - TT | |
Tunisia | TN |
Türkiye | TR |
Turkmenistan | TM |
Kepulauan Turks dan Caicos | TC |
Tuvalu | TELEVISI |
Kepulauan Terluar Kecil A.S. | UM |
Kepulauan Virgin A.S. | VI |
Uganda | UG |
Ukraina | UA |
Uni Emirat Arab | Æ |
Inggris Raya | GB |
Amerika Serikat | Amerika Serikat |
Uruguay | UY |
Uzbekistan | UZ |
Vanuatu | VU |
Vietnam | VN |
Wallis dan Futuna | WF |
Yaman | YA |
Zambia | ZM |
Zimbabwe | ZW |
Kepulauan Åland | Kapak |
Kategori dan Sub-kategori
Kategori | Subkategori |
---|---|
BooksAndReference | EReader, Fiksi, Nonfiksi, Referensi |
Bisnis | AkuntansiDanKeuangan, Kolaborasi, CRM, DataDanAnalisis, ManajemenFile, InventarisDanLogistik, LegalDanHR, ManajemenProyek, DesktopJarakJauh, PenjualanDanPemasaran, WaktuDanPengeluaran |
DeveloperTools | Database, DesignTools, DevelopmentKits, Jaringan, ReferenceAndTraining, Server, Utilitas, WebHosting |
Pendidikan | BukuPendidikanDanReferensi, PembelajaranDini, AlatInstruksional, Bahasa, BantuanBelajar |
Hiburan | (Tidak Ada) |
FoodAndDining | (Tidak Ada) |
Pemerintahan dan Politik | (Tidak Ada) |
Kesehatan dan Kebugaran | (Tidak Ada) |
KidsAndFamily | BukuDanRujukanAnakDanKeluarga, HiburanAnakDanKeluarga, HobiDanMainan, OlahragaDanKegiatan, PerjalananAnakDanKeluarga |
Gaya hidup | Otomotif, DYI, HomeAndGarden, Hubungan, SpecialInterest, StyleAndFashion |
Medis | (Tidak Ada) |
Desain Multimedia | IlustrasiAndGraphicDesign, MusicProduction, PhotoAndVideoProduction |
Musik | (Tidak Ada) |
NavigationAndMaps | (Tidak Ada) |
BeritaDanCuaca | Berita, Cuaca |
Keuangan Pribadi | PerbankanDanInvestasi, AnggaranDanPajak |
Personalisasi | RingtonesAndSounds, tema, WallpaperAndLockScreens |
PhotoAndVideo | (Tidak Ada) |
Produktivitas | (Tidak Ada) |
Keamanan | PCProtection, PersonalSecurity |
Berbelanja | (Tidak Ada) |
Sosial | (Tidak Ada) |
Olahraga | (Tidak Ada) |
Perjalanan | KotaGuides, Hotel-hotel |
UtilitasDanAlat | BackupAndManage, FileManager |
Bahasa
Nama bahasa | Kode bahasa yang didukung |
---|---|
Afrika | af, af-za |
Albania | sq, sq-al |
Amharik | pagi, am-et |
Armenia | hy, hy-am |
Assam | sebagai, as-in |
Azerbaijan | az-arab, az-arab-az, az-cyrl, az-cyrl-az, az-latn, az-latn-az |
Basque (Bahasa Basque) | Uni Eropa, eu-es |
Belarusia | menjadi, be-by |
Bengali | bn, bn-bd, bn-in |
Bosnia | bs, bs-cyrl, bs-cyrl-ba, bs-latn, bs-latn-ba |
Bulgaria | bg, bg-bg |
Katalan | ca, ca-es, ca-es-valensia |
Cherokee | chr-cher, chr-cher-us, chr-latn |
Tionghoa (Aksara Sederhana) | zh-Hans, zh-cn, zh-hans-cn, zh-sg, zh-hans-sg |
Tionghoa (Aksara Tradisional) | zh-Hant, zh-hk, zh-mo, zh-tw, zh-hant-hk, zh-hant-mo, zh-hant-tw, zh-mo, zh-tw, zh-hant-hk, zh-hant-mo, zh-hant-tw |
Kroasia | jam, jam-jam, hr-ba |
Cheska | cs, cs-cz |
Dansk | da, da-dk |
Dari | prs, prs-af, prs-arab |
Belanda | nl, nl-nl, nl-be |
Inggris | en, en-au, en-ca, en-gb, en-ie, en-in, en-nz, en-sg, en-us, en-za, en-bz, en-hk, en-id, en-jm, en-kz, en-mt, en-my, en-ph, en-pk, en-tt, en-vn, en-zw |
Esti | dan, et-ee |
Filipina - fil, fil-latn, fil-ph | |
Suomi | fi, fi-fi |
Prancis | fr, fr-be , fr-ca , fr-ch , fr-fr, fr-lu, fr-cd, fr-ci, fr-cm, fr-ht, fr-ma, fr-mc, fr-ml, fr-re, frc-latn, frp-latn |
Galisia | gl, gl-es |
Georgia | ka, ka-ge |
Jerman | de, de-at, de-ch, de-de, de-lu, de-li |
Yunani | el, el-gr |
Gujarat | gu, gu-in |
Hausa | ha, ha-latn, ha-latn-ng |
Ibrani | dia, he-il |
Bahasa Hindi | hai, hi-in |
Hungaria | hu, hu-hu |
Islandia | adalah, is-is |
Igb - ig-latn, ig-ng | |
Indonesia | id, id-id |
Inuktitut (Latin) | iu-cans, iu-latn, iu-latn-ca |
Irlandia | ga, ga-ie |
isiXhosa | xh, xh-za |
isiZulu | zu, zu-za |
Italia | itu, it-it, it-ch |
Jepang | ya , ja-jp |
Kannada | kn, kn-in |
Bahasa Kazak | kk, kk-kz |
Khmer | km, km-kh |
K'iche' | quc-latn, qut-gt, qut-latn |
Kinyarwanda | rw, rw-rw |
Kiswahili | sw, sw-ke |
Konkani | kok, kok-in |
Korea | ko, ko-kr |
Kurdi | ku-arab, ku-arab-iq |
Kirgiz | ky-kg, ky-cyrl |
Laos | Halo, lo-la |
Latvi | lv, lv-lv |
Lituavi | lt, lt-lt |
Luksemburg | lb, lb-lu |
Makedonia | mk, mk-mk |
Melayu | ms, ms-bn, ms-my |
Malayalam | ml, ml-in |
Malta | mt, mt-mt |
Maori | mi, mi-latn, mi-nz |
Marathi | mr, mr-in |
Bahasa Mongolia (Sirilik) | mn-cyrl, mn-mong, mn-mn, mn-phag |
Nepal | ne, ne-np |
Norwegia | nb, nb-no, nn, nn-no, tidak, no-no |
Odia | atau, atau |
Farsi | fa, fa-ir |
Polski | pl, pl-pl |
Portugis (Brasil) | pt-br |
Portugis (Portugal) | pt, pt-pt |
Punjabi | pa, pa-arab, pa-arab-pk, pa-deva, pa-in |
Quechua | quz, quz-bo, quz-ec, quz-pe |
Rumania | ro, ro-ro |
Rusia | ru , ru-ru |
Gaelik Skotlandia | gd-gb, gd-latn |
Serbia (Latin) | sr-Latn, sr-latn-cs, sr, sr-latn-ba, sr-latn-me, sr-latn-rs |
Serbia (Sirilik) | sr-cyrl, sr-cyrl-ba, sr-cyrl-cs, sr-cyrl-me, sr-cyrl-rs |
Sesotho sa Leboa | nso, nso-za |
Setswana | tn, tn-bw, tn-za |
Sindhi | sd-arab, sd-arab-pk, sd-deva |
Sinhala | si, si-lk |
Bahasa Slowakia | sk, sk-sk |
Sloven | sl, sl-si |
Spanyol | es, es-cl, es-co, es-es, es-mx, es-ar, es-bo, es-cr, es-do, es-ec, es-gt, es-hn, es-ni, es-pa, es-pe, es-pr, es-py, es-sv, es-us, es-uy, es-ve |
Swedia | sv, sv-se, sv-fi |
Tajik (Sirilik) | tg-arab, tg-cyrl, tg-cyrl-tj, tg-latn |
Tamil | Oke, ta-in |
Tatar | tt-arab, tt-cyrl, tt-latn, tt-ru |
Telugu | te, te-in |
Thailand | th, th-th |
Tigrinya | ti, ti-et |
Turki | tr, tr-tr |
etnis Turkmen | tk-cyrl, tk-latn, tk-tm, tk-latn-tr, tk-cyrl-tr |
Ukraina | Inggris, uk-ua |
Bahasa Urdu | Anda, your-pk |
Suku Uighur | ug-arab, ug-cn, ug-cyrl, ug-latn |
Uzbekistan (Latin) | uz, uz-cyrl, uz-latn, uz-latn-uz |
Vietnam | vi, vi-vn |
Wales | cy, cy-gb |
Wolof | wo, wo-sn |
Yoruba | yo-latn, yo-ng |
Permintaan Sampel
{
"availability":{
"markets": ["US"],
"discoverability": "DISCOVERABLE",
"enableInFutureMarkets": true,
"pricing": "PAID",
"freeTrial": "NO_FREE_TRIAL"
},
"properties":{
"isPrivacyPolicyRequired": true,
"privacyPolicyUrl": "http://contoso.com",
"website": "http://contoso.com",
"supportContactInfo": "http://contoso.com",
"certificationNotes": "Certification Notes",
"category": "DeveloperTools",
"subcategory": "Database",
"productDeclarations": {
"dependsOnDriversOrNT": false,
"accessibilitySupport": false,
"penAndInkSupport": false
},
"isSystemFeatureRequired": [
{
"isRequired": true,
"isRecommended": false,
"hardwareItemType": "Touch"
},
{
"isRequired": true,
"isRecommended": false,
"hardwareItemType": "Keyboard"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Mouse"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Camera"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "NFC_HCE"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "NFC_Proximity"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Bluetooth_LE"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Telephony"
},
{
"isRequired": false,
"isRecommended": false,
"hardwareItemType": "Microphone"
}
],
"systemRequirementDetails": [
{
"minimumRequirement": "1GB",
"recommendedRequirement": "4GB",
"hardwareItemType": "Memory"
},
{
"minimumRequirement": "",
"recommendedRequirement": "",
"hardwareItemType": "DirectX"
},
{
"minimumRequirement": "",
"recommendedRequirement": "",
"hardwareItemType": "Video_Memory"
},
{
"minimumRequirement": "",
"recommendedRequirement": "",
"hardwareItemType": "Processor"
},
{
"minimumRequirement": "",
"recommendedRequirement": "",
"hardwareItemType": "Graphics"
}
]
},
"listings":{
"language": "en-us",
"description": "Description",
"whatsNew": "What's New",
"productFeatures": ["Feature 1"],
"shortDescription": "Short Description",
"searchTerms": ["Search Ter 1"],
"additionalLicenseTerms": "License Terms",
"copyright": "Copyright Information",
"developedBy": "Developer Details",
"sortTitle": "Product 101",
"requirements": [
{
"minimumHardware": "Pentium4",
"recommendedHardware": "Corei9"
}
],
"contactInfo": "contactus@contoso.com"
},
"listingsToAdd": ["en-au"],
"listingsToRemove": ["en-gb"]
}
Header Respons
Kepala Halaman | Nilai |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan Tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | Daftar pesan kesalahan atau peringatan jika ada |
kode | string | Kode kesalahan Pesan |
pesan | string | Deskripsi kesalahan |
sasaran | string | Entitas tempat Kesalahan berasal |
responseData | Objek | Berisi Payload respons aktual untuk Permintaan |
URL pemungutan suara | string | URL Polling untuk mendapatkan status Pengiriman Yang Sedang Berlangsung |
IDPengajuanBerlangsung | string | Id Pengiriman dari Pengiriman yang Sudah Berlangsung |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"pollingUrl": "/submission/v1/product/{productId}/submission/{submissionId}/status",
"ongoingSubmissionId": ""
}
}
Dapatkan API Paket Draf Saat Ini
Mengambil detail paket di bawah pengiriman draf saat ini.
Jalur [Semua Paket]: /submission/v1/product/{productId}/packages
Metode: GET
Jalur [Paket Tunggal]: /submission/v1/product/{productId}/packages/{packageId}
Metode: GET
Parameter Jalur
Nama | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
packageId | ID unik paket yang akan diambil |
Header yang Diperlukan
Kepala Halaman | Nilai |
---|---|
Authorization: Bearer <Token> |
Menggunakan ID aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Header Respons
Kepala Halaman | Nilai |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | Daftar kesalahan atau pesan peringatan jika ada |
kode | string | Kode kesalahan Pesan |
pesan | string | Deskripsi kesalahan |
sasaran | string | Entitas tempat kesalahan berasal |
responseData | Objek | |
paket | Array objek | Objek untuk menyimpan data modul paket |
packageId | string | |
packageUrl | string | |
bahasa | Array string | |
Arsitektur | Array string | [Netral, X86, X64, Arm, Arm64] |
isSilentInstall | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Ini harus ditandai sebagai true jika alat penginstal Anda berjalan dalam mode senyap tanpa memerlukan sakelar atau false lainnya |
installerParameters | string | |
genericDocUrl | string | |
detailKesalahan | Array objek | |
skenarioKesalahan | string | |
errorScenarioDetails | Array objek | |
nilaiKesalahan | string | |
errorUrl | string | |
jenis paket | string |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData":{
"packages":[{
"packageId": "pack0832",
"packageUrl": "https://www.contoso.com/downloads/1.1/setup.exe",
"languages": ["en-us"],
"architectures": ["X86"],
"isSilentInstall": true,
"installerParameters": "/s",
"genericDocUrl": "https://docs.contoso.com/doclink",
"errorDetails": [{
"errorScenario": "rebootRequired",
"errorScenarioDetails": [{
"errorValue": "ERR001001",
"errorUrl": "https://errors.contoso.com/errors/ERR001001"
}]
}],
"packageType": "exe",
}]
}
}
Perbarui API Paket Draf Saat Ini
Memperbarui detail paket di bawah pengiriman draf saat ini.
Jalur [Pembaruan Modul Lengkap]: /submission/v1/product/{productId}/packages
Metode: PUT
Jalur [Pembaruan Patch Paket Tunggal]: /submission/v1/product/{productId}/packages/{packageId}
Metode: PATCH
Perilaku API
Dalam kasus API Pembaruan Modul Penuh - seluruh data paket perlu ada dalam permintaan untuk pembaruan penuh dari setiap bidang. Bidang apa pun yang tidak ada dalam permintaan, nilai defaultnya digunakan untuk menimpa nilai saat ini untuk modul tertentu tersebut. Ini menghasilkan penimpaan semua paket yang ada dengan sekumpulan paket baru dari permintaan. Ini akan mengakibatkan regenerasi Id Paket dan pengguna harus memanggil GET Packages API untuk Id Paket terbaru.
Dalam kasus API Pembaruan Patch Paket Tunggal – hanya bidang yang akan diperbarui untuk paket tertentu yang perlu ada dalam permintaan. Nilai bidang dari permintaan ini akan menimpa nilai yang ada, menyimpan semua bidang lain yang tidak ada dalam permintaan, sama seperti saat ini untuk paket tertentu tersebut. Paket lain dalam set tetap apa adanya.
Parameter Jalur
Nama | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
packageId | ID unik paket |
Header yang Diperlukan
Kepala Halaman | Nilai |
---|---|
Authorization: Bearer <Token> |
Menggunakan ID aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Parameter Permintaan
Nama | Tipe | Deskripsi |
---|---|---|
paket | Array Objek | Objek untuk menyimpan data Modul Paket [Hanya Diperlukan untuk Pembaruan Modul Penuh] |
packageUrl | string | Diperlukan |
bahasa | Array string | Diperlukan |
Arsitektur | Array string | Diperlukan Harus berisi arsitektur tunggal - Netral, X86, X64, Arm, Arm64 |
isSilentInstall | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Diperlukan Ini harus ditandai sebagai true jika alat penginstal Anda berjalan dalam mode senyap tanpa memerlukan sakelar atau false lainnya |
installerParameters | string | Diperlukan jika isSilentInstall salah |
genericDocUrl | string | Diperlukan jika packageType adalah exe Link ke dokumen yang berisi detail kode kesalahan kustom untuk penginstal jenis EXE |
detailKesalahan | Array Objek | Metadata untuk menyimpan kode kesalahan kustom dan detail untuk Penginstal jenis EXE. |
skenarioKesalahan | string | Identifikasi skenario kesalahan tertentu. [instalasiDibatalkanOlehPengguna, aplikasiSudahAda, instalasiSedangBerlangsung, ruangDiskPenuh, perluRestart, kegagalanJaringan, paketDitolakSelamaInstalasi, instalasiBerhasil, lain-lain] |
errorScenarioDetails | Array Objek | |
nilaiKesalahan | string | Kode kesalahan yang dapat ada selama Penginstalan |
URL kesalahan | string | URL untuk memiliki detail tentang kesalahan |
jenis paket | string | Diperlukan [exe, msi] |
Permintaan Sampel [Pembaruan Modul Lengkap]
{
"packages":[{
"packageUrl": "https://www.contoso.com/downloads/1.1/setup.exe",
"languages": ["en-us"],
"architectures": ["X86"],
"isSilentInstall": true,
"installerParameters": "/s",
"genericDocUrl": "https://docs.contoso.com/doclink",
"errorDetails": [{
"errorScenario": "rebootRequired",
"errorScenarioDetails": [{
"errorValue": "ERR001001",
"errorUrl": "https://errors.contoso.com/errors/ERR001001"
}]
}],
"packageType": "exe",
}]
}
Permintaan Sampel [Pembaruan Patch Paket Tunggal]
{
"packageUrl": "https://www.contoso.com/downloads/1.1/setup.exe",
"languages": ["en-us"],
"architectures": ["X86"],
"isSilentInstall": true,
"installerParameters": "/s",
"genericDocUrl": "https://docs.contoso.com/doclink",
"errorDetails": [{
"errorScenario": "rebootRequired",
"errorScenarioDetails": [{
"errorValue": "ERR001001",
"errorUrl": "https://errors.contoso.com/errors/ERR001001"
}]
}],
"packageType": "exe",
}
Header Respons
Kepala Halaman | Nilai |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | [Daftar pesan kesalahan atau peringatan jika ada] |
kode | string | Kode Kesalahan Pesan |
pesan | string | Deskripsi Kesalahan |
sasaran | string | Entitas tempat Kesalahan berasal |
responseData | Objek | |
URL pemungutan suara | string | [URL Polling untuk mendapatkan Status Pengiriman jika ada Pengiriman yang Sudah Berlangsung] |
IDPengajuanBerlangsung | string | [ID Pengiriman dari Pengiriman yang Sudah Berlangsung] |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"pollingUrl": "/submission/v1/product/{productId}/submission/{submissionId}/status",
"ongoingSubmissionId": ""
}
}
Commit Packages API
Menerapkan kumpulan Paket baru yang diperbarui menggunakan API Pembaruan Paket di bawah pengiriman draf saat ini. API ini mengembalikan URL Polling untuk melacak Unggahan Paket.
Jalur: /submission/v1/product/{productId}/packages/commit
Metode: POST
Parameter Jalur
Nama | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
Header yang Diperlukan
Kepala Halaman | Nilai |
---|---|
Authorization: Bearer <Token> |
Menggunakan ID Aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Header Respons
Kepala Halaman | Nilai |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | [Daftar pesan kesalahan atau peringatan jika ada] |
kode | string | Kode kesalahan Pesan |
pesan | string | Deskripsi kesalahan |
sasaran | string | Entitas tempat kesalahan berasal |
responseData | Objek | |
URL pemungutan suara | string | [URL Polling untuk mendapatkan status Status Unggahan atau Pengiriman Paket jika ada Pengiriman yang Sudah Berlangsung] |
IDPengajuanBerlangsung | string | [Id Pengiriman dari Pengiriman yang Sudah Berlangsung] |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"pollingUrl": "/submission/v1/product/{productId}/status",
"ongoingSubmissionId": ""
}
}
Dapatkan API Aset Daftar Draf Saat Ini
Mengambil detail aset daftar di bawah pengiriman draf saat ini.
Jalur: /submission/v1/product/{productId}/listings/assets?languages={languages}
Metode: GET
Parameter Jalur
Nama | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
Parameter Kueri:
Nama | Deskripsi |
---|---|
bahasa | [Opsional] Bahasa daftar memfilter sebagai string yang dipisahkan koma [batas hingga 200 bahasa]. Jika tidak ada, 200 data aset bahasa daftar pertama yang tersedia akan diambil. (misalnya, "en-us, en-gb") |
Header yang Diperlukan
Kepala Halaman | Nilai |
---|---|
Authorization: Bearer <Token> |
Menggunakan ID Aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Header Respons
Kepala Halaman | Nilai |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | Daftar pesan kesalahan atau peringatan jika ada |
kode | string | Kode kesalahan Pesan |
pesan | string | Deskripsi kesalahan |
sasaran | string | Entitas tempat kesalahan berasal |
responseData | Objek | |
daftarAset | Array objek | Mencantumkan detail aset untuk setiap bahasa |
bahasa | string | |
storeLogos | Array objek | |
cuplikan layar | Array objek | |
Id | string | |
assetUrl | string | Harus berupa URL yang valid |
ukuran gambar | Objek | |
lebar | Bilangan bulat | |
tinggi | Bilangan bulat |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData":{
"listingAssets": [{
"language": "en-us",
"storeLogos": [
{
"id": "1234567890abcdefgh",
"assetUrl": "https://contoso.com/blob=1234567890abcdefgh",
"imageSize": {
"width": 2160,
"height": 2160
}
}
],
"screenshots": [
{
"id": "1234567891abcdefgh",
"assetUrl": "https://contoso.com/blob=1234567891abcdefgh",
"imageSize": {
"width": 2160,
"height": 2160
}
}
]
}]
}
}
Membuat API Aset Daftar
Membuat Unggahan Aset Daftar baru di bawah pengiriman draf saat ini.
Pembaruan aset Daftar
MICROSOFT Store Submission API untuk EXE atau aplikasi MSI menggunakan URL SAS yang dihasilkan runtime ke Blob Stores untuk setiap unggahan aset gambar individu, bersama dengan panggilan Commit API setelah pengunggahan berhasil. Untuk memiliki kemampuan untuk memperbarui aset daftar, dan pada gilirannya, untuk dapat menambahkan/menghapus lokal dalam modul daftar, pendekatan berikut dapat digunakan:
- Gunakan API Buat Aset Daftar untuk mengirim permintaan mengenai pengunggahan aset bersama dengan bahasa, jenis, dan jumlah aset.
- Berdasarkan jumlah aset yang diminta, ID Aset dibuat sesuai permintaan dan akan membuat URL SAS jangka pendek dan mengirimkannya kembali di Isi Respons di bawah jenis aset. Anda dapat menggunakan URL ini untuk mengunggah aset Gambar dari jenis tertentu menggunakan Klien HTTP [Put Blob (REST API) - Azure Storage | Microsoft Docs].
- Setelah mengunggah, Anda dapat menggunakan COMmit Listing Assets API untuk juga mengirim informasi ID Aset baru yang diterima sebelumnya dari panggilan API sebelumnya. API tunggal akan secara internal menerapkan data aset daftar setelah validasi.
- Pendekatan ini akan secara efektif menimpa seluruh set Gambar Sebelumnya dari Jenis Aset di bawah Bahasa tertentu yang sedang dikirim dalam Permintaan. Oleh karena itu, Aset yang diunggah sebelumnya akan dihapus.
Jalur: /submission/v1/product/{productId}/listings/assets/create
Metode: POST
Parameter Jalur
Nama | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
Header yang Diperlukan
Kepala Halaman | Deskripsi |
---|---|
Authorization: Bearer <Token> |
Menggunakan ID Aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Parameter Permintaan
Nama | Tipe | Deskripsi |
---|---|---|
bahasa | string | Diperlukan |
buatPermintaanAset | Objek | Diperlukan |
Cuplikan layar | Bilangan bulat | Diperlukan jika ISV perlu memperbarui cuplikan layar atau menambahkan bahasa daftar baru [1 - 10] |
Logo | Bilangan bulat | Diperlukan jika ISV perlu memperbarui logo atau menambahkan bahasa daftar baru [1 atau 2] |
Header Respons
Kepala Halaman | Deskripsi |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | Daftar pesan kesalahan atau peringatan jika ada |
kode | string | Kode kesalahan Pesan |
pesan | string | Deskripsi kesalahan |
sasaran | string | Entitas tempat kesalahan berasal |
responseData | Objek | |
daftarAset | Objek | Objek yang berisi detail StoreLogos dan Cuplikan layar yang akan diunggah |
bahasa | string | |
storeLogos | Array objek | |
cuplikan layar | Array objek | |
Id | string | |
URL Upload Aset Utama | string | URL utama untuk mengunggah aset daftar menggunakan Azure Blob REST API |
URLUnggahAsetSekunder | string | URL sekunder untuk mengunggah aset daftar menggunakan Azure Blob REST API |
Metode HTTP | Metode HTTP | Metode HTTP perlu digunakan untuk mengunggah Aset melalui URL Pengunggahan Aset – Primer atau Sekunder |
httpHeader | Objek | Objek dengan kunci sebagai Header yang diperlukan untuk hadir dalam panggilan Unggah API ke URL Pengunggahan Aset. Jika nilainya tidak kosong, header harus memiliki nilai tertentu. Jika tidak, nilai dihitung selama panggilan API. |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"listingAssets": {
"language": "en-us",
"storeLogos":[{
"id": "1234567890abcdefgh",
"primaryAssetUploadUrl": "https://contoso.com/upload?blob=1234567890abcdefgh&sig=12345",
"secondaryAssetUploadUrl": "https://contoso.com/upload?blob=0987654321abcdfger&sig=54326",
"httpMethod": "PUT",
"httpHeaders": {"Required Header Name": "Header Value"}
}],
"screenshots":[{
"id": "0987654321abcdfger",
"primaryAssetUploadUrl": "https://contoso.com/upload?blob=0987654321abcdfger&sig=54321",
"secondaryAssetUploadUrl": "https://contoso.com/upload?blob=0987654321abcdfger&sig=54322",
"httpMethod": "PUT",
"httpHeaders": {"Required Header Name": "Header Value"}
}]
}
}
}
Terapkan API Aset Daftar
Menerapkan Aset Daftar baru yang Diunggah menggunakan detail dari Buat Aset API di bawah pengiriman draf saat ini.
Jalur: /submission/v1/product/{productId}/listings/assets/commit
Metode: PUT
Parameter Jalur
Nama | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
Header yang Diperlukan
Kepala Halaman | Deskripsi |
---|---|
Authorization: Bearer <Token> |
Menggunakan ID Aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Parameter Permintaan
Nama | Tipe | Deskripsi |
---|---|---|
daftarAset | Objek | |
bahasa | string | |
logo toko | Array Objek | |
cuplikan layar | Array Objek | |
Id | string | Harus berupa ID yang sudah ada yang ingin dipertahankan pengguna dari Get Current Listing Assets API atau ID baru di mana Aset baru diunggah di Create Listing Assets API. |
assetUrl | string | Harus berupa URL Aset yang ada yang ingin dipertahankan pengguna dari Get Current Listing Assets API atau URL Unggah – Primer atau Sekunder, yang menggunakan Aset baru yang diunggah di Api Buat Aset Daftar. Harus berupa URL yang valid |
Permintaan Sampel
{
"listingAssets": {
"language": "en-us",
"storeLogos": [
{
"id": "1234567890abcdefgh",
"assetUrl": "https://contoso.com/blob=1234567890abcdefgh",
}
],
"screenshots": [
{
"id": "1234567891abcdefgh",
"assetUrl": "https://contoso.com/blob=1234567891abcdefgh",
}
]
}
}
Header Respons
Kepala Halaman | Deskripsi |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | Daftar pesan kesalahan atau peringatan jika ada |
kode | string | Kode kesalahan Pesan |
pesan | string | Deskripsi kesalahan |
sasaran | string | Entitas tempat kesalahan berasal |
responseData | Objek | |
URL pemungutan suara | string | URL polling untuk mendapatkan status pengiriman yang sedang berlangsung |
IDPengajuanBerlangsung | string | ID pengiriman dari pengiriman yang sudah berlangsung |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"pollingUrl": "/submission/v1/product/{productId}/submission/{submissionId}/status",
"ongoingSubmissionId": ""
}
}
API Polling Status Modul
API untuk memeriksa kesiapan modul sebelum pengiriman dapat dibuat. Juga memvalidasi status unggahan paket.
Jalur: /submission/v1/product/{productId}/status
Metode: GET
Parameter Jalur
Nama | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
Header yang Diperlukan
Kepala Halaman | Deskripsi |
---|---|
Authorization: Bearer <Token> |
Menggunakan ID Aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Header Respons
Kepala Halaman | Deskripsi |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | Daftar pesan kesalahan atau peringatan jika ada |
kode | string | Kode kesalahan Pesan |
pesan | string | Deskripsi kesalahan |
sasaran | string | Entitas tempat kesalahan berasal |
responseData | Objek | |
isReady | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Menunjukkan apakah semua Modul dalam status siap termasuk unggahan paket |
IDPengajuanBerlangsung | string | ID pengiriman dari pengiriman yang sudah berlangsung |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"isReady": true,
"ongoingSubmissionId": ""
}
}
Membuat API Pengiriman
Membuat pengiriman dari draf saat ini untuk aplikasi MSI atau EXE. API memeriksa:
- untuk pengiriman aktif dan gagal dengan pesan kesalahan jika pengiriman aktif ada.
- jika semua modul dalam status siap untuk membuat pengiriman.
- setiap bidang dalam pengiriman divalidasi sesuai persyaratan Penyimpanan
Jalur:/submission/v1/product/{productId}/submit
Metode: POST
Parameter Jalur
Nama | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
Header yang Diperlukan
Kepala Halaman | Deskripsi |
---|---|
Authorization: Bearer <Token> |
Menggunakan ID Aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Header Respons
Kepala Halaman | Deskripsi |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | Daftar pesan kesalahan atau peringatan jika ada |
kode | string | Kode kesalahan Pesan |
pesan | string | Deskripsi kesalahan |
sasaran | string | Entitas tempat kesalahan berasal |
responseData | Objek | |
URL pemungutan suara | string | URL polling untuk mendapatkan status kesiapan modul termasuk unggahan paket untuk pengiriman |
ID pengajuan | string | ID untuk Pengiriman yang baru dibuat |
IDPengajuanBerlangsung | string | ID pengiriman dari pengiriman yang sudah berlangsung |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"submissionId": "1234567890",
"pollingUrl": "/submission/v1/product/{productId}/submission/{submissionId}/status",
"ongoingSubmissionId": ""
}
}
API Polling Status Pengiriman
API untuk memeriksa Status Pengiriman.
Jalur: /submission/v1/product/{productId}/submission/{submissionId}/status
Metode: GET
Parameter Jalur
Nama | Deskripsi |
---|---|
ID produk | ID Pusat Mitra produk |
Header yang Diperlukan
Kepala Halaman | Deskripsi |
---|---|
Authorization: Bearer <Token> |
Menggunakan ID Aplikasi Azure ACTIVE Directory yang terdaftar di akun Pusat Mitra |
X-Seller-Account-Id |
ID Penjual akun Pusat Mitra |
Header Respons
Kepala Halaman | Deskripsi |
---|---|
X-Correlation-ID |
ID unik jenis GUID untuk setiap permintaan. Ini dapat dibagikan dengan tim Dukungan untuk menganalisis masalah apa pun. |
Retry-After |
Waktu dalam detik klien harus menunggu sebelum memanggil API lagi karena pembatasan tarif. |
Parameter Respons
Nama | Tipe | Deskripsi |
---|---|---|
apakahBerhasil | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | |
Kesalahan | Array objek | Daftar pesan kesalahan atau peringatan jika ada |
kode | string | Kode kesalahan Pesan |
pesan | string | Deskripsi kesalahan |
sasaran | string | Entitas tempat kesalahan berasal |
responseData | Objek | |
status penerbitan | string | Status Penerbitan Pengiriman - [INPROGRESS, PUBLISHED, FAILED, UNKNOWN] |
telah gagal | Boolean (tipe data yang hanya memiliki dua nilai: true atau false) | Menunjukkan apakah Penerbitan Gagal dan tidak akan dicoba kembali |
Respons Sampel
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"publishingStatus": "INPROGRESS",
"hasFailed": false
}
}
Contoh kode
Artikel berikut ini menyediakan contoh kode terperinci yang menunjukkan cara menggunakan API pengiriman Microsoft Store dalam bahasa pemrograman yang berbeda:
Sampel C#: MICROSOFT Store Submission API untuk aplikasi MSI atau EXE
Artikel ini menyediakan contoh kode C# yang menunjukkan cara menggunakan API pengiriman Microsoft Store untuk aplikasi MSI atau EXE. Anda dapat meninjau setiap contoh untuk mempelajari lebih lanjut tentang tugas yang ditunjukkannya, atau Anda dapat membuat semua contoh kode dalam artikel ini ke dalam aplikasi konsol.
Prasyarat Contoh ini menggunakan pustaka berikut:
- Paket Newtonsoft.Json NuGet dari Newtonsoft.
Program utama Contoh berikut mengimplementasikan program baris perintah yang memanggil metode contoh lain dalam artikel ini untuk menunjukkan berbagai cara untuk menggunakan API pengiriman Microsoft Store. Untuk menyesuaikan program ini untuk penggunaan Anda sendiri:
- Tetapkan properti SellerId ke ID Penjual akun Pusat Mitra Anda.
- Tetapkan properti ApplicationId ke ID aplikasi yang ingin Anda kelola.
- Tetapkan properti ClientId dan ClientSecret ke ID klien dan kunci untuk aplikasi Anda, dan ganti string tenantid di URL TokenEndpoint dengan ID penyewa untuk aplikasi Anda. Untuk informasi selengkapnya, lihat Cara mengaitkan aplikasi Microsoft Azure Active Directory dengan akun Pusat Mitra Anda
using System;
using System.Threading.Tasks;
namespace Win32SubmissionApiCSharpSample
{
public class Program
{
static async Task Main(string[] args)
{
var config = new ClientConfiguration()
{
ApplicationId = "...",
ClientId = "...",
ClientSecret = "...",
Scope = "https://api.store.microsoft.com/.default",
ServiceUrl = "https://api.store.microsoft.com",
TokenEndpoint = "...",
SellerId = 0
};
await new AppSubmissionUpdateSample(config).RunAppSubmissionUpdateSample();
}
}
}
Kelas pembantu ClientConfiguration menggunakan C#
Aplikasi sampel menggunakan kelas pembantu ClientConfiguration untuk meneruskan data Azure Active Directory dan data aplikasi ke setiap metode contoh yang menggunakan API pengiriman Microsoft Store.
using System;
using System.Collections.Generic;
using System.Text;
namespace Win32SubmissionApiCSharpSample
{
public class ClientConfiguration
{
/// <summary>
/// Client Id of your Azure Active Directory app.
/// Example" 00001111-aaaa-2222-bbbb-3333cccc4444
/// </summary>
public string ClientId { get; set; }
/// <summary>
/// Client secret of your Azure Active Directory app
/// </summary>
public string ClientSecret { get; set; }
/// <summary>
/// Service root endpoint.
/// Example: "https://api.store.microsoft.com"
/// </summary>
public string ServiceUrl { get; set; }
/// <summary>
/// Token endpoint to which the request is to be made. Specific to your Azure Active Directory app
/// Example: https://login.microsoftonline.com/d454d300-128e-2d81-334a-27d9b2baf002/oauth2/v2.0/token
/// </summary>
public string TokenEndpoint { get; set; }
/// <summary>
/// Resource scope. If not provided (set to null), default one is used for the production API
/// endpoint ("https://api.store.microsoft.com/.default")
/// </summary>
public string Scope { get; set; }
/// <summary>
/// Partner Center Application ID.
/// Example: 3e31a9f9-84e8-4d2d-9eba-487878d02ebf
/// </summary>
public string ApplicationId { get; set; }
/// <summary>
/// The Partner Center Seller Id
/// Example: 123456892
/// </summary>
public int SellerId { get; set; }
}
}
Membuat pengiriman aplikasi menggunakan C#
Contoh berikut mengimplementasikan kelas yang menggunakan beberapa metode di API pengiriman Microsoft Store untuk memperbarui pengiriman aplikasi.
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace Win32SubmissionApiCSharpSample
{
public class AppSubmissionUpdateSample
{
private ClientConfiguration ClientConfig;
/// <summary>
/// Constructor
/// </summary>
/// <param name="configuration">An instance of ClientConfiguration that contains all parameters populated</param>
public AppSubmissionUpdateSample(ClientConfiguration configuration)
{
this.ClientConfig = configuration;
}
/// <summary>
/// Main method to Run the Sample Application
/// </summary>
/// <returns></returns>
/// <exception cref="InvalidOperationException"></exception>
public async Task RunAppSubmissionUpdateSample()
{
// **********************
// SETTINGS
// **********************
var appId = this.ClientConfig.ApplicationId;
var clientId = this.ClientConfig.ClientId;
var clientSecret = this.ClientConfig.ClientSecret;
var serviceEndpoint = this.ClientConfig.ServiceUrl;
var tokenEndpoint = this.ClientConfig.TokenEndpoint;
var scope = this.ClientConfig.Scope;
// Get authorization token.
Console.WriteLine("Getting authorization token");
var accessToken = await SubmissionClient.GetClientCredentialAccessToken(
tokenEndpoint,
clientId,
clientSecret,
scope);
var client = new SubmissionClient(accessToken, serviceEndpoint);
client.DefaultHeaders = new Dictionary<string, string>()
{
{"X-Seller-Account-Id", this.ClientConfig.SellerId.ToString() }
};
Console.WriteLine("Getting Current Application Draft Status");
dynamic AppDraftStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ProductDraftStatusPollingUrlTemplate,
SubmissionClient.Version, appId), null);
Console.WriteLine(AppDraftStatus.ToString());
Console.WriteLine("Getting Application Packages ");
dynamic PackagesResponse = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.PackagesUrlTemplate,
SubmissionClient.Version, appId), null);
Console.WriteLine(PackagesResponse.ToString());
Console.WriteLine("Getting Single Package");
dynamic SinglePackageResponse = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.PackageByIdUrlTemplate,
SubmissionClient.Version, appId, (string)PackagesResponse.responseData.packages[0].packageId), null);
Console.WriteLine(SinglePackageResponse.ToString());
Console.WriteLine("Updating Entire Package Set");
// Update data in Packages list to have final set of updated Packages
// Example - Updating Installer Parameters
PackagesResponse.responseData.packages[0].installerParameters = "/s /r new-args";
dynamic PackagesUpdateRequest = new
{
packages = PackagesResponse.responseData.packages
};
dynamic PackagesUpdateResponse = await client.Invoke<dynamic>(HttpMethod.Put, string.Format(SubmissionClient.PackagesUrlTemplate,
SubmissionClient.Version, appId), PackagesUpdateRequest);
Console.WriteLine(PackagesUpdateResponse.ToString());
Console.WriteLine("Updating Single Package's Download Url");
// Update data in the SinglePackage object
var SinglePackageUpdateRequest = SinglePackageResponse.responseData.packages[0];
// Example - Updating Installer Parameters
SinglePackageUpdateRequest.installerParameters = "/s /r /t new-args";
dynamic PackageUpdateResponse = await client.Invoke<dynamic>(HttpMethod.Patch, string.Format(SubmissionClient.PackageByIdUrlTemplate,
SubmissionClient.Version, appId, SinglePackageUpdateRequest.packageId), SinglePackageUpdateRequest);
Console.WriteLine("Committing Packages");
dynamic PackageCommitResponse = await client.Invoke<dynamic>(HttpMethod.Post, string.Format(SubmissionClient.PackagesCommitUrlTemplate,
SubmissionClient.Version, appId), null);
Console.WriteLine(PackageCommitResponse.ToString());
Console.WriteLine("Polling Package Upload Status");
AppDraftStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ProductDraftStatusPollingUrlTemplate,
SubmissionClient.Version, appId), null);
while (!((bool)AppDraftStatus.responseData.isReady))
{
AppDraftStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ProductDraftStatusPollingUrlTemplate,
SubmissionClient.Version, appId), null);
Console.WriteLine("Waiting for Upload to finish");
await Task.Delay(TimeSpan.FromSeconds(2));
if(AppDraftStatus.errors != null && AppDraftStatus.errors.Count > 0)
{
for(var index = 0; index < AppDraftStatus.errors.Count; index++)
{
if(AppDraftStatus.errors[index].code == "packageuploaderror")
{
throw new InvalidOperationException("Package Upload Failed. Please try committing packages again.");
}
}
}
}
Console.WriteLine("Getting Application Metadata - All Modules");
dynamic AppMetadata = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.AppMetadataUrlTemplate,
SubmissionClient.Version, appId), null);
Console.WriteLine(AppMetadata.ToString());
Console.WriteLine("Getting Application Metadata - Listings");
dynamic AppListingsMetadata = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.AppListingsFetchMetadataUrlTemplate,
SubmissionClient.Version, appId), null);
Console.WriteLine(AppListingsMetadata.ToString());
Console.WriteLine("Updating Listings Metadata - Description");
// Update Required Fields in Listings Metadata Object - Per Language. For eg. AppListingsMetadata.responseData.listings[0]
// Example - Updating Description
AppListingsMetadata.responseData.listings[0].description = "New Description Updated By C# Sample Code";
dynamic ListingsUpdateRequest = new
{
listings = AppListingsMetadata.responseData.listings[0]
};
dynamic UpdateListingsMetadataResponse = await client.Invoke<dynamic>(HttpMethod.Put, string.Format(SubmissionClient.AppMetadataUrlTemplate,
SubmissionClient.Version, appId), ListingsUpdateRequest);
Console.WriteLine(UpdateListingsMetadataResponse.ToString());
Console.WriteLine("Getting All Listings Assets");
dynamic ListingAssets = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ListingAssetsUrlTemplate,
SubmissionClient.Version, appId), null);
Console.WriteLine(ListingAssets.ToString());
Console.WriteLine("Creating Listing Assets for 1 Screenshot");
dynamic AssetCreateRequest = new
{
language = ListingAssets.responseData.listingAssets[0].language,
createAssetRequest = new Dictionary<string, int>()
{
{"Screenshot", 1 },
{"Logo", 0 }
}
};
dynamic AssetCreateResponse = await client.Invoke<dynamic>(HttpMethod.Post, string.Format(SubmissionClient.ListingAssetsCreateUrlTemplate,
SubmissionClient.Version, appId), AssetCreateRequest);
Console.WriteLine(AssetCreateResponse.ToString());
Console.WriteLine("Uploading Listing Assets");
// Path to PNG File to be Uploaded as Screenshot / Logo
var PathToFile = "./Image.png";
var AssetToUpload = File.OpenRead(PathToFile);
await client.UploadAsset(AssetCreateResponse.responseData.listingAssets.screenshots[0].primaryAssetUploadUrl.Value as string, AssetToUpload);
Console.WriteLine("Committing Listing Assets");
dynamic AssetCommitRequest = new
{
listingAssets = new
{
language = ListingAssets.responseData.listingAssets[0].language,
storeLogos = ListingAssets.responseData.listingAssets[0].storeLogos,
screenshots = JToken.FromObject(new List<dynamic>() { new
{
id = AssetCreateResponse.responseData.listingAssets.screenshots[0].id.Value as string,
assetUrl = AssetCreateResponse.responseData.listingAssets.screenshots[0].primaryAssetUploadUrl.Value as string
}
}.ToArray())
}
};
dynamic AssetCommitResponse = await client.Invoke<dynamic>(HttpMethod.Put, string.Format(SubmissionClient.ListingAssetsCommitUrlTemplate,
SubmissionClient.Version, appId), AssetCommitRequest);
Console.WriteLine(AssetCommitResponse.ToString());
Console.WriteLine("Getting Current Application Draft Status before Submission");
AppDraftStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.ProductDraftStatusPollingUrlTemplate,
SubmissionClient.Version, appId), null);
Console.WriteLine(AppDraftStatus.ToString());
if (AppDraftStatus == null || !((bool)AppDraftStatus.responseData.isReady))
{
throw new InvalidOperationException("Application Current Status is not in Ready Status for All Modules");
}
Console.WriteLine("Creating Submission");
dynamic SubmissionCreationResponse = await client.Invoke<dynamic>(HttpMethod.Post, string.Format(SubmissionClient.CreateSubmissionUrlTemplate,
SubmissionClient.Version, appId), null);
Console.WriteLine(SubmissionCreationResponse.ToString());
Console.WriteLine("Current Submission Status");
dynamic SubmissionStatus = await client.Invoke<dynamic>(HttpMethod.Get, string.Format(SubmissionClient.SubmissionStatusPollingUrlTemplate,
SubmissionClient.Version, appId, SubmissionCreationResponse.responseData.submissionId.Value as string), null);
Console.Write(SubmissionStatus.ToString());
// User can Poll on this API to know if Submission Status is INPROGRESS, PUBLISHED or FAILED.
// This Process involves File Scanning, App Certification and Publishing and can take more than a day.
}
}
}
Kelas pembantu IngestionClient menggunakan C#
Kelas IngestionClient menyediakan metode pembantu yang digunakan oleh metode lain dalam aplikasi sampel untuk melakukan tugas-tugas berikut:
- Dapatkan token akses Microsoft Azure ACTIVE Directory yang dapat digunakan untuk memanggil metode di API pengiriman Microsoft Store. Setelah mendapatkan token, Anda memiliki waktu 60 menit untuk menggunakan token ini dalam panggilan ke API pengiriman Microsoft Store sebelum token kedaluwarsa. Setelah token kedaluwarsa, Anda dapat menghasilkan token baru.
- Proses permintaan HTTP untuk API pengiriman Microsoft Store.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace Win32SubmissionApiCSharpSample
{
/// <summary>
/// This class is a proxy that abstracts the functionality of the API service
/// </summary>
public class SubmissionClient : IDisposable
{
public static readonly string Version = "1";
private HttpClient httpClient;
private HttpClient imageUploadClient;
private readonly string accessToken;
public static readonly string PackagesUrlTemplate = "/submission/v{0}/product/{1}/packages";
public static readonly string PackageByIdUrlTemplate = "/submission/v{0}/product/{1}/packages/{2}";
public static readonly string PackagesCommitUrlTemplate = "/submission/v{0}/product/{1}/packages/commit";
public static readonly string AppMetadataUrlTemplate = "/submission/v{0}/product/{1}/metadata";
public static readonly string AppListingsFetchMetadataUrlTemplate = "/submission/v{0}/product/{1}/metadata/listings";
public static readonly string ListingAssetsUrlTemplate = "/submission/v{0}/product/{1}/listings/assets";
public static readonly string ListingAssetsCreateUrlTemplate = "/submission/v{0}/product/{1}/listings/assets/create";
public static readonly string ListingAssetsCommitUrlTemplate = "/submission/v{0}/product/{1}/listings/assets/commit";
public static readonly string ProductDraftStatusPollingUrlTemplate = "/submission/v{0}/product/{1}/status";
public static readonly string CreateSubmissionUrlTemplate = "/submission/v{0}/product/{1}/submit";
public static readonly string SubmissionStatusPollingUrlTemplate = "/submission/v{0}/product/{1}/submission/{2}/status";
public const string JsonContentType = "application/json";
public const string PngContentType = "image/png";
public const string BinaryStreamContentType = "application/octet-stream";
/// <summary>
/// Initializes a new instance of the <see cref="SubmissionClient" /> class.
/// </summary>
/// <param name="accessToken">
/// The access token. This is JWT a token obtained from Azure Active Directory allowing the caller to invoke the API
/// on behalf of a user
/// </param>
/// <param name="serviceUrl">The service URL.</param>
public SubmissionClient(string accessToken, string serviceUrl)
{
if (string.IsNullOrEmpty(accessToken))
{
throw new ArgumentNullException("accessToken");
}
if (string.IsNullOrEmpty(serviceUrl))
{
throw new ArgumentNullException("serviceUrl");
}
this.accessToken = accessToken;
this.httpClient = new HttpClient
{
BaseAddress = new Uri(serviceUrl)
};
this.imageUploadClient = new HttpClient();
this.DefaultHeaders = new Dictionary<string, string>();
}
/// <summary>
/// Gets or Sets the default headers.
/// </summary>
public Dictionary<string, string> DefaultHeaders { get; set; }
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting
/// unmanaged resources.
/// </summary>
public void Dispose()
{
if (this.httpClient != null)
{
this.httpClient.Dispose();
this.httpClient = null;
GC.SuppressFinalize(this);
}
}
/// <summary>
/// Gets the authorization token for the provided client id, client secret, and the scope.
/// This token is usually valid for 1 hour, so if your submission takes longer than that to complete,
/// make sure to get a new one periodically.
/// </summary>
/// <param name="tokenEndpoint">Token endpoint to which the request is to be made. Specific to your
/// Azure Active Directory app. Example: https://login.microsoftonline.com/d454d300-128e-2d81-334a-27d9b2baf002/oauth2/v2.0/token </param>
/// <param name="clientId">Client Id of your Azure Active Directory app. Example" 00001111-aaaa-2222-bbbb-3333cccc4444</param>
/// <param name="clientSecret">Client secret of your Azure Active Directory app</param>
/// <param name="scope">Scope. If not provided, default one is used for the production API endpoint.</param>
/// <returns>Autorization token. Prepend it with "Bearer: " and pass it in the request header as the
/// value for "Authorization: " header.</returns>
public static async Task<string> GetClientCredentialAccessToken(
string tokenEndpoint,
string clientId,
string clientSecret,
string scope = null)
{
if (scope == null)
{
scope = "https://api.store.microsoft.com/.default";
}
dynamic result;
using (HttpClient client = new HttpClient())
{
string tokenUrl = tokenEndpoint;
using (
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Post,
tokenUrl))
{
string strContent =
string.Format(
"grant_type=client_credentials&client_id={0}&client_secret={1}&scope={2}",
clientId,
clientSecret,
scope);
request.Content = new StringContent(strContent, Encoding.UTF8,
"application/x-www-form-urlencoded");
using (HttpResponseMessage response = await client.SendAsync(request))
{
string responseContent = await response.Content.ReadAsStringAsync();
result = JsonConvert.DeserializeObject(responseContent);
}
}
}
return result.access_token;
}
/// <summary>
/// Invokes the specified HTTP method.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="httpMethod">The HTTP method.</param>
/// <param name="relativeUrl">The relative URL.</param>
/// <param name="requestContent">Content of the request.</param>
/// <returns>instance of the type T</returns>
/// <exception cref="ServiceException"></exception>
public async Task<T> Invoke<T>(HttpMethod httpMethod,
string relativeUrl,
object requestContent)
{
using (var request = new HttpRequestMessage(httpMethod, relativeUrl))
{
this.SetRequest(request, requestContent);
using (HttpResponseMessage response = await this.httpClient.SendAsync(request))
{
T result;
if (this.TryHandleResponse(response, out result))
{
return result;
}
if (response.IsSuccessStatusCode)
{
var resource = JsonConvert.DeserializeObject<T>(await response.Content.ReadAsStringAsync());
return resource;
}
throw new Exception(await response.Content.ReadAsStringAsync());
}
}
}
/// <summary>
/// Uploads a given Image Asset file to Asset Storage
/// </summary>
/// <param name="assetUploadUrl">Asset Storage Url</param>
/// <param name="fileStream">The Stream instance of file to be uploaded</param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task UploadAsset(string assetUploadUrl, Stream fileStream)
{
using (var request = new HttpRequestMessage(HttpMethod.Put, assetUploadUrl))
{
request.Headers.Add("x-ms-blob-type", "BlockBlob");
request.Content = new StreamContent(fileStream);
request.Content.Headers.ContentType = new MediaTypeHeaderValue(PngContentType);
using (HttpResponseMessage response = await this.imageUploadClient.SendAsync(request))
{
if (response.IsSuccessStatusCode)
{
return;
}
throw new Exception(await response.Content.ReadAsStringAsync());
}
}
}
/// <summary>
/// Sets the request.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="requestContent">Content of the request.</param>
protected virtual void SetRequest(HttpRequestMessage request, object requestContent)
{
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", this.accessToken);
foreach (var header in this.DefaultHeaders)
{
request.Headers.Add(header.Key, header.Value);
}
if (requestContent != null)
{
request.Content = new StringContent(JsonConvert.SerializeObject(requestContent),
Encoding.UTF8,
JsonContentType);
}
}
/// <summary>
/// Tries the handle response.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="response">The response.</param>
/// <param name="result">The result.</param>
/// <returns>true if the response was handled</returns>
protected virtual bool TryHandleResponse<T>(HttpResponseMessage response, out T result)
{
result = default(T);
return false;
}
}
}
sampel Node.js: MICROSOFT Store Submission API untuk aplikasi MSI atau EXE
Artikel ini menyediakan contoh kode Node.js yang menunjukkan cara menggunakan API pengiriman Microsoft Store untuk aplikasi MSI atau EXE. Anda dapat meninjau setiap contoh untuk mempelajari lebih lanjut tentang tugas yang ditunjukkannya, atau Anda dapat membuat semua contoh kode dalam artikel ini ke dalam aplikasi konsol.
Prasyarat Contoh ini menggunakan pustaka berikut:
- Gunakan perintah berikut untuk menginstal versi 2 dari node-fetch: node-fetch v2 [npm install node-fetch@2]
Membuat pengiriman aplikasi menggunakan node.js
Contoh berikut memanggil contoh metode lain dalam artikel ini untuk menunjukkan berbagai cara untuk menggunakan API pengiriman Microsoft Store. Untuk menyesuaikan program ini untuk penggunaan Anda sendiri:
- Tetapkan properti SellerId ke ID Penjual akun Pusat Mitra Anda.
- Tetapkan properti ApplicationId ke ID aplikasi yang ingin Anda kelola.
- Tetapkan properti ClientId dan ClientSecret ke ID klien dan kunci untuk aplikasi Anda, dan ganti string tenantid di URL TokenEndpoint dengan ID penyewa untuk aplikasi Anda. Untuk informasi selengkapnya, lihat Cara mengaitkan aplikasi Microsoft Azure Active Directory dengan akun Pusat Mitra Anda
Contoh berikut mengimplementasikan kelas yang menggunakan beberapa metode di API pengiriman Microsoft Store untuk memperbarui pengiriman aplikasi.
const config = require('./Configuration');
const submissionClient = require('./SubmissionClient');
const fs = require('fs');
var client = new submissionClient(config);
/**
* Main entry method to Run the Store Submission API Node.js Sample
*/
async function RunNodeJsSample(){
print('Getting Access Token');
await client.getAccessToken();
print('Getting Current Application Draft Status');
var currentDraftStatus = await client.callStoreAPI(client.productDraftStatusPollingUrlTemplate, 'get');
print(currentDraftStatus);
print('Getting Application Packages');
var currentPackages = await client.callStoreAPI(client.packagesUrlTemplate, 'get');
print(currentPackages);
print('Getting Single Package');
var packageId = currentPackages.responseData.packages[0].packageId;
var packageIdUrl = `${client.packageByIdUrlTemplate}`.replace('{packageId}', packageId);
var singlePackage = await client.callStoreAPI(packageIdUrl, 'get');
print(singlePackage);
print('Updating Entire Package Set');
// Update data in Packages list to have final set of updated Packages
currentPackages.responseData.packages[0].installerParameters = "/s /r new-args";
var packagesUpdateRequest = {
'packages': currentPackages.responseData.packages
};
print(packagesUpdateRequest);
var packagesUpdateResponse = await client.callStoreAPI(client.packagesUrlTemplate, 'put', packagesUpdateRequest);
print(packagesUpdateResponse);
print('Updating Single Package\'s Download Url');
// Update data in the SinglePackage object
singlePackage.responseData.packages[0].installerParameters = "/s /r /t new-args";
var singlePackageUpdateResponse = await client.callStoreAPI(packageIdUrl, 'patch', singlePackage.responseData.packages[0]);
print(singlePackageUpdateResponse);
print('Committing Packages');
var commitPackagesResponse = await client.callStoreAPI(client.packagesCommitUrlTemplate, 'post');
print(commitPackagesResponse);
await poll(async ()=>{
print('Waiting for Upload to finish');
return await client.callStoreAPI(client.productDraftStatusPollingUrlTemplate, 'get');
}, 2);
print('Getting Application Metadata - All Modules');
var appMetadata = await client.callStoreAPI(client.appMetadataUrlTemplate, 'get');
print(appMetadata);
print('Getting Application Metadata - Listings');
var appListingMetadata = await client.callStoreAPI(client.appListingsFetchMetadataUrlTemplate, 'get');
print(appListingMetadata);
print('Updating Listings Metadata - Description');
// Update Required Fields in Listings Metadata Object - Per Language. For eg. AppListingsMetadata.responseData.listings[0]
// Example - Updating Description
appListingMetadata.responseData.listings[0].description = 'New Description Updated By Node.js Sample Code';
var listingsUpdateRequest = {
'listings': appListingMetadata.responseData.listings[0]
};
var listingsMetadataUpdateResponse = await client.callStoreAPI(client.appMetadataUrlTemplate, 'put', listingsUpdateRequest);
print(listingsMetadataUpdateResponse);
print('Getting All Listings Assets');
var listingAssets = await client.callStoreAPI(client.listingAssetsUrlTemplate, 'get');
print(listingAssets);
print('Creating Listing Assets for 1 Screenshot');
var listingAssetCreateRequest = {
'language': listingAssets.responseData.listingAssets[0].language,
'createAssetRequest': {
'Screenshot': 1,
'Logo': 0
}
};
var listingAssetCreateResponse = await client.callStoreAPI(client.listingAssetsCreateUrlTemplate, 'post', listingAssetCreateRequest);
print(listingAssetCreateResponse);
print('Uploading Listing Assets');
const pathToFile = './Image.png';
const stats = fs.statSync(pathToFile);
const fileSize = stats.size;
const fileStream = fs.createReadStream(pathToFile);
await client.uploadAssets(listingAssetCreateResponse.responseData.listingAssets.screenshots[0].primaryAssetUploadUrl, fileStream, fileSize);
print('Committing Listing Assets');
var assetCommitRequest = {
'listingAssets': {
'language': listingAssets.responseData.listingAssets[0].language,
'storeLogos': listingAssets.responseData.listingAssets[0].storeLogos,
'screenshots': [{
'id': listingAssetCreateResponse.responseData.listingAssets.screenshots[0].id,
'assetUrl': listingAssetCreateResponse.responseData.listingAssets.screenshots[0].primaryAssetUploadUrl
}]
}
};
var assetCommitResponse = await client.callStoreAPI(client.listingAssetsCommitUrlTemplate, 'put', assetCommitRequest);
print(assetCommitResponse);
print('Getting Current Application Draft Status before Submission');
currentDraftStatus = await client.callStoreAPI(client.productDraftStatusPollingUrlTemplate, 'get');
print(currentDraftStatus);
if(!currentDraftStatus.responseData.isReady){
throw new Error('Application Current Status is not in Ready Status for All Modules');
}
print('Creating Submission');
var submissionCreationResponse = await client.callStoreAPI(client.createSubmissionUrlTemplate, 'post');
print(submissionCreationResponse);
print('Current Submission Status');
var submissionStatusUrl = `${client.submissionStatusPollingUrlTemplate}`.replace('{submissionId}', submissionCreationResponse.responseData.submissionId);
var submissionStatusResponse = await client.callStoreAPI(submissionStatusUrl, 'get');
print(submissionStatusResponse);
// User can Poll on this API to know if Submission Status is INPROGRESS, PUBLISHED or FAILED.
// This Process involves File Scanning, App Certification and Publishing and can take more than a day.
}
/**
* Utility Method to Poll using a given function and time interval in seconds
* @param {*} func
* @param {*} intervalInSeconds
* @returns
*/
async function poll(func, intervalInSeconds){
var result = await func();
if(result.responseData.isReady){
Promise.resolve(true);
}
else if(result.errors && result.errors.length > 0 && result.errors.find(element => element.code == 'packageuploaderror') != undefined){
throw new Error('Package Upload Failed');
}
else{
await new Promise(resolve => setTimeout(resolve, intervalInSeconds*1000));
return await poll(func, intervalInSeconds);
}
}
/**
* Utility function to Print a Json or normal string
* @param {*} json
*/
function print(json){
if(typeof(json) == 'string'){
console.log(json);
}
else{
console.log(JSON.stringify(json));
}
console.log("\n");
}
/** Run the Node.js Sample Application */
RunNodeJsSample();
Pembantu ClientConfiguration
Aplikasi sampel menggunakan kelas pembantu ClientConfiguration untuk meneruskan data Azure Active Directory dan data aplikasi ke setiap metode contoh yang menggunakan API pengiriman Microsoft Store.
/** Configuration Object for Store Submission API */
var config = {
version : "1",
applicationId : "...",
clientId : "...",
clientSecret : "...",
serviceEndpoint : "https://api.store.microsoft.com",
tokenEndpoint : "...",
scope : "https://api.store.microsoft.com/.default",
sellerId : "...",
jsonContentType : "application/json",
pngContentType : "image/png",
binaryStreamContentType : "application/octet-stream"
};
module.exports = config;
Pembantu IngestionClient menggunakan node.js
Kelas IngestionClient menyediakan metode pembantu yang digunakan oleh metode lain dalam aplikasi sampel untuk melakukan tugas-tugas berikut:
- Dapatkan token akses Microsoft Azure ACTIVE Directory yang dapat digunakan untuk memanggil metode di API pengiriman Microsoft Store. Setelah mendapatkan token, Anda memiliki waktu 60 menit untuk menggunakan token ini dalam panggilan ke API pengiriman Microsoft Store sebelum token kedaluwarsa. Setelah token kedaluwarsa, Anda dapat menghasilkan token baru.
- Proses permintaan HTTP untuk API pengiriman Microsoft Store.
const fetch = require('node-fetch');
/**
* Submission Client to invoke all available Store Submission API and Asset Upload to Blob Store
*/
class SubmissionClient{
constructor(config){
this.configuration = config;
this.accessToken = "";
this.packagesUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/packages`;
this.packageByIdUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/packages/{packageId}`;
this.packagesCommitUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/packages/commit`;
this.appMetadataUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/metadata`;
this.appListingsFetchMetadataUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/metadata/listings`;
this.listingAssetsUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/listings/assets`;
this.listingAssetsCreateUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/listings/assets/create`;
this.listingAssetsCommitUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/listings/assets/commit`;
this.productDraftStatusPollingUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/status`;
this.createSubmissionUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/submit`;
this.submissionStatusPollingUrlTemplate = `/submission/v${this.configuration.version}/product/${this.configuration.applicationId}/submission/{submissionId}/status`;
}
async getAccessToken(){
var params = new URLSearchParams();
params.append('grant_type','client_credentials');
params.append('client_id',this.configuration.clientId);
params.append('client_secret',this.configuration.clientSecret);
params.append('scope',this.configuration.scope);
var response = await fetch(this.configuration.tokenEndpoint,{
method: "POST",
body: params
});
var data = await response.json();
this.accessToken = data.access_token;
}
async callStoreAPI(url, method, data){
var request = {
method: method,
headers:{
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': this.configuration.jsonContentType,
'X-Seller-Account-Id': this.configuration.sellerId
},
};
if(data){
request.body = JSON.stringify(data);
}
var response = await fetch(`${this.configuration.serviceEndpoint}${url}`,request);
var jsonResponse = await response.json();
return jsonResponse;
}
async uploadAssets(url, stream, size){
var request = {
method: 'put',
headers:{
'Content-Type': this.configuration.pngContentType,
'x-ms-blob-type': 'BlockBlob',
"Content-length": size
},
body: stream
};
var response = await fetch(`${url}`,request);
if(response.ok){
return response;
}
else{
throw new Error('Uploading of assets failed');
}
}
}
module.exports = SubmissionClient;
Bantuan tambahan
Jika Anda memiliki pertanyaan tentang API pengiriman Microsoft Store atau memerlukan bantuan dalam mengelola pengiriman Anda dengan API ini, gunakan sumber daya berikut:
- Ajukan pertanyaan Anda di forum kami.
- Kunjungi halaman dukungan kami dan minta salah satu opsi dukungan yang dibantu untuk Pusat Mitra. Jika Anda diminta untuk memilih jenis dan kategori masalah, pilih Pengiriman dan sertifikasi aplikasi dan Mengirimkan aplikasi.
Windows developer