Tải bản đầy đủ (.pdf) (5 trang)

PHP 5 e-commerce Development- P52 pps

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (249.93 KB, 5 trang )

Taking Payment for Orders
[ 238 ]
$test = ( $this->registry->getSetting('payment.testmode') ==
'ACTIVE' ) ? '.sandbox' : '';
$this->registry->getObject('template')->getPage()->
addTag('payment.test', $test );
}
Of course, we need a template to display the payment button, where these variables
and variables set by the payment system are inserted.
<h1>Pay for your order</h1>
The payment button image is actually a submit button, and so to submit,
it needs to be within a form, with an action of the PayPal processing URL. The
payment.testmode tag is populated with sandbox if we are running in test mode.
<form
action="https://www{payment.testmode}.paypal.com/cgi-bin/webscr"
method="post">
<input type="hidden" name="cmd" value="_xclick">
The custom form eld is where we store our order ID number—when PayPal noties
us of payment, we need this to process the payment.
<input type="hidden" name="custom" value="{reference}">
PayPal needs to know our e-mail address, so it knows who to send the payment to!
<input type="hidden" name="business"
value="{payment.paypal.email}">
We also supply a name for the item and an item number.
<input type="hidden" name="item_name" value="{sitename} Purchase">
<input type="hidden" name="item_number"
value="{siteshortname}-{reference}">
We supply the cost, so PayPal knows how much to charge the customer, and in
which currency.
<input type="hidden" name="amount" value="{cost}">
<input type="hidden" name="no_shipping" value="1">


<input type="hidden" name="no_note" value="1">
<input type="hidden" name="currency_code"
value="{payment.currency}">
<input type="hidden" name="src" value="1">
This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010
953 Quincy Drive, , Brick, , 08724
Chapter 11
[ 239 ]
Next we have our notication URL, which is where PayPal sends payment
notication, the return URL where the customer is returned to once payment is
made, and the cancel URL where the customer is returned to if they cancel payment.
<input type="hidden" name="notify_url"
value="{siteurl}payment/process-payment/{reference}">
<input type="hidden" name="return"
value="{siteurl}payment/payment-received">
<input type="hidden" name="cancel_return"
value="{siteurl}payment/payment-cancelled">
<input type="hidden" name="lc" value="GB">
<input type="hidden" name="bn" value="PP-BuyNowBF">
Finally, we have the PayPal payment image button.
<input type="image"
class="paypal-button"
src="
border="0" name="submit"
alt="Make payments with PayPal - it's fast, free and secure!" >
<img alt="" border="0"
src="https://www{paymen.testmode}.paypal.com
/en_GB/i/scr/pixel.gif"
width="1" height="1">
</form>

Processing payment to update the order
Although the customer is sent back to a "thanks" or a "cancelled" page when the
payment is sent, PayPal sends some POST data to a special callback page. We can
develop this page to process the data, verify the transaction is valid, and mark an
order as "paid".
First we take POST data, which PayPal has sent to us, and use it to structure our
callback request, which we will use to verify the transaction is genuine (and not
just someone with a specially formatted script to send these requests to us).
$postback = '';
foreach ( $_POST as $key => $value )
{
$postback .= $key . '=' . urlencode( stripslashes( $value )) . '&';
}
$postback .='cmd=_notify-validate';
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen( $postback ) . "\r\n\r\n";
This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010
953 Quincy Drive, , Brick, , 08724
Taking Payment for Orders
[ 240 ]
Next we must check if our store is in test payment mode; if it is, we send our callback
request to the PayPal sandbox, otherwise we use the live PayPal site.
// live payment or test payment?
if( $this->registry->getSetting('payment.testmode') != 'ACTIVE' )
{
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);
}
else
{

$fp = fsockopen ('www.sandbox.paypal.com', 80, $errno,
$errstr, 30);
}
if (!$fp)
{
// debug point
}
else
{
$request = $header . $postback;
fputs( $fp, $request );
while ( ! feof( $fp ) )
{
$response = fgets ( $fp, 1024 );
We check that PayPal's response to our callback is that the transaction is veried.
if (strcmp( $respose, "VERIFIED" ) == 0 )
{
// transaction is verified!
We then check that there is a relevant order in our orders table, based off the custom
POST value. This POST value is the same as the custom eld we provided in our
PayPal payment button, before the customer made payment.
$order = intval( $_POST['custom'] );
$sql = "SELECT FORMAT( ( o.products_cost + o.shipping_cost ),
2 ) AS order_cost, u.email AS customer_email
FROM orders o, users u
WHERE u.ID=o.user_id AND o.ID={$order} LIMIT 1";
$this->registry->getObject('db')->executeQuery( $sql );
if( $this->registry->getObject('db')->numRows() == 1 )
{
// we have an order in our database

$orderData = $this->registry->getObject('db')->getRows();
This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010
953 Quincy Drive, , Brick, , 08724
Chapter 11
[ 241 ]
If the order exists, we must then check that the cost of the order matches the amount
being sent and that the payment has actually been sent to us, and not sent to pay
someone else, yet sending notication to our processing script. We must also check
that the currency of the payment is the one we wish to accept—otherwise, someone
may send us the correct value of payment, in a currency with a lower value.
$currency = $_POST['mc_currency'];
$total = $_POST['mc_gross'];
$email = $_POST['receiver_email'];
if( $orderData['order_cost'] == $total &&
$currency == $this->registry->
getSetting('payment.currency') &&
$email == $this->registry->
getSetting('payment.paypal.email') )
{
if( $status == 'Completed' )
{
// We then update the order in the database, and can
// then e-mail the customer and the administrator to
// inform them of this.
// update the order
$changes = array( 'status' => 2 );
$this->registry->getObject('db')->
updateRecords('orders', $changes, 'ID=' . $order );
// email the customer
// email the administrator

}
elseif( $status == 'Reversed' )
{
// charge back
// update the order

// e-mail the customer
// e-mail the administrator
}
elseif( $status == 'Refunded' )
{
// we refunded the payment
// update the order

// email the customer
// email the administrator
}
else
{
This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010
953 Quincy Drive, , Brick, , 08724
Taking Payment for Orders
[ 242 ]
//
}
}
else
{
// amount incorrect or wasn't sent to us
}

}
else
{
// error
}
}
}
fclose ($fp);
}
exit();
Direct with a credit/debit card
Sometimes a store may not want to use an off-site payment gateway; many
high-prole stores such as Amazon, Play.com, most supermarkets, and high street
stores, process payments directly on their websites. This generally works in one
of two ways:
Payment details are passed behind the scenes to a gateway to verify them.
The site then stores the details until the order is processed, at which point it
charges the card and dispatches the order.
Payment details are passed, behind the scenes, directly to the payment
gateway and are never stored on the website itself. This method either
returns a response to indicate if the transaction was accepted or not (and if
not, why not), or returning a secure token. This token can then be used by the
store to charge the card at a later stage (also for recurrent billing), by simply
passing details of the charge and the secure token to the gateway, which can
then process the transaction.
Storing card details
Storing card details on our own server offers a range of exibility. As we would
be keeping a copy of the card details, we can charge the card when we require it
(for example, recurring billing, charging only when we are ready to dispatch,
service-based payments—we can charge the card to settle their account, and so on).

If the gateway we use changes its pricing structure, or is unavailable, we have the
details; so we can use another gateway, or process the payment when the gateway
is back online.


This material is copyright and is licensed for the sole use by jackie tracey on 23rd February 2010
953 Quincy Drive, , Brick, , 08724

×