mirror of
https://github.com/Bigherollc/wticreatorstudio.git
synced 2026-01-16 19:05:08 -05:00
498 lines
27 KiB
PHP
498 lines
27 KiB
PHP
<?php
|
|
|
|
namespace Modules\Subscription\Http\Controllers;
|
|
|
|
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller;
|
|
use Modules\Subscription\Entities\SubscriptionSetting;
|
|
use Modules\Subscription\Entities\CustomerSubscription;
|
|
use Modules\Subscription\Entities\UserCredit;
|
|
use Modules\Subscription\Entities\UserCreditHistory;
|
|
use Modules\Subscription\Entities\SubscriptionPlanPrice;
|
|
use Modules\Subscription\Entities\SubscriptionCoupon;
|
|
use Modules\Subscription\Entities\SubscriptionCouponRedemption;
|
|
use Modules\FrontendCMS\Entities\SubsciptionPaymentInfo;
|
|
use Modules\Customer\Services\CustomerService;
|
|
use App\Traits\SendMail;
|
|
use Carbon\Carbon;
|
|
use Exception;
|
|
use Log;
|
|
|
|
class StripeWebhookController extends Controller
|
|
{
|
|
use SendMail;
|
|
|
|
protected $stripe;
|
|
protected $customerService;
|
|
|
|
public function __construct(CustomerService $customerService){
|
|
$credential = getPaymentInfoViaSellerId(1, 4);
|
|
$this->stripe = \Stripe\Stripe::setApiKey(@$credential->perameter_3);
|
|
$this->customerService = $customerService;
|
|
}
|
|
|
|
public function webhook() {
|
|
|
|
// This is your Stripe CLI webhook secret for testing your endpoint locally.
|
|
//$endpoint_secret = 'whsec_Gyr6d2lzXXF3goYZVyNyxPWg4ZumlPrb'; // live .app
|
|
$endpoint_secret = 'whsec_3EeUyDnEVgmUGLL4wqxXGh6Hp74sqeDz'; // live .com
|
|
//$endpoint_secret = 'whsec_8713fc6dfb985a0a56eaa2dce9fa5e836b2480189f49865431a0fd529a6a7087'; // testing
|
|
|
|
$payload = @file_get_contents('php://input');
|
|
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
|
|
$event = null;
|
|
|
|
try {
|
|
$event = \Stripe\Webhook::constructEvent(
|
|
$payload, $sig_header, $endpoint_secret
|
|
);
|
|
} catch(\UnexpectedValueException $e) {
|
|
// Invalid payload
|
|
http_response_code(400);
|
|
exit();
|
|
} catch(\Stripe\Exception\SignatureVerificationException $e) {
|
|
// Invalid signature
|
|
http_response_code(400);
|
|
exit();
|
|
}
|
|
|
|
$response = $event->data->object;
|
|
|
|
\Log::debug(json_encode($response));
|
|
|
|
if($event->type == 'charge.captured' && $response['status'] == 'succeeded' && $response['captured'] == true){
|
|
$this->updateCustomerSubscription('active','succeeded', true, $response, $event->type);
|
|
} else if($event->type == 'charge.expired'){
|
|
$this->updateCustomerSubscription('expired','expired', false, $response, $event->type);
|
|
} else if($event->type == 'charge.failed'){
|
|
$this->updateCustomerSubscription('inactive','failed', false, $response, $event->type);
|
|
} else if($event->type == 'charge.refunded'){
|
|
$this->updateCustomerSubscription('inactive','refunded', false, $response, $event->type);
|
|
} else if($event->type == 'charge.succeeded' && $response['status'] == 'succeeded' && $response['captured'] == true){
|
|
$this->updateCustomerSubscription('active','succeeded', true, $response, $event->type);
|
|
} else if($event->type == 'customer.subscription.deleted'){
|
|
$this->updateCustomerSubscription('cancelled', 'cancelled', false, $response, $event->type);
|
|
} else if($event->type == 'customer.subscription.paused'){
|
|
$this->updateCustomerSubscription('paused','paused', false, $response, $event->type);
|
|
} else if($event->type == 'customer.subscription.resumed'){
|
|
$this->updateCustomerSubscription('active','succeeded', true, $response, $event->type);
|
|
} else if($event->type == 'customer.subscription.updated'){
|
|
if($response['status'] != 'trialing'){
|
|
$status = $response['status'];
|
|
$payment_status = $status == 'active' ? 'succeeded' : 'failed';
|
|
$paid = $status == 'active' ? true : false;
|
|
$this->updateCustomerSubscription($status, $payment_status, $paid, $response, $event->type);
|
|
}
|
|
} else if($event->type == 'invoice.paid'){
|
|
$this->updateCustomerSubscription('active','succeeded', true, $response, $event->type);
|
|
} else if($event->type == 'invoice.payment_failed'){
|
|
$this->updateCustomerSubscription('inactive','failed', false, $response, $event->type);
|
|
} else if($event->type == 'checkout.session.completed') {
|
|
|
|
if($response->mode == 'setup'){
|
|
|
|
$checkout_session = \Stripe\Checkout\Session::retrieve([
|
|
'id' => $response->id
|
|
]);
|
|
|
|
//lets retrieve setup intent
|
|
$setup_intent = \Stripe\SetupIntent::retrieve([
|
|
'id' => $checkout_session['setup_intent']
|
|
]);
|
|
|
|
$planPrice = SubscriptionPlanPrice::where('stripe_price_id',$setup_intent['metadata']['subscription_plan_price_id'])->first();
|
|
if($planPrice){
|
|
|
|
//lets create the customer
|
|
$customer = \Stripe\Customer::create([
|
|
'name' => $setup_intent['metadata']['user_name'],
|
|
'email' => $setup_intent['metadata']['user_email'],
|
|
'payment_method' => $setup_intent['payment_method'],
|
|
'invoice_settings' => [
|
|
'default_payment_method' => $setup_intent['payment_method']
|
|
]
|
|
]);
|
|
|
|
$customer_id = $setup_intent['metadata']['user_id'];
|
|
|
|
$subscriptionData = [
|
|
'customer' => $customer['id'],
|
|
'items' => [
|
|
[
|
|
'price_data' => [
|
|
'unit_amount_decimal' => $planPrice->payment == 'monthly' ? round(($planPrice->price / $planPrice->custom_interval) * 100,2) : round($planPrice->price * 100,2),
|
|
'currency' => 'usd',
|
|
'product' => $planPrice->plan->stripe_product_id,
|
|
'recurring' => [
|
|
'interval' => $planPrice->payment == 'monthly' ? 'month' : 'year'
|
|
],
|
|
]
|
|
],
|
|
],
|
|
//'cancel_at' => Carbon::now()->addMonths($planPrice->custom_interval)->addDays($planPrice->trial_period > 0 ? $planPrice->trial_duration : 7)->timestamp,
|
|
'trial_period_days' => $planPrice->trial_period > 0 ? $planPrice->trial_duration : 7
|
|
];
|
|
|
|
|
|
if(isset($setup_intent['metadata']['coupon_id'])){
|
|
$subscriptionData['coupon'] = $setup_intent['metadata']['coupon_id'];
|
|
}
|
|
|
|
$prorate_discount = (float)$setup_intent['metadata']['prorate_discount'];
|
|
if($prorate_discount > 0){
|
|
|
|
//lets create coupon for the prorate discount
|
|
$response = \Stripe\Coupon::create([
|
|
'amount_off' => $prorate_discount * 100,
|
|
'currency' => getCurrencyCode(),
|
|
'name' => 'Prorated Discount',
|
|
'applies_to' => [
|
|
'products' => [$planPrice->plan->stripe_product_id]
|
|
],
|
|
'max_redemptions' => 1,
|
|
]);
|
|
|
|
$coupon = new SubscriptionCoupon();
|
|
$coupon->fill([
|
|
'subscription_plan_price_id' => $planPrice->id,
|
|
'stripe_coupon_id' => $response['id'],
|
|
'name' => $response['name'],
|
|
'code' => $response['id'],
|
|
'type' => 'Amount',
|
|
'applied_to' => 'subscription',
|
|
'payment_mode' => 'Monthly',
|
|
'discount' => $prorate_discount,
|
|
'duration' => 'Once',
|
|
'max_redemptions' => 1,
|
|
'active' => 1
|
|
]);
|
|
$coupon->save();
|
|
|
|
$subscriptionData['coupon'] = $response['id'];
|
|
}
|
|
|
|
$subscription = \Stripe\Subscription::create($subscriptionData);
|
|
|
|
if(isset($subscription['id'])){
|
|
|
|
$customer_subscription = new CustomerSubscription();
|
|
$customer_subscription->customer_id = $customer_id;
|
|
$customer_subscription->txn_id = $subscription['id'];
|
|
$customer_subscription->subscription_plan_price_id = $planPrice->id;
|
|
$customer_subscription->payment_mode = $planPrice->payment == 'monthly' ? 'Monthly' :'All';
|
|
$customer_subscription->paid_invoice = 0;
|
|
$customer_subscription->status = $subscription['status'];
|
|
$customer_subscription->payment_status = 'uncaptured';
|
|
$customer_subscription->is_paid = false;
|
|
$customer_subscription->next_payment_at = $planPrice->billing_type == 'Recurring' ? Carbon::createFromTimestamp($subscription['billing_cycle_anchor'])->format('Y-m-d H:i:s') : null;
|
|
$customer_subscription->expired_at = Carbon::createFromTimestamp($subscription['trial_end'])->format('Y-m-d H:i:s');
|
|
$customer_subscription->last_payment_date = Carbon::now()->format('Y-m-d');
|
|
$customer_subscription->save();
|
|
|
|
if($subscription['discount'] != null && isset($subscription['discount']['coupon'])){
|
|
|
|
$coupon = SubscriptionCoupon::where('stripe_coupon_id',$subscription['discount']['coupon']['id'])->first();
|
|
if($coupon){
|
|
|
|
$coupon_redemption = new SubscriptionCouponRedemption;
|
|
$coupon_redemption->subscription_coupon_id = $coupon->id;
|
|
$coupon_redemption->customer_id = $customer_id;
|
|
$coupon_redemption->subscription_id = $customer_subscription->id;
|
|
$coupon_redemption->save();
|
|
}
|
|
}
|
|
|
|
$user = $customer_subscription->user;
|
|
|
|
$this->sendSubscriptionPendingApproval($user, $user->company_details['storefront']);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Log::debug('Subscription Plan Price not found: '. $setup_intent['metadata']['subscription_plan_price_id']);
|
|
}
|
|
|
|
|
|
} else if($response->mode == 'subscription'){
|
|
|
|
$checkout_session = \Stripe\Checkout\Session::retrieve([
|
|
'id' => $response->id,
|
|
'expand' => ['subscription'],
|
|
]);
|
|
|
|
$planPrice = SubscriptionPlanPrice::find($checkout_session['subscription']['metadata']['subscription_plan_id']);
|
|
if($planPrice){
|
|
|
|
$subscription = \Stripe\Subscription::update($checkout_session['subscription']['id'],[
|
|
'cancel_at' => Carbon::now()->addMonths($planPrice->custom_interval)->addDays($planPrice->trial_period ? $planPrice->trial_duration : 7)->timestamp
|
|
]);
|
|
|
|
$customer_subscription = new CustomerSubscription();
|
|
$customer_subscription->customer_id = $response->client_reference_id;
|
|
$customer_subscription->txn_id = $checkout_session['subscription']['id'];
|
|
$customer_subscription->subscription_plan_price_id = $planPrice->id;
|
|
$customer_subscription->payment_mode = $planPrice->payment == 'monthly' ? 'Monthly' :'All';
|
|
$customer_subscription->paid_invoice = 1;
|
|
$customer_subscription->status = $checkout_session['subscription']['status'];
|
|
$customer_subscription->payment_status = 'uncaptured';
|
|
$customer_subscription->is_paid = false;
|
|
$customer_subscription->next_payment_at = $planPrice->billing_type == 'Recurring' ? Carbon::createFromTimestamp($checkout_session['subscription']['billing_cycle_anchor'])->format('Y-m-d H:i:s') : null;
|
|
$customer_subscription->expired_at = Carbon::createFromTimestamp($checkout_session['subscription']['trial_end'])->format('Y-m-d H:i:s');
|
|
$customer_subscription->last_payment_date = Carbon::now()->format('Y-m-d');
|
|
$customer_subscription->save();
|
|
|
|
if($checkout_session['subscription']['discount'] != null && isset($checkout_session['subscription']['discount']['coupon'])){
|
|
|
|
$coupon = SubscriptionCoupon::where('stripe_coupon_id',$checkout_session['subscription']['discount']['coupon']['id'])->first();
|
|
if($coupon){
|
|
|
|
$coupon_redemption = new SubscriptionCouponRedemption;
|
|
$coupon_redemption->subscription_coupon_id = $coupon->id;
|
|
$coupon_redemption->customer_id = $response->client_reference_id;
|
|
$coupon_redemption->subscription_id = $customer_subscription->id;
|
|
$coupon_redemption->save();
|
|
}
|
|
}
|
|
|
|
} else {
|
|
|
|
Log::debug('Subscription Plan Price not found: '. $checkout_session['subscription']['metadata']['subscription_plan_id']);
|
|
}
|
|
|
|
} else {
|
|
Log::debug('Mode is not subscription');
|
|
}
|
|
|
|
} else {
|
|
echo 'Received unknown event type ' . $event->type;
|
|
Log::debug(json_encode($response));
|
|
}
|
|
|
|
http_response_code(200);
|
|
}
|
|
|
|
public function updateCustomerSubscription($status, $payment_status, $paid, $response, $event) {
|
|
|
|
if($event == 'invoice.paid'){
|
|
|
|
$subscription = CustomerSubscription::with('planPrice')->where('txn_id',$response['subscription'])->first();
|
|
if($subscription){
|
|
|
|
Log::debug('Subscription found, event: '.$event.' id: '.$response['subscription']);
|
|
|
|
if($subscription->planPrice->billing_type == 'Recurring' && isset($response['lines']['data'][0]['period']['end'])) {
|
|
$period_end = $response['lines']['data'][0]['period']['end'];
|
|
$subscription->expired_at = Carbon::createFromTimestamp($period_end)->toDateTimeString();
|
|
$subscription->next_payment_at = Carbon::createFromTimestamp($period_end)->toDateTimeString();
|
|
$subscription->last_payment_date = Carbon::createFromTimestamp($response['effective_at'])->format('Y-m-d');
|
|
}
|
|
|
|
if(isset($response['charge']) && $response['charge'] != null){
|
|
|
|
$user_credits = UserCredit::firstOrCreate(['user_id' => $subscription->customer_id]);
|
|
if($subscription->paid_invoice == 1){
|
|
|
|
$old_subscription = CustomerSubscription::where('customer_id',$subscription->customer_id)->where('status','cancelled')->where('payment_status','cancelled')->where('paid_invoice','>',1)->latest()->first();
|
|
|
|
|
|
//for flex plan downgrade remove unused credits
|
|
if($old_subscription && $subscription->planPrice->payment == 'upfront' && $user_credits->subscription_credits > 0 ){
|
|
|
|
$before_credits = $this->customerService->credits($user_credits->user_id);
|
|
$subscription_credits = $user_credits->subscription_credits - $before_credits['total_available_credits']['subscription'];
|
|
$user_credits->subscription_credits = $subscription_credits;
|
|
$user_credits->save();
|
|
$after_credits = $this->customerService->credits($user_credits->user_id);
|
|
|
|
$user_credits_history = new UserCreditHistory;
|
|
$user_credits_history->user_id = $user_credits->user_id;
|
|
$user_credits_history->subscription_credits_from = $before_credits['total_available_credits']['subscription'];
|
|
$user_credits_history->subscription_credits_to = $after_credits['total_available_credits']['subscription'];
|
|
$user_credits_history->alacarte_credits_from = $before_credits['total_available_credits']['alacarte'];;
|
|
$user_credits_history->alacarte_credits_to = $after_credits['total_available_credits']['alacarte'];
|
|
$user_credits_history->details = 'Remove unused subscription credits because of downgrade to Flex Plan';
|
|
$user_credits_history->save();
|
|
}
|
|
|
|
if($old_subscription){
|
|
|
|
$paid_months = $old_subscription->paid_invoice;
|
|
$plan_credits = $old_subscription->planPrice->total_credits;
|
|
$months = $old_subscription->planPrice->custom_interval;
|
|
if($old_subscription->planPrice->payment == 'monthly' && $subscription->planPrice->payment == 'monthly'){
|
|
$prorate_credits = $subscription->planPrice->total_credits - (( $plan_credits / $months ) * ($months - $paid_months));
|
|
$prorate_credits = $prorate_credits >= 0 ? floor($prorate_credits) : -1 * floor(abs($prorate_credits));
|
|
|
|
$subscription_credits = $user_credits->subscription_credits + $prorate_credits;
|
|
$user_credits_history_details = 'Prorated Credits from '.$old_subscription->planPrice->plan->title.' to '.$subscription->planPrice->plan->title;
|
|
|
|
} else {
|
|
|
|
$subscription_credits = $user_credits->subscription_credits + $subscription->planPrice->total_credits;
|
|
$user_credits_history_details = 'Added Total Plan Credits of '.$subscription->planPrice->plan->title;
|
|
}
|
|
|
|
} else {
|
|
|
|
$subscription_credits = $user_credits->subscription_credits + $subscription->planPrice->total_credits;
|
|
$user_credits_history_details = 'Added Total Plan Credits of '.$subscription->planPrice->plan->title;
|
|
}
|
|
|
|
|
|
$before_credits = $this->customerService->credits($user_credits->user_id);
|
|
$user_credits->subscription_credits = $subscription_credits;
|
|
$user_credits->save();
|
|
$after_credits = $this->customerService->credits($user_credits->user_id);
|
|
|
|
$user_credits_history = new UserCreditHistory;
|
|
$user_credits_history->user_id = $user_credits->user_id;
|
|
$user_credits_history->subscription_credits_from = $before_credits['total_available_credits']['subscription'];
|
|
$user_credits_history->subscription_credits_to = $after_credits['total_available_credits']['subscription'];
|
|
$user_credits_history->alacarte_credits_from = $before_credits['total_available_credits']['alacarte'];;
|
|
$user_credits_history->alacarte_credits_to = $after_credits['total_available_credits']['alacarte'];
|
|
$user_credits_history->details = $user_credits_history_details;
|
|
$user_credits_history->save();
|
|
|
|
} else if($subscription->paid_invoice >= 1){
|
|
|
|
if($subscription->planPrice->payment == 'monthly'){
|
|
//per month
|
|
$subscription_credits = $user_credits->subscription_credits + $subscription->planPrice->per_month_credits;
|
|
$details = 'Added Monthly Credits';
|
|
} else {
|
|
//yearly
|
|
$subscription_credits = $user_credits->subscription_credits + $subscription->planPrice->total_credits;
|
|
$details = 'Added Yearly Credits';
|
|
}
|
|
|
|
$before_credits = $this->customerService->credits($user_credits->user_id);
|
|
$user_credits->subscription_credits = $subscription_credits;
|
|
$user_credits->save();
|
|
$after_credits = $this->customerService->credits($user_credits->user_id);
|
|
|
|
$user_credits_history = new UserCreditHistory;
|
|
$user_credits_history->user_id = $user_credits->user_id;
|
|
$user_credits_history->subscription_credits_from = $before_credits['total_available_credits']['subscription'];
|
|
$user_credits_history->subscription_credits_to = $after_credits['total_available_credits']['subscription'];
|
|
$user_credits_history->alacarte_credits_from = $before_credits['total_available_credits']['alacarte'];;
|
|
$user_credits_history->alacarte_credits_to = $after_credits['total_available_credits']['alacarte'];
|
|
$user_credits_history->details = $details;
|
|
$user_credits_history->save();
|
|
|
|
}
|
|
|
|
$subscription->status = $status;
|
|
$subscription->payment_status = $payment_status;
|
|
$subscription->is_paid = $paid;
|
|
|
|
if($this->stripe == null){
|
|
$credential = getPaymentInfoViaSellerId(1, 4);
|
|
$stripe = new \Stripe\StripeClient($credential->perameter_3);
|
|
$charge_response = $stripe->charges->retrieve($response['charge'], []);
|
|
} else {
|
|
$charge_response = $this->stripe->charges->retrieve($response['charge'],[]);
|
|
}
|
|
|
|
if($charge_response && isset($charge_response['amount_captured']) && isset($charge_response['receipt_url'])){
|
|
$this->sendInvoicePaid($subscription->user->email, $charge_response['amount_captured'],$charge_response['receipt_url']);
|
|
}
|
|
|
|
$subscription->approved = 1;
|
|
}
|
|
|
|
$subscription->paid_invoice++;
|
|
$subscription->save();
|
|
|
|
} else {
|
|
Log::debug('Subscription not found, event: '.$event.' id: '.$response['id']);
|
|
}
|
|
|
|
} else if($event == 'invoice.payment_failed'){
|
|
|
|
$subscription = CustomerSubscription::with('planPrice')->where('txn_id',$response['subscription'])->first();
|
|
if($subscription){
|
|
|
|
$this->sendPaymentFailed($subscription->user->email, $response['number'], $response['hosted_invoice_url']);
|
|
$this->sendPaymentFailedForSales($subscription->user->email, $response['number'], $response['hosted_invoice_url'], $response['amount_due']);
|
|
|
|
if($this->stripe == null){
|
|
$credential = getPaymentInfoViaSellerId(1, 4);
|
|
$stripe = new \Stripe\StripeClient($credential->perameter_3);
|
|
$charge_response = $stripe->charges->retrieve($response['charge'], []);
|
|
} else {
|
|
$charge_response = $this->stripe->charges->retrieve($response['charge'],[]);
|
|
}
|
|
|
|
if($charge_response && isset($charge_response['failure_message'])){
|
|
$subscription->message = $charge_response['failure_message'];
|
|
}
|
|
|
|
$subscription->status = $status;
|
|
$subscription->payment_status = $payment_status;
|
|
$subscription->is_paid = $paid;
|
|
$subscription->save();
|
|
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$subscription = CustomerSubscription::with('planPrice')->where('txn_id',$response['id'])->first();
|
|
if($subscription){
|
|
|
|
if($subscription->planPrice->billing_type == 'Recurring' && isset($response['current_period_end'])) {
|
|
$period_end = $response['current_period_end'];
|
|
$subscription->expired_at = Carbon::createFromTimestamp($period_end)->toDateTimeString();
|
|
$subscription->next_payment_at = Carbon::createFromTimestamp($period_end)->toDateTimeString();
|
|
$subscription->last_payment_date = Carbon::createFromTimestamp($response['effective_at'])->format('Y-m-d');
|
|
}
|
|
|
|
$subscription->status = $status;
|
|
$subscription->payment_status = $payment_status;
|
|
$subscription->is_paid = $paid;
|
|
$subscription->save();
|
|
|
|
if($event == 'customer.subscription.deleted'){
|
|
|
|
$this->sendSubscriptionCancelled($subscription->user->email, $subscription->planPrice->plan->title);
|
|
$this->sendSubscriptionCancelledForSales($subscription->user->email, $subscription->planPrice->plan->title);
|
|
|
|
} else if($event == 'customer.subscription.updated'){
|
|
|
|
if($subscription->discount == null && isset($response['discount']) && $response['discount'] != null){
|
|
|
|
$coupon_data = $response['discount']['coupon'];
|
|
$coupon = SubscriptionCoupon::firstOrCreate(
|
|
[
|
|
'stripe_coupon_id' => $coupon_data['id']
|
|
],
|
|
[
|
|
'subscription_plan_price_id' => [$subscription->planPrice->id],
|
|
'name' => $coupon_data['name'],
|
|
'code' => $coupon_data['id'],
|
|
'type' => $coupon_data['percent_off'] != null ? 'Percentage' : 'Amount',
|
|
'applied_to' => 'subscription',
|
|
'payment_mode' => 'Monthly',
|
|
'discount' => $coupon_data['percent_off'] != null ? $coupon_data['percent_off'] : $coupon_data['amount_off'] / 100,
|
|
'duration' => ucfirst($coupon_data['duration']),
|
|
'max_redemptions' => $coupon_data['max_redemptions']
|
|
]
|
|
);
|
|
|
|
$coupon_redemption = new SubscriptionCouponRedemption;
|
|
$coupon_redemption->subscription_coupon_id = $coupon->id;
|
|
$coupon_redemption->customer_id = $subscription->customer_id;
|
|
$coupon_redemption->subscription_id = $subscription->id;
|
|
$coupon_redemption->save();
|
|
}
|
|
}
|
|
|
|
} else {
|
|
Log::debug('Subscription not found, event: '.$event.' id: '.$response['id']);
|
|
}
|
|
}
|
|
}
|
|
}
|