Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Gebruik de Microsoft Store-inzendings-API voor MSI- of EXE-app om programmatisch query's uit te voeren en verzendingen te maken voor MSI- of EXE-apps voor het Partnercentrum-account van uw organisatie. Deze API is handig als uw account veel apps beheert en u het indieningsproces voor deze assets wilt automatiseren en optimaliseren. Deze API maakt gebruik van Microsoft Entra ID om de aanroepen van uw app of service te verifiëren.
In de volgende stappen wordt het end-to-end-proces beschreven voor het gebruik van de Microsoft Store-inzendings-API:
- Zorg ervoor dat u alle vereisten hebt voltooid.
- Voordat u een methode aanroept in de Microsoft Store-indienings-API, moet u een Microsoft Entra ID-toegangstoken verkrijgen. Nadat u een token hebt verkregen, hebt u 60 minuten de tijd om dit token te gebruiken in aanroepen naar de Microsoft Store-inzendings-API voordat het token verloopt. Nadat het token is verlopen, kunt u een nieuw token genereren.
- Roep de Microsoft Store-indienings-API aan voor MSI- of EXE-app.
Stap 1: Voltooi vereisten voor het gebruik van de Microsoft Store-inzendings-API
Voordat u begint met het schrijven van code voor het aanroepen van de Microsoft Store-inzendings-API voor MSI- of EXE-app, moet u ervoor zorgen dat u aan de volgende vereisten voldoet.
- u (of uw organisatie) moet beschikken over een Microsoft Entra ID-directory en u moet de machtiging Globale beheerder voor die directory hebben. Als u al Microsoft 365 of andere zakelijke diensten van Microsoft gebruikt, hebt u al een Microsoft Entra ID-directory. Anders kunt u zonder extra kosten een nieuwe Microsoft Entra-id maken in het Partnercentrum .
- U moet een Microsoft Entra ID-toepassing koppelen aan uw Partnercentrum-account en uw tenant-id, client-id en -sleutel verkrijgen. U hebt deze waarden nodig om een Microsoft Entra ID-toegangstoken te verkrijgen, dat u gaat gebruiken in aanroepen naar de Microsoft Store-inzendings-API.
- Bereid uw app voor op gebruik met de Microsoft Store-inzendings-API:
- Als uw app nog niet bestaat in Partnercentrum, moet u uw app aanmaken door de naam te reserveren in Partnercentrum. U kunt de Microsoft Store-inzendings-API niet gebruiken om een app te maken in partnercentrum; u moet in partnercentrum werken om het te maken en daarna kunt u de API gebruiken om toegang te krijgen tot de app en programmatisch indieningen voor de app te maken.
- Voordat u een inzending voor een bepaalde app kunt maken met behulp van deze API, moet u eerst één inzending maken voor de app in partnercentrum, inclusief het beantwoorden van de vragenlijst voor leeftijdsclassificaties . Nadat u dit hebt uitgevoerd, kunt u programmatisch nieuwe inzendingen voor deze app maken met behulp van de API.
- Als u een app-inzending maakt of bijwerkt en u een nieuw pakket moet opnemen, de pakketdetails voorbereiden.
- Als u een app-inzending maakt of bijwerkt en u schermafbeeldingen of afbeeldingen voor de Store-vermelding moet opnemen, de app-schermafbeeldingen en -afbeeldingenvoorbereiden.
Een Microsoft Entra ID-toepassing koppelen aan uw Partnercentrum-account
Voordat u de Microsoft Store-indienings-API voor MSI- of EXE-app kunt gebruiken, moet u een Microsoft Entra-id-toepassing koppelen aan uw Partnercentrum-account, de tenant-id en client-id voor de toepassing ophalen en een sleutel genereren. De Microsoft Entra ID-toepassing vertegenwoordigt de app of service waaruit u de Microsoft Store-inzendings-API wilt aanroepen. U hebt de tenant-id, client-id en -sleutel nodig om een Microsoft Entra ID-toegangstoken te verkrijgen dat u doorgeeft aan de API.
Opmerking
U hoeft deze taak slechts één keer uit te voeren. Nadat u de tenant-id, client-id en -sleutel hebt, kunt u deze telkens opnieuw gebruiken wanneer u een nieuw Microsoft Entra ID-toegangstoken moet maken.
- Koppel in Partnercentrum het Partnercentrum-account van uw organisatie aan de Microsoft Entra ID-adreslijst van uw organisatie.
- Voeg vervolgens op de pagina Gebruikers in het gedeelte Accountinstellingen van partnercentrum de Microsoft Entra-id-toepassing toe die de app of service vertegenwoordigt die u gebruikt voor toegang tot inzendingen voor uw PartnerCentrum-account. Zorg ervoor dat u deze toepassing de rol Manager toewijst. Als de toepassing nog niet bestaat in uw Microsoft Entra ID-map, kunt u een nieuwe Microsoft Entra ID-toepassing maken in Partnercentrum.
- Ga terug naar de pagina Gebruikers, klik op de naam van uw Microsoft Entra ID-toepassing om naar de toepassingsinstellingen te gaan en kopieer de waarden voor tenant-id en client-id.
- Als u een nieuwe sleutel of clientgeheim wilt toevoegen, raadpleegt u de volgende instructies of raadpleegt u de instructies voor het registreren van de app via Azure Portal:
Ga als volgende te werk om uw app te registreren:
Meld u aan bij het Azure-portaal.
Als u toegang hebt tot meerdere tenants, gebruikt u het filter Mappen en abonnementen in het bovenste menu om over te schakelen naar de tenant waarin u de toepassing wilt registreren.
Zoek en selecteer Microsoft Entra ID Directory.
Selecteer onder Beheren de app-registraties > Selecteer uw toepassing.
Selecteer Certificaten en geheimen Clientgeheimen >> Nieuw clientgeheim.
Voeg een beschrijving voor uw clientgeheim toe.
Selecteer een vervaldatum voor het geheim of geef een aangepaste levensduur op.
De levensduur van het clientgeheim is beperkt tot twee jaar (24 maanden) of minder. U kunt geen aangepaste levensduur opgeven die langer is dan 24 maanden.
Opmerking
Microsoft raadt u aan een verloopwaarde van minder dan 12 maanden in te stellen.
Selecteer Toevoegen.
Registreer de waarde van het geheim voor gebruik in de toepassingscode van uw client. Deze geheimwaarde wordt nooit meer weergegeven nadat u deze pagina hebt verlaten.
Stap 2: een Microsoft Entra ID-toegangstoken verkrijgen
Voordat u een van de methoden aanroept in de Microsoft Store-indienings-API voor MSI- of EXE-app, moet u eerst een Microsoft Entra ID-toegangstoken verkrijgen dat u doorgeeft aan de autorisatieheader van elke methode in de API. Nadat u een toegangstoken hebt verkregen, hebt u 60 minuten om het te gebruiken voordat het verloopt. Nadat het token is verlopen, kunt u het token vernieuwen, zodat u het kunt blijven gebruiken in verdere aanroepen naar de API.
Om het toegangstoken te verkrijgen, volgt u de instructies in Service-naar-service-aanroepen met clientreferenties om een HTTP POST-verzoek te verzenden naar het https://login.microsoftonline.com/<tenant_id>/oauth2/token-eindpunt. Hier volgt een voorbeeldaanvraag.
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
Geef voor de tenant_id waarde in de POST-URI en de client_id en client_secret parameters de tenant-id, client-id en de sleutel op voor uw toepassing die u in de vorige sectie hebt opgehaald uit Partner Center. Voor de bereikparameter moet u opgeven https://api.store.microsoft.com/.default.
Nadat uw toegangstoken is verlopen, kunt u het vernieuwen door de instructies hier te volgen.
Voor voorbeelden die laten zien hoe u een toegangstoken kunt verkrijgen met behulp van C# of Node.js, raadpleegt u de codevoorbeelden voor de Microsoft Store-indienings-API voor MSI- of EXE-app.
Stap 3: de Microsoft Store-indienings-API gebruiken
Nadat u een Toegangstoken voor Microsoft Entra ID hebt, kunt u methoden aanroepen in de Microsoft Store-indienings-API voor MSI- of EXE-app. De API bevat veel methoden die zijn gegroepeerd in scenario's voor apps. Als u verzendingen wilt maken of bijwerken, roept u doorgaans meerdere methoden in een specifieke volgorde aan. Zie de volgende secties voor informatie over elk scenario en de syntaxis van elke methode:
Opmerking
Nadat u een toegangstoken hebt verkregen, hebt u 60 minuten de tijd om methoden aan te roepen in de Microsoft Store-indienings-API voor MSI- of EXE-app voordat het token verloopt.
Basis-URL
De basis-URL voor de Microsoft Store-indienings-API voor exe- of MSI-app is: https://api.store.microsoft.com
API-contracten
API voor het ophalen van metagegevens van de huidige conceptindiening
Haalt metagegevens op in elke module (vermeldingen, eigenschappen of beschikbaarheid) onder de huidige conceptinzending.
Pad [Alle modules]: /submission/v1/product/{productId}/metadata?languages={languages}&includelanguagelist={true/false}
Pad [enkele module]: /submission/v1/product/{productId}/metadata/{moduleName}?languages={languages}&includelanguagelist={true/false}
Methode : GET
padparameters
| Kenmerk | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
| modulenaam | Partnercentrummodule: vermeldingen, eigenschappen of beschikbaarheid |
Query-parameters
| Kenmerk | Beschrijving |
|---|---|
| Talen |
Facultatief De lijst met talen wordt gefilterd als door komma's gescheiden tekenreeks [limiet van maximaal 200 talen]. Als u afwezig bent, worden de eerste 200 beschikbare metagegevens van talen opgehaald. [ bijvoorbeeld "en-us, en-gb"]. |
| taallijst opnemen | Optionele Booleaanse waarde - als waar is, retourneert de lijst met toegevoegde vermeldingstalen en hun volledigheidsstatus. |
vereiste headers
| Koptekst | Waarde |
|---|---|
Authorization: Bearer <Token> |
De app-ID van Microsoft Entra ID die is geregistreerd voor het Partner Center-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Antwoordheaders
| Koptekst | Waarde |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| ondersteuning voor toegankelijkheid | Booleaan | |
| aanvullende licentievoorwaarden | Snaar / Touwtje | |
| beschikbaarheid | Voorwerp | Beschikbaarheidsmodulegegevens |
| categorie | Snaar / Touwtje | Zie de lijst met categorieën hieronder |
| certificationNotes | Snaar / Touwtje | |
| code | Snaar / Touwtje | De foutcode van het bericht |
| contactgegevens | Snaar / Touwtje | |
| auteursrecht | Snaar / Touwtje | |
| afhankelijkVanBestuurdersOfNT | Booleaan | |
| beschrijving | Snaar / Touwtje | |
| ontwikkeld door | Snaar / Touwtje | |
| vindbaarheid | Snaar / Touwtje | [VINDBAAR, DEEPLINK_ONLY] |
| inschakelen in toekomstige markten | Booleaan | |
| Fouten | Matrix van objecten | De lijst met foutberichten of waarschuwingsberichten, indien van toepassing |
| freeTrial | Snaar / Touwtje | [GEEN_GRATIS_PROEFVERSIE, GRATIS_PROEFVERSIE] |
| hardwareartikeltype | Snaar / Touwtje | |
| isPrivacyPolicyVereist | Booleaan | |
| isAanbevolen | Booleaan | |
| isVerplicht | Booleaan | |
| isSuccesvol | Booleaan | |
| isSysteemfunctieVereist | Matrix van objecten | |
| Taal | Snaar / Touwtje | Zie de onderstaande lijst met talen |
| Lijstingen | Matrix van objecten | Bevat modulegegevens voor elke taal |
| Markten | Array van tekenreeksen | Zie de lijst met markten hieronder |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| minimale hardwarevereisten | Snaar / Touwtje | |
| minimumvereiste | Snaar / Touwtje | |
| ondersteuning voor pen en inkt | Booleaan | |
| Prijzen | Snaar / Touwtje | [GRATIS, FREEMIUM, ABONNEMENT, BETAALD] |
| privacybeleidUrl | Snaar / Touwtje | |
| productverklaringen | Voorwerp | |
| productkenmerken | Array van tekenreeksen | |
| eigenschappen | Voorwerp | Modulegegevens voor eigenschappen |
| aanbevolen hardware | Snaar / Touwtje | |
| aanbevolen vereiste | Snaar / Touwtje | |
| responsGegevens | Voorwerp | Bevat de daadwerkelijke payload van de respons voor het verzoek |
| Eisen | Matrix van objecten | |
| zoektermen | Array van tekenreeksen | |
| korteBeschrijving | Snaar / Touwtje | |
| Subcategorie | Snaar / Touwtje | Zie de lijst met subcategorieën hieronder |
| ondersteuningscontactinformatie | Snaar / Touwtje | |
| systeemvereistenDetails | Matrix van objecten | |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| webpagina | Snaar / Touwtje | |
| watIsNieuw | Snaar / Touwtje |
Huidige metagegevens-API voor indiening bijwerken
Hiermee worden metagegevens in elke module bijgewerkt onder conceptinzending. De API-controles
- Voor actieve inzending. Indien aanwezig, mislukt met foutbericht.
- Als alle modules de gereed status hebben om de Concept opslaan-bewerking toe te staan.
- Elk veld in de inzending wordt gevalideerd volgens de vereisten van de Store
- Validatieregels voor systeemvereistedetails:
- Toegestane waarden in hardwareItemType = Geheugen: 300 MB, 750 MB, 1 GB, 2 GB, 4 GB, 6 GB, 8 GB, 12 GB, 16 GB, 20 GB
- Toegestane waarden in hardwareItemType = DirectX: DX9, DX10, DX11, DX12-FEATURELEVEL11, DX12-FEATURELEVEL12
- Toegestane waarden in hardwareItemType = Video_Memory: 1 GB, 2 GB, 4 GB, 6 GB
pad [Volledige module-update]: /submission/v1/product/{productId}/metadata
Methode : PUT
pad [modulepatchupdate]: /submission/v1/product/{productId}/metadata
methode: PATCH
API-gedrag
In het geval van de API voor volledige module-updates: volledige modulegegevens moeten aanwezig zijn in Aanvraag voor volledige update van elk veld. Elk veld dat niet aanwezig is in Aanvraag, wordt de standaardwaarde gebruikt om de huidige waarde voor die specifieke module te overschrijven.
In het geval van de Patch Module Update-API hoeven in het verzoek alleen velden te worden opgenomen die moeten worden bijgewerkt. Deze veldwaarden uit Aanvraag overschrijven hun bestaande waarden, waarbij alle andere velden die niet aanwezig zijn in de aanvraag, hetzelfde als de huidige voor die specifieke module behouden blijven.
padparameters
| Kenmerk | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
vereiste headers
| Koptekst | Waarde |
|---|---|
Authorization: Bearer <Token> |
De Microsoft Entra ID-app-ID die is geregistreerd bij het Partner Center-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Verzoekparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| beschikbaarheid | Voorwerp | Object voor het opslaan van metagegevens van de beschikbaarheidsmodule |
| Markten | Array van tekenreeksen | Vereist Zie de lijst met markten hieronder |
| vindbaarheid | Snaar / Touwtje | Vereist [VINDBAAR, DEEPLINK_ONLY] |
| inschakelen in toekomstige markten | Booleaan | Vereist |
| Prijzen | Snaar / Touwtje | Vereist [GRATIS, FREEMIUM, ABONNEMENT, BETAALD] |
| freeTrial | Snaar / Touwtje | Vereist als de prijzen BETAALD of ABONNEMENT zijn [NO_FREE_TRIAL, FREE_TRIAL] |
| eigenschappen | Voorwerp | Object voor het opslaan van metagegevens van eigenschappenmodule |
| isPrivacyPolicyVereist | Booleaan | Vereist |
| privacybeleidUrl | Snaar / Touwtje | Vereist als isPrivacyPolicyRequired = true Moet een geldige URL zijn |
| webpagina | Snaar / Touwtje | Moet een geldige URL zijn |
| ondersteuningscontactinformatie | Snaar / Touwtje | Moet een geldige URL of e-mailadres zijn |
| certificationNotes | Snaar / Touwtje | Aanbevolen Tekenlimiet = 2000 |
| categorie | Snaar / Touwtje | Vereist Zie de lijst met categorieën hieronder |
| Subcategorie | Snaar / Touwtje | Vereist Zie de lijst met subcategorieën hieronder |
| productverklaringen | Voorwerp | Vereist |
| isSysteemfunctieVereist | Matrix van objecten | [Aanraken, Toetsenbord, Muis, Camera, NFC_HCE, NFC_Proximity, Bluetooth_LE, Telefonie, Microfoon] |
| isVerplicht | Booleaan | Vereist |
| isAanbevolen | Booleaan | Vereist |
| hardwareartikeltype | Snaar / Touwtje | Vereist |
| systeemvereistenDetails | Matrix van objecten | [Processor, Graphics, Memory, DirectX, Videogeheugen] |
| minimumvereiste | Snaar / Touwtje |
Vereist Voor systemRequirementsText, MaxLength = 200 Toegestane waarden in hardwareItemType = Geheugen: [300 MB, 750 MB, 1 GB, 2 GB, 4 GB, 6 GB, 8 GB, 12 GB, 16 GB, 20 GB] Toegestane waarden in hardwareItemType = DirectX: [DX9, DX10, DX11, DX12-FEATURELEVEL11, DX12-FEATURELEVEL12] Toegestane waarden in hardwareItemType = Video_Memory: [1 GB, 2 GB, 4 GB, 6 GB] |
| aanbevolen vereiste | Snaar / Touwtje |
Vereist Voor systemRequirementsText, MaxLength = 200 Toegestane waarden in hardwareItemType = Geheugen: [300 MB, 750 MB, 1 GB, 2 GB, 4 GB, 6 GB, 8 GB, 12 GB, 16 GB, 20 GB] Toegestane waarden in hardwareItemType = DirectX: [DX9, DX10, DX11, DX12-FEATURELEVEL11, DX12-FEATURELEVEL12] Toegestane waarden in hardwareItemType = Video_Memory: [1 GB, 2 GB, 4 GB, 6 GB] |
| afhankelijkVanBestuurdersOfNT | Booleaan | Vereist |
| ondersteuning voor toegankelijkheid | Booleaan | Vereist |
| ondersteuning voor pen en inkt | Booleaan | Vereist |
| Lijstingen | Voorwerp | Object voor het weergeven van modulegegevens voor één taal |
| Taal | Snaar / Touwtje | Vereist Zie de onderstaande lijst met talen |
| beschrijving | Snaar / Touwtje | Vereist tekenlimiet = 10000 |
| watIsNieuw | Snaar / Touwtje | Tekenlimiet = 1500 |
| productkenmerken | Array van tekenreeksen | 200 tekens per functie; Maximaal 20 functies |
| korteBeschrijving | Snaar / Touwtje | Tekenlimiet = 1000 |
| zoektermen | Array van tekenreeksen | 30 tekens per zoekterm; Maximaal 7 zoektermen 21 unieke woorden TOTAAL voor alle zoektermen |
| aanvullende licentievoorwaarden | Snaar / Touwtje | Vereist tekenlimiet = 10000 |
| auteursrecht | Snaar / Touwtje | Tekenlimiet = 200 |
| ontwikkeld door | Snaar / Touwtje | Tekenlimiet = 255 |
| Eisen | Matrix van objecten | 200 tekens per item; Maximaal 11 items TOTAAL tussen minimum en aanbevolen] |
| minimale hardwarevereisten | Snaar / Touwtje | Tekenlimiet = 200 |
| aanbevolen hardware | Snaar / Touwtje | Tekenlimiet = 200 |
| contactgegevens | Snaar / Touwtje | Tekenlimiet = 200 |
| vermeldingenToevoegen | Array van tekenreeksen | Zie de onderstaande lijst met talen |
| vermeldingen om te verwijderen | Array van tekenreeksen | Zie de onderstaande lijst met talen |
Markten
Tabel weergeven
| Markt | Afkorting | |--------|--------------| | Afghanistan | AF | | Albanië | AL | | Algerije | DZ | | Amerikaans-Samoa | AS | | Andorra | AD | | Angola | AO | | Anguilla | AI | | Antarctica | AQ | | Antigua en Barbuda | AG | | Argentinië | AR | | Armenië | AM | | Aruba | AW | | Australië | AU | | Oostenrijk | AT | | Azerbeidzjan | AZ | | Bahama's | BS | | Bahrein | BH | | Bangladesh | BD | | Barbados | BB | | Belarus | BY | | België | BE | | Belize | BZ | | Benin | BJ | | Bermuda | BM | | Bhutan | BT | | Bolivariaanse Republiek Venezuela | VE | | Bolivia | BO | | Bonaire | BQ | | Bosnië en Herzegovina | BA | | Botswana | BW | | Bouveteiland | BV | | Brazilië | BR | | Brits Indische Oceaanterritorium | IO | | Britse Maagdeneilanden | VG | | Brunei | BN | | Bulgarije | BG | | Burkina Faso | BF | | Burundi | BI | | Cambodja | KH | | Kameroen | CM | | Canada | CA | | Cabo Verde | CV | | Kaaimaneilanden | KY | | Centraal-Afrikaanse Republiek | CF | | Tsjaad | TD | | Chili | CL | | China | CN | | Kersteiland | CX | | Cocoseilanden (Keelingeilanden) | CC | | Colombia | CO | | Comoren | KM | | Congo | CG | | Congo (DRC) | CD | | Cookeilanden | CK | | Costa Rica | CR | | Kroatië | HR | | Curaçao | CW | | Cyprus | CY | | Tsjechische Republiek | CZ | | Côte d'Ivoire | CI | | Denemarken | DK | | Djibouti | DJ | | Dominica | DM | | Dominicaanse Republiek | DO | | Ecuador | EC | | Egypte | EG | | El Salvador | SV | | Equatoriaal-Guinea | GQ | | Eritrea | ER | | Estland | EE | | Ethiopië | ET | | Falklandeilanden | FK | | Faeröer | FO | | Fiji | FJ | | Finland | FI | | Frankrijk | FR | | Frans-Guyana | GF | | Frans-Polynesië | PF | | Franse Zuidelijke en Antarctische Gebieden | TF | | Gabon | GA | | Gambia | GM | | Georgië | GE | | Duitsland | DE | | Ghana | GH | | Gibraltar | GI | | Griekenland | GR | | Groenland | GL | | Grenada | GD | | Guadeloupe | GP | | Guam | GU | | Guatemala | GT | | Guernsey | GG | | Guinea | GN | | Guinee-Bissau | GW | | Guyana | GY | | Haïti | HT | | Heardeiland en McDonaldeilanden | HM | | Vaticaanstad | VA | | Honduras | HN | | Hongkong SAR | HK | | Hongarije | HU | | IJsland | IS | | India | IN | | Indonesië | ID | | Irak | IQ | | Ierland | IE | | Israël | IL | | Italië | IT | | Jamaica | JM | | Japan | JP | | Jersey | JE | | Jordanië | JO | | Kazachstan | KZ | | Kenia | KE | | Kiribati | KI | | Korea | KR | | Koeweit | KW | | Kirgizië | KG | | Laos | LA | | Letland | LV | | Libanon | LB | | Lesotho | LS | | Liberia | LR | | Libië | LY | | Liechtenstein | LI | | Litouwen | LT | | Luxemburg | LU | | Macao SAR | MO | | Noord-Macedonië | MK | | Madagaskar | MG | | Malawi | MW | | Maleisië | MY | | Malediven | MV | | Mali | ML | | Malta | MT | | Man | IM | | Marshalleilanden | MH | | Martinique | MQ | | Mauritanië | MR | | Mauritius | MU | | Mayotte | YT | | Mexico | MX | | Micronesië | FM | | Moldavië | MD | | Monaco | MC | | Mongolië | MN | | Montenegr - ME | | Montserrat | MS | | Marokko | MA | | Mozambique | MZ | | Myanmar | MM | | Namibië | NA | | Nauru | NR | | Nepal | NP | | Nederland | NL | | Nieuw-Caledonië | NC | | Nieuw-Zeeland | NZ | | Nicaragua | NI | | Niger | NE | | Nigeria | NG | | Niue | NU | | Norfolkeiland | NF | | Noordelijke Marianen | MP | | Noorwegen | NO | | Oman | OM | | Pakistan | PK | | Palau | PW | | Palestijnse Autoriteit | PS | | Panama | PA | | Papoea-Nieuw-Guinea | PG | | Paraguay | PY | | Peru | PE | | Filipijnen | PH | | Pitcairneilanden | PN | | Polen | PL | | Portugal | PT | | Qatar | QA | | Réunion | RE | | Roemenië | RO | | Rusland | RU | | Rwanda | RW | | Saint-Barthélemy | BL | | Sint-Helena, Ascension en Tristan da Cunha | SH | | Saint Kitts en Nevis | KN | | Saint Lucia | LC | | Saint Martin (Franse deel) | MF | | Saint Pierre en Miquelon | PM | | Saint Vincent en de Grenadines | VC | | Samoa | WS | | San Marino | SM | | Saoedi-Arabië | SA | | Senegal | SN | | Servië | RS | | Seychellen | SC | | Sierra Leone | SL | | Singapore | SG | | Sint Maarten (Nederlands deel) | SX | | Slowakije | SK | | Slovenië | SI | | Salomonseilanden | SB | | Somalië | SO | | Zuid-Afrika | ZA | | Zuid-Georgia en de Zuidelijke Sandwicheilanden | GS | | Spanje | ES | | Sri Lanka | LK | | Suriname | SR | | Spitsbergen en Jan Mayen | SJ | | Swaziland | SZ | | Zweden | SE | | Zwitserland | CH | | São Tomé en Príncipe | ST | | Taiwan | TW | | Tadzjikistan | TJ | | Tanzania | TZ | | Thailand | TH | | Timor-Leste | TL | | Tog - TG | | Tokelau | TK | | Tonga | TO | | Trinidad and Tobag - TT | | Tunesië | TN | | Turkije | TR | | Turkmenistan | TM | | Turks- en Caicoseilanden | TC | | Tuvalu | TV | | Kleine afgelegen eilanden van de VS | UM | | Amerikaanse Maagdeneilanden | VI | | Oeganda | UG | | Oekraïne | UA | | Verenigde Arabische Emiraten | AE | | Verenigd Koninkrijk | GB | | Verenigde Staten | US | | Uruguay | UY | | Oezbekistan | UZ | | Vanuatu | VU | | Vietnam | VN | | Wallis en Futuna | WF | | Jemen | YE | | Zambia | ZM | | Zimbabwe | ZW | | Ålandeilanden | AX |categorieën en subcategorieën
Tabel weergeven
| Categorie | Subcategorieën | |-----------------------|---------------| | Boeken en naslagwerken | E-reader, Fictie, Non-fictie, Naslagwerken | | Zakelijk | Boekhouding en financiën, Samenwerking, CRM, Gegevens en analyses, Bestandsbeheer, Voorraad en logistiek, Juridische zaken en HR, Projectbeheer, Extern bureaublad, Verkoop en marketing, Tijd en uitgaven | | Ontwikkelaarstools | Database, Ontwerptools, Ontwikkelkits, Netwerk, Naslagwerken en training, Servers, Hulpprogramma's, Webhosting | | Onderwijs | Onderwijsboeken en naslagwerken, Vroeg leren, Instructietools, Taal, Studiemiddelen | | Entertainment | (Geen) | | Eten en drinken | (Geen) | | Overheid en politiek | (Geen) | | Gezondheid en fitness | (Geen) | | Kinderen en gezin | Boeken en naslagwerken voor kinderen en gezinnen, Entertainment voor kinderen en gezinnen, Hobby's en speelgoed, Sport en activiteiten, Reizen voor kinderen en gezinnen | | Lifestyle | Auto's, Doe-het-zelf, Huis en tuin, Relaties, Speciale interesses, Stijl en mode | | Medisch | (Geen) | | Multimediaontwerp | Illustratie en grafisch ontwerp, Muziekproductie, Foto- en videoproductie | | Muziek | (Geen) | | Navigatie en kaarten | (Geen) | | Nieuws en weer | Nieuws, Weer | | Persoonlijke financiën | Bankieren en investeringen, Budgettering en belastingen | | Personalisatie | Beltonen en geluiden, Thema's, Achtergronden en vergrendelschermen | | Foto en video | (Geen) | | Productiviteit | (Geen) | | Beveiliging | PC-beveiliging, Persoonlijke beveiliging | | Winkelen | (Geen) | | Sociaal | (Geen) | | Sporten | (Geen) | | Reizen | Stadsgidsen, Hotels | | Hulpprogramma's en tools | Back-up en beheren, Bestandsbeheer |Talen
Tabel weergeven
| Taalnaam | Ondersteunde taalcodes | |---------------|--------------------------| | Afrikaans | af, af-za | | Albanese | sq, sq-al | | Amharisch | am, am-et | | Armeens | hy, hy-am | | Assamese | as-in | | Azerbeidzjaans | az-arab, az-arab-az, az-cyrl, az-cyrl-az, az-latn, az-latn-az | Baskisch (Baskisch) | eu, eu-es | | Wit-Rusland | be, be-by | | Bangla | bn, bn-bd, bn-in | Bosnisch | bs, bs-cyrl, bs-cyrl-ba, bs-latn, bs-latn-ba | Bulgaars | bg, bg-bg | | Catalaans | ca, ca-es, ca-es-valencia | | Cherokee | chr-cher, chr-cher-us, chr-latn | | Chinees (vereenvoudigd) | zh-Hans, zh-cn, zh-hans-cn, zh-sg, zh-hans-sg | | Chinees (traditioneel) | 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 | | Kroatisch | hr, hr-hr, hr-ba | Tsjechisch | cs, cs-cz | | Deens | da, da-dk | | Dari | prs, prs-af, prs-arab | | Nederlands | nl, nl-nl, nl-be | Engels | 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 | | Ests | et, et-ee | | Filipin - fil, fil-latn, fil-ph | Fins | fi, fi-fi | | Frans | 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 | | Galicisch | gl, gl-es | Georgisch | ka, ka-ge | | Duits | de, de-at, de-ch, de-de, de-lu, de-li | Grieks | el, el-gr | | Gujarati | gu, gu-in | | Hausa | ha, ha-latn, ha-latn-ng | | Hebreeuws | hij, he-il | Hindi | hallo, hi-in | Hongaars | hu, hu-hu | | IJslands | is, is-is | | Igb - ig-latn, ig-ng | Indonesisch | id, id-id | | Inuktitut (Latijns) | iu-cans, iu-latn, iu-latn-ca | | Iers | ga, ga-ie | | isiXhosa | xh, xh-za | | isiZulu | zu, zu-za | | Italiaans | it-it, it-ch | Japans | ja , ja-jp | | Kannada | kn, kn-in | | Kazachs | 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 | | Koreaans | ko, ko-kr | | Turks | ku-arab, ku-arab-iq | Kirgizisch | ky-kg, ky-cyrl | | Lao | lo, lo-la | | Lets | lv, lv-lv | | Litouws | lt, lt-lt | | Luxemburgs | lb, lb-lu | | Macedonisch | mk, mk-mk | | Maleis | ms, ms-bn, ms-my | Malayalam | ml, ml-in | | Maltees | mt, mt-mt | | Maori | mi, mi-latn, mi-nz | Marathi | mr, mr-in | | Mongools (Cyrillisch) | mn-cyrl, mn-mong, mn-mn, mn-phag | | Nepalee | ne, ne-np | Noors | nb, nb-no, nn, nn-no, nee, no-no | | Odia | of, or-in | | Perzisch | fa, fa-ir | | Pools | pl, pl-pl | | Portugees (Brazilië) | pt-br | | Portugees (Portugal) | pt, pt-pt | | Punjabi | pa, pa-arab, pa-arab-pk, pa-deva, pa-in | Quechua | quz, quz-bo, quz-ec, quz-pe | Roemeens | ro, ro-ro | | Russisch | ru , ru-ru | | Schotse Gaelic | gd-gb, gd-latn | | Servisch (Latijns) | sr-Latn, sr-latn-cs, sr, sr-latn-ba, sr-latn-me, sr-latn-rs | Servisch (Cyrillisch) | 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 | | Slowaaks | sk, sk-sk | | Sloveens | sl, sl-si | Spaans | 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 | Zweeds | sv, sv-se, sv-fi | Tadzjiik (Cyrillisch) | tg-arab, tg-cyrl, tg-cyrl-tj, tg-latn | Tamil | ta, ta-in | | Tatar | tt-arab, tt-cyrl, tt-latn, tt-ru | | Telugu | te, te-in | | Thais | th, th-th | | Tigrinya | ti, ti-et | | Turks | tr, tr-tr | | Turkmen | tk-cyrl, tk-latn, tk-tm, tk-latn-tr, tk-cyrl-tr | | Oekraïens | uk, uk-ua | | Urdu | uw, ur-pk | | Uyghur | ug-arab, ug-cn, ug-cyrl, ug-latn | | Oezbeeks (Latijns) | uz, uz-cyrl, uz-latn, uz-latn-uz | | Vietnamees | vi, vi-vn | | Welsh | cy, cy-gb | | Wolof | wo, wo-sn | | Yoruba | yo-latn, yo-ng |Voorbeeldaanvraag
{
"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"]
}
Antwoordheaders
| Koptekst | Waarde |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | De lijst met foutberichten of waarschuwingsberichten, indien van toepassing |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| responsGegevens | Voorwerp | Bevat de daadwerkelijke payload van de respons voor het verzoek |
| pollingUrl | Snaar / Touwtje | Polling-URL om de status van een In-Progress Inzending op te halen |
| lopendeInzendingId | Snaar / Touwtje | Inzendings-id van elke reeds bestaande In-Progress inzending |
Voorbeeldantwoord
{
"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": ""
}
}
Huidige conceptpakketten ophalen via de API
Haalt pakketdetails op in de huidige conceptinzending.
Pad [Alle pakketten]: /submission/v1/product/{productId}/packages
Methode : GET
Path [enkelvoudig pakket]: /submission/v1/product/{productId}/packages/{packageId}
Methode : GET
padparameters
| Naam | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
| pakket-ID | De unieke id van het pakket dat moet worden opgehaald |
vereiste headers
| Koptekst | Waarde |
|---|---|
Authorization: Bearer <Token> |
De app-id van Microsoft Entra gebruiken die is geregistreerd bij het Partnercentrum-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Antwoordheaders
| Koptekst | Waarde |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | De lijst met fouten of waarschuwingsberichten, indien van toepassing |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| responsGegevens | Voorwerp | |
| Pakketten | Matrix van objecten | Object voor het opslaan van pakketmodulegegevens |
| pakket-ID | Snaar / Touwtje | |
| pakketUrl | Snaar / Touwtje | |
| Talen | Array van tekenreeksen | |
| Architecturen | Array van tekenreeksen | [Neutraal, X86, X64, Arm, Arm64] |
| isSilentInstall | Booleaan | Dit moet als waar worden gemarkeerd als uw installatieprogramma wordt uitgevoerd in de stille modus zonder schakelopties of anders onwaar |
| installerParameters | Snaar / Touwtje | |
| genericDocUrl | Snaar / Touwtje | |
| foutdetails | Matrix van objecten | |
| foutscenario | Snaar / Touwtje | |
| errorScenarioDetails | Matrix van objecten | |
| foutwaarde | Snaar / Touwtje | |
| foutUrl | Snaar / Touwtje | |
| pakkettype | Snaar / Touwtje |
voorbeeldantwoord
{
"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",
}]
}
}
Huidige api voor conceptpakketten bijwerken
Hiermee worden pakketdetails bijgewerkt onder de huidige conceptinzending.
pad [Volledige module-update]: /submission/v1/product/{productId}/packages
Methode : PUT
Pad [Bijwerken van enkele pakketten]: /submission/v1/product/{productId}/packages/{packageId}
methode: PATCH
API-gedrag
In het geval van de API voor volledige module-updates: volledige pakketgegevens moeten aanwezig zijn in aanvraag voor volledige update van elk veld. Elk veld dat niet aanwezig is in de aanvraag, wordt de standaardwaarde gebruikt om de huidige waarde voor die specifieke module te overschrijven. Dit resulteert in het overschrijven van alle bestaande pakketten met een nieuwe set pakketten uit het verzoek. Dit resulteert in het opnieuw genereren van pakket-id's en de gebruiker moet GET Packages-API aanroepen voor de nieuwste pakket-id's.
In het geval van API voor update van één pakket: alleen velden die moeten worden bijgewerkt voor een bepaald pakket, moeten aanwezig zijn in de aanvraag. Deze veldwaarden van de aanvraag overschrijven hun bestaande waarden, waarbij alle andere velden die niet aanwezig zijn in de aanvraag, hetzelfde als actueel voor dat specifieke pakket worden overschreven. Andere pakketten in de set blijven ongewijzigd.
padparameters
| Naam | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
| pakket-ID | De unieke id van het pakket |
vereiste headers
| Koptekst | Waarde |
|---|---|
Authorization: Bearer <Token> |
De app-id van Microsoft Entra gebruiken die is geregistreerd bij het Partnercentrum-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Verzoekparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| Pakketten | Matrix van objecten | Object voor het opslaan van pakketmodulegegevens [alleen vereist voor volledige module-update] |
| pakketUrl | Snaar / Touwtje | Vereist |
| Talen | Array van tekenreeksen | Vereist |
| Architecturen | Array van tekenreeksen | Vereist Moet één architectuur bevatten: Neutraal, X86, X64, Arm, Arm64 |
| isSilentInstall | Booleaan | Vereist Dit moet als waar worden gemarkeerd als uw installatieprogramma wordt uitgevoerd in de stille modus zonder schakelopties of anders onwaar |
| installerParameters | Snaar / Touwtje | Vereist als 'isSilentInstall' gelijk is aan onwaar |
| genericDocUrl | Snaar / Touwtje | Vereist als packageType exe is Koppeling naar document met details van aangepaste foutcodes voor het installatieprogramma van het EXE-type |
| foutdetails | Matrix van objecten | Metagegevens voor het opslaan van aangepaste foutcodes en details voor EXE-type Installers. |
| foutscenario | Snaar / Touwtje | Identificeer het specifieke foutscenario. [installatieGeannuleerdDoorGebruiker, applicatieBestaatAl, installatieReedsAanDeGang, schijfruimteVol, herstartVereist, netwerkFout, pakketAfgewezenTijdensInstallatie, installatieSuccesvol, diverse] |
| errorScenarioDetails | Matrix van objecten | |
| foutwaarde | Snaar / Touwtje | Foutcode die tijdens de installatie aanwezig kan zijn |
| foutUrl | Snaar / Touwtje | URL voor meer informatie over de fout |
| pakkettype | Snaar / Touwtje | Vereist [exe, msi] |
Voorbeeldaanvraag [volledige module-update]
{
"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",
}]
}
voorbeeldaanvraag [update voor één pakketpatch]
{
"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",
}
Antwoordheaders
| Koptekst | Waarde |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | [De lijst met foutberichten of waarschuwingsberichten indien aanwezig] |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout is ontstaan |
| responsGegevens | Voorwerp | |
| pollingUrl | Snaar / Touwtje | [Polling-URL voor het ophalen van de inzendingsstatus in het geval van een reeds In-Progress inzending] |
| lopendeInzendingId | Snaar / Touwtje | [Inzendings-ID van elke reeds In-Progress indieningen] |
voorbeeldantwoord
{
"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 voor commit-pakketten
Hiermee wordt de nieuwe set pakketten vastgelegd die zijn bijgewerkt met behulp van Pakketupdate-API's onder de huidige conceptindiening. Deze API retourneert een polling-URL om het uploaden van pakketten bij te houden.
Pad: /submission/v1/product/{productId}/packages/commit
methode: POST
padparameters
| Naam | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
vereiste headers
| Koptekst | Waarde |
|---|---|
Authorization: Bearer <Token> |
De Microsoft Entra ID-app-id gebruiken die is geregistreerd bij het Partnercentrum-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Antwoordheaders
| Koptekst | Waarde |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | [De lijst met foutberichten of waarschuwingsberichten indien aanwezig] |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| responsGegevens | Voorwerp | |
| pollingUrl | Snaar / Touwtje | [URL voor peiling om de status van de pakketupload of indieningsstatus op te halen in geval van een reeds ingediende In-Progress inzending] |
| lopendeInzendingId | Snaar / Touwtje | [Inzendings-id van een al In-Progress inzending] |
voorbeeldantwoord
{
"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": ""
}
}
Huidige api voor conceptvermeldingsassets ophalen
Hiermee worden itemdetails opgehaald onder de huidige conceptinzending.
Pad: /submission/v1/product/{productId}/listings/assets?languages={languages}
Methode : GET
padparameters
| Naam | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
Query-parameters
| Naam | Beschrijving |
|---|---|
| Talen | [Optioneel] De lijst met talen wordt gefilterd als door komma's gescheiden tekenreeks [limiet van maximaal 200 talen]. Als u afwezig bent, worden de gegevens van de assets van de eerste 200 beschikbare vermeldingstaal opgehaald. (bijvoorbeeld "en-us, en-gb") |
vereiste headers
| Koptekst | Waarde |
|---|---|
Authorization: Bearer <Token> |
De Microsoft Entra ID-app-id gebruiken die is geregistreerd bij het Partnercentrum-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Antwoordheaders
| Koptekst | Waarde |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | De lijst met foutberichten of waarschuwingsberichten, indien van toepassing |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| responsGegevens | Voorwerp | |
| vermelde activa | Matrix van objecten | De details van de assets voor elke taal weergeven |
| Taal | Snaar / Touwtje | |
| storeLogos | Matrix van objecten | |
| schermopnamen | Matrix van objecten | |
| identiteitskaart | Snaar / Touwtje | |
| assetUrl | Snaar / Touwtje | Moet een geldige URL zijn |
| afbeeldingsgrootte | Voorwerp | |
| Breedte | Geheel getal | |
| hoogte | Geheel getal |
voorbeeldantwoord
{
"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
}
}
]
}]
}
}
Api voor vermeldingen van assets maken
Hiermee maakt u een nieuwe asset-upload voor de huidige conceptinzending.
Bijwerken van de lijst van assets
Microsoft Store Submission-API voor EXE- of MSI-app maakt gebruik van door runtime gegenereerde SAS-URL's naar Blob Stores voor elke afzonderlijke upload van afbeeldingsassets, samen met een Doorvoer-API-aanroep nadat het uploaden is geslaagd. Als u de mogelijkheid wilt hebben om vermeldingsassets bij te werken en op zijn beurt landinstellingen in de vermeldingsmodule toe te voegen of te verwijderen, kunt u de volgende methode gebruiken:
- Gebruik de API voor het maken van vermeldingsassets om verzoeken in te dienen voor het uploaden van assets, samen met de taal, het type en het aantal assets.
- Op basis van het aantal aangevraagde assets worden asset-id's op aanvraag gemaakt en wordt een SAS-URL voor de korte termijn gemaakt en teruggestuurd in de responsebody als onderdeel van de assets. U kunt deze URL gebruiken om afbeeldingsassets van een specifiek type te uploaden met behulp van HTTP-clients [Put Blob (REST API) - Azure Storage | Microsoft Docs].
- Na het uploaden kunt u de API voor het vastleggen van vermogensvermeldingen gebruiken om ook de nieuwe asset-ID-informatie te verzenden welke eerder is ontvangen uit de vorige API-aanroep. De enkele API zal na validatie de gegevens van de vermogensbestanddelen van de vermelding intern vastleggen.
- Deze aanpak overschrijft effectief de volledige set eerdere afbeeldingen van het type activa voor een specifieke taal die in de aanvraag wordt verzonden. Daarom worden eerder geüploade assets verwijderd.
Pad: /submission/v1/product/{productId}/listings/assets/create
methode: POST
padparameters
| Naam | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
vereiste headers
| Koptekst | Beschrijving |
|---|---|
Authorization: Bearer <Token> |
De Microsoft Entra ID-app-id gebruiken die is geregistreerd bij het Partnercentrum-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Verzoekparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| Taal | Snaar / Touwtje | Vereist |
| createAssetRequest | Voorwerp | Vereist |
| Schermafbeelding | Geheel getal | Vereist als ISV schermopnamen moet bijwerken of nieuwe vermeldingstaal moet toevoegen [1 - 10] |
| Logo | Geheel getal | Vereist als ISV logo's moet bijwerken of nieuwe vermeldingstaal moet toevoegen [1 of 2] |
Antwoordheaders
| Koptekst | Beschrijving |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | De lijst met foutberichten of waarschuwingsberichten, indien van toepassing |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| responsGegevens | Voorwerp | |
| vermelde activa | Voorwerp | Object met details van StoreLogos en Schermafbeeldingen die moeten worden geüpload |
| Taal | Snaar / Touwtje | |
| storeLogos | Matrix van objecten | |
| schermopnamen | Matrix van objecten | |
| identiteitskaart | Snaar / Touwtje | |
| primaryAssetUploadUrl | Snaar / Touwtje | Primaire URL voor het uploaden van vermeldingsasset met behulp van azure Blob REST API |
| secondaryAssetUploadUrl | Snaar / Touwtje | Secundaire URL voor het uploaden van vermeldingsbestand met behulp van Azure Blob REST API |
| httpMethode | HTTP-methode | De HTTP-methode moet worden gebruikt om assets te uploaden via de URL's voor het uploaden van assets : primair of secundair |
| httpHeaders | Voorwerp | Een object met sleutels als vereiste headers die aanwezig moeten zijn in de upload-API-aanroep naar URL's voor het uploaden van assets. Als de waarde niet leeg is, moeten de headers specifieke waarden hebben. Anders worden waarden berekend tijdens de API-aanroep. |
voorbeeldantwoord
{
"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"}
}]
}
}
}
Api voor het doorvoeren van assets
Hiermee wordt de nieuwe vermeldingsonderdeel doorgevoerd die is geüpload met behulp van de details van de Creëer Assets API binnen de huidige conceptinzending.
Pad: /submission/v1/product/{productId}/listings/assets/commit
Methode : PUT
padparameters
| Naam | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
vereiste headers
| Koptekst | Beschrijving |
|---|---|
Authorization: Bearer <Token> |
De Microsoft Entra ID-app-id gebruiken die is geregistreerd bij het Partnercentrum-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Verzoekparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| vermelde activa | Voorwerp | |
| Taal | Snaar / Touwtje | |
| storeLogos | Matrix van object | |
| schermopnamen | Matrix van object | |
| identiteitskaart | Snaar / Touwtje | Moet een bestaande ID zijn die de gebruiker wil behouden uit de API 'Get Current Listing Assets' of een nieuwe ID waaronder een nieuwe asset is geüpload in de API 'Create Listing Assets'. |
| assetUrl | Snaar / Touwtje | Moet de URL zijn van een bestaande asset die de gebruiker wil behouden uit de API "Get Current Listing Assets" of de upload-URL - primair of secundair - waarmee een nieuwe asset is geüpload in de API "Create Listing Assets." Moet een geldige URL zijn |
Voorbeeldaanvraag
{
"listingAssets": {
"language": "en-us",
"storeLogos": [
{
"id": "1234567890abcdefgh",
"assetUrl": "https://contoso.com/blob=1234567890abcdefgh",
}
],
"screenshots": [
{
"id": "1234567891abcdefgh",
"assetUrl": "https://contoso.com/blob=1234567891abcdefgh",
}
]
}
}
Antwoordheaders
| Koptekst | Beschrijving |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | De lijst met foutberichten of waarschuwingsberichten, indien van toepassing |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| responsGegevens | Voorwerp | |
| pollingUrl | Snaar / Touwtje | URL om de status op te halen van iedere lopende inzending |
| lopendeInzendingId | Snaar / Touwtje | Indienings-id van elke reeds lopende indiening |
voorbeeldantwoord
{
"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 voor module-statuspeiling
API om de gereedheid van de module te controleren voordat verzending kan worden gemaakt. Valideert ook de uploadstatus van het pakket.
Pad: /submission/v1/product/{productId}/status
Methode : GET
padparameters
| Naam | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
vereiste headers
| Koptekst | Beschrijving |
|---|---|
Authorization: Bearer <Token> |
De Microsoft Entra ID-app-id gebruiken die is geregistreerd bij het Partnercentrum-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Antwoordheaders
| Koptekst | Beschrijving |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | De lijst met foutberichten of waarschuwingsberichten, indien van toepassing |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| responsGegevens | Voorwerp | |
| isReady | Booleaan | Geeft aan of alle modules de status Gereed hebben, inclusief het uploaden van pakketten |
| lopendeInzendingId | Snaar / Touwtje | Indienings-id van elke reeds lopende indiening |
voorbeeldantwoord
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"isReady": true,
"ongoingSubmissionId": ""
}
}
Indienings-API maken
Hiermee maakt u een inzending op basis van het huidige concept voor MSI- of EXE-app. De API controleert:
- voor actieve inzending en mislukt met een foutbericht als er een actieve inzending bestaat.
- als alle modules in gereed status zijn om een indiening te doen.
- elk veld in de inzending wordt gevalideerd volgens de vereisten van de Store
Pad:/submission/v1/product/{productId}/submit
methode: POST
padparameters
| Naam | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
vereiste headers
| Koptekst | Beschrijving |
|---|---|
Authorization: Bearer <Token> |
De Microsoft Entra ID-app-id gebruiken die is geregistreerd bij het Partnercentrum-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Antwoordheaders
| Koptekst | Beschrijving |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | De lijst met foutberichten of waarschuwingsberichten, indien van toepassing |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| responsGegevens | Voorwerp | |
| pollingUrl | Snaar / Touwtje | Polling-URL voor het ophalen van de status van modulegereedheid, inclusief het uploaden van pakketten voor verzending |
| indieningsId | Snaar / Touwtje | De id voor de zojuist gemaakte inzending |
| lopendeInzendingId | Snaar / Touwtje | Indienings-id van elke reeds lopende indiening |
voorbeeldantwoord
{
"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 voor het peilen van indieningsstatus
API om de status van de inzending te controleren.
Pad: /submission/v1/product/{productId}/submission/{submissionId}/status
Methode : GET
padparameters
| Naam | Beschrijving |
|---|---|
| product-ID | De partnercentrum-id van het product |
vereiste headers
| Koptekst | Beschrijving |
|---|---|
Authorization: Bearer <Token> |
De Microsoft Entra ID-app-id gebruiken die is geregistreerd bij het Partnercentrum-account |
X-Seller-Account-Id |
Verkopers-ID van het Partnercentrumaccount |
Antwoordheaders
| Koptekst | Beschrijving |
|---|---|
X-Correlation-ID |
De unieke ID van het GUID-type voor elke aanvraag. Dit kan worden gedeeld met het ondersteuningsteam voor het analyseren van elk probleem. |
Retry-After |
De tijd in seconden waarop de client moet wachten voordat de API's opnieuw worden aangeroepen vanwege snelheidsbeperking. |
antwoordparameters
| Naam | Typologie | Beschrijving |
|---|---|---|
| isSuccesvol | Booleaan | |
| Fouten | Matrix van objecten | De lijst met foutberichten of waarschuwingsberichten, indien van toepassing |
| code | Snaar / Touwtje | De foutcode van het bericht |
| bericht | Snaar / Touwtje | De beschrijving van de fout |
| doel | Snaar / Touwtje | De entiteit waaruit de fout afkomstig is |
| responsGegevens | Voorwerp | |
| publicatiestatus | Snaar / Touwtje | Publicatiestatus van inzending - [INPROGRESS, GEPUBLICEERD, MISLUKT, ONBEKEND] |
| isMislukt | Booleaan | Geeft aan of publiceren is mislukt en niet opnieuw wordt geprobeerd |
voorbeeldantwoord
{
"isSuccess": true,
"errors": [{
"code": "badrequest",
"message": "Error Message 1",
"target": "listings"
}, {
"code": "warning",
"message": "Warning Message 1",
"target": "properties"
}],
"responseData": {
"publishingStatus": "INPROGRESS",
"hasFailed": false
}
}
Codevoorbeelden
De volgende artikelen bevatten gedetailleerde codevoorbeelden die laten zien hoe u de Microsoft Store-inzendings-API in verschillende programmeertalen kunt gebruiken:
C#-voorbeeld: Microsoft Store-indienings-API voor MSI- of EXE-app
Dit artikel bevat voorbeelden van C#-code die laten zien hoe u de Microsoft Store-inzendings-API voor MSI- of EXE-app gebruikt. U kunt elk voorbeeld bekijken voor meer informatie over de taak die wordt gedemonstreert, of u kunt alle codevoorbeelden in dit artikel bouwen in een consoletoepassing.
Voorwaarden In deze voorbeelden wordt de volgende bibliotheek gebruikt:
- Newtonsoft.Json NuGet-pakket van Newtonsoft.
Hoofdprogramma In het volgende voorbeeld wordt een opdrachtregelprogramma geïmplementeerd dat de andere voorbeeldmethoden in dit artikel aanroept om verschillende manieren te demonstreren om de Microsoft Store-indienings-API te gebruiken. Dit programma aanpassen voor uw eigen gebruik:
- Wijs de eigenschap SellerId toe aan de verkoper-id van uw Partnercentrum-account.
- Wijs de eigenschap ApplicationId toe aan de id van de app die u wilt beheren.
- Wijs de eigenschappen ClientId en ClientSecret toe aan de client-id en -sleutel voor uw app en vervang de tenantid-tekenreeks in de TokenEndpoint-URL door de tenant-id voor uw app. Zie Een Microsoft Entra ID-toepassing koppelen aan uw Partnercentrum-account voor meer informatie
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();
}
}
}
Helperklasse voor ClientConfiguration met C#
De voorbeeld-app maakt gebruik van de helperklasse ClientConfiguration om Microsoft Entra ID Directory-gegevens en app-gegevens door te geven aan elk van de voorbeeldmethoden die gebruikmaken van de Microsoft Store-inzendings-API.
using System;
using System.Collections.Generic;
using System.Text;
namespace Win32SubmissionApiCSharpSample
{
public class ClientConfiguration
{
/// <summary>
/// Client Id of your Microsoft Entra ID Directory app.
/// Example" 00001111-aaaa-2222-bbbb-3333cccc4444
/// </summary>
public string ClientId { get; set; }
/// <summary>
/// Client secret of your Microsoft Entra ID 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 Microsoft Entra ID 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; }
}
}
Een app-inzending maken met C#
In het volgende voorbeeld wordt een klasse geïmplementeerd die gebruikmaakt van verschillende methoden in de Microsoft Store-indienings-API om een app-inzending bij te werken.
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.
}
}
}
Helperklasse van IngestionClient met behulp van C#
De klasse IngestionClient biedt helpermethoden die worden gebruikt door andere methoden in de voorbeeld-app om de volgende taken uit te voeren:
- Haal een Microsoft Entra ID-toegangstoken op dat kan worden gebruikt om methoden aan te roepen in de Microsoft Store-inzendings-API. Nadat u een token hebt verkregen, hebt u 60 minuten de tijd om dit token te gebruiken in aanroepen naar de Microsoft Store-inzendings-API voordat het token verloopt. Nadat het token is verlopen, kunt u een nieuw token genereren.
- De HTTP-aanvragen voor de Microsoft Store-inzendings-API verwerken.
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 Microsoft Entra ID 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
/// Microsoft Entra ID Directory app. Example: https://login.microsoftonline.com/d454d300-128e-2d81-334a-27d9b2baf002/oauth2/v2.0/token </param>
/// <param name="clientId">Client Id of your Microsoft Entra ID Directory app. Example" 00001111-aaaa-2222-bbbb-3333cccc4444</param>
/// <param name="clientSecret">Client secret of your Microsoft Entra ID 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;
}
}
}
Node.js voorbeeld: Microsoft Store-indienings-API voor MSI- of EXE-app
Dit artikel bevat Node.js codevoorbeelden die laten zien hoe u de Microsoft Store-inzendings-API voor MSI- of EXE-app gebruikt. U kunt elk voorbeeld bekijken voor meer informatie over de taak die wordt gedemonstreert, of u kunt alle codevoorbeelden in dit artikel bouwen in een consoletoepassing.
Voorwaarden In deze voorbeelden wordt de volgende bibliotheek gebruikt:
- node-fetch v2 [gebruik de volgende opdracht: npm install node-fetch@2]
Een app-inzending maken met behulp van node.js
In het volgende voorbeeld worden de andere voorbeeldmethoden in dit artikel aangeroepen om verschillende manieren te demonstreren om de Microsoft Store-inzendings-API te gebruiken. Dit programma aanpassen voor uw eigen gebruik:
- Wijs de eigenschap SellerId toe aan de verkoper-id van uw Partnercentrum-account.
- Wijs de eigenschap ApplicationId toe aan de id van de app die u wilt beheren.
- Wijs de eigenschappen ClientId en ClientSecret toe aan de client-id en -sleutel voor uw app en vervang de tenantid-tekenreeks in de TokenEndpoint-URL door de tenant-id voor uw app. Zie Een Microsoft Entra ID-toepassing koppelen aan uw Partnercentrum-account voor meer informatie
In het volgende voorbeeld wordt een klasse geïmplementeerd die gebruikmaakt van verschillende methoden in de Microsoft Store-indienings-API om een app-inzending bij te werken.
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();
ClientConfiguration-hulpprogramma
De voorbeeld-app maakt gebruik van de helperklasse ClientConfiguration om Microsoft Entra ID Directory-gegevens en app-gegevens door te geven aan elk van de voorbeeldmethoden die gebruikmaken van de Microsoft Store-inzendings-API.
/** 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;
Helper van IngestionClient met behulp van node.js
De klasse IngestionClient biedt helpermethoden die worden gebruikt door andere methoden in de voorbeeld-app om de volgende taken uit te voeren:
- Haal een Microsoft Entra ID-toegangstoken op dat kan worden gebruikt om methoden aan te roepen in de Microsoft Store-inzendings-API. Nadat u een token hebt verkregen, hebt u 60 minuten de tijd om dit token te gebruiken in aanroepen naar de Microsoft Store-inzendings-API voordat het token verloopt. Nadat het token is verlopen, kunt u een nieuw token genereren.
- De HTTP-aanvragen voor de Microsoft Store-inzendings-API verwerken.
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;
Aanvullende hulp
Als u vragen hebt over de Microsoft Store-inzendings-API of hulp nodig hebt bij het beheren van uw inzendingen met deze API, gebruikt u de volgende bronnen:
- Stel uw vragen op onze forums.
- Ga naar onze ondersteuningspagina en vraag een van de ondersteunde ondersteuningsopties voor partnercentrum aan. Als u wordt gevraagd een probleemtype en categorie te kiezen, kiest u respectievelijk App-inzending en certificering en Een app verzenden.
Veelgestelde vragen
Wat kan ik doen via de Microsoft Store indienings-API?
Met de Microsoft Store-inzendings-API kunnen ontwikkelaars app-beheertaken automatiseren, waaronder:
- Nieuwe app-updates maken en verzenden.
- App-pakketten uploaden en beheren.
- Metagegevens en Store-vermeldingen bijwerken.
U kunt deze API integreren in uw continue integratie of werkstromen bouwen, routinetaken automatiseren om uw publicatieproces te stroomlijnen.
Windows developer