Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
<?php
use CRM_Stripe_ExtensionUtil as E;
class CRM_Stripe_Webhook {
use CRM_Stripe_Webhook_Trait;
/**
* Checks whether the payment processors have a correctly configured
* webhook (we may want to check the test processors too, at some point, but
* for now, avoid having false alerts that will annoy people).
*
* @see stripe_civicrm_check()
*/
public static function check() {
$result = civicrm_api3('PaymentProcessor', 'get', [
'class_name' => 'Payment_Stripe',
'is_active' => 1,
]);
foreach ($result['values'] as $paymentProcessor) {
$webhook_path = self::getWebhookPath(TRUE, $paymentProcessor['id']);
\Stripe::setApiKey(CRM_Core_Payment_Stripe::getSecretKey($paymentProcessor));
try {
$webhooks = \Stripe\WebhookEndpoint::all(["limit" => 100]);
}
catch (Exception $e) {
$error = $e->getMessage();
$messages[] = new CRM_Utils_Check_Message(
'stripe_webhook',
E::ts('The %1 (%2) Payment Processor has an error: %3', [
1 => $paymentProcessor['name'],
2 => $paymentProcessor['id'],
3 => $error,
]),
E::ts('Stripe - API Key'),
\Psr\Log\LogLevel::ERROR,
'fa-money'
);
continue;
}
$found_wh = FALSE;
foreach ($webhooks->data as $wh) {
if ($wh->url == $webhook_path) {
$found_wh = TRUE;
// Check and update webhook
self::checkAndUpdateWebhook($wh);
}
}
if (!$found_wh) {
try {
self::createWebhook($paymentProcessor['id']);
}
catch (Exception $e) {
$messages[] = new CRM_Utils_Check_Message(
'stripe_webhook',
E::ts('Could not create webhook. You can review from your Stripe account, under Developers > Webhooks.<br/>The webhook URL is: %3', [
1 => $paymentProcessor['name'],
2 => $paymentProcessor['id'],
3 => urldecode($webhook_path),
]) . '.<br/>Error from Stripe: <em>' . $e->getMessage() . '</em>',
E::ts('Stripe Webhook: %1 (%2)', [
1 => $paymentProcessor['name'],
2 => $paymentProcessor['id'],
]
),
\Psr\Log\LogLevel::WARNING,
'fa-money'
);
}
}
}
return $messages;
}
/**
* Create a new webhook for payment processor
*
* @param int $paymentProcessorId
*/
public static function createWebhook($paymentProcessorId) {
\Stripe\Stripe::setApiKey(CRM_Core_Payment_Stripe::getSecretKeyById($paymentProcessorId));
$params = [
'enabled_events' => self::getDefaultEnabledEvents(),
'url' => self::getWebhookPath(TRUE, $paymentProcessorId),
'api_version' => CRM_Core_Payment_Stripe::getApiVersion(),
'connect' => FALSE,
];
\Stripe\WebhookEndpoint::create($params);
}
/**
* Check and update existing webhook
*
* @param array $webhook
*/
public static function checkAndUpdateWebhook($webhook) {
$update = FALSE;
if ($webhook['api_version'] !== CRM_Core_Payment_Stripe::API_VERSION) {
$update = TRUE;
$params['api_version'] = CRM_Core_Payment_Stripe::API_VERSION;
}
if (array_diff(self::getDefaultEnabledEvents(), $webhook['enabled_events'])) {
$update = TRUE;
$params['enabled_events'] = self::getDefaultEnabledEvents();
}
if ($update) {
\Stripe\WebhookEndpoint::update($webhook['id'], $params);
}
}
/**
* List of webhooks we currently handle
* @return array
*/
public static function getDefaultEnabledEvents() {
return [
'invoice.payment_succeeded',
'invoice.payment_failed',
'charge.failed',
'charge.refunded',
'charge.succeeded',
'customer.subscription.updated',
'customer.subscription.deleted',
];
}
}