4

I'm trying to find the best way to integrate Paypal "Buy Now" buttons in my website, but I'm quite lost with all the various Paypal integration techniques (hosted buttons, dynamic buttons, IPN, PDT, and other various APIs)

I would like to integrate the better/easiest solution for my need and also a secure one...

I don't really know where to go...
Many thanks in advance for your help!

The context :

I own a website that aims to be a "marketplace" to sell digital goods.

Some people (let's call them SELLERS) register to my website as "sellers" and upload some digital goods they want to sell. I generate for them online pages for each "product" they sell.

Some other people (let's call them BUYERS) also register to my websites as "buyers" only: they just want to buy these digital goods from various sellers.

My need :

I want to integrate on each product page the paypal button of the SELLER, so he will be paid directly. I don't want to be intermediate in the payment.

So I need to integrate on each product page a different button, depending on the seller for this product.

I also need for each product to specify dynamically a different price, depending on the product sold (price will be fixed by sellers on their back-office on my website)

When the transaction is complete (payment done by the buyer), I need to unlock the download of the product on the product page for this buyer. In fact I need to update my database to associate the product to this buyer, so when he come back on my website later, he always have the product he bought "unlocked".

What I already think about buttons :

1/ Dynamic HTML buttons

<form name="_xclick" action="https://www.paypal.com/fr/cgi-bin/webscr" method="post">
<input type="hidden" name="cmd" value="_xclick">
<input type="hidden" name="item_name" value="Digital good 1">
<input type="hidden" name="amount" value="12.99">
<input type="hidden" name="currency_code" value="USD">
<input type="hidden" name="quantity" value="1">
<input type="hidden" name="item_number" value="internal_user_and_product_id">
<input type="hidden" name="business" value="seller@abusiness.com">
<input type="hidden" name="notify_url" value="https://mywebsite.com/paypal-ipn.php">
<input type="image" src="http://www.paypal.com/fr_FR/i/btn/x-click-but01.gif" border="0" name="submit">
</form>

It seems here that I just need to ask the seller its Paypal business email or ID, and dynamically generate a button for him and his product. I can also provide my IPN listener URL to unlock the product for the buyer in my database using the data passed through "item_number" upon complete transaction received. Quite simple.

BUT:
- this is NOT secure
(anybody can change the amount or paypal ID in HTML before to make the purchase)
- what happens if the seller provide an incorrect (mispelled) email address ?
(I tried to make a purchase with a test button and the fake email address "djfhsgfshdgfsd@dghe.com" and I was able to process the payment !! That was not te case with an incorrect business ID...)

2/ Paypal hosted buttons

<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
<input type="hidden" name="cmd" value="_s-xclick">
<input type="hidden" name="hosted_button_id" value="PJM2WY8H648ZK">
<input type="hidden" name="item_name" value="Digital good 2">
<input type="hidden" name="quantity" value="1">
<input type="hidden" name="item_number" value="internal_user_and_product_id">
<input type="hidden" name="notify_url" value="https://mywebsite.com/paypal-ipn.php">
<input type="image" src="http://www.paypal.com/fr_FR/i/btn/x-click-but01.gif" border="0" name="submit">
<input type="image" src="https://www.paypalobjects.com/fr_FR/FR/i/btn/btn_buynow_LG.gif" border="0" name="submit">
<img alt="" border="0" src="https://www.paypalobjects.com/fr_FR/i/scr/pixel.gif" width="1" height="1">
</form>

This would avoid fraud with the button hosted on Paypal.

BUT:
- I can't generate dynamically the button (like amount and currency).
This means that I will have to ask for sellers to generate themselves an hosted button for each item they want to sell, and set the correct price.
This also means that I will not be able to display on my website the price of the product ? Indeed, if the seller set 2USD in his Paypal hosted button but 1USD in my back-office, I will display 1USD in my website whereas the real price is 2USD...

  • I'm not sure of which variables I can provide to override the hosted button.
    I need at least the "notify_url" (IPN listener URL) and "item_number" (my product/buyer technical IDs)

Next...

I also have many interrogations for next steps, like IPN/PDT and what I can really do with these. but let's answer first the type of button I can use and integrate first!

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
TooLiPHoNe.NeT
  • 479
  • 1
  • 5
  • 22

2 Answers2

2

Your best solution for this is to not use the PayPal Buttons. You would want to use the PayPal Express Checkout solution. There is an example here:

http://marshalcurrier.com/paypal/ExpressCheckout/SetDo.php

This process is a little more programming but it will resolve all of your issues. The amount is passed from your server to PayPal directly and cannot be modified through the HTML. Also, when you complete the payment you receive a payment confirmation immediately. This way you don't have to rely on the IPN.

Here is a direct link to the intro page:

https://developer.paypal.com/docs/classic/express-checkout/gs_expresscheckout/

Here is the code for the Express Checkout example link above:

Buyer email: buyer@clubcovert.com

Buyer pwd: test1234

<a href='http://marshalcurrier.com/paypal/ExpressCheckout/custom/SetDo.php'>RESET</a><br>
<form method='post'><input type="text" name="CHARGE" value="1"/><input type="submit" value="Pay Now"/><form>

<?php
session_start();

$PPUSER = 'marshal_api1.clubcovert.com';
$PPPWD = 'LL6NV7TDRB9RFXQ5';
$PPSIG = 'ANc3YRaMB1Tgm9TediH0gENHB02JAksSKWD08wVNN3w3pwHqdBW8Im6y';
function url(){                 //PayPal Payment URL (TEST or LIVE)
    $url = "https://api-3t.sandbox.paypal.com/nvp"; //Test Server
    //$url = "https://api-3t.paypal.com/nvp"; //Live Server
    return $url;
}
function curlCall($nvp){        // Function for Curl Call to PayPal.
    $url = url();
    $ch = curl_init(); 
    curl_setopt($ch, CURLOPT_HEADER, FALSE); 
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($nvp) );
    //echo http_build_query($nvp);  //Print String
    curl_setopt($ch, CURLOPT_URL, $url); 
    $server_output = curl_exec($ch);
    mb_parse_str($server_output, $arr);
    return $arr;
}
if(isset($_POST['CHARGE'])){    // SetExpressCheckout Call
    $_SESSION['AMT'] = $_POST['CHARGE'];
    $nvp = array(
        'USER'    => $PPUSER,
        'PWD'   => $PPPWD,
        'SIGNATURE' => $PPSIG,
        'METHOD' => 'SetExpressCheckout',
        'VERSION' => '123',
        'PAYMENTREQUEST_0_PAYMENTACTION' => 'SALE',
        'PAYMENTREQUEST_0_AMT' => $_POST['CHARGE'],
        'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD',
        'RETURNURL' => 'http://marshalcurrier.com/paypal/ExpressCheckout/SetDo.php',
        'CANCELURL' => 'http://marshalcurrier.com/paypal/ExpressCheckout/SetDo.php',
    );
    $arr = curlCall($nvp);
    echo '<br><br>SetExpressCheckout Call to PayPal:<br><pre>';
    print_r ($nvp);
    echo '</pre>';
    echo 'SetExpressCheckout Server Response:<br><pre>';
    print_r ($arr);
    echo '</pre>';
    echo '<a href="https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.($arr['TOKEN']).'">Go To PayPal</a>';
}
if(isset($_GET['PayerID'])){    // DoExpressCheckoutPayment Call
    if (isset($_SESSION['AMT'])){
        $AMT = $_SESSION['AMT'];
    }else{
        $AMT = null;
    }
    $nvp = array(
        'METHOD' => 'DoExpressCheckoutPayment',
        'VERSION' => '123',
        'USER'    => $PPUSER,
        'PWD'   => $PPPWD,
        'SIGNATURE' => $PPSIG,
        'PAYERID' => $_GET['PayerID'],
        'TOKEN' => $_GET['token'],
        'PAYMENTREQUEST_0_PAYMENTACTION' => 'SALE',
        'PAYMENTREQUEST_0_AMT' => $AMT,
        'PAYMENTREQUEST_0_CURRENCYCODE' => 'USD',
    );
    $arr = curlCall($nvp);
    echo '<br><br>DoExpressCheckoutPayment Call to PayPal:<br><pre>';
    print_r ($nvp);
    echo '</pre>';
    echo 'DoExpressCheckoutPayment Server Response:<br><pre>';
    print_r ($arr);
    echo '</pre>';
    unset($_SESSION['AMT']); 
}
?>
  • 2
    The only thing I would adjust here is that IPN would still be very important. The API response alone won't correctly handle things like e-checks that need time to clear, payments caught in fraud management filters, etc. IPNs would trigger for each of these events, so you could automate procedures accordingly. Also, for the Express Checkout integration with PHP I'd recommend checking out this [PayPal PHP SDK](https://github.com/angelleye/paypal-php-library). You can get advanced Express Checkout integrations done within minutes. – Drew Angell Jul 26 '15 at 01:52
  • thanks for your answers. I need to analyse this more deeply. BUT can you confirm me that with this solution, I can send payments to dynamic SELLERS ? If I correctly understand, user ID needs password and will be MY paypal API user ID/PWD. Where do I set the recipient paypal business ID or email ? I don't want each of my registered sellers to provide me their paypal API user ID and password, this should be not acceptable... – TooLiPHoNe.NeT Jul 27 '15 at 14:22
  • 1
    If you are not looking to request your buyer's API information, than there other options that you can use but it will complicate things a little more. As mentioned in your original post, you were looking for the simplest way to resolve the issue so I suggested the Express Checkout options. We also have Mass Pay options. This would allow you to take the payment (your PayPal account) and initiate a payment to your sellers at the end of the day. You would take on responsibility for Chargebacks and Disputes through. https://developer.paypal.com/webapps/developer/docs/classic/mass-pay/gs_MassPay/ – PayPal_MSI_Marshal Jul 27 '15 at 15:13
1

After continuing my search on the big Paypal documentation, I think I've found exactly what I was looking for: Paypal Adaptive Payments.

According to the documentation, I can be an "application owner" that is an intermediate between a "payment sender" (one of my buyers) and a "payment receiver" (one of my sellers).
That is completely my case!

enter image description here

You can also do more complex things like sending to multiple receivers or do "chained payment" and be a "primary receiver" that is an intermediate between buyer and seller, and optionnaly take a fee for that.

enter image description here

This looks very complete and flexible!

I now need to learn deeper how to achieve that in technical details, but the doc says that I do not need to ask for PAypal informations to the receiver of the payment (he doesn't even have to own a Paypal account, that looks strange but true...)

Note [extract from Paypal's documentation]: 
The application owner must have a PayPal Business account.
Senders and receivers can have any PayPal account type. 
Senders and receivers are not required to have PayPal accounts initially.
PayPal prompts a sender to create an account before a payment can be completed.
A receiver must create an account to receive the funds after the payment completes.
TooLiPHoNe.NeT
  • 479
  • 1
  • 5
  • 22