|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* Give - Stripe Core Helpers |
|
4
|
|
|
* |
|
5
|
|
|
* @since 2.5.0 |
|
6
|
|
|
* |
|
7
|
|
|
* @package Give |
|
8
|
|
|
* @subpackage Stripe Core |
|
9
|
|
|
* @copyright Copyright (c) 2019, GiveWP |
|
10
|
|
|
* @license https://opensource.org/licenses/gpl-license GNU Public License |
|
11
|
|
|
*/ |
|
12
|
|
|
|
|
13
|
|
|
// Exit, if accessed directly. |
|
14
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
|
15
|
|
|
exit; |
|
16
|
|
|
} |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* This function is used to fetch the secret key based on the test mode status. |
|
20
|
|
|
* |
|
21
|
|
|
* @since 2.5.0 |
|
22
|
|
|
* |
|
23
|
|
|
* @return string |
|
24
|
|
|
*/ |
|
25
|
|
|
function give_stripe_get_secret_key() { |
|
26
|
|
|
|
|
27
|
|
|
$secret_key = trim( give_get_option( 'live_secret_key' ) ); |
|
28
|
|
|
|
|
29
|
|
|
// Update secret key, if test mode is enabled. |
|
30
|
|
|
if ( give_is_test_mode() ) { |
|
31
|
|
|
$secret_key = trim( give_get_option( 'test_secret_key' ) ); |
|
32
|
|
|
} |
|
33
|
|
|
|
|
34
|
|
|
return $secret_key; |
|
35
|
|
|
} |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* Is Stripe Checkout Enabled? |
|
39
|
|
|
* |
|
40
|
|
|
* @since 2.5.0 |
|
41
|
|
|
* |
|
42
|
|
|
* @return bool |
|
43
|
|
|
*/ |
|
44
|
|
|
function give_stripe_is_checkout_enabled() { |
|
45
|
|
|
return give_is_setting_enabled( give_get_option( 'stripe_checkout_enabled', 'disabled' ) ); |
|
46
|
|
|
} |
|
47
|
|
|
|
|
48
|
|
|
/** |
|
49
|
|
|
* Get Settings for the Stripe account connected via Connect API. |
|
50
|
|
|
* |
|
51
|
|
|
* @since 2.5.0 |
|
52
|
|
|
* |
|
53
|
|
|
* @return mixed |
|
54
|
|
|
*/ |
|
55
|
|
|
function give_stripe_get_connect_settings() { |
|
56
|
|
|
|
|
57
|
|
|
$options = array( |
|
58
|
|
|
'connected_status' => give_get_option( 'give_stripe_connected' ), |
|
59
|
|
|
'user_id' => give_get_option( 'give_stripe_user_id' ), |
|
60
|
|
|
'access_token' => give_get_option( 'live_secret_key' ), |
|
61
|
|
|
'access_token_test' => give_get_option( 'test_secret_key' ), |
|
62
|
|
|
'publishable_key' => give_get_option( 'live_publishable_key' ), |
|
63
|
|
|
'publishable_key_test' => give_get_option( 'test_publishable_key' ), |
|
64
|
|
|
); |
|
65
|
|
|
|
|
66
|
|
|
/** |
|
67
|
|
|
* This filter hook is used to override the existing stripe connect settings stored in DB. |
|
68
|
|
|
* |
|
69
|
|
|
* @param array $options List of Stripe Connect settings required to make functionality work. |
|
70
|
|
|
* |
|
71
|
|
|
* @since 2.5.0 |
|
72
|
|
|
*/ |
|
73
|
|
|
return apply_filters( 'give_stripe_get_connect_settings', $options ); |
|
74
|
|
|
} |
|
75
|
|
|
|
|
76
|
|
|
/** |
|
77
|
|
|
* Is Stripe connected using Connect API? |
|
78
|
|
|
* |
|
79
|
|
|
* @since 2.5.0 |
|
80
|
|
|
* |
|
81
|
|
|
* @return bool |
|
82
|
|
|
*/ |
|
83
|
|
|
function give_stripe_is_connected() { |
|
84
|
|
|
|
|
85
|
|
|
$settings = give_stripe_get_connect_settings(); |
|
86
|
|
|
|
|
87
|
|
|
$user_api_keys_enabled = give_is_setting_enabled( give_get_option( 'stripe_user_api_keys' ) ); |
|
88
|
|
|
|
|
89
|
|
|
// Return false, if manual API keys are used to configure Stripe. |
|
90
|
|
|
if ( $user_api_keys_enabled ) { |
|
91
|
|
|
return false; |
|
92
|
|
|
} |
|
93
|
|
|
|
|
94
|
|
|
// Check all the necessary options. |
|
95
|
|
|
if ( |
|
96
|
|
|
! empty( $settings['connected_status'] ) && '1' === $settings['connected_status'] |
|
97
|
|
|
&& ! empty( $settings['user_id'] ) |
|
98
|
|
|
&& ! empty( $settings['access_token'] ) |
|
99
|
|
|
&& ! empty( $settings['access_token_test'] ) |
|
100
|
|
|
&& ! empty( $settings['publishable_key'] ) |
|
101
|
|
|
&& ! empty( $settings['publishable_key_test'] ) |
|
102
|
|
|
) { |
|
103
|
|
|
return true; |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
// Default return value. |
|
107
|
|
|
return false; |
|
108
|
|
|
} |
|
109
|
|
|
|
|
110
|
|
|
/** |
|
111
|
|
|
* This function will return connected account options. |
|
112
|
|
|
* |
|
113
|
|
|
* @since 2.5.0 |
|
114
|
|
|
* |
|
115
|
|
|
* @return array |
|
116
|
|
|
*/ |
|
117
|
|
|
function give_stripe_get_connected_account_options() { |
|
118
|
|
|
|
|
119
|
|
|
$args = array(); |
|
120
|
|
|
|
|
121
|
|
|
if ( give_stripe_is_connected() ) { |
|
122
|
|
|
$args['stripe_account'] = give_get_option( 'give_stripe_user_id' ); |
|
123
|
|
|
} |
|
124
|
|
|
|
|
125
|
|
|
return $args; |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
/** |
|
129
|
|
|
* Displays Stripe Connect Button. |
|
130
|
|
|
* |
|
131
|
|
|
* @since 2.5.0 |
|
132
|
|
|
* |
|
133
|
|
|
* @return string |
|
134
|
|
|
*/ |
|
135
|
|
|
function give_stripe_connect_button() { |
|
136
|
|
|
|
|
137
|
|
|
$connected = give_get_option( 'give_stripe_connected' ); |
|
138
|
|
|
|
|
139
|
|
|
// Prepare Stripe Connect URL. |
|
140
|
|
|
$link = add_query_arg( |
|
141
|
|
|
array( |
|
142
|
|
|
'stripe_action' => 'connect', |
|
143
|
|
|
'mode' => give_is_test_mode() ? 'test' : 'live', |
|
144
|
|
|
'return_url' => rawurlencode( admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=gateways§ion=stripe-settings' ) ), |
|
145
|
|
|
'website_url' => get_bloginfo( 'url' ), |
|
146
|
|
|
'give_stripe_connected' => ! empty( $connected ) ? '1' : '0', |
|
147
|
|
|
), |
|
148
|
|
|
esc_url_raw( 'https://connect.givewp.com/stripe/connect.php' ) |
|
149
|
|
|
); |
|
150
|
|
|
|
|
151
|
|
|
return sprintf( |
|
152
|
|
|
'<a href="%1$s" id="give-stripe-connect"><span>%2$s</span></a>', |
|
153
|
|
|
esc_url( $link ), |
|
154
|
|
|
esc_html__( 'Connect with Stripe', 'give' ) |
|
155
|
|
|
); |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* Stripe Disconnect URL. |
|
160
|
|
|
* |
|
161
|
|
|
* @since 2.5.0 |
|
162
|
|
|
* |
|
163
|
|
|
* @return void |
|
164
|
|
|
*/ |
|
165
|
|
|
function give_stripe_disconnect_url() { |
|
166
|
|
|
|
|
167
|
|
|
// Prepare Stripe Disconnect URL. |
|
168
|
|
|
$link = add_query_arg( |
|
169
|
|
|
array( |
|
170
|
|
|
'stripe_action' => 'disconnect', |
|
171
|
|
|
'mode' => give_is_test_mode() ? 'test' : 'live', |
|
172
|
|
|
'stripe_user_id' => give_get_option( 'give_stripe_user_id' ), |
|
173
|
|
|
'return_url' => rawurlencode( admin_url( 'edit.php?post_type=give_forms&page=give-settings&tab=gateways§ion=stripe-settings' ) ), |
|
174
|
|
|
), |
|
175
|
|
|
esc_url_raw( 'https://connect.givewp.com/stripe/connect.php' ) |
|
176
|
|
|
); |
|
177
|
|
|
|
|
178
|
|
|
echo esc_url( $link ); |
|
179
|
|
|
} |
|
180
|
|
|
|
|
181
|
|
|
/** |
|
182
|
|
|
* Get Publishable Key. |
|
183
|
|
|
* |
|
184
|
|
|
* @since 2.5.0 |
|
185
|
|
|
* |
|
186
|
|
|
* @return string |
|
187
|
|
|
*/ |
|
188
|
|
|
function give_stripe_get_publishable_key() { |
|
189
|
|
|
|
|
190
|
|
|
$publishable_key = give_get_option( 'live_publishable_key' ); |
|
191
|
|
|
|
|
192
|
|
|
if ( give_is_test_mode() ) { |
|
193
|
|
|
$publishable_key = give_get_option( 'test_publishable_key' ); |
|
194
|
|
|
} |
|
195
|
|
|
|
|
196
|
|
|
return $publishable_key; |
|
197
|
|
|
} |
|
198
|
|
|
|
|
199
|
|
|
/** |
|
200
|
|
|
* Delete all the Give settings options for Stripe Connect. |
|
201
|
|
|
* |
|
202
|
|
|
* @since 2.5.0 |
|
203
|
|
|
* |
|
204
|
|
|
* @return void |
|
205
|
|
|
*/ |
|
206
|
|
|
function give_stripe_connect_delete_options() { |
|
207
|
|
|
|
|
208
|
|
|
// Disconnection successful. |
|
209
|
|
|
// Remove the connect options within the db. |
|
210
|
|
|
give_delete_option( 'give_stripe_connected' ); |
|
211
|
|
|
give_delete_option( 'give_stripe_user_id' ); |
|
212
|
|
|
give_delete_option( 'live_secret_key' ); |
|
213
|
|
|
give_delete_option( 'test_secret_key' ); |
|
214
|
|
|
give_delete_option( 'live_publishable_key' ); |
|
215
|
|
|
give_delete_option( 'test_publishable_key' ); |
|
216
|
|
|
give_delete_option( "give_stripe_is_live_webhook_exists" ); |
|
217
|
|
|
give_delete_option( "give_stripe_is_test_webhook_exists" ); |
|
218
|
|
|
give_delete_option( "give_stripe_live_webhook_id" ); |
|
219
|
|
|
give_delete_option( "give_stripe_test_webhook_id" ); |
|
220
|
|
|
} |
|
221
|
|
|
|
|
222
|
|
|
/** |
|
223
|
|
|
* This function will prepare JSON for default base styles. |
|
224
|
|
|
* |
|
225
|
|
|
* @since 2.5.0 |
|
226
|
|
|
* |
|
227
|
|
|
* @return mixed|string |
|
228
|
|
|
*/ |
|
229
|
|
|
function give_stripe_get_default_base_styles() { |
|
230
|
|
|
|
|
231
|
|
|
$float_labels = give_is_float_labels_enabled( |
|
232
|
|
|
array( |
|
233
|
|
|
'form_id' => get_the_ID(), |
|
234
|
|
|
) |
|
235
|
|
|
); |
|
236
|
|
|
|
|
237
|
|
|
return wp_json_encode( |
|
238
|
|
|
array( |
|
239
|
|
|
'color' => '#32325D', |
|
240
|
|
|
'fontWeight' => 500, |
|
241
|
|
|
'fontSize' => '16px', |
|
242
|
|
|
'fontSmoothing' => 'antialiased', |
|
243
|
|
|
'::placeholder' => array( |
|
244
|
|
|
'color' => $float_labels ? '#CCCCCC' : '#222222', |
|
245
|
|
|
), |
|
246
|
|
|
':-webkit-autofill' => array( |
|
247
|
|
|
'color' => '#e39f48', |
|
248
|
|
|
), |
|
249
|
|
|
) |
|
250
|
|
|
); |
|
251
|
|
|
} |
|
252
|
|
|
|
|
253
|
|
|
/** |
|
254
|
|
|
* This function is used to get the stripe styles. |
|
255
|
|
|
* |
|
256
|
|
|
* @since 2.5.0 |
|
257
|
|
|
* |
|
258
|
|
|
* @return mixed |
|
259
|
|
|
*/ |
|
260
|
|
|
function give_stripe_get_stripe_styles() { |
|
261
|
|
|
|
|
262
|
|
|
$default_styles = array( |
|
263
|
|
|
'base' => give_stripe_get_default_base_styles(), |
|
264
|
|
|
'empty' => false, |
|
265
|
|
|
'invalid' => false, |
|
266
|
|
|
'complete' => false, |
|
267
|
|
|
); |
|
268
|
|
|
|
|
269
|
|
|
return give_get_option( 'stripe_styles', $default_styles ); |
|
|
|
|
|
|
270
|
|
|
} |
|
271
|
|
|
|
|
272
|
|
|
/** |
|
273
|
|
|
* Get Base Styles for Stripe Elements CC Fields. |
|
274
|
|
|
* |
|
275
|
|
|
* @since 2.5.0 |
|
276
|
|
|
* |
|
277
|
|
|
* @return object |
|
278
|
|
|
*/ |
|
279
|
|
|
function give_stripe_get_element_base_styles() { |
|
280
|
|
|
|
|
281
|
|
|
$stripe_styles = give_stripe_get_stripe_styles(); |
|
282
|
|
|
$base_styles = json_decode( $stripe_styles['base'] ); |
|
283
|
|
|
|
|
284
|
|
|
return (object) apply_filters( 'give_stripe_get_element_base_styles', $base_styles ); |
|
285
|
|
|
} |
|
286
|
|
|
|
|
287
|
|
|
/** |
|
288
|
|
|
* Get Complete Styles for Stripe Elements CC Fields. |
|
289
|
|
|
* |
|
290
|
|
|
* @since 2.5.0 |
|
291
|
|
|
* |
|
292
|
|
|
* @return object |
|
293
|
|
|
*/ |
|
294
|
|
|
function give_stripe_get_element_complete_styles() { |
|
295
|
|
|
|
|
296
|
|
|
$stripe_styles = give_stripe_get_stripe_styles(); |
|
297
|
|
|
$complete_styles = json_decode( $stripe_styles['complete'] ); |
|
298
|
|
|
|
|
299
|
|
|
return (object) apply_filters( 'give_stripe_get_element_complete_styles', $complete_styles ); |
|
300
|
|
|
} |
|
301
|
|
|
|
|
302
|
|
|
/** |
|
303
|
|
|
* Get Invalid Styles for Stripe Elements CC Fields. |
|
304
|
|
|
* |
|
305
|
|
|
* @since 2.5.0 |
|
306
|
|
|
* |
|
307
|
|
|
* @return object |
|
308
|
|
|
*/ |
|
309
|
|
|
function give_stripe_get_element_invalid_styles() { |
|
310
|
|
|
|
|
311
|
|
|
$stripe_styles = give_stripe_get_stripe_styles(); |
|
312
|
|
|
$invalid_styles = json_decode( $stripe_styles['invalid'] ); |
|
313
|
|
|
|
|
314
|
|
|
return (object) apply_filters( 'give_stripe_get_element_invalid_styles', $invalid_styles ); |
|
315
|
|
|
} |
|
316
|
|
|
|
|
317
|
|
|
/** |
|
318
|
|
|
* Get Empty Styles for Stripe Elements CC Fields. |
|
319
|
|
|
* |
|
320
|
|
|
* @since 2.5.0 |
|
321
|
|
|
* |
|
322
|
|
|
* @return object |
|
323
|
|
|
*/ |
|
324
|
|
|
function give_stripe_get_element_empty_styles() { |
|
325
|
|
|
|
|
326
|
|
|
$stripe_styles = give_stripe_get_stripe_styles(); |
|
327
|
|
|
$empty_styles = json_decode( $stripe_styles['empty'] ); |
|
328
|
|
|
|
|
329
|
|
|
return (object) apply_filters( 'give_stripe_get_element_empty_styles', $empty_styles ); |
|
330
|
|
|
} |
|
331
|
|
|
|
|
332
|
|
|
/** |
|
333
|
|
|
* Get Stripe Element Font Styles. |
|
334
|
|
|
* |
|
335
|
|
|
* @since 2.5.0 |
|
336
|
|
|
* |
|
337
|
|
|
* @return string |
|
338
|
|
|
*/ |
|
339
|
|
|
function give_stripe_get_element_font_styles() { |
|
340
|
|
|
|
|
341
|
|
|
$font_styles = ''; |
|
|
|
|
|
|
342
|
|
|
$stripe_fonts = give_get_option( 'stripe_fonts', 'google_fonts' ); |
|
343
|
|
|
|
|
344
|
|
|
if ( 'custom_fonts' === $stripe_fonts ) { |
|
345
|
|
|
$custom_fonts_attributes = give_get_option( 'stripe_custom_fonts' ); |
|
346
|
|
|
$font_styles = json_decode( $custom_fonts_attributes ); |
|
347
|
|
|
} else { |
|
348
|
|
|
$font_styles = array( |
|
349
|
|
|
'cssSrc' => give_get_option( 'stripe_google_fonts_url' ), |
|
350
|
|
|
); |
|
351
|
|
|
} |
|
352
|
|
|
|
|
353
|
|
|
if ( empty( $font_styles ) ) { |
|
354
|
|
|
$font_styles = array(); |
|
355
|
|
|
} |
|
356
|
|
|
|
|
357
|
|
|
return apply_filters( 'give_stripe_get_element_font_styles', $font_styles ); |
|
358
|
|
|
|
|
359
|
|
|
} |
|
360
|
|
|
|
|
361
|
|
|
/** |
|
362
|
|
|
* Get Preferred Locale based on the selection of language. |
|
363
|
|
|
* |
|
364
|
|
|
* @since 2.5.0 |
|
365
|
|
|
* |
|
366
|
|
|
* @return string |
|
367
|
|
|
*/ |
|
368
|
|
|
function give_stripe_get_preferred_locale() { |
|
369
|
|
|
|
|
370
|
|
|
$language_code = substr( get_locale(), 0, 2 ); // Get the lowercase language code. For Example, en, es, de. |
|
371
|
|
|
|
|
372
|
|
|
// Return "no" as accepted parameter for norwegian language code "nb" && "nn". |
|
373
|
|
|
$language_code = in_array( $language_code, array( 'nb', 'nn' ), true ) ? 'no' : $language_code; |
|
374
|
|
|
|
|
375
|
|
|
return apply_filters( 'give_stripe_elements_preferred_locale', $language_code ); |
|
376
|
|
|
} |
|
377
|
|
|
|
|
378
|
|
|
/** |
|
379
|
|
|
* Look up the stripe customer id in user meta, and look to recurring if not found yet. |
|
380
|
|
|
* |
|
381
|
|
|
* @since 2.5.0 |
|
382
|
|
|
* |
|
383
|
|
|
* @param int $user_id_or_email The user ID or email to look up. |
|
384
|
|
|
* |
|
385
|
|
|
* @return string Stripe customer ID. |
|
386
|
|
|
*/ |
|
387
|
|
|
function give_stripe_get_customer_id( $user_id_or_email ) { |
|
388
|
|
|
|
|
389
|
|
|
$user_id = 0; |
|
390
|
|
|
$stripe_customer_id = ''; |
|
391
|
|
|
|
|
392
|
|
|
// First check the customer meta of purchase email. |
|
393
|
|
View Code Duplication |
if ( class_exists( 'Give_DB_Donor_Meta' ) && is_email( $user_id_or_email ) ) { |
|
|
|
|
|
|
394
|
|
|
$donor = new Give_Donor( $user_id_or_email ); |
|
395
|
|
|
$stripe_customer_id = $donor->get_meta( give_stripe_get_customer_key() ); |
|
396
|
|
|
} |
|
397
|
|
|
|
|
398
|
|
|
// If not found via email, check user_id. |
|
399
|
|
View Code Duplication |
if ( class_exists( 'Give_DB_Donor_Meta' ) && empty( $stripe_customer_id ) ) { |
|
|
|
|
|
|
400
|
|
|
$donor = new Give_Donor( $user_id, true ); |
|
401
|
|
|
$stripe_customer_id = $donor->get_meta( give_stripe_get_customer_key() ); |
|
402
|
|
|
} |
|
403
|
|
|
|
|
404
|
|
|
// Get user ID from customer. |
|
405
|
|
|
if ( is_email( $user_id_or_email ) && empty( $stripe_customer_id ) ) { |
|
406
|
|
|
|
|
407
|
|
|
$donor = new Give_Donor( $user_id_or_email ); |
|
408
|
|
|
// Pull user ID from customer object. |
|
409
|
|
|
if ( $donor->id > 0 && ! empty( $donor->user_id ) ) { |
|
410
|
|
|
$user_id = $donor->user_id; |
|
411
|
|
|
} |
|
412
|
|
|
} else { |
|
413
|
|
|
// This is a user ID passed. |
|
414
|
|
|
$user_id = $user_id_or_email; |
|
415
|
|
|
} |
|
416
|
|
|
|
|
417
|
|
|
// If no Stripe customer ID found in customer meta move to wp user meta. |
|
418
|
|
|
if ( empty( $stripe_customer_id ) && ! empty( $user_id ) ) { |
|
419
|
|
|
|
|
420
|
|
|
$stripe_customer_id = get_user_meta( $user_id, give_stripe_get_customer_key(), true ); |
|
421
|
|
|
|
|
422
|
|
|
} elseif ( empty( $stripe_customer_id ) && class_exists( 'Give_Recurring_Subscriber' ) ) { |
|
423
|
|
|
|
|
424
|
|
|
// Not found in customer meta or user meta, check Recurring data. |
|
425
|
|
|
$by_user_id = is_int( $user_id_or_email ) ? true : false; |
|
426
|
|
|
$subscriber = new Give_Recurring_Subscriber( $user_id_or_email, $by_user_id ); |
|
427
|
|
|
|
|
428
|
|
|
if ( $subscriber->id > 0 ) { |
|
429
|
|
|
|
|
430
|
|
|
$verified = false; |
|
431
|
|
|
|
|
432
|
|
|
if ( ( $by_user_id && $user_id_or_email == $subscriber->user_id ) ) { |
|
433
|
|
|
// If the user ID given, matches that of the subscriber. |
|
434
|
|
|
$verified = true; |
|
435
|
|
|
} else { |
|
436
|
|
|
// If the email used is the same as the primary email. |
|
437
|
|
|
if ( $subscriber->email == $user_id_or_email ) { |
|
438
|
|
|
$verified = true; |
|
439
|
|
|
} |
|
440
|
|
|
|
|
441
|
|
|
// If the email is in the Give's Additional emails. |
|
442
|
|
|
if ( property_exists( $subscriber, 'emails' ) && in_array( $user_id_or_email, $subscriber->emails ) ) { |
|
443
|
|
|
$verified = true; |
|
444
|
|
|
} |
|
445
|
|
|
} |
|
446
|
|
|
|
|
447
|
|
|
if ( $verified ) { |
|
448
|
|
|
|
|
449
|
|
|
// Backwards compatibility from changed method name. |
|
450
|
|
|
// We changed the method name in recurring. |
|
451
|
|
|
if ( method_exists( $subscriber, 'get_recurring_donor_id' ) ) { |
|
452
|
|
|
$stripe_customer_id = $subscriber->get_recurring_donor_id( 'stripe' ); |
|
453
|
|
|
} elseif ( method_exists( $subscriber, 'get_recurring_customer_id' ) ) { |
|
454
|
|
|
$stripe_customer_id = $subscriber->get_recurring_customer_id( 'stripe' ); |
|
455
|
|
|
} |
|
456
|
|
|
} |
|
457
|
|
|
} |
|
458
|
|
|
|
|
459
|
|
|
if ( ! empty( $stripe_customer_id ) ) { |
|
460
|
|
|
update_user_meta( $subscriber->user_id, give_stripe_get_customer_key(), $stripe_customer_id ); |
|
461
|
|
|
} |
|
462
|
|
|
}// End if(). |
|
463
|
|
|
|
|
464
|
|
|
return $stripe_customer_id; |
|
465
|
|
|
|
|
466
|
|
|
} |
|
467
|
|
|
|
|
468
|
|
|
/** |
|
469
|
|
|
* Get the meta key for storing Stripe customer IDs in. |
|
470
|
|
|
* |
|
471
|
|
|
* @since 2.5.0 |
|
472
|
|
|
* |
|
473
|
|
|
* @return string $key |
|
474
|
|
|
*/ |
|
475
|
|
|
function give_stripe_get_customer_key() { |
|
476
|
|
|
|
|
477
|
|
|
$key = '_give_stripe_customer_id'; |
|
478
|
|
|
|
|
479
|
|
|
if ( give_is_test_mode() ) { |
|
480
|
|
|
$key .= '_test'; |
|
481
|
|
|
} |
|
482
|
|
|
|
|
483
|
|
|
return $key; |
|
484
|
|
|
} |
|
485
|
|
|
|
|
486
|
|
|
/** |
|
487
|
|
|
* Determines if the shop is using a zero-decimal currency. |
|
488
|
|
|
* |
|
489
|
|
|
* @since 2.5.0 |
|
490
|
|
|
* |
|
491
|
|
|
* @return bool |
|
492
|
|
|
*/ |
|
493
|
|
|
function give_stripe_is_zero_decimal_currency() { |
|
494
|
|
|
|
|
495
|
|
|
$ret = false; |
|
496
|
|
|
$currency = give_get_currency(); |
|
497
|
|
|
|
|
498
|
|
|
switch ( $currency ) { |
|
499
|
|
|
case 'BIF': |
|
500
|
|
|
case 'CLP': |
|
501
|
|
|
case 'DJF': |
|
502
|
|
|
case 'GNF': |
|
503
|
|
|
case 'JPY': |
|
504
|
|
|
case 'KMF': |
|
505
|
|
|
case 'KRW': |
|
506
|
|
|
case 'MGA': |
|
507
|
|
|
case 'PYG': |
|
508
|
|
|
case 'RWF': |
|
509
|
|
|
case 'VND': |
|
510
|
|
|
case 'VUV': |
|
511
|
|
|
case 'XAF': |
|
512
|
|
|
case 'XOF': |
|
513
|
|
|
case 'XPF': |
|
514
|
|
|
$ret = true; |
|
515
|
|
|
break; |
|
516
|
|
|
} |
|
517
|
|
|
|
|
518
|
|
|
return $ret; |
|
519
|
|
|
} |
|
520
|
|
|
|
|
521
|
|
|
/** |
|
522
|
|
|
* Get Statement Descriptor. |
|
523
|
|
|
* |
|
524
|
|
|
* Create the Statement Description. |
|
525
|
|
|
* |
|
526
|
|
|
* @see https://stripe.com/docs/api/php#create_charge-statement_descriptor |
|
527
|
|
|
* |
|
528
|
|
|
* @since 2.5.0 |
|
529
|
|
|
* |
|
530
|
|
|
* @param array $data List of posted variable while submitting donation. |
|
531
|
|
|
* |
|
532
|
|
|
* @return mixed |
|
533
|
|
|
*/ |
|
534
|
|
|
function give_stripe_get_statement_descriptor( $data = array() ) { |
|
535
|
|
|
|
|
536
|
|
|
$descriptor_option = give_get_option( 'stripe_statement_descriptor', get_bloginfo( 'name' ) ); |
|
537
|
|
|
|
|
538
|
|
|
// Clean the statement descriptor. |
|
539
|
|
|
$unsupported_characters = array( '<', '>', '"', '\'' ); |
|
540
|
|
|
$statement_descriptor = mb_substr( $descriptor_option, 0, 22 ); |
|
541
|
|
|
$statement_descriptor = str_replace( $unsupported_characters, '', $statement_descriptor ); |
|
542
|
|
|
|
|
543
|
|
|
return apply_filters( 'give_stripe_statement_descriptor', $statement_descriptor, $data ); |
|
544
|
|
|
|
|
545
|
|
|
} |
|
546
|
|
|
|
|
547
|
|
|
/** |
|
548
|
|
|
* Get the sequential order number of donation. |
|
549
|
|
|
* |
|
550
|
|
|
* @since 2.5.0 |
|
551
|
|
|
* |
|
552
|
|
|
* @param integer $donation_or_post_id Donation or wp post id. |
|
553
|
|
|
* @param bool $check_enabled Check if sequential-ordering_status is activated or not. |
|
554
|
|
|
* |
|
555
|
|
|
* @return bool|string |
|
556
|
|
|
*/ |
|
557
|
|
|
function give_stripe_get_sequential_id( $donation_or_post_id, $check_enabled = true ) { |
|
558
|
|
|
// Check if enabled. |
|
559
|
|
|
if ( true === $check_enabled ) { |
|
560
|
|
|
$sequential_ordering = give_get_option( 'sequential-ordering_status' ); |
|
561
|
|
|
|
|
562
|
|
|
if ( ! give_is_setting_enabled( $sequential_ordering ) ) { |
|
563
|
|
|
return false; |
|
564
|
|
|
} |
|
565
|
|
|
} |
|
566
|
|
|
|
|
567
|
|
|
return Give()->seq_donation_number->get_serial_code( $donation_or_post_id ); |
|
568
|
|
|
} |
|
569
|
|
|
|
|
570
|
|
|
/** |
|
571
|
|
|
* Get Custom FFM Fields. |
|
572
|
|
|
* |
|
573
|
|
|
* @param int $form_id Donation Form ID. |
|
574
|
|
|
* @param int $donation_id Donation ID. |
|
575
|
|
|
* |
|
576
|
|
|
* @since 2.5.0 |
|
577
|
|
|
* |
|
578
|
|
|
* @return array |
|
579
|
|
|
*/ |
|
580
|
|
|
function give_stripe_get_custom_ffm_fields( $form_id, $donation_id = 0 ) { |
|
581
|
|
|
|
|
582
|
|
|
// Bail out, if FFM add-on is not active. |
|
583
|
|
|
if ( ! class_exists( 'Give_Form_Fields_Manager' ) ) { |
|
584
|
|
|
return array(); |
|
585
|
|
|
} |
|
586
|
|
|
|
|
587
|
|
|
$ffm_meta = array(); |
|
588
|
|
|
$ffm_required = array(); |
|
589
|
|
|
$ffm_optional = array(); |
|
590
|
|
|
$field_label = ''; |
|
591
|
|
|
$ffm_fields = give_get_meta( $form_id, 'give-form-fields', true ); |
|
592
|
|
|
|
|
593
|
|
|
if ( is_array( $ffm_fields ) && count( $ffm_fields ) > 0 ) { |
|
594
|
|
|
|
|
595
|
|
|
// Loop through ffm fields. |
|
596
|
|
|
foreach ( $ffm_fields as $field ) { |
|
597
|
|
|
|
|
598
|
|
|
// Continue, if field name is empty which means the input type is not submitable. |
|
599
|
|
|
if ( empty( $field['name'] ) ) { |
|
600
|
|
|
continue; |
|
601
|
|
|
} |
|
602
|
|
|
|
|
603
|
|
|
$input_field_value = ! empty( $_POST[$field['name']] ) ? give_clean( $_POST[$field['name']] ) : ''; |
|
604
|
|
|
|
|
605
|
|
|
if ( $donation_id > 0 ) { |
|
606
|
|
|
$field_value = give_get_meta( $donation_id, $field['name'], true ); |
|
607
|
|
|
} elseif ( ! empty( $input_field_value ) ) { |
|
608
|
|
|
$field_value = give_stripe_ffm_field_value_to_str( $input_field_value ); |
|
609
|
|
|
} else { |
|
610
|
|
|
$field_value = __( '-- N/A --', 'give' ); |
|
611
|
|
|
} |
|
612
|
|
|
|
|
613
|
|
|
// Strip the number of characters below 450 for custom fields value input when passed to metadata. |
|
614
|
|
|
if ( strlen( $field_value ) > 450 ) { |
|
615
|
|
|
$field_value = substr( $field_value, 0, 450 ) . '...'; |
|
616
|
|
|
} |
|
617
|
|
|
|
|
618
|
|
|
if ( ! empty( $field['label'] ) ) { |
|
619
|
|
|
$field_label = strlen( $field['label'] ) > 25 |
|
620
|
|
|
? trim( substr( $field['label'], 0, 25 ) ) . '...' |
|
621
|
|
|
: $field['label']; |
|
622
|
|
|
} elseif ( ! empty( $field['name'] ) ) { |
|
623
|
|
|
$field_label = strlen( $field['name'] ) > 25 |
|
624
|
|
|
? trim( substr( $field['name'], 0, 25 ) ) . '...' |
|
625
|
|
|
: $field['name']; |
|
626
|
|
|
} |
|
627
|
|
|
|
|
628
|
|
|
// Make sure that the required fields are at the top. |
|
629
|
|
|
$required_field = ! empty( $field['required'] ) ? $field['required'] : ''; |
|
630
|
|
|
if ( give_is_setting_enabled( $required_field ) ) { |
|
631
|
|
|
$ffm_required[ $field_label ] = is_array( $field_value ) ? implode( ' | ', $field_value ) : $field_value; |
|
632
|
|
|
} else { |
|
633
|
|
|
$ffm_optional[ $field_label ] = is_array( $field_value ) ? implode( ' | ', $field_value ) : $field_value; |
|
634
|
|
|
} |
|
635
|
|
|
|
|
636
|
|
|
$ffm_meta = array_merge( $ffm_required, $ffm_optional ); |
|
637
|
|
|
|
|
638
|
|
|
} // End foreach(). |
|
639
|
|
|
} // End if(). |
|
640
|
|
|
|
|
641
|
|
|
return array_filter( $ffm_meta ); |
|
642
|
|
|
|
|
643
|
|
|
} |
|
644
|
|
|
|
|
645
|
|
|
/** |
|
646
|
|
|
* This function is used to set application information to Stripe. |
|
647
|
|
|
* |
|
648
|
|
|
* @since 2.5.0 |
|
649
|
|
|
* |
|
650
|
|
|
* @return void |
|
651
|
|
|
*/ |
|
652
|
|
|
function give_stripe_set_app_info() { |
|
653
|
|
|
|
|
654
|
|
|
try { |
|
655
|
|
|
|
|
656
|
|
|
/** |
|
657
|
|
|
* This filter hook is used to change the application name when Stripe add-on is used. |
|
658
|
|
|
* |
|
659
|
|
|
* Note: This filter hook is for internal purposes only. |
|
660
|
|
|
* |
|
661
|
|
|
* @since 2.5.0 |
|
662
|
|
|
*/ |
|
663
|
|
|
$application_name = apply_filters( 'give_stripe_get_application_name', 'Give Core' ); |
|
664
|
|
|
|
|
665
|
|
|
/** |
|
666
|
|
|
* This filter hook is used to chnage the application version when Stripe add-on is used. |
|
667
|
|
|
* |
|
668
|
|
|
* Note: This filter hook is for internal purposes only. |
|
669
|
|
|
* |
|
670
|
|
|
* @since 2.5.0 |
|
671
|
|
|
*/ |
|
672
|
|
|
$application_version = apply_filters( 'give_stripe_get_application_version', GIVE_VERSION ); |
|
673
|
|
|
|
|
674
|
|
|
\Stripe\Stripe::setAppInfo( |
|
675
|
|
|
$application_name, |
|
676
|
|
|
$application_version, |
|
677
|
|
|
esc_url_raw( 'https://givewp.com' ), |
|
678
|
|
|
'pp_partner_DKj75W1QYBxBLK' // Partner ID. |
|
679
|
|
|
); |
|
680
|
|
|
} catch ( \Stripe\Error\Base $e ) { |
|
681
|
|
|
Give_Stripe_Logger::log_error( $e, $this->id ); |
|
682
|
|
|
} catch ( Exception $e ) { |
|
683
|
|
|
|
|
684
|
|
|
give_record_gateway_error( |
|
685
|
|
|
__( 'Stripe Error', 'give' ), |
|
686
|
|
|
sprintf( |
|
687
|
|
|
/* translators: %s Exception Error Message */ |
|
688
|
|
|
__( 'Unable to set application information to Stripe. Details: %s', 'give' ), |
|
689
|
|
|
$e->getMessage() |
|
690
|
|
|
) |
|
691
|
|
|
); |
|
692
|
|
|
|
|
693
|
|
|
give_set_error( 'stripe_app_info_error', __( 'Unable to set application information to Stripe. Please try again.', 'give' ) ); |
|
694
|
|
|
} // End try(). |
|
695
|
|
|
|
|
696
|
|
|
// Set API Key after setting app info to ensure that API key is set on every Stripe call. |
|
697
|
|
|
give_stripe_set_api_key(); |
|
698
|
|
|
|
|
699
|
|
|
} |
|
700
|
|
|
|
|
701
|
|
|
/** |
|
702
|
|
|
* This function is used to get application fee percentage. |
|
703
|
|
|
* |
|
704
|
|
|
* Note: This function is for internal purpose only. |
|
705
|
|
|
* |
|
706
|
|
|
* @since 2.5.0 |
|
707
|
|
|
* |
|
708
|
|
|
* @return int |
|
709
|
|
|
*/ |
|
710
|
|
|
function give_stripe_get_application_fee_percentage() { |
|
711
|
|
|
|
|
712
|
|
|
// Set Application Fee Percentage. |
|
713
|
|
|
$fee_percentage = 2; |
|
714
|
|
|
|
|
715
|
|
|
// Return the fee percentage based on the currency used. |
|
716
|
|
|
return give_stripe_is_zero_decimal_currency() ? $fee_percentage : give_stripe_cents_to_dollars( $fee_percentage ); |
|
717
|
|
|
} |
|
718
|
|
|
|
|
719
|
|
|
/** |
|
720
|
|
|
* This function is used to calculate application fee amount. |
|
721
|
|
|
* |
|
722
|
|
|
* @param int $amount Donation amount. |
|
723
|
|
|
* |
|
724
|
|
|
* @since 2.5.0 |
|
725
|
|
|
* |
|
726
|
|
|
* @return int |
|
727
|
|
|
*/ |
|
728
|
|
|
function give_stripe_get_application_fee_amount( $amount ) { |
|
729
|
|
|
return $amount * give_stripe_get_application_fee_percentage() / 100; |
|
730
|
|
|
} |
|
731
|
|
|
|
|
732
|
|
|
/** |
|
733
|
|
|
* This function is used to fetch the donation id by meta key. |
|
734
|
|
|
* |
|
735
|
|
|
* @param string $id Any String. |
|
736
|
|
|
* @param string $type intent_id/client_secret |
|
737
|
|
|
* |
|
738
|
|
|
* @since 2.5.0 |
|
739
|
|
|
* |
|
740
|
|
|
* @return void |
|
741
|
|
|
*/ |
|
742
|
|
|
function give_stripe_get_donation_id_by( $id, $type ) { |
|
743
|
|
|
|
|
744
|
|
|
global $wpdb; |
|
745
|
|
|
|
|
746
|
|
|
$donation_id = 0; |
|
747
|
|
|
|
|
748
|
|
|
switch ( $type ) { |
|
749
|
|
|
case 'intent_id': |
|
750
|
|
|
$donation_id = $wpdb->get_var( $wpdb->prepare( "SELECT donation_id FROM {$wpdb->donationmeta} WHERE meta_key = '_give_stripe_payment_intent_id' AND meta_value = %s LIMIT 1", $id ) ); |
|
751
|
|
|
break; |
|
752
|
|
|
|
|
753
|
|
|
case 'client_secret': |
|
754
|
|
|
$donation_id = $wpdb->get_var( $wpdb->prepare( "SELECT donation_id FROM {$wpdb->donationmeta} WHERE meta_key = '_give_stripe_payment_intent_client_secret' AND meta_value = %s LIMIT 1", $id ) ); |
|
755
|
|
|
break; |
|
756
|
|
|
} |
|
757
|
|
|
|
|
758
|
|
|
return $donation_id; |
|
759
|
|
|
|
|
760
|
|
|
} |
|
761
|
|
|
|
|
762
|
|
|
/** |
|
763
|
|
|
* This function is used to set Stripe API Key. |
|
764
|
|
|
* |
|
765
|
|
|
* @since 2.5.0 |
|
766
|
|
|
* |
|
767
|
|
|
* @return void |
|
768
|
|
|
*/ |
|
769
|
|
|
function give_stripe_set_api_key() { |
|
770
|
|
|
|
|
771
|
|
|
try { |
|
772
|
|
|
|
|
773
|
|
|
// Fetch secret key. |
|
774
|
|
|
$secret_key = give_stripe_get_secret_key(); |
|
775
|
|
|
|
|
776
|
|
|
// Set secret key. |
|
777
|
|
|
\Stripe\Stripe::setApiKey( $secret_key ); |
|
778
|
|
|
|
|
779
|
|
|
} catch ( \Stripe\Error\Base $e ) { |
|
780
|
|
|
|
|
781
|
|
|
// Log Error. |
|
782
|
|
|
$this->log_error( $e ); |
|
783
|
|
|
|
|
784
|
|
|
} catch ( Exception $e ) { |
|
785
|
|
|
|
|
786
|
|
|
// Something went wrong outside of Stripe. |
|
787
|
|
|
give_record_gateway_error( |
|
788
|
|
|
__( 'Stripe Error', 'give' ), |
|
789
|
|
|
sprintf( |
|
790
|
|
|
/* translators: %s Exception Message Body */ |
|
791
|
|
|
__( 'Unable to set Stripe API Key. Details: %s', 'give' ), |
|
792
|
|
|
$e->getMessage() |
|
793
|
|
|
) |
|
794
|
|
|
); |
|
795
|
|
|
give_set_error( 'stripe_error', __( 'An error occurred while processing the donation. Please try again.', 'give' ) ); |
|
796
|
|
|
|
|
797
|
|
|
// Send donor back to donation form page. |
|
798
|
|
|
give_send_back_to_checkout( '?payment-mode=' . give_clean( $_GET['payment-mode'] ) ); |
|
799
|
|
|
|
|
800
|
|
|
} |
|
801
|
|
|
|
|
802
|
|
|
} |
|
803
|
|
|
|
|
804
|
|
|
/** |
|
805
|
|
|
* This function is used to fetch the webhook key used to store in options table. |
|
806
|
|
|
* |
|
807
|
|
|
* @since 2.5.0 |
|
808
|
|
|
* |
|
809
|
|
|
* @return string |
|
810
|
|
|
*/ |
|
811
|
|
|
function give_stripe_get_webhook_key() { |
|
812
|
|
|
|
|
813
|
|
|
$mode = give_stripe_get_payment_mode(); |
|
814
|
|
|
|
|
815
|
|
|
return "give_stripe_{$mode}_webhook_id"; |
|
816
|
|
|
} |
|
817
|
|
|
|
|
818
|
|
|
/** |
|
819
|
|
|
* This function is used to fetch the webhook id which is stored in DB, if the webhook is set on Stripe. |
|
820
|
|
|
* |
|
821
|
|
|
* @since 2.5.0 |
|
822
|
|
|
* |
|
823
|
|
|
* @return string |
|
824
|
|
|
*/ |
|
825
|
|
|
function give_stripe_get_webhook_id() { |
|
826
|
|
|
|
|
827
|
|
|
$key = give_stripe_get_webhook_key(); |
|
828
|
|
|
|
|
829
|
|
|
return trim( give_get_option( $key ) ); |
|
830
|
|
|
} |
|
831
|
|
|
|
|
832
|
|
|
/** |
|
833
|
|
|
* This function is used to fetch the webhook id which is stored in DB, if the webhook is set on Stripe. |
|
834
|
|
|
* |
|
835
|
|
|
* @since 2.5.0 |
|
836
|
|
|
* |
|
837
|
|
|
* @return string |
|
838
|
|
|
*/ |
|
839
|
|
|
function give_stripe_delete_webhook_id() { |
|
840
|
|
|
|
|
841
|
|
|
$key = give_stripe_get_webhook_key(); |
|
842
|
|
|
|
|
843
|
|
|
return trim( give_delete_option( $key ) ); |
|
844
|
|
|
} |
|
845
|
|
|
|
|
846
|
|
|
/** |
|
847
|
|
|
* This function is used to get the payment mode text. For example, "test" or "live" |
|
848
|
|
|
* |
|
849
|
|
|
* @since 2.5.0 |
|
850
|
|
|
* |
|
851
|
|
|
* @return string |
|
852
|
|
|
*/ |
|
853
|
|
|
function give_stripe_get_payment_mode() { |
|
854
|
|
|
|
|
855
|
|
|
$mode = 'live'; |
|
856
|
|
|
|
|
857
|
|
|
if ( give_is_test_mode() ) { |
|
858
|
|
|
$mode = 'test'; |
|
859
|
|
|
} |
|
860
|
|
|
|
|
861
|
|
|
return $mode; |
|
862
|
|
|
} |
|
863
|
|
|
|
|
864
|
|
|
/** |
|
865
|
|
|
* This function will be used to convert upto 2 dimensional array to string as per FFM add-on Repeater field needs. |
|
866
|
|
|
* |
|
867
|
|
|
* This function is for internal purpose only. |
|
868
|
|
|
* |
|
869
|
|
|
* @param array|string $data Data to be converted to string. |
|
870
|
|
|
* |
|
871
|
|
|
* @since 2.5.0 |
|
872
|
|
|
* |
|
873
|
|
|
* @return array|string |
|
874
|
|
|
*/ |
|
875
|
|
|
function give_stripe_ffm_field_value_to_str( $data ) { |
|
876
|
|
|
|
|
877
|
|
|
if ( is_array( $data ) && count( $data ) > 0 ) { |
|
878
|
|
|
$count = 0; |
|
879
|
|
|
foreach ( $data as $item ) { |
|
880
|
|
|
if ( is_array( $item ) && count( $item ) > 0 ) { |
|
881
|
|
|
$data[ $count ] = implode( ',', $item ); |
|
882
|
|
|
} |
|
883
|
|
|
|
|
884
|
|
|
$count ++; |
|
885
|
|
|
} |
|
886
|
|
|
|
|
887
|
|
|
$data = implode( '|', $data ); |
|
888
|
|
|
} |
|
889
|
|
|
|
|
890
|
|
|
return $data; |
|
891
|
|
|
} |
|
892
|
|
|
|
|
893
|
|
|
/** |
|
894
|
|
|
* This function will be used to get Stripe transaction id link. |
|
895
|
|
|
* |
|
896
|
|
|
* @param int $donation_id Donation ID. |
|
897
|
|
|
* @param string $transaction_id Stripe Transaction ID. |
|
898
|
|
|
* |
|
899
|
|
|
* @since 2.5.0 |
|
900
|
|
|
* |
|
901
|
|
|
* @return string |
|
902
|
|
|
*/ |
|
903
|
|
|
function give_stripe_get_transaction_link( $donation_id, $transaction_id = '' ) { |
|
904
|
|
|
|
|
905
|
|
|
// If empty transaction id then get transaction id from donation id. |
|
906
|
|
|
if ( empty( $transaction_id ) ) { |
|
907
|
|
|
$transaction_id = give_get_payment_transaction_id( $donation_id ); |
|
908
|
|
|
} |
|
909
|
|
|
|
|
910
|
|
|
$transaction_link = sprintf( |
|
911
|
|
|
'<a href="%1$s" target="_blank">%2$s</a>', |
|
912
|
|
|
give_stripe_get_transaction_url( $transaction_id ), |
|
913
|
|
|
$transaction_id |
|
914
|
|
|
); |
|
915
|
|
|
|
|
916
|
|
|
return $transaction_link; |
|
917
|
|
|
} |
|
918
|
|
|
|
|
919
|
|
|
/** |
|
920
|
|
|
* This function will return stripe transaction url. |
|
921
|
|
|
* |
|
922
|
|
|
* @param string $transaction_id Stripe Transaction ID. |
|
923
|
|
|
* |
|
924
|
|
|
* @since 2.5.0 |
|
925
|
|
|
* |
|
926
|
|
|
* @return string |
|
927
|
|
|
*/ |
|
928
|
|
|
function give_stripe_get_transaction_url( $transaction_id ) { |
|
929
|
|
|
|
|
930
|
|
|
$mode = ''; |
|
931
|
|
|
|
|
932
|
|
|
if ( give_is_test_mode() ) { |
|
933
|
|
|
$mode = 'test/'; |
|
934
|
|
|
} |
|
935
|
|
|
|
|
936
|
|
|
$transaction_url = esc_url_raw( "https://dashboard.stripe.com/{$mode}payments/{$transaction_id}" ); |
|
937
|
|
|
|
|
938
|
|
|
return $transaction_url; |
|
939
|
|
|
} |
|
940
|
|
|
|
|
941
|
|
|
/** |
|
942
|
|
|
* This function will record errors under Stripe Log. |
|
943
|
|
|
* |
|
944
|
|
|
* @param string $title Log Title. |
|
945
|
|
|
* @param string $message Log Message. |
|
946
|
|
|
* @param int $parent Parent. |
|
947
|
|
|
* |
|
948
|
|
|
* @since 2.5.0 |
|
949
|
|
|
* |
|
950
|
|
|
* @return int |
|
951
|
|
|
*/ |
|
952
|
|
|
function give_stripe_record_log( $title = '', $message = '', $parent = 0 ) { |
|
953
|
|
|
$title = empty( $title ) ? esc_html__( 'Stripe Error', 'give' ) : $title; |
|
954
|
|
|
|
|
955
|
|
|
return give_record_log( $title, $message, $parent, 'stripe' ); |
|
956
|
|
|
} |
|
957
|
|
|
|
|
958
|
|
|
/** |
|
959
|
|
|
* This function will check whether the ID exists or not based on type. |
|
960
|
|
|
* |
|
961
|
|
|
* @param string $id Source ID. |
|
962
|
|
|
* @param string $type Source type. |
|
963
|
|
|
* |
|
964
|
|
|
* @since 2.5.0 |
|
965
|
|
|
* @access public |
|
966
|
|
|
* |
|
967
|
|
|
* @return bool |
|
968
|
|
|
*/ |
|
969
|
|
|
function give_stripe_is_source_type( $id, $type = 'src' ) { |
|
970
|
|
|
return ( |
|
971
|
|
|
$id && |
|
972
|
|
|
preg_match( "/{$type}_/i", $id ) |
|
973
|
|
|
); |
|
974
|
|
|
} |
|
975
|
|
|
|
|
976
|
|
|
/** |
|
977
|
|
|
* This helper function is used to process Stripe payments. |
|
978
|
|
|
* |
|
979
|
|
|
* @param array $donation_data Donation form data. |
|
980
|
|
|
* @param object $stripe_gateway $this data. |
|
981
|
|
|
* |
|
982
|
|
|
* @since 2.5.0 |
|
983
|
|
|
* |
|
984
|
|
|
* @return void |
|
985
|
|
|
*/ |
|
986
|
|
|
function give_stripe_process_payment( $donation_data, $stripe_gateway ) { |
|
|
|
|
|
|
987
|
|
|
|
|
988
|
|
|
// Make sure we don't have any left over errors present. |
|
989
|
|
|
give_clear_errors(); |
|
990
|
|
|
|
|
991
|
|
|
$stripe_gateway = new Give_Stripe_Gateway(); |
|
992
|
|
|
|
|
993
|
|
|
$payment_method_id = ! empty( $donation_data['post_data']['give_stripe_payment_method'] ) |
|
994
|
|
|
? $donation_data['post_data']['give_stripe_payment_method'] |
|
995
|
|
|
: $stripe_gateway->check_for_source( $donation_data ); |
|
996
|
|
|
|
|
997
|
|
|
// Any errors? |
|
998
|
|
|
$errors = give_get_errors(); |
|
999
|
|
|
|
|
1000
|
|
|
// No errors, proceed. |
|
1001
|
|
|
if ( ! $errors ) { |
|
1002
|
|
|
|
|
1003
|
|
|
$form_id = ! empty( $donation_data['post_data']['give-form-id'] ) ? intval( $donation_data['post_data']['give-form-id'] ) : 0; |
|
1004
|
|
|
$price_id = ! empty( $donation_data['post_data']['give-price-id'] ) ? $donation_data['post_data']['give-price-id'] : 0; |
|
1005
|
|
|
$donor_email = ! empty( $donation_data['post_data']['give_email'] ) ? $donation_data['post_data']['give_email'] : 0; |
|
1006
|
|
|
$donation_summary = give_payment_gateway_donation_summary( $donation_data, false ); |
|
1007
|
|
|
|
|
1008
|
|
|
// Get an existing Stripe customer or create a new Stripe Customer and attach the source to customer. |
|
1009
|
|
|
$give_stripe_customer = new Give_Stripe_Customer( $donor_email, $payment_method_id ); |
|
1010
|
|
|
$stripe_customer = $give_stripe_customer->customer_data; |
|
|
|
|
|
|
1011
|
|
|
$stripe_customer_id = $give_stripe_customer->get_id(); |
|
1012
|
|
|
|
|
1013
|
|
|
// We have a Stripe customer, charge them. |
|
1014
|
|
|
if ( $stripe_customer_id ) { |
|
1015
|
|
|
|
|
1016
|
|
|
// Proceed to get stripe source/payment method details. |
|
1017
|
|
|
$payment_method = $give_stripe_customer->attached_payment_method; |
|
1018
|
|
|
$payment_method_id = $payment_method->id; |
|
1019
|
|
|
|
|
1020
|
|
|
// Setup the payment details. |
|
1021
|
|
|
$payment_data = array( |
|
1022
|
|
|
'price' => $donation_data['price'], |
|
1023
|
|
|
'give_form_title' => $donation_data['post_data']['give-form-title'], |
|
1024
|
|
|
'give_form_id' => $form_id, |
|
1025
|
|
|
'give_price_id' => $price_id, |
|
1026
|
|
|
'date' => $donation_data['date'], |
|
1027
|
|
|
'user_email' => $donation_data['user_email'], |
|
1028
|
|
|
'purchase_key' => $donation_data['purchase_key'], |
|
1029
|
|
|
'currency' => give_get_currency( $form_id ), |
|
1030
|
|
|
'user_info' => $donation_data['user_info'], |
|
1031
|
|
|
'status' => 'pending', |
|
1032
|
|
|
'gateway' => $stripe_gateway->id, |
|
1033
|
|
|
); |
|
1034
|
|
|
|
|
1035
|
|
|
// Record the pending payment in Give. |
|
1036
|
|
|
$donation_id = give_insert_payment( $payment_data ); |
|
1037
|
|
|
|
|
1038
|
|
|
// Assign required data to array of donation data for future reference. |
|
1039
|
|
|
$donation_data['donation_id'] = $donation_id; |
|
1040
|
|
|
$donation_data['description'] = $donation_summary; |
|
1041
|
|
|
$donation_data['source_id'] = $payment_method_id; |
|
1042
|
|
|
|
|
1043
|
|
|
// Save Stripe Customer ID to Donation note, Donor and Donation for future reference. |
|
1044
|
|
|
give_insert_payment_note( $donation_id, 'Stripe Customer ID: ' . $stripe_customer_id ); |
|
|
|
|
|
|
1045
|
|
|
$stripe_gateway->save_stripe_customer_id( $stripe_customer_id, $donation_id ); |
|
|
|
|
|
|
1046
|
|
|
give_update_meta( $donation_id, '_give_stripe_customer_id', $stripe_customer_id ); |
|
|
|
|
|
|
1047
|
|
|
|
|
1048
|
|
|
// Save Source ID to donation note and DB. |
|
1049
|
|
|
give_insert_payment_note( $donation_id, 'Stripe Source/Payment Method ID: ' . $payment_method_id ); |
|
|
|
|
|
|
1050
|
|
|
give_update_meta( $donation_id, '_give_stripe_source_id', $payment_method_id ); |
|
|
|
|
|
|
1051
|
|
|
|
|
1052
|
|
|
// Save donation summary to donation. |
|
1053
|
|
|
give_update_meta( $donation_id, '_give_stripe_donation_summary', $donation_summary ); |
|
|
|
|
|
|
1054
|
|
|
|
|
1055
|
|
|
|
|
1056
|
|
|
if ( give_stripe_is_checkout_enabled() ) { |
|
1057
|
|
|
|
|
1058
|
|
|
// Process charge w/ support for preapproval. |
|
1059
|
|
|
$charge = $stripe_gateway->process_charge( $donation_data, $stripe_customer_id ); |
|
1060
|
|
|
|
|
1061
|
|
|
// Verify the Stripe payment. |
|
1062
|
|
|
$stripe_gateway->verify_payment( $donation_id, $stripe_customer_id, $charge ); |
|
|
|
|
|
|
1063
|
|
|
} else { |
|
1064
|
|
|
|
|
1065
|
|
|
/** |
|
1066
|
|
|
* This filter hook is used to update the payment intent arguments. |
|
1067
|
|
|
* |
|
1068
|
|
|
* @since 2.5.0 |
|
1069
|
|
|
*/ |
|
1070
|
|
|
$intent_args = apply_filters( |
|
1071
|
|
|
'give_stripe_create_intent_args', |
|
1072
|
|
|
array( |
|
1073
|
|
|
'amount' => $stripe_gateway->format_amount( $donation_data['price'] ), |
|
1074
|
|
|
'currency' => give_get_currency( $form_id ), |
|
1075
|
|
|
'payment_method_types' => [ 'card' ], |
|
1076
|
|
|
'statement_descriptor' => give_stripe_get_statement_descriptor(), |
|
1077
|
|
|
'description' => give_payment_gateway_donation_summary( $donation_data ), |
|
1078
|
|
|
'metadata' => $stripe_gateway->prepare_metadata( $donation_id ), |
|
|
|
|
|
|
1079
|
|
|
'customer' => $stripe_customer_id, |
|
1080
|
|
|
'payment_method' => $payment_method_id, |
|
1081
|
|
|
'confirm' => true, |
|
1082
|
|
|
'return_url' => give_get_success_page_uri(), |
|
1083
|
|
|
) |
|
1084
|
|
|
); |
|
1085
|
|
|
|
|
1086
|
|
|
// Send Stripe Receipt emails when enabled. |
|
1087
|
|
|
if ( give_is_setting_enabled( give_get_option( 'stripe_receipt_emails' ) ) ) { |
|
1088
|
|
|
$intent_args['receipt_email'] = $donation_data['user_email']; |
|
1089
|
|
|
} |
|
1090
|
|
|
|
|
1091
|
|
|
$intent = $stripe_gateway->payment_intent->create( $intent_args ); |
|
1092
|
|
|
|
|
1093
|
|
|
// Save Payment Intent Client Secret to donation note and DB. |
|
1094
|
|
|
give_insert_payment_note( $donation_id, 'Stripe Payment Intent Client Secret: ' . $intent->client_secret ); |
|
|
|
|
|
|
1095
|
|
|
give_update_meta( $donation_id, '_give_stripe_payment_intent_client_secret', $intent->client_secret ); |
|
|
|
|
|
|
1096
|
|
|
|
|
1097
|
|
|
// Set Payment Intent ID as transaction ID for the donation. |
|
1098
|
|
|
give_set_payment_transaction_id( $donation_id, $intent->id ); |
|
|
|
|
|
|
1099
|
|
|
give_insert_payment_note( $donation_id, 'Stripe Charge/Payment Intent ID: ' . $intent->id ); |
|
|
|
|
|
|
1100
|
|
|
|
|
1101
|
|
|
// Process additional steps for SCA or 3D secure. |
|
1102
|
|
|
give_stripe_process_additional_authentication( $donation_id, $intent ); |
|
|
|
|
|
|
1103
|
|
|
|
|
1104
|
|
|
// Send them to success page. |
|
1105
|
|
|
give_send_to_success_page(); |
|
1106
|
|
|
|
|
1107
|
|
|
} |
|
1108
|
|
View Code Duplication |
} else { |
|
|
|
|
|
|
1109
|
|
|
|
|
1110
|
|
|
// No customer, failed. |
|
1111
|
|
|
give_record_gateway_error( |
|
1112
|
|
|
__( 'Stripe Customer Creation Failed', 'give' ), |
|
1113
|
|
|
sprintf( |
|
1114
|
|
|
/* translators: %s Donation Data */ |
|
1115
|
|
|
__( 'Customer creation failed while processing the donation. Details: %s', 'give' ), |
|
1116
|
|
|
wp_json_encode( $donation_data ) |
|
1117
|
|
|
) |
|
1118
|
|
|
); |
|
1119
|
|
|
give_set_error( 'stripe_error', __( 'The Stripe Gateway returned an error while processing the donation.', 'give' ) ); |
|
1120
|
|
|
give_send_back_to_checkout( '?payment-mode=' . give_clean( $_POST['payment-mode'] ) ); |
|
1121
|
|
|
|
|
1122
|
|
|
} // End if(). |
|
1123
|
|
|
} else { |
|
1124
|
|
|
give_send_back_to_checkout( '?payment-mode=' . give_clean( $_POST['payment-mode'] ) ); |
|
1125
|
|
|
} // End if(). |
|
1126
|
|
|
} |
|
1127
|
|
|
|
|
1128
|
|
|
/** |
|
1129
|
|
|
* Process additional authentication. |
|
1130
|
|
|
* |
|
1131
|
|
|
* @param int $donation_id Donation ID. |
|
1132
|
|
|
* @param \Stripe\PaymentIntent $payment_intent Stripe Payment Intent Object. |
|
1133
|
|
|
* |
|
1134
|
|
|
* @since 2.5.0 |
|
1135
|
|
|
* |
|
1136
|
|
|
* @return void |
|
1137
|
|
|
*/ |
|
1138
|
|
|
function give_stripe_process_additional_authentication( $donation_id, $payment_intent ) { |
|
1139
|
|
|
|
|
1140
|
|
|
// Additional steps required when payment intent status is set to `requires_action`. |
|
1141
|
|
|
if ( 'requires_action' === $payment_intent->status ) { |
|
1142
|
|
|
|
|
1143
|
|
|
$action_url = $payment_intent->next_action->redirect_to_url->url; |
|
1144
|
|
|
|
|
1145
|
|
|
// Save Payment Intent requires action related information to donation note and DB. |
|
1146
|
|
|
give_insert_payment_note( $donation_id, 'Stripe requires additional action to be fulfilled.' ); |
|
1147
|
|
|
give_update_meta( $donation_id, '_give_stripe_payment_intent_require_action_url', $action_url ); |
|
1148
|
|
|
|
|
1149
|
|
|
wp_redirect( $action_url ); |
|
1150
|
|
|
exit; |
|
1151
|
|
|
} |
|
1152
|
|
|
|
|
1153
|
|
|
} |
|
1154
|
|
|
|
|
1155
|
|
|
/** |
|
1156
|
|
|
* Converts Cents to Dollars |
|
1157
|
|
|
* |
|
1158
|
|
|
* @param string $cents Amount in cents. |
|
1159
|
|
|
* |
|
1160
|
|
|
* @since 2.5.0 |
|
1161
|
|
|
* |
|
1162
|
|
|
* @return string |
|
1163
|
|
|
*/ |
|
1164
|
|
|
function give_stripe_cents_to_dollars( $cents ) { |
|
1165
|
|
|
return ( $cents / 100 ); |
|
1166
|
|
|
} |
|
1167
|
|
|
|
|
1168
|
|
|
/** |
|
1169
|
|
|
* Converts Dollars to Cents |
|
1170
|
|
|
* |
|
1171
|
|
|
* @param string $dollars Amount in dollars. |
|
1172
|
|
|
* |
|
1173
|
|
|
* @since 2.5.0 |
|
1174
|
|
|
* |
|
1175
|
|
|
* @return string |
|
1176
|
|
|
*/ |
|
1177
|
|
|
function give_stripe_dollars_to_cents( $dollars ) { |
|
1178
|
|
|
return round( $dollars, give_currency_decimal_filter() ) * 100; |
|
1179
|
|
|
} |
|
1180
|
|
|
|
|
1181
|
|
|
/** |
|
1182
|
|
|
* Format currency for Stripe. |
|
1183
|
|
|
* |
|
1184
|
|
|
* @see https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support |
|
1185
|
|
|
* |
|
1186
|
|
|
* @param float $amount Donation amount. |
|
1187
|
|
|
* |
|
1188
|
|
|
* @since 2.5.4 |
|
1189
|
|
|
* |
|
1190
|
|
|
* @return mixed |
|
1191
|
|
|
*/ |
|
1192
|
|
|
function give_stripe_format_amount( $amount ) { |
|
1193
|
|
|
|
|
1194
|
|
|
// Return donation amount based on whether the currency is zero decimal or not. |
|
1195
|
|
|
if ( give_stripe_is_zero_decimal_currency() ) { |
|
1196
|
|
|
return round( $amount ); |
|
1197
|
|
|
} |
|
1198
|
|
|
|
|
1199
|
|
|
return give_stripe_dollars_to_cents( $amount ); |
|
1200
|
|
|
} |
|
1201
|
|
|
|
It seems like the type of the argument is not accepted by the function/method which you are calling.
In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.
We suggest to add an explicit type cast like in the following example: