Failed Conditions
Pull Request — master (#48)
by Rafael
05:06
created

handleCustomerSubscriptionTrialwillend()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.8846

Importance

Changes 0
Metric Value
cc 3
eloc 13
nc 3
nop 1
dl 0
loc 21
ccs 7
cts 13
cp 0.5385
crap 3.8846
rs 9.8333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gewaer\Api\Controllers;
6
7
use Phalcon\Http\Response;
8
use Gewaer\Models\Users;
9
use Carbon\Carbon;
10
use Gewaer\Exception\NotFoundHttpException;
11
use Gewaer\Traits\EmailTrait;
12
use Datetime;
13
14
/**
15
 * Class PaymentsController
16
 *
17
 * Class to handle payment webhook from our cashier library
18
 *
19
 * @package Gewaer\Api\Controllers
20
 *
21
 */
22
class PaymentsController extends BaseController
23
{
24
    /**
25
     * Handle stripe webhoook calls
26
     *
27
     * @return Response
28
     */
29 4
    public function handleWebhook(): Response
30
    {
31
        //we cant processs if we dont find the stripe header
32 4
        if (!defined('API_TESTS')) {
33
            if (!$this->request->hasHeader('Stripe-Signature')) {
34
                throw new NotFoundHttpException('Route not found for this call');
35
            }
36
        }
37
38 4
        $request = $this->request->getPost();
39
40 4
        if (empty($request)) {
41
            $request = $this->request->getJsonRawBody(true);
42
        }
43 4
        $type = str_replace('.', '', ucwords(str_replace('_', '', $request['type']), '.'));
44 4
        $method = 'handle' . $type;
45 4
        if (method_exists($this, $method)) {
46 4
            return $this->{$method}($request);
47
        } else {
48
            return $this->response(['Missing Method to Handled']);
49
        }
50
    }
51
52
    /**
53
     * Handle customer subscription updated.
54
     *
55
     * @param  array $payload
56
     * @return Response
57
     */
58
    protected function handleCustomerSubscriptionUpdated(array $payload): Response
59
    {
60
        $user = Users::findFirstByStripeId($payload['data']['object']['customer']);
61
        if ($user) {
62
            $data = $payload['data']['object'];
63
            //get the current subscription they are updating
64
            $subscription = $user->getAllSubscriptions('stripe_id =' . $data['id']);
65
66
            if (is_object($subscription)) {
67
                // Quantity...
68
                if (isset($data['quantity'])) {
69
                    $subscription->quantity = $data['quantity'];
70
                }
71
                // Plan...
72
                if (isset($data['plan']['id'])) {
73
                    $subscription->stripe_plan = $data['plan']['id'];
74
                }
75
                // Trial ending date...
76
                if (isset($data['trial_end'])) {
77
                    $trial_ends = Carbon::createFromTimestamp($data['trial_end']);
78
                    if (!$subscription->trial_ends_at || $subscription->trial_ends_at->ne($trial_ends)) {
79
                        $subscription->trial_ends_at = $trial_ends;
80
                    }
81
                }
82
                // Cancellation date...
83
                if (isset($data['cancel_at_period_end']) && $data['cancel_at_period_end']) {
84
                    $subscription->ends_at = $subscription->onTrial()
85
                        ? $subscription->trial_ends_at
86
                        : Carbon::createFromTimestamp($data['current_period_end']);
87
                }
88
89
                if ($subscription->update()) {
90
                    $subject = "{$user->firstname} {$user->lastname} Updated Subscription";
91
                    $content = "Dear user {$user->firstname} {$user->lastname}, your subscription has been updated.";
92
93
                    $template = [
94
                        'subject' => $subject,
95
                        'content' => $content
96
                    ];
97
                    //We need to send a mail to the user
98
                    if (!defined('API_TESTS')) {
99
                        EmailTrait::sendWebhookEmail($user->email, $template);
100
                    }
101
                }
102
            }
103
        }
104
        return $this->response(['Webhook Handled']);
105
    }
106
107
    /**
108
     * Handle a cancelled customer from a Stripe subscription.
109
     *
110
     * @param  array  $payload
111
     * @return Response
112
     */
113
    protected function handleCustomerSubscriptionDeleted(array $payload): Response
114
    {
115
        $user = Users::findFirstByStripeId($payload['data']['object']['customer']);
116
        if ($user) {
117
            $subscription = $user->getAllSubscriptions('stripe_id =' . $payload['data']['object']['id']);
118
119
            if (is_object($subscription)) {
120
                $subscription->markAsCancelled();
121
            }
122
        }
123
        return $this->response(['Webhook Handled']);
124
    }
125
126
    /**
127
     * Handle customer subscription free trial ending.
128
     *
129
     * @param  array $payload
130
     * @return Response
131
     */
132 1
    protected function handleCustomerSubscriptionTrialwillend(array $payload): Response
133
    {
134 1
        $trialEndDate = new Datetime();
135 1
        $trialEndDate->setTimestamp((int)$payload['data']['object']['trial_end']);
136 1
        $formatedEndDate = $trialEndDate->format('Y-m-d H:i:s');
137
138 1
        $user = Users::findFirstByStripeId($payload['data']['object']['customer']);
139 1
        if ($user) {
140
            $subject = "{$user->firstname} {$user->lastname} Free Trial Ending";
141
            $content = "Dear user {$user->firstname} {$user->lastname}, your free trial is coming to an end on {$formatedEndDate}.Please choose one of our available subscriptions. Thank you";
142
143
            $template = [
144
                'subject' => $subject,
145
                'content' => $content
146
            ];
147
            //We need to send a mail to the user
148
            if (!defined('API_TESTS')) {
149
                EmailTrait::sendWebhookEmail($user->email, $template);
150
            }
151
        }
152 1
        return $this->response(['Webhook Handled']);
153
    }
154
155
    /**
156
     * Handle customer updated.
157
     *
158
     * @param  array $payload
159
     * @return Response
160
     */
161
    protected function handleCustomerUpdated(array $payload): Response
162
    {
163
        if ($user = Users::findFirstByStripeId($payload['data']['object']['id'])) {
164
            $user->updateCardFromStripe();
165
        }
166
        return $this->response(['Webhook Handled']);
167
    }
168
169
    /**
170
     * Handle customer source deleted.
171
     *
172
     * @param  array $payload
173
     * @return Response
174
     */
175
    protected function handleCustomerSourceDeleted(array $payload) : Response
176
    {
177
        if ($user = Users::findFirstByStripeId($payload['data']['object']['customer'])) {
178
            $user->updateCardFromStripe();
179
        }
180
        return $this->response(['Webhook Handled']);
181
    }
182
183
    /**
184
     * Handle deleted customer.
185
     *
186
     * @param  array $payload
187
     * @return Response
188
     */
189
    protected function handleCustomerDeleted(array $payload) : Response
190
    {
191
        $user = Users::findFirstByStripeId($payload['data']['object']['id']);
192
        if ($user) {
193
            foreach ($user->subscriptions as $subscription) {
194
                $subscription->skipTrial()->markAsCancelled();
195
            }
196
197
            $user->stripe_id = null;
198
            $user->trial_ends_at = null;
199
            $user->card_brand = null;
200
            $user->card_last_four = null;
201
            $user->update();
202
        }
203
        return $this->response(['Webhook Handled']);
204
    }
205
206
    /**
207
     * Handle sucessfull payment
208
     *
209
     * @todo send email
210
     * @param array $payload
211
     * @return Response
212
     */
213 1
    protected function handleChargeSucceeded(array $payload): Response
214
    {
215 1
        $user = Users::findFirstByStripeId($payload['data']['object']['customer']);
216 1
        if ($user) {
217
            $subject = "{$user->firstname} {$user->lastname} Successful Payment";
218
            $content = "Dear user {$user->firstname} {$user->lastname}, your subscription payment of {$payload['data']['object']['amount']} was successful. Thank you";
219
220
            $template = [
221
                'subject' => $subject,
222
                'content' => $content
223
            ];
224
            //We need to send a mail to the user
225
            if (!defined('API_TESTS')) {
226
                EmailTrait::sendWebhookEmail($user->email, $template);
227
            }
228
        }
229 1
        return $this->response(['Webhook Handled']);
230
    }
231
232
    /**
233
     * Handle bad payment
234
     *
235
     * @todo send email
236
     * @param array $payload
237
     * @return Response
238
     */
239 1
    protected function handleChargeFailed(array $payload) : Response
240
    {
241 1
        $user = Users::findFirstByStripeId($payload['data']['object']['customer']);
242 1
        if ($user) {
243
            $subject = "{$user->firstname} {$user->lastname} Failed Payment";
244
            $content = "Dear user {$user->firstname} {$user->lastname}, your subscription presents a failed payment of the amount of {$payload['data']['object']['amount']}. Please check card expiration date";
245
246
            $template = [
247
                'subject' => $subject,
248
                'content' => $content
249
            ];
250
            //We need to send a mail to the user
251
            if (!defined('API_TESTS')) {
252
                EmailTrait::sendWebhookEmail($user->email, $template);
253
            }
254
        }
255 1
        return $this->response(['Webhook Handled']);
256
    }
257
258
    /**
259
     * Handle looking for refund
260
     *
261
     * @todo send email
262
     * @param array $payload
263
     * @return Response
264
     */
265
    protected function handleChargeDisputeCreated(array $payload) : Response
266
    {
267
        return $this->response(['Webhook Handled']);
268
    }
269
270
    /**
271
     * Handle pending payments
272
     *
273
     * @todo send email
274
     * @param array $payload
275
     * @return Response
276
     */
277 1
    protected function handleChargePending(array $payload) : Response
278
    {
279 1
        $user = Users::findFirstByStripeId($payload['data']['object']['customer']);
280 1
        if ($user) {
281
            $subject = "{$user->firstname} {$user->lastname} Pending Payment";
282
            $content = "Dear user {$user->firstname} {$user->lastname}, your subscription presents a pending payment of {$payload['data']['object']['amount']}";
283
284
            $template = [
285
                'subject' => $subject,
286
                'content' => $content
287
            ];
288
            //We need to send a mail to the user
289
            if (!defined('API_TESTS')) {
290
                EmailTrait::sendWebhookEmail($user->email, $template);
291
            }
292
        }
293 1
        return $this->response(['Webhook Handled']);
294
    }
295
}
296