I've seen a few people ask how to have a custom thankyou redirected page after someone pays so I thought I'd share my solution. I use this to show a user a One Time Offer page that I have on an external site, only users that have bought the original product (http://imgraphicsplugin.com) will be able to purchase it. I was originally going to sell this but after talking with David on this forum, it seemed like it would need to have more things added to make it qualify to be a 'premium' solution. It works fine for me and it does what I need it to do so I wont be adding more features or functions to it which means you get it for free coz I'm nice like that. Disclaimer This works for me on a live site so it should for you, if it doesn't then you did something wrong. I am providing it here for free without any guarantees or obligation to provide support. If you do not know how to implement PHP or Amember plugins then you should not attempt to install this. Always always always make a backup of your database and files and know how to restore them before you make any attempt to add custom code to your live membership site. --- My amember install is located in a folder called member . if yours is called amember or different then you should change it wherever you see directory paths below. Summary You will be creating a new amember plugin inside /member/application/default/plugins/misc/ with it's own folder with two files; /otoUrl/otoUrl.php /otoUrl/brick.php (see the next post in the thread for the steps, it seems I can only add a limited sized post)
Steps 1. Create a folder called otoUrl in /member/application/default/plugins/misc/ 2. Create a php file called otoUrl.php inside that folder with this code inside PHP: <?phpclass Am_Plugin_otoUrl extends Am_Plugin{ const PLUGIN_STATUS = self::STATUS_PRODUCTION; const PLUGIN_REVISION = '0.3'; protected $oto_arr; protected $products; public function __construct(Am_Di $di, array $config) { $a = array(); $products = Am_Di::getInstance()->db->select("SELECT title,product_id FROM ?_product WHERE product_id "); // store each products oto url in array key = product_id , value = oto_url foreach($products as $product){ $a[$product['product_id']] = $di->config->get($product['product_id'].'_oto_url'); } $this->oto_arr = $a; // store products to save on a db query later $this->products = $products; parent::__construct($di, $config); } // this method will be called in the product edit page function onProductForm(Am_Event $event){ // get product being shown $product_id = $_REQUEST['_product_id']; // render disabled text field to show oto url for this product $form = $event->getForm(); if(!$product_id){ $form->addElement('text', 'oto_url', array('size' => 60, 'class'=>'translate')) ->setLabel(___("Aweber Sub Email\n" . "This is the url amember will redirect to after payment\n" . "You will need to save the product first and then this field will be editable.\n")) ->setAttribute('disabled'); } else { $form->addElement('text', 'oto_url', array('size' => 60, 'class'=>'translate')) ->setLabel(___("OTO URL\n" . "This is the url amember will redirect to after payment\n" . "You can use this for one time offers by setting the return url\n". "in Setup/configuration/One Time Offer\n". "(It can be overriden for a particular product by adding the oto_url brick found in forms editor)")) ->setValue($this->oto_arr[$product_id] == '' ? '' : $this->oto_arr[$product_id]) ->addRule('regex', ___('Must start with http:// or https://'), "/^(http|https)\:.*$/"); } } // this is the first event I can catch that still has $_POST of the vars I want function onInitFinished(Am_Event $event){ if($_POST['_save_'] == 'admin-product'){ if(isset($_POST['oto_url'])){ if($product_id = $_POST['product_id']){ $config = Am_Di::getInstance()->config; $config->saveValue($product_id.'_oto_url',$_POST['oto_url']); } } } } // this adds the button to the top of the configuration admin page function onSetupForms(Am_Event_SetupForms $forms) { //debugBreak(); $form = new Am_Form_Setup('otoUrl'); $form->setTitle("One Time Offer"); $form->setComment('You can override these urls by setting an OTO url for a product by adding the OTO Url brick in the products form (found in Configuration / Forms Editor)'); foreach($this->products as $product){ $form->addElement('text',$product['product_id'] . '_oto_url') ->setLabel(array("OTO URL for ".$product['title'])) ->addRule('regex', ___('Must start with http'), "/^(http|https)\:.*$/"); } $forms->addForm($form); } // this will load the custom brick function onLoadBricks(Am_Event $event) { require_once dirname(__FILE__) . '/brick.php'; } // events for signup updated/added to store redirect_url in session // http://www.amember.com/forum/threads/how-to-retrieve-additional-fields-on-the-edit-product-page.14269/#post-55019 function onSignupUserUpdated (Am_Event $event){ $this->store_oto_url($event->getvars()); } function onSignupUserAdded(Am_Event $event){ // getvars returns all form vars $this->store_oto_url($event->getvars()); } function store_oto_url($vars){ if(isset($vars['oto_url'])){ $_SESSION['oto_url'] = $vars['oto_url']; } } // this method will be called before rendering "thanks" page function onThanksPage(Am_Event $event) { $controller = $event->getController(); // ThanksController instance $invoice = $event->getInvoice(); // Invoice instance OR NULL (!) if (!$invoice) return; if(isset($_SESSION['oto_url'])){ // there was an oto url in the signup form. Delete it from the session // and forward to the OTO page (deleting prevents next purchase from forwarding again to same url) $controller->getResponse()->setRedirect($_SESSION['oto_url']); unset($_SESSION['oto_url']); } else { // no session oto url, get default if saved (go to first products oto_url that we find in list of items) $items = $invoice->getItems(); foreach($items as $item){ $product_id = $item->item_id; if($this->oto_arr[$product_id]){ $oto_url = $this->oto_arr[$product_id]; $controller->getResponse()->setRedirect($oto_url); return; } } } }} 3. Create a file called brick.php inside the folder with this code PHP: <?php // add a new brick to allow user to set a redirect url for this form// use for returning to an oto page after seeign the thanks page//http://www.amember.com/forum/threads/possible-to-add-custom-brick-without-editing-brick-php.14260/#post-54869// class name needs to be Am_Form_Brick_camelcasenameofpluginphpfileclass Am_Form_Brick_otoUrl extends Am_Form_Brick{ protected $hideIfLoggedInPossible = self::HIDE_DONT; public function __construct($id = null, $config = null) { $this->name = ___('OTO URL (Hidden)'); parent::__construct($id, $config); } public function initConfigForm(Am_Form $form) { $form->addText('oto_url')->setLabel(___('OTO URL'."\nUse this to forward user to an OTO after payment success")); } public function insertBrick(HTML_QuickForm2_Container $form) { $form->addHidden('oto_url')->setValue($this->getConfig('oto_url')); }}?> 4. Visit your Amember admin dashboard and go to Setup/Configuration -> Plugins and select the otoUrl plugin in the drop down list of other plugins View attachment 143 This will add it to the list below the drop down. Click save to save 5. You will now see a new button on the toolbar in Setup/Configuration for One Time Offer if you click that, you will be able to see a list of all your products with a field next to them. You can add your custom redirect URL in that field (be sure to prefix with http://) and whenever someone buys that product they will be redirected to that url instead of seeing the thanks page. View attachment 144 If you don't want to redirect to a URL for a product then leave the field blank 5a you will also be able to edit/add the OTO url in the additional fieldset of a product on the products page in Products -> Manage Products -> edit product View attachment 145 please note : if you are creating a new product, you will not be able to add an oto url to this field until AFTER you have saved the product (the field will be disabled until the product has been created succesfully) 6. You can override the url for a particular product by using the custom brick on the forms editor. This is useful if you have a special signup you are using for a campaign and only want to offer the OTO for people that signup from that campaign. Visit the forms editor and edit the signup form that you wish to override the OTO url for and drag the OTO URL (hidden) brick over to the form and click the configure to add your custom OTO url (please note, there is no sanitization on this custom brick so be sure that the value you enter is a proper url and actually works) View attachment 146 View attachment 147 7. Test Test Test. You can see if it works by making the product free and then logging in as a user and 'purchasing' the product via the default signup form which should direct you to the OTO url you have saved in the plugin config page (or to the product in manage products) Then view a custom signup form where you added the custom brick and 'purchase' the product from there, you should be redirected to the URL you configured the brick to use. --- That's how I set up my custom redirect URL on the thanks page, it works for me and does all that I need it to do. The URL for the OTO will be viewable in the users browser so if your theme does not handle the OTO page and makes it only viewable once then the user would be able to bookmark it and come back to it. If you want, you can prevent a user from buying an OTO product if they haven't bought the original offer by editing the OTO product and choosing which product they need to have active before ordering. View attachment 148 You can prevent the product from showing up on the default signup form by making sure the OTO product is in it's own category and then select only the other categories in the default signup form. (in Forms Editor -> Signup (default)) View attachment 149
I've just implemented this with the code above, brilliant instructions, easy to follow and works like a charm. Thank you for taking the time out to share this incredibly useful plugin. Certainly a thread which needs to be "stickied". Thanks a lot. Ben
Hey you're welcome Ben, I have another similar plugin which I use to add a customer to an aweber list once they have bought a plugin. I'll write up the tutorial for that if I get time
That would be brilliant thank you. On my old installations I've been using the in-built amember list but plan on moving all those over to aweber with the other main lists. Would be good to have a solution to add new members who signup.
Thanks for posting this "tut" (which by the way means "a sweet berry" in Arabic It would be great to have a category in the forum called "Custom Code" or something like that where people like yourself can post useful code for other users. I really appreciate the time and effort you put into this. Very simple and easy to follow. Thanks for posting. By the way, do you do custom work?
Thanks for sharing this! Very useful in what it does, and also as a roadmap for creating plugins for amember 4.x. David
hello, thank you for the plugin is awesome and exactly what I falait. but I have a concern, when installed, I have a problem with forwarding newrewrit protect The redirection is no longer you have an idea of what's happening?
This is absolutely brilliant, thanks! I've been trying to figure this out for months and didn't find this thread until now! I also contacted support, but they gave me a very incomplete response. I've noticed it's a very common request and it's difficult to find what the optimal solution is. There was one posted by David, but it wasn't very clear and I still don't understand how it's supposed to work. I love amember as a product, the previous version was very clunky but it sort of worked (and my customers tolerated the unprofessional-looking interface). Version 4 is a vast improvement and I'm discovering many wonderful ways to customize the customer experience. However, these popular (necessary) requests should be incorporated into newer releases as standard. I see that this plugin was posted in February and it still hasn't been incorporated into the product. Isn't this sort of thing what we are paying $80 per year for upgrades???? There's one thing that is missing in this plugin: Please could you explain how to redirect the return from PayPal or 2Checkout, etc. when the payment has been cancelled. On PayPal, there is a link that says "Click here to cancel the transaction and return to the vendor", but that either doesn't go anywhere, or it goes to the amember front end, which is completely meaningless to the customer. I'd like to be able to send the customer to different pages, depending on which product they attempted to purchase. Thanks again - and please write more plugins. I'd be happy to pay for them... amember could expand itself significantly by having a plugin store (a bit like Joomla extensions). (A suggestion to David and Co.: instead of trying to satisfy all the feature requests, why not create an easy SDK and a plugin install manager to allow developers to produce plugins which can be easily installed by end users... You could even set up a kind of an 'app store', like Apple does, and sell plugins - cheaply please! - to existing customers and help the developers make a good income from their efforts!)
I'm glad it was able to help you! I haven't really looked in to doing anything other than redirect successful purchases. I don't do anything if they user cancels payment. I might have a look at it in the future.
I think the official amember OTO plugin is now available on the members page here- go to my account / add renew- you'll see some plugins listed as free David
Please, I need to know how can I stop user to come back on my OTO offer for the second time. It's a One Time Offer, not Two (or more) Time Offer Please, can you help me to solve this problem?
Unfortunately, it doesn't work for me. The error message I get is "==DEBUG==NOTICE: Undefined index: _save_in line 56 of file /PATH/To/amember/application/default/plugins/misc/otoUrl/otoUrl.php"Do you know what the problem is?
Hei, Excuse me but I have no idea where I enter a custom URL ? I needed that after joining for free now routed back on the same page. Somewhere in the later teachings of the OTO? Described here as it does not match what I see your admin bar. Mihkel