我正在使用以下方法来覆盖默认的handleCustomerSubscriptionDeleted
方法,将其放置在app/Http/Controllers/WebHookController.php
中:
<?php namespace App\Http\Controllers;
use Laravel\Cashier\WebhookController;
use Symfony\Component\HttpFoundation\Response;
class StripeWebhooks extends WebhookController {
/**
* Handle stripe subscription webhook
*
* @param array $payload
* @return Response
*/
public function handleCustomerSubscriptionDeleted($payload)
{
$billable = $this->getBillable($payload['data']['object']['customer']);
if ($billable && $billable->subscribed()) {
$billable->subscription()->cancel();
}
return new Response('Webhook Handled', 200);
}
}
为了真正覆盖默认设置,我应该更新我的路由到扩展控制器,还是仍然引用默认设置?我认为保留默认设置甚至不会让Laravel知道我的控制器存在,但也想确认一下。
当前:
Route::post('stripe/webhook', '\Laravel\Cashier\WebhookController@handleWebhook');
另一部分内容涉及到
handleCustomerSubscriptionDeleted
,我也想能够获取当前用户并执行其他操作;在这种情况下,自动将记录设置为未发布状态。检索用户的最佳方法是什么?看起来$payload['data']['object']['customer']
可能会持有并关联到用户表中的stripe_id
列,但需要确认。感谢任何帮助!
更新
我认为(根据文档),应该更像这样:<?php namespace App\Http\Controllers;
use App\Models\Dashboard\Listing;
use App\User;
use Symfony\Component\HttpFoundation\Response;
use Laravel\Cashier\WebhookController as BaseController;
class WebhookController extends BaseController
{
/**
* Handle stripe subscription webhook
*
* @param array $payload
* @return Response
*/
public function handleCustomerSubscriptionDeleted($payload)
{
$billable = $this->getBillable($payload['data']['object']['customer']);
if ($billable && $billable->subscribed()) {
$billable->subscription()->cancel();
// Get current user
$user = User::find($billable);
// Set each listing to draft
foreach ($user->listings as $listing) {
$current_listing = Listing::find($listing->id);
if ($current_listing->status == 'published') {
$current_listing->status = 'draft';
$current_listing->save();
}
}
}
return new Response('Webhook Handled', 200);
}
}
我随后将我的路由更新为以下内容:
Route::post('stripe/webhook', 'WebhookController@handleWebhook');
但它仍未触发。但是,我也在想,当用户取消订阅时是否会调用handleCustomerSubscriptionDeleted
,还是在他们的宽限期结束并实际取消订阅后才会调用。是否有比在本地等待更可靠的方法来测试这一点?
更新#2
我已将覆盖类更新为以下内容:
<?php namespace App\Http\Controllers;
use App\Models\Dashboard\Listing;
use App\User;
use Symfony\Component\HttpFoundation\Response;
use Laravel\Cashier\WebhookController as BaseController;
class WebhookController extends BaseController
{
/**
* Handle stripe subscription webhook
*
* @param array $payload
* @return Response
*/
public function handleCustomerSubscriptionDeleted(array $payload)
{
$billable = $this->getBillable($payload['data']['object']['customer']);
if ($billable && $billable->subscribed()) {
$billable->subscription()->cancel();
// Get current user
$user = User::where('stripe_id', $billable)->firstOrFail();
// Set each listing to draft
foreach ($user->listings as $listing) {
$current_listing = Listing::find($listing->id);
if ($current_listing->status == 'published') {
$current_listing->status = 'draft';
$current_listing->save();
}
}
}
return new Response('Webhook Handled', 200);
}
}
我所做的更改是将
$billable
更改为按用户搜索,因为响应返回的是用户,而不是我曾经认为的用户ID。我最终尝试了@Shaz提到的localtunnel.me,这确实允许我向其发送请求,但是由于无法传递我想要影响的客户ID,我不确定如何验证一切是否真正起作用。我可能会尝试深入挖掘以查看是否可以通过Cashier手动运行事件,但仍然似乎有些奇怪。更新#3
尝试做一些更简单的事情,例如监听
customer.subscription.created
(因为它立即触发):<?php namespace App\Http\Controllers;
use App\Models\Dashboard\Listing;
use App\User;
use Symfony\Component\HttpFoundation\Response;
use Laravel\Cashier\WebhookController as BaseController;
class WebhookController extends BaseController
{
/**
* @param array $payload
*/
public function handleCustomerSubscriptionCreated(array $payload) {
$billable = $this->getBillable($payload['data']['object']['customer']);
if ($billable) {
// Get current user
$user = User::where('stripe_id', $billable)->firstOrFail();
$user->first_name = 'Helloooooo';
$user->save();
}
}
/**
* Handle stripe subscription webhook
*
* @param array $payload
* @return Response
*/
public function handleCustomerSubscriptionDeleted(array $payload)
{
$billable = $this->getBillable($payload['data']['object']['customer']);
if ($billable && $billable->subscribed()) {
$billable->subscription()->cancel();
// Get current user
$user = User::where('stripe_id', $billable)->firstOrFail();
// Set each listing to draft
foreach ($user->listings as $listing) {
$current_listing = Listing::find($listing->id);
if ($current_listing->status == 'published') {
$current_listing->status = 'draft';
$current_listing->save();
}
}
}
return new Response('Webhook Handled', 200);
}
}
我使用localtunnel.me来设置webhook,但是它似乎没有正确响应webhook,因为我在Stripe响应日志中看到500错误,尽管我的“测试Webhooks”事件从Stripe仪表板触发(显然没有设置客户ID)是正常的。关于500错误的响应不幸地丢失/截断在Laravel输出的混乱源代码中:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="robots" content="noindex,nofollow" />
<style>
/* Copyright (c) 2010, Yahoo! Inc. All rights reserved. Code licensed under the BSD License: http://developer.yahoo.com/yui/license.html */
html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}
html { backgr...
__construct
实际上破坏了我的路由,所以我不确定是否应该将其放在那里。有没有示例可以用来触发Stripe事件并传递customer_id,以便我可以确保必要的DB更新也已完成?希望Cashier只是发出事件,我可以在此之外连接它。 - Zachparent::handleWebhook()
。 对于500错误,请记住在handleCustomerSubscriptionCreated()
方法的结尾处添加return new Response('Webhook已处理',200);
。 - Shaz MJparent::handleWebhook
片段时,出现了undefined index $id
的错误-- 尝试查看缺失响应消息是否会触发已创建的订阅事件。 - Zach