class-wc-subscriptions-payment-gateways.php
8.88 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
<?php
/**
* Subscriptions Payment Gateways
*
* Hooks into the WooCommerce payment gateways class to add subscription specific functionality.
*
* @package WooCommerce Subscriptions
* @subpackage WC_Subscriptions_Payment_Gateways
* @category Class
* @author Brent Shepherd
* @since 1.0
*/
class WC_Subscriptions_Payment_Gateways {
protected static $one_gateway_supports = array();
/**
* Bootstraps the class and hooks required actions & filters.
*
* @since 1.0
*/
public static function init() {
add_action( 'init', __CLASS__ . '::init_paypal', 10 );
add_filter( 'woocommerce_available_payment_gateways', __CLASS__ . '::get_available_payment_gateways' );
add_filter( 'woocommerce_no_available_payment_methods_message', __CLASS__ . '::no_available_payment_methods_message' );
// Create a custom hook for gateways that need to manually charge recurring payments
add_action( 'woocommerce_scheduled_subscription_payment', __CLASS__ . '::gateway_scheduled_subscription_payment', 10, 1 );
// Create a gateway specific hooks for subscription events
add_action( 'woocommerce_subscription_status_updated', __CLASS__ . '::trigger_gateway_status_updated_hook', 10, 2 );
}
/**
* Instantiate our custom PayPal class
*
* @since 2.0
*/
public static function init_paypal() {
require_once( 'paypal/class-wcs-paypal.php' );
WCS_PayPal::init();
}
/**
* Returns a payment gateway object by gateway's ID, or false if it could not find the gateway.
*
* @since 1.2.4
*/
public static function get_payment_gateway( $gateway_id ) {
$found_gateway = false;
if ( WC()->payment_gateways ) {
foreach ( WC()->payment_gateways->payment_gateways() as $gateway ) {
if ( $gateway_id == $gateway->id ) {
$found_gateway = $gateway;
}
}
}
return $found_gateway;
}
/**
* Only display the gateways which support subscriptions if manual payments are not allowed.
*
* @since 1.0
*/
public static function get_available_payment_gateways( $available_gateways ) {
if ( WC_Subscriptions_Cart::cart_contains_subscription() || ( isset( $_GET['order_id'] ) && wcs_order_contains_subscription( $_GET['order_id'] ) ) ) {
$accept_manual_renewals = ( 'no' !== get_option( WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals', 'no' ) ) ? true : false;
$subscriptions_in_cart = count( WC()->cart->recurring_carts );
foreach ( $available_gateways as $gateway_id => $gateway ) {
$supports_subscriptions = $gateway->supports( 'subscriptions' );
// Remove the payment gateway if there are multiple subscriptions in the cart and this gateway either doesn't support multiple subscriptions or isn't manual (all manual gateways support multiple subscriptions)
if ( $subscriptions_in_cart > 1 && $gateway->supports( 'multiple_subscriptions' ) !== true && ( $supports_subscriptions || ! $accept_manual_renewals ) ) {
unset( $available_gateways[ $gateway_id ] );
// If there is just the one subscription the cart, remove the payment gateway if manual renewals are disabled and this gateway doesn't support automatic payments
} elseif ( ! $supports_subscriptions && ! $accept_manual_renewals ) {
unset( $available_gateways[ $gateway_id ] );
}
}
}
return $available_gateways;
}
/**
* Helper function to check if at least one payment gateway on the site supports a certain subscription feature.
*
* @since 2.0
*/
public static function one_gateway_supports( $supports_flag ) {
// Only check if we haven't already run the check
if ( ! isset( self::$one_gateway_supports[ $supports_flag ] ) ) {
self::$one_gateway_supports[ $supports_flag ] = false;
foreach ( WC()->payment_gateways->get_available_payment_gateways() as $gateway ) {
if ( $gateway->supports( $supports_flag ) ) {
self::$one_gateway_supports[ $supports_flag ] = true;
break;
}
}
}
return self::$one_gateway_supports[ $supports_flag ];
}
/**
* Improve message displayed on checkout when a subscription is in the cart but not gateways support subscriptions.
*
* @since 1.5.2
*/
public static function no_available_payment_methods_message( $no_gateways_message ) {
if ( WC_Subscriptions_Cart::cart_contains_subscription() && 'no' == get_option( WC_Subscriptions_Admin::$option_prefix . '_accept_manual_renewals', 'no' ) ) {
$no_gateways_message = __( 'Sorry, it seems there are no available payment methods which support subscriptions. Please contact us if you require assistance or wish to make alternate arrangements.', 'woocommerce-subscriptions' );
}
return $no_gateways_message;
}
/**
* Fire a gateway specific whenever a subscription's status is changed.
*
* @since 2.0
*/
public static function trigger_gateway_status_updated_hook( $subscription, $new_status ) {
if ( $subscription->is_manual() ) {
return;
}
switch ( $new_status ) {
case 'active' :
$hook_prefix = 'woocommerce_subscription_activated_';
break;
case 'on-hold' :
$hook_prefix = 'woocommerce_subscription_on-hold_';
break;
case 'pending-cancel' :
$hook_prefix = 'woocommerce_subscription_pending-cancel_';
break;
case 'cancelled' :
$hook_prefix = 'woocommerce_subscription_cancelled_';
break;
case 'expired' :
$hook_prefix = 'woocommerce_subscription_expired_';
break;
default :
$hook_prefix = apply_filters( 'woocommerce_subscriptions_gateway_status_updated_hook_prefix', 'woocommerce_subscription_status_updated_', $subscription, $new_status );
break;
}
do_action( $hook_prefix . $subscription->payment_method, $subscription );
}
/**
* Fire a gateway specific hook for when a subscription payment is due.
*
* @since 1.0
*/
public static function gateway_scheduled_subscription_payment( $subscription_id, $deprecated = null ) {
// Passing the old $user_id/$subscription_key parameters
if ( null != $deprecated ) {
_deprecated_argument( __METHOD__, '2.0', 'Second parameter is deprecated' );
$subscription = wcs_get_subscription_from_key( $deprecated );
} else {
$subscription = wcs_get_subscription( $subscription_id );
}
if ( ! $subscription->is_manual() && $subscription->get_total() > 0 && ! empty( $subscription->payment_method ) ) {
do_action( 'woocommerce_scheduled_subscription_payment_' . $subscription->payment_method, $subscription->get_total(), $subscription->get_last_order( 'all' ) );
}
}
/**
* Fire a gateway specific hook for when a subscription is activated.
*
* @since 1.0
*/
public static function trigger_gateway_activated_subscription_hook( $user_id, $subscription_key ) {
_deprecated_function( __METHOD__, '2.0', __CLASS__ . '::trigger_gateway_status_updated_hook()' );
self::trigger_gateway_status_updated_hook( wcs_get_subscription_from_key( $subscription_key ), 'active' );
}
/**
* Fire a gateway specific hook for when a subscription is activated.
*
* @since 1.0
*/
public static function trigger_gateway_reactivated_subscription_hook( $user_id, $subscription_key ) {
_deprecated_function( __METHOD__, '2.0', __CLASS__ . '::trigger_gateway_status_updated_hook()' );
self::trigger_gateway_status_updated_hook( wcs_get_subscription_from_key( $subscription_key ), 'active' );
}
/**
* Fire a gateway specific hook for when a subscription is on-hold.
*
* @since 1.2
*/
public static function trigger_gateway_subscription_put_on_hold_hook( $user_id, $subscription_key ) {
_deprecated_function( __METHOD__, '2.0', __CLASS__ . '::trigger_gateway_status_updated_hook()' );
self::trigger_gateway_status_updated_hook( wcs_get_subscription_from_key( $subscription_key ), 'on-hold' );
}
/**
* Fire a gateway specific when a subscription is cancelled.
*
* @since 1.0
*/
public static function trigger_gateway_cancelled_subscription_hook( $user_id, $subscription_key ) {
_deprecated_function( __METHOD__, '2.0', __CLASS__ . '::trigger_gateway_status_updated_hook()' );
self::trigger_gateway_status_updated_hook( wcs_get_subscription_from_key( $subscription_key ), 'cancelled' );
}
/**
* Fire a gateway specific hook when a subscription expires.
*
* @since 1.0
*/
public static function trigger_gateway_subscription_expired_hook( $user_id, $subscription_key ) {
_deprecated_function( __METHOD__, '2.0', __CLASS__ . '::trigger_gateway_status_updated_hook()' );
self::trigger_gateway_status_updated_hook( wcs_get_subscription_from_key( $subscription_key ), 'expired' );
}
/**
* Fired a gateway specific when a subscription was suspended. Suspended status was changed in 1.2 to match
* WooCommerce with the "on-hold" status.
*
* @deprecated 1.2
* @since 1.0
*/
public static function trigger_gateway_suspended_subscription_hook( $user_id, $subscription_key ) {
_deprecated_function( __METHOD__, '1.2', __CLASS__ . '::trigger_gateway_subscription_put_on_hold_hook( $subscription_key, $user_id )' );
self::trigger_gateway_subscription_put_on_hold_hook( $subscription_key, $user_id );
}
}
WC_Subscriptions_Payment_Gateways::init();