Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Shopping Common Protos Laravel Package

google/shopping-common-protos

google/shopping-common-protos provides generated PHP protobuf classes for Google Shopping shared message types. It supplies common data structures used by Google Shopping APIs and related PHP libraries, simplifying protobuf request and response handling. A low-level dependency, not a standalone clie...

View on GitHub
Deep Wiki
Context7

Getting Started

This package is not a client library — it is a bundle of protobuf-generated PHP classes for the shared google.shopping.type messages (Price, Weight, CustomAttribute, Destination, Channel, ReportingContext, etc.) that the Merchant Center / Shopping APIs use in their request and response bodies. You will almost never install it deliberately; it arrives transitively when you pull in any google/shopping-merchant-* client.

composer require google/shopping-merchant-products   # brings this in
composer why google/shopping-common-protos           # confirm the path

Look first at: vendor/google/shopping-common-protos/src/ for the generated message classes under Google\Shopping\Type\, and composer.json there to confirm the PSR-4 roots and the pinned google/protobuf constraint. There is no service provider, no config file, no facade — nothing Laravel-specific to wire up.

First use case: building the common value objects that get embedded in a product payload.

use Google\Shopping\Type\Price;
use Google\Shopping\Type\CustomAttribute;

$price = (new Price())
    ->setAmountMicros(1_999_000_000) // micros, not cents
    ->setCurrencyCode('USD');

$attr = (new CustomAttribute())
    ->setName('season')
    ->setValue('ss26');

If you only need to read these values from an API response, you rarely touch the classes at all — the generated client hydrates them for you.

Implementation Patterns

Keep proto construction out of controllers. Treat these classes the way you'd treat a third-party SDK DTO: map from Eloquent models in a dedicated layer.

// app/Services/Merchant/ProductMapper.php
public function priceFrom(Product $product): Price
{
    return (new Price())
        ->setAmountMicros((int) round($product->price * 1_000_000))
        ->setCurrencyCode($product->currency);
}

Static factories for the unit conversion. Micros are the single most common source of off-by-1000 bugs. Wrap the conversion once (PriceFactory::fromCents(), fromDecimalString()) and never inline * 1_000_000 again.

Build payloads once, reuse across jobs. A queued bulk-sync job should construct the message tree in handle() and let the transport serialize it. Don't rebuild per retry attempt from scratch if the input hasn't changed — but do clone any message you reuse across two different requests (see Gotchas).

Round-trip through JSON at your boundaries. For logging, API responses, or Blade views, convert to plain arrays:

$payload = json_decode($message->serializeToJsonString(), true);

This is also the cleanest way to snapshot a message in a test fixture.

Testing. Build messages in test factories and assert on serialized output rather than object identity:

$this->assertJsonStringEqualsJsonString(
    '{"amountMicros":"1999000000","currencyCode":"USD"}',
    $price->serializeToJsonString()
);

Integration tip: if you're already using a google/shopping-merchant-* client, pass these objects straight into the request builders ($request->setPrice($price)) — no conversion layer needed. The reverse (pulling fields out of a response) is just $response->getPrice()->getAmountMicros().

Namespace hygiene. Group these in something like app/Support/Google/Shopping/ so the rest of the app never imports Google\Shopping\Type\* directly. That gives you one place to swap or stub when Google changes the surface.

Gotchas and Tips

  • Don't require it directly. With zero dependents and a single star, this is pure generated output. Let a Merchant client own the version constraint; pinning it yourself is how you get composer update deadlocks later.
  • json_encode() silently fails on messages. They are not JsonSerializable in a useful way. Always use serializeToJsonString() / mergeFromJsonString().
  • Proto3 presence is a trap. For scalar fields, 0 and '' are indistinguishable from "unset." hasFoo() only exists for message and optional fields. A zero-price product may serialize with the field omitted — send a non-zero placeholder or use an explicit optional wrapper if the API requires presence.
  • int64 is JSON-encoded as a string. amountMicros will come back as "1999000000", not 1999000000. Cast deliberately; don't assertSame(1999000000, ...) against decoded JSON.
  • Enums are plain ints. Destination::SHOPPING_ADS is a constant, not an object. Comparing with === works, but unknown enum values are legal on the wire — handle the default branch.
  • Generated objects are mutable. Reusing one Price instance across a loop of requests means later mutations leak into earlier references. clone (or rebuild) when sharing.
  • Nothing validates. setCurrencyCode('usdollars') will not throw; the failure surfaces as a 400 from the API, often with a field path that's hard to trace back. Validate at your own boundary before constructing.
  • Version skew is the real risk. These protos are locked to the API version of whichever Merchant client you use. If you see "unknown field" or missing-setter errors after an upgrade, check composer show google/shopping-common-protos against the client's constraint before debugging anything else.
  • Never patch vendor/. It's Apache-2.0 generated code from googleapis; local edits vanish on composer install. Report upstream or wrap the behavior.
  • Debugging: log serializeToJsonString() immediately before the transport call. It's the only faithful view of what actually goes over the wire and reproduces most API rejections instantly.
  • No Laravel surface. There's no config to publish, no service provider to register, no config/services.php entry this package needs — that belongs to your credentials setup, not here.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels