Omer
Omer

Reputation: 1796

How to integrate PayPal express checkout?

I'm developing a wordpress plugin that needed the PayPal Express checkout feature.

I was following this article from paypal site on how to Integrating the In-Context Checkout Feature (https://developer.paypal.com/webapps/developer/docs/classic/express-checkout/integration-guide/ECGettingStarted/#id53620a28-e357-4744-9979-66ed5c592183) which gave me the following form on 1 step.

<form method=post action=https://api-3t.sandbox.paypal.com/nvp>
    <input type=hidden name=USER value=API_username>
    <input type=hidden name=PWD value=API_password>
    <input type=hidden name=SIGNATURE value=API_signature>
    <input type=hidden name=VERSION value=XX.0>
    <input type=hidden name=PAYMENTREQUEST_0_PAYMENTACTION value=Sale>
    <input name=PAYMENTREQUEST_0_AMT value=19.95>
    <input type=hidden name=RETURNURL value=https://www.YourReturnURL.com>
    <input type=hidden name=CANCELURL value=https://www.YourCancelURL.com>
    <input type=submit name=METHOD value=SetExpressCheckout>
</form>

I have added my own API_username, API_password & API_Signature from PayPal but when submitted it shows ACK=Failure.

Following is the message from paypal I'm geting:

TIMESTAMP=2015%2d10%2d30T05%3a27%3a09Z&CORRELATIONID=24cb45b8dd36b&ACK=Failure&VERSION=0%2e000000&BUILD=18308778&L_ERRORCODE0=10002&L_SHORTMESSAGE0=Security%20error&L_LONGMESSAGE0=Security%20header%20is%20not%20valid&L_SEVERITYCODE0=Error

Because of this I cannot go to step 2 on the PayPal documentation, so need help here. What am I doing wrong?

Upvotes: 4

Views: 3541

Answers (3)

Pavel Kenarov
Pavel Kenarov

Reputation: 964

I recommended to implement PayPal Express Checkout API.

There is a lot benefits to use this method instead that you use for creating a wordpress plugin. The main reason is that the response will be delivered immediately and you will not use a IPN methods to check if transaction is successful. Also you can add several recurring and one time payments in one session, including taxes and benefits. You will have the freedom to add all this stuff, practically everything - that's need for your wordpress plugin to be cool!

This is just as recommendation. Here one simple (PHP) example how to set a transaction with several products (also recurring payment):

// Parameters for SetExpressCheckout, which will be sent to PayPal
$padata['L_BILLINGAGREEMENTDESCRIPTION0'] = 'Product description'; $padata['L_BILLINGAGREEMENTDESCRIPTION0'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'] . ' $'.$product->price.'/month'; $padata['L_PAYMENTREQUEST_0_DESC0'] = $padata['L_BILLINGAGREEMENTDESCRIPTION0'] . ' $'.$product->price.'/month';
$padata['PAYMENTREQUEST_0_NOTIFYURL'] = 'http://site_url/paypal/ipn'; $padata['PAYMENTREQUEST_0_DESC'] = $product->name; $padata['RETURNURL'] = 'http://site_url/paypal/returnurl'; $padata['CANCELURL'] = 'http://site_url/paypal/cancelurl';
$padata['PAYMENTREQUEST_0_CURRENCYCODE'] = 'USD'; $padata['PAYMENTREQUEST_0_PAYMENTACTION'] = 'SALE'; $padata['PAYMENTREQUEST_0_ITEMAMT'] = $product->price;
$padata['PAYMENTREQUEST_0_AMT'] = $product->price;
$padata['L_BILLINGTYPE0'] = 'RecurringPayments';
$padata['L_PAYMENTREQUEST_0_NAME0'] = $product->name;
$padata['L_PAYMENTREQUEST_0_NUMBER0'] = '322';
$padata['L_PAYMENTREQUEST_0_QTY0'] = '1';
$padata['L_PAYMENTREQUEST_0_AMT0'] = $product->price; $padata['L_PAYMENTREQUEST_0_NAME1'] = 'Second Product name';
$hosteddata['L_PAYMENTREQUEST_0_DESC1'] = 'second product description';
$hosteddata['L_PAYMENTREQUEST_0_NUMBER1'] = $secondproduct->id;
$hosteddata['L_PAYMENTREQUEST_0_QTY1'] = '1';
$hosteddata['L_PAYMENTREQUEST_0_AMT1'] = $secondproduct->price; $paypal_data = http_build_query($padata); $httpParsedResponseAr = $this->PPHttpPost('SetExpressCheckout', $paypal_data); //Respond according to message we receive from Paypal if("SUCCESS" == strtoupper($httpParsedResponseAr["ACK"]) || "SUCCESSWITHWARNING" == strtoupper($httpParsedResponseAr["ACK"])){ //Redirect user to PayPal store with Token received. $paypalurl ='https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token='.$httpParsedResponseAr["TOKEN"].''; header('Location: '.$paypalurl); }else{ echo 'Error : '.urldecode($httpParsedResponseAr["L_LONGMESSAGE0"]).'';
}

Page returnurl:

$hosteddata['L_BILLINGAGREEMENTDESCRIPTION0']   = 'Recurring Description';
$hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] = $hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'] . ' $'.$pr->price.'/month';
$hosteddata['L_PAYMENTREQUEST_0_NAME0'] = $pr->name;
$hosteddata['PROFILEREFERENCE'] = $GetExpressCheckoutDetails['L_PAYMENTREQUEST_0_NUMBER0'];
$hosteddata['PROFILESTARTDATE'] = date('Y-m-d') . 'T' . date('H:i:s').'Z';
$hosteddata['SUBSCRIBERNAME'] = $GetExpressCheckoutDetails['FIRSTNAME'] . ' ' . $GetExpressCheckoutDetails['LASTNAME'];
$hosteddata['TOKEN'] = urlencode($_POST['token']);
$hosteddata['DESC'] = $hosteddata['L_BILLINGAGREEMENTDESCRIPTION0'];
$hosteddata['AMT'] = $pr->price;
$hosteddata['BILLINGPERIOD'] = 'Month';
$hosteddata['BILLINGFREQUENCY'] = '1';
$hosteddata['TOTALBILLINGCYCLES'] = '12';
$hosteddata['REGULARTOTALBILLINGCYCLES'] = '1';
$hosteddata['VERSION'] = '74.0';
$hosteddata['MAXFAILEDPAYMENTS'] = '1';
$hosteddata['L_PAYMENTREQUEST_0_QTY0'] = '1';
$hosteddata['L_BILLINGTYPE0'] = 'RecurringPayments';
$hosteddata['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Digital';
$hosteddata['L_PAYMENTREQUEST_0_AMT0'] = $pr->price;
$hosteddata['INITAMT'] = $pr->price;
$hosteddata['L_PAYMENTREQUEST_0_NUMBER0'] = $pr->id;
$hosteddata['PAYMENTREQUEST_0_NOTIFYURL'] = 'http://site_url/paypal/ipn';
$padata['L_PAYMENTREQUEST_0_NAME1'] = 'Second Product name'; $hosteddata['L_PAYMENTREQUEST_0_DESC1'] = 'second product description';
$hosteddata['L_PAYMENTREQUEST_0_NUMBER1'] = $secondproduct->id;
$hosteddata['L_PAYMENTREQUEST_0_QTY1'] = '1';
$hosteddata['L_PAYMENTREQUEST_0_AMT1'] = $secondproduct->price; $paypal_data = http_build_query($hosteddata); $hosted_saas_response = $this->PPHttpPost('CreateRecurringPaymentsProfile', $paypal_data);

I used a separate method to post parameters to paypal

private function PPHttpPost( $methodName_, $nvpStr_ ) {
$api_username = '[email protected]'; $api_password = 'QWEQWEWQEQWEQEQWE';
$api_signature = 'WQEQWEQWEQWEWQEQWEQWEQWEQWEQWE.cT';
$api_endpoint = "https://api-3t.paypal.com/nvp";
$version = '124.0'; $ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_endpoint);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
$nvpreq = "METHOD=$methodName_&VERSION=$version&PWD=$api_password&USER=$api_username&SIGNATURE=$api_signature&$nvpStr_";
curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
$httpResponse = curl_exec($ch);

if(!$httpResponse) { exit("$methodName_ failed: ".curl_error($ch).'('.curl_errno($ch).')');
}

// Extract the response details.
$httpResponseAr = explode("&", $httpResponse);
$httpParsedResponseAr = array();

foreach ($httpResponseAr as $i => $value) {
$tmpAr = explode("=", $value);
if(sizeof($tmpAr) > 1) {
$httpParsedResponseAr[$tmpAr[0]] = $tmpAr[1];
}

} if((0 == sizeof($httpParsedResponseAr)) || !array_key_exists('ACK', $httpParsedResponseAr)) {
exit("Invalid HTTP Response for POST request($nvpreq) to $api_endpoint.");
} return $httpParsedResponseAr;
}

Upvotes: 3

user5196325
user5196325

Reputation:

Try this code I used in my project and it works.

PHP:

$paypal_url='https://www.paypal.com/cgi-bin/webscr'; 
$paypal_id='[email protected]';

HTML:

<form action='<?php echo $paypal_url; ?>' method='post' name='frmPayPal1'>
    <input type='hidden' name='business' value='<?php echo $paypal_id;?>'>
    <input type='hidden' name='cmd' value='_xclick'>
    <input type='hidden' name='item_name' value='Products Total'>
    <input type='hidden' name='amount' value='<?php echo $tot;?>'>
    <input type='hidden' name='no_shipping' value='1'>
    <input type='hidden' name='currency_code' value='USD'>
    <input type='hidden' name='handling' value='0'>
    <input type='hidden' name='cancel_return' value='http://localhost/paypal/cancel.php'>
    <input type='hidden' name='return' value='http://localhost/paypal/success.php'>
    <input type="image" src="https://www.sandbox.paypal.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.sandbox.paypal.com/en_US/i/scr/pixel.gif" width="1" height="1">
</form>

Upvotes: 10

Thomas
Thomas

Reputation: 677

To implement PayPal Express Checkout you need to do some server side code (PHP, ASP.Net, ...). What you are trying to do is an HTML form which won't work. You have to do 3 API calls to validate a full payment.

In each call you will use your API credentials.

Upvotes: 3

Related Questions