PayPal

Edit the file paypal.inc in the folder includes.

paypal.inc
  1. global $paypal_context, $paypal_url, $paypal_api_url, $paypal_api_version;
  2.  
  3. $paypal_context = 'sandbox';    // 'sandbox' or 'live'
  4.  
  5. if ($paypal_context == 'sandbox') {
  6.     $paypal_api_url = 'https://api-3t.sandbox.paypal.com/nvp';
  7.     $paypal_url = 'https://www.sandbox.paypal.com';
  8. }
  9. else {
  10.     $paypal_api_url = 'https://api-3t.paypal.com/nvp';
  11.     $paypal_url = 'https://www.paypal.com';
  12. }
  13.  
  14. $paypal_api_version='124';
  15.  
  16. global $paypal_username, $paypal_password, $paypal_signature;
  17.  
  18. if ($paypal_context == 'sandbox') {
  19.     $paypal_username = false;
  20.     $paypal_password = false;
  21.     $paypal_signature = false;
  22. }
  23. else {
  24.     $paypal_username = false;
  25.     $paypal_password = false;
  26.     $paypal_signature = false;
  27. }
  28.  
  29. global $paypal_log;
  30.  
  31. $paypal_log=true;

Initialize $paypal_username, $paypal_password and $paypal_signature in the case where $paypal_context is 'sandbox' with the values defined in the configuration of your developer's account.

IMPORTANT: Make sure that $paypal_context is set to 'sandbox'.

Test

Validate a complete payment by the site with the donation form. Go to the home page of the site. If the home page doesn't display the button Donate in the banner, make sure that the action home builds the block banner with the parameter donate at true. You can also directly enter the URL /en/donation in the address bar of the navigator. In case of error, check if the action donation is properly associated to a URL in the file aliases.inc of the folder config.

Entrer an amount of 25 EUR and press on Donate. The navigator is redirected to the payment page of Paypal.

Start by cancelling the payment. The site displays the page which confirms the cancellation of a payment.

Payment cancelled

Your payment of 25.00 EUR has been cancelled. If you think this is an error, please contact us.

Retry the operation this time validating the payment using your buyer's test account. The site displays the page which confirms a payment.

Payment accepted

Your payment of 25.00 EUR has been accepted. Thank you for your confidence and support.

If a payment is rejected, the site displays yet another page.

Payment rejected

Your payment of 25.00 EUR has been rejected. If you think this is an error, please contact us.

If you have set the parameter $paypal_log to true, display the log of the operations in the file of the day in the folder log/paypal.log.

2017-09-26 11:23:43 127.0.0.1	METHOD=SetExpressCheckout;ACK=SUCCESS;TOKEN=PP-8LW79843V0049193J

To switch the site in production mode with real payments, initialize $paypal_username, $paypal_password and $paypal_signature in the case where $paypal_context is not 'sandbox' with the values defined in the configuration of your merchant's account. Set the parameter $paypal_context to 'live'.

Code
paypalcheckout.php
  1. require_once 'paypal.php';
  2. require_once 'userisidentified.php';
  3. require_once 'userprofile.php';
  4. require_once 'validatecurrency.php';

Loads the code of the functions paypal_setexpresscheckout, paypal_amt and paypal_localecode which interface Paypal as well as the configuration file paypal.inc. Loads the code of the functions user_is_identified, user_profile and validate_currency.

  1. function paypalcheckout($lang, $amount, $currency, $tax=0, $context=false) {

The function paypalcheckout has 5 parameters: the language, the total amount of the payment all taxes included, the currency of the payment, the total tax amount and an optional array which can be used to carry through the whole process details on the payment such as a product number, billing informations, etc.

  1.     global $base_url, $paypal_url, $sitename, $supported_languages;

Accesses the global variable $base_url which contains the URL of the entry point of the site, $paypal_url which defines the URL which will be used to call Paypal, $sitename which will be passed as a parameter to Paypal and $supported_languages which is used to choose a default language for the Paypal payment page.

  1.     if (!user_is_identified()) {
  2.         return run('error/unauthorized', $lang);
  3.     }

Checks if the user is identified.

  1.     if (!(is_numeric($amount) and $amount > 0)) {
  2.         return run('error/badrequest', $lang);
  3.     }
  4.     $amt=paypal_amt($amount);

Checks the parameter $amount and formats it for the Paypal interface.

  1.     if (!validate_currency($currency)) {
  2.         return run('error/badrequest', $lang);
  3.     }
  4.     $currencycode=$currency;

Checks the parameter $currency and formats it for the Paypal interface.

  1.     if (!(is_numeric($tax) and $tax >= 0)) {
  2.         return run('error/badrequest', $lang);
  3.     }
  4.     $taxamt=paypal_amt($tax);

Checks the parameter $tax and formats it for the Paypal interface.

  1.     $itemamt=paypal_amt($amount-$tax);

Calculates and formats the total price free of tax.

  1.     $name=translate('donate:name', $lang);
  2.  
  3.     $locale = $lang;
  4.     if (!$locale) {
  5.         $locale=user_profile('locale');
  6.     }
  7.     if (!$locale) {
  8.         $locale=$supported_languages[0];
  9.     }
  10.     $localecode=paypal_localecode($locale);
  11.  
  12.     $email=user_profile('mail');
  13.     $brandname=$sitename;
  14.     $hdrimg=$base_url . '/logos/sitelogo.png';
  15.  
  16.     $returnurl=$base_url . url('paypalreturn', $lang);
  17.     $cancelurl=$base_url . url('paypalcancel', $lang);
  18.  
  19.     $params = array(
  20.         'LOCALECODE'                        => $localecode,
  21.         'PAYMENTREQUEST_0_PAYMENTACTION'    => 'Sale',
  22.         'PAYMENTREQUEST_0_CURRENCYCODE'     => $currencycode,
  23.         'PAYMENTREQUEST_0_AMT'              => $amt,
  24.         'PAYMENTREQUEST_0_ITEMAMT'          => $itemamt,
  25.         'PAYMENTREQUEST_0_TAXAMT'           => $taxamt,
  26.         'L_PAYMENTREQUEST_0_NAME0'          => $name,
  27.         'L_PAYMENTREQUEST_0_AMT0'           => $itemamt,
  28.         'L_PAYMENTREQUEST_0_TAXAMT0'        => $taxamt,
  29.         'L_PAYMENTREQUEST_0_QTY0'           => '1',
  30.         'NOSHIPPING'                        => '1',
  31.         'EMAIL'                             => $email,
  32.         'BRANDNAME'                         => $sitename,
  33.         'HDRIMG'                            => $hdrimg,
  34.         'RETURNURL'                         => $returnurl,
  35.         'CANCELURL'                         => $cancelurl,
  36.         );

Prepares the parameters required by the Paypal interface for a request for an immediate payment.

  1.     $r = paypal_setexpresscheckout($params);
  2.  
  3.     if (!$r) {
  4.         return run('error/internalerror', $lang);
  5.     }

Calls the function paypal_setexpresscheckout which sends a request to the Paypal site. Displays the page signaling an internal error if the operation has failed.

  1.     $token = $r['TOKEN'];

Extracts the value of the token given to the operation by Paypal.

  1.     $_SESSION['paypal'] = compact('token', 'amt', 'itemamt', 'taxamt', 'currencycode', 'context');

Saves in the session the token provided by Paypal and the parameters of the payment.

  1.     reload($paypal_url . '/webscr&cmd=_express-checkout&token=' . $token);
  2. }

Loads the payment page of the Paypal site in the navigator.

paypalreturn.php
  1. require_once 'paypal.php';
  2.  
  3. function paypalreturn($lang, $arglist=false) {
  4.     if (!isset($_SESSION['paypal'])) {
  5.         return run('error/badrequest', $lang);
  6.     }
  7.  
  8.     $token=$_SESSION['paypal']['token'];
  9.  
  10.     $amt=$_SESSION['paypal']['amt'];
  11.     $itemamt=$_SESSION['paypal']['itemamt'];
  12.     $taxamt=$_SESSION['paypal']['taxamt'];
  13.     $currencycode=$_SESSION['paypal']['currencycode'];
  14.     $context=$_SESSION['paypal']['context'];
  15.  
  16.     unset($_SESSION['paypal']);
  17.  
  18.     if (!isset($arglist['token']) or $arglist['token'] != $token) {
  19.         return run('error/badrequest', $lang);
  20.     }
  21.  
  22.     $params = array(
  23.         'TOKEN'                             => $token,
  24.     );
  25.  
  26.     $r = paypal_getexpresscheckoutdetails($params);
  27.  
  28.     if (!$r) {
  29.         return run('error/internalerror', $lang);
  30.     }
  31.  
  32.     if ($r['TOKEN'] != $token or $r['PAYMENTREQUEST_0_AMT'] != $amt or $r['PAYMENTREQUEST_0_ITEMAMT'] != $itemamt or $r['PAYMENTREQUEST_0_TAXAMT'] != $taxamt or $r['PAYMENTREQUEST_0_CURRENCYCODE'] != $currencycode) {
  33.         return run('error/internalerror', $lang);
  34.     }
  35.  
  36.     $payerid = $r['PAYERID'];
  37.     $email = $r['EMAIL'];
  38.  
  39.     $params = array(
  40.         'TOKEN'                             => $token,
  41.         'PAYERID'                           => $payerid,
  42.         'PAYMENTREQUEST_0_PAYMENTACTION'    => 'Sale',
  43.         'PAYMENTREQUEST_0_CURRENCYCODE'     => $currencycode,
  44.         'PAYMENTREQUEST_0_AMT'              => $amt,
  45.         'PAYMENTREQUEST_0_ITEMAMT'          => $itemamt,
  46.         'PAYMENTREQUEST_0_TAXAMT'           => $taxamt,
  47.     );
  48.  
  49.     $r = paypal_doexpresscheckoutpayment($params);
  50.  
  51.     if (!$r) {
  52.         return run('error/internalerror', $lang);
  53.     }
  54.  
  55.     if ($r['TOKEN'] != $token or $r['PAYMENTINFO_0_AMT'] != $amt or $r['PAYMENTINFO_0_TAXAMT'] != $taxamt or $r['PAYMENTINFO_0_CURRENCYCODE'] != $currencycode) {
  56.         return run('error/internalerror', $lang);
  57.     }
  58.  
  59.     $transactionid=$r['PAYMENTINFO_0_TRANSACTIONID'];
  60.     $paymentstatus=strtoupper($r['PAYMENTINFO_0_PAYMENTSTATUS']);
  61.  
  62.     $completed=false;
  63.  
  64.     switch ($paymentstatus) {
  65.         case 'COMPLETED':
  66.             $feeamt=$r['PAYMENTINFO_0_FEEAMT'];
  67.             $completed=true;
  68.             break;
  69.         case 'PENDING':
  70.             $pendingreason=strtoupper($r['PAYMENTINFO_0_PENDINGREASON']);
  71.             break;
  72.         default:
  73.             break;
  74.     }
  75.  
  76.     if (!$completed) {
  77.         require_once 'actions/paymentrejected.php';
  78.  
  79.         $output = paymentrejected($lang, $amt, $currencycode, $context);
  80.     }
  81.     else {
  82.         require_once 'actions/paymentaccepted.php';
  83.  
  84.         $output = paymentaccepted($lang, $amt, $currencycode, $context);
  85.     }
  86.  
  87.     return $output;
  88. }
paypalcancel.php
  1. function paypalcancel($lang, $arglist=false) {
  2.     if (!isset($_SESSION['paypal'])) {
  3.         return run('error/badrequest', $lang);
  4.     }
  5.  
  6.     $token=$_SESSION['paypal']['token'];
  7.  
  8.     $amt=$_SESSION['paypal']['amt'];
  9.     $currencycode=$_SESSION['paypal']['currencycode'];
  10.     $context=$_SESSION['paypal']['context'];
  11.  
  12.     unset($_SESSION['paypal']);
  13.  
  14.     if (!isset($arglist['token']) or $arglist['token'] != $token) {
  15.         return run('error/badrequest', $lang);
  16.     }
  17.  
  18.     require_once 'actions/paymentcancelled.php';
  19.  
  20.     return paymentcancelled($lang, $amt, $currencycode, $context);
  21. }

See the documentation on the functions which interface the Paypal service defined in paypal by the library.

Comments

To add a comment, click here.