Guest User

Untitled

a guest
Mar 28th, 2019
7,127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 15.72 KB | None | 0 0
  1. <?php
  2. /**
  3.  * PayPal Standard Payment Gateway
  4.  *
  5.  * @package     Restrict Content Pro
  6.  * @subpackage  Classes/Gateways/PayPal
  7.  * @copyright   Copyright (c) 2017, Pippin Williamson
  8.  * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
  9.  * @since       2.1
  10. */
  11.  
  12. class RCP_Payment_Gateway_Paypal_BRL extends RCP_Payment_Gateway {
  13.  
  14.     private $api_endpoint;
  15.     private $checkout_url;
  16.     protected $username;
  17.     protected $password;
  18.     protected $signature;
  19.  
  20.     /**
  21.      * Get things going
  22.      *
  23.      * @access public
  24.      * @since  2.1
  25.      * @return void
  26.      */
  27.     public function init() {
  28.  
  29.         global $rcp_options;
  30.  
  31.         $this->supports[]  = 'one-time';
  32.         $this->supports[]  = 'recurring';
  33.         $this->supports[]  = 'fees';
  34.         $this->supports[] = 'trial';
  35.  
  36.         if( $this->test_mode ) {
  37.  
  38.             $this->api_endpoint = 'https://api-3t.sandbox.paypal.com/nvp';
  39.             $this->checkout_url = 'https://www.sandbox.paypal.com/webscr&cmd=_express-checkout&token=';
  40.  
  41.         } else {
  42.  
  43.             $this->api_endpoint = 'https://api-3t.paypal.com/nvp';
  44.             $this->checkout_url = 'https://www.paypal.com/webscr&cmd=_express-checkout&token=';
  45.  
  46.         }
  47.  
  48.         if( rcp_has_paypal_api_access() ) {
  49.  
  50.             $creds = rcp_get_paypal_api_credentials();
  51.  
  52.             $this->username  = $creds['username'];
  53.             $this->password  = $creds['password'];
  54.             $this->signature = $creds['signature'];
  55.  
  56.         }
  57.  
  58.     }
  59.  
  60.     /**
  61.      * Process registration
  62.      *
  63.      * @access public
  64.      * @since  2.1
  65.      * @return void
  66.      */
  67.     public function process_signup() {
  68.  
  69.         global $rcp_options;
  70.  
  71.         if( $this->test_mode ) {
  72.             $paypal_redirect = 'https://www.sandbox.paypal.com/cgi-bin/webscr/?';
  73.         } else {
  74.             $paypal_redirect = 'https://www.paypal.com/cgi-bin/webscr/?';
  75.         }
  76.  
  77.         $cancel_url = wp_get_referer();
  78.         if ( empty( $cancel_url ) ) {
  79.             $cancel_url = get_permalink( $rcp_options['registration_page'] );
  80.         }
  81.  
  82.         // Setup PayPal arguments
  83.         $paypal_args = array(
  84.             'business'      => trim( $rcp_options['paypal_email'] ),
  85.             'email'         => $this->email,
  86.             'item_number'   => $this->subscription_key,
  87.             'item_name'     => $this->subscription_name,
  88.             'no_shipping'   => '1',
  89.             'shipping'      => '0',
  90.             'no_note'       => '1',
  91.             'currency_code' => 'BRL',
  92.             'charset'       => get_bloginfo( 'charset' ),
  93.             'custom'        => $this->user_id,
  94.             'rm'            => '2',
  95.             'return'        => $this->return_url,
  96.             'cancel_return' => $cancel_url,
  97.             'notify_url'    => add_query_arg( 'listener', 'IPN', home_url( 'index.php' ) ),
  98.             'cbt'           => get_bloginfo( 'name' ),
  99.             'tax'           => 0,
  100.             'page_style'    => ! empty( $rcp_options['paypal_page_style'] ) ? trim( $rcp_options['paypal_page_style'] ) : '',
  101.             'bn'            => 'EasyDigitalDownloads_SP'
  102.         );
  103.  
  104.         // recurring paypal payment
  105.         if( $this->auto_renew && ! empty( $this->length ) ) {
  106.  
  107.             // recurring paypal payment
  108.             $paypal_args['cmd'] = '_xclick-subscriptions';
  109.             $paypal_args['src'] = '1';
  110.             $paypal_args['sra'] = '1';
  111.             $paypal_args['a3'] = currencyConverterPaypalBrl("USD","BRL",$this->amount);
  112.             $paypal_args['a1'] = currencyConverterPaypalBrl("USD","BRL",$this->initial_amount);
  113.  
  114.             $paypal_args['p3'] = $this->length;
  115.             $paypal_args['p1'] = $this->length;
  116.  
  117.             switch ( $this->length_unit ) {
  118.  
  119.                 case "day" :
  120.  
  121.                     $paypal_args['t3'] = 'D';
  122.                     $paypal_args['t1'] = 'D';
  123.                     break;
  124.  
  125.                 case "month" :
  126.  
  127.                     $paypal_args['t3'] = 'M';
  128.                     $paypal_args['t1'] = 'M';
  129.                     break;
  130.  
  131.                 case "year" :
  132.  
  133.                     $paypal_args['t3'] = 'Y';
  134.                     $paypal_args['t1'] = 'Y';
  135.                     break;
  136.  
  137.             }
  138.  
  139.             if ( $this->is_trial() ) {
  140.  
  141.                 $paypal_args['a1'] = 0;
  142.                 $paypal_args['p1'] = $this->subscription_data['trial_duration'];
  143.  
  144.                 switch ( $this->subscription_data['trial_duration_unit'] ) {
  145.  
  146.                     case 'day':
  147.                         $paypal_args['t1'] = 'D';
  148.                         break;
  149.  
  150.                     case 'month':
  151.                         $paypal_args['t1'] = 'M';
  152.                         break;
  153.  
  154.                     case 'year':
  155.                         $paypal_args['t1'] = 'Y';
  156.                         break;
  157.                 }
  158.             }
  159.  
  160.         } else {
  161.  
  162.             // one time payment
  163.             $paypal_args['cmd'] = '_xclick';
  164.             $paypal_args['amount'] = currencyConverterPaypalBrl("USD","BRL",$this->initial_amount);
  165.  
  166.         }
  167.  
  168.         $paypal_args = apply_filters( 'rcp_paypal_args', $paypal_args, $this );
  169.  
  170.         // Build query
  171.         $paypal_redirect .= http_build_query( $paypal_args );
  172.  
  173.         // Fix for some sites that encode the entities
  174.         $paypal_redirect = str_replace( '&amp;', '&', $paypal_redirect );
  175.  
  176.         // Redirect to paypal
  177.         header( 'Location: ' . $paypal_redirect );
  178.         exit;
  179.  
  180.     }
  181.  
  182.     /**
  183.      * Process PayPal IPN
  184.      *
  185.      * @access public
  186.      * @since  2.1
  187.      * @return void
  188.      */
  189.     public function process_webhooks() {
  190.  
  191.         if( ! isset( $_GET['listener'] ) || strtoupper( $_GET['listener'] ) != 'IPN' ) {
  192.             return;
  193.         }
  194.  
  195.         rcp_log( 'Starting to process PayPal Standard IPN.' );
  196.  
  197.         global $rcp_options;
  198.  
  199.         nocache_headers();
  200.  
  201.         if( ! class_exists( 'IpnListener' ) ) {
  202.             // instantiate the IpnListener class
  203.             include( RCP_PLUGIN_DIR . 'includes/gateways/paypal/paypal-ipnlistener.php' );
  204.         }
  205.  
  206.         $listener = new IpnListener();
  207.         $verified = false;
  208.  
  209.         if( $this->test_mode ) {
  210.             $listener->use_sandbox = true;
  211.         }
  212.  
  213.         /*
  214.         if( isset( $rcp_options['ssl'] ) ) {
  215.             $listener->use_ssl = true;
  216.         } else {
  217.             $listener->use_ssl = false;
  218.         }
  219.         */
  220.  
  221.         //To post using the fsockopen() function rather than cURL, use:
  222.         if( isset( $rcp_options['disable_curl'] ) ) {
  223.             $listener->use_curl = false;
  224.         }
  225.  
  226.         try {
  227.             $listener->requirePostMethod();
  228.             $verified = $listener->processIpn();
  229.         } catch ( Exception $e ) {
  230.             status_header( 402 );
  231.             //die( 'IPN exception: ' . $e->getMessage() );
  232.         }
  233.  
  234.         /*
  235.         The processIpn() method returned true if the IPN was "VERIFIED" and false if it
  236.         was "INVALID".
  237.         */
  238.         if ( $verified || isset( $_POST['verification_override'] ) || ( $this->test_mode || isset( $rcp_options['disable_ipn_verify'] ) ) )  {
  239.  
  240.             status_header( 200 );
  241.  
  242.             $user_id = 0;
  243.             $posted  = apply_filters('rcp_ipn_post', $_POST ); // allow $_POST to be modified
  244.  
  245.             if( ! empty( $posted['subscr_id'] ) ) {
  246.  
  247.                 $user_id = rcp_get_member_id_from_profile_id( $posted['subscr_id'] );
  248.  
  249.             }
  250.  
  251.             if( empty( $user_id ) && ! empty( $posted['custom'] ) && is_numeric( $posted['custom'] ) ) {
  252.  
  253.                 $user_id = absint( $posted['custom'] );
  254.  
  255.             }
  256.  
  257.             if( empty( $user_id ) && ! empty( $posted['payer_email'] ) ) {
  258.  
  259.                 $user    = get_user_by( 'email', $posted['payer_email'] );
  260.                 $user_id = $user ? $user->ID : false;
  261.  
  262.             }
  263.  
  264.             $member = new RCP_Member( $user_id );
  265.  
  266.             if( ! $member || ! $member->ID > 0 ) {
  267.                 rcp_log( sprintf( 'PayPal IPN Failed: unable to find associated member in RCP. Item Name: %s; Item Number: %d; TXN Type: %s; TXN ID: %s', $posted['item_name'], $posted['item_number'], $posted['txn_type'], $posted['txn_id'] ), true );
  268.                 die( 'no member found' );
  269.             }
  270.  
  271.             rcp_log( sprintf( 'Processing IPN for member #%d.', $member->ID ) );
  272.  
  273.             $subscription_id = $member->get_pending_subscription_id();
  274.  
  275.             if( empty( $subscription_id ) ) {
  276.  
  277.                 $subscription_id = $member->get_subscription_id();
  278.  
  279.             }
  280.  
  281.             if( ! $subscription_id ) {
  282.                 die( 'no subscription for member found' );
  283.             }
  284.  
  285.             if( ! rcp_get_subscription_details( $subscription_id ) ) {
  286.                 die( 'no subscription level found' );
  287.             }
  288.  
  289.             $subscription_key   = $posted['item_number'];
  290.             $has_trial          = isset( $posted['mc_amount1'] ) && '0.00' == $posted['mc_amount1'];
  291.             $amount             = ! $has_trial ? number_format( (float) $posted['mc_gross'], 2, '.', '' ) : number_format( (float) $posted['mc_amount1'], 2, '.', '' );
  292.             $amount = currencyConverterPaypalBrl("USD","BRL",$amount);
  293.             $payment_status     = ! empty( $posted['payment_status'] ) ? $posted['payment_status'] : false;
  294.             $currency_code      = "USD";
  295.  
  296.             $pending_amount = get_user_meta( $member->ID, 'rcp_pending_subscription_amount', true );
  297.             $pending_amount = number_format( (float) $pending_amount, 2, '.', '' );
  298.  
  299.             $pending_payment_id = $member->get_pending_payment_id();
  300.  
  301.             // Check for invalid amounts in the IPN data
  302.             if ( ! empty( $pending_amount ) && ! empty( $amount ) && in_array( $posted['txn_type'], array( 'web_accept', 'subscr_payment' ) ) ) {
  303.  
  304.                 if ( $amount < $pending_amount ) {
  305.  
  306.                     rcp_add_member_note( $member->ID, sprintf( __( 'Incorrect amount received in the IPN. Amount received was %s. The amount should have been %s. PayPal Transaction ID: %s', 'rcp' ), $amount, $pending_amount, sanitize_text_field( $posted['txn_id'] ) ) );
  307.  
  308.                     die( 'incorrect amount' );
  309.  
  310.                 } else {
  311.                     delete_user_meta( $member->ID, 'rcp_pending_subscription_amount' );
  312.                 }
  313.  
  314.             }
  315.  
  316.             $rcp_payments = new RCP_Payments();
  317.  
  318.             // setup the payment info in an array for storage
  319.             $payment_data = array(
  320.                 'date'             => ! empty( $posted['payment_date'] ) ? date( 'Y-m-d H:i:s', strtotime( $posted['payment_date'], current_time( 'timestamp' ) ) ) : date( 'Y-m-d H:i:s', strtotime( 'now', current_time( 'timestamp' ) ) ),
  321.                 'subscription'     => $posted['item_name'],
  322.                 'payment_type'     => $posted['txn_type'],
  323.                 'subscription_key' => $subscription_key,
  324.                 'amount'           => $amount,
  325.                 'user_id'          => $user_id,
  326.                 'transaction_id'   => ! empty( $posted['txn_id'] ) ? $posted['txn_id'] : false,
  327.                 'status'           => 'complete'
  328.             );
  329.  
  330.             // We don't want any empty values in the array in order to avoid deleting a transaction ID or other data.
  331.             foreach ( $payment_data as $payment_key => $payment_value ) {
  332.                 if ( empty( $payment_value ) ) {
  333.                     unset( $payment_data[ $payment_key ] );
  334.                 }
  335.             }
  336.  
  337.             do_action( 'rcp_valid_ipn', $payment_data, $user_id, $posted );
  338.  
  339.             if( $posted['txn_type'] == 'web_accept' || $posted['txn_type'] == 'subscr_payment' ) {
  340.  
  341.                 // only check for an existing payment if this is a payment IPD request
  342.                 if( ! empty( $posted['txn_id'] ) && $rcp_payments->payment_exists( $posted['txn_id'] ) ) {
  343.  
  344.                     do_action( 'rcp_ipn_duplicate_payment', $posted['txn_id'], $member, $this );
  345.  
  346.                     die( 'duplicate IPN detected' );
  347.                 }
  348.  
  349.                 if( ! rcp_is_valid_currency( $currency_code ) ) {
  350.                     // the currency code is invalid
  351.  
  352.                     rcp_log( sprintf( 'The currency code in a PayPal IPN request did not match the site currency code. Provided: %s', $currency_code ), true );
  353.  
  354.  
  355.                     die( 'invalid currency code' );
  356.                 }
  357.  
  358.             }
  359.  
  360.             if( isset( $rcp_options['email_ipn_reports'] ) ) {
  361.                 wp_mail( get_bloginfo('admin_email'), __( 'IPN report', 'rcp' ), $listener->getTextReport() );
  362.             }
  363.  
  364.             /* now process the kind of subscription/payment */
  365.  
  366.             // Subscriptions
  367.             switch ( $posted['txn_type'] ) :
  368.  
  369.                 case "subscr_signup" :
  370.                     // when a new user signs up
  371.  
  372.                     rcp_log( 'Processing PayPal Standard subscr_signup IPN.' );
  373.  
  374.                     // store the recurring payment ID
  375.                     update_user_meta( $user_id, 'rcp_paypal_subscriber', $posted['payer_id'] );
  376.  
  377.                     if( $member->just_upgraded() && $member->can_cancel() ) {
  378.                         $cancelled = $member->cancel_payment_profile( false );
  379.                     }
  380.  
  381.                     $member->set_payment_profile_id( $posted['subscr_id'] );
  382.                     $member->set_recurring( true );
  383.  
  384.                     if ( $has_trial && ! empty( $pending_payment_id ) ) {
  385.                         // This activates the trial.
  386.                         $rcp_payments->update( $pending_payment_id, $payment_data );
  387.                     }
  388.  
  389.                     do_action( 'rcp_ipn_subscr_signup', $user_id );
  390.                     do_action( 'rcp_webhook_recurring_payment_profile_created', $member, $this );
  391.  
  392.  
  393.                     die( 'successful subscr_signup' );
  394.  
  395.                     break;
  396.  
  397.                 case "subscr_payment" :
  398.  
  399.                     // when a user makes a recurring payment
  400.  
  401.                     rcp_log( 'Processing PayPal Standard subscr_payment IPN.' );
  402.  
  403.                     update_user_meta( $user_id, 'rcp_paypal_subscriber', $posted['payer_id'] );
  404.  
  405.                     if ( ! empty( $pending_payment_id ) ) {
  406.  
  407.                         $member->set_recurring( true );
  408.  
  409.                         // This activates the membership.
  410.                         $rcp_payments->update( $pending_payment_id, $payment_data );
  411.  
  412.                         $payment_id = $pending_payment_id;
  413.  
  414.                     } else {
  415.  
  416.                         $member->renew( true );
  417.  
  418.                         // record this payment in the database
  419.                         $payment_id = $rcp_payments->insert( $payment_data );
  420.  
  421.                     }
  422.  
  423.                     do_action( 'rcp_ipn_subscr_payment', $user_id );
  424.                     do_action( 'rcp_webhook_recurring_payment_processed', $member, $payment_id, $this );
  425.                     do_action( 'rcp_gateway_payment_processed', $member, $payment_id, $this );
  426.  
  427.                     die( 'successful subscr_payment' );
  428.  
  429.                     break;
  430.  
  431.                 case "subscr_cancel" :
  432.  
  433.                     rcp_log( 'Processing PayPal Standard subscr_cancel IPN.' );
  434.  
  435.                     if( isset( $posted['subscr_id'] ) && $posted['subscr_id'] == $member->get_payment_profile_id() && 'cancelled' !== $member->get_status() && ! $member->just_upgraded() ) {
  436.  
  437.                         // user is marked as cancelled but retains access until end of term
  438.                         if ( $member->is_active() ) {
  439.                             $member->cancel();
  440.                         } else {
  441.                             rcp_log( sprintf( 'Member #%d is not active - not cancelling account.', $member->ID ) );
  442.                         }
  443.  
  444.                         // set the use to no longer be recurring
  445.                         delete_user_meta( $user_id, 'rcp_paypal_subscriber' );
  446.  
  447.                         do_action( 'rcp_ipn_subscr_cancel', $user_id );
  448.                         do_action( 'rcp_webhook_cancel', $member, $this );
  449.  
  450.                         die( 'successful subscr_cancel' );
  451.  
  452.                     }
  453.  
  454.                     break;
  455.  
  456.                 case "subscr_failed" :
  457.  
  458.                     rcp_log( 'Processing PayPal Standard subscr_failed IPN.' );
  459.  
  460.                     if ( ! empty( $posted['txn_id'] ) ) {
  461.  
  462.                         $this->webhook_event_id = sanitize_text_field( $posted['txn_id'] );
  463.  
  464.                     } elseif ( ! empty( $posted['ipn_track_id'] ) ) {
  465.  
  466.                         $this->webhook_event_id = sanitize_text_field( $posted['ipn_track_id'] );
  467.                     }
  468.  
  469.                     do_action( 'rcp_recurring_payment_failed', $member, $this );
  470.                     do_action( 'rcp_ipn_subscr_failed' );
  471.  
  472.                     die( 'successful subscr_failed' );
  473.  
  474.                     break;
  475.  
  476.                 case "subscr_eot" :
  477.  
  478.                     // user's subscription has reached the end of its term
  479.  
  480.                     rcp_log( 'Processing PayPal Standard subscr_eot IPN.' );
  481.  
  482.                     if( isset( $posted['subscr_id'] ) && $posted['subscr_id'] == $member->get_payment_profile_id() && 'cancelled' !== $member->get_status() ) {
  483.  
  484.                         $member->set_status( 'expired' );
  485.  
  486.                     }
  487.  
  488.                     do_action('rcp_ipn_subscr_eot', $user_id );
  489.  
  490.  
  491.                     die( 'successful subscr_eot' );
  492.  
  493.                     break;
  494.  
  495.                 case "web_accept" :
  496.  
  497.                     rcp_log( sprintf( 'Processing PayPal Standard web_accept IPN. Payment status: %s', $payment_status ) );
  498.  
  499.                     switch ( strtolower( $payment_status ) ) :
  500.  
  501.                         case 'completed' :
  502.  
  503.                             if( $member->just_upgraded() && $member->can_cancel() ) {
  504.                                 $cancelled = $member->cancel_payment_profile( false );
  505.                                 if( $cancelled ) {
  506.  
  507.                                     $member->set_payment_profile_id( '' );
  508.  
  509.                                 }
  510.                             }
  511.  
  512.                             if ( ! empty( $pending_payment_id ) ) {
  513.  
  514.                                 // Complete the pending payment.
  515.  
  516.                                 $member->set_recurring( false );
  517.  
  518.                                 // This activates the membership.
  519.                                 $rcp_payments->update( $pending_payment_id, $payment_data );
  520.  
  521.                                 $payment_id = $pending_payment_id;
  522.  
  523.                             } else {
  524.  
  525.                                 // Renew the account.
  526.                                 $member->renew();
  527.  
  528.                                 $payment_id = $rcp_payments->insert( $payment_data );
  529.  
  530.                             }
  531.  
  532.                             do_action( 'rcp_gateway_payment_processed', $member, $payment_id, $this );
  533.  
  534.                             break;
  535.  
  536.                         case 'denied' :
  537.                         case 'expired' :
  538.                         case 'failed' :
  539.                         case 'voided' :
  540.                             $member->cancel();
  541.                             break;
  542.  
  543.                     endswitch;
  544.  
  545.  
  546.                     die( 'successful web_accept' );
  547.  
  548.                 break;
  549.  
  550.             case "cart" :
  551.             case "express_checkout" :
  552.             default :
  553.  
  554.                 break;
  555.  
  556.             endswitch;
  557.  
  558.         } else {
  559.  
  560.             rcp_log( 'Invalid PayPal IPN attempt.', true );
  561.  
  562.             if( isset( $rcp_options['email_ipn_reports'] ) ) {
  563.                 // an invalid IPN attempt was made. Send an email to the admin account to investigate
  564.                 wp_mail( get_bloginfo( 'admin_email' ), __( 'Invalid IPN', 'rcp' ), $listener->getTextReport() );
  565.             }
  566.  
  567.             status_header( 400 );
  568.             die( 'invalid IPN' );
  569.  
  570.         }
  571.  
  572.     }
  573.  
  574. }
Advertisement
Add Comment
Please, Sign In to add comment