swpm-stripe-buy-now-ipn.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. <?php
  2. require SIMPLE_WP_MEMBERSHIP_PATH . 'ipn/swpm_handle_subsc_ipn.php';
  3. class SwpmStripeBuyNowIpnHandler {
  4. public function __construct() {
  5. $this->handle_stripe_ipn();
  6. }
  7. public function handle_stripe_ipn() {
  8. SwpmLog::log_simple_debug( 'Stripe Buy Now IPN received. Processing request...', true );
  9. // SwpmLog::log_simple_debug(print_r($_REQUEST, true), true);//Useful for debugging purpose
  10. // Include the Stripe library.
  11. SwpmMiscUtils::load_stripe_lib();
  12. // Read and sanitize the request parameters.
  13. $button_id = sanitize_text_field( $_REQUEST['item_number'] );
  14. $button_id = absint( $button_id );
  15. $button_title = sanitize_text_field( $_REQUEST['item_name'] );
  16. $payment_amount = sanitize_text_field( $_REQUEST['item_price'] );
  17. $currency_code = sanitize_text_field( $_REQUEST['currency_code'] );
  18. $zero_cents = unserialize( SIMPLE_WP_MEMBERSHIP_STRIPE_ZERO_CENTS );
  19. if ( in_array( $currency_code, $zero_cents ) ) {
  20. $price_in_cents = $payment_amount;
  21. } else {
  22. $price_in_cents = $payment_amount * 100;// The amount (in cents). This value is used in Stripe API.
  23. }
  24. $stripe_token = filter_input( INPUT_POST, 'stripeToken', FILTER_SANITIZE_STRING );
  25. $stripe_token_type = filter_input( INPUT_POST, 'stripeTokenType', FILTER_SANITIZE_STRING );
  26. $stripe_email = filter_input( INPUT_POST, 'stripeEmail', FILTER_SANITIZE_EMAIL );
  27. // Retrieve the CPT for this button
  28. $button_cpt = get_post( $button_id );
  29. if ( ! $button_cpt ) {
  30. // Fatal error. Could not find this payment button post object.
  31. SwpmLog::log_simple_debug( 'Fatal Error! Failed to retrieve the payment button post object for the given button ID: ' . $button_id, false );
  32. wp_die( esc_html( sprintf( 'Fatal Error! Payment button (ID: %d) does not exist. This request will fail.', $button_id ) ) );
  33. }
  34. $membership_level_id = get_post_meta( $button_id, 'membership_level_id', true );
  35. // Validate and verify some of the main values.
  36. $true_payment_amount = get_post_meta( $button_id, 'payment_amount', true );
  37. $true_payment_amount = apply_filters( 'swpm_payment_amount_filter', $true_payment_amount, $button_id );
  38. if ( $payment_amount != $true_payment_amount ) {
  39. // Fatal error. Payment amount may have been tampered with.
  40. $error_msg = 'Fatal Error! Received payment amount (' . $payment_amount . ') does not match with the original amount (' . $true_payment_amount . ')';
  41. SwpmLog::log_simple_debug( $error_msg, false );
  42. wp_die( esc_html( $error_msg ) );
  43. }
  44. $true_currency_code = get_post_meta( $button_id, 'payment_currency', true );
  45. if ( $currency_code != $true_currency_code ) {
  46. // Fatal error. Currency code may have been tampered with.
  47. $error_msg = 'Fatal Error! Received currency code (' . $currency_code . ') does not match with the original code (' . $true_currency_code . ')';
  48. SwpmLog::log_simple_debug( $error_msg, false );
  49. wp_die( esc_html( $error_msg ) );
  50. }
  51. // Validation passed. Go ahead with the charge.
  52. // Sandbox and other settings
  53. $settings = SwpmSettings::get_instance();
  54. $sandbox_enabled = $settings->get_value( 'enable-sandbox-testing' );
  55. //API keys
  56. $api_keys = SwpmMiscUtils::get_stripe_api_keys_from_payment_button( $button_id, ! $sandbox_enabled );
  57. // Set secret API key in the Stripe library
  58. \Stripe\Stripe::setApiKey( $api_keys['secret'] );
  59. // Get the credit card details submitted by the form
  60. $token = $stripe_token;
  61. // Create the charge on Stripe's servers - this will charge the user's card
  62. try {
  63. $charge = \Stripe\Charge::create(
  64. array(
  65. 'amount' => $price_in_cents, // Amount in cents
  66. 'currency' => strtolower( $currency_code ),
  67. 'source' => $token,
  68. 'description' => $button_title,
  69. 'receipt_email' => $stripe_email,
  70. )
  71. );
  72. } catch ( \Stripe\Error\Card $e ) {
  73. // The card has been declined
  74. SwpmLog::log_simple_debug( 'Stripe Charge Error! The card has been declined. ' . $e->getMessage(), false );
  75. $body = $e->getJsonBody();
  76. $error = $body['error'];
  77. $error_string = print_r( $error, true );
  78. SwpmLog::log_simple_debug( 'Error details: ' . $error_string, false );
  79. wp_die( esc_html( 'Stripe Charge Error! Card charge has been declined. ' . $e->getMessage() . $error_string ) );
  80. }
  81. // Everything went ahead smoothly with the charge.
  82. SwpmLog::log_simple_debug( 'Stripe Buy Now charge successful.', true );
  83. // Grab the charge ID and set it as the transaction ID.
  84. $txn_id = $charge->id;// $charge->balance_transaction;
  85. // The charge ID can be used to retrieve the transaction details using hte following call.
  86. // \Stripe\Charge::retrieve($charge->id);
  87. $custom = sanitize_text_field( $_REQUEST['custom'] );
  88. $custom_var = SwpmTransactions::parse_custom_var( $custom );
  89. $swpm_id = isset( $custom_var['swpm_id'] ) ? $custom_var['swpm_id'] : '';
  90. // Create the $ipn_data array.
  91. $ipn_data = array();
  92. $ipn_data['mc_gross'] = $payment_amount;
  93. $ipn_data['first_name'] = '';
  94. $ipn_data['last_name'] = '';
  95. $ipn_data['payer_email'] = $stripe_email;
  96. $ipn_data['membership_level'] = $membership_level_id;
  97. $ipn_data['txn_id'] = $txn_id;
  98. $ipn_data['subscr_id'] = $txn_id;/* Set the txn_id as subscriber_id so it is similar to PayPal buy now. Also, it can connect to the profile in the "payments" menu. */
  99. $ipn_data['swpm_id'] = $swpm_id;
  100. $ipn_data['ip'] = $custom_var['user_ip'];
  101. $ipn_data['custom'] = $custom;
  102. $ipn_data['gateway'] = 'stripe';
  103. $ipn_data['status'] = 'completed';
  104. $ipn_data['address_street'] = '';
  105. $ipn_data['address_city'] = '';
  106. $ipn_data['address_state'] = '';
  107. $ipn_data['address_zipcode'] = '';
  108. $ipn_data['country'] = '';
  109. // Handle the membership signup related tasks.
  110. swpm_handle_subsc_signup_stand_alone( $ipn_data, $membership_level_id, $txn_id, $swpm_id );
  111. // Save the transaction record
  112. SwpmTransactions::save_txn_record( $ipn_data );
  113. SwpmLog::log_simple_debug( 'Transaction data saved.', true );
  114. // Trigger the stripe IPN processed action hook (so other plugins can can listen for this event).
  115. do_action( 'swpm_stripe_ipn_processed', $ipn_data );
  116. do_action( 'swpm_payment_ipn_processed', $ipn_data );
  117. // Redirect the user to the return URL (or to the homepage if a return URL is not specified for this payment button).
  118. $return_url = get_post_meta( $button_id, 'return_url', true );
  119. if ( empty( $return_url ) ) {
  120. $return_url = SIMPLE_WP_MEMBERSHIP_SITE_HOME_URL;
  121. }
  122. SwpmLog::log_simple_debug( 'Redirecting customer to: ' . $return_url, true );
  123. SwpmLog::log_simple_debug( 'End of Stripe Buy Now IPN processing.', true, true );
  124. SwpmMiscUtils::redirect_to_url( $return_url );
  125. }
  126. }
  127. $swpm_stripe_buy_ipn = new SwpmStripeBuyNowIpnHandler();