GunSpec
Rezept

Einen Marktplatz bauen

Ein Shop liest Daten und Bildmaterial aus dem Katalog, ein Händler schreibt Preise und Bestand zurück. Beide Seiten, mit den Regeln, über die man stolpert.

Dieselbe Form wie das Produktseiten-Rezept, ergänzt um den Handelsteil: Händler, Preise und ein gezählter Link.

  1. Einmal auflösen, ID speichernIhre SKU trägt eine Katalog-ID. Lösen Sie beim Anlegen der SKU auf, nicht beim Seitenaufruf.
  2. Datensatz und Medien gemeinsam holenDaten, Silhouette und Fotos sind unabhängige Aufrufe und laufen parallel.
  3. Angebote für die Region des KäufersHändler, die nicht dorthin liefern, sind Rauschen, und ein seit dreißig Tagen nicht aufgefrischtes Angebot wird für Sie ausgeblendet.
  4. Über die gezählte Weiterleitung verlinkenDer Ausgangslink belegt, dass eine Platzierung gewirkt hat, und ist der einzige Link, den ein Händler messen kann.
  5. Die fertige Seite cachenEine gecachte Seite je Datensatz, invalidiert über die Version, statt vier Aufrufen je Ansicht.
listing.ts
javascript
// A listing page, assembled from the catalog.const [firearm, media, offers] = await Promise.all([  gunspec.firearms.get(id),  gunspec.firearms.listMedia(id),  gunspec.firearms.getOffers(id, { region: shopper.country }),]) const rows = offers.data.map((offer) => ({  vendor: offer.vendor.name,  // Integer minor units. Format, never divide into a float.  price: new Intl.NumberFormat(locale, { style: 'currency', currency: offer.currency })    .format(offer.priceCents / 100),  inStock: offer.inStock,  // The counted redirect, not offer.url. This is what tells a  // seller their placement worked.  href: `${API}/v1/out/${offer.clickId}`,  rel: 'nofollow sponsored',}))

Geld ist hier eine ganze Zahl in der kleinsten Einheit plus ISO-4217-Code. Ein Float wird an der Grenze abgelehnt, aus dem Grund, den jedes Commerce-Team schon erlebt hat.

  • priceCents ist die kleinste Einheit: 58900 mit currency: "USD" sind 589,00 $. Teilen Sie erst beim Rendern, innerhalb von Intl.NumberFormat.
  • Runden Sie nie beim Einlesen. Ein als 589.0 gespeicherter Preis wird irgendwo stromabwärts zu 588,99.
  • Zeigen Sie die Währung des Angebots, statt umzurechnen. Ein umgerechneter Preis ist ein Angebot, das Sie nicht halten können.
  • inStock ist die Meldung des Händlers. Behandeln Sie sie in der UI als Hinweis und lassen Sie beim Checkout den Shop entscheiden.

Schicken Sie Käufer über /v1/out/{clickId} statt auf offer.url. Die Weiterleitung zählt den Besuch für dieses Angebot und schickt den Käufer dann zum Shop, und das ist die eine Zahl, die eine Platzierung rechtfertigt. Das Ziel stammt aus der Angebotszeile und nie aus der Anfrage, der Link lässt sich also nicht umbiegen. Markieren Sie den Anker mit rel="nofollow sponsored", denn eine bezahlte Platzierung ist genau das. Die Händlerreferenz dokumentiert die Route.

Ein Shop schreibt mit einem gewöhnlichen Schlüssel, der unter Profil > Händler eingetragen wurde. Es gibt keinen Vendor-Scope am Schlüssel, weshalb eine Integration zuerst /v1/vendor/shops liest: sie bekommt einen Schlüssel und nie eine Shop-ID.

vendor-feed
TypeScript
A key becomes a vendor key by being named in Profile > Seller.
1/3
// There is no scope on the key itself, and an integration is handed// a key rather than a shop id, so read the shops first.const { data: shops } = await gunspec.vendor.shops()const vendor = shops[0].id const { data } = await gunspec.vendor.pushOffers(  {    offers: feed.map((row) => ({      sku: row.sku,      attachment_id: row.gunspecId,      price_cents: row.priceCents,      currency: row.currency,      url: row.productUrl,      in_stock: row.qty > 0,      region: row.shipsTo,    })),  },  { vendor },)
  • Der volle Push ist PUT, bis zu 500 Zeilen, adressiert über Ihre eigene SKU. Unbekannte IDs kommen als unmatched zurück, statt den Batch scheitern zu lassen.
  • Umpreisen ist PATCH auf die SKU, nur mit den geänderten Feldern. Die ganze Zeile erneut zu senden ist der Weg, auf dem ein Preisjob stillschweigend eine Produkt-URL überschreibt.
  • Senden Sie stock_qty oder in_stock, nie beides: eine Zeile mit Menge leitet ihr Flag daraus ab. Die Menge bleibt privat, das Flag sehen Käufer.
  • Eine Feed-Zeile wird nach dreißig Tagen ohne Auffrischung ausgeblendet, lassen Sie den Job also täglich laufen, auch wenn sich nichts geändert hat.
  • Ein Schlüssel je Storefront, wenn Sie mehrere betreiben. Ein von zwei Shops genannter Schlüssel muss sagen, für welchen er handelt.

Der Grund, einen Marktplatz auf diesem Katalog statt auf einer Tabelle zu bauen, ist die aus Montageschnittstellen berechnete Passung: eine Cross-Selling-Leiste kann korrekt sein. Was passt worauf erklärt die Engine und ihre Konfidenzgrenzen, der Bildleitfaden die Bilder neben jeder Zeile.