moirei/laravel-google-merchant-api

Laravel Google Merchant Products API for Google Shopping.

1.1.4 2021-06-25 04:07 UTC

This package is auto-updated.

Last update: 2024-09-27 11:43:24 UTC


README

这是一个用于管理Google Shopping的Google Merchant Center数据流的精美包。该包准备实现商家高级 内容API

使用示例

use MOIREI\GoogleMerchantApi\Facades\ProductApi;
use MOIREI\GoogleMerchantApi\Facades\OrderApi;

...

ProductApi::insert(function($product){
    $product->offerId(1)
        	->title('Purple Shoes')
        	->description('What are thooose!!')
        	->price(10)
        	->custom('purchase_quantity_limit', 1000)
            ->availabilityDate( today()->addDays(7) );
})->then(function($response){
    echo 'Product inserted';
})->otherwise(function($response){
    echo 'Insert failed';
})->catch(function($e){
    echo($e->getResponse()->getBody()->getContents());
});

OrderApi::list()->then(function($response){
    //
})->otherwise(function($response){
    echo 'List failed';
})->catch(function($e){
    echo($e->getResponse()->getBody()->getContents());
});


OrderApi::scout(); // Scout and fire event

功能

  • 产品API
    • 实现了 insertgetdeletelist API调用
    • 使用定义的模式接口直接与eloquent模型(产品模型)一起工作
    • 事件监听器以响应对eloquent模型的更改,并自动插入它们
  • 订单API
    • 实现了 acknowledgecancelcancelLineItemrejectReturnLineItemreturnRefundLineItemgetlist API调用。
    • 内部调度器扫描未确认的订单并触发事件。这意味着您可以在Google Shopping中自动确认和注册新订单。
    • 包括用于 testOrders 的沙盒功能。
  • 多商家(1.1.0)

升级到1.1.x

尽管具有向后兼容性,但请确保更新您的配置以使用多个商家。

安装

通过composer

composer require moirei/laravel-google-merchant-api

安装服务提供者(对于Laravel>=5.5可跳过);

// config/app.php
'providers' => [
    ...
    MOIREI\GoogleMerchantApi\GoogleMerchantApiServiceProvider::class,
],

发布配置

php artisan vendor:publish --tag="google-merchant-api-config"

设置与授权

  • 请遵循此处的说明并创建一个服务帐户密钥。在您的应用程序根目录中创建 storage/app/google-merchant-api/service-account-credentials.json 并存储下载的json内容
  • 获取您的商家ID
  • 将您的商家ID和服务帐户凭证的路径添加到配置中
  • 在配置中,如果您需要使用数组或模型,请在产品内容中设置属性部分

使用方法

多商家

1.1.0 开始,我们现在可以定义多个商家,并且可以通过从订单或产品API类中调用 merchant 方法在它们之间切换。

ProductApi::merchant('my-pet-store')->insert($product);
// config/laravel-google-merchant-api.php
...
    'merchants' => [
        'my-pet-store' => [
			'app_name' => config('app.name'),
			'merchant_id' => '000000000',
			'client_credentials_path' => storage_path('app/my-pet-store-credentials.json'),
		]
    ],
...

或者

ProductApi::merchant([
    'app_name' => 'My Pet Store',
    'merchant_id' => '000000000',
    'client_credentials_path' => storage_path('app/my-pet-store-credentials.json')
])->insert($product);

产品API

可以通过 insertgetdelete、和 list 方法查询Google Merchant内容。产品内容由 Product 类包含和处理。可以直接传递此类的一个实例或通过闭包回调解决。可以通过以下方式填充实例:

  • 直接访问底层属性。请参阅特殊函数
  • 传递一个eloquent模型,或者通过
  • 传递一个原始数组

要传递一个数组或一个模型,必须在配置中定义属性关系。

插入

插入方法创建一个新的内容,如果 channelcontentLanguagetargetCountryofferId 相同,则更新旧内容。

$attributes = [
    'id' => 1, // maps to offerId (if set in config)
    'name' => 'Product 1', // likewise maps to title
];
ProductApi::insert(function($product) use($attributes){
    $product->with($attributes)
        	->link('https://moirei.com/mg001')
        	->price(60, 'USD');
})->then(function($data){
    echo 'Product inserted';
})->otherwise(function(){
    echo 'Insert failed';
})->catch(function($e){
    dump($e);
});

使用数组:

use MOIREI\GoogleMerchantApi\Contents\Product\Product as GMProduct;

...
$attributes = [
    'id' => 1,
    'name' => 'Product 1',
];
$product = (new GMProduct)->with($attributes);

必须按照配置中的属性映射定义 attributes 值。

使用Eloquent模型:

use App\Models\Product;
use MOIREI\GoogleMerchantApi\Contents\Product\Product as GMProduct;


...
$model = Product::find(1);
$product = (new GMProduct)->with($model);

ProductApi::insert($product)->catch(function($e){
    // always catch exceptions
});

模型的 attributes 值必须按照配置中的属性映射进行定义。要访问未定义的模型属性,请使用访问器和自定义模型属性

protected $appends = [
    'availability',
    'gm_price',
];

...

public function getAvailabilityAttribute(){
    return 'in stock'; // calculate
}
public function getGmPriceAttribute(){
    return [
        'value' => $this->price,
        'currency' => $this->currency->code,
    ];
}

对于设置自定义产品内容(customAttributes),您可能更倾向于使用custom()方法。同样,对于availabilityDate,请使用availabilityUntil()方法。

使用事件与监听器:

提供的事件和监听器可以被设置,以便当您的应用程序创建或更新一个模型时,产品内容会自动插入。

要设置此功能,请将以下代码片段添加到您的eloquent模式中。变量product可以是模型或数组。

use MOIREI\GoogleMerchantApi\Events\ProductCreatedOrUpdatedEvent;

...

/**
 * The "booting" method of the model.
 *
 * @return void
 */
protected static function boot() {
    parent::boot();

    // when a product is created
    static::created(function(Product $product){
        // perhaps a logic to ignore drafts and private products
        if($product->is_active && (config('app.env') === 'production')){
        	event(new ProductCreatedOrUpdatedEvent($product));
        }
    });

    // when a product is updated
    static::updated(function(Product $product){
        // perhaps a logic to ignore drafts and private products
        if($product->is_active && (config('app.env') === 'production')){
        	event(new ProductCreatedOrUpdatedEvent(function($gm_product) use ($product){
                $gm_product->with($product)
                    	   ->preorder()
                    	   ->availabilityDate($product->preorder_date);
            }));
        }
    });
}

接下来,在EventServiceProvider.php中定义事件关系。

use MOIREI\GoogleMerchantApi\Listeners\ProductCreatedOrUpdatedListener;

...

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    ...,
    /**
     * Product events
     */
    ProductCreatedOrUpdatedEvent::class => [
        ProductCreatedOrUpdatedListener::class,
    ],

];

获取与列表

ProductApi::get($product)->then(function($data){
    //
})->catch(function($e){
    // always catch exceptions
});

list方法在没有任何参数的情况下调用get方法;

ProductApi::list()->then(function($data){
    //
});

因此,以下代码同样可以检索产品列表

ProductApi::get()->then(function($data){
    //
});

删除

ProductApi::delete($product)->then(function($data){
    //
});

要设置事件监听器,请将以下内容添加到您的eloquent模型中

use MOIREI\GoogleMerchantApi\Events\ProductDeletedEvent;

...

protected static function boot() {
    parent::boot();

    ...

    // when a product is deleted
    static::deleted(function(Product $product){
        if(config('app.env') === 'production'){
        	event(new ProductDeletedEvent($product));
        }
    });
}

然后在EventServiceProvider.php中定义关系

use MOIREI\GoogleMerchantApi\Listeners\ProductDeletedListener;

...

protected $listen = [
    ...,
    ProductDeletedEvent::class => [
        ProductDeletedListener::class,
    ],
];

订单API

请注意,这些实现尚未经过适当测试。

使用API方法

目前实现的方法acknowledgecancelcancelLineItemrejectReturnLineItemreturnRefundLineItemgetlist可用于与您的Google Merchant进行交互。

使用这些方法的格式在整个包中都是标准的。例如,可以通过以下方式确认订单

OrderApi::acknowledge(function($order){
    $order->id('TEST-1953-43-0514');
});

或者通过以下方式

$order = (new Order)->with([
    'id' => 'TEST-1953-43-0514',
]);
OrderApi::acknowledge($order);

此外,还提供了listAcknowledged方法,以便在需要时列出已确认的订单。

计划侦察兵

如果配置中的schedule_orders_check设置为true,则该包将定期侦察未确认的订单,并触发一个\MOIREI\GoogleMerchantApi\Events\NewOrdersScoutedEvent事件。该事件包含一个类为\MOIREI\GoogleMerchantApi\Contents\Order的订单数组。订单结构遵循订单资源

在监听器中的示例处理

use MOIREI\GoogleMerchantApi\Events\NewOrdersScoutedEvent;
use MOIREI\GoogleMerchantApi\Facades\OrderApi;

...
public function handle(NewOrdersScoutedEvent $event)
{
    $merchant = $event->merchant; // array key as defined in config
    $merchant_id = $event->merchant_id;

    foreach($event->orders as $gm_order){
        OrderApi::acknowledge($gm_order);

        $gm_order = $gm_order->all(); // get all attributes, including mutated attributes
        foreach($gm_order['lineItems'] as $line_item){
            $model = $line_item['model']; // retrieves model
            $quantity = $line_item['quantityOrdered'];
            $shipping = $line_item['shippingDetails'];
            $delivery_date = $shipping['deliverByDate']->diffForHumans();

            // register new order item
        }

        // register new order
    }
}

备注:

  • 访问lineItems将自动解析并附加相应的模型到每个项目。当然,这假设您插入的产品offerId与模型的ID和主键相对应。
  • 如果您尚未启动Laravel调度器,您需要在服务器中添加以下Cron条目。 * * * * * php artisan schedule:run >> /dev/null 2>&1
  • 确保调度器正确设置非常重要。因此,提供了MOIREI\GoogleMerchantApi\Events\OrderContentScoutedEvent事件。如果配置中的debug_scout设置为true,则每次调度器触发时都会触发此事件。

沙箱

OrderApi类提供了一种调用一些沙箱操作的方法。例如

OrderApi::sandbox()->create(function($order){
    $order->shippingCost(30)
          ->shippingOption('economy')
          ->predefinedEmail('pog.dwight.schrute@gmail.com')
          ->predefinedDeliveryAddress('dwight');
})

您可以使用以下内容

OrderApi::sandbox()->testCreate();

来使用预设示例。

实现的沙箱操作

命令

此包提供了一个用于侦察订单的artisan命令。

php artisan gm-orders:scout

错误处理

抛出异常的方法

  • MOIREI\GoogleMerchantApi\Contents\Product::with()

    如果提供的属性不是模型或数组,则抛出MOIREI\GoogleMerchantApi\Exceptions\ProductContentAttributesUndefined

  • API类中的insertgetdeletelistlistAcknowledgedscout方法如果客户端请求损坏、失败、未定义或未授权,将抛出GuzzleHttp\Exception\ClientException

  • 如果将无法解析的实体传递为内容属性,则抛出MOIREI\GoogleMerchantApi\Exceptions\Invalid**Input异常。

  • 如果无法解析商家ID或凭证路径,则merchant方法抛出MOIREI\GoogleMerchantApi\Exceptions\InvalidMechantDetails

应该使用catch函数来处理异常。如果进行同步调用,请使用try-catch块。鉴于谷歌有千万个理由拒绝任何请求,因此强烈建议始终捕获请求(并通知您的业务逻辑)。

设计说明

  • 如果使用默认的异步功能,则插入、列表、获取、删除方法将始终返回原始实例的克隆。这允许多个请求的then、otherwise和catch回调不会相互覆盖。这些方法在设置为同步模式时返回Guzzle响应。
  • 如果调用删除方法且解析出的内容ID无效,则不会发起任何请求或抛出任何错误。如果调用获取方法,则返回产品或订单列表。
  • 有效的产品内容ID遵循以下模式:online:en:AU:1,即channel:contentLanguage:targetCountry:offerId。这个ID当然是自动生成的;除了offerId外,其他属性都有默认值。
  • 请求可能需要2小时才能反映在您的Google Merchant Center上。请耐心等待!
  • 与ProductApi或OrderApi类不同,事件的构造函数可以接受模型、数组或回调。
  • ProductOrder或任何内容类上调用all方法将解析所有已更改的属性。例如,$order['lineItems'][0]['shippingDetails']['deliverByDate']返回一个Carbon

同步调用

以上内容默认都是异步的。要进行同步调用,请使用sync方法

try{
    $response = ProductApi::sync()->insert(function($product){
        $product->offerId(1)
            	->country('AU')
            	->inStock(false);
    });
}catch(\GuzzleHttp\Exception\ClientException $e){
    //
}

注意:在这种情况下,例如insertgetdeletelist等方法,在异步调用时返回Guzzle响应(而不是ProductApiOrderApi的实例。这意味着您的异常块应围绕请求进行包装。

贡献

本包旨在为Google Merchant的Google Shopping API提供Laravel解决方案。目前,只有产品内容得到了充分的实现和测试。对于订单、退款等,欢迎提出想法和pull请求。

致谢

许可证

MIT许可证(MIT)。有关更多信息,请参阅许可证文件