29

I have a form and a custom PayPal button, but how do I pass the value/price variable to PayPal?

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
    <input type="hidden" name="cmd" value="_s-xclick">
    <input type="hidden" name="hosted_button_id" value="ZEFZFYBY2SZB8">
    <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_paynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
    <img alt="" border="0" src="https://www.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>

I have a variable $total = "238.00";

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Denoteone
  • 4,043
  • 21
  • 96
  • 150

8 Answers8

25

The previous code did not work for me. After much headache I finally figured out you have to go into PayPal and on step 2 of creating the button code make sure you click the unhosted button, and then copy the unencrypted button code, which will give you something like this (I blanked out my business value for security):

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
    <input type="hidden" name="cmd" value="_xclick">
    <input type="hidden" name="business" value="XXX">
    <input type="hidden" name="lc" value="CA">
    <input type="hidden" name="item_name" value="Tangled Roots">
    <input type="hidden" name="button_subtype" value="services">
    <input type="hidden" name="no_note" value="0">
    <input type="hidden" name="cn" value="Add special instructions to the seller">
    <input type="hidden" name="no_shipping" value="2">
    <input name="amount" value="16.99">
    <input type="hidden" name="currency_code" value="CAD">
    <input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHosted">
    <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
    <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>

This code creates a button where the user can input the amount, which by default starts at 16.99, but you could just as easily replace that with a PHP variable.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Julian
  • 267
  • 3
  • 4
  • 3
    Even better if add type="hidden" to amount :) – fkoessler Oct 19 '12 at 03:58
  • 1
    so this is not from paypal API? and no security issue has been consider, right? – user1900121 Mar 14 '13 at 05:56
  • This doesn't really answer the question posed and really shouldn't have so many upvotes. – Brett Feb 20 '16 at 11:00
  • 5
    This shouldn't be considered as the answer to the question by op. The OP has a hosted button which avoids any form data tampering on the client side. If you just add a form as such and don't perform any server side validation, a user can edit the actual value of the product as they want. Even if you make the field hidden it's still not good enough as you can edit the value using inspect element and submit. I'd gladly down vote this post. – avizzzy Jun 03 '16 at 13:49
  • This comment is helpful, thank you! My mistake was I created hosted button, rather than un-hosted and I couldn't change any value on the fly. So, the advice is make sure you uncheck option "save button at PayPal" when you create a new button – Ilja Hämäläinen Jan 16 '17 at 19:53
  • Hello guys, do you thing it's a secure way to pass the price ? I mean a user can change the input type hidden to text and change the value – Paul Noris Jul 26 '17 at 07:05
  • what do you recomend ? @Vinod – Paul Noris Jul 26 '17 at 07:07
15

I tried and failed with all of the above. I found this to be the answer from the PayPal website.

<form name="_xclick" action="https://www.paypal.com/cgi-bin/webscr" method="post">
    <input type="hidden" name="cmd" value="_xclick">
    <input type="hidden" name="business" value="me@mybusiness.com">
    <input type="hidden" name="currency_code" value="USD">
    <input type="hidden" name="item_name" value="Teddy Bear">
    <input type="hidden" name="amount" value="12.99">
    <input type="image" src="http://www.paypalobjects.com/en_US/i/btn/btn_buynow_LG.gif"         border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!">
</form>

Test this and you'll understand how it works... change the business to the email address of person you want to pay etc.

IanOSullivan
  • 549
  • 1
  • 4
  • 12
14

Add one more hidden field for amount

<input type="hidden" name="amount" value="<?php echo $total; ?>">
Shakti Singh
  • 84,385
  • 21
  • 134
  • 153
  • 1
    @x-yurl, you mean "Save button at PayPal" options which can't be unchecked? If yes what is the solution, because now I need too an option to add different prices to PayPal. Thanks! – Harkály Gergő Aug 23 '16 at 09:57
  • 2
    @x-yuri I tried hosted and unhosted buttons, both don't seem to work for me. My question: http://stackoverflow.com/questions/40210676/not-able-to-specify-amount-per-payment-request-on-paypal-htmlbutton – cyberjar09 Oct 24 '16 at 05:17
  • 2
    @HarkályGergő Sorry, it's only now that I've noticed your question. I haven't dealt with paypal for a while now, but I believe the reason is because all hosted button's data (like price) are supposed to be stored on paypal. With no way of altering them from the form. If you want one button with different prices you're supposed to use non-hosted buttons. That is, nothing is stored on paypal, you specify all the params in the form. – x-yuri Oct 24 '16 at 11:27
  • Thanks x-yuri, yes, I have realized that. I solved my problem with own form instead of hosted buttons, you are right! – Harkály Gergő Oct 24 '16 at 12:20
  • Hello guys, do you thing it's a secure way to pass the price ? I mean a user can change the **input type hidden to text** and change the value – Paul Noris Jul 26 '17 at 07:03
5

Here is the 2013 version: Go to create a button, when you get to step 2, uncheck the box, proceed to step 3 then create the button. Once you have the code, it will look like this:

<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="business" value="XXXXXXXX">
<input type="hidden" name="lc" value="US">
<input type="hidden" name="item_name" value="Payments">
<input type="hidden" name="amount" value="100.00">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="button_subtype" value="services">
<input type="hidden" name="no_note" value="0">
<input type="hidden" name="cn" value="Add special instructions to the seller:">
<input type="hidden" name="no_shipping" value="2">
<input type="hidden" name="rm" value="1">
<input type="hidden" name="return" value="http://YOURSITE.com/">
<input type="hidden" name="cancel_return"     value="http://YOURSITE.com/payments.html">
<input type="hidden" name="bn" value="PP-BuyNowBF:btn_buynowCC_LG.gif:NonHostedGuest">
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_buynowCC_LG.gif"     border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
<img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>

Your "business" value will not be XXXXXXXX, so make sure you leave the one Paypal gives you. You can also set your cancel and return URL's.

For more advanced PHP users: I actually setup a PHP string and it works great! For example, see below:

 https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&businesss=XXXXXXXXX&lc=US&item_name=$mydescription&amount=$myprice&........

And so on.....As you can see $mydescription is a PHP variable and $myprice is a PHP variable. What I did was setup a HTML form to collect data and used that form as a payment processing form. Once the user clicks submit, I have it going to a PHP page to use as a Mailer, Database Insertion, Autoresponder, and finally a Header redirect. The URL for the redirect is the Paypal URL with the Variables in the string! This thread actually helped me find the correct Paypal button code so that string will work properly with price variations! FYI - If you are a beginner PHP person, the image field is not used in the string. Only the URL and then the Hidden Names and Values.

Phil Mulkins
  • 188
  • 1
  • 3
  • 10
  • 3
    I don't think this works now. Paypal seems to prevent any client side alteration of the preset payment amounts in a buy now button.. at least I can't get it to work. – P a u l Sep 25 '13 at 19:41
  • 1
    @Paul Me neither. I am trying to get a 'pay via paypal' button at the end of my checkout process, but I can't manually set the price. Which is annoying. – Chud37 Nov 19 '14 at 11:10
4

I found the solution:

<input type="hidden" name="cmd" value="_s-xclick">

needs to be changed to

<input type="hidden" name="cmd" value="_xclick">

The first encrypts the data sent by the form - which caused the issue with my checkout.

Mike
  • 23,542
  • 14
  • 76
  • 87
mavame
  • 399
  • 4
  • 12
  • 2
    This does not appear to be an answer to the question. – TRiG Mar 08 '14 at 16:11
  • `_s-xclick` means a hosted (saved) button, from what I can tell. With `_xclick` you've got to supply all the data in place. – x-yuri Oct 22 '15 at 10:03
1

Here is one that allows the user to enter a price and reference.

NOTE: You'll need to change business from shop@ekerner.com to your PayPal email address, but its fine by me if you don't because it just means that I will receive your payments.

You may also like to change currency_code and lc to suit your locale ...

                        <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
                            <fieldset>
                                <input type="hidden" name="cmd" value="_xclick" />
                                <input type="hidden" name="business" value="shop@ekerner.com" />
                                <input type="hidden" name="lc" value="AU" />
                                <input type="hidden" name="item_name" value="Payment" />
                                <input type="hidden" name="item_number" value="P1" />
                                <input type="hidden" name="currency_code" value="AUD" />
                                <input type="hidden" name="button_subtype" value="services" />
                                <input type="hidden" name="no_note" value="0" />
                                <input type="hidden" name="cn" value="Comments" />
                                <input type="hidden" name="no_shipping" value="1" />
                                <input type="hidden" name="rm" value="1" />
                                <input type="hidden" name="return" value="http://www.ekerner.com/payments/?payment=success" />
                                <input type="hidden" name="cancel_return" value="http://www.ekerner.com/payments/?payment=cancelled" />
                                <input type="hidden" name="bn" value="PP-BuyNowBF:btn_paynowCC_LG.gif:NonHostedGuest" />
                                <table>
                                        <tr><td style="padding:0 5px 5px 0;">Amount AUD</td><td style="padding:0 5px 5px 0;"><input type="text" name="amount" maxlength="200" /></td></tr>
                                        <tr><td style="padding:0 5px 5px 0;"><input type="hidden" name="on0" value="Reference" />Reference</td><td style="padding:0 5px 5px 0;"> <input type="text" name="os0" maxlength="200" /></td></tr>
                                        <tr><td>&nbsp;</td><td style="padding:0 5px 5px 0;">
                                                <input style="position:relative; left:-10px; background:#ffffff; border:0;" type="image" src="https://www.paypalobjects.com/en_AU/i/btn/btn_paynowCC_LG.gif" name="submit" alt="PayPal . The safer, easier way to pay online." />
                                                <img alt="" style="border:0;" src="https://www.paypalobjects.com/en_AU/i/scr/pixel.gif" width="1" height="1" />
                                        </td></tr>
                                </table>
                            </fieldset>
                        </form>
user229044
  • 232,980
  • 40
  • 330
  • 338
ekerner
  • 5,650
  • 1
  • 37
  • 31
0

Unfortunately at the time of writing, all of the other answers to this question are incorrect - that is if you're trying to change the price of a hosted button; which is what the question was about.

The correct way to do this is below:

Important Notes: When you update the button details, it isn't just updated for that users session, it updates it within your paypal account - so the new name/price etc will affect all users that attempt to use it.

Also, be advised when altering the contents of a hosted button you need to pass all the details of the button to it as when you created it; so as an example, if you leave out passing it an item name the item name will be blank and Paypal will allow the user to set it.

On that note, we shall continue..

I personally started with this class:

<?php

class Paypal
{
    /**
     * Last error message(s)
     * @var array
     */
    protected $_errors = array();

    /**
     * API Credentials
     * Use the correct credentials for the environment in use (Live / Sandbox)
     * @var array
     */
    protected $_credentials = array(
        'USER' => 'seller_1297608781_biz_api1.lionite.com',
        'PWD' => '1297608792',
        'SIGNATURE' => 'A3g66.FS3NAf4mkHn3BDQdpo6JD.ACcPc4wMrInvUEqO3Uapovity47p',
    );

    /**
     * API endpoint
     * Live - https://api-3t.paypal.com/nvp
     * Sandbox - https://api-3t.sandbox.paypal.com/nvp
     * @var string
     */
    protected $_endPoint = 'https://api-3t.sandbox.paypal.com/nvp';

    /**
     * API Version
     * @var string
     */
    protected $_version = '74.0';

    /**
     * Make API request
     *
     * @param string $method string API method to request
     * @param array $params Additional request parameters
     * @return array / boolean Response array / boolean false on failure
     */
    public function request($method, $params = array())
    {
        $this->_errors = array();
        if (empty($method)) { //Check if API method is not empty
            $this->_errors = array('API method is missing');
            return false;
        }

        //Our request parameters
        $requestParams = array(
                'METHOD' => $method,
                'VERSION' => $this->_version
            ) + $this->_credentials;

        //Building our NVP string
        $request = http_build_query($requestParams + $params);

        //cURL settings
        $curlOptions = array(
            CURLOPT_URL => $this->_endPoint,
            CURLOPT_VERBOSE => 1,
            CURLOPT_SSL_VERIFYPEER => true,
            CURLOPT_SSL_VERIFYHOST => 2,
            CURLOPT_CAINFO => dirname(__FILE__) . '/cacert.pem', //CA cert file
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_POST => 1,
            CURLOPT_POSTFIELDS => $request
        );

        $ch = curl_init();
        curl_setopt_array($ch, $curlOptions);

        //Sending our request - $response will hold the API response
        $response = curl_exec($ch);

        //Checking for cURL errors
        if (curl_errno($ch)) {
            $this->_errors = curl_error($ch);
            curl_close($ch);
            return false;
            //Handle errors
        } else {
            curl_close($ch);
            $responseArray = array();
            parse_str($response, $responseArray); // Break the NVP string to an array
            return $responseArray;
        }
    }
}

?>

Credit: https://www.smashingmagazine.com/2011/09/getting-started-with-the-paypal-api/

Then I did the below:

include(dirname(__FILE__) . '/includes/paypal.class.php');

$paypal = new Paypal();

// Set our method
$method = 'BMUpdateButton';

// Set our params
$params = array(
    'HOSTEDBUTTONID' => 'your_button_id',
    'BUTTONTYPE' => 'BUYNOW',
    'BUTTONSUBTYPE' => 'SERVICES',
    'L_BUTTONVAR0' => 'item_name=Your Description',
    'L_BUTTONVAR1' => 'amount=999.00',
    'L_BUTTONVAR2' => 'currency_code=AUD',
    'L_BUTTONVAR3' => 'cancel_return=http://www.example.com/cancel.html',
    'L_BUTTONVAR4' => 'return=http://www.example.com/success.html'
);

// Make request to change button details
$result = $paypal->request($method, $params);

Note that while Paypal say that BUTTONSUBTYPE is optional, you will likely get an error if you don't include it.

Unfortunately the Paypal docs aren't very clear and don't provide the greatest examples, so I hope this saves someone else the many hours I spent finding out how to do this.

Brett
  • 19,449
  • 54
  • 157
  • 290
-1

Although an old post, it came across me when searching. And there is nowhere on the first pages that answers the question! Reading for about 10 hours, I managed to make a working example. But remember that paypal is constantly changing, so at some point this solution will not work anymore.

First things first. You cannot ever have a variable price value for an item. So, the first workaround is to send a request as if the item is a total in your cart! Yep, smart move :)

<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
    <input type="hidden" name="cmd" value="_cart">
    <input type="hidden" name="upload" value="1">
    <input type="hidden" name="business" value="XVR95QDG6M53J">
    <input type="hidden" name="item_name_1" value="This is the name of what you are selling">
    <input type="hidden" name="amount_1" value="<?php echo $total_cost; ?>">
    <input type="hidden" name="currency_code" value="the currency code">
    <input type="hidden" name="lc" value="if you dont need delete">
    <input type="hidden" name="shopping_url" value="link to your shop or cart on your website">
    <input type="hidden" name="retun" value="URL the user returns if payment is OK">
    <input type="hidden" name="cancel_return" value="URL the user returns if payment is canceled">
    <input type="submit" class="read-more-btn4" value="Text of [read more] button">
</form>

You may want to change the value of business to yours. But I don't really care :)

Leon Adler
  • 2,993
  • 1
  • 29
  • 42
K. Balta
  • 7
  • 3