joseaneto/laravel-google-merchant-api

Laravel Google Merchant Products API for Google Shopping.

1.1.1 2020-07-23 08:13 UTC

This package is auto-updated.

Last update: 2024-09-29 05:49:44 UTC


README

这是一个用于管理Google Merchant Center数据包的甜美的包,为Google Shopping准备实现高级的内容API

使用示例

use Joseaneto\GoogleMerchantApi\Facades\ProductApi;
use Joseaneto\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模型所做的更改,并自动insert它们
  • 订单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' => [
    ...
    Joseaneto\GoogleMerchantApi\GoogleMerchantApiServiceProvider::class,
],

发布配置

php artisan vendor:publish --provider=Joseaneto\GoogleMerchantApi\GoogleMerchantApiServiceProvider --tag="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

可以通过insertgetdeletelist方法查询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 Joseaneto\GoogleMerchantApi\Contents\Product\Product as GMProduct;

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

必须根据配置中的属性映射定义attributes值。

使用Eloquent模型:

use App\Models\Product;
use Joseaneto\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 Joseaneto\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 Joseaneto\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 Joseaneto\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 Joseaneto\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,则包将定期侦察未确认的订单,并触发一个\Joseaneto\GoogleMerchantApi\Events\NewOrdersScoutedEvent事件。此事件包含一个包含类\Joseaneto\GoogleMerchantApi\Contents\Order的订单的数组。订单的结构符合订单资源

在您的监听器中的示例处理

use Joseaneto\GoogleMerchantApi\Events\NewOrdersScoutedEvent;
use Joseaneto\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
  • 确保调度器已正确设置非常重要。因此,提供了Joseaneto\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

错误处理

抛出异常的方法

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

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

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

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

  • 如果无法解析商户ID或凭据路径,则merchant方法将抛出Joseaneto\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类不同,事件构造函数可以接受Model、数组或回调。
  • 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)。有关更多信息,请参阅许可证文件