onauthorize developer avanzadas php dynamic paypal

php - developer - Generación dinámica de botones de PayPal: ¿no es muy inseguro?



paypal javascript (6)

Me pregunto aquí ... ¿No son los botones de PayPal creados dinámicamente, muy inseguros y fácilmente "pirateables"?

Al igual que:

<form name="_xclick" target="paypal" action="https://www.paypal.com" method="post"> <input type="hidden" name="cmd" value="_cart"> <input type="hidden" name="business" value="[email protected]"> <input type="hidden" name="currency_code" value="USD"> <input type="hidden" name="item_name" value="HTML book"> <input type="hidden" name="amount" value="24.99"> <input type="image" src="http://www.paypal.com/en_US/i/btn/btn_cart_LG.gif" border="0" name="submit" alt="Make payments with PayPal - it''s fast, free and secure!"> <input type="hidden" name="add" value="1"> </form>

Cambiar el precio del producto es sencillo cuando se puede modificar el código con, digamos, FireBug.

La razón por la que estoy preguntando es porque podría / voy a comenzar a desarrollar un sistema de comercio electrónico, donde los productos pueden agregarse en ese sistema, sin hacerlo en PayPal.


Creo que también se puede utilizar un enfoque hash donde todos los valores importantes son hash para que no se puedan modificar.

El enfoque actual es, de hecho, pirateable, pero una vez que estás en el sitio de PayPal, aún puedes ver el monto que vas a pagar. Depende del usuario verificar la cantidad realmente.


Creo que tengo una solución para este problema:
Primero, envíe a PayPal desde una página segura: SSL público.

En segundo lugar, puede usar Ajax para evitar que los usuarios examinen su código HTML con "Clic derecho - Ver código fuente" o herramientas de navegadores como Fire-Bug.

Aquí hay un ejemplo en jQuery:
Normalmente programo con C # .NET, por eso me comunico con .ashx Generic Handler (pero también puede funcionar con PHP)

$ (función () {

$.ajax({ type: "POST", url: "myPage.ashx", data: { theProductsIdAndAmountsString: yourValue }, success: function (allHtmlCode) { $("body").append(allHtmlCode); $("form").submit(); } }); });

En el lado del servidor, puede generar todo el formulario HTML agrupando los datos de su base de datos y luego enviarlos de vuelta a la página.
Después, agréguela al cuerpo y envíe el formulario a PayPal.

Ahora nadie puede usar herramientas del navegador como Fire-Bug para cambiar los valores HTML.


Debería utilizar la API de botones de PayPal como la siguiente:

$sendPayData = array( "METHOD" => "BMCreateButton", "VERSION" => "65.2", "USER" => "username", "PWD" => "password", "SIGNATURE" => "abcdefg", "BUTTONCODE" => "ENCRYPTED", "BUTTONTYPE" => "BUYNOW", "BUTTONSUBTYPE" => "SERVICES", "BUTTONCOUNTRY" => "GB", "BUTTONIMAGE" => "reg", "BUYNOWTEXT" => "BUYNOW", "L_BUTTONVAR1" => "item_number=$invoiceNumber", "L_BUTTONVAR2" => "item_name=$invoiceType", "L_BUTTONVAR3" => "amount=$invoiceTotal", "L_BUTTONVAR4" => "currency_code=GBP", "L_BUTTONVAR5" => "no_shipping=1", "L_BUTTONVAR6" => "no_note=1", "L_BUTTONVAR7" => "notify_url=http://www.abc.co.uk/paypal/ipn.php", "L_BUTTONVAR8" => "cancel_return=http://www.abc.co.uk/paypal/thanks", "L_BUTTONVAR9" => "return=http://www.abc.co.uk/paypal/return.php" );

A continuación, puede enviar eso con cURL a su API

$curl = curl_init(); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_URL, ''https://api-3t.paypal.com/nvp?''.http_build_query($sendPayData)); $nvpPayReturn = curl_exec($curl); curl_close($curl);

Para generar un botón HTML encriptado que no se puede editar

<form action="https://www.paypal.com/cgi-bin/webscr" method="post"> <input type="hidden" name="cmd" value="_s-xclick"> <input type="hidden" name="encrypted" value="-----BEGIN PKCS7-----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-----END PKCS7----- "> <input type="image" src="https://www.paypal.com/en_US/i/btn/btn_paynow_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_GB/i/scr/pixel.gif" width="1" height="1">

Estos enlaces deberían ayudarlo con las opciones de los botones:

https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_nvp_BMCreateButton

https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_api_ButtonMgrAPIIntro


Estás en lo correcto. <input type="hidden" name="amount" value="24.99"> se puede manipular fácilmente en el lado del cliente. En el ejemplo que proporcionó, esta podría ser una forma en la que se supone que el cliente puede establecer la cantidad, por ej. un botón de donación de PayPal. De lo contrario, debería haber controles del lado del servidor después de este envío del formulario para asegurarse de que no haya ningún negocio divertido.



Tiene razón: los botones dinámicos de PayPal son fácilmente "pirateables" si pasa, por ejemplo, el precio del producto en texto claro.

Sin embargo, PayPal admite cifrado de botón de clave pública, por lo que los detalles relevantes no se pueden modificar fácilmente. Así es como funciona:

  • Generas un par de claves públicas / privadas con un programa apropiado como OpenSSL.
  • Inicia sesión en su cuenta de PayPal y envía la clave pública a PayPal, luego almacena la clave privada de forma segura en su servidor web. También deberá descargar el certificado de PayPal y almacenarlo en su servidor también. También se recomienda encarecidamente decirle a PayPal que no acepte transacciones sin firmar / sin encriptar (consulte el enlace en la parte inferior para obtener más información).
  • Cada vez que necesita generar un botón de PayPal, cifra los datos usando la clave pública de PayPal y lo firma con su clave privada, luego visualiza el resultado en su página web. Cuando el usuario hace clic en el botón, PayPal descifrará los detalles y comprobará que no han sido manipulados desde su generación en su servidor.

De esta forma, mientras su clave privada no esté comprometida, nadie podrá alterar los detalles de la transacción.

Más información e instrucciones detalladas están disponibles en https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_html_encryptedwebpayments#id08A3I0P017Q . (Aunque PayPal proporciona su software para generar botones encriptados, creo que es posible crearlos "sobre la marcha" utilizando funciones apropiadas, como openssl_*() en PHP; no los he probado personalmente).

Una alternativa sería implementar la Notificación de pago instantánea ( https://cms.paypal.com/us/cgi-bin/?cmd=_render-content&content_ID=developer/e_howto_admin_IPNIntro ); puede verificar que el monto de la transacción realizada por el usuario sea igual al monto total del pedido.