We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 36760
    • 136 Posts
    Currently running MODX Revolution 2.1.3-pl (traditional).

    I’m just about done with this project I’ve been working on. The last piece is a button (or, three buttons I guess) that correspond to the different subscription options available. When an already logged in user clicks on a button to pick their subscription type, I want it to redirect them to PayPal where they make the payment. Once the payment is cleared (or however it works), I want PayPal to communicate with Modx and put that user into the paid user group (there is only one, regardless of subscription type), while still keeping the user in all of their other groups.

    I’ve found bits and pieces of how to put this all together. I have the PayPal IPN PHP example (https://cms.paypal.com/cms_content/US/en_US/files/developer/IPN_PHP_41.txt), and I found this eForm example for how to add things to the Modx database (http://wiki.modxcms.com/index.php/Use_eForm_to_Store_data_into_Database).

    I’m having trouble figuring out how to get the current logged in user’s id, and along with the id for the paid user group and the other numbers required for a table entry, pass it to the database using a button click (as opposed to a form). Also, in the user_group table, there are the columns for id, user group, member, role, rank. I know what each of those numbers does besides the one in the id column. It’s not the member id, and it’s not the user group id. So I don’t know what value I should pass along for that either.

    Finally, I have even less of an idea how to get all of this to communicate with the PayPal IPN script so it only gets changed once a payment is cleared.

    I don’t want someone to do all the work for me, but I wouldn’t be against a good tutorial or a solid example. Even just a nudge in the right direction, since I’ve never worked with any of this before.
      • 36760
      • 136 Posts
      Okay, I’m getting closer with this.

      I now have a "Pay Now" button from PayPal that’s redirecting to PayPal correctly, and going though my IPN file.

      Now I just need to figure out how to tell the IPN file to add a new entry to a database table once the payment is cleared. Something along these lines (I know this is incorrect, because it’s not working, but I’m not sure what will work).

      function agregarmember_groups
      	{
      		global $modx;
      		// Init our array
      		$dbTable = array();
      		$dbTable['id']         = $modx->db->escape('150');
      		$dbTable['user_group'] = $modx->db->escape('3');
      		$dbTable['member']     = $modx->db->escape('[[+modx.user.id]]');
      		$dbTable['role']       = $modx->db->escape('1');
                      $dbTable['rank']       = $modx->db->escape('0');
      		// Run the db insert query
      		$dbQuery = $modx->db->insert($dbTable, 'memeber_groups' );
      		return true;
      	}


      I need a new entry in the member_groups table for Modx, and I’m not sure how to achieve this. If anyone can point me in the right direction, I would appreciate it.
      • If that’s the actual code, and not a typo when posting your code...
        		$dbQuery = $modx->db->insert($dbTable, 'memeber_groups' );

        that should be ’member_groups’.
          Studying MODX in the desert - http://sottwell.com
          Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
          Join the Slack Community - http://modx.org
          • 36760
          • 136 Posts
          That was definitely a typo, thank you.

          Unfortunately, I still don’t think I’m using it within the IPN correctly. The code itself is giving me errors when I put the snippet on the page and load it, and I’m not quite sure how to fix the rest of them. If anyone could point me in the right direction I would appreciate it.

          My assumption was, if I put whatever I want to have happen after the payment is verified between the two curly brackets for that section, it would run if the payment is verified, but not run if there is an error. This could be a wrong assumption.

          Here is the IPN file:

          <?php
          // PHP 4.1
          
          // read the post from PayPal system and add 'cmd'
          $req = 'cmd=_notify-validate';
          
          foreach ($_POST as $key => $value) {
          $value = urlencode(stripslashes($value));
          $req .= "&$key=$value";
          }
          
          // post back to PayPal system to validate
          $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
          $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
          $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
          $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
          
          // assign posted variables to local variables
          $item_name = $_POST['item_name'];
          $item_number = $_POST['item_number'];
          $payment_status = $_POST['payment_status'];
          $payment_amount = $_POST['mc_gross'];
          $payment_currency = $_POST['mc_currency'];
          $txn_id = $_POST['txn_id'];
          $receiver_email = $_POST['receiver_email'];
          $payer_email = $_POST['payer_email'];
          
          if (!$fp) {
          // HTTP ERROR
          } else {
          fputs ($fp, $header . $req);
          while (!feof($fp)) {
          $res = fgets ($fp, 1024);
          if (strcmp ($res, "VERIFIED") == 0) {
          // check the payment_status is Completed
          // check that txn_id has not been previously processed
          // check that receiver_email is your Primary PayPal email
          // check that payment_amount/payment_currency are correct
          // process payment
          
          function agregarmember_groups
          	(
          		global $modx;
          		// Init our array
          		$dbTable = array();
          		$dbTable['id']         = $modx->db->escape('150');
          		$dbTable['user_group'] = $modx->db->escape('3');
          		$dbTable['member']     = $modx->db->escape('[[+modx.user.id]]');
          		$dbTable['role']       = $modx->db->escape('1');
                  $dbTable['rank']       = $modx->db->escape('0');
          		// Run the db insert query
          		$dbQuery = $modx->db->insert($dbTable, 'member_groups' );
          		return true;
          	)
          
          }
          else if (strcmp ($res, "INVALID") == 0) {
          // log for manual investigation
          }
          }
          fclose ($fp);
          }


          The two errors I’m getting when I just put the snippet for this code on a page are as follows:

          Parse error: syntax error, unexpected T_GLOBAL, expecting ’&’ or T_VARIABLE in /home/mldraf5/public_html/members/core/cache/includes/elements/modsnippet/56.include.cache.php on line 48

          Fatal error: Cannot use object of type modSession_mysql as array in /home/mldraf5/public_html/members/core/xpdo/validation/xpdovalidator.class.php on line 57
            • 36760
            • 136 Posts
            I tried out a different way of posting things to the database, but still no dice. I did get rid of the errors though, so that’s a plus (I was missing curly brackets).

            Here’s the latest piece of code I tried.

            <?php
            // PHP 4.1
            
            // read the post from PayPal system and add 'cmd'
            $req = 'cmd=_notify-validate';
            
            foreach ($_POST as $key => $value) {
            $value = urlencode(stripslashes($value));
            $req .= "&$key=$value";
            }
            
            // post back to PayPal system to validate
            $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
            $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
            $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
            $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30);
            
            // assign posted variables to local variables
            $item_name = $_POST['item_name'];
            $item_number = $_POST['item_number'];
            $payment_status = $_POST['payment_status'];
            $payment_amount = $_POST['mc_gross'];
            $payment_currency = $_POST['mc_currency'];
            $txn_id = $_POST['txn_id'];
            $receiver_email = $_POST['receiver_email'];
            $payer_email = $_POST['payer_email'];
            
            if (!$fp) {
            // HTTP ERROR
            } else {
            fputs ($fp, $header . $req);
            while (!feof($fp)) {
            $res = fgets ($fp, 1024);
            if (strcmp ($res, "VERIFIED") == 0) {
            // check the payment_status is Completed
            // check that txn_id has not been previously processed
            // check that receiver_email is your Primary PayPal email
            // check that payment_amount/payment_currency are correct
            // process payment
            
            function insert_my_rows() {
            	global $modx;
            	$table_name = $modx->getFullTableName( 'member_groups' );
            
                    $id = ('150');
                    $user_group = ('3');
                    $member = ('[[+modx.user.id]]');
                    $role = ('1');
                    $rank = ('0');
            
            	$fields = array('id'	        => $id,
            			'user_group'	=> $user_group,
            			'member'	=> $member,
            			'role'	        => $role,
                                    'rank'	        => $rank,
            			);
            	
            	$modx->db->insert( $fields, $table_name);
            }
            
            }
            else if (strcmp ($res, "INVALID") == 0) {
            // log for manual investigation
            }
            }
            fclose ($fp);
            }


            It’s possible this is less of a Modx related thing at this point, and more of a PayPal IPN thing. So maybe I’ll try asking over there. I’m still open to any help I can get though.
              • 4041
              • 788 Posts
              Looking at your code, it seems that the following post may be relevent to your issue ( note the part about the deprecated code being removed).
              http://modxcms.com/forums/index.php/topic,64823.0.html
                xforum
                http://frsbuilders.net (under construction) forum for evolution
                • 36760
                • 136 Posts
                It would seem that may be my problem. Not sure how I never found that in all my searching. I’ll look at the xPDO stuff and see what I come up with.

                Thanks!
                  • 22019
                  • 390 Posts
                  I use the AngellEye basic Paypal php code - I don’t have a link to hand, which includes scripts for logging all IPN transactions and process the different payment types. It can also work with both live and sandbox Paypal systems.

                  Ok - looked it up again - here it is https://www.x.com/thread/30664

                  To tie up the user before and after I add a custom field to the button-related-string I send to Paypal, and search for it in my IPN listener PHP script (or more accurately, the script that deals with the SUBSCR payment type), to move people between active and non-active, or different user groups. That also allows me to deal with unsubs, or payment failures.

                  There are probably more robust and secure ways of doing it, but it works for me.
                    Writer > E-consultant > MODx developer || Salesforce || modx 2.x || PHP 5.2.13 || MySQL client 5.0.86
                    • 18367
                    • 834 Posts
                    Hi Preston,

                    did you ever get this working?

                    As I'm trying to do the same thing.
                      Content Creator and Copywriter
                    • I'm also trying to get this to work, anyone?
                        Ben Morrison
                        Hacking templates to pieces since 2003