/var/www/hkosl.com/aga/wp-content/plugins/simple-membership/ipn/swpm-stripe-subscription-ipn.php


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
<?php

include(SIMPLE_WP_MEMBERSHIP_PATH 'ipn/swpm_handle_subsc_ipn.php');

class 
SwpmStripeSubscriptionIpnHandler {

    public function 
__construct() {

        
$this->handle_stripe_ipn();
    }

    public function 
handle_stripe_ipn() {
        if (isset(
$_GET['hook'])) {
            
//this is Webhook notify from Stripe
            //TODO: add Webhook Signing Secret verification
            //To do this, we need to get customer ID, retreive its details from Stripe, get button_id from metadata
            //and see if the button has Signing Secret option set. If it is - we need to check signatures
            //More details here: https://stripe.com/docs/webhooks#signatures

            
$input = @file_get_contents("php://input");
            if (empty(
$input)) {
                
SwpmLog::log_simple_debug("Stripe Subscription Webhook sent empty data or page was accessed directly. Aborting."false);
                echo 
'Empty Webhook data received.';
                die;
            }
            
//SwpmLog::log_simple_debug($input, true);
            
$event_json json_decode($input);

            
$type $event_json->type;

            if (
$type == 'customer.subscription.deleted' || $type == "charge.refunded") {
                
//Subscription expired or refunded event
                
SwpmLog::log_simple_debug("Stripe Subscription Webhook received. Processing request..."true);
                
//Let's form minimal ipn_data array for swpm_handle_subsc_cancel_stand_alone
                
$customer $event_json->data->object->customer;
                
$subscr_id $event_json->data->object->id;
                
$ipn_data = array();
                
$ipn_data['subscr_id'] = $subscr_id;
                
$ipn_data['parent_txn_id'] = $customer;

                
swpm_handle_subsc_cancel_stand_alone($ipn_data);
            }
            
http_response_code(200); //tells Stripe we received this notify
            
return;
        }

        
SwpmLog::log_simple_debug("Stripe Subscription IPN received. Processing request..."true);
        
//SwpmLog::log_simple_debug(print_r($_REQUEST, true), true);//Useful for debugging purpose
        //Include the Stripe library.
        
include(SIMPLE_WP_MEMBERSHIP_PATH 'lib/stripe-gateway/init.php');

        
//Read and sanitize the request parameters.
        
$button_id sanitize_text_field($_REQUEST['item_number']);
        
$button_id absint($button_id);
        
$button_title sanitize_text_field($_REQUEST['item_name']);

        
$stripe_token sanitize_text_field($_POST['stripeToken']);
        
$stripe_token_type sanitize_text_field($_POST['stripeTokenType']);
        
$stripe_email sanitize_email($_POST['stripeEmail']);

        
//Retrieve the CPT for this button
        
$button_cpt get_post($button_id);
        if (!
$button_cpt) {
            
//Fatal error. Could not find this payment button post object.
            
SwpmLog::log_simple_debug("Fatal Error! Failed to retrieve the payment button post object for the given button ID: " $button_idfalse);
            
wp_die("Fatal Error! Payment button (ID: " $button_id ") does not exist. This request will fail.");
        }

        
$plan_id get_post_meta($button_id'stripe_plan_id'true);
        
$descr 'Subscription to "' $plan_id '" plan';

        
$membership_level_id get_post_meta($button_id'membership_level_id'true);

        
//Validate and verify some of the main values.
        //Validation passed. Go ahead with the charge.
        //Sandbox and other settings
        
$settings SwpmSettings::get_instance();
        
$sandbox_enabled $settings->get_value('enable-sandbox-testing');
        if (
$sandbox_enabled) {
            
SwpmLog::log_simple_debug("Sandbox payment mode is enabled. Using test API key details."true);
            
$secret_key get_post_meta($button_id'stripe_test_secret_key'true);
            ; 
//Use sandbox API key
        
} else {
            
$secret_key get_post_meta($button_id'stripe_live_secret_key'true);
            ; 
//Use live API key
        
}

        
//Set secret API key in the Stripe library
        
\Stripe\Stripe::setApiKey($secret_key);

        
// Get the credit card details submitted by the form
        
$token $stripe_token;

        
// Create the charge on Stripe's servers - this will charge the user's card
        
try {
            
$customer = \Stripe\Customer::create(array(
                        
'description' => $descr,
                        
'email' => $stripe_email,
                        
'source' => $token,
                        
'plan' => $plan_id,
                        
'trial_from_plan' => 'true',
            ));
        } catch (
Exception $e) {
            
SwpmLog::log_simple_debug("Error occurred during Stripe Subscribe. " $e->getMessage(), false);
            
$body $e->getJsonBody();
            
$error $body['error'];
            
$error_string print_r($errortrue);
            
SwpmLog::log_simple_debug("Error details: " $error_stringfalse);
            
wp_die("Stripe Subscription Error! " $e->getMessage() . $error_string);
        }

        
//Everything went ahead smoothly with the charge.
        
SwpmLog::log_simple_debug("Stripe Subscription successful."true);

        
//let's add button_id to metadata
        
$customer->metadata = array('button_id' => $button_id);
        try {
            
$customer->save();
        } catch (
Exception $e) {
            
SwpmLog::log_simple_debug("Error occurred during Stripe customer metadata update. " $e->getMessage(), false);
            
$body $e->getJsonBody();
            
SwpmLog::log_simple_debug("Error details: " $error_stringfalse);
        }

        
//Grab customer ID and set it as the transaction ID.
        
$txn_id $customer->id//$charge->balance_transaction;
        //Grab subscription ID
        
$subscr_id $customer->subscriptions->data[0]->id;
        
$custom sanitize_text_field($_REQUEST['custom']);
        
$custom_var SwpmTransactions::parse_custom_var($custom);
        
$swpm_id = isset($custom_var['swpm_id']) ? $custom_var['swpm_id'] : '';

        
$payment_amount $customer->subscriptions->data[0]->plan->amount 100;

        
//Create the $ipn_data array.
        
$ipn_data = array();
        
$ipn_data['mc_gross'] = $payment_amount;
        
$ipn_data['first_name'] = '';
        
$ipn_data['last_name'] = '';
        
$ipn_data['payer_email'] = $stripe_email;
        
$ipn_data['membership_level'] = $membership_level_id;
        
$ipn_data['txn_id'] = $txn_id;
        
$ipn_data['subscr_id'] = $subscr_id '|' $button_id;
        
$ipn_data['swpm_id'] = $swpm_id;
        
$ipn_data['ip'] = $custom_var['user_ip'];
        
$ipn_data['custom'] = $custom;
        
$ipn_data['gateway'] = 'stripe';
        
$ipn_data['status'] = 'completed';

        
$ipn_data['address_street'] = '';
        
$ipn_data['address_city'] = '';
        
$ipn_data['address_state'] = '';
        
$ipn_data['address_zipcode'] = '';
        
$ipn_data['country'] = '';

        
//Handle the membership signup related tasks.
        
swpm_handle_subsc_signup_stand_alone($ipn_data$membership_level_id$txn_id$swpm_id);

        
//Save the transaction record
        
SwpmTransactions::save_txn_record($ipn_data);
        
SwpmLog::log_simple_debug('Transaction data saved.'true);

        
//Trigger the stripe IPN processed action hook (so other plugins can can listen for this event).
        
do_action('swpm_stripe_ipn_processed'$ipn_data);

        
do_action('swpm_payment_ipn_processed'$ipn_data);

        
//Redirect the user to the return URL (or to the homepage if a return URL is not specified for this payment button).
        
$return_url get_post_meta($button_id'return_url'true);
        if (empty(
$return_url)) {
            
$return_url SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
        }
        
SwpmLog::log_simple_debug("Redirecting customer to: " $return_urltrue);
        
SwpmLog::log_simple_debug("End of Stripe Subscription IPN processing."truetrue);
        
SwpmMiscUtils::redirect_to_url($return_url);
    }

}

$swpm_stripe_subscription_ipn = new SwpmStripeSubscriptionIpnHandler();